spectracer 1.2.1 → 1.3.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fbfa5429478965d82098a285c1c6319df7ec0354dc01f5797acb4c7618412bf0
|
|
4
|
+
data.tar.gz: 35fdb890ce1c67257a0cb41cb09a4bfd4f5479c428cc2f477484ba2afb90f919
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 973f20fc2e7168cb2af8bb865ab5740a590b189dadb8f94635dfe9a4f3c68b033f42b983c15799fe97e84078da40c7d482926d26e9a2faf230e9f2991f4c1db7
|
|
7
|
+
data.tar.gz: ff5a83f41d30a6038ef597b559585897c11c30fbeb2e396a077984fcef7e04f26b9aad4e8718e8fbc4c516e38034df27b18646937041adda63db9f50f5afa9ef
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.3.0] - 2026-02-02
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- GlobFactorizer to reduce redundant spec patterns before running tests
|
|
8
|
+
- Removes concrete files already matched by broader globs
|
|
9
|
+
- Eliminates narrower globs subsumed by broader ones
|
|
10
|
+
- Example: `{spec/user/**/*_spec.rb, spec/user/**/one_spec.rb}` → `{spec/user/**/*_spec.rb}`
|
|
11
|
+
|
|
3
12
|
## [1.2.0] - 2026-02-02
|
|
4
13
|
|
|
5
14
|
### Added
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Spectracer
|
|
4
|
+
module Core
|
|
5
|
+
class GlobFactorizer
|
|
6
|
+
def call(patterns)
|
|
7
|
+
return patterns.to_a if patterns.size <= 1
|
|
8
|
+
|
|
9
|
+
patterns_array = patterns.to_a.uniq
|
|
10
|
+
globs, files = patterns_array.partition { |p| glob_pattern?(p) }
|
|
11
|
+
|
|
12
|
+
# Remove files that are matched by any glob
|
|
13
|
+
remaining_files = files.reject do |file|
|
|
14
|
+
globs.any? { |glob| File.fnmatch?(glob, file, File::FNM_PATHNAME) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Remove globs subsumed by other globs (broader patterns win)
|
|
18
|
+
remaining_globs = globs.reject do |glob|
|
|
19
|
+
globs.any? { |other| other != glob && subsumes?(other, glob) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
remaining_globs + remaining_files
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def glob_pattern?(pattern)
|
|
28
|
+
pattern.include?("*") || pattern.include?("?") || pattern.include?("[")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def subsumes?(broader, narrower)
|
|
32
|
+
return false if broader == narrower
|
|
33
|
+
|
|
34
|
+
# Convert the narrower glob to a concrete-ish path by replacing wildcards
|
|
35
|
+
# then check if the broader glob would match it
|
|
36
|
+
test_path = narrower
|
|
37
|
+
.gsub("**", "any/nested/path")
|
|
38
|
+
.gsub("*", "placeholder")
|
|
39
|
+
|
|
40
|
+
File.fnmatch?(broader, test_path, File::FNM_PATHNAME)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -5,6 +5,10 @@ module Spectracer
|
|
|
5
5
|
class SpecSelector
|
|
6
6
|
Result = Struct.new(:specs, :file_to_specs_map, keyword_init: true)
|
|
7
7
|
|
|
8
|
+
def initialize(factorizer: GlobFactorizer.new)
|
|
9
|
+
@factorizer = factorizer
|
|
10
|
+
end
|
|
11
|
+
|
|
8
12
|
def call(changed_files:, inverse_deps:, globs:, on_empty:)
|
|
9
13
|
spec_set = Set.new
|
|
10
14
|
file_to_specs = {}
|
|
@@ -34,7 +38,7 @@ module Spectracer
|
|
|
34
38
|
file_to_specs[file] = matched_specs.uniq.sort unless matched_specs.empty?
|
|
35
39
|
end
|
|
36
40
|
|
|
37
|
-
files = spec_set.
|
|
41
|
+
files = @factorizer.call(spec_set).sort
|
|
38
42
|
specs_result = files.empty? ? on_empty : files.join(",")
|
|
39
43
|
|
|
40
44
|
Result.new(specs: specs_result, file_to_specs_map: file_to_specs)
|
|
@@ -24,7 +24,9 @@ module Spectracer
|
|
|
24
24
|
|
|
25
25
|
inverse_deps.each_value(&:sort!)
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
output_path = @paths.collected_dependencies_file
|
|
28
|
+
@logger&.debug("Writing collected dependencies to: #{output_path}")
|
|
29
|
+
@store.write(inverse_deps, output_path)
|
|
28
30
|
|
|
29
31
|
nil
|
|
30
32
|
end
|
data/lib/spectracer/version.rb
CHANGED
data/lib/spectracer.rb
CHANGED
|
@@ -5,6 +5,7 @@ require_relative "spectracer/logger"
|
|
|
5
5
|
|
|
6
6
|
require_relative "spectracer/core/paths"
|
|
7
7
|
require_relative "spectracer/core/path_filter"
|
|
8
|
+
require_relative "spectracer/core/glob_factorizer"
|
|
8
9
|
require_relative "spectracer/core/spec_selector"
|
|
9
10
|
|
|
10
11
|
require_relative "spectracer/io/command_runner"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spectracer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mitch Smith
|
|
@@ -38,6 +38,7 @@ files:
|
|
|
38
38
|
- README.md
|
|
39
39
|
- lib/spectracer.default.yml
|
|
40
40
|
- lib/spectracer.rb
|
|
41
|
+
- lib/spectracer/core/glob_factorizer.rb
|
|
41
42
|
- lib/spectracer/core/path_filter.rb
|
|
42
43
|
- lib/spectracer/core/paths.rb
|
|
43
44
|
- lib/spectracer/core/spec_selector.rb
|