chef 0.10.0.beta.3 → 0.10.0.beta.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -32,17 +32,13 @@ class Chef::Application::Knife < Chef::Application
32
32
  :description => "The configuration file to use",
33
33
  :proc => lambda { |path| File.expand_path(path, Dir.pwd) }
34
34
 
35
- option :log_level,
36
- :short => "-l LEVEL",
37
- :long => "--log_level LEVEL",
38
- :description => "Set the log level (debug, info, warn, error, fatal)",
39
- :proc => lambda { |l| l.to_sym }
40
-
41
- option :log_location,
42
- :short => "-L LOGLOCATION",
43
- :long => "--logfile LOGLOCATION",
44
- :description => "Set the log file location, defaults to STDOUT",
45
- :proc => nil
35
+ verbosity_level = 0
36
+ option :verbosity,
37
+ :short => '-V',
38
+ :long => '--verbose',
39
+ :description => "More verbose output. Use twice for max verbosity",
40
+ :proc => Proc.new { verbosity_level += 1},
41
+ :default => 0
46
42
 
47
43
  option :environment,
48
44
  :short => "-E ENVIRONMENT",
@@ -94,7 +90,6 @@ class Chef::Application::Knife < Chef::Application
94
90
  :description => "Accept default values for all questions"
95
91
 
96
92
  option :print_after,
97
- :short => "-p",
98
93
  :long => "--print-after",
99
94
  :description => "Show the data after a destructive operation"
100
95
 
@@ -151,7 +151,7 @@ class Chef
151
151
  load_commands
152
152
  subcommand_class = subcommand_class_from(args)
153
153
  subcommand_class.options = options.merge!(subcommand_class.options)
154
- subcommand_class.load_deps
154
+ subcommand_class.load_deps unless want_help?(args)
155
155
  instance = subcommand_class.new(args)
156
156
  instance.configure_chef
157
157
  instance.run
@@ -282,8 +282,15 @@ class Chef
282
282
  self.msg("No knife configuration file found")
283
283
  end
284
284
 
285
- Chef::Config[:log_level] = config[:log_level] if config[:log_level]
286
- Chef::Config[:log_location] = config[:log_location] if config[:log_location]
285
+ case config[:verbosity]
286
+ when 0
287
+ Chef::Config[:log_level] = :error
288
+ when 1
289
+ Chef::Config[:log_level] = :info
290
+ else
291
+ Chef::Config[:log_level] = :debug
292
+ end
293
+
287
294
  Chef::Config[:node_name] = config[:node_name] if config[:node_name]
288
295
  Chef::Config[:client_key] = config[:client_key] if config[:client_key]
289
296
  Chef::Config[:chef_server_url] = config[:chef_server_url] if config[:chef_server_url]
@@ -26,6 +26,9 @@ class Chef
26
26
  require 'chef/json_compat'
27
27
  require 'tempfile'
28
28
  require 'erubis'
29
+ require 'highline'
30
+ require 'net/ssh'
31
+ require 'net/ssh/multi'
29
32
  end
30
33
 
31
34
  banner "knife bootstrap FQDN [RUN LIST...] (options)"
@@ -41,6 +44,13 @@ class Chef
41
44
  :long => "--ssh-password PASSWORD",
42
45
  :description => "The ssh password"
43
46
 
47
+ option :ssh_port,
48
+ :short => "-p PORT",
49
+ :long => "--ssh-port PORT",
50
+ :description => "The ssh port",
51
+ :default => "22",
52
+ :proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
53
+
44
54
  option :identity_file,
45
55
  :short => "-i IDENTITY_FILE",
46
56
  :long => "--identity-file IDENTITY_FILE",
@@ -118,8 +128,6 @@ class Chef
118
128
  end
119
129
 
120
130
  def run
121
- require 'highline'
122
- require 'net/ssh'
123
131
 
124
132
  validate_name_args!
125
133
  @node_name = Array(@name_args).first
@@ -156,6 +164,7 @@ class Chef
156
164
  ssh.name_args = [ server_name, ssh_command ]
157
165
  ssh.config[:ssh_user] = config[:ssh_user]
158
166
  ssh.config[:ssh_password] = config[:ssh_password]
167
+ ssh.config[:ssh_port] = Chef::Config[:knife][:ssh_port] || config[:ssh_port]
159
168
  ssh.config[:identity_file] = config[:identity_file]
160
169
  ssh.config[:manual] = true
161
170
  ssh.config[:no_host_key_verify] = config[:no_host_key_verify]
@@ -25,6 +25,7 @@ class Chef
25
25
 
26
26
  deps do
27
27
  require 'chef/knife/cookbook_delete'
28
+ require 'chef/cookbook_version'
28
29
  end
29
30
 
30
31
  option :purge, :short => '-p', :long => '--purge', :boolean => true, :description => 'Permanently remove files from backing data store'
@@ -44,12 +45,12 @@ class Chef
44
45
  cookbooks_to_delete = cookbooks_names.inject({}) { |hash, name| hash[name] = all_cookbooks[name];hash }
45
46
  output(format_list_for_display(cookbooks_to_delete))
46
47
 
47
- confirm("Do you really want to delete these cookbooks? All versions will be deleted. (Y/N) ", false)
48
+ ui.confirm("Do you really want to delete these cookbooks? All versions will be deleted. (Y/N) ", false)
48
49
 
49
- confirm("Files that are common to multiple cookbooks are shared, so purging the files may disable other cookbooks. Are you sure you want to purge files instead of just deleting the cookbooks") if config[:purge]
50
+ ui.confirm("Files that are common to multiple cookbooks are shared, so purging the files may disable other cookbooks. Are you sure you want to purge files instead of just deleting the cookbooks") if config[:purge]
50
51
 
51
52
  cookbooks_names.each do |cookbook_name|
52
- versions = rest.get_rest("cookbooks/#{cookbook_name}").values.flatten
53
+ versions = rest.get_rest("cookbooks/#{cookbook_name}")[cookbook_name]["versions"].map {|v| v["version"]}.flatten
53
54
  versions.each do |version|
54
55
  object = rest.delete_rest("cookbooks/#{cookbook_name}/#{version}#{config[:purge] ? "?purge=true" : ""}")
55
56
  ui.info("Deleted cookbook #{cookbook_name.ljust(25)} [#{version}]")
@@ -95,7 +95,7 @@ class Chef
95
95
  if available_versions.size == 1
96
96
  @version = available_versions.first
97
97
  elsif config[:latest]
98
- @version = available_versions.map { |v| Chef::Cookbook::Metadata::Version.new(v) }.sort.last
98
+ @version = available_versions.map { |v| Chef::Version.new(v) }.sort.last
99
99
  else
100
100
  ask_which_version
101
101
  end
@@ -104,7 +104,7 @@ class Chef
104
104
  def available_versions
105
105
  @available_versions ||= begin
106
106
  versions = Chef::CookbookVersion.available_versions(@cookbook_name).map do |version|
107
- Chef::Cookbook::Metadata::Version.new(version)
107
+ Chef::Version.new(version)
108
108
  end
109
109
  versions.sort!
110
110
  versions
@@ -40,7 +40,10 @@ class Chef
40
40
  num_versions = config[:all_versions] ? "num_versions=all" : "num_versions=1"
41
41
  api_endpoint = env ? "/environments/#{env}/cookbooks?#{num_versions}" : "/cookbooks?#{num_versions}"
42
42
  ui.info("Showing latest versions. Use --show-all to list all available versions.") unless config[:all_versions]
43
- output(format_cookbook_list_for_display(rest.get_rest(api_endpoint)))
43
+ cookbook_versions = rest.get_rest(api_endpoint)
44
+ format_cookbook_list_for_display(cookbook_versions).each do |line|
45
+ ui.msg(line)
46
+ end
44
47
  end
