between_meals 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -9,8 +9,8 @@ Between Meals is the library for calculating what Chef objects where modified
9
9
  between two revisions in a version control system. It is also the library
10
10
  that that backs Taste Tester and Grocery Delivery.
11
11
 
12
- It currently supports SVN and GIT, but plugins can easily be written for
13
- other systems.
12
+ It currently supports SVN, GIT and HG, but plugins can easily be written for
13
+ other source control systems.
14
14
 
15
15
  It also includes some wrappers around knife execution and a few other utility
16
16
  functions.
@@ -1,13 +1,13 @@
1
1
  # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
2
2
 
3
3
  # Copyright 2013-present Facebook
4
- #
4
+ #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
7
7
  # You may obtain a copy of the License at
8
- #
8
+ #
9
9
  # http://www.apache.org/licenses/LICENSE-2.0
10
- #
10
+ #
11
11
  # Unless required by applicable law or agreed to in writing, software
12
12
  # distributed under the License is distributed on an "AS IS" BASIS,
13
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -1,13 +1,13 @@
1
1
  # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
2
2
 
3
3
  # Copyright 2013-present Facebook
4
- #
4
+ #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
7
7
  # You may obtain a copy of the License at
8
- #
8
+ #
9
9
  # http://www.apache.org/licenses/LICENSE-2.0
10
- #
10
+ #
11
11
  # Unless required by applicable law or agreed to in writing, software
12
12
  # distributed under the License is distributed on an "AS IS" BASIS,
13
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -54,10 +54,10 @@ module BetweenMeals
54
54
  # otherwise it was modified
55
55
  # and will be re-uploaded
56
56
  if files.
57
- select { |x| x[:status] == :deleted }.
58
- map { |x| x[:path].match(%{.*metadata\.rb$}) }.
59
- compact.
60
- any?
57
+ select { |x| x[:status] == :deleted }.
58
+ map { |x| x[:path].match(%{.*metadata\.rb$}) }.
59
+ compact.
60
+ any?
61
61
  @status = :deleted
62
62
  else
63
63
  @status = :modified
@@ -78,7 +78,7 @@ module BetweenMeals
78
78
  g = self.explode_path(x[:path], cookbook_dirs)
79
79
  g[:cookbook_dir] + '/' + g[:name] if g
80
80
  end.
81
- map do |_, change|
81
+ map do |_, change|
82
82
  # Confirm we're dealing with a cookbook
83
83
  # Changes to OWNERS or other stuff that might end up
84
84
  # in [core, other, secure] dirs are ignored
@@ -1,13 +1,13 @@
1
1
  # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
2
2
 
3
3
  # Copyright 2013-present Facebook
4
- #
4
+ #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
7
7
  # You may obtain a copy of the License at
8
- #
8
+ #
9
9
  # http://www.apache.org/licenses/LICENSE-2.0
10
- #
10
+ #
11
11
  # Unless required by applicable law or agreed to in writing, software
12
12
  # distributed under the License is distributed on an "AS IS" BASIS,
13
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -1,13 +1,13 @@
1
1
  # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
2
2
 
3
3
  # Copyright 2013-present Facebook
4
- #
4
+ #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
7
7
  # You may obtain a copy of the License at
8
- #
8
+ #
9
9
  # http://www.apache.org/licenses/LICENSE-2.0
10
- #
10
+ #
11
11
  # Unless required by applicable law or agreed to in writing, software
12
12
  # distributed under the License is distributed on an "AS IS" BASIS,
13
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,7 +20,7 @@ module BetweenMeals
20
20
  # Changeset aware role
21
21
  class Role < Change
22
22
  def self.name_from_path(path, role_dir)
