Hey! How feasible would it be to combine a joker script with joker itself as standalone binary?
I had a little play with the go wrapper @pyr created back in Feb https://gist.github.com/pyr/bf63ac3a014517cafa371e96fdddfea0
It is pretty neat and IMO is worth documenting, at the very least it would make clear what is possible.
As I understand it, this apprach only permits a single joker as the source for the binary. Namespace loading doesn't work. I had a look into what it would take to support namespace loading and I think it could be done using Go's https://golang.org/pkg/embed/ feature. Could it be as simple as creating a version of https://github.com/candid82/joker/blob/1052d6aee932c07aa3ba30e498e4868ea1e23436/core/procs.go#L1482 which operates on the embedded filesystem? Or parameterizing os
I don’t know why namespace loading wouldn’t work; can’t think of anything fundamental about that. Maybe something simple like a global var that needs to be initialized by the replacement head?
I'm new to Go + Joker internals so I could be way off but my understanding is that os.Open can only see files on the real filesystem. With the standalone binary the files need to be embedded in the binary so os.Open can't see them
Ah, ok. Might take a closer look at this myself sometime soon, then!
Namespace loading could definitely work and embed now opens the door to bundle files, you need to wire up the file loader to pull from embedded files indeed
I've hacked together support for embedding, here's a demo: https://github.com/timmw/joker-standalone-demo and the minimal changes needed to make it work: https://github.com/timmw/joker/commit/d757aa0237537dc030cd30501d99db854c8c6f21
I fixed a problem with my first attempt by making the embedded filesystem a pointer in GLOBAL_ENV https://github.com/timmw/joker/compare/master...standalone-binary
@timmw this is pretty cool! I am warming up to the idea of adding “official” support for this in Joker, if there are volunteers to make it happen 🙂. Ideally all the boilerplate could be generated by the build script, so that all you’d need to do is to run something like ./build-embedded --root-dir 'my-src' --main-file 'main.clj'
Glad you like the idea. Seems natural to take advantage of the embed functionality in go. I agree about generating the boilerplate, that idea did cross my mind. I'd be happy to help out although as I mentioned I'm new to go so might need a bit of guidance.
@timmw what you have looks way nicer than my small hack, nice stuff!
I’m frustrated that I can’t find anyplace I saved this info, but not too long ago (maybe a couple of months), somebody asked about, and I think got working, some cool hack in which they built their own variant of a Joker executable having a relatively small main() module and pulling in Joker’s core
package (after having built Joker there, so all the initialization stuff was taken care of).
But I can’t recall exactly what they were seeking to accomplish, though I do think their approach (while @roman.bataev agreed that it wasn’t a “supported” use of Joker) might have some promise for what you’re looking to do.
Whomever they are, I hope they chime in here!
Looks promising, thanks! Is this ever likely to see official support? Or would you recommend using clojure with graal instead?
Depends on what you mean by official support 🙂. Nobody prevents you from doing this now. Maybe we could add a section about this in readme and try to keep it up-to-date if Joker’s internals change…