45
48
  end
46
49
  end
@@ -41,7 +41,7 @@ class Chef
41
41
 
42
42
  @version = cookbook_data['version']
43
43
 
44
- ui.info("Downloading #{@name_args[0]} from the cookbooks site at version #{cookbook_data['version']}")
44
+ ui.info("Downloading #{@name_args[0]} from the cookbooks site at version #{cookbook_data['version']} to #{config[:file]}")
45
45
  rest.sign_on_redirect = false
46
46
  tf = rest.get_rest(cookbook_data["file"], true)
47
47
  unless config[:file]
@@ -0,0 +1,272 @@
1
+ #
2
+ # Author:: Adam Jacob (<adam@opscode.com>)
3
+ # Copyright:: Copyright (c) 2010 Opscode, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife'
20
+ require 'chef/mixin/shell_out'
21
+
22
+ class Chef
23
+ class Knife
24
+ class CookbookRepo
25
+
26
+ DIRTY_REPO = /^[\s]+M/
27
+
28
+ include Chef::Mixin::ShellOut
29
+
30
+ attr_reader :repo_path
31
+ attr_reader :default_branch
32
+ attr_reader :ui
33
+
34
+ def initialize(repo_path, ui, opts={})
35
+ @repo_path = repo_path
36
+ @ui = ui
37
+ @default_branch = 'master'
38
+ end
39
+
40
+ def sanity_check
41
+ unless ::File.directory?(repo_path)
42
+ ui.error("The cookbook repo path #{repo_path} does not exist or is not a directory")
43
+ exit 1
44
+ end
45
+ unless git_repo?(repo_path)
46
+ ui.error "The cookbook repo #{repo_path} is not a git repository."
47
+ ui.info("Use `git init` to initialize a git repo")
48
+ exit 1
49
+ end
50
+ unless branch_exists?(default_branch)
51
+ ui.error "The default branch '#{default_branch}' does not exist"
52
+ ui.info "If this is a new git repo, make sure you have at least one commit before installing cookbooks"
53
+ exit 1
54
+ end
55
+ cmd = git('status --porcelain')
56
+ if cmd.stdout =~ DIRTY_REPO
57
+ ui.error "You have uncommitted changes to your cookbook repo (#{repo_path}):"
58
+ ui.msg cmd.stdout
59
+ ui.info "Commit or stash your changes before importing cookbooks"
60
+ exit 1
61
+ end
62
+ # TODO: any untracked files in the cookbook directory will get nuked later
63
+ # make this an error condition also.
64
+ true
65
+ end
66
+
67
+ def reset_to_default_state
68
+ ui.info("Checking out the #{default_branch} branch.")
69
+ git("checkout #{default_branch}")
70
+ end
71
+
72
+ def prepare_to_import(cookbook_name)
73
+ branch = "chef-vendor-#{cookbook_name}"
74
+ if branch_exists?(branch)
75
+ ui.info("Pristine copy branch (#{branch}) exists, switching to it.")
76
+ git("checkout #{branch}")
77
+ else
78
+ ui.info("Creating pristine copy branch #{branch}")
79
+ git("checkout -b #{branch}")
80
+ end
81
+ end
82
+
83
+ def finalize_updates_to(cookbook_name, version)
84
+ if update_count = updated?(cookbook_name)
85
+ ui.info "#{update_count} files updated, committing changes"
86
+ git("add #{cookbook_name}")
87
+ git("commit -m 'Import #{cookbook_name} version #{version}' -- #{cookbook_name}")
88
+ ui.info("Creating tag cookbook-site-imported-#{cookbook_name}-#{version}")
89
+ git("tag -f cookbook-site-imported-#{cookbook_name}-#{version}")
90
+ true
91
+ else
92
+ ui.info("No changes made to #{cookbook_name}")
93
+ false
94
+ end
95
+ end
96
+
97
+ def merge_updates_from(cookbook_name, version)
98
+ branch = "chef-vendor-#{cookbook_name}"
99
+ Dir.chdir(repo_path) do
100
+ if system("git merge #{branch}")
101
+ ui.info("Cookbook #{cookbook_name} version #{version} successfully installed")
102
+ else
103
+ ui.error("You have merge conflicts - please resolve manually")
104
+ ui.info("Merge status (cd #{repo_path}; git status):")
105
+ system("git status")
106
+ exit 3
107
+ end
108
+ end
109
+ end
110
+
111
+ def updated?(cookbook_name)
112
+ update_count = git("status --porcelain -- #{cookbook_name}").stdout.strip.lines.count
113
+ update_count == 0 ? nil : update_count
114
+ end
115
+
116
+ def branch_exists?(branch_name)
117
+ git("branch --no-color").stdout.lines.any? {|l| l.include?(branch_name) }
118
+ end
119
+
120
+ private
121
+
122
+ def git_repo?(directory)
123
+ if File.directory?(File.join(directory, '.git'))
124
+ return true
125
+ elsif File.dirname(directory) == directory
126
+ return false
127
+ else
128
+ git_repo?(File.dirname(directory))
129
+ end
130
+ end
131
+
132
+ def apply_opts(opts)
133
+ opts.each do |option, value|
134
+ case option.to_s
135
+ when 'default_branch'
136
+ @default_branch = value
137
+ else
138
+ raise ArgumentError, "invalid option `#{option}' passed to CookbookRepo.new()"
139
+ end
140
+ end
141
+ end
142
+
143
+ def git(command)
144
+ shell_out!("git #{command}", :cwd => repo_path)
145
+ end
146
+
147
+ end
148
+
149
+ class CookbookSiteInstall < Knife
150
+
151
+ deps do
152
+ require 'chef/mixin/shell_out'
153
+ require 'chef/cookbook/metadata'
154
+ end
155
+
156
+ banner "knife cookbook site vendor COOKBOOK [VERSION] (options)"
157
+ category "cookbook site"
158
+
159
+ option :deps,
160
+ :short => "-d",
161
+ :long => "--dependencies",
162
+ :boolean => true,
163
+ :description => "Grab dependencies automatically"
164
+
165
+ option :cookbook_path,
166
+ :short => "-o PATH:PATH",
167
+ :long => "--cookbook-path PATH:PATH",
168
+ :description => "A colon-separated path to look for cookbooks in",
169
+ :proc => lambda { |o| o.split(":") }
170
+
171
+ option :branch_default,
172
+ :short => "-B BRANCH",
173
+ :long => "--branch BRANCH",
174
+ :description => "Default branch to work with",
175
+ :default => "master"
176
+
177
+ attr_reader :cookbook_name
178
+ attr_reader :vendor_path
179
+
180
+ def run
181
+ extend Chef::Mixin::ShellOut
182
+
183
+ if config[:cookbook_path]
184
+ Chef::Config[:cookbook_path] = config[:cookbook_path]
185
+ else
186
+ config[:cookbook_path] = Chef::Config[:cookbook_path]
187
+ end
188
+
189
+ @cookbook_name = parse_name_args!
190
+ # Check to ensure we have a valid source of cookbooks before continuing
191
+ #
192
+ @install_path = config[:cookbook_path].first
193
+ ui.info "Installing #@cookbook_name to #{@install_path}"
194
+
195
+ @repo = CookbookRepo.new(@install_path, ui, config)
196
+ #cookbook_path = File.join(vendor_path, name_args[0])
197
+ upstream_file = File.join(@install_path, "#{@cookbook_name}.tar.gz")
198
+
199
+ @repo.sanity_check
200
+ @repo.reset_to_default_state
201
+ @repo.prepare_to_import(@cookbook_name)
202
+
203
+ downloader = download_cookbook_to(upstream_file)
204
+ clear_existing_files(File.join(@install_path, @cookbook_name))
205
+ extract_cookbook(upstream_file, @install_path)
206
+
207
+ # TODO: it'd be better to store these outside the cookbook repo and
208
+ # keep them around, e.g., in ~/Library/Caches on OS X.
209
+ ui.info("removing downloaded tarball")
210
+ shell_out!("rm #{upstream_file}", :cwd => vendor_path)
211
+
212
+ if @repo.finalize_updates_to(@cookbook_name, downloader.version)
213
+ @repo.reset_to_default_state
214
+ @repo.merge_updates_from(@cookbook_name, downloader.version)
215
+ else
216
+ @repo.reset_to_default_state
217
+ end
218
+
219
+
220
+ if config[:deps]
221
+ md = Chef::Cookbook::Metadata.new
222
+ md.from_file(File.join(cookbook_path, "metadata.rb"))
223
+ md.dependencies.each do |cookbook, version_list|
224
+ # Doesn't do versions.. yet
225
+ nv = Chef::Knife::CookbookSiteVendor.new
226
+ nv.config = config
227
+ nv.name_args = [ cookbook ]
228
+ nv.run
229
+ end
230
+ end
231
+ end
232
+
233
+ def parse_name_args!
234
+ if name_args.empty?
235
+ ui.error("please specify a cookbook to download and install")
236
+ exit 1
237
+ elsif name_args.size > 1
238
+ ui.error("Installing multiple cookbooks at once is not supported")
239
+ exit 1
240
+ else
241
+ name_args.first
242
+ end
243
+ end
244
+
245
+ def download_cookbook_to(download_path)
246
+ downloader = Chef::Knife::CookbookSiteDownload.new
247
+ downloader.config[:file] = download_path
248
+ downloader.name_args = name_args
249
+ downloader.run
250
+ downloader
251
+ end
252
+
253
+ def extract_cookbook(upstream_file, version)
254
+ ui.info("Uncompressing #{@cookbook_name} version #{version}.")
255
+ shell_out!("tar zxvf #{upstream_file}", :cwd => @install_path)
256
+ end
257
+
258
+ def clear_existing_files(cookbook_path)
259
+ ui.info("Removing pre-existing version.")
260
+ shell_out!("rm -r #{cookbook_path}", :cwd => @install_path) if File.directory?(cookbook_path)
261
+ end
262
+
263
+
264
+ end
265
+ end
266
+ end
267
+
268
+
269
+
270
+
271
+
272
+
@@ -62,6 +62,13 @@ class Chef
62
62
  :long => "--ssh-password PASSWORD",
