buildkite-builder 2.3.0 → 3.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 +4 -4
- data/CHANGELOG.md +10 -0
- data/VERSION +1 -1
- data/lib/buildkite/builder/commands.rb +0 -1
- data/lib/buildkite/builder/loaders.rb +0 -1
- data/lib/buildkite/builder/pipeline.rb +8 -18
- data/lib/buildkite/builder.rb +0 -3
- metadata +6 -12
- data/lib/buildkite/builder/commands/files.rb +0 -24
- data/lib/buildkite/builder/file_resolver.rb +0 -59
- data/lib/buildkite/builder/github.rb +0 -71
- data/lib/buildkite/builder/loaders/manifests.rb +0 -23
- data/lib/buildkite/builder/manifest/rule.rb +0 -51
- data/lib/buildkite/builder/manifest.rb +0 -88
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b19e2a9c84be58408585027ddc221dd1b8d6b5f9303085f874a97b460eaf4b7f
|
|
4
|
+
data.tar.gz: 939afa112be8163360618af03a4d21241b3cdceebef90fee3501052d1258e2cc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 54cb436ddc5a4d68da270ae84e62af8902d15388d2d44edaf6f9cc0473bec0f7744286a8e8d9ed1ed5a9d15e8c46e23928a70a51c3078bc1426adb1a1a54c685
|
|
7
|
+
data.tar.gz: f67035e4e34f940c2a5b5c2fae14cda001e8185e20e2aa17db7d38574bf3ddcd5bccf47bd6ccf3a96e6325582a88b52cd8594df4a30f080d3eb712863b51ee6f
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 3.0.0
|
|
2
|
+
* Remove manifest features to prevent Github API dependency and simplify the gem to focus on Buildkite features.
|
|
3
|
+
|
|
4
|
+
## 2.4.1
|
|
5
|
+
* Fix pipeline upload as artifact logic.
|
|
6
|
+
|
|
7
|
+
## 2.4.0
|
|
8
|
+
* Upload custom pipeline artifacts in a single command.
|
|
9
|
+
* Only upload the pipeline as an artifact when the pipeline upload fails.
|
|
10
|
+
|
|
1
11
|
## 2.3.0
|
|
2
12
|
* Improve BKB step idempotency.
|
|
3
13
|
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.0.0
|
|
@@ -4,7 +4,6 @@ module Buildkite
|
|
|
4
4
|
module Builder
|
|
5
5
|
module Loaders
|
|
6
6
|
autoload :Abstract, File.expand_path('loaders/abstract', __dir__)
|
|
7
|
-
autoload :Manifests, File.expand_path('loaders/manifests', __dir__)
|
|
8
7
|
autoload :Templates, File.expand_path('loaders/templates', __dir__)
|
|
9
8
|
autoload :Extensions, File.expand_path('loaders/extensions', __dir__)
|
|
10
9
|
end
|
|
@@ -37,7 +37,6 @@ module Buildkite
|
|
|
37
37
|
use(Extensions::Env)
|
|
38
38
|
use(Extensions::Notify)
|
|
39
39
|
use(Extensions::Steps)
|
|
40
|
-
load_manifests
|
|
41
40
|
end
|
|
42
41
|
|
|
43
42
|
def upload
|
|
@@ -51,10 +50,12 @@ module Buildkite
|
|
|
51
50
|
file.sync = true
|
|
52
51
|
file.write(contents)
|
|
53
52
|
|
|
54
|
-
logger.info
|
|
55
|
-
Buildkite::Pipelines::Command.
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
logger.info "+++ :pipeline: Uploading pipeline"
|
|
54
|
+
unless Buildkite::Pipelines::Command.pipeline(:upload, file.path)
|
|
55
|
+
logger.info "Pipeline upload failed, saving as artifact…"
|
|
56
|
+
Buildkite::Pipelines::Command.artifact!(:upload, file.path)
|
|
57
|
+
abort
|
|
58
|
+
end
|
|
58
59
|
logger.info "+++ :toolbox: Setting job meta-data to #{Buildkite.env.job_id.color(:yellow)}"
|
|
59
60
|
Buildkite::Pipelines::Command.meta_data!(:set, Builder::META_DATA.fetch(:job), Buildkite.env.job_id)
|
|
60
61
|
end
|
|
@@ -80,22 +81,11 @@ module Buildkite
|
|
|
80
81
|
|
|
81
82
|
attr_reader :extensions
|
|
82
83
|
|
|
83
|
-
def load_manifests
|
|
84
|
-
Loaders::Manifests.load(root).each do |name, asset|
|
|
85
|
-
Manifest[name] = asset
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
|
|
89
84
|
def upload_artifacts
|
|
90
85
|
return if artifacts.empty?
|
|
91
86
|
|
|
92
|
-
logger.info "+++ :paperclip: Uploading
|
|
93
|
-
|
|
94
|
-
artifacts.each do |path|
|
|
95
|
-
if File.exist?(path)
|
|
96
|
-
Buildkite::Pipelines::Command.artifact!(:upload, path)
|
|
97
|
-
end
|
|
98
|
-
end
|
|
87
|
+
logger.info "+++ :paperclip: Uploading artifacts"
|
|
88
|
+
Buildkite::Pipelines::Command.artifact!(:upload, artifacts.join(";"))
|
|
99
89
|
end
|
|
100
90
|
|
|
101
91
|
def pipeline_definition
|
data/lib/buildkite/builder.rb
CHANGED
|
@@ -13,11 +13,8 @@ module Buildkite
|
|
|
13
13
|
autoload :Extension, File.expand_path('builder/extension', __dir__)
|
|
14
14
|
autoload :ExtensionManager, File.expand_path('builder/extension_manager', __dir__)
|
|
15
15
|
autoload :Extensions, File.expand_path('builder/extensions', __dir__)
|
|
16
|
-
autoload :FileResolver, File.expand_path('builder/file_resolver', __dir__)
|
|
17
|
-
autoload :Github, File.expand_path('builder/github', __dir__)
|
|
18
16
|
autoload :Loaders, File.expand_path('builder/loaders', __dir__)
|
|
19
17
|
autoload :LoggingUtils, File.expand_path('builder/logging_utils', __dir__)
|
|
20
|
-
autoload :Manifest, File.expand_path('builder/manifest', __dir__)
|
|
21
18
|
autoload :Processors, File.expand_path('builder/processors', __dir__)
|
|
22
19
|
autoload :Rainbow, File.expand_path('builder/rainbow', __dir__)
|
|
23
20
|
autoload :Plugin, File.expand_path('builder/plugin', __dir__)
|
metadata
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: buildkite-builder
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ngan Pham
|
|
8
8
|
- Andrew Lee
|
|
9
|
-
autorequire:
|
|
9
|
+
autorequire:
|
|
10
10
|
bindir: exe
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2022-05-31 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: rainbow
|
|
@@ -116,7 +116,6 @@ files:
|
|
|
116
116
|
- lib/buildkite/builder.rb
|
|
117
117
|
- lib/buildkite/builder/commands.rb
|
|
118
118
|
- lib/buildkite/builder/commands/abstract.rb
|
|
119
|
-
- lib/buildkite/builder/commands/files.rb
|
|
120
119
|
- lib/buildkite/builder/commands/preview.rb
|
|
121
120
|
- lib/buildkite/builder/commands/run.rb
|
|
122
121
|
- lib/buildkite/builder/data.rb
|
|
@@ -130,17 +129,12 @@ files:
|
|
|
130
129
|
- lib/buildkite/builder/extensions/notify.rb
|
|
131
130
|
- lib/buildkite/builder/extensions/steps.rb
|
|
132
131
|
- lib/buildkite/builder/extensions/use.rb
|
|
133
|
-
- lib/buildkite/builder/file_resolver.rb
|
|
134
|
-
- lib/buildkite/builder/github.rb
|
|
135
132
|
- lib/buildkite/builder/group.rb
|
|
136
133
|
- lib/buildkite/builder/loaders.rb
|
|
137
134
|
- lib/buildkite/builder/loaders/abstract.rb
|
|
138
135
|
- lib/buildkite/builder/loaders/extensions.rb
|
|
139
|
-
- lib/buildkite/builder/loaders/manifests.rb
|
|
140
136
|
- lib/buildkite/builder/loaders/templates.rb
|
|
141
137
|
- lib/buildkite/builder/logging_utils.rb
|
|
142
|
-
- lib/buildkite/builder/manifest.rb
|
|
143
|
-
- lib/buildkite/builder/manifest/rule.rb
|
|
144
138
|
- lib/buildkite/builder/pipeline.rb
|
|
145
139
|
- lib/buildkite/builder/plugin.rb
|
|
146
140
|
- lib/buildkite/builder/plugin_collection.rb
|
|
@@ -181,7 +175,7 @@ metadata:
|
|
|
181
175
|
source_code_uri: https://github.com/Gusto/buildkite-builder
|
|
182
176
|
changelog_uri: https://github.com/Gusto/buildkite-builder/blob/master/CHANGELOG.md
|
|
183
177
|
bug_tracker_uri: https://github.com/Gusto/buildkite-builder/issues
|
|
184
|
-
post_install_message:
|
|
178
|
+
post_install_message:
|
|
185
179
|
rdoc_options: []
|
|
186
180
|
require_paths:
|
|
187
181
|
- lib
|
|
@@ -196,8 +190,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
196
190
|
- !ruby/object:Gem::Version
|
|
197
191
|
version: '0'
|
|
198
192
|
requirements: []
|
|
199
|
-
rubygems_version: 3.
|
|
200
|
-
signing_key:
|
|
193
|
+
rubygems_version: 3.3.13
|
|
194
|
+
signing_key:
|
|
201
195
|
specification_version: 4
|
|
202
196
|
summary: A gem for programmatically creating Buildkite pipelines.
|
|
203
197
|
test_files: []
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Buildkite
|
|
4
|
-
module Builder
|
|
5
|
-
module Commands
|
|
6
|
-
class Files < Abstract
|
|
7
|
-
private
|
|
8
|
-
|
|
9
|
-
self.description = 'Outputs files that match the specified manifest.'
|
|
10
|
-
|
|
11
|
-
def run
|
|
12
|
-
manifests = Loaders::Manifests.load(pipeline_path)
|
|
13
|
-
puts manifests[options[:manifest]].files.sort.join("\n")
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def parse_options(opts)
|
|
17
|
-
opts.on('--manifest MANIFEST', 'The manifest to use') do |manifest|
|
|
18
|
-
options[:manifest] = manifest
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'open3'
|
|
4
|
-
require 'set'
|
|
5
|
-
|
|
6
|
-
module Buildkite
|
|
7
|
-
module Builder
|
|
8
|
-
class FileResolver
|
|
9
|
-
@cache = true
|
|
10
|
-
|
|
11
|
-
attr_reader :modified_files
|
|
12
|
-
|
|
13
|
-
class << self
|
|
14
|
-
attr_accessor :cache
|
|
15
|
-
|
|
16
|
-
def resolve(reset = false)
|
|
17
|
-
@resolve = nil if !cache || reset
|
|
18
|
-
@resolve ||= new
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def initialize
|
|
23
|
-
@modified_files = Set.new(pull_request? ? files_from_pull_request.sort! : files_from_git.sort!)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def files_from_pull_request
|
|
29
|
-
Github.pull_request_files.map { |f| f.fetch('filename') }
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def files_from_git
|
|
33
|
-
if Buildkite.env
|
|
34
|
-
changed_files = command("git diff-tree --no-commit-id --name-only -r #{Buildkite.env.commit}")
|
|
35
|
-
else
|
|
36
|
-
default_branch = command('git symbolic-ref refs/remotes/origin/HEAD').strip
|
|
37
|
-
changed_files = command("git diff --name-only #{default_branch}")
|
|
38
|
-
changed_files << command('git diff --name-only')
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
changed_files.split.uniq.sort
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def pull_request?
|
|
45
|
-
Buildkite.env&.pull_request
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def command(cmd)
|
|
49
|
-
output, status = Open3.capture2(*cmd.split)
|
|
50
|
-
|
|
51
|
-
if status.success?
|
|
52
|
-
output
|
|
53
|
-
else
|
|
54
|
-
raise "Command failed (exit #{status.exitstatus}): #{cmd}"
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
end
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'json'
|
|
4
|
-
require 'net/http'
|
|
5
|
-
require 'uri'
|
|
6
|
-
|
|
7
|
-
module Buildkite
|
|
8
|
-
module Builder
|
|
9
|
-
class Github
|
|
10
|
-
BASE_URI = URI('https://api.github.com').freeze
|
|
11
|
-
ACCEPT_HEADER = 'application/vnd.github.v3+json'
|
|
12
|
-
LINK_HEADER = 'link'
|
|
13
|
-
NEXT_LINK_REGEX = /<(?<uri>.+)>; rel="next"/.freeze
|
|
14
|
-
REPO_REGEX = /github\.com(?::|\/)(.*?)(?:\.git)?\z/.freeze
|
|
15
|
-
PER_PAGE = 100
|
|
16
|
-
|
|
17
|
-
def self.pull_request_files
|
|
18
|
-
new.pull_request_files
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def initialize(env = ENV)
|
|
22
|
-
@env = env
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def pull_request_files
|
|
26
|
-
files = []
|
|
27
|
-
next_uri = URI.join(BASE_URI, "repos/#{repo}/pulls/#{pull_request_number}/files?per_page=#{PER_PAGE}")
|
|
28
|
-
|
|
29
|
-
while next_uri
|
|
30
|
-
response = request(next_uri)
|
|
31
|
-
files.concat(JSON.parse(response.body))
|
|
32
|
-
next_uri = parse_next_uri(response)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
files
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
def repo
|
|
41
|
-
Buildkite.env.repo[REPO_REGEX, 1]
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def token
|
|
45
|
-
@env.fetch('GITHUB_API_TOKEN')
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def pull_request_number
|
|
49
|
-
Buildkite.env.pull_request
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def request(uri)
|
|
53
|
-
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
|
54
|
-
request = Net::HTTP::Get.new(uri)
|
|
55
|
-
request['Authorization'] = "token #{token}"
|
|
56
|
-
request['Accept'] = ACCEPT_HEADER
|
|
57
|
-
|
|
58
|
-
http.request(request)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def parse_next_uri(response)
|
|
63
|
-
links = response[LINK_HEADER]
|
|
64
|
-
return unless links
|
|
65
|
-
|
|
66
|
-
matches = links.match(NEXT_LINK_REGEX)
|
|
67
|
-
URI.parse(matches[:uri]) if matches
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Buildkite
|
|
4
|
-
module Builder
|
|
5
|
-
module Loaders
|
|
6
|
-
class Manifests < Abstract
|
|
7
|
-
MANIFESTS_PATH = Pathname.new('manifests').freeze
|
|
8
|
-
|
|
9
|
-
def load
|
|
10
|
-
return unless manifests_path.directory?
|
|
11
|
-
|
|
12
|
-
manifests_path.children.map do |file|
|
|
13
|
-
add(file.basename, Manifest.new(Buildkite::Builder.root, file.readlines))
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def manifests_path
|
|
18
|
-
root.join(MANIFESTS_PATH)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'set'
|
|
4
|
-
require 'pathname'
|
|
5
|
-
|
|
6
|
-
module Buildkite
|
|
7
|
-
module Builder
|
|
8
|
-
class Manifest::Rule
|
|
9
|
-
GLOB_OPTIONS = File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB
|
|
10
|
-
|
|
11
|
-
attr_reader :exclude
|
|
12
|
-
attr_reader :glob
|
|
13
|
-
|
|
14
|
-
def initialize(root, pattern)
|
|
15
|
-
@root = Pathname.new(root)
|
|
16
|
-
@exclude = false
|
|
17
|
-
@glob = @root
|
|
18
|
-
|
|
19
|
-
if pattern[0] == '!'
|
|
20
|
-
@exclude = true
|
|
21
|
-
pattern = pattern[1..-1]
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
if pattern.start_with?('/')
|
|
25
|
-
pattern = pattern[1..-1]
|
|
26
|
-
else
|
|
27
|
-
@glob = @glob.join('**')
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
@glob = @glob.join(pattern).to_s
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def files
|
|
34
|
-
@files ||= begin
|
|
35
|
-
matched = Dir.glob(glob, GLOB_OPTIONS)
|
|
36
|
-
matched.map! { |file| Pathname.new(file) }
|
|
37
|
-
matched.reject!(&:directory?)
|
|
38
|
-
matched.map! { |file| file.relative_path_from(Builder.root) }
|
|
39
|
-
Set.new(matched.sort!)
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def match?(file)
|
|
44
|
-
file = Pathname.new(file)
|
|
45
|
-
file = @root.join(file) unless file.absolute?
|
|
46
|
-
|
|
47
|
-
File.fnmatch?(glob, file.to_s, GLOB_OPTIONS)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'digest/md5'
|
|
4
|
-
require 'pathname'
|
|
5
|
-
|
|
6
|
-
module Buildkite
|
|
7
|
-
module Builder
|
|
8
|
-
class Manifest
|
|
9
|
-
autoload :Rule, File.expand_path('manifest/rule', __dir__)
|
|
10
|
-
|
|
11
|
-
class << self
|
|
12
|
-
def resolve(root, patterns)
|
|
13
|
-
new(root, Array(patterns)).modified?
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def manifests
|
|
17
|
-
@manifests ||= {}
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def [](name)
|
|
21
|
-
manifests[name.to_s]
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def []=(name, manifest)
|
|
25
|
-
name = name.to_s
|
|
26
|
-
if manifests.key?(name)
|
|
27
|
-
raise ArgumentError, "manifest #{name} already exists"
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
manifests[name] = manifest
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
attr_reader :root
|
|
35
|
-
|
|
36
|
-
def initialize(root, patterns)
|
|
37
|
-
@root = Pathname.new(root)
|
|
38
|
-
@root = Buildkite::Builder.root.join(@root) unless @root.absolute?
|
|
39
|
-
@patterns = patterns.map(&:to_s)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def modified?
|
|
43
|
-
# DO NOT intersect FileResolver with manifest files. If the manifest is
|
|
44
|
-
# large, the operation can be expensive. It's always cheaper to loop
|
|
45
|
-
# through the changed files and compare them against the rules.
|
|
46
|
-
unless defined?(@modified)
|
|
47
|
-
@modified = FileResolver.resolve.modified_files.any? do |file|
|
|
48
|
-
file = Buildkite::Builder.root.join(file)
|
|
49
|
-
inclusion_rules.any? { |rule| rule.match?(file) } &&
|
|
50
|
-
exclusion_rules.none? { |rule| rule.match?(file) }
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
@modified
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def files
|
|
58
|
-
@files ||= (inclusion_rules.map(&:files).reduce(Set.new, :merge) - exclusion_rules.map(&:files).reduce(Set.new, :merge)).sort.to_set
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def digest
|
|
62
|
-
@digest ||= begin
|
|
63
|
-
digests = files.map { |file| Digest::MD5.file(Buildkite::Builder.root.join(file)).hexdigest }
|
|
64
|
-
Digest::MD5.hexdigest(digests.join)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
private
|
|
69
|
-
|
|
70
|
-
def rules
|
|
71
|
-
@rules ||= @patterns.each_with_object([]) do |pattern, rules|
|
|
72
|
-
pattern = pattern.strip
|
|
73
|
-
unless pattern.match?(/\A(#|\z)/)
|
|
74
|
-
rules << Rule.new(root, pattern)
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def inclusion_rules
|
|
80
|
-
@inclusion_rules ||= rules.reject(&:exclude)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def exclusion_rules
|
|
84
|
-
@exclusion_rules ||= rules.select(&:exclude)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|