code_manifest 1.0.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be523e36c254ee8749c037a2e1c9fa57dd10d2e86d83b49aed3349f56da72bdb
4
- data.tar.gz: 6741764dfc73fc92fa87f9c5acfbba1fae8650c617a5aa15efabafec25bb8dd0
3
+ metadata.gz: 94f0a39e5da9d75029e1834402dd5bda25d18510d7eca6291c67876caf5aad17
4
+ data.tar.gz: 4b6d063a77093c6fd674964c15525808b6cd22e5d8d9d9770adb7c41421b4c9e
5
5
  SHA512:
6
- metadata.gz: fc9bd31b43bdc5637de024cb0063f88519c09a3120025f452a5733fff4dfca6d1f4f9c5067866fea82395c846e3a2027388cfe7a74d77f50c13665fde43d6303
7
- data.tar.gz: e802a2695b4409eb40fac80e9a79a0f88b1fcac45a4549c4be1a496540b4769d99ebbed2389ccb7deeca4bc5a002b1a8515eedd82930c2881ab6e391dc638bbf
6
+ metadata.gz: d3d985ad3f694e285c28ce13e3ec2036a939c5767ec8b6c6f6898d78b30eae608d68a680602155b5f866c78797328357ed34c88c0bd1818c22ffd659f9028d27
7
+ data.tar.gz: 19d20c8fd6756f2b92cb068add7b22e9005ff6c41f75b065bf096251000c75ec7b676a238b26345f934b29f73a0324c36a2d915214dc9116ee2788de61114fae
@@ -1,46 +1,63 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
  require 'digest/md5'
5
4
  require_relative 'rule'
6
5
 
7
6
  module CodeManifest
8
7
  class Manifest
9
- attr_reader :root
8
+ GLOB_OPTIONS = File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB
9
+
10
+ attr_reader :root, :rules
10
11
 
11
12
  def initialize(root, patterns)
12
13
  @root = root
13
- @patterns = patterns.map(&:to_s)
14
+ @rules ||= patterns.map do |pattern|
15
+ Rule.new(root, pattern)
16
+ end
14
17
  end
15
18
 
16
19
  def files
17
- @files ||= (inclusion_rules.map(&:files).reduce(Set.new, :merge) - exclusion_rules.map(&:files).reduce(Set.new, :merge)).sort.to_set
20
+ @files ||= (inclusion_files - exclusion_files).sort!.freeze
18
21
  end
19
22
 
20
23
  def digest
21
24
  @digest ||= begin
22
25
  digests = files.map { |file| Digest::MD5.file(root.join(file)).hexdigest }
23
- Digest::MD5.hexdigest(digests.join)
26
+ Digest::MD5.hexdigest(digests.join).freeze
24
27
  end
25
28
  end
26
29
 
30
+ def matches(paths)
31
+ result_paths = paths.select { |path| inclusion_rules.any? { |rule| rule.match?(path) } }
32
+ result_paths.reject! { |path| exclusion_files.any? { |rule| rule.match?(path) } }
33
+
34
+ result_paths
35
+ end
36
+
27
37
  private
28
38
 