63
63
  :description => "The ssh password"
64
64
 
65
+ option :ssh_port,
66
+ :short => "-p PORT",
67
+ :long => "--ssh-port PORT",
68
+ :description => "The ssh port",
69
+ :default => "22",
70
+ :proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
71
+
65
72
  option :identity_file,
66
73
  :short => "-i IDENTITY_FILE",
67
74
  :long => "--identity-file IDENTITY_FILE",
@@ -115,6 +122,7 @@ class Chef
115
122
  session_opts = {}
116
123
  session_opts[:keys] = File.expand_path(config[:identity_file]) if config[:identity_file]
117
124
  session_opts[:password] = config[:ssh_password] if config[:ssh_password]
125
+ session_opts[:port] = Chef::Config[:knife][:ssh_port] || config[:ssh_port]
118
126
  session_opts[:logger] = Chef::Log.logger if Chef::Log.level == :debug
119
127
 
120
128
  if config[:no_host_key_verify]
@@ -147,10 +147,14 @@ class Chef
147
147
  if config[:with_uri]
148
148
  item
149
149
  else
150
- item.inject({}){|result, (k,v)|
151
- result[k] = v["versions"].inject([]){|res, ver| res.push(ver["version"]); res}
152
- result
153
- }
150
+ versions_by_cookbook = item.inject({}) do |collected, ( cookbook, versions )|
151
+ collected[cookbook] = versions["versions"].map {|v| v['version']}
152
+ collected
153
+ end
154
+ key_length = versions_by_cookbook.keys.map {|name| name.size }.max + 2
155
+ versions_by_cookbook.sort.map do |cookbook, versions|
156
+ "#{cookbook.ljust(key_length)} #{versions.join(',')}"
157
+ end
154
158
  end
