code_manifest 1.0.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/README.md +42 -0
- data/lib/code_manifest/manifest.rb +46 -0
- data/lib/code_manifest/rule.rb +46 -0
- data/lib/code_manifest/version.rb +5 -0
- data/lib/code_manifest.rb +47 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: be523e36c254ee8749c037a2e1c9fa57dd10d2e86d83b49aed3349f56da72bdb
|
4
|
+
data.tar.gz: 6741764dfc73fc92fa87f9c5acfbba1fae8650c617a5aa15efabafec25bb8dd0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fc9bd31b43bdc5637de024cb0063f88519c09a3120025f452a5733fff4dfca6d1f4f9c5067866fea82395c846e3a2027388cfe7a74d77f50c13665fde43d6303
|
7
|
+
data.tar.gz: e802a2695b4409eb40fac80e9a79a0f88b1fcac45a4549c4be1a496540b4769d99ebbed2389ccb7deeca4bc5a002b1a8515eedd82930c2881ab6e391dc638bbf
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# CodeManifest
|
2
|
+
|
3
|
+
Simple manifest to fetch file by globs and generate digest.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Install the gem and add to the application's Gemfile by executing:
|
8
|
+
|
9
|
+
$ bundle add code_manifest
|
10
|
+
|
11
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
12
|
+
|
13
|
+
$ gem install code_manifest
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
Put a `.code_manifest.yml` config file under your project root, for example:
|
18
|
+
|
19
|
+
```yml
|
20
|
+
ruby:
|
21
|
+
- app/**/*.rb
|
22
|
+
js:
|
23
|
+
- frontend/**/*.js
|
24
|
+
```
|
25
|
+
|
26
|
+
Then use it with:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'code_manifest'
|
30
|
+
|
31
|
+
# Returns a `Set` with filepaths
|
32
|
+
CodeManifest['ruby'].files
|
33
|
+
CodeManifest['js'].files
|
34
|
+
|
35
|
+
# Returns a digest based on all files specified under same namespace
|
36
|
+
CodeManifest['ruby'].digest
|
37
|
+
CodeManifest['js'].digest
|
38
|
+
```
|
39
|
+
|
40
|
+
## Contributing
|
41
|
+
|
42
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/code_manifest.
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
require 'digest/md5'
|
5
|
+
require_relative 'rule'
|
6
|
+
|
7
|
+
module CodeManifest
|
8
|
+
class Manifest
|
9
|
+
attr_reader :root
|
10
|
+
|
11
|
+
def initialize(root, patterns)
|
12
|
+
@root = root
|
13
|
+
@patterns = patterns.map(&:to_s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def files
|
17
|
+
@files ||= (inclusion_rules.map(&:files).reduce(Set.new, :merge) - exclusion_rules.map(&:files).reduce(Set.new, :merge)).sort.to_set
|
18
|
+
end
|
19
|
+
|
20
|
+
def digest
|
21
|
+
@digest ||= begin
|
22
|
+
digests = files.map { |file| Digest::MD5.file(root.join(file)).hexdigest }
|
23
|
+
Digest::MD5.hexdigest(digests.join)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
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
|
36
|
+
end
|
37
|
+
|
38
|
+
def inclusion_rules
|
39
|
+
@inclusion_rules ||= rules.reject(&:exclude)
|
40
|
+
end
|
41
|
+
|
42
|
+
def exclusion_rules
|
43
|
+
@exclusion_rules ||= rules.select(&:exclude)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CodeManifest
|
4
|
+
class Rule
|
5
|
+
GLOB_OPTIONS = File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB
|
6
|
+
|
7
|
+
attr_reader :exclude
|
8
|
+
attr_reader :glob
|
9
|
+
|
10
|
+
def initialize(root, pattern)
|
11
|
+
@root = root
|
12
|
+
@exclude = false
|
13
|
+
@glob = @root
|
14
|
+
|
15
|
+
if pattern[0] == '!'
|
16
|
+
@exclude = true
|
17
|
+
pattern = pattern[1..-1]
|
18
|
+
end
|
19
|
+
|
20
|
+
if pattern.start_with?('/')
|
21
|
+
pattern = pattern[1..-1]
|
22
|
+
else
|
23
|
+
@glob = @glob.join('**')
|
24
|
+
end
|
25
|
+
|
26
|
+
@glob = @glob.join(pattern).to_s
|
27
|
+
end
|
28
|
+
|
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
|
+
def match?(file)
|
40
|
+
file = Pathname.new(file)
|
41
|
+
file = @root.join(file) unless file.absolute?
|
42
|
+
|
43
|
+
File.fnmatch?(glob, file.to_s, GLOB_OPTIONS)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require_relative "code_manifest/version"
|
5
|
+
require_relative "code_manifest/manifest"
|
6
|
+
|
7
|
+
module CodeManifest
|
8
|
+
class Error < StandardError; end
|
9
|
+
|
10
|
+
DOTFILE = '.code_manifest.yml'.freeze
|
11
|
+
KEY_PATTERN = /[a-z_0-9]+/.freeze
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def [](name)
|
15
|
+
manifests[name.to_s]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def manifests
|
21
|
+
@manifests ||= begin
|
22
|
+
config_file = traverse_files(DOTFILE, Dir.pwd)
|
23
|
+
|
24
|
+
raise "#{DOTFILE} was not found in your project directory, please check README for instructions." unless config_file
|
25
|
+
|
26
|
+
root = Pathname.new(config_file).dirname
|
27
|
+
|
28
|
+
YAML.load_file(config_file).each_with_object({}) do |(name, patterns), collection|
|
29
|
+
next unless name.match?(KEY_PATTERN)
|
30
|
+
|
31
|
+
if collection.key?(name)
|
32
|
+
raise ArgumentError, "#{name} defined multiple times in #{DOTFILE}"
|
33
|
+
end
|
34
|
+
|
35
|
+
collection[name] = Manifest.new(root, patterns)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def traverse_files(filename, start_dir)
|
41
|
+
Pathname.new(start_dir).expand_path.ascend do |dir|
|
42
|
+
file = dir.join(filename)
|
43
|
+
return file.to_s if file.exist?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: code_manifest
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gusto Engineers
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-09-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
description: A code manifest
|
28
|
+
email:
|
29
|
+
- dev@gusto.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- lib/code_manifest.rb
|
36
|
+
- lib/code_manifest/manifest.rb
|
37
|
+
- lib/code_manifest/rule.rb
|
38
|
+
- lib/code_manifest/version.rb
|
39
|
+
homepage: https://github.com/rubyatscale/code_manifest
|
40
|
+
licenses: []
|
41
|
+
metadata:
|
42
|
+
homepage_uri: https://github.com/rubyatscale/code_manifest
|
43
|
+
source_code_uri: https://github.com/rubyatscale/code_manifest
|
44
|
+
changelog_uri: https://github.com/rubyatscale/code_manifest/blob/main/releases
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options: []
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.7'
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
requirements: []
|
60
|
+
rubygems_version: 3.3.7
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: A code manifest
|
64
|
+
test_files: []
|