<[gnubie]>
i want to learn how to write in crystal. i only write in bash script. i want to have a simple web page to input a username and password then it will get the data from a remote api.
<[gnubie]>
currently, i just do it in bash with curl like: curl -d '{"username":"$USERNAME", "password":"$PASSWORD"}' -X POST https://$FQDN:$PORT/api/...
<[gnubie]>
my plan is to have a simple web page that when a user visits that page, the user needs to submit his/her username and password. when he/she clicks the submit button, the username and password will be used to connect to a remote api similar to the above curl command. if successful, the output will be printed on the page
<[gnubie]>
can anyone share what should i need to read in order for me to achieve my objective? thanks!
<FromGitter>
<Blacksmoke16> remote api that already exists?
<[gnubie]>
yes
<[gnubie]>
basically, i just want to have a similar curl client on the web page
<FromGitter>
<Blacksmoke16> for personal use or public
<[gnubie]>
personal use.
<FromGitter>
<Blacksmoke16> and i assume the username/password, fdn, port, path are all static?
<[gnubie]>
yes
<FromGitter>
<Blacksmoke16> so prob new up one of these with the hostname
<[gnubie]>
so what i do now is: export USERNAME="abc" && export PASSWORD="123" && curl -d '{"username":"$USERNAME", "password":"$PASSWORD"}' -X POST https://$FQDN:$PORT/api/...
<[gnubie]>
once the above command is successful, i will get the data in json format
<[gnubie]>
i will read the docs you've suggested, Blacksmoke16. thanks!
<[gnubie]>
do i need to have a web server running on the same crystal application?
<FromGitter>
<Blacksmoke16> i mean do you need a web server?
<FromGitter>
<Blacksmoke16> any reason this couldnt just be a cli app like curl?
<[gnubie]>
so that i will not use the terminal when i want to get the value since most of the time i have a web browser already open
<FromGitter>
<Blacksmoke16> fair enough
<FromGitter>
<Blacksmoke16> could prob use the stdlib's http server, dont really need any routing so any request coming in just make the request and return the response
<FromGitter>
<Blacksmoke16> new up a client with your api domain (assuming its https)
<FromGitter>
<Blacksmoke16> auth the client with username and password passed in via env vars (or could just make the constants really)
<FromGitter>
<Blacksmoke16> define an HTTP server that when a request comes in sets the content type as JSON, does a request to your api, and streams the response body back to the client
<[gnubie]>
let me try it out. thanks again Blacksmoke16.
<FromGitter>
<Blacksmoke16> ofc doing a like `crystal build app.cr`
<FromGitter>
<Blacksmoke16> then `USERNAME=FOO PASSWORD=BAR ./app`
<FromGitter>
<Blacksmoke16> to run it
<[gnubie]>
if i want to make a text field for entering the username and password on the web page similar to a login page, how should i do that?
<FromGitter>
<Blacksmoke16> Now you're getting complex :p
<FromGitter>
<Blacksmoke16> What about query params?
<[gnubie]>
for now, the query params are static so i can just hardcode it for now
<[gnubie]>
i just need to input username and password
<[gnubie]>
the password field should be masked
<FromGitter>
<Blacksmoke16> If they're static why bother needing to input them?
<FromGitter>
<Daniel-Worrall> use query params from your login page to a POST route on the crystal server
<[gnubie]>
the only thing may change is the username and password
<FromGitter>
<Daniel-Worrall> not the backend query params
<[gnubie]>
the web page may look like a normal login page where this is only an input text field for username and password only then a submit button
<FromGitter>
<Daniel-Worrall> Then you want 2 routes, 1 to present the form, and the other to receive the login/pass and display the result
<FromGitter>
<Blacksmoke16> Yea, actually won't be that hard I think
<[gnubie]>
yes, something like that
<FromGitter>
<Daniel-Worrall> Would be really nice to have a full tracked ruby vs crystal modules/methods and the official word on if they're included, to be included, intentionally left out, etc
<FromGitter>
<Blacksmoke16> something like that ought to work eh?
<FromGitter>
<Blacksmoke16> er minus the pp ;P
<FromGitter>
<Daniel-Worrall> I don't think he wanted the basic auth, just to be passed to the api
<[gnubie]>
yes, i don't need the basic auth on the web app itself
<FromGitter>
<Blacksmoke16> well when you land on the form, the username and password are used as the username and password within the submit route
<FromGitter>
<Blacksmoke16> which is what it was doing before no?
<FromGitter>
<Daniel-Worrall> They want instead of, not also
<FromGitter>
<Blacksmoke16> mm not sure i follow
<[gnubie]>
if i open my web browser and type in http://localhost:8080 then a simple form with username and password text fields will be displayed. if i fill in the username and password then click the submit button, the username and password will be posted to a remote api. if it succeeded, i will get a json output
<FromGitter>
<Blacksmoke16> right, whats what i did no?
<[gnubie]>
on your first code, you have this line ~> CLIENT.basic_auth ENV["USERNAME"], ENV["PASSWORD"]
<FromGitter>
<Blacksmoke16> right, now it gets those values from the form data
<[gnubie]>
which the environment variables are required when executing the app itself
<FromGitter>
<Blacksmoke16> notice i dont have the env vars anymore
<FromGitter>
<Daniel-Worrall> the auth is going to be in a POST JSON body, not Authorization header
<FromGitter>
<HertzDevil> @3n-k1 use `Enumerable#to_h`
<FromGitter>
<HertzDevil> ```code paste, see link```
f1reflyylmao is now known as f1refly
<raz>
hmm, one thing i miss in vscode + crystal is refactoring support (mark block of code, hit shortcut, it's moved out of the current method and wrapped into a `def foo; end`)
<raz>
</random-afternoon-rant>
wmoxam has quit [Ping timeout: 256 seconds]
<kevinsjoberg>
Would it be of interest supporting passing implementation files to `crystal spec`? So given src/whatever.cr it would try to find spec/whatever_spec.cr and run that?
<oprypin>
i dont think so
<oprypin>
no one-size-fits-all approach here
<kevinsjoberg>
oprypin: Care to elaborate? :) I was thinking that we've already have strong conventions in place for impl/spec, so it kind of makes sense.
<kevinsjoberg>
It wouldn't break any of the existing features either.
<oprypin>
i havent seen that those conventions are so strictly followed
<oprypin>
yea but it's complexity and confusion and support requests
<kevinsjoberg>
Well, isn't `crystal spec` following these conventions already?
<oprypin>
it's just spec/**
<kevinsjoberg>
E.g., running `crystal spec` is basically like passing `crystal spec spec/**/*_spec.cr`?
<kevinsjoberg>
oprypin: Oh, really? Could have sworn it was spec/**/*_spec.cr.
<oprypin>
hm maybe it is
<kevinsjoberg>
The docs says the following
<kevinsjoberg>
`crystal spec spec/my/test/` will do
<kevinsjoberg>
`Run all specs in files matching spec/my/test/**/*_spec.cr`
<kevinsjoberg>
Yeah, you see. So that's why I think it kind of makes sense. We've already make these assumptions.
<kevinsjoberg>
So it's just nice to be able to run crystal spec over the current file, be it the implementation or the spec itself, and the tests for that file run.
<oprypin>
it's not really the same to say '*_spec" and "<exactly name of a source file>_spec"
<oprypin>
crystal compiler has src/box.cr -> spec/std/box_spec.cr
<kevinsjoberg>
oprypin: Sure, that's true. But it would be an assumption it could make whenever you pass it something that's not *_spec.cr. If it exists, sweet, we can run the spec for you, otherwise, we just say it can't find a test for the given file.
<kevinsjoberg>
It wouldn't break any existing workflow. It would just make it a little bit sweet when files map 1-1.
<oprypin>
`function crspec { for f in "$@"; do f="${f#src/}"; echo spec/**/"${f%.cr}_spec.cr"; done | xargs -t crystal spec; }`
<oprypin>
kevinsjoberg, here^. usage: `crspec src/box.cr` or `crspec box`
<oprypin>
bonus: you can customize it however you want, dont need to change crystal
<kevinsjoberg>
oprypin: Thanks for that, doing it myself is always an option I was just scouting for opinions on adding this as a default in Crystal itself. :)
<oprypin>
thanks for the idea of the alias, it's actually a good one :p
<kevinsjoberg>
oprypin: Glad I could help, I did indeed add it to my shell as well. :)
<kevinsjoberg>
Quick question, have `crystal spec` ever accepted absolute paths? I'm using the Crystal TextMate bundle and it seem to provide crystal spec with the absolute path, which doesn't seem to work.
<kevinsjoberg>
It looks like `crystal spec` assume files to be provided relative to the spec directory. Is there any technical reason for this?
<oprypin>
no, probably just shitty implementation
<kevinsjoberg>
Alright, then I'll dive into the code then, I want to support that. :)
<oprypin>
kevinsjoberg, ah i see now. it is actually somewhat technical. crystal spec is implemented by writing out a program that has a bunch of `require "path_you_specified"`. and requires dont suppot absolute paths
<kevinsjoberg>
Oh, yeah, that makes sense. I guess we could check if absolute paths were provided?
<kevinsjoberg>
oprypin: Thanks for that, appreciate it. Will do!
<oprypin>
i can tell one edge case already: on Windows you won't be able to run a spec with an absolute path that happens to be on another drive π but not much can be done
<oprypin>
umm while we're looking at that line, it really really should be `require #{"./#{::Path[filename].relative_to(Dir.current).to_posix}".inspect}`
<FromGitter>
<HertzDevil> and how does that make `Hash` a candidate for `#bsearch` and a semantically unsound `#equals?`?
<yxhuvud>
j8r: Hash IS ordered.
<FromGitter>
<j8r> yxhuvud: and not officially indexed?
<yxhuvud>
yes? Because what would the use case be?
<FromGitter>
<j8r> even if there is `Hash#key_index`?
<FromGitter>
<j8r> just the point that was confusing me π
<yxhuvud>
:shrug: It is used in a few places internally (based on the commit that added it).
<FromGitter>
<mattrberry> If I just have a macro like this β β ```macro set_bit(value, bit) β ({{value}} | 1 << {{bit}}) β end``` β β Is there any advantage to making that a macro rather than just making it a function with the `@[AlwaysInline]` annotation? The function is nice because then I get proper type restrictions, but I'm just curious if there's any performance impact with an inlined function instead
<oprypin>
mattrberry, the common wisdom has been to avoid macros if at all possible. but i'm not sure if it's backed by any assertion that there's no performance difference whatsoever
<FromGitter>
<mattrberry> Good to know, thanks @oprypin
<FromGitter>
<mattrberry> I overuse macros for sure
<FromGitter>
<mattrberry> I also have been using these macros for months, but I recently realized that Int has effectively the same methods already β β ```code paste, see link``` β β but I haven't measured the performance impact of switching to those yet [https://gitter.im/crystal-lang/crystal?at=5fb95f6ebba6a3778b7405cb]
<FromGitter>
<mattrberry> My `bits` macro is definitely faster than Int.bits though, since Int.bits does bounds checks and other stuff, and checks the range's bounds at runtime
<FromGitter>
<mattrberry> I'm curious what the performance impact is when I'm running this ~45m+ times per second
HumanG33k has quit [Ping timeout: 260 seconds]
<oprypin>
mattrberry, oh wow do i have news for you
<oprypin>
`alwaysinline` somehow makes it different tho
<FromGitter>
<mattrberry> That's awesome!
<FromGitter>
<mattrberry> Thanks for checking :)
<FromGitter>
<mattrberry> I assume that `exe_test_def` is `exe_macro` and you just changed the name?
<yxhuvud>
oprypin: that is a bit weird, I'd have assumed the debug and dwarf stuff would be different
<yxhuvud>
regardless of if the actual executed code ends up identical
<oprypin>
mattrberry, yes. oops i messed up the output, updated now.
<yxhuvud>
actually, perhaps it is expected when the defs and macros are on the same line. adding an extra line for alwaysinline would throw off the dwarf and debug stuff though and that would make the shasum differ
<FromGitter>
<mattrberry> Hmm super interesting. Would set_bit always be inlined there anyway, even without the annotation? Whatβs the general approach the compiler uses when deciding to inline functions?
<oprypin>
mattrberry, as you can see, yes, it's inlined. almost sure that it's always
<FromGitter>
<mattrberry> Interesting, good to know. I wonder what llvm decides that based on
<FromGitter>
<mattrberry> Also, do you know why adding the new lines changed the compiled output? Iβd have assumed that wouldnβt matter
<yxhuvud>
mattrberry: the executable have debug info that includes line numbers.
<FromGitter>
<mattrberry> Ahh
<FromGitter>
<mattrberry> So presumably it wouldnβt matter if you built with βno-debug?
<FromGitter>
<mattrberry> Iβll be back at my computer in 5 mins to check
<yxhuvud>
don't think so, you'd still have stack traces etc
<yxhuvud>
ugh. it is funny how it always is some other issue is hiding behind every one I fix. turns out monkeypatching the scheduler to not use libevent is a pretty deep hole to dig into. Perhaps not so surprising.
<kevinsjoberg>
oprypin: got some feedback that it would not work for all cases, if you for instance gave them an abs path that was not relative to the project.
<kevinsjoberg>
or cwd, more precisely.
<oprypin>
then make it work, i guess? right now as it is there's 0 effect from your PR
<oprypin>
i forgot that relative_to is useless
<kevinsjoberg>
It's working properly right now, I'm just addressing some other points that was brought up. :)
<oprypin>
i have no idea how it can work
<oprypin>
so i guess absolute includes work after all?
<oprypin>
no, it definitely doesn't work
<kevinsjoberg>
oprypin: before it was always prefixed with "./".
<kevinsjoberg>
No we only prefix non-absolute path with that.
<kevinsjoberg>
And tests still passing for absolute and relative paths
<oprypin>
no wait, relative_to does work
<kevinsjoberg>
oprypin: You're right though, it did fail now, after the latest changes I did from the suggestions. Nice catch! :)
<kevinsjoberg>
I've reverted my changes to the original implementation, I'll address the comments on GitHub as well.
<FromGitter>
<Blacksmoke16> so i had a thought of adding a new `undefined` type
<straight-shoota>
yes, kv-pars in Hash are insertion ordered
postmodern has joined #crystal-lang
<postmodern>
how do shards define their own additional build steps? like what if a shard needs to also compile some additional C code that gets embedded into the final output?
<FromGitter>
<Blacksmoke16> which could call like `make build` or whatever
hightower4 has joined #crystal-lang
<FromGitter>
<franciscoadasme> hey everyone, having a generic module `Foo(T)`, is there a way to get the includers for a specific concrete type, let say, only those that include `Foo(String)`?
<postmodern>
Blacksmoke16, cool. Does the postinstall command(s) get executed by all shards that are pulled in before compiling the main project targets?
<FromGitter>
<Blacksmoke16> After that shard has been installed