Skip to content

Add TextMate::Gems shared gem store for bundles - #21

Merged
dayglojesus merged 1 commit into
mainfrom
bundles/shared-gem-store
Jun 9, 2026
Merged

Add TextMate::Gems shared gem store for bundles#21
dayglojesus merged 1 commit into
mainfrom
bundles/shared-gem-store

Conversation

@dayglojesus

Copy link
Copy Markdown
Collaborator

Introduces a shared RubyGems store so bundles can declare dependencies in a Support/Gemfile and have them installed once into a common, ABI-keyed location — instead of trusting the system GEM_PATH or vendoring duplicate copies per bundle.

shared/lib/tm/gems.rb

TextMate::Gems.setup(name:, gemfile:):

  • Resolves the calling bundle's Support/Gemfile from one shared store at
    ~/Library/Application Support/TextMate/Gems/<ruby_api_version> (override via TM_GEMS_DIR).
  • Dedup: a gem+version is installed once and reused by every bundle that lists it.
  • Silent on the happy path — installs via bundle install with no window.
  • On failure: one concise native alert (TextMate::UI.alert, no stacktrace); the full failing command, output, and backtrace go to <store>/install.log. Never falls back silently to system gems.

ABI keying is required because native extensions are compiled per Ruby version/arch; pure-Ruby gems share across everything.

shared/lib/tm/gems_test.rb

Unit tests for the no-network logic — store keying, default Gemfile path, bundle-binary resolution, missing-Gemfile error, and log contents/append behaviour. 6 runs, 16 assertions, 0 failures.

Verified

Exercised end-to-end against a real consumer (the GitHub-Markdown bundle, separate PR): clean store → silent install → render; second run no-network; a second bundle shares the single gem copy; unresolvable Gemfile → exit 1, empty stdout, detail logged.

First consumer

textmatelives/GitHub-Markdown.tmbundle (companion PR) uses this to drop redcarpet + Rouge in place of the Python pygments dependency. That bundle's command requires $TM_SUPPORT_PATH/lib/tm/gems, so this PR should land first.

Design notes: DESIGN-shared-gems.md (workshop).

Bundles that need RubyGems currently `require` from the system GEM_PATH,
which is fragile, or vendor gems per-bundle, which duplicates them. This
adds a shared, ABI-keyed gem store plus a per-bundle Gemfile convention.

shared/lib/tm/gems.rb — TextMate::Gems.setup(name:, gemfile:):
- resolves a bundle's Support/Gemfile from one shared store under
  ~/Library/Application Support/TextMate/Gems/<ruby_api_version>
  (override with TM_GEMS_DIR); a gem+version is installed once and reused
  by every bundle that lists it.
- installs silently on first use via `bundle install`; no UI on success.
- on failure: one concise native alert (TextMate::UI.alert, no stacktrace),
  with the full command/output/backtrace written to <store>/install.log;
  never falls back silently to system gems.

shared/lib/tm/gems_test.rb — unit tests for the no-network logic
(store keying, default Gemfile path, bundle binary resolution, missing-Gemfile
error, log contents and append behaviour). 6 runs, 16 assertions, green.
@dayglojesus
dayglojesus merged commit 47a59b4 into main Jun 9, 2026
2 checks passed
@dayglojesus
dayglojesus deleted the bundles/shared-gem-store branch August 21, 2026 02:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant