librarian 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -16,20 +16,59 @@ An adapter for Librarian applying to Chef cookbooks in a Chef Repository.
16
16
 
17
17
  Usage:
18
18
 
19
+ # install librarian onto your system
20
+ $ gem install librarian
21
+
19
22
  $ cd ~/path/to/chef-repo
20
- # put dependencies and their sources into ./Cheffile
21
23
 
22
- # resolve dependencies:
23
- $ librarian-chef resolve [--clean] [--verbose]
24
+ # make sure your cookbooks directory exists but is gitignored
25
+ $ git rm -r cookbooks # if the directory is present
26
+ $ mkdir cookbooks
27
+ $ echo cookbooks >> .gitignore
28
+
29
+ # put dependencies and their sources into Cheffile
30
+ $ cat Cheffile
31
+ site 'http://community.opscode.com/api/v1'
32
+ cookbook 'ntp'
33
+ cookbook 'timezone'
34
+ cookbook 'rvm',
35
+ :git => 'https://github.com/fnichol/chef-rvm',
36
+ :ref => 'v0.7.1'
24
37
 
25
38
  # install dependencies into ./cookbooks
26
39
  $ librarian-chef install [--clean] [--verbose]
27
40
 
41
+ # check into version control your ./Cheffile.lock
42
+ $ git add Cheffile.lock
43
+ $ git commit -m "I want these particular versions of these particular cookbooks from these particular."
44
+
28
45
  # update your cheffile with new/changed/removed constraints/sources/dependencies
46
+ $ cat Cheffile
47
+ site 'http://community.opscode.com/api/v1'
48
+ cookbook 'ntp'
49
+ cookbook 'timezone'
50
+ cookbook 'rvm',
51
+ :git => 'https://github.com/fnichol/chef-rvm',
52
+ :ref => 'v0.7.1'
53
+ cookbook 'monit' # new!
54
+ $ git diff Cheffile
29
55
  $ librarian-chef install [--verbose]
56
+ $ git diff Cheffile.lock
57
+ $ git add Cheffile
58
+ $ git add Cheffile.lock
59
+ $ git commit -m "I also want these additional cookbooks."
30
60
 
31
61
  # update the version of a dependency
32
- $ librarian-chef update dependency-1 dependency-2 dependency-3 [--verbose]
62
+ $ librarian-chef update ntp timezone monit [--verbose]
63
+ $ git diff Cheffile.lock
64
+ $ git add Cheffile.lock
65
+ $ git commit -m "I want updated versions of these cookbooks."
66
+
67
+ # push your changes to the git repository
68
+ $ git push origin master
69
+
70
+ # upload the cookbooks to your chef-server
71
+ $ knife cookbook upload --all
33
72
 
34
73
  You should `.gitignore` your `./cookbooks` directory.
35
74
  If you are manually tracking/vendoring outside cookbooks within the repository,
@@ -27,12 +27,13 @@ module Librarian
27
27
  :ref => 'master'
28
28
  }
29
29
 
30
- attr_reader :uri, :ref, :sha
30
+ attr_reader :uri, :ref, :sha, :path
31
31
 
32
32
  def initialize(uri, options = {})
33
33
  @uri = uri
34
34
  @ref = options[:ref] || DEFAULTS[:ref]
35
35
  @sha = options[:sha]
36
+ @path = options[:path]
36
37
  @repository = nil
37
38
  @repository_cache_path = nil
38
39
  end
@@ -46,15 +47,20 @@ module Librarian
46
47
  self.class == other.class &&
47
48
  self.uri == other.uri &&
48
49
  self.ref == other.ref &&
50
+ self.path == other.path &&
49
51
  (self.sha.nil? || other.sha.nil? || self.sha == other.sha)
50
52
  end
51
53
 
52
54
  def to_spec_args
53
- [uri, {:ref => ref}]
55
+ options = {:ref => ref}
56
+ options.merge!(:path => path) if path
57
+ [uri, options]
54
58
  end
55
59
 
56
60
  def to_lock_options
57
- {:remote => uri, :ref => ref, :sha => sha}
61
+ options = {:remote => uri, :ref => ref, :sha => sha}
62
+ options.merge!(:path => path) if path
63
+ options
58
64
  end
59
65
 
60
66
  def cache!(dependencies)
@@ -71,7 +77,8 @@ module Librarian
71
77
 
72
78
  def repository_cache_path
73
79
  @repository_cache_path ||= begin
74
- dir = Digest::MD5.hexdigest(uri)
80
+ dir = path ? "#{uri}/#{path}" : uri
81
+ dir = Digest::MD5.hexdigest(dir)
75
82
  root_module.cache_path.join("source/git/#{dir}")
76
83
  end
77
84
  end
@@ -82,8 +89,18 @@ module Librarian
82
89
  end
83
90
  end
84
91
 
85
- def path
86
- @path ||= repository.path
92
+ def filesystem_path
93
+ @filesystem_path ||= repository.path
94
+ end
95
+
96
+ # Override Local#manifest_search_paths
97
+ def manifest_search_paths(dependency)
98
+ if path.nil?
99
+ paths = [filesystem_path, filesystem_path.join(dependency.name)]
100
+ paths.select{|s| s.exist?}
101
+ else
102
+ [filesystem_path.join(path)]
103
+ end
87
104
  end
88
105
 
89
106
  end
@@ -12,19 +12,19 @@ module Librarian
12
12
  abstract_method :path
13
13
 
14
14
  def manifests(dependency)
15
- manifest = manifest_class.create(self, dependency, path)
15
+ manifest = manifest_class.create(self, dependency, filesystem_path)
16
16
  [manifest].compact
17
17
  end
18
18
 
19
19
  def manifest(name, version, dependencies)
20
- manifest = manifest_class.create(self, Dependency.new(name, nil, nil), path)
20
+ manifest = manifest_class.create(self, Dependency.new(name, nil, nil), filesystem_path)
21
21
  manifest.version = version
22
22
  manifest.dependencies = dependencies
23
23
  manifest
24
24
  end
25
25
 
26
26
  def manifest_search_paths(dependency)
27
- paths = [path, path.join(dependency.name)]
27
+ paths = [filesystem_path, filesystem_path.join(dependency.name)]
28
28
  paths.select{|s| s.exist?}
29
29
  end
30
30
 
@@ -21,7 +21,7 @@ module Librarian
21
21
  attr_reader :path
22
22
 
23
23
  def initialize(path, options)
24
- @path = Pathname.new(path).expand_path(root_module.project_path)
24
+ @path = path
25
25
  end
26
26
 
27
27
  def to_s
@@ -39,14 +39,16 @@ module Librarian
39
39
  end
40
40
 
41
41
  def to_lock_options
42
- absolute_path = path.absolute? ? path : path.expand_path(root_module.project_path)
43
- relative_path = path.relative? ? path : path.relative_path_from(root_module.project_path)
44
- {:remote => relative_path.to_s[0, 3] == '../' ? absolute_path : relative_path}
42
+ {:remote => path}
45
43
  end
46
44
 
47
45
  def cache!(dependencies)
48
46
  end
49
47
 
48
+ def filesystem_path
49
+ @filesystem_path ||= Pathname.new(path).expand_path(root_module.project_path)
50
+ end
51
+
50
52
  end
51
53
  end
52
54
  end
@@ -1,3 +1,3 @@
1
1
  module Librarian
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/librarian.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_development_dependency "rspec"
25
25
  s.add_development_dependency "cucumber"
26
26
  s.add_development_dependency "aruba"
27
+ s.add_development_dependency "webmock"
27
28
 
28
29
  s.add_development_dependency "chef", ">= 0.10"
29
30
  end
@@ -13,24 +13,25 @@ module Librarian
13
13
  project_path = Pathname.new(__FILE__).expand_path
14
14
  project_path = project_path.dirname until project_path.join("Rakefile").exist?