29
- def rules
30
- @rules ||= @patterns.each_with_object([]) do |pattern, rules|
31
- pattern = pattern.strip
32
- unless pattern.match?(/\A(#|\z)/)
33
- rules << Rule.new(root, pattern)
34
- end
35
- end
39
+ def inclusion_files
40
+ @inclusion_files ||= files_with_relative_path(Dir.glob(inclusion_rules.map(&:glob), GLOB_OPTIONS))
36
41
  end
37
42
 
38
43
  def inclusion_rules
39
44
  @inclusion_rules ||= rules.reject(&:exclude)
40
45
  end
41
46
 
47
+ def exclusion_files
48
+ @exclusion_files ||= files_with_relative_path(Dir.glob(exclusion_rules.map(&:glob), GLOB_OPTIONS))
49
+ end
50
+
42
51
  def exclusion_rules
43
52
  @exclusion_rules ||= rules.select(&:exclude)
44
53
  end
54
+
55
+ def files_with_relative_path(files)
56
+ files.map do |file|
57
+ pathname = Pathname.new(file)
58
+ next if pathname.directory?
59
+ pathname.relative_path_from(root.expand_path).to_s
60
+ end.compact
61
+ end
45
62
  end
46
63
  end
@@ -1,18 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pathname'
4
+
3
5
  module CodeManifest
4
6
  class Rule
5
- GLOB_OPTIONS = File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB
6
-
7
- attr_reader :exclude
8
- attr_reader :glob
7
+ attr_reader :exclude, :glob
9
8
 
10
9
  def initialize(root, pattern)
11
10
  @root = root
12
11
  @exclude = false
13
12
  @glob = @root
14
13
 
15
- if pattern[0] == '!'
14
+ if pattern.start_with?('!')
16
15
  @exclude = true
17
16
  pattern = pattern[1..-1]
18
17
  end
@@ -26,21 +25,11 @@ module CodeManifest
26
25
  @glob = @glob.join(pattern).to_s
27
26
  end
28
27
 
29
- def files
30
- @files ||= begin
31
- matched = Dir.glob(glob, GLOB_OPTIONS)
32
- matched.map! { |file| Pathname.new(file) }
33
- matched.reject!(&:directory?)
34
- matched.map! { |file| file.relative_path_from(@root.expand_path).to_s }
35
- Set.new(matched.sort!)
36
- end
37
- end
38
-
39
28
  def match?(file)
40
29
  file = Pathname.new(file)
41
30
  file = @root.join(file) unless file.absolute?
42
31
 
43
- File.fnmatch?(glob, file.to_s, GLOB_OPTIONS)
32
+ File.fnmatch?(glob, file.to_s, Manifest::GLOB_OPTIONS)
44
33
  end
45
34
  end
46
35
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CodeManifest
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
data/lib/code_manifest.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'pathname'
3
4
  require 'yaml'
4
- require_relative "code_manifest/version"
5
- require_relative "code_manifest/manifest"
5
+ require_relative 'code_manifest/version'
6
+ require_relative 'code_manifest/manifest'
6
7
 
7
8
  module CodeManifest
8
9
  class Error < StandardError; end
9
10
 
10
- DOTFILE = '.code_manifest.yml'.freeze
11
+ DOTFILE = '.code_manifest.yml'
11
12
  KEY_PATTERN = /[a-z_0-9]+/.freeze
12
13
 
13
14
  class << self
@@ -19,18 +20,18 @@ module CodeManifest
19
20
 
20
21
  def manifests
21
22
  @manifests ||= begin
22
- config_file = traverse_files(DOTFILE, Dir.pwd)
23
+ manifest_file = traverse_files(DOTFILE, Dir.pwd)
23
24
 
24
- raise "#{DOTFILE} was not found in your project directory, please check README for instructions." unless config_file
25
+ unless manifest_file
26
+ raise "#{DOTFILE} was not found in your project directory, please check README for instructions."
27
+ end
25
28
 
26
- root = Pathname.new(config_file).dirname
29
+ root = Pathname.new(manifest_file).dirname
27
30
 
28
- YAML.load_file(config_file).each_with_object({}) do |(name, patterns), collection|
31
+ load_manifest(manifest_file).each_with_object({}) do |(name, patterns), collection|
29
32
  next unless name.match?(KEY_PATTERN)
30
33
 
31
- if collection.key?(name)
32
- raise ArgumentError, "#{name} defined multiple times in #{DOTFILE}"
33
- end
34
+ raise ArgumentError, "#{name} defined multiple times in #{DOTFILE}" if collection.key?(name)
34
35
 
35
36
  collection[name] = Manifest.new(root, patterns)
36
37
  end
@@ -43,5 +44,12 @@ module CodeManifest
43
44
  return file.to_s if file.exist?
44
45
  end
45
46
  end
47
+
48
+ # https://stackoverflow.com/a/71192990
49
+ def load_manifest(file)
50
+ YAML.load_file(file, aliases: true)
51
+ rescue ArgumentError
52
+ YAML.load_file(file)
53
+ end
46
54
  end
47
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: code_manifest
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gusto Engineers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-20 00:00:00.000000000 Z
11
+ date: 2022-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec