librarian 0.0.22 → 0.0.23

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.0.23
4
+
5
+ * \#41. Build gems with a built gemspec.
6
+
7
+ * \#67. Cache remote objects at the latest possible moments, and only when they
8
+ are needed.
9
+
10
+ * \#68. Fix unpacking chef site-sourced packages on Windows by pivoting from a
11
+ Librarian-managed scratch space, rather than pivoting from Windows' temp
12
+ directory. There were unexplained problems with using the Windows temp
13
+ directory in certain cases, possibly related to the temp directory and the
14
+ Librarian cache directory being on different volumes.
15
+
16
+ * \#69. Fix invoking Librarian with git-sourced dependencies from git hooks by
17
+ unsetting `GIT_DIR` around shelling out to git.
18
+
19
+ * Print general environment information when running with `--verbose`.
20
+
3
21
  ## 0.0.22
4
22
 
5
23
  * Fix the `outdated` CLI command.
data/Rakefile CHANGED
@@ -1,4 +1,25 @@
1
1
  require 'bundler'
2
+
3
+ module Bundler
4
+ class GemHelper
5
+
6
+ def build_gem_with_built_spec
7
+ spec = Gem::Specification.load(spec_path)
8
+ spec_ruby = spec.to_ruby
9
+ original_spec_path = spec_path + ".original"
10
+ FileUtils.mv(spec_path, original_spec_path)
11
+ File.open(spec_path, "wb"){|f| f.write(spec_ruby)}
12
+ build_gem_without_built_spec
13
+ ensure
14
+ FileUtils.mv(original_spec_path, spec_path)
15
+ end
16
+
17
+ alias build_gem_without_built_spec build_gem
18
+ alias build_gem build_gem_with_built_spec
19
+
20
+ end
21
+ end
22
+
2
23
  Bundler::GemHelper.install_tasks
3
24
 
4
25
  begin
@@ -35,17 +35,10 @@ module Librarian
35
35
  def perform_installation
36
36
  manifests = sorted_manifests
37
37
 
38
- cache_manifests(manifests)
39
38
  create_install_path
40
39
  install_manifests(manifests)
41
40
  end
42
41
 
43
- def cache_manifests(manifests)
44
- manifests.each do |manifest|
45
- manifest.source.cache!([manifest.name])
46
- end
47
- end
48
-
49
42
  def create_install_path
50
43
  install_path.rmtree if install_path.exist?
51
44
  install_path.mkpath
@@ -5,7 +5,7 @@ require 'net/http'
5
5
  require 'json'
6
6
  require 'digest'
7
7
  require 'zlib'
8
- require 'tmpdir'
8
+ require 'securerandom'
9
9
  require 'archive/tar/minitar'
10
10
 
11
11
  require 'librarian/helpers/debug'
@@ -233,12 +233,8 @@ module Librarian
233
233
 
234
234
  package_path = version_uri_package_cache_path(version_uri)
235
235
  unpacked_path = version_uri_unpacked_cache_path(version_uri)
236
- temp_path = Pathname(Dir.tmpdir)
237
236
 
238
- Zlib::GzipReader.open(package_path) do |input|
239
- Archive::Tar::Minitar.unpack(input, temp_path.to_s)
240
- end
241
- FileUtils.move(temp_path.join(name), unpacked_path)
237
+ unpack_package! unpacked_path, package_path
242
238
  end
243
239
 
244
240
  def cache_remote_json!(path, uri)
@@ -282,6 +278,28 @@ module Librarian
282
278
  path.open("wb"){|f| f.write(bytes)}
283
279
  end
284
280
 
281
+ def unpack_package!(path, source)
282
+ path = Pathname(path)
283
+ source = Pathname(source)
284
+
285
+ temp = environment.scratch_path.join(SecureRandom.hex(16))
286
+ temp.mkpath
287
+
288
+ debug { "Unpacking #{relative_path_to(source)} to #{relative_path_to(temp)}" }
289
+ Zlib::GzipReader.open(source) do |input|
290
+ Archive::Tar::Minitar.unpack(input, temp.to_s)
291
+ end
292
+
293
+ # Cookbook files, as pulled from Opscode Community Site API, are
294
+ # embedded in a subdirectory of the tarball, and the subdirectory's
295
+ # name is equal to the name of the cookbook.
296
+ subtemp = temp.join(name)
297
+ debug { "Moving #{relative_path_to(subtemp)} to #{relative_path_to(path)}" }
298
+ FileUtils.mv(subtemp, path)
299
+ ensure
300
+ temp.rmtree if temp && temp.exist?
301
+ end
302
+
285
303
  def parse_local_json(path)
286
304
  JSON.parse(path.read)
287
305
  end
@@ -358,9 +376,6 @@ module Librarian
358
376
  def unpin!
359
377
  end
360
378
 
361
- def cache!(names)
362
- end
363
-
364
379
  def install!(manifest)
365
380
  manifest.source == self or raise ArgumentError
366
381
 
data/lib/librarian/cli.rb CHANGED
@@ -6,6 +6,8 @@ require 'librarian/error'
6
6
  require 'librarian/action'
7
7
  require "librarian/ui"
8
8
 
9
+ require "librarian/helpers/debug"
10
+
9
11
  module Librarian
10
12
  class Cli < Thor
11
13
 
@@ -22,6 +24,8 @@ module Librarian
22
24
  include Particularity
23
25
  extend Particularity
24
26
 
27
+ include Helpers::Debug
28
+
25
29
  class << self
26
30
  def bin!
27
31
  begin
@@ -44,6 +48,8 @@ module Librarian
44
48
  environment.ui = UI::Shell.new(the_shell)
45
49
  environment.ui.debug! if options["verbose"]
46
50
  environment.ui.debug_line_numbers! if options["verbose"] && options["line-numbers"]
51
+
52
+ write_debug_header
47
53
  end
48
54
 
49
55
  desc "version", "Displays the version."
@@ -91,7 +97,6 @@ module Librarian
91
97
  resolution = environment.lock
92
98
  resolution.manifests.sort_by(&:name).each do |manifest|
93
99
  source = manifest.source
94
- source.cache!([manifest.name])
95
100
  source_manifest = source.manifests(manifest.name).first
96
101
  next if manifest.version == source_manifest.version
97
102
  say "#{manifest.name} (#{manifest.version} -> #{source_manifest.version})"
@@ -142,5 +147,29 @@ module Librarian
142
147
  ManifestPresenter.new(self, environment.lock.manifests)
143
148
  end
144
149
 
150
+ def write_debug_header
151
+ debug { "Ruby Version: #{RUBY_VERSION}" }
152
+ debug { "Ruby Platform: #{RUBY_PLATFORM}" }
153
+ debug { "Rubinius Version: #{Rubinius::VERSION}" } if defined?(Rubinius)
154
+ debug { "JRuby Version: #{JRUBY_VERSION}" } if defined?(JRUBY_VERSION)
155
+ debug { "Rubygems Version: #{Gem::VERSION}" }
156
+ debug { "Librarian Version: #{VERSION}" }
157
+ debug { "Librarian Adapter: #{environment.adapter_name}"}
158
+ debug { "Project: #{environment.project_path}" }
159
+ debug { "Specfile: #{relative_path_to(environment.specfile_path)}" }
160
+ debug { "Lockfile: #{relative_path_to(environment.lockfile_path)}" }
161
+ debug { "Git: #{Source::Git::Repository.bin}" }
162
+ debug { "Git Version: #{Source::Git::Repository.new(environment, environment.project_path).version(:silent => true)}" }
163
+ debug { "Git Environment Variables:" }
164
+ git_env = ENV.to_a.select{|(k, v)| k =~ /\AGIT/}.sort_by{|(k, v)| k}
165
+ if git_env.empty?
166
+ debug { " (empty)" }
167
+ else
168
+ git_env.each do |(k, v)|
169
+ debug { " #{k}=#{v}"}
170
+ end
171
+ end
172
+ end
173
+
145
174
  end
146
175
  end
@@ -28,16 +28,18 @@ module Librarian
28
28
  to_gem_requirement.to_s
29
29
  end
30
30
 
31
+ protected
32
+
33
+ attr_accessor :backing
34
+
31
35
  private
32
36
 
33
37
  def initialize_normalize_args(args)
34
38
  args.map do |arg|
35
- arg = [arg] if self.class === arg
39
+ arg = arg.backing if self.class === arg
36
40
  arg
37
41
  end
38
42
  end
39
-
40
- attr_accessor :backing
41
43
  end
42
44
 
43
45
  include Helpers::Debug
@@ -60,7 +62,6 @@ module Librarian
60
62
  end
61
63
 
62
64
  def cache_manifests!
63
- source.cache!([name])
64
65
  source.manifests(name)
65
66
  end
66
67
 
@@ -95,6 +95,10 @@ module Librarian
95
95
  project_path.join("tmp/librarian/cache")
96
96
  end
97
97
 
98
+ def scratch_path
99
+ project_path.join("tmp/librarian/scratch")
100
+ end
101
+
98
102
  def project_relative_path_to(path)
99
103
  Pathname.new(path).relative_path_from(project_path)
100
104
  end
@@ -28,7 +28,7 @@ module Librarian
28
28
  string = string.dup
29
29
  source_type_names_map = Hash[dsl_class.source_types.map{|t| [t[1].lock_name, t[1]]}]
30
30
  source_type_names = dsl_class.source_types.map{|t| t[1].lock_name}
31
- lines = string.split(/(\r?\n)+/).reject{|l| l =~ /^\s*$/}
31
+ lines = string.split(/(\r|\n|\r\n)+/).select{|l| l =~ /\S/}
32
32
  sources = []
33
33
  while source_type_names.include?(lines.first)
34
34
  source = {}
@@ -60,7 +60,7 @@ module Librarian
60
60
  dependencies = []
61
61
  while lines.first =~ /^ {2}([\w-]+)(?: \((.*)\))?$/
62
62
  lines.shift
63
- name, requirement = $1, $2
63
+ name, requirement = $1, $2.split(/,\s*/)
64
64
  dependencies << Dependency.new(name, requirement, manifests_index[name].source)
65
65
  end
66
66
  Resolution.new(dependencies, manifests)
@@ -113,10 +113,14 @@ module Librarian
113
113
 
114
114
  def consistent?
115
115
  index.values.all? do |manifest|
116
- manifest.dependencies.all? do |dependency|
117
- match = index[dependency.name]
118
- match && match.satisfies?(dependency)
119
- end
116
+ in_compliance_with?(manifest.dependencies)
117
+ end
118
+ end
119
+
120
+ def in_compliance_with?(dependencies)
121
+ dependencies.all? do |dependency|
122
+ manifest = index[dependency.name]
123
+ manifest && manifest.satisfies?(dependency)
120
124
  end
121
125
  end
122
126
 
@@ -74,9 +74,6 @@ module Librarian
74
74
  end
75
75
  end
76
76
 
77
- def cache!(names)
78
- end
79
-
80
77
  def install!(manifest)
81
78
  end
82
79
 
@@ -33,10 +33,7 @@ module Librarian
33
33
  end
34
34
 
35
35
  def manifests_consistent_with_dependencies?
36
- dependencies.all? do |dependency|
37
- manifest = manifests_index[dependency.name]
38
- dependency.satisfied_by?(manifest)
39
- end
36
+ ManifestSet.new(manifests).in_compliance_with?(dependencies)
40
37
  end
41
38
 
42
39
  def manifests_internally_consistent?
@@ -39,14 +39,17 @@ module Librarian
39
39
 
40
40
  attr_accessor :environment
41
41
  private :environment=
42
- attr_reader :uri, :ref, :sha, :path
42
+
43
+ attr_accessor :uri, :ref, :sha, :path
44
+ private :uri=, :ref=, :sha=, :path=
43
45
 
44
46
  def initialize(environment, uri, options)
45
47
  self.environment = environment
46
- @uri = uri
47
- @ref = options[:ref] || DEFAULTS[:ref]
48
- @sha = options[:sha]
49
- @path = options[:path]
48
+ self.uri = uri
49
+ self.ref = options[:ref] || DEFAULTS[:ref]
50
+ self.sha = options[:sha]
51
+ self.path = options[:path]
52
+
50
53
  @repository = nil
51
54
  @repository_cache_path = nil
52
55
  end
@@ -85,30 +88,40 @@ module Librarian
85
88
  @sha = nil
86
89
  end
87
90
 
88
- def cache!(names)
91
+ def cache!
92
+ repository_cached? and return or repository_cached!
93
+
89
94
  unless repository.git?
90
95
  repository.path.rmtree if repository.path.exist?
91
96
  repository.path.mkpath
92
97
  repository.clone!(uri)
93
98
  end
94
99
  repository.reset_hard!
95
- unless sha == repository.current_commit_hash
100
+ repository.clean!
101
+ unless repository.checked_out?(sha)
96
102
  remote = repository.default_remote
97
103
  repository.fetch!(remote)
98
104
  repository.fetch!(remote, :tags => true)
99
105
 
100
- new_sha = repository.hash_from(remote, sha || ref)
101
- repository.checkout!(new_sha)
106
+ self.sha = repository.hash_from(remote, ref) unless sha
107
+ repository.checkout!(sha) unless repository.checked_out?(sha)
102
108
 
103
- @sha ||= new_sha
109
+ raise Error, "failed to checkout #{sha}" unless repository.checked_out?(sha)
104
110
  end
105
111
  end
106
112
 
113
+ private
114
+
115
+ attr_accessor :repository_cached
116
+ alias repository_cached? repository_cached
117
+
118
+ def repository_cached!
119
+ self.repository_cached = true
120
+ end
121
+
107
122
  def repository_cache_path