15
15
  tmp_path = project_path.join("tmp/spec/chef/git-source")
16
- sample_path = tmp_path.join('sample')
17
- sample_metadata = Helpers.strip_heredoc(<<-METADATA)
18
- version '0.6.5'
19
- METADATA
20
-
21
- before :all do
22
- sample_path.rmtree if sample_path.exist?
23
- sample_path.mkpath
24
- sample_path.join('metadata.rb').open('wb') { |f| f.write(sample_metadata) }
25
- Dir.chdir(sample_path) do
26
- `git init`
27
- `git add metadata.rb`
28
- `git commit -m "Initial commit."`
29
- end
30
- end
31
16
 
32
17
  context "a single dependency with a git source" do
33
18
 
19
+ sample_path = tmp_path.join('sample')
20
+ sample_metadata = Helpers.strip_heredoc(<<-METADATA)
21
+ version '0.6.5'
22
+ METADATA
23
+
24
+ before :all do
25
+ sample_path.rmtree if sample_path.exist?
26
+ sample_path.mkpath
27
+ sample_path.join('metadata.rb').open('wb') { |f| f.write(sample_metadata) }
28
+ Dir.chdir(sample_path) do
29
+ `git init`
30
+ `git add metadata.rb`
31
+ `git commit -m "Initial commit."`
32
+ end
33
+ end
34
+
34
35
  it "should resolve" do
35
36
  repo_path = tmp_path.join('repo/resolve')
36
37
  repo_path.rmtree if repo_path.exist?
@@ -87,6 +88,86 @@ module Librarian
87
88
 
88
89
  end
89
90
 
91
+ context "with a path" do
92
+
93
+ git_path = tmp_path.join('big-git-repo')
94
+ sample_path = git_path.join('buttercup')
95
+ sample_metadata = Helpers.strip_heredoc(<<-METADATA)
96
+ version '0.6.5'
97
+ METADATA
98
+
99
+ before :all do
100
+ git_path.rmtree if git_path.exist?
101
+ git_path.mkpath
102
+ sample_path.mkpath
103
+ sample_path.join('metadata.rb').open('wb') { |f| f.write(sample_metadata) }
104
+ Dir.chdir(git_path) do
105
+ `git init`
106
+ `git add .`
107
+ `git commit -m "Initial commit."`
108
+ end
109
+ end
110
+
111
+ context "if no path option is given" do
112
+ it "should not resolve" do
113
+ repo_path = tmp_path.join('repo/resolve')
114
+ repo_path.rmtree if repo_path.exist?
115
+ repo_path.mkpath
116
+ repo_path.join('cookbooks').mkpath
117
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
118
+ #!/usr/bin/env ruby
119
+ cookbook "sample",
120
+ :git => #{git_path.to_s.inspect}
121
+ CHEFFILE
122
+ repo_path.join('Cheffile').open('wb') { |f| f.write(cheffile) }
123
+ Chef.stub!(:project_path) { repo_path }
124
+
125
+ expect{ Chef.resolve! }.to raise_error
126
+ end
127
+ end
128
+
129
+ context "if the path option is wrong" do
130
+ it "should not resolve" do
131
+ repo_path = tmp_path.join('repo/resolve')
132
+ repo_path.rmtree if repo_path.exist?
133
+ repo_path.mkpath
134
+ repo_path.join('cookbooks').mkpath
135
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
136
+ #!/usr/bin/env ruby
137
+ cookbook "sample",
138
+ :git => #{git_path.to_s.inspect},
139
+ :path => "jelly"
140
+ CHEFFILE
141
+ repo_path.join('Cheffile').open('wb') { |f| f.write(cheffile) }
142
+ Chef.stub!(:project_path) { repo_path }
143
+
144
+ expect{ Chef.resolve! }.to raise_error
145
+ end
146
+ end
147
+
148
+ context "if the path option is right" do
149
+ it "should not resolve" do
150
+ repo_path = tmp_path.join('repo/resolve')
151
+ repo_path.rmtree if repo_path.exist?
152
+ repo_path.mkpath
153
+ repo_path.join('cookbooks').mkpath
154
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
155
+ #!/usr/bin/env ruby
156
+ cookbook "sample",
157
+ :git => #{git_path.to_s.inspect},
158
+ :path => "buttercup"
159
+ CHEFFILE
160
+ repo_path.join('Cheffile').open('wb') { |f| f.write(cheffile) }
161
+ Chef.stub!(:project_path) { repo_path }
162
+
163
+ Chef.resolve!
164
+ repo_path.join('Cheffile.lock').should be_exist
165
+ repo_path.join('cookbooks/sample').should_not be_exist
166
+ end
167
+ end
168
+
169
+ end
170
+
90
171
  end
