berkshelf 1.0.0 → 1.0.2
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.
- data/lib/berkshelf.rb +2 -2
- data/lib/berkshelf/cli.rb +1 -1
- data/lib/berkshelf/core_ext/file_utils.rb +3 -24
- data/lib/berkshelf/git.rb +12 -10
- data/lib/berkshelf/locations/git_location.rb +33 -8
- data/lib/berkshelf/locations/github_location.rb +10 -10
- data/lib/berkshelf/version.rb +1 -1
- data/spec/unit/berkshelf/core_ext/file_utils_spec.rb +3 -9
- data/spec/unit/berkshelf/git_spec.rb +106 -108
- data/spec/unit/berkshelf/locations/git_location_spec.rb +6 -0
- metadata +3 -3
data/lib/berkshelf.rb
CHANGED
@@ -83,8 +83,8 @@ module Berkshelf
|
|
83
83
|
# @return [String]
|
84
84
|
# path to the created temporary directory
|
85
85
|
def mktmpdir
|
86
|
-
FileUtils.mkdir_p(
|
87
|
-
Dir.mktmpdir(nil,
|
86
|
+
FileUtils.mkdir_p(tmp_dir)
|
87
|
+
Dir.mktmpdir(nil, tmp_dir)
|
88
88
|
end
|
89
89
|
|
90
90
|
def cookbooks_dir
|
data/lib/berkshelf/cli.rb
CHANGED
@@ -183,7 +183,7 @@ module Berkshelf
|
|
183
183
|
client_name: Berkshelf::Config.instance.chef.node_name,
|
184
184
|
client_key: Berkshelf::Config.instance.chef.client_key,
|
185
185
|
ssl: {
|
186
|
-
verify: (options[:ssl_verify]
|
186
|
+
verify: (options[:ssl_verify].nil? ? Berkshelf::Config.instance.ssl.verify : options[:ssl_verify])
|
187
187
|
}
|
188
188
|
)
|
189
189
|
rescue Ridley::Errors::ClientKeyFileNotFound => e
|
@@ -2,34 +2,13 @@ require 'fileutils'
|
|
2
2
|
|
3
3
|
module FileUtils
|
4
4
|
class << self
|
5
|
-
|
6
|
-
|
7
|
-
# Override mv to ensure {safe_mv} is run if we are on the Windows platform.
|
5
|
+
# Override mv to avoid several bugs (Errno::EACCES in Windows, Errno::ENOENT
|
6
|
+
# with relative softlinks on Linux), by forcing to copy and delete instead
|
8
7
|
#
|
9
8
|
# @see {FileUtils::mv}
|
10
9
|
# @see {safe_mv}
|
11
10
|
def mv(src, dest, options = {})
|
12
|
-
|
13
|
-
safe_mv(src, dest, options)
|
14
|
-
else
|
15
|
-
old_mv(src, dest, options)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# If we encounter Errno::EACCES, which seems to happen occasionally on Windows,
|
20
|
-
# try to copy and delete the file instead of moving it.
|
21
|
-
#
|
22
|
-
# @see https://github.com/RiotGames/berkshelf/issues/140
|
23
|
-
# @see http://www.ruby-forum.com/topic/1044813
|
24
|
-
#
|
25
|
-
# @param [String] src
|
26
|
-
# @param [String] dest
|
27
|
-
# @param [Hash] options
|
28
|
-
# @see {FileUtils::mv}
|
29
|
-
def safe_mv(src, dest, options = {})
|
30
|
-
FileUtils.old_mv(src, dest, options)
|
31
|
-
rescue Errno::EACCES
|
32
|
-
FileUtils.cp_r(src, dest)
|
11
|
+
FileUtils.cp_r(src, dest, options)
|
33
12
|
FileUtils.rm_rf(src)
|
34
13
|
end
|
35
14
|
end
|
data/lib/berkshelf/git.rb
CHANGED
@@ -73,16 +73,8 @@ module Berkshelf
|
|
73
73
|
def find_git
|
74
74
|
git_path = nil
|
75
75
|
ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
|
76
|
-
|
77
|
-
if
|
78
|
-
git_path = potential_path
|
79
|
-
break
|
80
|
-
end
|
81
|
-
potential_path = File.join(path, 'git.exe')
|
82
|
-
if File.executable?(potential_path)
|
83
|
-
git_path = potential_path
|
84
|
-
break
|
85
|
-
end
|
76
|
+
git_path = detect_git_path(path)
|
77
|
+
break if git_path
|
86
78
|
end
|
87
79
|
|
88
80
|
unless git_path
|
@@ -144,6 +136,16 @@ module Berkshelf
|
|
144
136
|
return arg unless HAS_SPACE_RE.match(arg)
|
145
137
|
"\"#{arg}\""
|
146
138
|
end
|
139
|
+
|
140
|
+
def detect_git_path(base_dir)
|
141
|
+
%w{ git git.exe git.cmd }.each do |git_cmd|
|
142
|
+
potential_path = File.join(base_dir, git_cmd)
|
143
|
+
if File.executable?(potential_path)
|
144
|
+
return potential_path
|
145
|
+
end
|
146
|
+
end
|
147
|
+
nil
|
148
|
+
end
|
147
149
|
end
|
148
150
|
end
|
149
151
|
end
|
@@ -1,13 +1,25 @@
|
|
1
1
|
module Berkshelf
|
2
2
|
# @author Jamie Winsor <jamie@vialstudios.com>
|
3
3
|
class GitLocation
|
4
|
+
class << self
|
5
|
+
# Create a temporary directory for the cloned repository within Berkshelf's
|
6
|
+
# temporary directory
|
7
|
+
#
|
8
|
+
# @return [String]
|
9
|
+
# the path to the created temporary directory
|
10
|
+
def tmpdir
|
11
|
+
@tmpdir ||= Dir.mktmpdir(Berkshelf.mktmpdir)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
4
15
|
include Location
|
5
16
|
|
6
17
|
set_location_key :git
|
7
|
-
set_valid_options :ref, :branch, :tag
|
18
|
+
set_valid_options :ref, :branch, :tag, :rel
|
8
19
|
|
9
20
|
attr_accessor :uri
|
10
21
|
attr_accessor :branch
|
22
|
+
attr_accessor :rel
|
11
23
|
|
12
24
|
alias_method :ref, :branch
|
13
25
|
alias_method :tag, :branch
|
@@ -24,11 +36,14 @@ module Berkshelf
|
|
24
36
|
# same as ref
|
25
37
|
# @option options [String] :tag
|
26
38
|
# same as tag
|
39
|
+
# @option options [String] :rel
|
40
|
+
# the path within the repository to find the cookbook
|
27
41
|
def initialize(name, version_constraint, options = {})
|
28
42
|
@name = name
|
29
43
|
@version_constraint = version_constraint
|
30
44
|
@uri = options[:git]
|
31
45
|
@branch = options[:branch] || options[:ref] || options[:tag]
|
46
|
+
@rel = options[:rel]
|
32
47
|
|
33
48
|
Git.validate_uri!(@uri)
|
34
49
|
end
|
@@ -37,22 +52,22 @@ module Berkshelf
|
|
37
52
|
#
|
38
53
|
# @return [Berkshelf::CachedCookbook]
|
39
54
|
def download(destination)
|
40
|
-
|
41
|
-
::Berkshelf::Git.clone(uri, tmp_clone)
|
42
|
-
::Berkshelf::Git.checkout(tmp_clone, branch) if branch
|
55
|
+
::Berkshelf::Git.checkout(clone, branch) if branch
|
43
56
|
unless branch
|
44
|
-
self.branch = ::Berkshelf::Git.rev_parse(
|
57
|
+
self.branch = ::Berkshelf::Git.rev_parse(clone)
|
45
58
|
end
|
46
59
|
|
47
|
-
|
60
|
+
tmp_path = rel ? File.join(clone, rel) : clone
|
61
|
+
unless File.chef_cookbook?(tmp_path)
|
48
62
|
msg = "Cookbook '#{name}' not found at git: #{uri}"
|
49
63
|
msg << " with branch '#{branch}'" if branch
|
64
|
+
msg << " at path '#{rel}'" if rel
|
50
65
|
raise CookbookNotFound, msg
|
51
66
|
end
|
52
67
|
|
53
|
-
cb_path = File.join(destination, "#{self.name}-#{Git.rev_parse(
|
68
|
+
cb_path = File.join(destination, "#{self.name}-#{Git.rev_parse(clone)}")
|
54
69
|
FileUtils.rm_rf(cb_path)
|
55
|
-
FileUtils.mv(
|
70
|
+
FileUtils.mv(tmp_path, cb_path)
|
56
71
|
|
57
72
|
cached = CachedCookbook.from_store_path(cb_path)
|
58
73
|
validate_cached(cached)
|
@@ -79,5 +94,15 @@ module Berkshelf
|
|
79
94
|
def git
|
80
95
|
@git ||= Berkshelf::Git.new(uri)
|
81
96
|
end
|
97
|
+
|
98
|
+
def clone
|
99
|
+
tmp_clone = File.join(self.class.tmpdir, uri.gsub(/[\/:]/,'-'))
|
100
|
+
|
101
|
+
unless File.exists?(tmp_clone)
|
102
|
+
Berkshelf::Git.clone(uri, tmp_clone)
|
103
|
+
end
|
104
|
+
|
105
|
+
tmp_clone
|
106
|
+
end
|
82
107
|
end
|
83
108
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Berkshelf
|
2
2
|
# @author Josiah Kiehl <josiah@skirmisher.net>
|
3
3
|
class GithubLocation < GitLocation
|
4
|
-
DEFAULT_PROTOCOL =
|
4
|
+
DEFAULT_PROTOCOL = :git
|
5
5
|
|
6
6
|
set_location_key :github
|
7
7
|
set_valid_options :protocol
|
@@ -16,12 +16,12 @@ module Berkshelf
|
|
16
16
|
#
|
17
17
|
# @option options [String] :github
|
18
18
|
# the GitHub repo identifier to clone
|
19
|
-
# @option options [
|
19
|
+
# @option options [#to_sym] :protocol
|
20
20
|
# the protocol with which to communicate with GitHub
|
21
21
|
def initialize(name, version_constraint, options = {})
|
22
22
|
@repo_identifier = options.delete(:github)
|
23
|
-
@protocol
|
24
|
-
options[:git]
|
23
|
+
@protocol = (options.delete(:protocol) || DEFAULT_PROTOCOL).to_sym
|
24
|
+
options[:git] = github_url
|
25
25
|
super
|
26
26
|
end
|
27
27
|
|
@@ -32,12 +32,12 @@ module Berkshelf
|
|
32
32
|
# @return [String]
|
33
33
|
# GitHub url
|
34
34
|
def github_url
|
35
|
-
case protocol
|
36
|
-
when
|
35
|
+
case protocol
|
36
|
+
when :ssh
|
37
37
|
"git@github.com:#{repo_identifier}.git"
|
38
|
-
when
|
38
|
+
when :https
|
39
39
|
"https://github.com/#{repo_identifier}.git"
|
40
|
-
when
|
40
|
+
when :git
|
41
41
|
"git://github.com/#{repo_identifier}.git"
|
42
42
|
else
|
43
43
|
raise UnknownGitHubProtocol.new(protocol)
|
@@ -46,7 +46,7 @@ module Berkshelf
|
|
46
46
|
|
47
47
|
def to_s
|
48
48
|
s = "#{self.class.location_key}: '#{repo_identifier}'"
|
49
|
-
s << " with branch: '#{branch}'"
|
49
|
+
s << " with branch: '#{branch}'" if branch
|
50
50
|
s << " over protocol: '#{protocol}'" unless default_protocol?
|
51
51
|
s
|
52
52
|
end
|
@@ -54,7 +54,7 @@ module Berkshelf
|
|
54
54
|
private
|
55
55
|
|
56
56
|
def default_protocol?
|
57
|
-
|
57
|
+
self.protocol == DEFAULT_PROTOCOL
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
data/lib/berkshelf/version.rb
CHANGED
@@ -6,16 +6,10 @@ describe FileUtils do
|
|
6
6
|
let(:dest) { double('dest') }
|
7
7
|
let(:options) { double('options') }
|
8
8
|
|
9
|
-
it "
|
9
|
+
it "replaces mv with cp_r and rm_rf" do
|
10
10
|
subject.stub(:windows?) { true }
|
11
|
-
FileUtils.should_receive(:
|
12
|
-
|
13
|
-
FileUtils.mv(src, dest, options)
|
14
|
-
end
|
15
|
-
|
16
|
-
it "delegates to #old_mv if not on Windows" do
|
17
|
-
subject.stub(:windows?) { false }
|
18
|
-
FileUtils.should_receive(:old_mv).with(src, dest, options)
|
11
|
+
FileUtils.should_receive(:cp_r).with(src, dest, options)
|
12
|
+
FileUtils.should_receive(:rm_rf).with(src)
|
19
13
|
|
20
14
|
FileUtils.mv(src, dest, options)
|
21
15
|
end
|
@@ -1,157 +1,155 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
describe
|
5
|
-
|
6
|
-
subject { Git }
|
7
|
-
|
8
|
-
describe "::find_git" do
|
9
|
-
it "should find git" do
|
10
|
-
subject.find_git.should_not be_nil
|
11
|
-
end
|
3
|
+
describe Berkshelf::Git do
|
4
|
+
describe "ClassMethods" do
|
5
|
+
subject { Berkshelf::Git }
|
12
6
|
|
13
|
-
|
14
|
-
|
7
|
+
describe "::find_git" do
|
8
|
+
it "should find git" do
|
9
|
+
subject.find_git.should_not be_nil
|
10
|
+
end
|
15
11
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
it "should raise if it can't find git" do
|
13
|
+
ENV.should_receive(:[]).with("PATH").and_return(String.new)
|
14
|
+
|
15
|
+
lambda {
|
16
|
+
subject.find_git
|
17
|
+
}.should raise_error(Berkshelf::GitNotFound)
|
20
18
|
end
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
21
|
+
describe "::clone" do
|
22
|
+
let(:target) { tmp_path.join("nginx") }
|
24
23
|
|
25
|
-
|
26
|
-
|
24
|
+
it "clones the repository to the target path" do
|
25
|
+
subject.clone("git://github.com/opscode-cookbooks/nginx.git", target)
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
27
|
+
target.should exist
|
28
|
+
target.should be_directory
|
31
29
|
end
|
30
|
+
end
|
32
31
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
describe "::checkout" do
|
33
|
+
let(:repo_path) { tmp_path.join("nginx") }
|
34
|
+
let(:repo) { subject.clone("git://github.com/opscode-cookbooks/nginx.git", repo_path) }
|
35
|
+
let(:tag) { "0.101.2" }
|
37
36
|
|
38
|
-
|
39
|
-
|
37
|
+
it "checks out the specified path of the given repository" do
|
38
|
+
subject.checkout(repo, tag)
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
end
|
40
|
+
Dir.chdir repo_path do
|
41
|
+
%x[git rev-parse #{tag}].should == %x[git rev-parse HEAD]
|
44
42
|
end
|
45
43
|
end
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
46
|
+
describe "::rev_parse" do
|
47
|
+
let(:repo_path) { tmp_path.join("nginx") }
|
48
|
+
before(:each) do
|
49
|
+
subject.clone("git://github.com/opscode-cookbooks/nginx.git", repo_path)
|
50
|
+
subject.checkout(repo_path, "0e4887d9eef8cb83972f974a85890983c8204c3b")
|
51
|
+
end
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
end
|
53
|
+
it "returns the ref for HEAD" do
|
54
|
+
subject.rev_parse(repo_path).should eql("0e4887d9eef8cb83972f974a85890983c8204c3b")
|
57
55
|
end
|
56
|
+
end
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
let(:readonly_uri) { "git://github.com/reset/thor-foodcritic.git" }
|
59
|
+
let(:https_uri) { "https://github.com/reset/solve.git" }
|
60
|
+
let(:http_uri) { "http://github.com/reset/solve.git" }
|
61
|
+
let(:invalid_uri) { "/something/on/disk" }
|
63
62
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
63
|
+
describe "::validate_uri" do
|
64
|
+
context "given a valid Git read-only URI" do
|
65
|
+
it "returns true" do
|
66
|
+
subject.validate_uri(readonly_uri).should be_true
|
69
67
|
end
|
68
|
+
end
|
70
69
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
70
|
+
context "given a valid Git HTTPS URI" do
|
71
|
+
it "returns true" do
|
72
|
+
subject.validate_uri(https_uri).should be_true
|
75
73
|
end
|
74
|
+
end
|
76
75
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
76
|
+
context "given a valid Github SSH URI" do
|
77
|
+
it "returns true" do
|
78
|
+
subject.validate_uri("git@github.com:reset/solve.git").should be_true
|
81
79
|
end
|
80
|
+
end
|
82
81
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
end
|
82
|
+
context "given a valid SSH URI without an 'organization'" do
|
83
|
+
it "returns true" do
|
84
|
+
subject.validate_uri("gituser@githost:solve.git").should be_true
|
87
85
|
end
|
86
|
+
end
|
88
87
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end
|
88
|
+
context "given an invalid URI" do
|
89
|
+
it "returns false" do
|
90
|
+
subject.validate_uri(invalid_uri).should be_false
|
93
91
|
end
|
92
|
+
end
|
94
93
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
94
|
+
context "given a HTTP URI" do
|
95
|
+
it "returns false" do
|
96
|
+
subject.validate_uri(http_uri).should be_false
|
99
97
|
end
|
98
|
+
end
|
100
99
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
100
|
+
context "given an integer" do
|
101
|
+
it "returns false" do
|
102
|
+
subject.validate_uri(123).should be_false
|
105
103
|
end
|
106
104
|
end
|
105
|
+
end
|
107
106
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
end
|
107
|
+
describe "::validate_uri!" do
|
108
|
+
context "given a valid Git read-only URI" do
|
109
|
+
it "returns true" do
|
110
|
+
subject.validate_uri!(readonly_uri).should be_true
|
113
111
|
end
|
112
|
+
end
|
114
113
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
end
|
114
|
+
context "given a valid Git HTTPS URI" do
|
115
|
+
it "returns true" do
|
116
|
+
subject.validate_uri!(https_uri).should be_true
|
119
117
|
end
|
118
|
+
end
|
120
119
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
120
|
+
context "given a valid Git SSH URI" do
|
121
|
+
it "returns true" do
|
122
|
+
subject.validate_uri!("git@github.com:reset/solve.git").should be_true
|
125
123
|
end
|
124
|
+
end
|
126
125
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
end
|
126
|
+
context "given a valid SSH URI without an 'organization'" do
|
127
|
+
it "returns true" do
|
128
|
+
subject.validate_uri("gituser@githost:solve.git").should be_true
|
131
129
|
end
|
130
|
+
end
|
132
131
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
end
|
132
|
+
context "given an invalid URI" do
|
133
|
+
it "raises InvalidGitURI" do
|
134
|
+
lambda {
|
135
|
+
subject.validate_uri!(invalid_uri)
|
136
|
+
}.should raise_error(Berkshelf::InvalidGitURI)
|
139
137
|
end
|
138
|
+
end
|
140
139
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
end
|
140
|
+
context "given a HTTP URI" do
|
141
|
+
it "raises InvalidGitURI" do
|
142
|
+
lambda {
|
143
|
+
subject.validate_uri!(http_uri)
|
144
|
+
}.should raise_error(Berkshelf::InvalidGitURI)
|
147
145
|
end
|
146
|
+
end
|
148
147
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
end
|
148
|
+
context "given an integer" do
|
149
|
+
it "raises InvalidGitURI" do
|
150
|
+
lambda {
|
151
|
+
subject.validate_uri!(123)
|
152
|
+
}.should raise_error(Berkshelf::InvalidGitURI)
|
155
153
|
end
|
156
154
|
end
|
157
155
|
end
|
@@ -14,6 +14,12 @@ module Berkshelf
|
|
14
14
|
}.should raise_error(InvalidGitURI)
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
18
|
+
describe "::tmpdir" do
|
19
|
+
it "creates a temporary directory within the Berkshelf temporary directory" do
|
20
|
+
subject.tmpdir.should include(Berkshelf.tmp_dir)
|
21
|
+
end
|
22
|
+
end
|
17
23
|
end
|
18
24
|
|
19
25
|
subject { GitLocation.new("artifact", complacent_constraint, git: "git://github.com/RiotGames/artifact-cookbook.git") }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: berkshelf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-11-
|
15
|
+
date: 2012-11-14 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: yajl-ruby
|
@@ -361,7 +361,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
361
361
|
version: '0'
|
362
362
|
segments:
|
363
363
|
- 0
|
364
|
-
hash:
|
364
|
+
hash: 2215402916599096616
|
365
365
|
requirements: []
|
366
366
|
rubyforge_project:
|
367
367
|
rubygems_version: 1.8.23
|