Uru doesn't seem to update $PATH idempotently on re-run

Issue #84 closed
Will Robertson
created an issue

When re-running (say) uru auto with a $PATH, it seems everything up-to the "_U_" entry is deleted unceremoniously, and the new Ruby's path added.

This means I have to re-add any items that I may have added, but also causes some headaches on Mac OSX; OSX doesn't run the User's local .rc script when logging-in, so you have to re-run it before certain apps to allow certain app's to be easy to find (e.g. IDE's) and sometimes again within tools like Emacs for it to find certain tools.

Is there any way Uru can detect only it's own updates to the $PATH and update them in-place, similarly to tools like Chruby and RVM?

Comments (37)

  1. Will Robertson reporter

    For an example (using Zsh on Mac OSX), this works:

    uru_path=$path[(i)_U_]
    if [ -n "${uru_path}" ]; then
      path[${uru_path}-2]=()
      path[${uru_path}-2]=()
      path[${uru_path}-2]=()
    fi
    

    But this deletes all $PATH entries from the beginning to the _U_ entry:

    if which uru_rt >/dev/null; then
      eval "$(uru_rt admin install)"
      uru nil
    fi
    
  2. Jon repo owner

    I'm traveling and need to think about this a bit.

    Way back when, I thought using a PATH "canary" like _U_ in which uru "owns" everything before the canary and doesn't muck with anything after the canary, was a clever way to handle multiple platform pathing issues. I briefly discuss things here in the Background and Known Behaviors (issue 3) sections.

    This choice simplifies uru's multi-platform PATH handling functionality code (i.e. - simple splits into a "head" and "tail" portion) that keep things performant by not doing complex work. But it also means uru will clobber everything before _U_ including elements that you added after invoking uru to activate a ruby on PATH.

    First, for how you use your system, is it possible to never prepend PATH elements before uru's _U_ canary and still have your shell environment work as you like?

    Second, in your if which uru_rt ... block, why do you need to call uru nil? On OSX and Linux, all that uru_rt admin install does is infect the shell environment with a uru() wrapper/helper function that looks like this and can be viewed afterwards with declare -f uru or typeset -f uru. Try removing uru nil and see how things work.

  3. Will Robertson reporter

    Way back when, I thought using a PATH "canary" like U in which uru "owns" everything before the canary and doesn't muck with anything after the canary, was a clever way to handle multiple platform pathing issues.

    Have you tried surrounding it with path-separators (e.g. _A_ ... _B_). I think Unix handles it, but not sure about Windows. It's also a bit of a pain, if you want to add a different path in-front of the Uru paths, for example ~/bin to make it easier to temporarily override other commands just by adding a script into ~/bin/.

    First, for how you use your system, is it possible to never prepend PATH elements before uru's _U_ canary and still have your shell environment work as you like?

    I had tried to arrange things like this, and for most tools it works, but causes problems when any tool (e.g. Emacs or Atom) tries to run a shell-based command or an internal terminal.

    Second, in your if which uru_rt ... block, why do you need to call uru nil?

    Which is why I was using the uru nil behaviour at the head of my .zshrc, to try to clear-out any Uru $PATH settings before my .rc re-added all it's local-paths, and then ran uru auto.

    My alternative of searching the $path array for _U_ and then removing the prior two paths seems to work well, though I can see how it might be tricky if you are adding a variable number of paths.

  4. Will Robertson reporter

    Unfortunately, it seems like using the _U_ marker is a bit of a "trick" and you're trying to use $PATH for a purpose that it was never really intended for — which is leading to some slightly weird behaviour for a few of us ;-)

    If using markers is the right way forward, I think you probably need to have "start" and "end" markers, but it's still abusing what $PATH was intended for, a little.

    Personally, I think it should be safe to use an additional state variable to help work-out what version of Ruby had been set by a previous Uru run (e.g. a $URU_RUBY env-var, or something) and then use standard OS/stdlib functions (whether Windows, Unix, etc) to explode the $PATH into a more machine-friendly format, and from there calculate which parts of the path need to be removed/replaced. Env var's are nice, in that most OS' will pass local copies of them on to child processes.

    Does that sound reasonable/plausible?

  5. Jon repo owner

    I think either PATH canaries such as _U1_ and _U2_ or an envar is the way to go, and either will work multi-platform using go's builtin primitives to manage PATH. Now that we're discussing, I'm leaning to moving away from the canaries to namespaced envars .

    Before I make any changes, I want nail down your use cases and details (emacs, atom, zsh, etc) with you. I'm digging out of work the first part of this week and will likely ping you mid-week.

    How knowledgeable are you with uru's current source code?

  6. Will Robertson reporter

    I think either PATH canaries such as U1 and U2 or an envar is the way to go, and either will work multi-platform using go's builtin primitives to manage PATH. Now that we're discussing, I'm leaning to moving away from the canaries to namespaced envars .

    In a Unix env, I think you'd be in good company. In Windows, you may have to take care with the differences between system-wide, user-local and process-local env-vars.

    Before I make any changes, I want nail down your use cases and details (emacs, atom, zsh, etc) with you. I'm digging out of work the first part of this week and will likely ping you mid-week.

    Two main use-cases:

    • In Mac OSX, it doesn't run any user-local .rc scripts on login, so I have wrappers around those tools that need it to source my .rc files first — primarily Emacs and Atom, for now.

      • This seems to boil-down to being able to safely re-source my .rc settings without it destroying (e.g.) the $PATH.
    • On server-style systems, where multiple versions of Ruby are needed (think: shared VMs for small-ish but long-running tools). Combined with ruby-install or custom pre-built packages.

      • RVM mostly works here, but we really don't trust how much it messes with the environment.

      • Setting system defaults via explicit /etc/profile.d/ scripts

      • Being able to have .ruby-version in a tool's root-dir, and using uru auto in a super-simple wrapper.

    The former was a specific problem I had on my work laptop.

    The latter is a problem is for my job, where we're trying to find significantly simpler alternatives to RVM — it does an awful lot of "tricks" that make us feel very insecure on a server system. Also, on some of our smaller systems, it causes a huge slow-down simply logging-in to the console.

    There are other options, like containers, more-separated systems, custom packages, etc, but Uru is already available. ;-)

    How knowledgeable are you with uru's current source code?

    Not very knowledgeable, but that's more a function of available time, I expect. I know Go well-enough (though not expert).

  7. Jon repo owner

    I'll definitely take you up on the offer to help code (and test). Sadly, the key roadblock is my lack of time due to real work.

    I think we can solve all use case issues by making uru immune to PATH mods that occur after uru has activated a ruby. I see two key options:

    1. Use _U1_ and _U2_ canaries to compartmentalize uru's PATH changes
    2. Treat PATH as a string and split it into a "head" and a "tail" by using uru's portion of PATH as the split token to go's builtin string splitting functionality

    Before I investigate 1, I'll write some simple go code to test 2.

    For example, assume you've got PATH=/opt/atom/bin:/home/foo/.gem/ruby/2.2.0/bin:/home/foo/.rubies/ruby-2.2/bin:/home/foo/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin in which uru's portion is /home/foo/.gem/ruby/2.2.0/bin:/home/foo/.rubies/ruby-2.2/bin. If I can split the PATH string using uru's string portion as the split token and end up with a string array that essentially looks like ["/opt/atom/bin", "/home/foo/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"], I can join those and rewrite PATH and not have uru clobber PATH changes (i.e. - atom got added to PATH after uru activated a ruby) made by non-uru parts.

    Any solution needs to be performant, cross-platform, and not create a unmaintainable, buggy, spaghetti code.

    Thoughts?

  8. Will Robertson reporter
    1. Use U1 and U2 canaries to compartmentalize uru's PATH changes

    I still feel this is a bit of a hack, and therefore might cause unexpected behaviour in some situations. I've not heard of anyone else putting place-holders in the $PATH, you see, but I can understand the simplicity of doing it.

    1. Treat PATH as a string and split it into a "head" and a "tail" by using uru's portion of PATH as the split token to go's builtin string splitting functionality

    I prefer this option, but I think you might not get away with simply splitting the $PATH or %PATH% in that it's plausible the /home/foo/.gem/ruby/2.2.0/bin:/home/foo/.rubies/ruby-2.2/bin(or C:\rubies\gem\2.2.0\bin;C:\rubies\ruby-2.2\bin I guess) portion might have been repeated a few times, and even that only one of /home/foo/.gem/ruby/2.2.0/bin or /home/foo/.rubies/ruby-2.2/bin might appear, and at different places than you'd expect -- the humans are allowed to play with this path, after all...

    You could easily explain this logic and warn people of the expectations of Uru and the consequences of doing things it doesn't expect.

    For either option, I'd argue for an additional shell-local (or process-local, if appropriate) $URU_RUBY_VERSION env var (or similar) to help Uru discover and/or validate the items in the $PATH.

  9. Jon repo owner

    Option 2 is not valid; good catch.

    The PATH canaries are not a dangerous as you might think. Conceptually they are no different than ghost PATH entries currently haunting some systems. For example, imagine you manually build git, install it to /opt/git, and add /opt/git/bin to PATH. Later you delete /opt/git but forget to update PATH. While messy, the ghost /opt/git/bin entry referring to a non-existent fs location is handled fine by the OS, and most likely causes no other problems for sane apps. Using _U1_ and _U2_ canaries should work similarly, even though they look hackish.

    And no uru user has ever filed an issue caused by uru's current _U_ canary. Not 100% proof of anything, but I do think users would have hammered this project if _U_ caused major issues on either Linux, OSX, or Windows.

    I ask that you try an experiment in both your desktop and server scenarios. From your shell startup scripts, embed something like _U1_:/opt/uru-test/bin:_U2_ into PATH, and stress test to see if any problems arise.

  10. Will Robertson reporter

    I still feel this is a bit of a hack, and therefore might cause unexpected behaviour in some situations.

    The PATH canaries are not a dangerous as you might think.

    Oh, sorry if I implied it was dangerous!

    No, only that I automatically shy away from things that don't meet others' expectations, as it's more likely to lead to unexpecte behaviour — perhaps not too different from how you expected it to be OK to remove all path entries from beginning to the _U_ entry.

    Conceptually they are no different than ghost PATH entries currently haunting some systems.

    That's a very good point, and I agree.

    And no uru user has ever filed an issue caused by uru's current U canary.

    You are probably also right that it doesn't make sense to "early optimise" when no-one else is having trouble with it.

    ... embed something like U1:/opt/uru-test/bin:U2 into PATH, and stress test to see if any problems arise.

    I already tried adding this to my .zshrc:

    # Unset Uru:
    uru_path=$path[(i)_U_]
    if [ -n "${uru_path}" ]; then
      path[${uru_path}-2]=()
      path[${uru_path}-2]=()
      path[${uru_path}-2]=()
    fi
    

    ... and that worked fine for my use-case, incl. switching Rubies. Obviously it makes dangerous assumptions about the number of entries in the list, but it only affects me, and I know how to fix it for me. Having _U1_ and _U2_ is better, here.

    Will it be acceptable to have multiple instances of _U1_ and _U2_ and for Uru to clean them all up?

    BTW: It might be nice, for clarity, to choose a slightly-more descriptive canary, like _URU1_.

  11. Jon repo owner

    embed something like U1:/opt/uru-test/bin:U2 into PATH, and stress test to see if any problems arise.

    ..that worked fine for my use-case, incl. switching Rubies.

    Great.

    Will it be acceptable to have multiple instances of U1 and U2 and for Uru to clean them all up?

    Uru will only ever use a single set of _U1_ and _U2_ PATH canary pairs (e.g. - _U1_:/path/to/gem/bin:/path/to/ruby/bin:_U2_) to support all scenarios. For example, when switching from one ruby to another, uru will replace the original canary pair with a new canary pair similar to how uru currently handles _U_. Uru should only manage (1) ruby on PATH at a time (overriding a user's "system ruby" if present) by always placing the ruby to be activated at the front of PATH. Anything else and the extra complexity will likely cause other problems with user's customizations.

    I want uru to make minimal assumptions about a user's system, do just enough, and quickly get out of one's way. I think people want to focus on using ruby and don't want to care about uru and any unnecessary ceremony with using uru.

    BTW: It might be nice, for clarity, to choose a slightly-more descriptive canary, like URU1

    I'm trying to keep the canaries short so as to minimize and PATH length restriction issues.

  12. Will Robertson reporter

    Have you done any work on this, @Jon ?

    If not, was thinking I can take a look over the next few weeks as the work-load dies down:

    • Was going to look into adding the two canaries (_U1_ and _U2_) and single path.
    • I was also thinking that rather than deleting and re-adding to the head of $PATH that it might be friendlier to attempt in-place substitution, to preserve whatever path-ordering the user had already defined.
  13. Jon repo owner

    I've looked into the code but haven't made any commits yet. Real work should begin dying down, and I plan to look into this late this week or early next week.

    I agree with your approach. I want to remove _U1_ and _U2_ (inclusive) based upon reading the current PATH at the time one switches to another ruby or removes ruby from PATH via uru nil, leaving the rest of PATH as-is. For adds, the _U1_ and _U2_ string will always be prefixed to the existing PATH.

    Assuming the code works out, I think this will do the trick. We'll see. You're going to be the main OSX tester as I no longer have an OSX VM 😈

  14. Will Robertson reporter

    Assuming the code works out, I think this will do the trick. We'll see. You're going to be the main OSX tester as I no longer have an OSX VM 😈

    Sounds good.

    I also plan to test it on my Linux VM. I don't have access to Windows in any meaningful way.

  15. Will Robertson reporter

    A rough sketch of what I'm planning in this gist.

    That makes sense to me.

    I don't recognise addUserPathMod() from the current Uru.

    It looks like it's allowing the User to provide additional path(s) to be managed by Uru? Is this related some new functionality you're considering?

    It works on my win8.1 and ubuntu 15.10 64bit systems. Let me know how the snippet works for you.

    Thanks!

    I'll give it a go later today / early tomorrow.

  16. Jon repo owner

    Best to view uru_pathmunge.go as a way to quickly test out design ideas before injecting them into uru. That's why addUserPathMod() isn't recognizable as it's only a test helper func and doesn't belong in uru. Uru will need refactoring of mainly internal/env/{ruby,util}.go and internal/command/use_nil.go using funcs (e.g. - getUruHunk()) similar to those in uru_pathmunge.go.

    I'm interested in what you see on your OSX box when you run go run uru_pathmunge.go. The PATH mods that are done are isolated to the child process running the exe rather than your current shell environment.

  17. Will Robertson reporter

    It works on my win8.1 and ubuntu 15.10 64bit systems. Let me know how the snippet works for you.

    I'll give it a go later today / early tomorrow.

    I ran it this morning, with the below results, so looks pretty good.

    BTW: I misread what addUserPathMod() does, and running it has cleared that up.

     % go run uru_pathmunge.go
    ---> capturing user's original base PATH
    Base PATH = /Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    
    ---> enhancing base PATH with uru path hunk
    Uru path hunk = _U1_:/fake/.gem/ruby/2.2.0/bin:/fake/ruby/bin:_U2_
    Uru enhanced PATH = _U1_:/fake/.gem/ruby/2.2.0/bin:/fake/ruby/bin:_U2_:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    
    ---> removing uru path hunk from base PATH
    Clean PATH = /Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    
    ---> prefixing uru PATH with user mods
    User PATH = /fake/tool/bin:_U1_:/fake/.gem/ruby/2.2.0/bin:/fake/ruby/bin:_U2_:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    
    ---> removing uru path hunk from user PATH
    Final PATH = /fake/tool/bin:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    
  18. Jon repo owner

    If my smoke test results continue to pass on both win8.1 and ubuntu 15.10, I'll put up a beta version later today for your osx/linux testing.

    C:\>uru ver
    uru v0.8.1.alpha1 [windows/386 go1.5.2]
    
    C:\>uru ls
        218p440-x32 : ruby 2.1.8p440 (2015-12-16 revision 53158) [i386-mingw32]
     => 224p230-x32 : ruby 2.2.4p230 (2015-12-16 revision 53154) [i386-mingw32]
        jruby       : jruby 9.0.3.0 (2.2.2) 2015-10-21 633c9aa Java HotSpot(TM) 64-Bit...
    
    C:\>echo %PATH%
    _U1_;C:\Apps\rubies\ruby-2.2\bin;_U2_;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;...
    
  19. Will Robertson reporter

    uru 0.8.1.beta1 now available for your testing on the downloads page

    I'll take a look.

    Is there anything special I need to do with this version, if I prefer to build it myself?

  20. Jon repo owner

    If you test one of the downloads, simply rename the existing uru_rt, extract the new version to the same location, start a new shell, and then use uru ... as normal.

    I haven't committed the new source to the repo, so you can't build it yourself. If things look good with beta1 on your end, let me know and I'll push the new commits so you can build.

  21. Will Robertson reporter

    uru 0.8.1.beta1 now available for your testing on the downloads page

    This is my test, using 0.8.1.beta1.

    From a Terminal:

    mexisme@hostage: ~
    10:53:10/10009 % echo $PATH
    _U1_:/Users/mexisme/.gem/ruby/2.2.0/bin:/opt/rubies/ruby-2.2.3/bin:_U2_:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/MacGPG2/bin:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    
    mexisme@hostage: ~
    10:53:12/10010 % export PATH=HELLO:$PATH
    
    mexisme@hostage: ~
    10:53:24/10011 % echo $PATH
    HELLO:_U1_:/Users/mexisme/.gem/ruby/2.2.0/bin:/opt/rubies/ruby-2.2.3/bin:_U2_:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/MacGPG2/bin:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    
    mexisme@hostage: ~
    10:53:26/10012 % uru auto
    ---> now using ruby 2.2.3-p173 tagged as `ruby-2.2.3`
    
    mexisme@hostage: ~
    10:53:39/10013 % echo $PATH
    _U1_:/Users/mexisme/.gem/ruby/2.2.0/bin:/opt/rubies/ruby-2.2.3/bin:_U2_:HELLO:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/MacGPG2/bin:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    
    mexisme@hostage: ~
    10:59:34/10015 % uru 2.0
    ---> now using ruby 2.0.0-p647 tagged as `ruby-2.0.0`
    
    mexisme@hostage: ~
    10:59:40/10016 % echo $PATH
    _U1_:/Users/mexisme/.gem/ruby/2.0.0/bin:/opt/rubies/ruby-2.0.0-p647/bin:_U2_:HELLO:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/MacGPG2/bin:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    

    And from within Atom.

    • My Atom wrapper-script re-invokes .zshrc, as MacOSX doesn't run a "login" style script before starting the Window Manager, or any standard MacOSX apps, and this is how I'm setting-up Uru, currently.

    • I'm not quite sure why my paths have doubled-up, but I suspect it's because I have my Atom app-wrapper script, and then invoke a terminal within Atom which re-runs my .zshrc; i.e. not Uru's fault.

    mexisme@hostage: /Applications/Dev/Atom.app/Contents/Resources/Scripts
    11:01:29/10017 % echo $PATH
    _U1_:/Users/mexisme/.gem/ruby/2.2.0/bin:/opt/rubies/ruby-2.2.3/bin:_U2_:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/MacGPG2/bin:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/Use
    rs/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    
    mexisme@hostage: /Applications/Dev/Atom.app/Contents/Resources/Scripts
    11:01:32/10017 % uru 2.1
    ---> now using ruby 2.1.7-p400 tagged as `ruby-2.1.7`
    
    mexisme@hostage: /Applications/Dev/Atom.app/Contents/Resources/Scripts
    11:01:43/10018 % echo $PATH
    _U1_:/Users/mexisme/.gem/ruby/2.1.0/bin:/opt/rubies/ruby-2.1.7/bin:_U2_:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/usr/lo
    cal/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/MacGPG2/bin:/Users/mexisme/bin:/Users/mexisme/local/x86_64-macosx/bin:/Use
    rs/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin:/Users/mexisme/.npm-packages/bin:/Users/mexisme/dev/GOLANG/bin
    
  22. Jon repo owner

    Have you tried hoisting things earlier in the zsh startup by disabling the call to ~/.zshrc in your Atom wrapper script, putting the eval "$(uru_rt admin install)" first into ~/.zshenv then, if it fails, into ~/.zprofile? This could solve both the uru shell function install and the path doubling up issue at once.

    Odd that your ~/.zshrc isn't being run as part of the login shell startup. Perhaps OSX has tweaked a zsh compile option or the global config /etc/{zshenv,zprofile}.

    Your results basically look good. When you've done enough testing in your workstation and server scenarios, give me the "looks good" and I'll start the v0.8.1 release process.

  23. Will Robertson reporter

    Have you tried hoisting things earlier in the zsh startup by disabling the call to ~/.zshrc in your Atom wrapper script, putting the eval "$(uru_rt admin install)" first into ~/.zshenv then, if it fails, into ~/.zprofile? This could solve both the uru shell function install and the path doubling up issue at once.

    Yes, that's the sort-of thing I've done before, and is almost definitely what I'll do.

    But, my login is a half-way house between RVM (which is what we currently use at work, and which I'm hoping we can drop) and Uru, and I wanted to defer tweaking and/or cleaning-up my rc's until after experimentation & testing.

    Odd that your ~/.zshrc isn't being run as part of the login shell startup. Perhaps OSX has tweaked a zsh compile option or the global config /etc/{zshenv,zprofile}.

    OS-X has disabled quite a large number of standard Unix-isms, incl. rc scripts, in general — e.g. you're supposed to use launchd semantics for start-up, /etc/paths and /etc/paths.d/* to set global path additions.

    And scripts like ~/profile, ~/.bashrc and ~/.zshrc only get run when you open a Terminal.

    Your results basically look good. When you've done enough testing in your workstation and server scenarios, give me the "looks good" and I'll start the v0.8.1 release process.

    I'm going to try a few other things around Gem installation, Bundler, and running/building some of my Ruby code tonight; this was early feedback.

    I have a strong belief this will work well, though.

  24. Jon repo owner

    I'm going to try a few other things around Gem installation, Bundler, and running/building some of my Ruby code tonight; this was early feedback.

    I have a strong belief this will work well, though.

    Great. I've fixed a very subtle bug and will be uploading 0.8.1.rc1 shortly.

  25. Will Robertson reporter

    Great. I've fixed a very subtle bug and will be uploading 0.8.1.rc1 shortly.

    Have tried it with 2 CLI tools and 2 Rails projects, and doesn't seem to have any issues.

    Sub-tools (e.g. Rubocop) seem to be running correctly from Atom editor, as well.

  26. Jon repo owner

    Refactor uru's PATH mangling strategy. Closes #84

    Uru now uses two PATH canaries to isolate its PATH changes. U1 is used at the start, and U2 is used at the end. Essentially, this creates a type of sandbox for uru's PATH changes.

    Uru's sandbox (aka uru chunk) uses the following format:

    U1;[GEM_HOME_BIN_DIR];RUBY_BIN_DIR;U2 (Windows) U1:[GEM_HOME_BIN_DIR]:RUBY_BIN_DIR:U2 (Linux, OSX)

    → <<cset ebd890075d79>>

  27. Jon repo owner

    Here's hoping it continues to work 😸

    Cool that there's a Homebrew formula for uru. I'm surprised since most users are Windows folks.

    I don't know Homebrew, but too bad the formula can't automagically do the uru install dance (simply injects this function into your current shell environment; viewable via typeset -f uru) when you do brew install uru so one doesn't have to manually tweak a startup script with eval "$(uru_rt admin install)".

    For example, I create a chocolatey (a Windows pkg mgr similar to Homebrew or apt-get) pkg that has a custom install script that does the uru Windows install dance when installing uru via chocolatey.

  28. Will Robertson reporter

    Here's hoping it continues to work 😸

    Well, can always release 0.8.2 ;-)

    Cool that there's a Homebrew formula for uru. I'm surprised since most users are Windows folks.

    Well, the competitors are RVM, RubyEnv and chruby.

    RVM and RubyEnv are pretty invasive, e.g. replacing cd in RVM — which is particularly annoying in a cleaned-server situation — and chruby seems to do some weird things with Gem paths which failed for me at times.

    I don't know Homebrew, but too bad the formula can't automagically do the uru install dance (simply injects this function into your current shell environment; viewable via typeset -f uru) when you do brew install uru so one doesn't have to manually tweak a startup script with eval "$(uru_rt admin install)".

    Well, it is possible to do this, but I don't really like install-scripts automatically doing that to my user-local .rc scripts without asking first, and imagine there are quite a few people out there who feel the same.

    Having said that, a system-level .rc script would probably be ok.

    For example, I create a chocolatey (a Windows pkg mgr similar to Homebrew or apt-get) pkg that has a custom install script that does the uru Windows install dance when installing uru via chocolatey.

    Sure, I'm familiar with chocolatey (from a previous job) — it's come a long way!

    On Windows, I think I'd have less of a problem with it, since most people don't have anything like a login .rc script on the platform, anyway.

  29. Log in to comment