91
172
  end
92
173
  end
@@ -0,0 +1,120 @@
1
+ require 'webmock'
2
+
3
+ require 'librarian'
4
+ require 'librarian/helpers'
5
+ require 'librarian/chef'
6
+
7
+ module Librarian
8
+ module Chef
9
+ module Source
10
+ describe Site do
11
+
12
+ include WebMock::API
13
+
14
+ project_path = Pathname.new(__FILE__).expand_path
15
+ project_path = project_path.dirname until project_path.join("Rakefile").exist?
16
+ tmp_path = project_path.join("tmp/spec/chef/site-source")
17
+ sample_path = tmp_path.join('sample')
18
+ sample_metadata = Helpers.strip_heredoc(<<-METADATA)
19
+ version '0.6.5'
20
+ METADATA
21
+
22
+ api_url = "http://site.cookbooks.com"
23
+
24
+ sample_index_data = {
25
+ "name" => "sample",
26
+ "versions" => [
27
+ "#{api_url}/cookbooks/sample/versions/0_6_5"
28
+ ]
29
+ }
30
+ sample_0_6_5_data = {
31
+ "version" => "0.6.5",
32
+ "file" => "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz"
33
+ }
34
+
35
+ before :all do
36
+ sample_path.rmtree if sample_path.exist?
37
+ sample_path.mkpath
38
+ sample_path.join('metadata.rb').open('wb') { |f| f.write(sample_metadata) }
39
+ Dir.chdir(sample_path.dirname) do
40
+ system "tar --create --gzip --file sample.tar.gz #{sample_path.basename}"
41
+ end
42
+ end
43
+
44
+ before do
45
+ stub_request(:get, "#{api_url}/cookbooks/sample").
46
+ to_return(:body => JSON.dump(sample_index_data))
47
+
48
+ stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5").
49
+ to_return(:body => JSON.dump(sample_0_6_5_data))
50
+
51
+ stub_request(:get, "#{api_url}/cookbooks/sample/versions/0_6_5/file.tar.gz").
52
+ to_return(:body => sample_path.dirname.join("sample.tar.gz").read)
53
+ end
54
+
55
+ after do
56
+ WebMock.reset!
57
+ end
58
+
59
+ context "a single dependency with a site source" do
60
+
61
+ it "should resolve" do
62
+ repo_path = tmp_path.join('repo/resolve')
63
+ repo_path.rmtree if repo_path.exist?
64
+ repo_path.mkpath
65
+ repo_path.join('cookbooks').mkpath
66
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
67
+ #!/usr/bin/env ruby
68
+ cookbook "sample", :site => "#{api_url}"
69
+ CHEFFILE
70
+ repo_path.join('Cheffile').open('wb') { |f| f.write(cheffile) }
71
+ Chef.stub!(:project_path) { repo_path }
72
+
73
+ Chef.resolve!
74
+ repo_path.join('Cheffile.lock').should be_exist
75
+ repo_path.join('cookbooks/sample').should_not be_exist
76
+ end
77
+
78
+ it "should install" do
79
+ repo_path = tmp_path.join('repo/install')
80
+ repo_path.rmtree if repo_path.exist?
81
+ repo_path.mkpath
82
+ repo_path.join('cookbooks').mkpath
83
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
84
+ #!/usr/bin/env ruby
85
+ cookbook "sample", :site => "#{api_url}"
86
+ CHEFFILE
87
+ repo_path.join('Cheffile').open('wb') { |f| f.write(cheffile) }
88
+ Chef.stub!(:project_path) { repo_path }
89
+
90
+ Chef.install!
91
+ repo_path.join('Cheffile.lock').should be_exist
92
+ repo_path.join('cookbooks/sample').should be_exist
93
+ repo_path.join('cookbooks/sample/metadata.rb').should be_exist
94
+ end
95
+
96
+ it "should resolve and separately install" do
97
+ repo_path = tmp_path.join('repo/resolve-install')
98
+ repo_path.rmtree if repo_path.exist?
99
+ repo_path.mkpath
100
+ repo_path.join('cookbooks').mkpath
101
+ cheffile = Helpers.strip_heredoc(<<-CHEFFILE)
102
+ #!/usr/bin/env ruby
103
+ cookbook "sample", :site => "#{api_url}"
104
+ CHEFFILE
105
+ repo_path.join('Cheffile').open('wb') { |f| f.write(cheffile) }
106
+ Chef.stub!(:project_path) { repo_path }
107
+
108
+ Chef.resolve!
109
+ repo_path.join('tmp').rmtree if repo_path.join('tmp').exist?
110
+ Chef.install!
111
+ repo_path.join('cookbooks/sample').should be_exist
112
+ repo_path.join('cookbooks/sample/metadata.rb').should be_exist
113
+ end
114
+
115
+ end
116
+
117
+ end
118
+ end
119
+ end
120
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: librarian
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-06-20 00:00:00.000000000Z
12
+ date: 2011-06-23 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &12204460 !ruby/object:Gem::Requirement
16
+ requirement: &11791400 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *12204460
24
+ version_requirements: *11791400
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &12203620 !ruby/object:Gem::Requirement
27
+ requirement: &11789160 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *12203620
35
+ version_requirements: *11789160
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: cucumber
38
- requirement: &12199460 !ruby/object:Gem::Requirement
38
+ requirement: &11462680 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *12199460
46
+ version_requirements: *11462680
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: aruba
49
- requirement: &12198500 !ruby/object:Gem::Requirement
49
+ requirement: &11460640 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,21 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *12198500
57
+ version_requirements: *11460640
58
+ - !ruby/object:Gem::Dependency
59
+ name: webmock
60
+ requirement: &11459060 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *11459060
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: chef
60
- requirement: &12197740 !ruby/object:Gem::Requirement
71
+ requirement: &11456440 !ruby/object:Gem::Requirement
61
72
  none: false