108
123
  @repository_cache_path ||= begin
109
- dir = path ? "#{uri}/#{path}" : uri
110
- dir = Digest::MD5.hexdigest(dir)
111
- environment.cache_path.join("source/git/#{dir}")
124
+ environment.cache_path.join("source/git/#{cache_key}")
112
125
  end
113
126
  end
114
127
 
@@ -122,6 +135,16 @@ module Librarian
122
135
  @filesystem_path ||= path ? repository.path.join(path) : repository.path
123
136
  end
124
137
 
138
+ def cache_key
139
+ @cache_key ||= begin
140
+ uri_part = uri
141
+ path_part = "/#{path}" if path
142
+ ref_part = "##{ref}"
143
+ key_source = [uri_part, path_part, ref_part].join
144
+ Digest::MD5.hexdigest(key_source)
145
+ end
146
+ end
147
+
125
148
  end
126
149
  end
127
150
  end
@@ -59,6 +59,17 @@ module Librarian
59
59
  "origin"
60
60
  end
61
61
 
62
+ def version(options = { })
63
+ version!(options).strip
64
+ end
65
+
66
+ def version!(options = { })
67
+ silent = options.delete(:silent)
68
+
69
+ command = %w(--version)
70
+ run!(command, :silent => silent)
71
+ end
72
+
62
73
  def clone!(repository_url)