23
- re = "^#{role_dir}\/(.+)\.rb"
23
+ re = %r{^#{role_dir}/(.+)\.rb}
24
24
  debug("[role] Matching #{path} against #{re}")
25
25
  m = path.match(re)
26
26
  if m
@@ -1,13 +1,13 @@
1
1
  # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
2
2
 
3
3
  # Copyright 2013-present Facebook
4
- #
4
+ #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
7
7
  # You may obtain a copy of the License at
8
- #
8
+ #
9
9
  # http://www.apache.org/licenses/LICENSE-2.0
10
- #
10
+ #
11
11
  # Unless required by applicable law or agreed to in writing, software
12
12
  # distributed under the License is distributed on an "AS IS" BASIS,
13
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -0,0 +1,44 @@
1
+ # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
2
+
3
+ # Copyright 2013-present Facebook
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'logger'
18
+
19
+ module BetweenMeals
20
+ class Cmd
21
+ attr_accessor :bin
22
+
23
+ def initialize(params)
24
+ @bin = params[:bin] || fail
25
+ @cwd = params[:cwd] || Dir.pwd
26
+ @logger = params[:logger] || Logger.new(STDOUT)
27
+ end
28
+
29
+ def cmd(params, cwd = nil)
30
+ unless cwd
31
+ cwd = File.expand_path(@cwd)
32
+ end
33
+ cmd = "#{@bin} #{params}"
34
+ @logger.info("Running \"#{cmd}\"")
35
+ c = Mixlib::ShellOut.new(
36
+ cmd,
37
+ :cwd => cwd
38
+ )
39
+ c.run_command
40
+ c.error!
41
+ c
42
+ end
43
+ end
44
+ end
@@ -1,13 +1,13 @@
1
1
  # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
2
2
 
3
3
  # Copyright 2013-present Facebook
4
- #
4
+ #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
7
7
  # You may obtain a copy of the License at
8
- #
8
+ #
9
9
  # http://www.apache.org/licenses/LICENSE-2.0
10
- #
10
+ #
11
11
  # Unless required by applicable law or agreed to in writing, software
12
12
  # distributed under the License is distributed on an "AS IS" BASIS,
13
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -31,14 +31,16 @@ module BetweenMeals
31
31
  @user = opts[:user] || ENV['USER']
32
32
  @home = opts[:home] || ENV['HOME']
33
33
  # make sure people can pass in false :)
34
- @ssl = opts[:ssl].nil? ? true : opts[:ssl]
34
+ @ssl = opts[:ssl].nil? ? true : opts[:ssl]
35
35
  @host = opts[:host] || 'localhost'
36
36
  @port = opts[:port] || 4000
37
37
  @config = opts[:config] ||
38
- "#{@home}/.chef/knife-#{@user}-taste-tester.rb"
38
+ "#{@home}/.chef/knife-#{@user}-taste-tester.rb"
39
39
  @knife = opts[:bin] || 'knife'
40
+ @berks = opts[:berks_bin] || 'berks'
41
+ @berks_config = opts[:berks_config]
40
42
  @pem = opts[:pem] ||
41
- "#{@home}/.chef/#{@user}-taste-tester.pem"
43
+ "#{@home}/.chef/#{@user}-taste-tester.pem"
42
44
  @role_dir = opts[:role_dir]
43
45
  @cookbook_dirs = opts[:cookbook_dirs]
44
46
  @databag_dir = opts[:databag_dir]
@@ -48,8 +50,10 @@ module BetweenMeals
48
50
  end
49
51
 
50
52
  def role_upload_all
51
- roles = File.join(@role_dir, '*.rb')
52
- exec!("#{@knife} role from file #{roles} -c #{@config}", @logger)
53
+ if File.exists?(@role_dir)
54
+ roles = File.join(@role_dir, '*.rb')
55
+ exec!("#{@knife} role from file #{roles} -c #{@config}", @logger)
56
+ end
53
57
  end
54
58
 
55
59
  def role_upload(roles)
@@ -73,13 +77,45 @@ module BetweenMeals
73
77
  exec!("#{@knife} cookbook upload -a -c #{@config}", @logger)
74
78
  end
75
79
 
80
+ def berks_cookbook_upload_all
81
+ if @berks_config
82
+ berks_config = '--config=' + @berks_config
83
+ end
84
+ @cookbook_dirs.each do |path|
85
+ cookbooks = Dir["#{path}/*"].select { |o| File.directory?(o) }
86
+ cookbooks.each do |cb|
87
+ @logger.warn("Running berkshelf on cookbook: #{cb}")
88
+ exec!("cd #{cb} && #{@berks} install #{berks_config} && " +
89
+ "#{@berks} upload #{berks_config}", @logger)
90
+ end
91
+ end
92
+ end
93
+
76
94
  def cookbook_upload(cookbooks)
77
95
  if cookbooks.any?
78
- cookbooks = cookbooks.map { |x| x.name }.join(' ')
96
+ cookbooks = cookbooks.map(&:name).join(' ')
79
97
  exec!("#{@knife} cookbook upload #{cookbooks} -c #{@config}", @logger)
80
98
  end
81
99
  end
82
100
 
101
+ def berks_cookbook_upload(cookbooks)
102
+ # cookbooks: array
103
+ # cookbook_paths: array
104
+ if @berks_config
105
+ berks_config = '--config=' + @berks_config
106
+ end
107
+ if cookbooks.any?
108
+ @cookbook_dirs.each do |path|
109
+ cookbooks.each do |cb|
110
+ next unless File.exists?("#{path}/#{cb}")
111
+ @logger.warn("Running berkshelf on cookbook: #{cb}")
112
+ exec!("cd #{path}/#{cb} && #{@berks} install #{berks_config} && " +
113
+ "#{@berks} upload #{berks_config}", @logger)
114
+ end
115
+ end
116
+ end
117
+ end
118
+
83
119
  def cookbook_delete(cookbooks)
84
120
  if cookbooks.any?
85
121
  cookbooks.each do |cookbook|
@@ -101,19 +137,22 @@ module BetweenMeals
101
137
 
102
138
  def databag_upload(databags)
103
139
  if databags.any?
104
- databags.group_by { |x| x.name }.each do |dbname, dbs|
140
+ databags.group_by(&:name).each do |dbname, dbs|
105
141
  create_databag_if_missing(dbname)
106
142
  dbitems = dbs.map do |x|
107
143
  File.join(@databag_dir, dbname, "#{x.item}.json")
108
144
  end.join(' ')
109
- exec!("#{@knife} data bag from file #{dbname} #{dbitems}", @logger)
145
+ exec!(
146
+ "#{@knife} data bag from file #{dbname} #{dbitems} -c #{@config}",
147
+ @logger
148
+ )
110
149
  end
111
150
  end
112
151
  end
113
152
 
114
153
  def databag_delete(databags)
115
154
  if databags.any?
116
- databags.group_by { |x| x.name }.each do |dbname, dbs|
155
+ databags.group_by(&:name).each do |dbname, dbs|
117
156
  dbs.each do |db|
118
157
  exec!("#{@knife} data bag delete #{dbname} #{db.item}" +
119
158
  " --yes -c #{@config}", @logger)
@@ -146,7 +185,7 @@ BLOCK
146
185
  end
147
186
  if !File.exists?(@config) ||
148
187
  ::Digest::MD5.hexdigest(cfg) !=
149
- ::Digest::MD5.hexdigest(File.read(@config))
188
+ ::Digest::MD5.hexdigest(File.read(@config))
150
189
  @logger.info("Generating #{@config}")
151
190
  File.write(@config, cfg)
152
191
  end
@@ -1,13 +1,13 @@
1
1
  # vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2
2
2
 
3
3
  # Copyright 2013-present Facebook
4
- #
4
+ #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
7
7
  # You may obtain a copy of the License at
8
- #
8
+ #
9
9
  # http://www.apache.org/licenses/LICENSE-2.0
10
- #
10
+ #
11
11
  # Unless required by applicable law or agreed to in writing, software
12
12
  # distributed under the License is distributed on an "AS IS" BASIS,
13
13
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -19,8 +19,7 @@ require 'mixlib/shellout'
19
19
  module BetweenMeals
20
20
  # Local checkout wrapper
21
21
  class Repo
22
- attr_reader :repo_path
23
- attr_writer :bin
22
+ attr_reader :repo_path, :bin
24
23
 
25
24
  def initialize(repo_path, logger)
26
25
  @repo_path = repo_path
@@ -35,93 +34,138 @@ module BetweenMeals
35
34
 
36
35
  def self.get(type, repo_path, logger)
37
36
  case type
37
+ when 'auto'
38
+ unless File.directory?(repo_path)
39
+ logger.warn("#{repo_path} does not point to a repo")
40
+ exit(1)
41
+ end
42
+ logger.info('Trying to detect repo type')
43
+ require 'between_meals/repo/git'
44
+ require 'between_meals/repo/hg'
45
+ require 'between_meals/repo/svn'
46
+ [
47
+ BetweenMeals::Repo::Git,
48
+ BetweenMeals::Repo::Hg,
49
+ BetweenMeals::Repo::Svn,
50
+ ].each do |klass|
51
+ begin
52
+ r = klass.new(repo_path, logger)
53
+ if r.exists?
54
+ logger.info("Repo found to be #{klass.to_s.split('::').last}")
55
+ return r
56
+ end
57
+ rescue
58
+ logger.debug("Skipping #{klass}")
59
+ end
60
+ end
61
+ logger.warn("Failed detecting repo type at #{repo_path}")
62
+ exit(1)
38
63
  when 'svn'
39
64
  require 'between_meals/repo/svn'
40
65
  BetweenMeals::Repo::Svn.new(repo_path, logger)
41
66
  when 'git'
42
67
  require 'between_meals/repo/git'
43
68
  BetweenMeals::Repo::Git.new(repo_path, logger)
69
+ when 'hg'
70
+ require 'between_meals/repo/hg'
71
+ BetweenMeals::Repo::Hg.new(repo_path, logger)
44
72
  else
45
73
  fail "Do not know repo type #{type}"
46
74
  end
47
75
  end
48
76
 
77
+ def bin=(bin)
78
+ @bin = bin
79
+ @cmd.bin = bin
80
+ end
81
+
49
82
  def exists?
50
- fail 'Not implemented'
83
+ fail "#{__method__} not implemented"
51
84
  end
52
85
 
53
86
  def status
54
- fail 'Not implemented'
87
+ fail "#{__method__} not implemented"
55
88
  end
56
89
 
90
+ # This method *must* succeed in the case of no repo directory so that
91
+ # users can call `checkout`. Users may call `exists?` to find out if
92
+ # we have an underlying repo yet.
57
93
  def setup
58
- fail 'Not implemented'
94
+ fail "#{__method__} not implemented"
59
95
  end
60
96
 
61
97
  def head_rev
62
- fail 'Not implemented'
98
+ fail "#{__method__} not implemented"
63
99
  end
64
100
 
65
101
  def head_msg
66
- fail 'Not implemented'
102
+ fail "#{__method__} not implemented"
67
103
  end
68
104
 
69
105
  def head_msg=
70
- fail 'Not implemented'
106
+ fail "#{__method__} not implemented"
71
107
  end
72
108
 
73
109
  def head_parents
74
- fail 'Not implemented'
110
+ fail "#{__method__} not implemented"
75
111
  end
76
112
 
77
113
  def latest_revision
78
- fail 'Not implemented'
114
+ fail "#{__method__} not implemented"
79
115
  end
80
116
 
81
117
  def create(_url)
82
- fail 'Not implemented'
118
+ fail "#{__method__} not implemented"
83
119
  end
84
120
 
85
121
  # Return files changed between two revisions
86
122
  def changes(_start_ref, _end_ref)
87
- fail 'Not implemented'
123
+ fail "#{__method__} not implemented"
88
124
  end
89
125
 
90
126
  def update
91
- fail 'Not implemented'
127
+ fail "#{__method__} not implemented"
92
128
  end
93
129
 
94
130
  # Return all files
95
131
  def files
96
- fail 'Not implemented'
97
- end
98
-
99
- def latest_revision
100
- fail 'Not implemented'
132
+ fail "#{__method__} not implemented"
101
133
  end
102
134
 
103
135
  def head
104
- fail 'Not implemented'
136
+ fail "#{__method__} not implemented"
105
137
  end
106
138
 
107
139
  def checkout
108
- fail 'Not implemented'
109
- end
110
-
111
- def update
112
- fail 'Not implemented'
140
+ fail "#{__method__} not implemented"
113
141
  end
114
142
 
115
143
  def last_author
116
- fail 'Not implemented'
144
+ fail "#{__method__} not implemented"
117
145
  end
118
146
 
119
147
  def last_msg
120
- fail 'Not implemented'
148
+ fail "#{__method__} not implemented"
121
149
  end
122
150
 
123
151
  def last_msg=
124
- fail 'Not implemented'
152
+ fail "#{__method__} not implemented"
153
+ end
154
+
155
+ def name
156
+ fail "#{__method__} not implemented"
157
+ end
158
+
159
+ def email
160
+ fail "#{__method__} not implemented"
161
+ end
162
+
163
+ def upstream?(_rev)
164
+ fail "#{__method__} not implemented"
165
+ end
166
+
167
+ def valid_ref?(_rev)
168
+ fail "#{__method__} not implemented"
125
169
  end
126
170
  end
127
171
  end