62
73
  requirements:
63
74
  - - ! '>='
@@ -65,7 +76,7 @@ dependencies:
65
76
  version: '0.10'
66
77
  type: :development
67
78
  prerelease: false
68
- version_requirements: *12197740
79
+ version_requirements: *11456440
69
80
  description: Librarian
70
81
  email:
71
82
  - y_feldblum@yahoo.com
@@ -134,6 +145,7 @@ files:
134
145
  - lib/librarian/version.rb
135
146
  - librarian.gemspec
136
147
  - spec/chef/git_source_spec.rb
148
+ - spec/chef/site_source_spec.rb
137
149
  - spec/dsl_spec.rb
138
150
  - spec/lockfile_spec.rb
139
151
  - spec/meta/requires_spec.rb
@@ -153,7 +165,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
153
165
  version: '0'
154
166
  segments:
155
167
  - 0
156
- hash: 92490891024378775
168
+ hash: 695538775137796306
157
169
  required_rubygems_version: !ruby/object:Gem::Requirement
158
170
  none: false
159
171
  requirements:
@@ -162,7 +174,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
174
  version: '0'
163
175
  segments:
164
176
  - 0
165
- hash: 92490891024378775
177
+ hash: 695538775137796306
166
178
  requirements: []
167
179
  rubyforge_project: librarian
168
180
  rubygems_version: 1.7.1