librarian 0.0.1 → 0.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/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