Class: Bundler::Spinel::Vendorer
- Inherits:
-
Object
- Object
- Bundler::Spinel::Vendorer
- Defined in:
- lib/bundler/spinel/vendorer.rb
Overview
“Make it work” — the plugin’s primary job. Spinel has no load path (plain ‘require “x”` resolves only against <spinel>/lib) and inlines `require_relative`. So to actually use a resolved dependency in a Spinel build, its source has to be placed somewhere Spinel will follow, with the require wiring generated. This is the reusable form of what projects do by hand today (e.g. Toy’s build_tep_app.sh concatenation, Roundhouse vendoring part of Tep).
Given a Gemfile.lock, vendor each gem’s ‘lib/` into `<into>/<name>/` and emit `<into>/deps.rb` — a manifest of `require_relative`s in lock order. A Spinel program then just does `require_relative “vendor/spinel/deps”`.
Gating is layered on but advisory here: placement and compatibility are different jobs. ‘vendor` warns on non-compatible gems (so the experience is nicer) but still places them; `check` is the hard gate.
Instance Method Summary collapse
-
#initialize(engine: Engine.new, ledger: Ledger.new) ⇒ Vendorer
constructor
A new instance of Vendorer.
-
#resolve_source(spec, lock_dir) ⇒ Object
path:/git: lockfile sources (toy ↔ tep is the headline case) point at a local tree; we don’t go through ‘gem fetch`.
- #vendor(lockfile = "Gemfile.lock", into: "vendor/spinel", warn_incompatible: true, ext_overrides: {}, ext_disable: []) ⇒ Object
Constructor Details
Instance Method Details
#resolve_source(spec, lock_dir) ⇒ Object
path:/git: lockfile sources (toy ↔ tep is the headline case) point at a local tree; we don’t go through ‘gem fetch`. For GEM sources we fall back to the cache-backed RubyGems fetcher. Issue: OriPekelman/spinelgems#3.
60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/bundler/spinel/vendorer.rb', line 60 def resolve_source(spec, lock_dir) src = spec.source if src.respond_to?(:path) && src.path path = src.path.to_s # Bundler stores PATH as relative-to-lockfile; resolve to abs. path = File.(path, lock_dir) unless File.absolute_path?(path) unless File.directory?(path) raise Error, "path: source for #{spec.name} not found: #{path}" end return path end @fetcher.fetch(spec.name, spec.version.to_s) end |
#vendor(lockfile = "Gemfile.lock", into: "vendor/spinel", warn_incompatible: true, ext_overrides: {}, ext_disable: []) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/bundler/spinel/vendorer.rb', line 31 def vendor(lockfile = "Gemfile.lock", into: "vendor/spinel", warn_incompatible: true, ext_overrides: {}, ext_disable: []) parsed = Bundler::LockfileParser.new(File.read(lockfile)) lock_dir = File.dirname(File.(lockfile)) into = File.(into) FileUtils.mkdir_p(into) disable = (ext_disable + ENV["SPINEL_EXT_DISABLE"].to_s.split(",")).map(&:strip).reject(&:empty?) manifest = [] exts = 0 parsed.specs.each do |spec| name = spec.name version = spec.version.to_s src = resolve_source(spec, lock_dir) dest = File.join(into, name) place(src, dest) exts += wire_extensions(src, dest, ext_overrides, disable) manifest << require_target(name, dest) note_compat(name, version) if warn_incompatible end write_manifest(into, manifest) { into: into, count: manifest.size, extensions: exts } end |