Closed xzfc closed 6 years ago
I am leaning towards not having fully POSIX compatible syntax. What is the outcome you need from sourcing the existing scripts? Is that mainly to set up some environment variables?
What is the outcome you need from sourcing the existing scripts? Is that mainly to set up some environment variables?
Yes, setting environment variables. These scripts can be complex and even taking arguments but the main outcome is setting variables. Example: iccvars.sh
, needed for intel c++ compiler doc src:compilervars.sh src:compilervars_arch.sh.
It can be done using something like bash -c "source posix-shell-file.sh; exec closh"
(instead of just source posix-shell-file.sh
), but that will spawn new shell, not update state of the running one (i.e. losing all defn
s, etc).
This is doable using a wrapper like fish shell's bass.
Wrappers like bass work by executing the script using its native interpreter (in this case bash), taking a diff of the before and after state, and replaying that diff into the environment.
I think this is the best way to do it because what is the point of replicating POSIX in a project like this? closh exists because POSIX isn't what we want. Best to capture the environment variables from sourcing a bash/POSIX/whatever script and stick them in closh.
I actually implemented my own in fish (fix). It has its limitations but it made me familiar with the problem domain and why I don't want to code something like that in a POSIX-inspired shell again (even fish).
If y'all agree with that much, the only thing left would be how to integrate the functionality into closh. It could be a native operator, a function, or just an external utility. My vote is for a function, because this is going to be a common sticking point for those who want to use virtualenv or whatever. If it's included in closh itself, it lowers the friction considerably.
Let me know what you think and I can hack something together.
@mnewt Thanks, you are spot on with the reason for not replicating POSIX. I should probably start writing down some design philosophy document and add it there. I think the bass / fix approach is great for solving this particular need. If you are able to hack something up that would be really cool.
@xzfc Do you think this solution would solve your need or can you think of additional cases?
I don't have additional use-cases. Wrapper approach sounds good to me.
@dundalek Yes, I'll create a helper function in core.cljs
, unless you think a different approach is better.
@mnewt Cool! I think we might want to create util.cljs
or something like that and have it there.
@dundalek I created a proof of concept "source" helper function. Probably needs a different name, some tweaking, whatever. I will create tests and docs before making a PR.
https://github.com/mnewt/closh/commit/2800196fcc1a422c6eece99023bb0a2beca149c3
However, I can't seem to plug it in to eval.cljs
properly. This is what I get when I try to invoke it:
$ (source "export P=1")
Cannot read property 'source' of undefined
(evalmachine.<anonymous>:1:11)
ContextifyScript.Script.runInThisContext (vm.cljs:44:33)
Object.runInThisContext (vm.cljs:116:38)
(Object.lt)
(Object.lumo.repl.caching_node_eval)
(NO_SOURCE_FILE <embedded>:5720:273)
z (NO_SOURCE_FILE <embedded>:5721:263)
Object.cljs.js.eval_str_STAR_ (NO_SOURCE_FILE <embedded>:5722:328)
Function.cljs.js.eval_str.cljs$core$IFn$_invoke$arity$5 (NO_SOURCE_FILE <embedded>:5725:508)
lumo.repl.execute_text (NO_SOURCE_FILE <embedded>:6492:316)
"$ "
This works fine in lumo (https://gist.github.com/mnewt/c51a157b7f33ae768d31d8bffec8f1c0)
Can you point me toward the fix?
@mnewt Cool! If you add [closh.util]
into require statements in main.cljs
it will work (and keep it in eval as is). I agree on a different name since we don't want to override the Clojure's source
function.
This should be fixed with #35
Yeah, cool!
Have you considered using POSIX Shell compatible syntax?
That would allow sourcing shell scrips (e.g. virtualenv activate).
As far I can see, POSIX Shell have following incompatibles with closh:
( ... )
is a subshell (example:cd /bin; (cd /;pwd); pwd
)|>
is parsed as| >
(example:ls / |> out.txt tac
is same asls / | tac > out.txt
)#
is comment (sols / | #(...)
\<newline>tac
is same asls / | tac
in POSIX shell, but is invalid in closh).One way of having compatible syntax is make sure that that every part of syntax of closh is either have same meaning in POSIX Shell or invalid in POSIX Shell. For example, prepend every clojure command with
%
, and use|}
instead of|>
:Another one is using
shopt
to enable/disable POSIX compatible mode: