between_meals 0.0.7 → 0.0.12
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 +5 -5
- data/README.md +6 -4
- data/lib/between_meals/changes/change.rb +3 -6
- data/lib/between_meals/changes/cookbook.rb +88 -22
- data/lib/between_meals/changes/databag.rb +3 -1
- data/lib/between_meals/changes/role.rb +3 -1
- data/lib/between_meals/changeset.rb +9 -3
- data/lib/between_meals/cmd.rb +15 -5
- data/lib/between_meals/knife.rb +50 -21
- data/lib/between_meals/repo.rb +8 -2
- data/lib/between_meals/repo/git.rb +28 -20
- data/lib/between_meals/repo/git/cmd.rb +5 -1
- data/lib/between_meals/repo/hg.rb +25 -26
- data/lib/between_meals/repo/hg/cmd.rb +1 -1
- data/lib/between_meals/repo/svn.rb +5 -6
- data/lib/between_meals/util.rb +44 -18
- metadata +23 -108
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 21f7e5e4186f163af47afb9a74c9f877d12949c3a637232747eb1fbfd1e9b845
|
4
|
+
data.tar.gz: 3e5e53f85e47ae60291c05c83e244e4d3414e4984443b9471ef4711aad36e937
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ae9b2b8ad9a02e11dbbbce04bd8fb9e240f2c9af5ae4aa6bd709cc8a18e5453705d3bb41729ac4dd699c016aebbd658b62f0021779af47202c54882554d3d25
|
7
|
+
data.tar.gz: 138c9464b07cd6f797ac41fcb91bd360db357db3ca26a2ccca12b21f0d8afbabd99919e41129ae40a2f2b75e4ac1749822eeb291d126eb44172c42d39b109663
|
data/README.md
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# Between Meals
|
2
2
|
|
3
|
-
|
3
|
+

|
4
4
|
|
5
5
|
## Intro
|
6
6
|
Ohai!
|
7
7
|
|
8
|
-
Between Meals is the library for calculating what Chef objects
|
8
|
+
Between Meals is the library for calculating what Chef objects were modified
|
9
9
|
between two revisions in a version control system. It is also the library
|
10
|
-
that
|
10
|
+
that backs Taste Tester and Grocery Delivery.
|
11
11
|
|
12
12
|
It currently supports SVN, GIT and HG, but plugins can easily be written for
|
13
13
|
other source control systems.
|
@@ -18,7 +18,9 @@ functions.
|
|
18
18
|
## Dependencies
|
19
19
|
|
20
20
|
* Colorize
|
21
|
-
* JSON
|
22
21
|
* Mixlib::ShellOut
|
23
22
|
* Rugged
|
24
23
|
|
24
|
+
## License
|
25
|
+
|
26
|
+
See the `LICENSE` file in this repo.
|
@@ -37,15 +37,11 @@ module BetweenMeals
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.info(msg)
|
40
|
-
|
41
|
-
@@logger.info(msg)
|
42
|
-
end
|
40
|
+
@@logger&.info(msg)
|
43
41
|
end
|
44
42
|
|
45
43
|
def self.debug(msg)
|
46
|
-
|
47
|
-
@@logger.debug(msg)
|
48
|
-
end
|
44
|
+
@@logger&.debug(msg)
|
49
45
|
end
|
50
46
|
|
51
47
|
def info(msg)
|
@@ -58,3 +54,4 @@ module BetweenMeals
|
|
58
54
|
end
|
59
55
|
end
|
60
56
|
end
|
57
|
+
# rubocop:enable ClassVars
|
@@ -14,27 +14,21 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
# rubocop:disable ClassVars
|
18
17
|
module BetweenMeals
|
19
18
|
module Changes
|
20
19
|
# Changeset aware cookbook
|
21
20
|
class Cookbook < Change
|
22
|
-
def self.meaningful_cookbook_file?(path
|
23
|
-
|
24
|
-
re = %r{^#{dir}/([^/]+)/.*}
|
25
|
-
m = path.match(re)
|
26
|
-
debug("[cookbook] #{path} meaningful? [#{re}]: #{m}")
|
27
|
-
return true if m
|
28
|
-
end
|
29
|
-
false
|
21
|
+
def self.meaningful_cookbook_file?(path)
|
22
|
+
!explode_path(path).nil?
|
30
23
|
end
|
31
24
|
|
32
|
-
def self.explode_path(path
|
33
|
-
cookbook_dirs.each do |dir|
|
25
|
+
def self.explode_path(path)
|
26
|
+
@cookbook_dirs.each do |dir|
|
34
27
|
re = %r{^#{dir}/([^/]+)/.*}
|
35
28
|
debug("[cookbook] Matching #{path} against ^#{re}")
|
36
29
|
m = path.match(re)
|
37
30
|
next unless m
|
31
|
+
|
38
32
|
info("Cookbook is #{m[1]}")
|
39
33
|
return {
|
40
34
|
:cookbook_dir => dir,
|
@@ -44,21 +38,87 @@ module BetweenMeals
|
|
44
38
|
nil
|
45
39
|
end
|
46
40
|
|
41
|
+
def self.map_symlinks(files)
|
42
|
+
# For each symlink get the source path, if any files have changed under
|
43
|
+
# the source path, fake them as coming from the symlink path. This
|
44
|
+
# allows the normal cookbook logic to just work.
|
45
|
+
symlinks = {}
|
46
|
+
@cookbook_dirs.each do |dir|
|
47
|
+
dir = File.join(@repo_dir, dir)
|
48
|
+
# Find symlinks in each cookbook_dir
|
49
|
+
links = Dir.foreach(dir).select do |d|
|
50
|
+
File.symlink?(File.join(dir, d))
|
51
|
+
end
|
52
|
+
links.each do |link|
|
53
|
+
link = File.join(dir, link)
|
54
|
+
next if symlinks[link]
|
55
|
+
|
56
|
+
source = File.realpath(link)
|
57
|
+
repo = File.join(@repo_dir, '/')
|
58
|
+
# maps absolute symlink path to relative source and link paths
|
59
|
+
symlinks[link] = {
|
60
|
+
'source' => source.gsub(repo, ''),
|
61
|
+
'link' => link.gsub(repo, ''),
|
62
|
+
}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Create the file hash expected for each file that is a link or coming
|
67
|
+
# from a linked directory but fake the source path as a symlink path.
|
68
|
+
# Hacky but works :)
|
69
|
+
links_to_append = []
|
70
|
+
symlinks.each_value do |lrp| # link_abs_path, link_relative_path
|
71
|
+
files.each do |f|
|
72
|
+
# a symlink will never have trailing '/', add one.
|
73
|
+
f[:path] += '/' if f[:path] == lrp['link']
|
74
|
+
|
75
|
+
# If a metadata file in the path of a symlink target directory has a
|
76
|
+
# deleted status, check if a metadata file exists in the symlink
|
77
|
+
# source directory. If so, mark it as modified to prevent deletion.
|
78
|
+
symlink_source_dir = File.join(@repo_dir, lrp['source'])
|
79
|
+
if (f[:path] == File.join(lrp['link'], 'metadata.rb') ||
|
80
|
+
f[:path] == File.join(lrp['link'], 'metadata.json')) &&
|
81
|
+
f[:status] == :deleted &&
|
82
|
+
(File.file?(File.join(symlink_source_dir, 'metadata.rb')) ||
|
83
|
+
File.file?(File.join(symlink_source_dir, 'metadata.json')))
|
84
|
+
f[:status] = :modified
|
85
|
+
end
|
86
|
+
|
87
|
+
next unless f[:path].start_with?(lrp['source'])
|
88
|
+
|
89
|
+
# This make a deep dup of the file hash
|
90
|
+
l = Marshal.load(Marshal.dump(f))
|
91
|
+
l[:path].gsub!(lrp['source'], lrp['link'])
|
92
|
+
links_to_append << l
|
93
|
+
end
|
94
|
+
end
|
95
|
+
links_to_append
|
96
|
+
end
|
97
|
+
|
47
98
|
def initialize(files, cookbook_dirs)
|
48
99
|
@files = files
|
49
|
-
@
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
# if metadata.rb is being deleted
|
100
|
+
@cookbook_dirs = cookbook_dirs
|
101
|
+
@name = self.class.explode_path(files.sample[:path])[:name]
|
102
|
+
# if metadata.(json|rb) is being deleted and we aren't also
|
103
|
+
# adding/modifying one of those two,
|
54
104
|
# cookbook is marked for deletion
|
55
105
|
# otherwise it was modified
|
56
106
|
# and will be re-uploaded
|
57
107
|
if files.
|
58
108
|
select { |x| x[:status] == :deleted }.
|
59
|
-
map
|
109
|
+
map do |x|
|
110
|
+
x[:path].match(
|
111
|
+
%{^(#{cookbook_dirs.join('|')})/[^/]+/metadata\.(rb|json)$},
|
112
|
+
)
|
113
|
+
end.
|
60
114
|
compact.
|
61
|
-
any?
|
115
|
+
any? &&
|
116
|
+
files.reject { |x| x[:status] == :deleted }.
|
117
|
+
map do |x|
|
118
|
+
x[:path].match(
|
119
|
+
%{^(#{cookbook_dirs.join('|')})/[^/]+/metadata\.(rb|json)$},
|
120
|
+
)
|
121
|
+
end.none?
|
62
122
|
@status = :deleted
|
63
123
|
else
|
64
124
|
@status = :modified
|
@@ -67,16 +127,22 @@ module BetweenMeals
|
|
67
127
|
|
68
128
|
# Given a list of changed files
|
69
129
|
# create a list of Cookbook objects
|
70
|
-
def self.find(list, cookbook_dirs, logger)
|
130
|
+
def self.find(list, cookbook_dirs, logger, repo, track_symlinks = false)
|
131
|
+
# rubocop:disable ClassVars
|
71
132
|
@@logger = logger
|
133
|
+
# rubocop:enable ClassVars
|
72
134
|
return [] if list.nil? || list.empty?
|
135
|
+
|
73
136
|
# rubocop:disable MultilineBlockChain
|
137
|
+
@repo_dir = File.realpath(repo.repo_path)
|
138
|
+
@cookbook_dirs = cookbook_dirs
|
139
|
+
list += map_symlinks(list) if track_symlinks
|
74
140
|
list.
|
75
141
|
group_by do |x|
|
76
142
|
# Group by prefix of cookbok_dir + cookbook_name
|
77
143
|
# so that we treat deletes and modifications across
|
78
144
|
# two locations separately
|
79
|
-
g = self.explode_path(x[:path]
|
145
|
+
g = self.explode_path(x[:path])
|
80
146
|
g[:cookbook_dir] + '/' + g[:name] if g
|
81
147
|
end.
|
82
148
|
map do |_, change|
|
@@ -84,10 +150,10 @@ module BetweenMeals
|
|
84
150
|
# Changes to OWNERS or other stuff that might end up
|
85
151
|
# in [core, other, secure] dirs are ignored
|
86
152
|
is_cookbook = change.select do |c|
|
87
|
-
self.meaningful_cookbook_file?(c[:path]
|
153
|
+
self.meaningful_cookbook_file?(c[:path])
|
88
154
|
end.any?
|
89
155
|
if is_cookbook
|
90
|
-
BetweenMeals::Changes::Cookbook.new(change, cookbook_dirs)
|
156
|
+
BetweenMeals::Changes::Cookbook.new(change, @cookbook_dirs)
|
91
157
|
end
|
92
158
|
end.compact
|
93
159
|
# rubocop:enable MultilineBlockChain
|
@@ -14,7 +14,6 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
# rubocop:disable ClassVars
|
18
17
|
module BetweenMeals
|
19
18
|
module Changes
|
20
19
|
# Changeset aware databag
|
@@ -37,8 +36,11 @@ module BetweenMeals
|
|
37
36
|
end
|
38
37
|
|
39
38
|
def self.find(list, databag_dir, logger)
|
39
|
+
# rubocop:disable ClassVars
|
40
40
|
@@logger = logger
|
41
|
+
# rubocop:enable ClassVars
|
41
42
|
return [] if list.nil? || list.empty?
|
43
|
+
|
42
44
|
list.
|
43
45
|
select { |x| self.name_from_path(x[:path], databag_dir) }.
|
44
46
|
map do |x|
|
@@ -14,7 +14,6 @@
|
|
14
14
|
# See the License for the specific language governing permissions and
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
|
-
# rubocop:disable ClassVars
|
18
17
|
module BetweenMeals
|
19
18
|
module Changes
|
20
19
|
# Changeset aware role
|
@@ -38,8 +37,11 @@ module BetweenMeals
|
|
38
37
|
# Given a list of changed files
|
39
38
|
# create a list of Role objects
|
40
39
|
def self.find(list, role_dir, logger)
|
40
|
+
# rubocop:disable ClassVars
|
41
41
|
@@logger = logger
|
42
|
+
# rubocop:enable ClassVars
|
42
43
|
return [] if list.nil? || list.empty?
|
44
|
+
|
43
45
|
list.
|
44
46
|
select { |x| self.name_from_path(x[:path], role_dir) }.
|
45
47
|
map do |x|
|
@@ -29,13 +29,17 @@ module BetweenMeals
|
|
29
29
|
class Changeset
|
30
30
|
class ReferenceError < RuntimeError
|
31
31
|
end
|
32
|
-
|
33
|
-
def initialize(
|
32
|
+
# rubocop:disable Metrics/ParameterLists
|
33
|
+
def initialize(
|
34
|
+
logger, repo, start_ref, end_ref, locations, track_symlinks = false
|
35
|
+
)
|
36
|
+
# rubocop:enable Metrics/ParameterLists
|
34
37
|
@logger = logger
|
35
38
|
@repo = repo
|
36
39
|
@cookbook_dirs = locations[:cookbook_dirs].dup
|
37
40
|
@role_dir = locations[:role_dir]
|
38
41
|
@databag_dir = locations[:databag_dir]
|
42
|
+
@track_symlinks = track_symlinks
|
39
43
|
# Figure out which files changed if refs provided
|
40
44
|
# or return all files (full upload) otherwise
|
41
45
|
if start_ref
|
@@ -49,7 +53,9 @@ module BetweenMeals
|
|
49
53
|
end
|
50
54
|
|
51
55
|
def cookbooks
|
52
|
-
BetweenMeals::Changes::Cookbook.find(
|
56
|
+
BetweenMeals::Changes::Cookbook.find(
|
57
|
+
@files, @cookbook_dirs, @logger, @repo, @track_symlinks
|
58
|
+
)
|
53
59
|
end
|
54
60
|
|
55
61
|
def roles
|
data/lib/between_meals/cmd.rb
CHANGED
@@ -26,18 +26,28 @@ module BetweenMeals
|
|
26
26
|
@logger = params[:logger] || Logger.new(STDOUT)
|
27
27
|
end
|
28
28
|
|
29
|
-
def cmd(params, cwd = nil)
|
30
|
-
|
31
|
-
cwd = File.expand_path(@cwd)
|
32
|
-
end
|
29
|
+
def cmd(params, cwd = nil, nofail = false)
|
30
|
+
cwd ||= File.expand_path(@cwd)
|
33
31
|
cmd = "#{@bin} #{params}"
|
34
32
|
@logger.info("Running \"#{cmd}\"")
|
35
33
|
c = Mixlib::ShellOut.new(
|
36
34
|
cmd,
|
37
35
|
:cwd => cwd,
|
36
|
+
:env => {
|
37
|
+
# macOS needs /usr/local/bin as hg cannot be installed in /bin or
|
38
|
+
# /usr/bin
|
39
|
+
'PATH' => '/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin',
|
40
|
+
},
|
38
41
|
)
|
39
42
|
c.run_command
|
40
|
-
|
43
|
+
# If the user asked us not to fail, let them handle error reporting
|
44
|
+
if c.error? && !nofail
|
45
|
+
# Let's make sure the error goes to the logs
|
46
|
+
@logger.error("#{@bin} failed: #{c.format_for_exception}")
|
47
|
+
# if our logger is STDOUT, we'll double log when we throw
|
48
|
+
# the exception, but that's OK
|
49
|
+
c.error!
|
50
|
+
end
|
41
51
|
c
|
42
52
|
end
|
43
53
|
end
|
data/lib/between_meals/knife.rb
CHANGED
@@ -26,6 +26,8 @@ module BetweenMeals
|
|
26
26
|
class Knife
|
27
27
|
include BetweenMeals::Util
|
28
28
|
|
29
|
+
attr_accessor :cookbook_dirs
|
30
|
+
|
29
31
|
def initialize(opts = {})
|
30
32
|
@logger = opts[:logger] || nil
|
31
33
|
@user = opts[:user] || ENV['USER']
|
@@ -37,6 +39,14 @@ module BetweenMeals
|
|
37
39
|
@config = opts[:config] ||
|
38
40
|
"#{@home}/.chef/knife-#{@user}-taste-tester.rb"
|
39
41
|
@knife = opts[:bin] || 'knife'
|
42
|
+
@knife_verb_option = ''
|
43
|
+
unless @logger.nil?
|
44
|
+
if @logger.level == Logger::DEBUG
|
45
|
+
@knife_verb_option = '-VV'
|
46
|
+
elsif @logger.level == Logger::INFO
|
47
|
+
@knife_verb_option = '-V'
|
48
|
+
end
|
49
|
+
end
|
40
50
|
@berks = opts[:berks_bin] || 'berks'
|
41
51
|
@berks_config = opts[:berks_config]
|
42
52
|
@pem = opts[:pem] ||
|
@@ -51,9 +61,10 @@ module BetweenMeals
|
|
51
61
|
end
|
52
62
|
|
53
63
|
def role_upload_all
|
54
|
-
if File.
|
64
|
+
if File.exist?(@role_dir)
|
55
65
|
roles = File.join(@role_dir, "*.#{@role_type}")
|
56
|
-
exec!("#{@knife} role from file #{roles}
|
66
|
+
exec!("#{@knife} role from file #{roles} #{@knife_verb_option} " +
|
67
|
+
"-c #{@config}", @logger)
|
57
68
|
end
|
58
69
|
end
|
59
70
|
|
@@ -62,22 +73,23 @@ module BetweenMeals
|
|
62
73
|
roles = roles.map do |x|
|
63
74
|
File.join(@role_dir, "#{x.name}.#{@role_type}")
|
64
75
|
end.join(' ')
|
65
|
-
exec!("#{@knife} role from file #{roles}
|
76
|
+
exec!("#{@knife} role from file #{roles} #{@knife_verb_option} " +
|
77
|
+
"-c #{@config}", @logger)
|
66
78
|
end
|
67
79
|
end
|
68
80
|
|
69
81
|
def role_delete(roles)
|
70
82
|
if roles.any?
|
71
83
|
roles.each do |role|
|
72
|
-
exec!(
|
73
|
-
"
|
74
|
-
)
|
84
|
+
exec!("#{@knife} role delete #{role.name} #{@knife_verb_option} " +
|
85
|
+
"--yes -c #{@config}", @logger)
|
75
86
|
end
|
76
87
|
end
|
77
88
|
end
|
78
89
|
|
79
90
|
def cookbook_upload_all
|
80
|
-
exec!("#{@knife} cookbook upload -a
|
91
|
+
exec!("#{@knife} cookbook upload -a #{@knife_verb_option} " +
|
92
|
+
"-c #{@config}", @logger)
|
81
93
|
end
|
82
94
|
|
83
95
|
def berks_cookbook_upload_all
|
@@ -97,7 +109,8 @@ module BetweenMeals
|
|
97
109
|
def cookbook_upload(cookbooks)
|
98
110
|
if cookbooks.any?
|
99
111
|
cookbooks = cookbooks.map(&:name).join(' ')
|
100
|
-
exec!("#{@knife} cookbook upload #{cookbooks}
|
112
|
+
exec!("#{@knife} cookbook upload #{cookbooks} #{@knife_verb_option} " +
|
113
|
+
"-c #{@config}", @logger)
|
101
114
|
end
|
102
115
|
end
|
103
116
|
|
@@ -110,7 +123,8 @@ module BetweenMeals
|
|
110
123
|
if cookbooks.any?
|
111
124
|
@cookbook_dirs.each do |path|
|
112
125
|
cookbooks.each do |cb|
|
113
|
-
next unless File.
|
126
|
+
next unless File.exist?("#{path}/#{cb}")
|
127
|
+
|
114
128
|
@logger.warn("Running berkshelf on cookbook: #{cb}")
|
115
129
|
exec!("cd #{path}/#{cb} && #{@berks} install #{berks_config} && " +
|
116
130
|
"#{@berks} upload #{berks_config}", @logger)
|
@@ -123,7 +137,8 @@ module BetweenMeals
|
|
123
137
|
if cookbooks.any?
|
124
138
|
cookbooks.each do |cookbook|
|
125
139
|
exec!("#{@knife} cookbook delete #{cookbook.name}" +
|
126
|
-
" --purge -a --yes -c #{@config}",
|
140
|
+
" --purge -a --yes #{@knife_verb_option} -c #{@config}",
|
141
|
+
@logger)
|
127
142
|
end
|
128
143
|
end
|
129
144
|
end
|
@@ -146,7 +161,8 @@ module BetweenMeals
|
|
146
161
|
File.join(@databag_dir, dbname, "#{x.item}.json")
|
147
162
|
end.join(' ')
|
148
163
|
exec!(
|
149
|
-
"#{@knife} data bag from file #{dbname} #{dbitems}
|
164
|
+
"#{@knife} data bag from file #{dbname} #{dbitems} " +
|
165
|
+
"#{@knife_verb_option} -c #{@config}",
|
150
166
|
@logger,
|
151
167
|
)
|
152
168
|
end
|
@@ -158,7 +174,7 @@ module BetweenMeals
|
|
158
174
|
databags.group_by(&:name).each do |dbname, dbs|
|
159
175
|
dbs.each do |db|
|
160
176
|
exec!("#{@knife} data bag delete #{dbname} #{db.item}" +
|
161
|
-
" --yes -c #{@config}", @logger)
|
177
|
+
" --yes #{@knife_verb_option} -c #{@config}", @logger)
|
162
178
|
end
|
163
179
|
delete_databag_if_empty(dbname)
|
164
180
|
end
|
@@ -183,10 +199,13 @@ BLOCK
|
|
183
199
|
cfg << " \"#{dir}\",\n"
|
184
200
|
end
|
185
201
|
cfg << "]\n"
|
186
|
-
|
202
|
+
begin
|
187
203
|
Dir.mkdir(File.dirname(@config), 0o755)
|
204
|
+
rescue Errno::EEXIST
|
205
|
+
# not an error if it's already there.
|
206
|
+
nil
|
188
207
|
end
|
189
|
-
if !File.
|
208
|
+
if !File.exist?(@config) ||
|
190
209
|
::Digest::MD5.hexdigest(cfg) !=
|
191
210
|
::Digest::MD5.hexdigest(File.read(@config))
|
192
211
|
@logger.info("Generating #{@config}")
|
@@ -223,9 +242,16 @@ zvgEHqbS0/QkJGOZ+UifPRanTDuGYQkPdHHOER4UghbM+Kz5rZbBicJ3bCyNOsah
|
|
223
242
|
IAMAEpsWX2s2A6phgMCx7kH6wMmoZn3hb7Thh9+PfR8Jtp2/7k+ibCeF4gEWUCs5
|
224
243
|
6wX4GR84dwyhG80yd4TP8Qo=
|
225
244
|
-----END PRIVATE KEY-----
|
226
|
-
|
245
|
+
BLOCK
|
246
|
+
|
247
|
+
begin
|
248
|
+
Dir.mkdir(File.dirname(@pem), 0o755)
|
249
|
+
rescue Errno::EEXIST
|
250
|
+
# not an error if it's already there.
|
251
|
+
nil
|
252
|
+
end
|
227
253
|
|
228
|
-
unless File.
|
254
|
+
unless File.exist?(@pem)
|
229
255
|
@logger.info("Generating #{@pem}")
|
230
256
|
File.write(@pem, pem)
|
231
257
|
end
|
@@ -235,22 +261,25 @@ IAMAEpsWX2s2A6phgMCx7kH6wMmoZn3hb7Thh9+PfR8Jtp2/7k+ibCeF4gEWUCs5
|
|
235
261
|
|
236
262
|
def create_databag_if_missing(databag)
|
237
263
|
s = Mixlib::ShellOut.new("#{@knife} data bag list" +
|
238
|
-
" --format json
|
264
|
+
" --format json #{@knife_verb_option} " +
|
265
|
+
"-c #{@config}").run_command
|
239
266
|
s.error!
|
240
267
|
db = JSON.parse(s.stdout)
|
241
268
|
unless db.include?(databag)
|
242
|
-
exec!("#{@knife} data bag create #{databag}
|
269
|
+
exec!("#{@knife} data bag create #{databag} #{@knife_verb_option} " +
|
270
|
+
"-c #{@config}", @logger)
|
243
271
|
end
|
244
272
|
end
|
245
273
|
|
246
274
|
def delete_databag_if_empty(databag)
|
247
275
|
s = Mixlib::ShellOut.new("#{@knife} data bag show #{databag}" +
|
248
|
-
" --format json
|
276
|
+
" --format json #{@knife_verb_option} " +
|
277
|
+
"-c #{@config}").run_command
|
249
278
|
s.error!
|
250
279
|
db = JSON.parse(s.stdout)
|
251
280
|
if db.empty?
|
252
|
-
exec!("#{@knife} data bag delete #{databag} --yes
|
253
|
-
|
281
|
+
exec!("#{@knife} data bag delete #{databag} --yes " +
|
282
|
+
"#{@knife_verb_option} -c #{@config}", @logger)
|
254
283
|
end
|
255
284
|
end
|
256
285
|
end
|
data/lib/between_meals/repo.rb
CHANGED
@@ -27,7 +27,7 @@ module BetweenMeals
|
|
27
27
|
@repo = nil
|
28
28
|
@bin = nil
|
29
29
|
setup
|
30
|
-
rescue
|
30
|
+
rescue StandardError
|
31
31
|
@logger.warn("Unable to read repo from #{File.expand_path(repo_path)}")
|
32
32
|
exit(1)
|
33
33
|
end
|
@@ -54,7 +54,7 @@ module BetweenMeals
|
|
54
54
|
logger.info("Repo found to be #{klass.to_s.split('::').last}")
|
55
55
|
return r
|
56
56
|
end
|
57
|
-
rescue
|
57
|
+
rescue StandardError
|
58
58
|
logger.debug("Skipping #{klass}")
|
59
59
|
end
|
60
60
|
end
|
@@ -87,6 +87,12 @@ module BetweenMeals
|
|
87
87
|
fail "#{__method__} not implemented"
|
88
88
|
end
|
89
89
|
|
90
|
+
# Only interesting in the case of git where we have an underlying
|
91
|
+
# repo object courtesy of Rugged.
|
92
|
+
def repo_object
|
93
|
+
fail "#{__method__} not implemented"
|
94
|
+
end
|
95
|
+
|
90
96
|
# This method *must* succeed in the case of no repo directory so that
|
91
97
|
# users can call `checkout`. Users may call `exists?` to find out if
|
92
98
|
# we have an underlying repo yet.
|
@@ -26,10 +26,10 @@ module BetweenMeals
|
|
26
26
|
class Repo
|
27
27
|
class Git < BetweenMeals::Repo
|
28
28
|
def setup
|
29
|
-
if File.
|
29
|
+
if File.exist?(File.expand_path(@repo_path))
|
30
30
|
begin
|
31
31
|
@repo = Rugged::Repository.new(File.expand_path(@repo_path))
|
32
|
-
rescue
|
32
|
+
rescue StandardError
|
33
33
|
@repo = nil
|
34
34
|
end
|
35
35
|
else
|
@@ -43,6 +43,12 @@ module BetweenMeals
|
|
43
43
|
)
|
44
44
|
end
|
45
45
|
|
46
|
+
# Allow people to get access to the underlying Rugged
|
47
|
+
# object for their hooks
|
48
|
+
def repo_object
|
49
|
+
@repo
|
50
|
+
end
|
51
|
+
|
46
52
|
def exists?
|
47
53
|
!@repo.nil?
|
48
54
|
end
|
@@ -86,7 +92,7 @@ module BetweenMeals
|
|
86
92
|
stdout = @cmd.diff(start_ref, end_ref).stdout
|
87
93
|
begin
|
88
94
|
parse_status(stdout).compact
|
89
|
-
rescue => e
|
95
|
+
rescue StandardError => e
|
90
96
|
# We've seen some weird non-reproducible failures here
|
91
97
|
@logger.error(
|
92
98
|
'Something went wrong. Please report this output.',
|
@@ -108,12 +114,13 @@ module BetweenMeals
|
|
108
114
|
@repo.index.map { |x| { :path => x[:path], :status => :created } }
|
109
115
|
end
|
110
116
|
|
111
|
-
def upstream?(rev, master = '
|
117
|
+
def upstream?(rev, master = 'upstream/master')
|
112
118
|
if @cmd.merge_base(rev, master).stdout.strip == rev
|
113
119
|
return true
|
114
120
|
end
|
121
|
+
|
115
122
|
return false
|
116
|
-
rescue
|
123
|
+
rescue StandardError
|
117
124
|
return false
|
118
125
|
end
|
119
126
|
|
@@ -153,53 +160,54 @@ module BetweenMeals
|
|
153
160
|
|
154
161
|
# rubocop:disable MultilineBlockChain
|
155
162
|
changes.lines.map do |line|
|
156
|
-
|
157
|
-
|
163
|
+
parts = line.chomp.split("\t")
|
164
|
+
case parts[0]
|
165
|
+
when 'A'
|
158
166
|
# A path
|
159
167
|
{
|
160
168
|
:status => :modified,
|
161
|
-
:path =>
|
169
|
+
:path => parts[1],
|
162
170
|
}
|
163
|
-
when /^C(?:\d*)
|
171
|
+
when /^C(?:\d*)/
|
164
172
|
# C<numbers> path1 path2
|
165
173
|
{
|
166
174
|
:status => :modified,
|
167
|
-
:path =>
|
175
|
+
:path => parts[2],
|
168
176
|
}
|
169
|
-
when
|
177
|
+
when 'D'
|
170
178
|
# D path
|
171
179
|
{
|
172
180
|
:status => :deleted,
|
173
|
-
:path =>
|
181
|
+
:path => parts[1],
|
174
182
|
}
|
175
|
-
when /^M(?:\d*)
|
183
|
+
when /^M(?:\d*)/
|
176
184
|
# M<numbers> path
|
177
185
|
{
|
178
186
|
:status => :modified,
|
179
|
-
:path =>
|
187
|
+
:path => parts[1],
|
180
188
|
}
|
181
|
-
when /^R(?:\d*)
|
189
|
+
when /^R(?:\d*)/
|
182
190
|
# R<numbers> path1 path2
|
183
191
|
[
|
184
192
|
{
|
185
193
|
:status => :deleted,
|
186
|
-
:path =>
|
194
|
+
:path => parts[1],
|
187
195
|
},
|
188
196
|
{
|
189
197
|
:status => :modified,
|
190
|
-
:path =>
|
198
|
+
:path => parts[2],
|
191
199
|
},
|
192
200
|
]
|
193
|
-
when
|
201
|
+
when 'T'
|
194
202
|
# T path
|
195
203
|
[
|
196
204
|
{
|
197
205
|
:status => :deleted,
|
198
|
-
:path =>
|
206
|
+
:path => parts[1],
|
199
207
|
},
|
200
208
|
{
|
201
209
|
:status => :modified,
|
202
|
-
:path =>
|
210
|
+
:path => parts[1],
|
203
211
|
},
|
204
212
|
]
|
205
213
|
else
|
@@ -21,7 +21,11 @@ module BetweenMeals
|
|
21
21
|
class Git < BetweenMeals::Repo
|
22
22
|
class Cmd < BetweenMeals::Cmd
|
23
23
|
def config(key)
|
24
|
-
cmd("config #{key}")
|
24
|
+
s = cmd("config #{key}", nil, true)
|
25
|
+
unless [0, 1].include?(s.exitstatus)
|
26
|
+
s.error!
|
27
|
+
end
|
28
|
+
s
|
25
29
|
end
|
26
30
|
|
27
31
|
def clone(url, repo_path)
|
@@ -32,7 +32,7 @@ module BetweenMeals
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def exists?
|
35
|
-
Dir.
|
35
|
+
Dir.exist?(Pathname.new(@repo_path).join('.hg'))
|
36
36
|
end
|
37
37
|
|
38
38
|
def head_rev
|
@@ -50,7 +50,7 @@ module BetweenMeals
|
|
50
50
|
stdout = @cmd.status(start_ref, end_ref).stdout
|
51
51
|
begin
|
52
52
|
parse_status(stdout).compact
|
53
|
-
rescue => e
|
53
|
+
rescue StandardError => e
|
54
54
|
# We've seen some weird non-reproducible failures here
|
55
55
|
@logger.error(
|
56
56
|
'Something went wrong. Please report this output.',
|
@@ -65,9 +65,9 @@ module BetweenMeals
|
|
65
65
|
|
66
66
|
def update
|
67
67
|
@cmd.pull.stdout
|
68
|
-
rescue
|
68
|
+
rescue StandardError => e
|
69
69
|
@logger.error('Something went wrong with hg!')
|
70
|
-
@logger.error(
|
70
|
+
@logger.error(e)
|
71
71
|
raise
|
72
72
|
end
|
73
73
|
|
@@ -83,7 +83,7 @@ module BetweenMeals
|
|
83
83
|
:time => Time.parse(@cmd.log('date|isodate', 'master').stdout),
|
84
84
|
:rev => @cmd.log('node', 'master').stdout,
|
85
85
|
}]
|
86
|
-
rescue
|
86
|
+
rescue StandardError
|
87
87
|
[{
|
88
88
|
:time => nil,
|
89
89
|
:rev => nil,
|
@@ -103,7 +103,7 @@ module BetweenMeals
|
|
103
103
|
|
104
104
|
def last_msg
|
105
105
|
@cmd.log('desc').stdout
|
106
|
-
rescue
|
106
|
+
rescue StandardError
|
107
107
|
nil
|
108
108
|
end
|
109
109
|
|
@@ -115,13 +115,13 @@ module BetweenMeals
|
|
115
115
|
|
116
116
|
def email
|
117
117
|
username[2]
|
118
|
-
rescue
|
118
|
+
rescue StandardError
|
119
119
|
nil
|
120
120
|
end
|
121
121
|
|
122
122
|
def name
|
123
123
|
username[1]
|
124
|
-
rescue
|
124
|
+
rescue StandardError
|
125
125
|
nil
|
126
126
|
end
|
127
127
|
|
@@ -143,7 +143,7 @@ module BetweenMeals
|
|
143
143
|
def valid_ref?(ref)
|
144
144
|
@cmd.rev(ref)
|
145
145
|
return true
|
146
|
-
rescue
|
146
|
+
rescue StandardError
|
147
147
|
raise Changeset::ReferenceError
|
148
148
|
end
|
149
149
|
|
@@ -165,49 +165,48 @@ module BetweenMeals
|
|
165
165
|
# I = ignored
|
166
166
|
# = origin of the previous file (with --copies)
|
167
167
|
|
168
|
-
# rubocop:disable MultilineBlockChain
|
169
168
|
changes.lines.map do |line|
|
170
|
-
|
171
|
-
|
169
|
+
parts = line.chomp.split(nil, 2)
|
170
|
+
case parts[0]
|
171
|
+
when 'A'
|
172
172
|
{
|
173
173
|
:status => :added,
|
174
|
-
:path =>
|
174
|
+
:path => parts[1],
|
175
175
|
}
|
176
|
-
when
|
176
|
+
when 'C'
|
177
177
|
{
|
178
178
|
:status => :clean,
|
179
|
-
:path =>
|
179
|
+
:path => parts[1],
|
180
180
|
}
|
181
|
-
when
|
181
|
+
when 'R'
|
182
182
|
{
|
183
183
|
:status => :deleted,
|
184
|
-
:path =>
|
184
|
+
:path => parts[1],
|
185
185
|
}
|
186
|
-
when
|
186
|
+
when 'M'
|
187
187
|
{
|
188
188
|
:status => :modified,
|
189
|
-
:path =>
|
189
|
+
:path => parts[1],
|
190
190
|
}
|
191
|
-
when
|
191
|
+
when '!'
|
192
192
|
{
|
193
193
|
:status => :missing,
|
194
|
-
:path =>
|
194
|
+
:path => parts[1],
|
195
195
|
}
|
196
|
-
when
|
196
|
+
when '?'
|
197
197
|
{
|
198
198
|
:status => :untracked,
|
199
|
-
:path =>
|
199
|
+
:path => parts[1],
|
200
200
|
}
|
201
|
-
when
|
201
|
+
when 'I'
|
202
202
|
{
|
203
203
|
:status => :ignored,
|
204
|
-
:path =>
|
204
|
+
:path => parts[1],
|
205
205
|
}
|
206
206
|
else
|
207
207
|
fail 'Failed to parse repo diff line.'
|
208
208
|
end
|
209
209
|
end
|
210
|
-
# rubocop:enable MultilineBlockChain
|
211
210
|
end
|
212
211
|
end
|
213
212
|
end
|
@@ -33,7 +33,7 @@ module BetweenMeals
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def exists?
|
36
|
-
Dir.
|
36
|
+
Dir.exist?(Pathname.new(@repo_path).join('.svn'))
|
37
37
|
end
|
38
38
|
|
39
39
|
def head_rev
|
@@ -64,7 +64,7 @@ module BetweenMeals
|
|
64
64
|
|
65
65
|
begin
|
66
66
|
parse_status(changes).compact
|
67
|
-
rescue => e
|
67
|
+
rescue StandardError => e
|
68
68
|
@logger.error(
|
69
69
|
'Something went wrong. Please report this output.',
|
70
70
|
)
|
@@ -88,12 +88,11 @@ module BetweenMeals
|
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|
91
|
-
def upstream
|
92
|
-
end
|
91
|
+
def upstream?; end
|
93
92
|
|
94
93
|
def valid_ref?(ref)
|
95
94
|
@cmd.info_r(ref, @repo_path)
|
96
|
-
rescue
|
95
|
+
rescue StandardError
|
97
96
|
raise Changeset::ReferenceError
|
98
97
|
end
|
99
98
|
|
@@ -103,7 +102,7 @@ module BetweenMeals
|
|
103
102
|
# http://svnbook.red-bean.com/en/1.0/re26.html
|
104
103
|
changes.lines.map do |line|
|
105
104
|
case line
|
106
|
-
when /^([\w ])\w?\s+(
|
105
|
+
when /^([\w ])\w?\s+(.+)$/
|
107
106
|
{
|
108
107
|
:status => Regexp.last_match(1) == 'D' ? :deleted : :modified,
|
109
108
|
:path => Regexp.last_match(2).sub("#{@repo_path}/", ''),
|
data/lib/between_meals/util.rb
CHANGED
@@ -15,13 +15,15 @@
|
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
17
|
require 'colorize'
|
18
|
+
require 'net/http'
|
19
|
+
require 'openssl'
|
18
20
|
require 'socket'
|
19
21
|
require 'timeout'
|
20
22
|
|
21
23
|
module BetweenMeals
|
22
24
|
# A set of simple utility functions used throughout BetweenMeals
|
23
25
|
#
|
24
|
-
# Feel
|
26
|
+
# Feel free to use... note that if you pass in a logger once
|
25
27
|
# you don't need to again, but be safe and always pass one in. :)
|
26
28
|
|
27
29
|
# Util classes need class vars :)
|
@@ -36,28 +38,29 @@ module BetweenMeals
|
|
36
38
|
info("Executed in #{format('%.2f', Time.now - t0)}s")
|
37
39
|
end
|
38
40
|
|
39
|
-
def exec!(command, logger = nil)
|
41
|
+
def exec!(command, logger = nil, stream = nil)
|
40
42
|
@@logger = logger if logger
|
41
|
-
c = execute(command)
|
43
|
+
c = execute(command, stream)
|
42
44
|
c.error!
|
43
45
|
return c.status.exitstatus, c.stdout
|
44
46
|
end
|
45
47
|
|
46
|
-
def exec(command, logger = nil)
|
48
|
+
def exec(command, logger = nil, stream = nil)
|
47
49
|
@@logger = logger if logger
|
48
|
-
|
50
|
+
|
51
|
+
c = execute(command, stream)
|
49
52
|
return c.status.exitstatus, c.stdout
|
50
53
|
end
|
51
54
|
|
52
55
|
private
|
53
56
|
|
54
57
|
def info(msg)
|
55
|
-
@@logger
|
58
|
+
@@logger&.info(msg)
|
56
59
|
end
|
57
60
|
|
58
|
-
def execute(command)
|
61
|
+
def execute(command, stream)
|
59
62
|
info("Running: #{command}")
|
60
|
-
c = Mixlib::ShellOut.new(command)
|
63
|
+
c = Mixlib::ShellOut.new(command, :live_stream => stream)
|
61
64
|
c.run_command
|
62
65
|
c.stdout.lines.each do |line|
|
63
66
|
info("STDOUT: #{line.strip}")
|
@@ -69,20 +72,43 @@ module BetweenMeals
|
|
69
72
|
end
|
70
73
|
|
71
74
|
def port_open?(port)
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
ips = Socket.ip_address_list
|
76
|
+
ips.map!(&:ip_address)
|
77
|
+
ips.each do |ip|
|
78
|
+
begin
|
79
|
+
Timeout.timeout(1) do
|
80
|
+
begin
|
81
|
+
s = TCPSocket.new(ip, port)
|
82
|
+
s.close
|
83
|
+
return true
|
84
|
+
rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
|
85
|
+
next
|
86
|
+
end
|
87
|
+
end
|
88
|
+
rescue Timeout::Error
|
89
|
+
next
|
90
|
+
end
|
91
|
+
end
|
92
|
+
return false
|
93
|
+
end
|
94
|
+
|
95
|
+
def chef_zero_running?(port, use_ssl)
|
96
|
+
Timeout.timeout(1) do
|
97
|
+
begin
|
98
|
+
http = Net::HTTP.new('localhost', port)
|
99
|
+
if use_ssl
|
100
|
+
http.use_ssl = true
|
101
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
80
102
|
end
|
103
|
+
res = http.get('/')
|
104
|
+
return res['Server'] == 'chef-zero'
|
105
|
+
rescue StandardError
|
106
|
+
return false
|
81
107
|
end
|
82
|
-
rescue Timeout::Error
|
83
|
-
return false
|
84
108
|
end
|
109
|
+
rescue Timeout::Error
|
85
110
|
return false
|
86
111
|
end
|
87
112
|
end
|
88
113
|
end
|
114
|
+
# rubocop:enable ClassVars
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: between_meals
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Phil Dibowitz
|
@@ -9,135 +9,51 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-09-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: colorize
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
version: '0'
|
28
|
-
- !ruby/object:Gem::Dependency
|
29
|
-
name: json
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
31
|
-
requirements:
|
32
|
-
- - '>='
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version: '0'
|
35
|
-
type: :runtime
|
36
|
-
prerelease: false
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - '>='
|
25
|
+
- - ">="
|
40
26
|
- !ruby/object:Gem::Version
|
41
27
|
version: '0'
|
42
28
|
- !ruby/object:Gem::Dependency
|
43
29
|
name: mixlib-shellout
|
44
30
|
requirement: !ruby/object:Gem::Requirement
|
45
31
|
requirements:
|
46
|
-
- -
|
32
|
+
- - ">="
|
47
33
|
- !ruby/object:Gem::Version
|
48
34
|
version: '0'
|
49
35
|
type: :runtime
|
50
36
|
prerelease: false
|
51
37
|
version_requirements: !ruby/object:Gem::Requirement
|
52
38
|
requirements:
|
53
|
-
- -
|
39
|
+
- - ">="
|
54
40
|
- !ruby/object:Gem::Version
|
55
41
|
version: '0'
|
56
42
|
- !ruby/object:Gem::Dependency
|
57
43
|
name: rugged
|
58
44
|
requirement: !ruby/object:Gem::Requirement
|
59
45
|
requirements:
|
60
|
-
- -
|
46
|
+
- - ">="
|
61
47
|
- !ruby/object:Gem::Version
|
62
48
|
version: '0'
|
63
49
|
type: :runtime
|
64
50
|
prerelease: false
|
65
51
|
version_requirements: !ruby/object:Gem::Requirement
|
66
52
|
requirements:
|
67
|
-
- -
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '0'
|
70
|
-
- !ruby/object:Gem::Dependency
|
71
|
-
name: rspec-core
|
72
|
-
requirement: !ruby/object:Gem::Requirement
|
73
|
-
requirements:
|
74
|
-
- - '>='
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version: '0'
|
77
|
-
type: :development
|
78
|
-
prerelease: false
|
79
|
-
version_requirements: !ruby/object:Gem::Requirement
|
80
|
-
requirements:
|
81
|
-
- - '>='
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version: '0'
|
84
|
-
- !ruby/object:Gem::Dependency
|
85
|
-
name: rspec-expectations
|
86
|
-
requirement: !ruby/object:Gem::Requirement
|
87
|
-
requirements:
|
88
|
-
- - '>='
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: '0'
|
91
|
-
type: :development
|
92
|
-
prerelease: false
|
93
|
-
version_requirements: !ruby/object:Gem::Requirement
|
94
|
-
requirements:
|
95
|
-
- - '>='
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: '0'
|
98
|
-
- !ruby/object:Gem::Dependency
|
99
|
-
name: rspec-mocks
|
100
|
-
requirement: !ruby/object:Gem::Requirement
|
101
|
-
requirements:
|
102
|
-
- - '>='
|
103
|
-
- !ruby/object:Gem::Version
|
104
|
-
version: '0'
|
105
|
-
type: :development
|
106
|
-
prerelease: false
|
107
|
-
version_requirements: !ruby/object:Gem::Requirement
|
108
|
-
requirements:
|
109
|
-
- - '>='
|
53
|
+
- - ">="
|
110
54
|
- !ruby/object:Gem::Version
|
111
55
|
version: '0'
|
112
|
-
|
113
|
-
name: rubocop
|
114
|
-
requirement: !ruby/object:Gem::Requirement
|
115
|
-
requirements:
|
116
|
-
- - '>='
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: '0'
|
119
|
-
type: :development
|
120
|
-
prerelease: false
|
121
|
-
version_requirements: !ruby/object:Gem::Requirement
|
122
|
-
requirements:
|
123
|
-
- - '>='
|
124
|
-
- !ruby/object:Gem::Version
|
125
|
-
version: '0'
|
126
|
-
- !ruby/object:Gem::Dependency
|
127
|
-
name: simplecov
|
128
|
-
requirement: !ruby/object:Gem::Requirement
|
129
|
-
requirements:
|
130
|
-
- - '>='
|
131
|
-
- !ruby/object:Gem::Version
|
132
|
-
version: '0'
|
133
|
-
type: :development
|
134
|
-
prerelease: false
|
135
|
-
version_requirements: !ruby/object:Gem::Requirement
|
136
|
-
requirements:
|
137
|
-
- - '>='
|
138
|
-
- !ruby/object:Gem::Version
|
139
|
-
version: '0'
|
140
|
-
description: Library for calculation Chef differences between revisions
|
56
|
+
description: Library for calculating Chef differences between revisions
|
141
57
|
email:
|
142
58
|
executables: []
|
143
59
|
extensions: []
|
@@ -145,26 +61,26 @@ extra_rdoc_files:
|
|
145
61
|
- README.md
|
146
62
|
- LICENSE
|
147
63
|
files:
|
148
|
-
- README.md
|
149
64
|
- LICENSE
|
150
|
-
-
|
65
|
+
- README.md
|
66
|
+
- lib/between_meals/changes/change.rb
|
67
|
+
- lib/between_meals/changes/cookbook.rb
|
68
|
+
- lib/between_meals/changes/databag.rb
|
69
|
+
- lib/between_meals/changes/role.rb
|
151
70
|
- lib/between_meals/changeset.rb
|
71
|
+
- lib/between_meals/cmd.rb
|
152
72
|
- lib/between_meals/knife.rb
|
153
73
|
- lib/between_meals/repo.rb
|
154
|
-
- lib/between_meals/cmd.rb
|
155
|
-
- lib/between_meals/changes/databag.rb
|
156
|
-
- lib/between_meals/changes/cookbook.rb
|
157
|
-
- lib/between_meals/changes/change.rb
|
158
|
-
- lib/between_meals/changes/role.rb
|
159
74
|
- lib/between_meals/repo/git.rb
|
160
|
-
- lib/between_meals/repo/svn.rb
|
161
75
|
- lib/between_meals/repo/git/cmd.rb
|
162
|
-
- lib/between_meals/repo/svn/cmd.rb
|
163
|
-
- lib/between_meals/repo/hg/cmd.rb
|
164
76
|
- lib/between_meals/repo/hg.rb
|
77
|
+
- lib/between_meals/repo/hg/cmd.rb
|
78
|
+
- lib/between_meals/repo/svn.rb
|
79
|
+
- lib/between_meals/repo/svn/cmd.rb
|
80
|
+
- lib/between_meals/util.rb
|
165
81
|
homepage: https://github.com/facebook/between-meals
|
166
82
|
licenses:
|
167
|
-
- Apache
|
83
|
+
- Apache-2.0
|
168
84
|
metadata: {}
|
169
85
|
post_install_message:
|
170
86
|
rdoc_options: []
|
@@ -172,17 +88,16 @@ require_paths:
|
|
172
88
|
- lib
|
173
89
|
required_ruby_version: !ruby/object:Gem::Requirement
|
174
90
|
requirements:
|
175
|
-
- -
|
91
|
+
- - ">="
|
176
92
|
- !ruby/object:Gem::Version
|
177
93
|
version: '0'
|
178
94
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
95
|
requirements:
|
180
|
-
- -
|
96
|
+
- - ">="
|
181
97
|
- !ruby/object:Gem::Version
|
182
98
|
version: '0'
|
183
99
|
requirements: []
|
184
|
-
|
185
|
-
rubygems_version: 2.0.14
|
100
|
+
rubygems_version: 3.1.2
|
186
101
|
signing_key:
|
187
102
|
specification_version: 4
|
188
103
|
summary: Between Meals
|