Issue #53 new

add support for isolated gemsets

jonforums
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 (9)

  1. jonforums 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 Michał Papis
  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. jonforums 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. jonforums 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. jonforums 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. Log in to comment