155
159
  end
156
160
 
@@ -17,7 +17,7 @@
17
17
 
18
18
  class Chef
19
19
  CHEF_ROOT = File.dirname(File.expand_path(File.dirname(__FILE__)))
20
- VERSION = '0.10.0.beta.3'
20
+ VERSION = '0.10.0.beta.4'
21
21
  end
22
22
 
23
23
  # NOTE: the Chef::Version class is defined in version_class.rb
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: chef
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease: 7
5
- version: 0.10.0.beta.3
5
+ version: 0.10.0.beta.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Adam Jacob
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-03-30 00:00:00 -07:00
13
+ date: 2011-03-31 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -319,12 +319,12 @@ files:
319
319
  - lib/chef/knife/cookbook_metadata_from_file.rb
320
320
  - lib/chef/knife/cookbook_show.rb
321
321
  - lib/chef/knife/cookbook_site_download.rb
322
+ - lib/chef/knife/cookbook_site_install.rb
322
323
  - lib/chef/knife/cookbook_site_list.rb
323
324
  - lib/chef/knife/cookbook_site_search.rb
324
325
  - lib/chef/knife/cookbook_site_share.rb
325
326
  - lib/chef/knife/cookbook_site_show.rb
326
327
  - lib/chef/knife/cookbook_site_unshare.rb
