add support for isolated gemsets

Issue #53 new
Jon repo owner created an issue

Gemsets use GEM_HOME and separate filesystem locations to provide sandboxed gem environments isolated from other gemsets and each ruby's default gem home.

Comments (12)

  1. Jon reporter

    Initial Implementation

    Initially, implement support for only single, per-project (not per-user) gemsets.

    CLI

    • Initialize - uru admin gemset init
    • List - uru admin gemset ls
    • Remove - uru admin gemset rm
    • Use - uru RUBY_NAME@gemset, eg - 210@gemset

    IMPL NOTES

    1. Feature provided as a builtin, not a plugin, for Linux, Windows, and Darwin.
    2. A single gemset resides only in the $PROJECT_DIR/.gemset/$ENGINE/$VERSION subdir. Must deal with different "flavors" in a gemset due to $ENGINE and $VERSION parameters.
    3. RUBY_NAME is fuzzy matched against the currently registered ruby tag labels for PATH setting purposes. GEM_HOME is created from the absolute path to a project's gemset location as described in (2).
    4. Implemented by changing both PATH and GEM_HOME based upon the given RUBY_NAME@gemset.
    5. Activating a project's gemset (e.g. - uru 211@gemset) disables access to the selected ruby's default gems; i.e. - GEM_PATH is not supported in the initial impl. Deactivating a project's gemset (the default state or reset via uru 211) re-enables access to a ruby's default gems.
    6. Removing a project's gemset via the admin intfc purges the gemset from the filesystem similar to rm -rf or rmdir /s.
    7. Gemsets are not included as part of uru ruby ... or uru gem ... bulk operations. Those operations only iterate over each ruby and its default gem environment. Relax in a future enhancement?
    8. Do not over-complicate initial impl by trying to (poorly) integrate with Bundler.

    QUESTIONS

    1. Is postmodern's chgems all I really want for uru?
    2. Do user gemsets add value over Bundler? After initial impl, investigate supporting user gemsets living in $USER_HOME/.gem/gemset/$ENGINE/$VERSION/$GEMSET_NAME in addition to project gemsets.
    3. Why create a new "gembox" term when I can simply reuse RVM's "gemset" term? Uru's gemboxes are not as full featured as RVM's gemsets and likely never will be. Don't potentially confuse users by hijacking RVM's terminology. UPDATE: not enough difference with RVM gemsets to warrant a different name; thanks @mpapis
  2. MichaƂ Papis

    I would keep it gemsets the only extra feature that rvm has is inheritance of @global to all others, rest of the features is just helpers to make it easier working with multiple locations like copy, empty (check gem-empty), pristine (gem pristine) ...

  3. Luis Lavena

    If I may chime in, perhaps this could be simplified?

    • Leverage on already standarized .ruby-version to determine which version of Ruby to use
    • Attempt with current version (set earlier by uru xxx)
    • If no version is currently set or found in .ruby-version, throw error.
    • Perhaps command can be uru isolate for shortness

    Even people using Bundler want to keep their gems separated from projects. In my case, I have 12 projects with different gems requirements.

    Using Bundler to install everything in a shared place affects the command line version of some tools (always picking latest version) and forces me to always use bundle exec even to run a irb session since it affects which gem you can require.

    Not to mention, the more gems you have in a single repository, the longer it takes to process some commands.

    Cheers.

  4. Jon reporter

    I always welcome your thoughts, especially real-world workflows.

    My current thoughts on your feedback:

    • .ruby-version usage with gemsets will be integrated. I haven't decided on activation syntax, but don't like uru .@gemset or uru dot@gemset. Maybe uru project@gemset or uru rbver@gemset or uru auto@gemset. Whatever the syntax becomes, it MUST be conceptually consistent with the current non-gemset uru . usage. Naming is hard. I'm open to suggestions.
    • I'll consider uru isolate. Even though the current gemset CLI is conceptually admin in nature, hoisting it out of the admin intfc for concise commands is nicer. Perhaps the obvious uru gemset {init,ls,rm} CLI rather than introducing the new word isolate?
    • Per-project gemset support is what interests me. uru will likely never get per-user shared gemset support; it is currently out-of-scope.
  5. Jon reporter

    After further thought, the gemset admin commands will stay as sub-commands of the built-in admin interface. gemset will not be hoisted to a top-level core uru command.

    Gemset commands are admin commands that are expected to be used much less often than the core commands ls, gem, ruby, and switching ruby versions. Core commands should be a small set of easy-to-remember, commonly used commands. Additional commands will be added either as plugins, or admin sub-commands.

  6. Luis Lavena

    I'm 100% on per-project, which is why I commented on this.

    However, I found too repetitive to be doing uru admin gemset init tag@gemset command. If it will only create/set the gemset, or it will also set the version of Ruby?

    1. I'm already indicating that I want to use the gemset subcommand.
    2. Most likely I've already set my version (either using uru tag or uru . and .ruby-version)

    The workflow/scenario I had in mind:

    Scenario A: previously setting a version:

    1. cd into project
    2. Run uru . to set the current version using the one indicated in .ruby-version
    3. Run uru admin gemset init, so .gem/<engine>/<version> is created
    4. Install gems with gem install -g
    5. Have fun :-)

    Scenario B: no previous version set

    1. cd into project
    2. Run uru admin gemset init which will attempt to use current version of Ruby or the one defined in .ruby-version (fail if not possible)
    3. Install gems with gem install -g
    4. Have fun :-)

    At any time you can rd/rm the .gem directory of your project and start from scratch, so I'm not sure about the powers or the usage of both rm and ls from within gemset.

    Of course, I'm just thinking out loud trying to minimize the complexity of the tool.

    Thank you for your time.

  7. Jon reporter

    This workflow discussion is great. Thanks for starting the conversation.

    The initial impl will likely be less magical than you'd like. I tend to develop an explicit Initial impl, iterate via code-use-refine cycles, then add magic as usage patterns become more apparent and the code stabilizes.

    Two important CLI points for the initial impl:

    1. gemset initialization is conceptually different than gemset usage. Initializing a gemset (eg - uru admin gemset init) doesn't always mean one wants to use/activate the gemset (eg - uru 212@gemset) at the same time as initialization.
    2. ruby usage/switching (eg - uru 212) is separate from gemset usage/switching (eg - uru 212@gemset). The first makes shared gems available, the latter makes only project gems available.

    Similar to your scenarios, the two primary workflows I have in mind:

    Scenario A: add a gemset to a new/existing project

    1. cd project
    2. uru admin gemset init [RUBY_VER] - create $PROJECT_DIR/.gemset/$ENGINE/$VERSION based upon currently active ruby if RUBY_VER is not given, or set $VERSION in above path based upon matching installed ruby to specified RUBY_VER. I may require RUBY_VER rather than making it optional for performance reasons or to minimize magic.
    3. uru RUBY_VER@gemset - activate project gemset (eg - uru 212@gemset)
    4. Install gems to active gemset
    5. Hack

    Scenario B: use existing ruby installs and project gemsets within an existing project

    1. cd project
    2. uru RUBY_VER@gemset - activate project gemset matching RUBY_VER (eg - uru 200@gemset)
    3. Hack
    4. uru RUBY_VER2@gemset - switch to another project gemset matching RUBY_VER2 (eg - uru 212@gemset)
    5. Hack
    6. uru RUBY_VER3 - switch to using an installed ruby with shared gems rather than using a project gemset (eg - uru 193)
    7. Hack

    I want uru ruby ... and uru gem ... to iterate over all project gemsets, but that feature will come after gemsets are refined enough for a new release.

    What do you think?

  8. Former user Account Deleted

    For my following questions/suggestions, I am assuming that each gemset would be tied to a specific Ruby version since gems may constrain the versions of Ruby that they will install on.

    If gemsets are not constrained purely to projects, they could be useful for developing command line environments (which you probably don't want to be polluted by the gems installed for other projects). By command line environments, I mean something like a separate command line environment per framework version (like Rails 4 vs Rails 5 or Middleman 3 vs 4).

    Would gemsets be named? If they are named, do the names have to be globally unique or only unique per project (this obviously depends on the scope of gemsets) or would they follow some other set of scoping rules (like searching for a gemset by name first in the local project and then globally)? In terms of a project-based workflow, I believe my primary use-case for gemsets would be to have a single isolated gemset per project. For this kind of workflow, it would be nice not to have think about naming the gemset, but rather just specifying whether an isolated gemset is to be used or not.

    Also, I like that the uru ruby... command executes against all available Ruby versions and think that it would awesome to be able to iterate over all gemsets for a project (this would require some sort of way constrain the gemsets that the command would be run on if gemsets were not project specific though).

  9. Jignesh Gohel

    I am trying to setup my RoR dev env on my new Windows 10 Laptop. It is already setup on m Ubuntu laptop and I use RVM to manage Rubies, Gemsets etc on Ubuntu. I am trying to setup similar on my Windows 10 laptop searching for which I ended up finding uru. But am stuck on few things. Let me explain:

    There are 2 different rails apps

    rails-app-A

    .ruby-version contains 2.3.2
    .ruby-gemset contains rails-app-A-rails-5

    rails-app-B

    .ruby-version contains 2.3.2
    .ruby-gemset contains rails-app-B-rails-5

    I have installed Ruby 2.3.3 (x64) and the DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe and I successfully registered it with uru admin add. I can see the registered ruby listed with uru ls command:

    > uru ls
     => 233p222     : ruby 2.3.3p222 (2016-11-21 revision 56859) [x64-mingw32]
    

    However a major problem I am facing is that my both the applications are using Ruby v 2.3.2 but I could not find any installer for this specific version for Windows. On Ubuntu using rvm I can find that version available and hence use it.

    Next problem I am facing is using the uru auto command as explained in wiki page

    C:\WORK\Ruby\rails-app-A>uru auto
    ---> unable to find or process a `.ruby-version` file
    

    Is that because uru could not find a Ruby corresponding to version 2.3.2 defined in .ruby-gemset? Or it is because of some other known issue?

    Next I am trying to initialize the gemset as defined in my application-specific .ruby-gemset file and getting following error:

    C:\WORK\Ruby\rails-app-A>uru admin gemset init 233@rails-app-A-rails-5
    ---> unable to initialize gemset. Only project gemsets supported
    

    I really could not get what that error means. When using rvm it works in a pretty neat manner as in when changing directory to rails app root folder it detects the files and generates the gemset folder named in format ruby-version-defined-in-.ruby-version-file@gemset-name-defined-in.ruby-gemset-file for e.g. 2.3.2@rails-app-A-rails-5 and then I am all set to install application-specific gems in that gemset folder.

    Since both my applications are different and have different gems listed in their respective Gemfile I need to initialize different gemsets as per the ruby version and gemset names specified in .ruby-version and .ruby-gemset files and hence create a separate copy of gems for each application.

    Can you please let me know if I can achieve the above with the present version of uru? If yes please guide me providing the steps. If not, can you suggest me some alternative way in which I can move this forward on my Windows 10 computer?

    Thanks

  10. Jon reporter

    uru does not currently support gemsets. This issue is meant to track the bug. Unfortunately, there are a number of problems, including #94, that need to be fixed before uru will support project gemsets.

    re: the .ruby-version issue, as you suspected, since you have 2.3.3 installed but define 2.3.2 in .ruby-version, uru auto fails to find a ruby 2.3.2 variant.

    uru works differently than rvm regarding installing rubies. With uru you must first install ruby some way (e.g. - via a rubyinstaller exe or build from source as I do) and then register previously installed rubies with uru.

    Bottom line...current versions of uru cannot help you with project gemsets, but they can help you use multiple rubies and automagically activate registered rubies using uru auto and correctly defined .ruby-version files.

  11. Log in to comment