scint 0.1.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/FEATURES.md +13 -0
- data/README.md +216 -0
- data/bin/bundler-vs-scint +233 -0
- data/bin/scint +35 -0
- data/bin/scint-io-summary +46 -0
- data/bin/scint-syscall-trace +41 -0
- data/lib/bundler/setup.rb +5 -0
- data/lib/bundler.rb +168 -0
- data/lib/scint/cache/layout.rb +131 -0
- data/lib/scint/cache/metadata_store.rb +75 -0
- data/lib/scint/cache/prewarm.rb +192 -0
- data/lib/scint/cli/add.rb +85 -0
- data/lib/scint/cli/cache.rb +316 -0
- data/lib/scint/cli/exec.rb +150 -0
- data/lib/scint/cli/install.rb +1047 -0
- data/lib/scint/cli/remove.rb +60 -0
- data/lib/scint/cli.rb +77 -0
- data/lib/scint/commands/exec.rb +17 -0
- data/lib/scint/commands/install.rb +17 -0
- data/lib/scint/credentials.rb +153 -0
- data/lib/scint/debug/io_trace.rb +218 -0
- data/lib/scint/debug/sampler.rb +138 -0
- data/lib/scint/downloader/fetcher.rb +113 -0
- data/lib/scint/downloader/pool.rb +112 -0
- data/lib/scint/errors.rb +63 -0
- data/lib/scint/fs.rb +119 -0
- data/lib/scint/gem/extractor.rb +86 -0
- data/lib/scint/gem/package.rb +62 -0
- data/lib/scint/gemfile/dependency.rb +30 -0
- data/lib/scint/gemfile/editor.rb +93 -0
- data/lib/scint/gemfile/parser.rb +275 -0
- data/lib/scint/index/cache.rb +166 -0
- data/lib/scint/index/client.rb +301 -0
- data/lib/scint/index/parser.rb +142 -0
- data/lib/scint/installer/extension_builder.rb +264 -0
- data/lib/scint/installer/linker.rb +226 -0
- data/lib/scint/installer/planner.rb +140 -0
- data/lib/scint/installer/preparer.rb +207 -0
- data/lib/scint/lockfile/parser.rb +251 -0
- data/lib/scint/lockfile/writer.rb +178 -0
- data/lib/scint/platform.rb +71 -0
- data/lib/scint/progress.rb +579 -0
- data/lib/scint/resolver/provider.rb +230 -0
- data/lib/scint/resolver/resolver.rb +249 -0
- data/lib/scint/runtime/exec.rb +141 -0
- data/lib/scint/runtime/setup.rb +45 -0
- data/lib/scint/scheduler.rb +392 -0
- data/lib/scint/source/base.rb +46 -0
- data/lib/scint/source/git.rb +92 -0
- data/lib/scint/source/path.rb +70 -0
- data/lib/scint/source/rubygems.rb +79 -0
- data/lib/scint/vendor/pub_grub/assignment.rb +20 -0
- data/lib/scint/vendor/pub_grub/basic_package_source.rb +169 -0
- data/lib/scint/vendor/pub_grub/failure_writer.rb +182 -0
- data/lib/scint/vendor/pub_grub/incompatibility.rb +150 -0
- data/lib/scint/vendor/pub_grub/package.rb +43 -0
- data/lib/scint/vendor/pub_grub/partial_solution.rb +121 -0
- data/lib/scint/vendor/pub_grub/rubygems.rb +45 -0
- data/lib/scint/vendor/pub_grub/solve_failure.rb +19 -0
- data/lib/scint/vendor/pub_grub/static_package_source.rb +61 -0
- data/lib/scint/vendor/pub_grub/strategy.rb +42 -0
- data/lib/scint/vendor/pub_grub/term.rb +105 -0
- data/lib/scint/vendor/pub_grub/version.rb +3 -0
- data/lib/scint/vendor/pub_grub/version_constraint.rb +129 -0
- data/lib/scint/vendor/pub_grub/version_range.rb +423 -0
- data/lib/scint/vendor/pub_grub/version_solver.rb +236 -0
- data/lib/scint/vendor/pub_grub/version_union.rb +178 -0
- data/lib/scint/vendor/pub_grub.rb +32 -0
- data/lib/scint/worker_pool.rb +114 -0
- data/lib/scint.rb +87 -0
- metadata +116 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../source/rubygems"
|
|
4
|
+
require_relative "../source/git"
|
|
5
|
+
require_relative "../source/path"
|
|
6
|
+
|
|
7
|
+
module Scint
|
|
8
|
+
module Lockfile
|
|
9
|
+
# Data returned by the lockfile parser.
|
|
10
|
+
LockfileData = Struct.new(
|
|
11
|
+
:specs, :dependencies, :platforms, :sources,
|
|
12
|
+
:bundler_version, :ruby_version, :checksums,
|
|
13
|
+
keyword_init: true,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
# Parses a standard Gemfile.lock file into structured data.
|
|
17
|
+
# Compatible with the format produced by stock bundler.
|
|
18
|
+
class Parser
|
|
19
|
+
BUNDLED = "BUNDLED WITH"
|
|
20
|
+
DEPENDENCIES = "DEPENDENCIES"
|
|
21
|
+
CHECKSUMS = "CHECKSUMS"
|
|
22
|
+
PLATFORMS = "PLATFORMS"
|
|
23
|
+
RUBY = "RUBY VERSION"
|
|
24
|
+
GIT = "GIT"
|
|
25
|
+
GEM = "GEM"
|
|
26
|
+
PATH = "PATH"
|
|
27
|
+
SPECS = " specs:"
|
|
28
|
+
|
|
29
|
+
OPTIONS = /^ ([a-z]+): (.*)$/i
|
|
30
|
+
SOURCE_TYPES = [GIT, GEM, PATH].freeze
|
|
31
|
+
|
|
32
|
+
# Regex for spec/dependency lines:
|
|
33
|
+
# 2 spaces = dependency, 4 spaces = spec, 6 spaces = spec dependency
|
|
34
|
+
NAME_VERSION = /
|
|
35
|
+
^(\s{2}|\s{4}|\s{6})(?!\s) # exactly 2, 4, or 6 leading spaces
|
|
36
|
+
(.*?) # name
|
|
37
|
+
(?:\s\(([^-]*) # version in parens
|
|
38
|
+
(?:-(.*))?\))? # optional platform after dash
|
|
39
|
+
(!)? # optional pinned marker
|
|
40
|
+
(?:\s([^\s]+))? # optional checksum
|
|
41
|
+
$
|
|
42
|
+
/x
|
|
43
|
+
|
|
44
|
+
# Accepts either lockfile contents or a file path.
|
|
45
|
+
def self.parse(lockfile_or_contents)
|
|
46
|
+
contents =
|
|
47
|
+
if lockfile_or_contents.is_a?(String) && File.exist?(lockfile_or_contents)
|
|
48
|
+
File.read(lockfile_or_contents)
|
|
49
|
+
else
|
|
50
|
+
lockfile_or_contents.to_s
|
|
51
|
+
end
|
|
52
|
+
new(contents).parse
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def initialize(lockfile_contents)
|
|
56
|
+
@contents = lockfile_contents
|
|
57
|
+
@specs = []
|
|
58
|
+
@dependencies = {}
|
|
59
|
+
@platforms = []
|
|
60
|
+
@sources = []
|
|
61
|
+
@bundler_version = nil
|
|
62
|
+
@ruby_version = nil
|
|
63
|
+
@checksums = nil
|
|
64
|
+
|
|
65
|
+
@parse_method = nil
|
|
66
|
+
@current_source = nil
|
|
67
|
+
@current_spec = nil
|
|
68
|
+
@source_type = nil
|
|
69
|
+
@source_opts = {}
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def parse
|
|
73
|
+
if @contents.match?(/(<<<<<<<|=======|>>>>>>>|\|\|\|\|\|\|\|)/)
|
|
74
|
+
raise LockfileError, "Lockfile contains merge conflicts"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
@contents.each_line do |line|
|
|
78
|
+
line.chomp!
|
|
79
|
+
|
|
80
|
+
# Blank lines reset nothing; skip them
|
|
81
|
+
next if line.strip.empty?
|
|
82
|
+
|
|
83
|
+
if SOURCE_TYPES.include?(line)
|
|
84
|
+
@parse_method = :parse_source
|
|
85
|
+
@source_type = line
|
|
86
|
+
@source_opts = {}
|
|
87
|
+
@current_source = nil
|
|
88
|
+
next
|
|
89
|
+
elsif line == DEPENDENCIES
|
|
90
|
+
@parse_method = :parse_dependency
|
|
91
|
+
next
|
|
92
|
+
elsif line == CHECKSUMS
|
|
93
|
+
@checksums = {}
|
|
94
|
+
@parse_method = :parse_checksum
|
|
95
|
+
next
|
|
96
|
+
elsif line == PLATFORMS
|
|
97
|
+
@parse_method = :parse_platform
|
|
98
|
+
next
|
|
99
|
+
elsif line == RUBY
|
|
100
|
+
@parse_method = :parse_ruby
|
|
101
|
+
next
|
|
102
|
+
elsif line == BUNDLED
|
|
103
|
+
@parse_method = :parse_bundled_with
|
|
104
|
+
next
|
|
105
|
+
elsif line =~ /^[^\s]/
|
|
106
|
+
# Unknown section header
|
|
107
|
+
@parse_method = nil
|
|
108
|
+
next
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
next unless @parse_method
|
|
112
|
+
|
|
113
|
+
case @parse_method
|
|
114
|
+
when :parse_source then parse_source(line)
|
|
115
|
+
when :parse_dependency then parse_dependency(line)
|
|
116
|
+
when :parse_checksum then parse_checksum(line)
|
|
117
|
+
when :parse_platform then parse_platform(line)
|
|
118
|
+
when :parse_ruby then parse_ruby(line)
|
|
119
|
+
when :parse_bundled_with then parse_bundled_with(line)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
LockfileData.new(
|
|
124
|
+
specs: @specs,
|
|
125
|
+
dependencies: @dependencies,
|
|
126
|
+
platforms: @platforms,
|
|
127
|
+
sources: @sources,
|
|
128
|
+
bundler_version: @bundler_version,
|
|
129
|
+
ruby_version: @ruby_version,
|
|
130
|
+
checksums: @checksums,
|
|
131
|
+
)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
private
|
|
135
|
+
|
|
136
|
+
def parse_source(line)
|
|
137
|
+
case line
|
|
138
|
+
when SPECS
|
|
139
|
+
@current_source = build_source(@source_type, @source_opts)
|
|
140
|
+
@sources << @current_source if @current_source
|
|
141
|
+
when OPTIONS
|
|
142
|
+
key = $1
|
|
143
|
+
value = $2
|
|
144
|
+
value = true if value == "true"
|
|
145
|
+
value = false if value == "false"
|
|
146
|
+
|
|
147
|
+
if @source_opts[key]
|
|
148
|
+
@source_opts[key] = Array(@source_opts[key])
|
|
149
|
+
@source_opts[key] << value
|
|
150
|
+
else
|
|
151
|
+
@source_opts[key] = value
|
|
152
|
+
end
|
|
153
|
+
else
|
|
154
|
+
parse_spec(line)
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def parse_spec(line)
|
|
159
|
+
return unless line =~ NAME_VERSION
|
|
160
|
+
spaces = $1
|
|
161
|
+
name = $2.freeze
|
|
162
|
+
version = $3
|
|
163
|
+
platform = $4
|
|
164
|
+
|
|
165
|
+
if spaces.length == 4
|
|
166
|
+
# This is a spec line (top-level spec under a source)
|
|
167
|
+
spec = {
|
|
168
|
+
name: name,
|
|
169
|
+
version: version,
|
|
170
|
+
platform: platform || "ruby",
|
|
171
|
+
dependencies: [],
|
|
172
|
+
source: @current_source,
|
|
173
|
+
checksum: nil,
|
|
174
|
+
}
|
|
175
|
+
@specs << spec
|
|
176
|
+
@current_spec = spec
|
|
177
|
+
elsif spaces.length == 6 && @current_spec
|
|
178
|
+
# This is a dependency of the current spec
|
|
179
|
+
dep_versions = version ? version.split(",").map(&:strip) : [">= 0"]
|
|
180
|
+
@current_spec[:dependencies] << { name: name, version_reqs: dep_versions }
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def parse_dependency(line)
|
|
185
|
+
return unless line =~ NAME_VERSION
|
|
186
|
+
spaces = $1
|
|
187
|
+
return unless spaces.length == 2
|
|
188
|
+
|
|
189
|
+
name = $2.freeze
|
|
190
|
+
version = $3
|
|
191
|
+
pinned = $5
|
|
192
|
+
|
|
193
|
+
version_reqs = version ? version.split(",").map(&:strip) : [">= 0"]
|
|
194
|
+
|
|
195
|
+
@dependencies[name] = {
|
|
196
|
+
name: name,
|
|
197
|
+
version_reqs: version_reqs,
|
|
198
|
+
pinned: pinned == "!",
|
|
199
|
+
}
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def parse_checksum(line)
|
|
203
|
+
return unless line =~ NAME_VERSION
|
|
204
|
+
spaces = $1
|
|
205
|
+
return unless spaces.length == 2
|
|
206
|
+
|
|
207
|
+
name = $2
|
|
208
|
+
version = $3
|
|
209
|
+
platform = $4 || "ruby"
|
|
210
|
+
checksums_str = $6
|
|
211
|
+
|
|
212
|
+
key = platform == "ruby" ? "#{name}-#{version}" : "#{name}-#{version}-#{platform}"
|
|
213
|
+
|
|
214
|
+
if checksums_str
|
|
215
|
+
@checksums[key] = checksums_str.split(",").map(&:strip)
|
|
216
|
+
else
|
|
217
|
+
@checksums[key] = []
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def parse_platform(line)
|
|
222
|
+
stripped = line.strip
|
|
223
|
+
return if stripped.empty?
|
|
224
|
+
@platforms << stripped
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def parse_ruby(line)
|
|
228
|
+
stripped = line.strip
|
|
229
|
+
return if stripped.empty?
|
|
230
|
+
@ruby_version = stripped
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def parse_bundled_with(line)
|
|
234
|
+
stripped = line.strip
|
|
235
|
+
return if stripped.empty?
|
|
236
|
+
@bundler_version = stripped
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def build_source(type, opts)
|
|
240
|
+
case type
|
|
241
|
+
when GEM
|
|
242
|
+
Source::Rubygems.from_lock(opts.dup)
|
|
243
|
+
when GIT
|
|
244
|
+
Source::Git.from_lock(opts.dup)
|
|
245
|
+
when PATH
|
|
246
|
+
Source::Path.from_lock(opts.dup)
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Scint
|
|
4
|
+
module Lockfile
|
|
5
|
+
# Writes a standard Gemfile.lock file from structured data.
|
|
6
|
+
# Produces output compatible with stock bundler.
|
|
7
|
+
#
|
|
8
|
+
# Sections in order: source blocks (GEM/GIT/PATH), PLATFORMS,
|
|
9
|
+
# DEPENDENCIES, CHECKSUMS (if present), RUBY VERSION, BUNDLED WITH.
|
|
10
|
+
class Writer
|
|
11
|
+
def self.write(lockfile_data)
|
|
12
|
+
new(lockfile_data).generate
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def initialize(lockfile_data)
|
|
16
|
+
@data = lockfile_data
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def generate
|
|
20
|
+
out = String.new
|
|
21
|
+
|
|
22
|
+
add_sources(out)
|
|
23
|
+
add_platforms(out)
|
|
24
|
+
add_dependencies(out)
|
|
25
|
+
add_checksums(out)
|
|
26
|
+
add_ruby_version(out)
|
|
27
|
+
add_bundled_with(out)
|
|
28
|
+
|
|
29
|
+
out
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def add_sources(out)
|
|
35
|
+
# Group specs by source, preserving source order.
|
|
36
|
+
# Specs store source as a URI string; sources are Source objects.
|
|
37
|
+
# Match by checking if the spec's source URI matches any remote.
|
|
38
|
+
specs_by_source = {}
|
|
39
|
+
@data.sources.each { |s| specs_by_source[s] = [] }
|
|
40
|
+
|
|
41
|
+
@data.specs.each do |spec|
|
|
42
|
+
spec_src = spec.is_a?(Hash) ? spec[:source] : spec.source
|
|
43
|
+
spec_uri = normalize_source_uri(spec_src)
|
|
44
|
+
|
|
45
|
+
matched = @data.sources.find do |source|
|
|
46
|
+
if source.respond_to?(:remotes)
|
|
47
|
+
source.remotes.any? { |r| normalize_source_uri(r) == spec_uri }
|
|
48
|
+
elsif source.respond_to?(:uri)
|
|
49
|
+
normalize_source_uri(source.uri) == spec_uri
|
|
50
|
+
else
|
|
51
|
+
source == spec_src
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
target = matched || @data.sources.first
|
|
56
|
+
specs_by_source[target] ||= []
|
|
57
|
+
specs_by_source[target] << spec
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
first = true
|
|
61
|
+
@data.sources.each do |source|
|
|
62
|
+
out << "\n" unless first
|
|
63
|
+
first = false
|
|
64
|
+
|
|
65
|
+
out << source.to_lock
|
|
66
|
+
add_specs(out, specs_by_source[source] || [])
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def normalize_source_uri(uri)
|
|
71
|
+
s = uri.to_s.chomp("/")
|
|
72
|
+
s.sub(%r{^https?://}, "").downcase
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def add_specs(out, specs)
|
|
76
|
+
# Sort by full name (name-version-platform) for consistency
|
|
77
|
+
sorted = specs.sort_by do |s|
|
|
78
|
+
if s.is_a?(Hash)
|
|
79
|
+
n = s[:name]
|
|
80
|
+
v = s[:version]
|
|
81
|
+
p = s[:platform]
|
|
82
|
+
p == "ruby" ? "#{n}-#{v}" : "#{n}-#{v}-#{p}"
|
|
83
|
+
else
|
|
84
|
+
"#{s.name}-#{s.version}#{"-#{s.platform}" if s.platform != "ruby"}"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
sorted.each do |spec|
|
|
89
|
+
name, version, platform, deps = if spec.is_a?(Hash)
|
|
90
|
+
[spec[:name], spec[:version], spec[:platform], spec[:dependencies] || []]
|
|
91
|
+
else
|
|
92
|
+
[spec.name, spec.version, spec.platform, spec.dependencies || []]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Format: " name (version)" or " name (version-platform)"
|
|
96
|
+
version_str = platform && platform != "ruby" ? "#{version}-#{platform}" : version.to_s
|
|
97
|
+
out << " #{name} (#{version_str})\n"
|
|
98
|
+
|
|
99
|
+
# Dependencies of this spec (6-space indent)
|
|
100
|
+
dep_list = deps.sort_by { |d| d.is_a?(Hash) ? d[:name] : d.name }
|
|
101
|
+
dep_list.each do |dep|
|
|
102
|
+
dep_name, dep_reqs = if dep.is_a?(Hash)
|
|
103
|
+
[dep[:name], dep[:version_reqs]]
|
|
104
|
+
else
|
|
105
|
+
[dep.name, dep.version_reqs]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
if dep_reqs && dep_reqs != [">= 0"]
|
|
109
|
+
out << " #{dep_name} (#{Array(dep_reqs).join(", ")})\n"
|
|
110
|
+
else
|
|
111
|
+
out << " #{dep_name}\n"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def add_platforms(out)
|
|
118
|
+
return if @data.platforms.empty?
|
|
119
|
+
out << "\nPLATFORMS\n"
|
|
120
|
+
@data.platforms.sort.each do |p|
|
|
121
|
+
out << " #{p}\n"
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def add_dependencies(out)
|
|
126
|
+
return if @data.dependencies.empty?
|
|
127
|
+
out << "\nDEPENDENCIES\n"
|
|
128
|
+
|
|
129
|
+
deps = @data.dependencies
|
|
130
|
+
dep_list = if deps.is_a?(Hash)
|
|
131
|
+
deps.values
|
|
132
|
+
else
|
|
133
|
+
deps
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
dep_list.sort_by { |d| d.is_a?(Hash) ? d[:name] : d.name }.each do |dep|
|
|
137
|
+
name, reqs, pinned = if dep.is_a?(Hash)
|
|
138
|
+
[dep[:name], dep[:version_reqs], dep[:pinned]]
|
|
139
|
+
else
|
|
140
|
+
[dep.name, dep.version_reqs, dep.pinned]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
out << " #{name}"
|
|
144
|
+
if reqs && reqs != [">= 0"]
|
|
145
|
+
out << " (#{Array(reqs).join(", ")})"
|
|
146
|
+
end
|
|
147
|
+
out << "!" if pinned
|
|
148
|
+
out << "\n"
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def add_checksums(out)
|
|
153
|
+
return unless @data.checksums
|
|
154
|
+
out << "\nCHECKSUMS\n"
|
|
155
|
+
|
|
156
|
+
@data.checksums.sort.each do |key, values|
|
|
157
|
+
if values && !values.empty?
|
|
158
|
+
out << " #{key} #{values.join(",")}\n"
|
|
159
|
+
else
|
|
160
|
+
out << " #{key}\n"
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def add_ruby_version(out)
|
|
166
|
+
return unless @data.ruby_version
|
|
167
|
+
out << "\nRUBY VERSION\n"
|
|
168
|
+
out << " #{@data.ruby_version}\n"
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def add_bundled_with(out)
|
|
172
|
+
return unless @data.bundler_version
|
|
173
|
+
out << "\nBUNDLED WITH\n"
|
|
174
|
+
out << " #{@data.bundler_version}\n"
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "etc"
|
|
4
|
+
require "rbconfig"
|
|
5
|
+
|
|
6
|
+
module Scint
|
|
7
|
+
module Platform
|
|
8
|
+
module_function
|
|
9
|
+
|
|
10
|
+
def cpu_count
|
|
11
|
+
@cpu_count ||= Etc.nprocessors
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def abi_key
|
|
15
|
+
@abi_key ||= begin
|
|
16
|
+
engine = RUBY_ENGINE # "ruby", "jruby", etc.
|
|
17
|
+
version = RUBY_VERSION # "3.3.0"
|
|
18
|
+
arch = RbConfig::CONFIG["arch"] # "arm64-darwin24"
|
|
19
|
+
"#{engine}-#{version}-#{arch}"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def local_platform
|
|
24
|
+
@local_platform ||= ::Gem::Platform.local
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def match_platform?(spec_platform)
|
|
28
|
+
return true if spec_platform.nil?
|
|
29
|
+
return true if spec_platform == "ruby"
|
|
30
|
+
|
|
31
|
+
spec_plat = spec_platform.is_a?(::Gem::Platform) ? spec_platform : ::Gem::Platform.new(spec_platform)
|
|
32
|
+
spec_plat === local_platform
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def ruby_engine
|
|
36
|
+
RUBY_ENGINE
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def ruby_version
|
|
40
|
+
RUBY_VERSION
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def extension_api_version
|
|
44
|
+
::Gem.extension_api_version
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def arch
|
|
48
|
+
RbConfig::CONFIG["arch"]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def gem_arch
|
|
52
|
+
local_platform.to_s
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def os
|
|
56
|
+
RbConfig::CONFIG["host_os"]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def windows?
|
|
60
|
+
!!(os =~ /mswin|mingw|cygwin/)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def macos?
|
|
64
|
+
!!(os =~ /darwin/)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def linux?
|
|
68
|
+
!!(os =~ /linux/)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|