327
- - lib/chef/knife/cookbook_site_vendor.rb
328
328
  - lib/chef/knife/cookbook_test.rb
329
329
  - lib/chef/knife/cookbook_upload.rb
330
330
  - lib/chef/knife/data_bag_create.rb
@@ -1,142 +0,0 @@
1
- #
2
- # Author:: Adam Jacob (<adam@opscode.com>)
3
- # Copyright:: Copyright (c) 2010 Opscode, Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require 'chef/knife'
20
-
21
- class Chef
22
- class Knife
23
- class CookbookSiteVendor < Knife
24
-
25
- deps do
26
- require 'chef/cookbook/metadata'
27
- end
28
-
29
- banner "knife cookbook site vendor COOKBOOK [VERSION] (options)"
30
- category "cookbook site"
31
-
32
- option :deps,
33
- :short => "-d",
34
- :long => "--dependencies",
35
- :boolean => true,
36
- :description => "Grab dependencies automatically"
37
-
38
- option :cookbook_path,
39
- :short => "-o PATH:PATH",
40
- :long => "--cookbook-path PATH:PATH",
41
- :description => "A colon-separated path to look for cookbooks in",
42
- :proc => lambda { |o| o.split(":") }
43
-
44
- option :branch_default,
45
- :short => "-B BRANCH",
46
- :long => "--branch BRANCH",
47
- :description => "Default branch to work with",
48
- :default => "master"
49
-
50
- def run
51
- if config[:cookbook_path]
52
- Chef::Config[:cookbook_path] = config[:cookbook_path]
53
- else
54
- config[:cookbook_path] = Chef::Config[:cookbook_path]
55
- end
56
-
57
- # Check to ensure we have a valid source of cookbooks before continuing
58
- unless File.directory?(config[:cookbook_path].first)
59
- ui.error( File.join(config[:cookbook_path].first, " doesn't exist!. Make sure you have cookbook_path configured correctly"))
60
- exit 1
61
- end
62
-
63
- vendor_path = File.expand_path(File.join(config[:cookbook_path].first))
64
- cookbook_path = File.join(vendor_path, name_args[0])
65
- upstream_file = File.join(vendor_path, "#{name_args[0]}.tar.gz")
66
- branch_name = "chef-vendor-#{name_args[0]}"
67
-
68
- download = Chef::Knife::CookbookSiteDownload.new
69
- download.config[:file] = upstream_file
70
- download.name_args = name_args
71
- download.run
72
-
73
- ui.info("Checking out the #{config[:branch_default]} branch.")
74
- Chef::Mixin::Command.run_command(:command => "git checkout #{config[:branch_default]}", :cwd => vendor_path)
75
- ui.info("Checking the status of the vendor branch.")
76
- status, branch_output, branch_error = Chef::Mixin::Command.output_of_command("git branch --no-color | grep #{branch_name}", :cwd => vendor_path)
77
- if branch_output =~ /#{Regexp.escape(branch_name)}$/m
78
- ui.info("Vendor branch found.")
79
- Chef::Mixin::Command.run_command(:command => "git checkout #{branch_name}", :cwd => vendor_path)
80
- else
81
- ui.info("Creating vendor branch.")
82
- Chef::Mixin::Command.run_command(:command => "git checkout -b #{branch_name}", :cwd => vendor_path)
83
- end
84
- ui.info("Removing pre-existing version.")
85
- Chef::Mixin::Command.run_command(:command => "rm -r #{cookbook_path}", :cwd => vendor_path) if File.directory?(cookbook_path)
86
- ui.info("Uncompressing #{name_args[0]} version #{download.version}.")
87
- Chef::Mixin::Command.run_command(:command => "tar zxvf #{upstream_file}", :cwd => vendor_path)
88
- Chef::Mixin::Command.run_command(:command => "rm #{upstream_file}", :cwd => vendor_path)
89
- ui.info("Adding changes.")
90
- Chef::Mixin::Command.run_command(:command => "git add #{name_args[0]}", :cwd => vendor_path)
91
-
92
- ui.info("Committing changes.")
93
- changes = true
94
- begin
95
- Chef::Mixin::Command.run_command(:command => "git commit -a -m 'Import #{name_args[0]} version #{download.version}'", :cwd => vendor_path)
96
- rescue Chef::Exceptions::Exec => e
97
- ui.warn("Checking out the #{config[:branch_default]} branch.")
98
- ui.warn("No changes from current vendor #{name_args[0]}")
99
- Chef::Mixin::Command.run_command(:command => "git checkout #{config[:branch_default]}", :cwd => vendor_path)
100
- changes = false
101
- end
102
-
103
- if changes
104
- ui.info("Creating tag chef-vendor-#{name_args[0]}-#{download.version}.")
105
- Chef::Mixin::Command.run_command(:command => "git tag -f chef-vendor-#{name_args[0]}-#{download.version}", :cwd => vendor_path)
106
- ui.info("Checking out the #{config[:branch_default]} branch.")
107
- Chef::Mixin::Command.run_command(:command => "git checkout #{config[:branch_default]}", :cwd => vendor_path)
108
- ui.info("Merging changes from #{name_args[0]} version #{download.version}.")
109
-
110
- Dir.chdir(vendor_path) do
111
- if system("git merge #{branch_name}")
112
- ui.info("Cookbook #{name_args[0]} version #{download.version} successfully vendored!")
113
- else
114
- ui.error("You have merge conflicts - please resolve manually!")
115
- ui.error("(Hint: cd #{vendor_path}; git status)")
116
- exit 1
117
- end
118
- end
119
- end
120
-
121
- if config[:deps]
122
- md = Chef::Cookbook::Metadata.new
123
- md.from_file(File.join(cookbook_path, "metadata.rb"))
124
- md.dependencies.each do |cookbook, version_list|
125
- # Doesn't do versions.. yet
126
- nv = Chef::Knife::CookbookSiteVendor.new
127
- nv.config = config
128
- nv.name_args = [ cookbook ]
129
- nv.run
130
- end
131
- end
132
- end
133
-
134
- end
135
- end
136
- end
137
-
138
-
139
-
140
-
141
-
142
-