63
74
  command = %W(clone #{repository_url} . --quiet)
64
75
  run!(command, :chdir => true)
@@ -81,6 +92,15 @@ module Librarian
81
92
  run!(command, :chdir => true)
82
93
  end
83
94
 
95
+ def clean!
96
+ command = %w(clean -x -d --force --force)
97
+ run!(command, :chdir => true)
98
+ end
99
+
100
+ def checked_out?(sha)
101
+ current_commit_hash == sha
102
+ end
103
+
84
104
  def remote_names
85
105
  command = %W(remote)
86
106
  run!(command, :chdir => true).strip.lines.map(&:strip)
@@ -126,28 +146,67 @@ module Librarian
126
146
  chdir = options.delete(:chdir)
127
147
  chdir = path.to_s if chdir == true
128
148
 
149
+ silent = options.delete(:silent)
150
+
129
151
  command = [bin]
130
152
  command.concat(args)
131
153
 
132
154
  maybe_within(chdir) do
133
- debug { "Running `#{command.join(' ')}` in #{relative_path_to(Dir.pwd)}" }
134
- out = Open3.popen3(*command) do |i, o, e, t|
135
- raise StandardError, e.read unless (t ? t.value : $?).success?
136
- o.read
155
+ logging_command(command, :silent => silent) do
156
+ run_command_internal(command)
137
157
  end
138
- debug { " -> #{out}" } if out.size > 0
139
- out
140
158
  end
141
159
  end
142
160
 
143
161
  def maybe_within(path)
144
162
  if path
145
- Dir.chdir(path) { yield }
163
+ Dir.chdir(path) { with_env_var("GIT_DIR", nil) { yield } }
146
164
  else
147
165
  yield
148
166
  end
149
167
  end
150
168
 
169
+ def with_env_var(name, value)
170
+ original_value = ENV[name]
171
+ begin
172
+ ENV[name] = value
173
+ yield
174
+ ensure
175
+ ENV[name] = original_value
176
+ end
177
+ end
178
+
179
+ def logging_command(command, options)
180
+ silent = options.delete(:silent)
181
+
182
+ pwd = Dir.pwd
183
+
184
+ unless silent
185
+ debug { "Running `#{command.join(' ')}` in #{relative_path_to(pwd)}" }
186
+ end
187
+
188
+ out = yield
189
+
190
+ unless silent
191
+ if out.size > 0
192
+ out.lines.each do |line|
193
+ debug { " --> #{line}" }
194
+ end
195
+ else
196
+ debug { " --- No output" }
197
+ end
198
+ end
199
+
200
+ out
201
+ end
202
+
203
+ def run_command_internal(command)
204
+ Open3.popen3(*command) do |i, o, e, t|
205
+ raise StandardError, e.read unless (t ? t.value : $?).success?
206
+ o.read
207
+ end
208
+ end
209
+
151
210
  end
152
211
  end
153
212
  end
@@ -11,7 +11,7 @@ module Librarian
11
11
  include Helpers::Debug
12
12
  include Support::AbstractMethod
13
13
 
14
- abstract_method :path
14
+ abstract_method :path, :fetch_version, :fetch_dependencies
15
15
 
16
16
  def manifests(name)
17
17
  manifest = Manifest.new(self, name)
@@ -26,8 +26,12 @@ module Librarian
26
26
  end
27
27
 
28
28
  def manifest_search_paths(name)
29
- paths = [filesystem_path, filesystem_path.join(name)]
30
- paths.select{|s| s.exist?}
29
+ @manifest_search_paths ||= { }
30
+ @manifest_search_paths[name] ||= begin
31
+ cache!
32
+ paths = [filesystem_path, filesystem_path.join(name)]
33
+ paths.select{|s| s.exist?}
34
+ end
31
35
  end
32
36
 
33
37
  def found_path(name)
@@ -62,7 +62,7 @@ module Librarian
62
62
  def unpin!
63
63
  end
64
64
 
65
- def cache!(names)
65
+ def cache!
66
66
  end
67
67
 
68
68
  def filesystem_path
@@ -1,3 +1,3 @@
1
1
  module Librarian
2
- VERSION = "0.0.22"
2
+ VERSION = "0.0.23"
3
3
  end
data/librarian.gemspec CHANGED
@@ -1,33 +1,55 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "librarian/version"
4
2
 
5
3
  Gem::Specification.new do |s|
6
- s.name = "librarian"
7
- s.version = Librarian::VERSION
8
- s.platform = Gem::Platform::RUBY
9
- s.authors = ["Jay Feldblum"]
10
- s.email = ["y_feldblum@yahoo.com"]
11
- s.homepage = ""
12
- s.summary = %q{Librarian}
13
- s.description = %q{Librarian}
4
+ s.name = "librarian"
5
+ s.version = "0.0.23"
14
6
 
15
- s.rubyforge_project = "librarian"
16
-
17
- s.files = `git ls-files`.split("\n")
18
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Jay Feldblum"]
9
+ s.date = "2012-05-14"
10
+ s.description = "Librarian"
11
+ s.email = ["y_feldblum@yahoo.com"]
12
+ s.executables = ["librarian-chef", "librarian-mock"]
13
+ s.files = [".gitignore", ".rspec", ".travis.yml", "CHANGELOG.md", "Gemfile", "MIT-LICENSE", "README.md", "Rakefile", "bin/librarian-chef", "bin/librarian-mock", "config/cucumber.yaml", "features/chef/cli/init.feature", "features/chef/cli/install.feature", "features/chef/cli/show.feature", "features/chef/cli/version.feature", "features/support/env.rb", "lib/librarian.rb", "lib/librarian/action.rb", "lib/librarian/action/base.rb", "lib/librarian/action/clean.rb", "lib/librarian/action/ensure.rb", "lib/librarian/action/install.rb", "lib/librarian/action/resolve.rb", "lib/librarian/action/update.rb", "lib/librarian/chef.rb", "lib/librarian/chef/cli.rb", "lib/librarian/chef/dsl.rb", "lib/librarian/chef/environment.rb", "lib/librarian/chef/extension.rb", "lib/librarian/chef/integration/knife.rb", "lib/librarian/chef/manifest_reader.rb", "lib/librarian/chef/source.rb", "lib/librarian/chef/source/git.rb", "lib/librarian/chef/source/local.rb", "lib/librarian/chef/source/path.rb", "lib/librarian/chef/source/site.rb", "lib/librarian/chef/templates/Cheffile", "lib/librarian/cli.rb", "lib/librarian/cli/manifest_presenter.rb", "lib/librarian/dependency.rb", "lib/librarian/dsl.rb", "lib/librarian/dsl/receiver.rb", "lib/librarian/dsl/target.rb", "lib/librarian/environment.rb", "lib/librarian/error.rb", "lib/librarian/helpers.rb", "lib/librarian/helpers/debug.rb", "lib/librarian/lockfile.rb", "lib/librarian/lockfile/compiler.rb", "lib/librarian/lockfile/parser.rb", "lib/librarian/manifest.rb", "lib/librarian/manifest_set.rb", "lib/librarian/mock.rb", "lib/librarian/mock/cli.rb", "lib/librarian/mock/dsl.rb", "lib/librarian/mock/environment.rb", "lib/librarian/mock/extension.rb", "lib/librarian/mock/source.rb", "lib/librarian/mock/source/mock.rb", "lib/librarian/mock/source/mock/registry.rb", "lib/librarian/resolution.rb", "lib/librarian/resolver.rb", "lib/librarian/resolver/implementation.rb", "lib/librarian/source.rb", "lib/librarian/source/git.rb", "lib/librarian/source/git/repository.rb", "lib/librarian/source/local.rb", "lib/librarian/source/path.rb", "lib/librarian/spec.rb", "lib/librarian/spec_change_set.rb", "lib/librarian/specfile.rb", "lib/librarian/support/abstract_method.rb", "lib/librarian/ui.rb", "lib/librarian/version.rb", "librarian.gemspec", "spec/functional/chef/source/git_spec.rb", "spec/functional/chef/source/site_spec.rb", "spec/unit/action/base_spec.rb", "spec/unit/action/clean_spec.rb", "spec/unit/action/ensure_spec.rb", "spec/unit/action/install_spec.rb", "spec/unit/dependency_spec.rb", "spec/unit/dsl_spec.rb", "spec/unit/environment_spec.rb", "spec/unit/lockfile/parser_spec.rb", "spec/unit/lockfile_spec.rb", "spec/unit/manifest_set_spec.rb", "spec/unit/manifest_spec.rb", "spec/unit/mock/source/mock_spec.rb", "spec/unit/resolver_spec.rb", "spec/unit/source/git_spec.rb", "spec/unit/spec_change_set_spec.rb"]
14
+ s.homepage = ""
20
15
  s.require_paths = ["lib"]
16
+ s.rubyforge_project = "librarian"
17
+ s.rubygems_version = "1.8.17"
18
+ s.summary = "Librarian"
21
19
 
22
- s.add_dependency "thor", "~> 0.15"
23
-
24
- s.add_development_dependency "rake"
25
- s.add_development_dependency "rspec"
26
- s.add_development_dependency "cucumber"
27
- s.add_development_dependency "aruba"
28
- s.add_development_dependency "webmock"
20
+ if s.respond_to? :specification_version then
21
+ s.specification_version = 3
29
22
 
30
- s.add_dependency "chef", ">= 0.10"
31
- s.add_dependency "highline"
32
- s.add_dependency "archive-tar-minitar", ">= 0.5.2"
23
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
24
+ s.add_runtime_dependency(%q<thor>, ["~> 0.15"])
25
+ s.add_development_dependency(%q<rake>, [">= 0"])
26
+ s.add_development_dependency(%q<rspec>, [">= 0"])
27
+ s.add_development_dependency(%q<cucumber>, [">= 0"])
28
+ s.add_development_dependency(%q<aruba>, [">= 0"])
29
+ s.add_development_dependency(%q<webmock>, [">= 0"])
30
+ s.add_runtime_dependency(%q<chef>, [">= 0.10"])
31
+ s.add_runtime_dependency(%q<highline>, [">= 0"])
32
+ s.add_runtime_dependency(%q<archive-tar-minitar>, [">= 0.5.2"])
33
+ else
34
+ s.add_dependency(%q<thor>, ["~> 0.15"])
35
+ s.add_dependency(%q<rake>, [">= 0"])
36
+ s.add_dependency(%q<rspec>, [">= 0"])
37
+ s.add_dependency(%q<cucumber>, [">= 0"])
38
+ s.add_dependency(%q<aruba>, [">= 0"])
39
+ s.add_dependency(%q<webmock>, [">= 0"])
40
+ s.add_dependency(%q<chef>, [">= 0.10"])
41
+ s.add_dependency(%q<highline>, [">= 0"])
42
+ s.add_dependency(%q<archive-tar-minitar>, [">= 0.5.2"])
43
+ end
44
+ else
45
+ s.add_dependency(%q<thor>, ["~> 0.15"])
46
+ s.add_dependency(%q<rake>, [">= 0"])
47
+ s.add_dependency(%q<rspec>, [">= 0"])
48
+ s.add_dependency(%q<cucumber>, [">= 0"])
49
+ s.add_dependency(%q<aruba>, [">= 0"])
50
+ s.add_dependency(%q<webmock>, [">= 0"])
51
+ s.add_dependency(%q<chef>, [">= 0.10"])
52
+ s.add_dependency(%q<highline>, [">= 0"])
53
+ s.add_dependency(%q<archive-tar-minitar>, [">= 0.5.2"])
54
+ end
33
55
  end
@@ -81,15 +81,9 @@ module Librarian
81
81
  action.run
82
82
  end
83
83
 
84
- it "should sort, cache, and install the manifests" do
84
+ it "should sort and install the manifests" do
85
85
  ManifestSet.should_receive(:sort).with(manifests).exactly(:once).ordered { sorted_manifests }
86
86
 
87
- sorted_manifests.each do |manifest|
88
- source = mock
89
- manifest.stub(:source) { source }
90
- source.should_receive(:cache!).with([manifest.name]).exactly(:once).ordered
91
- end
92
-
93
87
  install_path.stub(:exist?) { false }
94
88
  install_path.should_receive(:mkpath).exactly(:once).ordered
95
89
 
@@ -100,7 +94,6 @@ module Librarian
100
94
 
101
95
  it "should recreate the install path if it already exists" do
102
96
  action.stub(:sorted_manifests) { sorted_manifests }
103
- action.stub(:cache_manifests)
104
97
  action.stub(:install_manifests)
105
98
 
106
99
  install_path.stub(:exist?) { true }
@@ -0,0 +1,162 @@
1
+ require "librarian/helpers"
2
+ require "librarian/lockfile/parser"
3
+ require "librarian/mock"
4
+
5
+ module Librarian
6
+ describe Lockfile::Parser do
7
+
8
+ let(:env) { Mock::Environment.new }
9
+ let(:parser) { described_class.new(env) }
10
+ let(:resolution) { parser.parse(lockfile) }
11
+
12
+ context "a mock lockfile with one source and no dependencies" do
13
+ let(:lockfile) do
14
+ Helpers.strip_heredoc <<-LOCKFILE
15
+ MOCK
16
+ remote: source-a
17
+ specs:
18
+
19
+ DEPENDENCIES
20
+
21
+ LOCKFILE
22
+ end
23
+
24
+ it "should give an empty list of dependencies" do
25
+ resolution.dependencies.should be_empty
26
+ end
27
+
28
+ it "should give an empty list of manifests" do
29
+ resolution.manifests.should be_empty
30
+ end
31
+ end
32
+
33
+ context "a mock lockfile with one source and one dependency" do
34
+ let(:lockfile) do
35
+ Helpers.strip_heredoc <<-LOCKFILE
36
+ MOCK
37
+ remote: source-a
38
+ specs:
39
+ jelly (1.3.5)
40
+
41
+ DEPENDENCIES
42
+ jelly (!= 1.2.6, ~> 1.1)
43
+
44
+ LOCKFILE
45
+ end
46
+
47
+ it "should give a list of one dependency" do
48
+ resolution.should have(1).dependencies
49
+ end
50
+
51
+ it "should give a dependency with the expected name" do
52
+ dependency = resolution.dependencies.first
53
+
54
+ dependency.name.should == "jelly"
55
+ end
56
+
57
+ it "should give a dependency with the expected requirement" do
58
+ dependency = resolution.dependencies.first
59
+
60
+ # Note: it must be this order because this order is lexicographically sorted.
61
+ dependency.requirement.to_s.should == "!= 1.2.6, ~> 1.1"
62
+ end
63
+
64
+ it "should give a dependency wth the expected source" do
65
+ dependency = resolution.dependencies.first
66
+ source = dependency.source
67
+
68
+ source.name.should == "source-a"
69
+ end
70
+
71
+ it "should give a list of one manifest" do
72
+ resolution.should have(1).manifests
73
+ end
74
+
75
+ it "should give a manifest with the expected name" do
76
+ manifest = resolution.manifests.first
77
+
78
+ manifest.name.should == "jelly"
79
+ end
80
+
81
+ it "should give a manifest with the expected version" do
82
+ manifest = resolution.manifests.first
83
+
84
+ manifest.version.to_s.should == "1.3.5"
85
+ end
86
+
87
+ it "should give a manifest with no dependencies" do
88
+ manifest = resolution.manifests.first
89
+
90
+ manifest.dependencies.should be_empty
91
+ end
92
+
93
+ it "should give a manifest with the expected source" do
94
+ manifest = resolution.manifests.first
95
+ source = manifest.source
96
+
97
+ source.name.should == "source-a"
98
+ end
99
+
100
+ it "should give the dependency and the manifest the same source instance" do
101
+ dependency = resolution.dependencies.first
102
+ manifest = resolution.manifests.first
103
+
104
+ dependency_source = dependency.source
105
+ manifest_source = manifest.source
106
+
107
+ manifest_source.should be dependency_source
108
+ end
109
+ end
110
+
111
+ context "a mock lockfile with one source and a complex dependency" do
112
+ let(:lockfile) do
113
+ Helpers.strip_heredoc <<-LOCKFILE
114
+ MOCK
115
+ remote: source-a
116
+ specs:
117
+ butter (2.5.3)
118
+ jelly (1.3.5)
119
+ butter (< 3, >= 1.1)
120
+
121
+ DEPENDENCIES
122
+ jelly (!= 1.2.6, ~> 1.1)
123
+
124
+ LOCKFILE
125
+ end
126
+
127
+ it "should give a list of one dependency" do
128
+ resolution.should have(1).dependencies
129
+ end
130
+
131
+ it "should have the expected dependency" do
132
+ dependency = resolution.dependencies.first
133
+
134
+ dependency.name.should == "jelly"
135
+ end
136
+
137
+ it "should give a list of all the manifests" do
138
+ resolution.should have(2).manifests
139
+ end
140
+
141
+ it "should include all the expected manifests" do
142
+ manifests = ManifestSet.new(resolution.manifests)
143
+
144
+ manifests.to_hash.keys.should =~ %w(butter jelly)
145
+ end
146
+
147
+ it "should have an internally consistent set of manifests" do
148
+ manifests = ManifestSet.new(resolution.manifests)
149
+
150
+ manifests.should be_consistent
151
+ end
152
+
153
+ it "should have an externally consistent set of manifests" do
154
+ dependencies = resolution.dependencies
155
+ manifests = ManifestSet.new(resolution.manifests)
156
+
157
+ manifests.should be_in_compliance_with dependencies
158
+ end
159
+ end
160
+
161
+ end
162
+ end
File without changes
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.22
4
+ version: 0.0.23
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: 2012-05-11 00:00:00.000000000 Z
12
+ date: 2012-05-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &15422220 !ruby/object:Gem::Requirement
16
+ requirement: &9010000 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0.15'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *15422220
24
+ version_requirements: *9010000
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &15421620 !ruby/object:Gem::Requirement
27
+ requirement: &9008640 !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: *15421620
35
+ version_requirements: *9008640
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &15420780 !ruby/object:Gem::Requirement
38
+ requirement: &9006600 !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: *15420780
46
+ version_requirements: *9006600
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: cucumber
49
- requirement: &15419740 !ruby/object:Gem::Requirement
49
+ requirement: &9004980 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *15419740
57
+ version_requirements: *9004980
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: aruba
60
- requirement: &15419140 !ruby/object:Gem::Requirement
60
+ requirement: &9003760 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *15419140
68
+ version_requirements: *9003760
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: webmock
71
- requirement: &15418540 !ruby/object:Gem::Requirement
71
+ requirement: &8997140 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *15418540
79
+ version_requirements: *8997140
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: chef
82
- requirement: &15417660 !ruby/object:Gem::Requirement
82
+ requirement: &8956960 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0.10'
88
88
  type: :runtime
89
89
  prerelease: false
90
- version_requirements: *15417660
90
+ version_requirements: *8956960
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: highline
93
- requirement: &15416820 !ruby/object:Gem::Requirement
93
+ requirement: &8951000 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :runtime
100
100
  prerelease: false
101
- version_requirements: *15416820
101
+ version_requirements: *8951000
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: archive-tar-minitar
104
- requirement: &15416020 !ruby/object:Gem::Requirement
104
+ requirement: &8947440 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ! '>='
@@ -109,7 +109,7 @@ dependencies:
109
109
  version: 0.5.2
110
110
  type: :runtime
111
111
  prerelease: false
112
- version_requirements: *15416020
112
+ version_requirements: *8947440
113
113
  description: Librarian
114
114
  email:
115
115
  - y_feldblum@yahoo.com
@@ -203,10 +203,11 @@ files:
203
203
  - spec/unit/dependency_spec.rb
204
204
  - spec/unit/dsl_spec.rb
205
205
  - spec/unit/environment_spec.rb
206
+ - spec/unit/lockfile/parser_spec.rb
206
207
  - spec/unit/lockfile_spec.rb
207
208
  - spec/unit/manifest_set_spec.rb
208
209
  - spec/unit/manifest_spec.rb
209
- - spec/unit/mock/source/mock.rb
210
+ - spec/unit/mock/source/mock_spec.rb
210
211
  - spec/unit/resolver_spec.rb
211
212
  - spec/unit/source/git_spec.rb
212
213
  - spec/unit/spec_change_set_spec.rb
@@ -222,18 +223,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
222
223
  - - ! '>='
223
224
  - !ruby/object:Gem::Version
224
225
  version: '0'
225
- segments:
226
- - 0
227
- hash: -1509747376632430187
228
226
  required_rubygems_version: !ruby/object:Gem::Requirement
229
227
  none: false
230
228
  requirements:
231
229
  - - ! '>='
232
230
  - !ruby/object:Gem::Version
233
231
  version: '0'
234
- segments:
235
- - 0
236
- hash: -1509747376632430187
237
232
  requirements: []
238
233
  rubyforge_project: librarian
239
234
  rubygems_version: 1.8.17
@@ -241,3 +236,4 @@ signing_key:
241
236
  specification_version: 3
242
237
  summary: Librarian
243
238
  test_files: []
239
+ has_rdoc: