scint 0.7.0 → 0.8.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.
@@ -1,9 +1,28 @@
1
1
  # frozen_string_literal: true
2
+ require "open3"
3
+ require "rbconfig"
2
4
 
3
5
  module Scint
4
6
  module SpecUtils
5
7
  module_function
6
8
 
9
+ GEMSPEC_LOAD_MUTEX = Thread::Mutex.new
10
+
11
+ GEMSPEC_SUBPROCESS_LOADER = <<~'RUBY'
12
+ path = ARGV.fetch(0)
13
+ begin
14
+ Dir.chdir(File.dirname(path)) do
15
+ spec = Gem::Specification.load(path)
16
+ exit(2) unless spec
17
+ STDOUT.binmode
18
+ STDOUT.write(Marshal.dump(spec))
19
+ end
20
+ rescue Exception => e
21
+ warn("#{e.class}: #{e.message}")
22
+ exit(1)
23
+ end
24
+ RUBY
25
+
7
26
  def name(spec)
8
27
  spec.respond_to?(:name) ? spec.name : spec[:name]
9
28
  end
@@ -54,5 +73,65 @@ module Scint
54
73
  def full_key_for(name, version, platform = "ruby")
55
74
  "#{name}-#{version}-#{platform_value(platform)}"
56
75
  end
76
+
77
+ # Load a gemspec with path-sensitive fallback.
78
+ #
79
+ # Some gemspecs depend on process cwd (e.g. `require "./lib/..."`,
80
+ # `File.read("README")`). A direct load can fail when evaluated from a
81
+ # different working directory. For those failures, evaluate in a dedicated
82
+ # subprocess that can safely chdir without affecting install worker threads.
83
+ def load_gemspec(path, isolate: false)
84
+ absolute = File.expand_path(path.to_s)
85
+ return nil unless File.file?(absolute)
86
+ return load_gemspec_in_subprocess(absolute) if isolate
87
+
88
+ spec = load_gemspec_direct(absolute)
89
+ return spec if spec
90
+
91
+ load_gemspec_in_subprocess(absolute)
92
+ rescue StandardError, ScriptError => e
93
+ return load_gemspec_in_subprocess(absolute) if gemspec_path_context_error?(e)
94
+
95
+ nil
96
+ end
97
+
98
+ def gemspec_path_context_error?(error)
99
+ return true if error.is_a?(LoadError)
100
+ return true if error.is_a?(Errno::ENOENT)
101
+
102
+ message = error.message.to_s
103
+ message.include?("conflicting chdir during another chdir block") ||
104
+ message.include?("cannot load such file -- ./") ||
105
+ message.include?("cannot load such file -- ../")
106
+ end
107
+ private_class_method :gemspec_path_context_error?
108
+
109
+ def load_gemspec_direct(absolute_path)
110
+ GEMSPEC_LOAD_MUTEX.synchronize do
111
+ old_stderr = $stderr
112
+ $stderr = StringIO.new
113
+ ::Gem::Specification.load(absolute_path)
114
+ ensure
115
+ $stderr = old_stderr
116
+ end
117
+ end
118
+ private_class_method :load_gemspec_direct
119
+
120
+ def load_gemspec_in_subprocess(absolute_path)
121
+ out, _err, status = Open3.capture3(
122
+ RbConfig.ruby,
123
+ "-rrubygems",
124
+ "-e",
125
+ GEMSPEC_SUBPROCESS_LOADER,
126
+ absolute_path,
127
+ )
128
+ return nil unless status.success?
129
+ return nil if out.nil? || out.empty?
130
+
131
+ Marshal.load(out)
132
+ rescue StandardError
133
+ nil
134
+ end
135
+ private_class_method :load_gemspec_in_subprocess
57
136
  end
58
137
  end
data/lib/scint.rb CHANGED
@@ -15,16 +15,24 @@ module Scint
15
15
 
16
16
  # XDG-based cache root
17
17
  def self.cache_root
18
- @cache_root ||= File.join(
19
- ENV.fetch("XDG_CACHE_HOME", File.join(Dir.home, ".cache")),
20
- "scint"
21
- )
18
+ @cache_root ||= default_cache_root
22
19
  end
23
20
 
24
21
  def self.cache_root=(path)
25
22
  @cache_root = path
26
23
  end
27
24
 
25
+ def self.default_cache_root
26
+ explicit = ENV["SCINT_CACHE"]
27
+ return File.expand_path(explicit) unless explicit.nil? || explicit.empty?
28
+
29
+ File.join(
30
+ ENV.fetch("XDG_CACHE_HOME", File.join(Dir.home, ".cache")),
31
+ "scint"
32
+ )
33
+ end
34
+ private_class_method :default_cache_root
35
+
28
36
  # Shared data structures used across all modules
29
37
  Dependency = Struct.new(
30
38
  :name, :version_reqs, :source, :groups, :platforms, :require_paths,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobi Lutke
@@ -27,8 +27,10 @@ files:
27
27
  - lib/bundler/setup.rb
28
28
  - lib/scint.rb
29
29
  - lib/scint/cache/layout.rb
30
+ - lib/scint/cache/manifest.rb
30
31
  - lib/scint/cache/metadata_store.rb
31
32
  - lib/scint/cache/prewarm.rb
33
+ - lib/scint/cache/validity.rb
32
34
  - lib/scint/cli.rb
33
35
  - lib/scint/cli/add.rb
34
36
  - lib/scint/cli/cache.rb
@@ -56,6 +58,8 @@ files:
56
58
  - lib/scint/installer/linker.rb
57
59
  - lib/scint/installer/planner.rb
58
60
  - lib/scint/installer/preparer.rb
61
+ - lib/scint/installer/promoter.rb
62
+ - lib/scint/linker.sh
59
63
  - lib/scint/lockfile/parser.rb
60
64
  - lib/scint/lockfile/writer.rb
61
65
  - lib/scint/platform.rb