gel 0.2.0
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 +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/LICENSE.txt +21 -0
- data/README.md +39 -0
- data/exe/gel +13 -0
- data/lib/gel.rb +22 -0
- data/lib/gel/catalog.rb +153 -0
- data/lib/gel/catalog/common.rb +82 -0
- data/lib/gel/catalog/compact_index.rb +152 -0
- data/lib/gel/catalog/dependency_index.rb +125 -0
- data/lib/gel/catalog/legacy_index.rb +157 -0
- data/lib/gel/catalog/marshal_hacks.rb +16 -0
- data/lib/gel/command.rb +86 -0
- data/lib/gel/command/config.rb +11 -0
- data/lib/gel/command/env.rb +7 -0
- data/lib/gel/command/exec.rb +66 -0
- data/lib/gel/command/help.rb +7 -0
- data/lib/gel/command/install.rb +7 -0
- data/lib/gel/command/install_gem.rb +16 -0
- data/lib/gel/command/lock.rb +34 -0
- data/lib/gel/command/ruby.rb +10 -0
- data/lib/gel/command/shell_setup.rb +25 -0
- data/lib/gel/command/stub.rb +12 -0
- data/lib/gel/command/update.rb +11 -0
- data/lib/gel/compatibility.rb +4 -0
- data/lib/gel/compatibility/bundler.rb +54 -0
- data/lib/gel/compatibility/bundler/cli.rb +6 -0
- data/lib/gel/compatibility/bundler/friendly_errors.rb +3 -0
- data/lib/gel/compatibility/bundler/setup.rb +4 -0
- data/lib/gel/compatibility/rubygems.rb +192 -0
- data/lib/gel/compatibility/rubygems/command.rb +4 -0
- data/lib/gel/compatibility/rubygems/dependency_installer.rb +0 -0
- data/lib/gel/compatibility/rubygems/gem_runner.rb +6 -0
- data/lib/gel/config.rb +80 -0
- data/lib/gel/db.rb +294 -0
- data/lib/gel/direct_gem.rb +29 -0
- data/lib/gel/environment.rb +592 -0
- data/lib/gel/error.rb +104 -0
- data/lib/gel/gemfile_parser.rb +144 -0
- data/lib/gel/gemspec_parser.rb +95 -0
- data/lib/gel/git_catalog.rb +38 -0
- data/lib/gel/git_depot.rb +119 -0
- data/lib/gel/httpool.rb +148 -0
- data/lib/gel/installer.rb +251 -0
- data/lib/gel/lock_loader.rb +164 -0
- data/lib/gel/lock_parser.rb +64 -0
- data/lib/gel/locked_store.rb +126 -0
- data/lib/gel/multi_store.rb +96 -0
- data/lib/gel/package.rb +156 -0
- data/lib/gel/package/inspector.rb +23 -0
- data/lib/gel/package/installer.rb +267 -0
- data/lib/gel/path_catalog.rb +44 -0
- data/lib/gel/pinboard.rb +140 -0
- data/lib/gel/pub_grub/preference_strategy.rb +82 -0
- data/lib/gel/pub_grub/source.rb +153 -0
- data/lib/gel/runtime.rb +27 -0
- data/lib/gel/store.rb +205 -0
- data/lib/gel/store_catalog.rb +31 -0
- data/lib/gel/store_gem.rb +80 -0
- data/lib/gel/stub_set.rb +51 -0
- data/lib/gel/support/gem_platform.rb +225 -0
- data/lib/gel/support/gem_requirement.rb +264 -0
- data/lib/gel/support/gem_version.rb +398 -0
- data/lib/gel/support/tar.rb +13 -0
- data/lib/gel/support/tar/tar_header.rb +229 -0
- data/lib/gel/support/tar/tar_reader.rb +123 -0
- data/lib/gel/support/tar/tar_reader/entry.rb +154 -0
- data/lib/gel/support/tar/tar_writer.rb +339 -0
- data/lib/gel/tail_file.rb +205 -0
- data/lib/gel/version.rb +5 -0
- data/lib/gel/work_pool.rb +143 -0
- data/man/man1/gel-exec.1 +16 -0
- data/man/man1/gel-install.1 +16 -0
- data/man/man1/gel.1 +30 -0
- metadata +131 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "strscan"
|
4
|
+
|
5
|
+
class Gel::LockParser
|
6
|
+
def parse(content)
|
7
|
+
sections = []
|
8
|
+
|
9
|
+
scanner = StringScanner.new(content)
|
10
|
+
while section = scanner.scan(/^(\w.+)\n/)
|
11
|
+
section.chomp!
|
12
|
+
case section
|
13
|
+
when "GIT", "PATH", "GEM"
|
14
|
+
content = {}
|
15
|
+
while scanner.skip(/^ \b/)
|
16
|
+
label = scanner.scan(/[^:]+:/).chop
|
17
|
+
if scanner.skip(/ /)
|
18
|
+
value = scanner.scan(/.*/)
|
19
|
+
scanner.skip(/\n/)
|
20
|
+
(content[label] ||= []) << value
|
21
|
+
else
|
22
|
+
scanner.skip(/\n/)
|
23
|
+
value = []
|
24
|
+
while scanner.skip(/^ \b/)
|
25
|
+
entry = scanner.scan(/.*/)
|
26
|
+
scanner.skip(/\n/)
|
27
|
+
children = []
|
28
|
+
while scanner.skip(/^ \b/)
|
29
|
+
child = scanner.scan(/.*/)
|
30
|
+
children << child
|
31
|
+
scanner.skip(/\n/)
|
32
|
+
end
|
33
|
+
if children.empty?
|
34
|
+
value << [entry]
|
35
|
+
else
|
36
|
+
value << [entry, children]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
content[label] = value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
when "PLATFORMS", "DEPENDENCIES"
|
43
|
+
content = []
|
44
|
+
while scanner.skip(/^ \b/)
|
45
|
+
entry = scanner.scan(/.*/)
|
46
|
+
content << entry
|
47
|
+
scanner.skip(/\n/)
|
48
|
+
end
|
49
|
+
when "BUNDLED WITH"
|
50
|
+
content = []
|
51
|
+
while scanner.skip(/^ \b/)
|
52
|
+
entry = scanner.scan(/.*/)
|
53
|
+
content << entry
|
54
|
+
scanner.skip(/\n/)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
scanner.skip(/\n+/)
|
58
|
+
|
59
|
+
sections << [section, content]
|
60
|
+
end
|
61
|
+
|
62
|
+
sections
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Gel::LockedStore
|
4
|
+
attr_reader :inner
|
5
|
+
|
6
|
+
def initialize(inner)
|
7
|
+
@inner = inner
|
8
|
+
@locked_versions = nil
|
9
|
+
|
10
|
+
@lib_cache = Hash.new { |h, k| h[k] = [] }
|
11
|
+
@full_cache = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def paths
|
15
|
+
@inner.paths
|
16
|
+
end
|
17
|
+
|
18
|
+
def root
|
19
|
+
@inner.root
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
content = @locked_versions.map { |name, version| "#{name}=#{version.is_a?(String) ? version : version.root}" }
|
24
|
+
content = ["(none)"] if content.empty?
|
25
|
+
content.sort!
|
26
|
+
|
27
|
+
"#<#{self.class} inner=#{@inner.inspect} locks=#{content.join(",")}>"
|
28
|
+
end
|
29
|
+
|
30
|
+
def prepare(locks)
|
31
|
+
return if @full_cache
|
32
|
+
|
33
|
+
inner_versions = {}
|
34
|
+
locks.each do |name, version|
|
35
|
+
if version.is_a?(Gel::StoreGem)
|
36
|
+
version.libs do |file, subdir|
|
37
|
+
@lib_cache[file] << [version, subdir]
|
38
|
+
end
|
39
|
+
else
|
40
|
+
inner_versions[name] = version
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
g = @inner.gems(inner_versions)
|
45
|
+
@inner.libs_for_gems(inner_versions) do |name, version, subs|
|
46
|
+
subs.each do |subdir, files|
|
47
|
+
v = [g[name], subdir]
|
48
|
+
files.each do |file|
|
49
|
+
@lib_cache[file] << v
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def lock(locks)
|
56
|
+
@locked_versions = locks.dup
|
57
|
+
prepare(locks)
|
58
|
+
@full_cache = true
|
59
|
+
end
|
60
|
+
|
61
|
+
def locked?(gem)
|
62
|
+
!@locked_versions || @locked_versions[gem.name] == gem.version
|
63
|
+
end
|
64
|
+
|
65
|
+
def locked_gems
|
66
|
+
@locked_versions ? @locked_versions.values.grep(Gel::StoreGem) : []
|
67
|
+
end
|
68
|
+
|
69
|
+
def gem(name, version)
|
70
|
+
if !@locked_versions || @locked_versions[name] == version
|
71
|
+
@inner.gem(name, version)
|
72
|
+
else
|
73
|
+
locked_gems.find { |g| g.name == name && g.version == version }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def gems(name_version_pairs)
|
78
|
+
r = @inner.gems(name_version_pairs)
|
79
|
+
locked_gems.each do |g|
|
80
|
+
r[g.name] = g
|
81
|
+
end
|
82
|
+
r
|
83
|
+
end
|
84
|
+
|
85
|
+
def gems_for_lib(file)
|
86
|
+
if c = @lib_cache.fetch(file, nil)
|
87
|
+
c.each { |gem, subdir| yield gem, subdir }
|
88
|
+
return
|
89
|
+
end
|
90
|
+
|
91
|
+
hits = []
|
92
|
+
unless @full_cache
|
93
|
+
@inner.gems_for_lib(file) do |gem, subdir|
|
94
|
+
if locked?(gem)
|
95
|
+
hits << [gem, subdir]
|
96
|
+
yield gem, subdir
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
locked_gems.each do |gem|
|
102
|
+
if File.exist?(gem.path(file) + ".rb")
|
103
|
+
hits << [gem, nil]
|
104
|
+
yield gem, nil
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
@lib_cache[file] = hits
|
109
|
+
end
|
110
|
+
|
111
|
+
def each(gem_name = nil)
|
112
|
+
return enum_for(__callee__, gem_name) unless block_given?
|
113
|
+
|
114
|
+
list = locked_gems
|
115
|
+
|
116
|
+
@inner.each(gem_name) do |gem|
|
117
|
+
next unless locked?(gem)
|
118
|
+
yield gem
|
119
|
+
list.delete gem
|
120
|
+
end
|
121
|
+
|
122
|
+
list.each do |gem|
|
123
|
+
yield gem if !gem_name || gem.name == gem_name
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rbconfig"
|
4
|
+
require_relative "stub_set"
|
5
|
+
|
6
|
+
class Gel::MultiStore
|
7
|
+
VERSION = "#{RbConfig::CONFIG["ruby_version"]}"
|
8
|
+
|
9
|
+
attr_reader :root
|
10
|
+
attr_reader :monitor
|
11
|
+
|
12
|
+
def initialize(root, stores)
|
13
|
+
@root = File.realpath(File.expand_path(root)) if root
|
14
|
+
@stores = stores
|
15
|
+
|
16
|
+
@monitor = Monitor.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def stub_set
|
20
|
+
@stub_set ||= Gel::StubSet.new(@root)
|
21
|
+
end
|
22
|
+
|
23
|
+
def paths
|
24
|
+
@stores.values.flat_map(&:paths).uniq
|
25
|
+
end
|
26
|
+
|
27
|
+
def [](architecture, version = false)
|
28
|
+
@stores[self.class.subkey(architecture, version)]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.subkey(architecture, version)
|
32
|
+
architecture ||= "ruby"
|
33
|
+
if version && architecture == "ruby"
|
34
|
+
VERSION
|
35
|
+
elsif version
|
36
|
+
"#{architecture}-#{VERSION}"
|
37
|
+
else
|
38
|
+
"#{architecture}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def prepare(versions)
|
43
|
+
@stores.each do |_, store|
|
44
|
+
store.prepare(versions)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def gems_for_lib(file)
|
49
|
+
@stores.each do |_, store|
|
50
|
+
store.gems_for_lib(file) do |gem, subdir|
|
51
|
+
yield gem, subdir
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def each(gem_name = nil, &block)
|
57
|
+
return enum_for(__callee__, gem_name) unless block_given?
|
58
|
+
|
59
|
+
@stores.each do |_, store|
|
60
|
+
store.each(gem_name, &block)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def gem(name, version)
|
65
|
+
@stores.each do |_, store|
|
66
|
+
g = store.gem(name, version)
|
67
|
+
return g if g
|
68
|
+
end
|
69
|
+
nil
|
70
|
+
end
|
71
|
+
|
72
|
+
def gems(name_version_pairs)
|
73
|
+
result = {}
|
74
|
+
|
75
|
+
@stores.each do |_, store|
|
76
|
+
result.update(store.gems(name_version_pairs)) do |l, r|
|
77
|
+
l
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
result
|
82
|
+
end
|
83
|
+
|
84
|
+
def gem?(name, version, platform = nil)
|
85
|
+
@stores.any? do |key, store|
|
86
|
+
next if platform && !key.start_with?(platform)
|
87
|
+
store.gem?(name, version)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def libs_for_gems(versions, &block)
|
92
|
+
@stores.each do |_, store|
|
93
|
+
store.libs_for_gems(versions, &block)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/gel/package.rb
ADDED
@@ -0,0 +1,156 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "zlib"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
require_relative "support/tar"
|
7
|
+
|
8
|
+
module Gel
|
9
|
+
class Package
|
10
|
+
class Specification
|
11
|
+
def initialize(inner)
|
12
|
+
@inner = inner
|
13
|
+
end
|
14
|
+
|
15
|
+
def name
|
16
|
+
@inner.name
|
17
|
+
end
|
18
|
+
|
19
|
+
def version
|
20
|
+
@inner.version
|
21
|
+
end
|
22
|
+
|
23
|
+
def architecture
|
24
|
+
@inner.architecture
|
25
|
+
end
|
26
|
+
|
27
|
+
def bindir
|
28
|
+
@inner.bindir
|
29
|
+
end
|
30
|
+
|
31
|
+
def executables
|
32
|
+
@inner.executables
|
33
|
+
end
|
34
|
+
|
35
|
+
def require_paths
|
36
|
+
@inner.require_paths
|
37
|
+
end
|
38
|
+
|
39
|
+
def extensions
|
40
|
+
@inner.extensions
|
41
|
+
end
|
42
|
+
|
43
|
+
def runtime_dependencies
|
44
|
+
h = {}
|
45
|
+
@inner.dependencies.each do |dep|
|
46
|
+
next unless dep.type == :runtime || dep.type.nil?
|
47
|
+
req = dep.requirement || dep.version_requirements
|
48
|
+
h[dep.name] = req.requirements.map { |pair| pair.map(&:to_s) }
|
49
|
+
end
|
50
|
+
h
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class YAMLLoader < ::YAML::ClassLoader::Restricted
|
55
|
+
#--
|
56
|
+
# Based on YAML.safe_load
|
57
|
+
def self.load(yaml, filename)
|
58
|
+
result = if Psych::VERSION < "3.1" # Ruby 2.5 & below
|
59
|
+
::YAML.parse(yaml, filename)
|
60
|
+
else
|
61
|
+
::YAML.parse(yaml, filename: filename)
|
62
|
+
end
|
63
|
+
return unless result
|
64
|
+
|
65
|
+
class_loader = self.new
|
66
|
+
scanner = ::YAML::ScalarScanner.new class_loader
|
67
|
+
|
68
|
+
visitor = ::YAML::Visitors::ToRuby.new scanner, class_loader
|
69
|
+
visitor.accept result
|
70
|
+
end
|
71
|
+
|
72
|
+
def initialize
|
73
|
+
super(%w(Symbol Time), [])
|
74
|
+
end
|
75
|
+
|
76
|
+
def find(klass)
|
77
|
+
case klass
|
78
|
+
when "Gem::Specification"
|
79
|
+
Gem_Specification
|
80
|
+
when "Gem::Version"
|
81
|
+
Gem_Version
|
82
|
+
when "Gem::Version::Requirement", "Gem::Requirement"
|
83
|
+
Gem_Requirement
|
84
|
+
when "Gem::Platform"
|
85
|
+
Gem_Platform
|
86
|
+
when "Gem::Dependency"
|
87
|
+
Gem_Dependency
|
88
|
+
else
|
89
|
+
super
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class Gem_Specification
|
94
|
+
attr_accessor :architecture, :bindir, :executables, :name, :require_paths, :specification_version, :version, :dependencies, :extensions
|
95
|
+
end
|
96
|
+
class Gem_Dependency
|
97
|
+
attr_accessor :name, :requirement, :type, :version_requirements
|
98
|
+
end
|
99
|
+
class Gem_Platform; end
|
100
|
+
Gem_Version = Gel::Support::GemVersion
|
101
|
+
class Gem_Requirement
|
102
|
+
attr_accessor :requirements
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.with_file(reader, filename, checksums)
|
107
|
+
reader.seek(filename) do |stream|
|
108
|
+
if checksums
|
109
|
+
data = stream.read
|
110
|
+
stream.rewind
|
111
|
+
|
112
|
+
checksums.each do |type, map|
|
113
|
+
next unless %w(SHA1 SHA512).include?(type)
|
114
|
+
calculated = Digest(type).hexdigest(data)
|
115
|
+
raise "#{type} checksum mismatch on #{filename}" unless calculated == map[filename]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
yield stream
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.extract(filename, receiver)
|
124
|
+
File.open(filename) do |io|
|
125
|
+
Gel::Support::Tar::TarReader.new(io) do |package_reader|
|
126
|
+
sums = with_file(package_reader, "checksums.yaml.gz", nil) do |sum_stream|
|
127
|
+
yaml = Zlib::GzipReader.new(sum_stream).read
|
128
|
+
|
129
|
+
if Psych::VERSION < "3.1" # Ruby 2.5 & below
|
130
|
+
::YAML.safe_load(yaml, [], [], false, "#{filename}:checksums.yaml.gz")
|
131
|
+
else
|
132
|
+
::YAML.safe_load(yaml, filename: "#{filename}:checksums.yaml.gz")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
spec = with_file(package_reader, "metadata.gz", sums) do |meta_stream|
|
137
|
+
yaml = Zlib::GzipReader.new(meta_stream).read
|
138
|
+
loaded = YAMLLoader.load(yaml, "#{filename}:metadata.gz")
|
139
|
+
Specification.new(loaded)
|
140
|
+
end or raise "no metadata.gz"
|
141
|
+
|
142
|
+
return receiver.gem(spec) do |target|
|
143
|
+
with_file(package_reader, "data.tar.gz", sums) do |data_stream|
|
144
|
+
Gel::Support::Tar::TarReader.new(Zlib::GzipReader.new(data_stream)) do |data_reader|
|
145
|
+
data_reader.each do |entry|
|
146
|
+
target.file(entry.full_name, entry, entry.header.mode)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
true
|
150
|
+
end or raise "no data.tar.gz"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gel
|
4
|
+
class Package
|
5
|
+
class Inspector
|
6
|
+
def initialize(&block)
|
7
|
+
@block = block
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :spec
|
11
|
+
|
12
|
+
def gem(spec)
|
13
|
+
@spec = spec
|
14
|
+
|
15
|
+
yield self if @block
|
16
|
+
end
|
17
|
+
|
18
|
+
def file(filename, io, _mode)
|
19
|
+
@block.call filename, io
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|