scint 0.1.0 → 0.7.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.
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Scint
4
+ module SpecUtils
5
+ module_function
6
+
7
+ def name(spec)
8
+ spec.respond_to?(:name) ? spec.name : spec[:name]
9
+ end
10
+
11
+ def version(spec)
12
+ spec.respond_to?(:version) ? spec.version : spec[:version]
13
+ end
14
+
15
+ def platform(spec)
16
+ return spec.platform if spec.respond_to?(:platform)
17
+ return spec[:platform] if spec.is_a?(Hash)
18
+ return nil unless spec.respond_to?(:[])
19
+
20
+ spec[:platform]
21
+ rescue NameError, ArgumentError
22
+ nil
23
+ end
24
+
25
+ def platform_str(spec)
26
+ platform_value(platform(spec))
27
+ end
28
+
29
+ def platform_value(platform)
30
+ value = platform.nil? ? "ruby" : platform.to_s
31
+ value.empty? ? "ruby" : value
32
+ end
33
+
34
+ def full_name(spec)
35
+ base = "#{name(spec)}-#{version(spec)}"
36
+ plat = platform_str(spec)
37
+ return base if plat == "ruby"
38
+
39
+ "#{base}-#{plat}"
40
+ end
41
+
42
+ def full_name_for(name, version, platform = "ruby")
43
+ base = "#{name}-#{version}"
44
+ plat = platform_value(platform)
45
+ return base if plat == "ruby"
46
+
47
+ "#{base}-#{plat}"
48
+ end
49
+
50
+ def full_key(spec)
51
+ full_key_for(name(spec), version(spec), platform(spec))
52
+ end
53
+
54
+ def full_key_for(name, version, platform = "ruby")
55
+ "#{name}-#{version}-#{platform_value(platform)}"
56
+ end
57
+ end
58
+ end
@@ -1,3 +1,7 @@
1
1
  module Scint::PubGrub
2
- VERSION = "0.5.0"
2
+ VERSION = if defined?(::Scint::VERSION)
3
+ ::Scint::VERSION
4
+ else
5
+ File.read(File.expand_path("../../../../VERSION", __dir__)).strip
6
+ end
3
7
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Scint
4
+ VERSION = File.read(File.expand_path("../../VERSION", __dir__)).strip
5
+ end
data/lib/scint.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Scint
4
- VERSION = "0.1.0"
3
+ require_relative "scint/version"
5
4
 
5
+ module Scint
6
6
  # Color support: respects NO_COLOR (https://no-color.org) and TERM=dumb.
7
7
  COLOR = !ENV.key?("NO_COLOR") && ENV["TERM"] != "dumb" && $stderr.tty?
8
8
 
@@ -59,6 +59,7 @@ module Scint
59
59
  autoload :Progress, "scint/progress"
60
60
  autoload :FS, "scint/fs"
61
61
  autoload :Platform, "scint/platform"
62
+ autoload :SpecUtils, "scint/spec_utils"
62
63
 
63
64
  # Errors
64
65
  autoload :BundlerError, "scint/errors"
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
- - Scint Contributors
7
+ - Tobi Lutke
8
8
  bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
@@ -16,17 +16,13 @@ email:
16
16
  - maintainers@example.com
17
17
  executables:
18
18
  - scint
19
- - scint-io-summary
20
- - scint-syscall-trace
21
19
  extensions: []
22
20
  extra_rdoc_files: []
23
21
  files:
24
22
  - FEATURES.md
25
23
  - README.md
26
- - bin/bundler-vs-scint
24
+ - VERSION
27
25
  - bin/scint
28
- - bin/scint-io-summary
29
- - bin/scint-syscall-trace
30
26
  - lib/bundler.rb
31
27
  - lib/bundler/setup.rb
32
28
  - lib/scint.rb
@@ -73,6 +69,7 @@ files:
73
69
  - lib/scint/source/git.rb
74
70
  - lib/scint/source/path.rb
75
71
  - lib/scint/source/rubygems.rb
72
+ - lib/scint/spec_utils.rb
76
73
  - lib/scint/vendor/pub_grub.rb
77
74
  - lib/scint/vendor/pub_grub/assignment.rb
