bundler-source-vault 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/gemvault_load_path.rb +163 -0
- data/plugins.rb +17 -36
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1ef5a7eef66715d1eef861c72b9d99ae3620f507cc67cc3e77ddc9ec388a1e66
|
|
4
|
+
data.tar.gz: cb6bf98bc161d1d69ddfa628787de932c4768a59cbcfe49ebbf01cec5c9ba739
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 495d5668e91b6508baefbfab28cca129e506da744f1026b93b3eecfe4b8623955fb27c74ee7d54f89b8c21bed561470f44ee65a61ace034abc1048dac7305206
|
|
7
|
+
data.tar.gz: 2c3539ddb5f9f098f39cdbad32747f9aa0d88f013247a464e5a9d8107657cadd621497f24a5f6860f16fe24aea9469815b691923c7f1b16c0af694f5c0b8ad1e
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
module BundlerSourceVault
|
|
2
|
+
# Finds gemvault, and the runtime dependencies it needs, across every gem root
|
|
3
|
+
# that could hold either, and puts their require paths on $LOAD_PATH.
|
|
4
|
+
#
|
|
5
|
+
# Bundler installs a plugin's dependencies alongside the plugin but does not
|
|
6
|
+
# put them on the load path before loading plugins.rb -- see the "Currently
|
|
7
|
+
# not done to avoid conflicts" comment in bundler/plugin.rb -- so the shim has
|
|
8
|
+
# to find gemvault itself.
|
|
9
|
+
#
|
|
10
|
+
# $LOAD_PATH rather than activation, because activation cannot survive here:
|
|
11
|
+
#
|
|
12
|
+
# bundler/runtime.rb clean_load_path runs immediately before specs_for, and
|
|
13
|
+
# resolution is what asks the vault source for specs.
|
|
14
|
+
# bundler/shared_helpers.rb
|
|
15
|
+
# clean_load_path strips a $LOAD_PATH entry only when it
|
|
16
|
+
# appears in loaded_gem_paths.
|
|
17
|
+
# bundler/rubygems_integration.rb
|
|
18
|
+
# loaded_gem_paths is built from Gem.loaded_specs, so
|
|
19
|
+
# activating is precisely what gets these paths removed
|
|
20
|
+
# one line before they are needed; and stub_rubygems
|
|
21
|
+
# sets Gem::Specification.all to the bundle's own specs,
|
|
22
|
+
# reapplying it via Gem.post_reset, so under bundle exec
|
|
23
|
+
# find_by_name cannot see outside the bundle and reset
|
|
24
|
+
# will not restore it.
|
|
25
|
+
#
|
|
26
|
+
# Skipping activation also skips gemvault's dependencies, which is why they
|
|
27
|
+
# are resolved here by hand. One that cannot be found is left out rather than
|
|
28
|
+
# raising: command_kit is needed only by the CLI, and activation would have
|
|
29
|
+
# aborted on it.
|
|
30
|
+
module GemvaultLoadPath
|
|
31
|
+
GEM = "gemvault".freeze
|
|
32
|
+
SHIM = "bundler-source-vault".freeze
|
|
33
|
+
VAULT_SOURCE = "bundler/plugin/vault_source.rb".freeze
|
|
34
|
+
|
|
35
|
+
module_function
|
|
36
|
+
|
|
37
|
+
def apply
|
|
38
|
+
entries.each { |path| $LOAD_PATH.push(path) unless $LOAD_PATH.include?(path) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Development: loaded from within the gemvault source tree, where the gem is
|
|
42
|
+
# not installed, so its lib has to lead the search.
|
|
43
|
+
def source_tree_lib
|
|
44
|
+
lib = shim_dir.parent.join("lib")
|
|
45
|
+
lib if lib.join(VAULT_SOURCE).file?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Registering these keeps the roots' specs discoverable to RubyGems, which is
|
|
49
|
+
# what lets `bundle plugin install` see a gem it has just written into the
|
|
50
|
+
# plugin root. It has to run on every evaluation, because it does not survive
|
|
51
|
+
# one: Gem.clear_paths and Gem::Specification.reset, both of which Bundler
|
|
52
|
+
# calls while configuring the bundle, recompute the dirs from Gem.path.
|
|
53
|
+
def register_spec_dirs
|
|
54
|
+
searched = Gem::Specification.dirs.map { |dir| Pathname(dir) }
|
|
55
|
+
unsearched = install_roots.map { |root| root.join("specifications") }.select(&:directory?) - searched
|
|
56
|
+
return refresh_stale_spec_cache if unsearched.empty?
|
|
57
|
+
|
|
58
|
+
Gem::Specification.dirs = (searched + unsearched).map { |dir| dir.parent.to_s }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# The searched dirs are right but the spec cache predates this install:
|
|
62
|
+
# `bundle plugin install` switches GEM_HOME to the plugin root and caches
|
|
63
|
+
# specs during resolution, before gemvault lands there.
|
|
64
|
+
def refresh_stale_spec_cache
|
|
65
|
+
Gem::Specification.find_by_name(GEM)
|
|
66
|
+
rescue Gem::LoadError
|
|
67
|
+
Gem::Specification.reset
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def entries
|
|
71
|
+
spec = gemvault_spec
|
|
72
|
+
return [] unless spec
|
|
73
|
+
|
|
74
|
+
[*dependency_specs(spec).flat_map(&:full_require_paths), *spec.full_require_paths]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Prefer the version the shim was released against, read off the shim's own
|
|
78
|
+
# spec rather than its directory name: that name is a version only for a
|
|
79
|
+
# plain `gem install`, and never for a source tree, a path: plugin, a git
|
|
80
|
+
# plugin or a platform gem. With no spec to read, take the newest gemvault
|
|
81
|
+
# present, which beats whichever the filesystem listed first.
|
|
82
|
+
def gemvault_spec
|
|
83
|
+
candidates = specs_named(GEM).select { |spec| vault_source_in?(spec) }
|
|
84
|
+
pinned = candidates.select { |spec| pinned_requirement.satisfied_by?(spec.version) }
|
|
85
|
+
|
|
86
|
+
(pinned.empty? ? candidates : pinned).max_by(&:version)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def pinned_requirement
|
|
90
|
+
dependency = shim_spec&.dependencies&.find { |dep| dep.name == GEM }
|
|
91
|
+
|
|
92
|
+
dependency&.requirement || Gem::Requirement.default
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def shim_spec
|
|
96
|
+
specs_named(SHIM).find { |spec| spec.full_gem_path == shim_dir.to_s }
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def dependency_specs(spec)
|
|
100
|
+
spec.runtime_dependencies.filter_map do |dependency|
|
|
101
|
+
specs_named(dependency.name)
|
|
102
|
+
.select { |candidate| dependency.requirement.satisfied_by?(candidate.version) }
|
|
103
|
+
.max_by(&:version)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def specs_named(name)
|
|
108
|
+
install_roots
|
|
109
|
+
.flat_map { |root| root.glob("specifications/#{name}-*.gemspec") }
|
|
110
|
+
.filter_map { |file| Gem::Specification.load(file.to_s) }
|
|
111
|
+
.select { |spec| spec.name == name }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def vault_source_in?(spec)
|
|
115
|
+
spec.full_require_paths.any? { |path| Pathname(path).join(VAULT_SOURCE).file? }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Installed, plugins.rb lives at <gem root>/gems/bundler-source-vault-<v>/,
|
|
119
|
+
# and gemvault may sit in the same root: Bundler's local or global plugin
|
|
120
|
+
# root, or a plain GEM_HOME. Both plugin roots count, because
|
|
121
|
+
# Bundler::Plugin.root is the project-local root even when the plugin loads
|
|
122
|
+
# from the global one.
|
|
123
|
+
#
|
|
124
|
+
# Gem.default_path is the load-bearing entry. Bundler skips installing a
|
|
125
|
+
# plugin dependency that is already installed, so wherever `gem install
|
|
126
|
+
# gemvault` has run the plugin root holds the shim alone; once the app bundle
|
|
127
|
+
# is populated Bundler narrows GEM_PATH to it and the ambient gemvault drops
|
|
128
|
+
# out of Gem.path. Gem.default_path is what RubyGems knows about its own gem
|
|
129
|
+
# roots regardless of that narrowing. Reading roots back out of the
|
|
130
|
+
# environment does not cover it -- rubies from rbenv, asdf, chruby, Homebrew
|
|
131
|
+
# and distros export neither GEM_HOME nor GEM_PATH -- but it still matters
|
|
132
|
+
# for the ones that export a root outside those defaults, like RVM.
|
|
133
|
+
def install_roots
|
|
134
|
+
candidate_roots
|
|
135
|
+
.reject { |root| root.to_s.empty? }
|
|
136
|
+
.map { |root| Pathname(root.to_s) }
|
|
137
|
+
.uniq
|
|
138
|
+
.select { |root| root.join("specifications").directory? }
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def candidate_roots
|
|
142
|
+
[shim_dir.parent.parent, *plugin_roots, *Gem.path, *Gem.default_path, *exported_roots]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def plugin_roots
|
|
146
|
+
return [] unless defined?(Bundler::Plugin)
|
|
147
|
+
|
|
148
|
+
[Bundler::Plugin.root, Bundler::Plugin.global_root]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def exported_roots
|
|
152
|
+
return [] unless defined?(Bundler) && Bundler.respond_to?(:original_env)
|
|
153
|
+
|
|
154
|
+
original = Bundler.original_env
|
|
155
|
+
|
|
156
|
+
[original["GEM_HOME"], *original["GEM_PATH"].to_s.split(File::PATH_SEPARATOR)]
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def shim_dir
|
|
160
|
+
Pathname(__dir__)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
data/plugins.rb
CHANGED
|
@@ -1,42 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
# but does not put them on the load path before loading plugins.rb -- see the
|
|
3
|
-
# "Currently not done to avoid conflicts" comment in bundler/plugin.rb. The
|
|
4
|
-
# require below must resolve gemvault through RubyGems itself, so every gem
|
|
5
|
-
# root that may hold gemvault has to be visible to Gem::Specification first.
|
|
6
|
-
#
|
|
7
|
-
# Development: when loaded from within the gemvault source tree, the gemvault
|
|
8
|
-
# gem isn't installed, so its lib/ must be on $LOAD_PATH for the require below.
|
|
9
|
-
gemvault_lib = Pathname(__dir__).parent.join("lib")
|
|
10
|
-
$LOAD_PATH.unshift(gemvault_lib.to_s) if gemvault_lib.directory? && !$LOAD_PATH.include?(gemvault_lib.to_s)
|
|
1
|
+
require_relative "gemvault_load_path"
|
|
11
2
|
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
# also candidates because `Bundler::Plugin.root` is the project-local root even
|
|
16
|
-
# when the plugin actually loads from the global one.
|
|
17
|
-
plugin_roots = defined?(Bundler::Plugin) ? [Bundler::Plugin.root, Bundler::Plugin.global_root] : []
|
|
18
|
-
gem_root = Pathname(__dir__).parent.parent
|
|
19
|
-
candidate_dirs = [gem_root, *plugin_roots]
|
|
20
|
-
.map { |root| Pathname(root.to_s).join("specifications") }
|
|
21
|
-
.uniq
|
|
22
|
-
.select(&:directory?)
|
|
3
|
+
# Runs on every evaluation. Bundler discards the registration while configuring
|
|
4
|
+
# the bundle, so it cannot sit behind the guard below.
|
|
5
|
+
BundlerSourceVault::GemvaultLoadPath.register_spec_dirs
|
|
23
6
|
|
|
24
|
-
|
|
25
|
-
|
|
7
|
+
# Bundler evaluates this file more than once per process: once when it saves a
|
|
8
|
+
# freshly installed plugin, again when the Gemfile asks for the source. Loading
|
|
9
|
+
# gemvault twice from two different roots is fatal rather than merely noisy,
|
|
10
|
+
# because Gemvault::GemEntry subclasses a fresh Data.define result each time, so
|
|
11
|
+
# a second definition raises a superclass mismatch. Resolve and require only on
|
|
12
|
+
# the first evaluation. The registration above and this one below still repeat --
|
|
13
|
+
# Bundler reads the source back out of Plugin::API after each load.
|
|
14
|
+
unless defined?(Bundler::Plugin::VaultSource)
|
|
15
|
+
source_tree_lib = BundlerSourceVault::GemvaultLoadPath.source_tree_lib
|
|
16
|
+
$LOAD_PATH.unshift(source_tree_lib.to_s) if source_tree_lib && !$LOAD_PATH.include?(source_tree_lib.to_s)
|
|
26
17
|
|
|
27
|
-
|
|
28
|
-
Gem::Specification.dirs = (searched_dirs + unsearched_dirs).map { |dir| dir.parent.to_s }
|
|
29
|
-
elsif candidate_dirs.any?
|
|
30
|
-
begin
|
|
31
|
-
Gem::Specification.find_by_name("gemvault")
|
|
32
|
-
rescue Gem::LoadError
|
|
33
|
-
# The searched dirs are right but the spec cache predates this install:
|
|
34
|
-
# `bundle plugin install` switches GEM_HOME to the plugin root and caches
|
|
35
|
-
# specs during resolution, before gemvault lands there.
|
|
36
|
-
Gem::Specification.reset
|
|
37
|
-
end
|
|
38
|
-
end
|
|
18
|
+
BundlerSourceVault::GemvaultLoadPath.apply
|
|
39
19
|
|
|
40
|
-
require "bundler/plugin/vault_source"
|
|
20
|
+
require "bundler/plugin/vault_source"
|
|
21
|
+
end
|
|
41
22
|
|
|
42
23
|
Bundler::Plugin::API.source("vault", Bundler::Plugin::VaultSource)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bundler-source-vault
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Gillis
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.2.
|
|
18
|
+
version: 0.2.2
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.2.
|
|
25
|
+
version: 0.2.2
|
|
26
26
|
description: Registers the :vault source type with Bundler, enabling gem installation
|
|
27
27
|
from .gemv vault files
|
|
28
28
|
email:
|
|
@@ -31,6 +31,7 @@ executables: []
|
|
|
31
31
|
extensions: []
|
|
32
32
|
extra_rdoc_files: []
|
|
33
33
|
files:
|
|
34
|
+
- gemvault_load_path.rb
|
|
34
35
|
- plugins.rb
|
|
35
36
|
homepage: https://github.com/gillisd/gemvault
|
|
36
37
|
licenses:
|
|
@@ -52,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
52
53
|
- !ruby/object:Gem::Version
|
|
53
54
|
version: '0'
|
|
54
55
|
requirements: []
|
|
55
|
-
rubygems_version: 4.0.
|
|
56
|
+
rubygems_version: 4.0.17
|
|
56
57
|
specification_version: 4
|
|
57
58
|
summary: Bundler source plugin for gemvault
|
|
58
59
|
test_files: []
|