78
75
  - lib/scint/vendor/pub_grub/basic_package_source.rb
@@ -90,6 +87,7 @@ files:
90
87
  - lib/scint/vendor/pub_grub/version_range.rb
91
88
  - lib/scint/vendor/pub_grub/version_solver.rb
92
89
  - lib/scint/vendor/pub_grub/version_union.rb
90
+ - lib/scint/version.rb
93
91
  - lib/scint/worker_pool.rb
94
92
  homepage: https://example.com/scint
95
93
  licenses:
data/bin/bundler-vs-scint DELETED
@@ -1,233 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Benchmark: stock bundler vs scint, cold and warm caches.
3
- #
4
- # Cold = fresh install dir, no caches.
5
- # Warm = fresh install dir, but gem download caches are warm from the cold run.
6
- #
7
- # No copying needed — warm runs just get a new BUNDLE_PATH while keeping
8
- # the same GEM_HOME / GEM_PATH / global cache so downloads are already cached.
9
- #
10
- # Creates an isolated tmp directory for all outputs. Clean up with:
11
- # rm -rf /tmp/scint-bench-*
12
- #
13
- # Usage: ./bin/bundler-vs-scint [/path/to/project]
14
- # Default project: /Users/tobi/src/github.com/Shopify/u2
15
-
16
- set -euo pipefail
17
-
18
- PROJECT="${1:-/Users/tobi/src/github.com/Shopify/u2}"
19
- SCINT_BIN="$(cd "$(dirname "$0")/.." && pwd)/bin/scint"
20
- TMPROOT=$(mktemp -d /tmp/scint-bench-XXXXXX)
21
-
22
- # Each run gets its own BUNDLE_PATH (install destination).
23
- # GEM_HOME/GEM_PATH stay shared so download caches persist between cold→warm.
24
- # Scint uses XDG_CACHE_HOME for its global cache — redirect to tmpdir.
25
- BUNDLER_COLD="$TMPROOT/bundler-cold"
26
- BUNDLER_WARM="$TMPROOT/bundler-warm"
27
- BUNDLER_GEM_HOME="$TMPROOT/bundler-gem-home"
28
- SCINT_COLD="$TMPROOT/scint-cold"
29
- SCINT_WARM="$TMPROOT/scint-warm"
30
- SCINT_GEM_HOME="$TMPROOT/scint-gem-home"
31
- SCINT_XDG_CACHE="$TMPROOT/scint-cache"
32
- LOGS="$TMPROOT/logs"
33
- mkdir -p "$BUNDLER_COLD" "$BUNDLER_WARM" "$BUNDLER_GEM_HOME" \
34
- "$SCINT_COLD" "$SCINT_WARM" "$SCINT_GEM_HOME" "$SCINT_XDG_CACHE" "$LOGS"
35
-
36
- echo "=== Benchmark: bundler vs scint ==="
37
- echo "Project: $PROJECT"
38
- echo "Tmp root: $TMPROOT"
39
- echo ""
40
-
41
- # Helper: time a command, capture output, return elapsed seconds
42
- run_timed() {
43
- local label="$1"
44
- local logfile="$2"
45
- shift 2
46
-
47
- echo "--- $label ---"
48
- local start end_time elapsed
49
- start=$(ruby -e 'puts Process.clock_gettime(Process::CLOCK_MONOTONIC)')
50
-
51
- # Run in the project directory, tee to both log and stdout
52
- (cd "$PROJECT" && "$@") 2>&1 | tee "$logfile" || true
53
-
54
- end_time=$(ruby -e 'puts Process.clock_gettime(Process::CLOCK_MONOTONIC)')
55
- elapsed=$(ruby -e "puts (($end_time - $start)).round(2)")
56
- echo " Elapsed: ${elapsed}s (log: $logfile)"
57
- echo "$elapsed" > "${logfile}.time"
58
- }
59
-
60
- # ── 1. Cold bundler ──────────────────────────────────────────────
61
- echo ""
62
- echo "════════════════════════════════════════"
63
- echo " 1/4 Bundler (cold)"
64
- echo "════════════════════════════════════════"
65
- SYSTEM_GEM_DIR="$(ruby -e 'puts Gem.default_dir')"
66
- run_timed "bundler install (cold)" "$LOGS/bundler-cold.log" \
67
- env BUNDLE_PATH="$BUNDLER_COLD" \
68
- GEM_HOME="$BUNDLER_GEM_HOME" \
69
- GEM_PATH="$BUNDLER_GEM_HOME:$SYSTEM_GEM_DIR" \
70
- BUNDLE_DISABLE_SHARED_GEMS=1 \
71
- bundle install --jobs=8
72
-
73
- # ── 2. Warm bundler (new install dir, same gem cache) ────────────
74
- echo ""
75
- echo "════════════════════════════════════════"
76
- echo " 2/4 Bundler (warm)"
77
- echo "════════════════════════════════════════"
78
- run_timed "bundler install (warm)" "$LOGS/bundler-warm.log" \
79
- env BUNDLE_PATH="$BUNDLER_WARM" \
80
- GEM_HOME="$BUNDLER_GEM_HOME" \
81
- GEM_PATH="$BUNDLER_GEM_HOME:$SYSTEM_GEM_DIR" \
82
- BUNDLE_DISABLE_SHARED_GEMS=1 \
83
- bundle install --jobs=8
84
-
85
- # ── 3. Cold scint ────────────────────────────────────────────────
86
- echo ""
87
- echo "════════════════════════════════════════"
88
- echo " 3/4 Scint (cold)"
89
- echo "════════════════════════════════════════"
90
- run_timed "scint install (cold)" "$LOGS/scint-cold.log" \
91
- env BUNDLE_PATH="$SCINT_COLD" \
92
- GEM_HOME="$SCINT_GEM_HOME" \
93
- GEM_PATH="$SCINT_GEM_HOME:$SYSTEM_GEM_DIR" \
94
- XDG_CACHE_HOME="$SCINT_XDG_CACHE" \
95
- "$SCINT_BIN" install --path "$SCINT_COLD"
96
-
97
- # ── 4. Warm scint (new install dir, global cache already warm) ───
98
- echo ""
99
- echo "════════════════════════════════════════"
100
- echo " 4/4 Scint (warm)"
101
- echo "════════════════════════════════════════"
102
- run_timed "scint install (warm)" "$LOGS/scint-warm.log" \
103
- env BUNDLE_PATH="$SCINT_WARM" \
104
- GEM_HOME="$SCINT_GEM_HOME" \
105
- GEM_PATH="$SCINT_GEM_HOME:$SYSTEM_GEM_DIR" \
106
- XDG_CACHE_HOME="$SCINT_XDG_CACHE" \
107
- "$SCINT_BIN" install --path "$SCINT_WARM"
108
-
109
- # ── Summary ──────────────────────────────────────────────────────
110
- echo ""
111
- echo "════════════════════════════════════════"
112
- echo " Results"
113
- echo "════════════════════════════════════════"
114
-
115
- bc=$(cat "$LOGS/bundler-cold.log.time")
116
- bw=$(cat "$LOGS/bundler-warm.log.time")
117
- sc=$(cat "$LOGS/scint-cold.log.time")
118
- sw=$(cat "$LOGS/scint-warm.log.time")
119
-
120
- printf " %-20s %8ss\n" "Bundler (cold):" "$bc"
121
- printf " %-20s %8ss\n" "Bundler (warm):" "$bw"
122
- printf " %-20s %8ss\n" "Scint (cold):" "$sc"
123
- printf " %-20s %8ss\n" "Scint (warm):" "$sw"
124
- echo ""
125
-
126
- cold_speedup=$(ruby -e "puts ($bc.to_f / $sc.to_f).round(1)")
127
- warm_speedup=$(ruby -e "puts ($bw.to_f / $sw.to_f).round(1)")
128
- echo " Cold speedup: ${cold_speedup}x"
129
- echo " Warm speedup: ${warm_speedup}x"
130
-
131
- # ── Directory comparison ─────────────────────────────────────────
132
- echo ""
133
- echo "════════════════════════════════════════"
134
- echo " Directory comparison"
135
- echo "════════════════════════════════════════"
136
-
137
- DIFF_LOG="$LOGS/diff-report.txt"
138
- > "$DIFF_LOG"
139
-
140
- # Compare installed gem directories
141
- bundler_gems="$BUNDLER_COLD/ruby/3.4.0/gems"
142
- scint_gems="$SCINT_COLD/ruby/3.4.0/gems"
143
-
144
- if [[ -d "$bundler_gems" && -d "$scint_gems" ]]; then
145
- # Gem directories present in each
146
- bundler_gem_list=$(cd "$bundler_gems" && ls -1 | sort)
147
- scint_gem_list=$(cd "$scint_gems" && ls -1 | sort)
148
-
149
- only_bundler=$(comm -23 <(echo "$bundler_gem_list") <(echo "$scint_gem_list"))
150
- only_scint=$(comm -13 <(echo "$bundler_gem_list") <(echo "$scint_gem_list"))
151
- in_both=$(comm -12 <(echo "$bundler_gem_list") <(echo "$scint_gem_list"))
152
-
153
- bundler_count=$(echo "$bundler_gem_list" | wc -l | tr -d ' ')
154
- scint_count=$(echo "$scint_gem_list" | wc -l | tr -d ' ')
155
- both_count=$(echo "$in_both" | wc -l | tr -d ' ')
156
-
157
- echo " Bundler gems: $bundler_count"
158
- echo " Scint gems: $scint_count"
159
- echo " In common: $both_count"
160
-
161
- if [[ -n "$only_bundler" ]]; then
162
- echo ""
163
- echo " Only in bundler:"
164
- echo "$only_bundler" | sed 's/^/ /'
165
- fi
166
-
167
- if [[ -n "$only_scint" ]]; then
168
- echo ""
169
- echo " Only in scint:"
170
- echo "$only_scint" | sed 's/^/ /'
171
- fi
172
-
173
- # Compare gemspec counts
174
- bundler_specs="$BUNDLER_COLD/ruby/3.4.0/specifications"
175
- scint_specs="$SCINT_COLD/ruby/3.4.0/specifications"
176
- if [[ -d "$bundler_specs" && -d "$scint_specs" ]]; then
177
- bs_count=$(ls -1 "$bundler_specs" | wc -l | tr -d ' ')
178
- ss_count=$(ls -1 "$scint_specs" | wc -l | tr -d ' ')
179
- echo ""
180
- echo " Bundler gemspecs: $bs_count"
181
- echo " Scint gemspecs: $ss_count"
182
- fi
183
-
184
- # Compare bin directories
185
- bundler_bin="$BUNDLER_COLD/ruby/3.4.0/bin"
186
- scint_bin_dir="$SCINT_COLD/ruby/3.4.0/bin"
187
- if [[ -d "$bundler_bin" && -d "$scint_bin_dir" ]]; then
188
- bb_count=$(ls -1 "$bundler_bin" | wc -l | tr -d ' ')
189
- sb_count=$(ls -1 "$scint_bin_dir" | wc -l | tr -d ' ')
190
- echo ""
191
- echo " Bundler bins: $bb_count"
192
- echo " Scint bins: $sb_count"
193
-
194
- only_b_bins=$(comm -23 <(ls -1 "$bundler_bin" | sort) <(ls -1 "$scint_bin_dir" | sort))
195
- only_s_bins=$(comm -13 <(ls -1 "$bundler_bin" | sort) <(ls -1 "$scint_bin_dir" | sort))
196
- if [[ -n "$only_b_bins" ]]; then
197
- echo " Bins only in bundler:"
198
- echo "$only_b_bins" | sed 's/^/ /'
199
- fi
200
- if [[ -n "$only_s_bins" ]]; then
201
- echo " Bins only in scint:"
202
- echo "$only_s_bins" | sed 's/^/ /'
203
- fi
204
- fi
205
-
206
- # Check a few random gems for file count differences
207
- echo ""
208
- echo " File count spot-check (first 10 shared gems):"
209
- echo "$in_both" | head -10 | while read -r gem; do
210
- bf=$(find "$bundler_gems/$gem" -type f 2>/dev/null | wc -l | tr -d ' ')
211
- sf=$(find "$scint_gems/$gem" -type f 2>/dev/null | wc -l | tr -d ' ')
212
- if [[ "$bf" != "$sf" ]]; then
213
- echo " $gem: bundler=$bf scint=$sf ← DIFF"
214
- else
215
- echo " $gem: $bf files ✓"
216
- fi
217
- done
218
-
219
- # Disk size comparison
220
- echo ""
221
- bundler_size=$(du -sh "$BUNDLER_COLD" 2>/dev/null | cut -f1)
222
- scint_size=$(du -sh "$SCINT_COLD" 2>/dev/null | cut -f1)
223
- echo " Bundler total size: $bundler_size"
224
- echo " Scint total size: $scint_size"
225
- else
226
- echo " ⚠ Could not find gem directories to compare"
227
- echo " Bundler: $bundler_gems (exists: $(test -d "$bundler_gems" && echo yes || echo no))"
228
- echo " Scint: $scint_gems (exists: $(test -d "$scint_gems" && echo yes || echo no))"
229
- fi
230
-
231
- echo ""
232
- echo "All logs and data in: $TMPROOT"
233
- echo "Clean up: rm -rf $TMPROOT"
data/bin/scint-io-summary DELETED
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "json"
5
-
6
- path = ARGV[0]
7
- unless path && !path.empty?
8
- warn "Usage: scint-io-summary TRACE.jsonl"
9
- exit 2
10
- end
11
-
12
- op_counts = Hash.new(0)
13
- op_path_counts = Hash.new(0)
14
- line_count = 0
15
-
16
- File.foreach(path) do |line|
17
- begin
18
- row = JSON.parse(line)
19
- rescue JSON::ParserError
20
- next
21
- end
22
-
23
- line_count += 1
24
- op = row["op"] || "(unknown)"
25
- op_counts[op] += 1
26
-
27
- args = row.dig("data", "args")
28
- first_arg = args.is_a?(Array) ? args[0] : nil
29
- if first_arg.is_a?(String) && !first_arg.empty?
30
- op_path_counts[[op, first_arg]] += 1
31
- end
32
- end
33
-
34
- puts "trace_file=#{path}"
35
- puts "total_rows=#{line_count}"
36
- puts
37
- puts "Top operations:"
38
- op_counts.sort_by { |_k, v| -v }.first(30).each do |op, count|
39
- puts "#{count}\t#{op}"
40
- end
41
-
42
- puts
43
- puts "Top repeated op+path:"
44
- op_path_counts.sort_by { |_k, v| -v }.first(50).each do |(op, p), count|
45
- puts "#{count}\t#{op}\t#{p}"
46
- end
@@ -1,41 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "rbconfig"
5
-
6
- def usage
7
- warn "Usage: scint-syscall-trace LOGFILE -- CMD [ARGS...]"
8
- warn "Example: scint-syscall-trace /tmp/scint-sys.log -- scint install"
9
- exit 2
10
- end
11
-
12
- sep = ARGV.index("--")
13
- usage unless sep && sep.positive?
14
-
15
- logfile = ARGV[0]
16
- cmd = ARGV[(sep + 1)..]
17
- usage if logfile.nil? || logfile.empty? || cmd.nil? || cmd.empty?
18
-
19
- if system("command -v strace >/dev/null 2>&1")
20
- exec("strace", "-ff", "-tt", "-s", "256", "-e", "trace=file,process", "-o", logfile, *cmd)
21
- end
22
-
23
- if system("command -v dtruss >/dev/null 2>&1")
24
- if Process.uid != 0
25
- warn "dtruss usually requires root on macOS. Re-run with sudo:"
26
- warn " sudo #{File.expand_path($PROGRAM_NAME)} #{logfile} -- #{cmd.join(" ")}"
27
- exit 2
28
- end
29
-
30
- exec(
31
- "dtruss",
32
- "-f",
33
- "-t", "open,open_nocancel,stat64,lstat64,access,rename,unlink,mkdir,rmdir,read,write,pread,pwrite,clonefile",
34
- "-o", logfile,
35
- "--",
36
- *cmd
37
- )
38
- end
39
-
40
- warn "No supported syscall tracer found (expected strace or dtruss)."
41
- exit 2