librarian 0.1.1 → 0.1.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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/CHANGELOG.md +15 -0
  4. data/Gemfile +2 -0
  5. data/VERSION +1 -0
  6. data/lib/librarian/algorithms.rb +133 -0
  7. data/lib/librarian/cli/manifest_presenter.rb +1 -5
  8. data/lib/librarian/dependency.rb +7 -1
  9. data/lib/librarian/environment.rb +20 -2
  10. data/lib/librarian/environment/runtime_cache.rb +101 -0
  11. data/lib/librarian/manifest.rb +7 -1
  12. data/lib/librarian/manifest_set.rb +11 -12
  13. data/lib/librarian/posix.rb +14 -5
  14. data/lib/librarian/resolver.rb +22 -9
  15. data/lib/librarian/resolver/implementation.rb +64 -49
  16. data/lib/librarian/source/git.rb +47 -11
  17. data/lib/librarian/source/git/repository.rb +33 -3
  18. data/lib/librarian/version.rb +1 -1
  19. data/librarian.gemspec +8 -6
  20. data/spec/functional/cli_spec.rb +1 -1
  21. data/spec/functional/posix_spec.rb +6 -8
  22. data/spec/functional/source/git/repository_spec.rb +55 -27
  23. data/spec/functional/source/git_spec.rb +152 -8
  24. data/spec/support/project_path_macro.rb +14 -0
  25. data/spec/unit/action/base_spec.rb +1 -1
  26. data/spec/unit/action/clean_spec.rb +6 -6
  27. data/spec/unit/action/install_spec.rb +5 -5
  28. data/spec/unit/algorithms_spec.rb +131 -0
  29. data/spec/unit/config/database_spec.rb +38 -38
  30. data/spec/unit/dependency/requirement_spec.rb +12 -0
  31. data/spec/unit/dsl_spec.rb +49 -49
  32. data/spec/unit/environment/runtime_cache_spec.rb +73 -0
  33. data/spec/unit/environment_spec.rb +28 -28
  34. data/spec/unit/lockfile/parser_spec.rb +18 -18
  35. data/spec/unit/lockfile_spec.rb +3 -3
  36. data/spec/unit/manifest/version_spec.rb +11 -0
  37. data/spec/unit/manifest_set_spec.rb +20 -20
  38. data/spec/unit/mock/environment_spec.rb +4 -4
  39. data/spec/unit/resolver_spec.rb +61 -20
  40. data/spec/unit/spec_change_set_spec.rb +19 -19
  41. metadata +19 -5
@@ -47,25 +47,34 @@ module Librarian
47
47
 
48
48
  class << self
49
49
 
50
- if defined?(JRuby) # built with jruby-1.7.4 in mind
50
+ if defined?(JRuby) # built with jruby-1.7.9 in mind
51
+
52
+ def rescuing(*klasses)
53
+ begin
54
+ yield
55
+ rescue *klasses
56
+ end
57
+ end
51
58
 
52
59
  def run!(command, options = { })
53
60
  out, err = nil, nil
54
61
  chdir = options[:chdir].to_s if options[:chdir]
55
62
  env = options[:env] || { }
56
63
  old_env = Hash[env.keys.map{|k| [k, ENV[k]]}]
64
+ out, err, wait = nil, nil, nil
57
65
  begin
58
66
  ENV.update env
59
67
  Dir.chdir(chdir || Dir.pwd) do
60
- IO.popen3(*command) do |i, o, e|
61
- i.close
62
- out, err = o.read, e.read
68
+ IO.popen3(*command) do |i, o, e, w|
69
+ rescuing(Errno::EBADF){ i.close } # jruby/1.9 can raise EBADF
70
+ out, err, wait = o.read, e.read, w
63
71
  end
64
72
  end
65
73
  ensure
66
74
  ENV.update old_env
67
75
  end
68
- $?.success? or CommandFailure.raise! command, $?, err
76
+ s = wait ? wait.value : $? # wait is 1.9+-only
77
+ s.success? or CommandFailure.raise! command, s, err
69
78
  out
70
79
  end
71
80
 
@@ -1,3 +1,4 @@
1
+ require 'librarian/error'
1
2
  require 'librarian/resolver/implementation'
2
3
  require 'librarian/manifest_set'
3
4
  require 'librarian/resolution'
@@ -5,26 +6,32 @@ require 'librarian/resolution'
5
6
  module Librarian
6
7
  class Resolver
7
8
 
8
- attr_accessor :environment
9
- private :environment=
9
+ attr_accessor :environment, :cyclic
10
+ private :environment=, :cyclic=
10
11
 
11
- def initialize(environment)
12
+ # Options:
13
+ # cyclic: truthy if the resolver should permit cyclic resolutions
14
+ def initialize(environment, options = { })
15
+ unrecognized_options = options.keys - [:cyclic]
16
+ unrecognized_options.empty? or raise Error,
17
+ "unrecognized options: #{unrecognized_options.join(", ")}"
12
18
  self.environment = environment
19
+ self.cyclic = !!options[:cyclic]
13
20
  end
14
21
 
15
22
  def resolve(spec, partial_manifests = [])
16
23
  manifests = implementation(spec).resolve(partial_manifests)
17
- if manifests
18
- enforce_consistency!(spec.dependencies, manifests)
19
- manifests = sort(manifests)
20
- Resolution.new(spec.dependencies, manifests)
21
- end
24
+ manifests or return
25
+ enforce_consistency!(spec.dependencies, manifests)
26
+ enforce_acyclicity!(manifests) unless cyclic
27
+ manifests = sort(manifests)
28
+ Resolution.new(spec.dependencies, manifests)
22
29
  end
23
30
 
24
31
  private
25
32
 
26
33
  def implementation(spec)
27
- Implementation.new(self, spec)
34
+ Implementation.new(self, spec, :cyclic => cyclic)
28
35
  end
29
36
 
30
37
  def enforce_consistency!(dependencies, manifests)
@@ -69,6 +76,12 @@ module Librarian
69
76
  raise Error, "Resolver Malfunctioned!"
70
77
  end
71
78
 
79
+ def enforce_acyclicity!(manifests)
80
+ ManifestSet.cyclic?(manifests) or return
81
+ debug { "Resolver Malfunctioned!" }
82
+ raise Error, "Resolver Malfunctioned!"
83
+ end
84
+
72
85
  def sort(manifests)
73
86
  ManifestSet.sort(manifests)
74
87
  end
@@ -1,3 +1,6 @@
1
+ require 'set'
2
+
3
+ require 'librarian/algorithms'
1
4
  require 'librarian/dependency'
2
5
 
3
6
  module Librarian
@@ -17,67 +20,62 @@ module Librarian
17
20
  end
18
21
  end
19
22
 
20
- attr_accessor :resolver, :spec
21
- private :resolver=, :spec=
23
+ class State
24
+ attr_accessor :manifests, :dependencies, :queue
25
+ private :manifests=, :dependencies=, :queue=
26
+ def initialize(manifests, dependencies, queue)
27
+ self.manifests = manifests
28
+ self.dependencies = dependencies # resolved
29
+ self.queue = queue # scheduled
30
+ end
31
+ end
32
+
33
+ attr_accessor :resolver, :spec, :cyclic
34
+ private :resolver=, :spec=, :cyclic=
22
35
 
23
- def initialize(resolver, spec)
36
+ def initialize(resolver, spec, options = { })
37
+ unrecognized_options = options.keys - [:cyclic]
38
+ unrecognized_options.empty? or raise Error,
39
+ "unrecognized options: #{unrecognized_options.join(", ")}"
24
40
  self.resolver = resolver
25
41
  self.spec = spec
42
+ self.cyclic = !!options[:cyclic]
26
43
  @level = 0
27
44
  end
28
45
 
29
46
  def resolve(manifests)
30
47
  manifests = index_by(manifests, &:name) if manifests.kind_of?(Array)
31
- addtl = spec.dependencies + sourced_dependencies_for_manifests(manifests)
32
- recursive_resolve([], manifests, [], addtl)
48
+ queue = spec.dependencies + sourced_dependencies_for_manifests(manifests)
49
+ state = State.new(manifests.dup, [], queue)
50
+ recursive_resolve(state)
33
51
  end
34
52
 
35
53
  private
36
54
 
37
- def find_inconsistency(dep, deps, mans)
38
- m = mans[dep.name]
39
- dep.satisfied_by?(m) or return m if m
40
- deps.find{|d| !dep.consistent_with?(d)}
41
- end
42
-
43
- def recursive_resolve(dependencies, manifests, queue, addtl)
44
- dependencies = dependencies.dup
45
- manifests = manifests.dup
46
- queue = queue.dup
55
+ def recursive_resolve(state)
56
+ shift_resolved_enqueued_dependencies(state) or return
57
+ state.queue.empty? and return state.manifests
47
58
 
48
- return unless enqueue_dependencies(queue, addtl, dependencies, manifests)
49
- return unless shift_resolved_enqueued_dependencies(dependencies, manifests, queue)
50
- return manifests if queue.empty?
51
-
52
- dependency = queue.shift
53
- dependencies << dependency
54
- all_deps = dependencies + queue
59
+ state.dependencies << state.queue.shift
60
+ dependency = state.dependencies.last
55
61
 
56
62
  resolving_dependency_map_find_manifests(dependency) do |manifest|
57
- next unless check_manifest(manifest, all_deps)
63
+ check_manifest(state, manifest) or next
64
+ check_manifest_for_cycles(state, manifest) or next unless cyclic
58
65
 
59
- m = manifests.merge(dependency.name => manifest)
66
+ m = state.manifests.merge(dependency.name => manifest)
60
67
  a = sourced_dependencies_for_manifest(manifest)
68
+ s = State.new(m, state.dependencies.dup, state.queue + a)
61
69
 
62
- recursive_resolve(dependencies, m, queue, a)
70
+ recursive_resolve(s)
63
71
  end
64
72
  end
65
73
 
66
- # When using this method, you are required to check the return value.
67
- # Returns +true+ if the enqueueables could all be enqueued.
68
- # Returns +false+ if there was an inconsistency when trying to enqueue one
69
- # or more of them.
70
- # This modifies +queue+ but does not modify any other arguments.
71
- def enqueue_dependencies(queue, enqueueables, dependencies, manifests)
72
- enqueueables.each do |d|
73
- if q = find_inconsistency(d, dependencies + queue, manifests)
74
- debug_conflict d, q
75
- return false
76
- end
77
- debug_schedule d
78
- queue << d
79
- end
80
- true
74
+ def find_inconsistency(state, dependency)
75
+ m = state.manifests[dependency.name]
76
+ dependency.satisfied_by?(m) or return m if m
77
+ violation = lambda{|d| !dependency.consistent_with?(d)}
78
+ state.dependencies.find(&violation) || state.queue.find(&violation)
81
79
  end
82
80
 
83
81
  # When using this method, you are required to check the return value.
@@ -86,14 +84,13 @@ module Librarian
86
84
  # Returns +false+ if there was an inconsistency when trying to move one or
87
85
  # more of them.
88
86
  # This modifies +queue+ and +dependencies+.
89
- def shift_resolved_enqueued_dependencies(dependencies, manifests, queue)
90
- all_deps = dependencies + queue
91
- while (dependency = queue.first) && manifests[dependency.name]
92
- if q = find_inconsistency(dependency, all_deps, manifests)
93
- debug_conflict dependency, q
87
+ def shift_resolved_enqueued_dependencies(state)
88
+ while (d = state.queue.first) && state.manifests[d.name]
89
+ if q = find_inconsistency(state, d)
90
+ debug_conflict d, q
94
91
  return false
95
92
  end
96
- dependencies << queue.shift
93
+ state.dependencies << state.queue.shift
97
94
  end
98
95
  true
99
96
  end
@@ -102,15 +99,29 @@ module Librarian
102
99
  # Returns +true+ if the manifest satisfies all of the dependencies.
103
100
  # Returns +false+ if there was a dependency that the manifest does not
104
101
  # satisfy.
105
- def check_manifest(manifest, all_deps)
106
- related = all_deps.select{|d| d.name == manifest.name}
107
- if q = related.find{|d| !d.satisfied_by?(manifest)}
102
+ def check_manifest(state, manifest)
103
+ violation = lambda{|d| d.name == manifest.name && !d.satisfied_by?(manifest)}
104
+ if q = state.dependencies.find(&violation) || state.queue.find(&violation)
108
105
  debug_conflict manifest, q
109
106
  return false
110
107
  end
111
108
  true
112
109
  end
113
110
 
111
+ # When using this method, you are required to check the return value.
112
+ # Returns +true+ if the manifest does not introduce a cycle.
113
+ # Returns +false+ if the manifest introduces a cycle.
114
+ def check_manifest_for_cycles(state, manifest)
115
+ manifests = state.manifests.merge(manifest.name => manifest)
116
+ known = manifests.keys
117
+ graph = Hash[manifests.map{|n, m| [n, m.dependencies.map(&:name) & known]}]
118
+ if Algorithms::AdjacencyListDirectedGraph.cyclic?(graph)
119
+ debug_cycle manifest
120
+ return false
121
+ end
122
+ true
123
+ end
124
+
114
125
  def default_source
115
126
  @default_source ||= MultiSource.new(spec.sources)
116
127
  end
@@ -191,6 +202,10 @@ module Librarian
191
202
  debug { "Conflict between #{dependency} and #{conflict}" }
192
203
  end
193
204
 
205
+ def debug_cycle(manifest)
206
+ debug { "Cycle with #{manifest}" }
207
+ end
208
+
194
209
  def map_find(enum)
195
210
  enum.each do |obj|
196
211
  res = yield(obj)
@@ -82,20 +82,30 @@ module Librarian
82
82
  repository.clone!(uri)
83
83
  raise Error, "failed to clone #{uri}" unless repository.git?
84
84
  end
85
- repository.reset_hard!
86
- repository.clean!
87
- unless repository.checked_out?(sha)
88
- remote = repository.default_remote
89
- repository.fetch!(remote)
90
- repository.fetch!(remote, :tags => true)
91
85
 
92
- self.sha = repository.hash_from(remote, ref) unless sha
93
- repository.checkout!(sha) unless repository.checked_out?(sha)
86
+ # Probably unnecessary: nobody should be writing to our cache but us.
87
+ # Just a precaution.
88
+ repository_clean_once!
89
+
90
+ unless sha
91
+ repository_update_once!
92
+ self.sha = fetch_sha_memo
93
+ end
94
94
 
95
+ unless repository.checked_out?(sha)
96
+ repository_update_once! unless repository.has_commit?(sha)
97
+ repository.checkout!(sha)
98
+ # Probably unnecessary: if git fails to checkout, it should exit
99
+ # nonzero, and we should expect Librarian::Posix::CommandFailure.
95
100
  raise Error, "failed to checkout #{sha}" unless repository.checked_out?(sha)
96
101
  end
97
102
  end
98
103
 
104
+ # For tests
105
+ def git_ops_count
106
+ repository.git_ops_history.size
107
+ end
108
+
99
109
  private
100
110
 
101
111
  attr_accessor :repository_cached
@@ -107,7 +117,7 @@ module Librarian
107
117
 
108
118
  def repository_cache_path
109
119
  @repository_cache_path ||= begin
110
- environment.cache_path.join("source/git/#{cache_key}")
120
+ environment.cache_path + "source/git" + cache_key
111
121
  end
112
122
  end
113
123
 
@@ -121,16 +131,42 @@ module Librarian
121
131
  @filesystem_path ||= path ? repository.path.join(path) : repository.path
122
132
  end
123
133
 
134
+ def repository_clean_once!
135
+ remote = repository.default_remote
136
+ runtime_cache.once ['repository-clean', uri, ref].to_s do
137
+ repository.reset_hard!
138
+ repository.clean!
139
+ end
140
+ end
141
+
142
+ def repository_update_once!
143
+ remote = repository.default_remote
144
+ runtime_cache.once ['repository-update', uri, remote, ref].to_s do
145
+ repository.fetch! remote
146
+ repository.fetch! remote, :tags => true
147
+ end
148
+ end
149
+
150
+ def fetch_sha_memo
151
+ remote = repository.default_remote
152
+ runtime_cache.memo ['fetch-sha', uri, remote, ref].to_s do
153
+ repository.hash_from(remote, ref)
154
+ end
155
+ end
156
+
124
157
  def cache_key
125
158
  @cache_key ||= begin
126
159
  uri_part = uri
127
- path_part = "/#{path}" if path
128
160
  ref_part = "##{ref}"
129
- key_source = [uri_part, path_part, ref_part].join
161
+ key_source = [uri_part, ref_part].join
130
162
  Digest::MD5.hexdigest(key_source)[0..15]
131
163
  end
132
164
  end
133
165
 
166
+ def runtime_cache
167
+ @runtime_cache ||= environment.runtime_cache.keyspace(self.class.name)
168
+ end
169
+
134
170
  end
135
171
  end
136
172
  end
@@ -1,3 +1,5 @@
1
+ require "pathname"
2
+
1
3
  require "librarian/posix"
2
4
 
3
5
  module Librarian
@@ -20,16 +22,17 @@ module Librarian
20
22
 
21
23
  def git_version
22
24
  command = %W[#{bin} version --silent]
23
- Posix.run!(command).strip =~ /([.\d]+)$/ && $1
25
+ Posix.run!(command).strip =~ /\Agit version (\d+(\.\d+)*)/ && $1
24
26
  end
25
27
  end
26
28
 
27
- attr_accessor :environment, :path
28
- private :environment=, :path=
29
+ attr_accessor :environment, :path, :git_ops_history
30
+ private :environment=, :path=, :git_ops_history=
29
31
 
30
32
  def initialize(environment, path)
31
33
  self.environment = environment
32
34
  self.path = Pathname.new(path)
35
+ self.git_ops_history = []
33
36
  end
34
37
 
35
38
  def git?
@@ -67,6 +70,13 @@ module Librarian
67
70
  run!(command, :chdir => true)
68
71
  end
69
72
 
73
+ def has_commit?(sha)
74
+ command = %W(log -1 --no-color --format=tformat:%H #{sha})
75
+ run!(command, :chdir => true).strip == sha
76
+ rescue Posix::CommandFailure => e
77
+ false
78
+ end
79
+
70
80
  def checked_out?(sha)
71
81
  current_commit_hash == sha
72
82
  end
@@ -136,6 +146,8 @@ module Librarian
136
146
 
137
147
  out = yield
138
148
 
149
+ git_ops_history << command + [{:pwd => pwd}]
150
+
139
151
  unless silent
140
152
  if out.size > 0
141
153
  out.lines.each do |line|
@@ -147,6 +159,24 @@ module Librarian
147
159
  end
148
160
 
149
161
  out
162
+
163
+ rescue Posix::CommandFailure => e
164
+
165
+ git_ops_history << command + [{:pwd => pwd}]
166
+
167
+ status, stderr = e.status, e.message
168
+ unless silent
169
+ debug { " --- Exited with #{status}" }
170
+ if stderr.size > 0
171
+ stderr.lines.each do |line|
172
+ debug { " --> #{line}" }
173
+ end
174
+ else
175
+ debug { " --- No output" }
176
+ end
177
+ end
178
+
179
+ raise e
150
180
  end
151
181
 
152
182
  def debug(*args, &block)
@@ -1,3 +1,3 @@
1
1
  module Librarian
2
- VERSION = "0.1.1"
2
+ VERSION = File.read(File.expand_path("../../../VERSION", __FILE__)).strip
3
3
  end
@@ -1,20 +1,22 @@
1
1
  # -*- encoding: utf-8 -*-
2
+ # stub: librarian 0.1.2 ruby lib
2
3
 
3
4
  Gem::Specification.new do |s|
4
5
  s.name = "librarian"
5
- s.version = "0.1.1"
6
+ s.version = "0.1.2"
6
7
 
7
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
9
  s.authors = ["Jay Feldblum"]
9
- s.date = "2013-08-17"
10
+ s.date = "2014-02-09"
10
11
  s.description = "A Framework for Bundlers."
11
12
  s.email = ["y_feldblum@yahoo.com"]
12
- s.files = [".gitignore", ".rspec", ".travis.yml", "CHANGELOG.md", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "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/persist_resolution_mixin.rb", "lib/librarian/action/resolve.rb", "lib/librarian/action/update.rb", "lib/librarian/cli.rb", "lib/librarian/cli/manifest_presenter.rb", "lib/librarian/config.rb", "lib/librarian/config/database.rb", "lib/librarian/config/file_source.rb", "lib/librarian/config/hash_source.rb", "lib/librarian/config/source.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/linter/source_linter.rb", "lib/librarian/lockfile.rb", "lib/librarian/lockfile/compiler.rb", "lib/librarian/lockfile/parser.rb", "lib/librarian/logger.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/mock/version.rb", "lib/librarian/posix.rb", "lib/librarian/resolution.rb", "lib/librarian/resolver.rb", "lib/librarian/resolver/implementation.rb", "lib/librarian/rspec/support/cli_macro.rb", "lib/librarian/source.rb", "lib/librarian/source/basic_api.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/cli_spec.rb", "spec/functional/posix_spec.rb", "spec/functional/source/git/repository_spec.rb", "spec/functional/source/git_spec.rb", "spec/support/fakefs.rb", "spec/support/method_patch_macro.rb", "spec/support/with_env_macro.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/config/database_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/environment_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"]
13
- s.homepage = ""
13
+ s.files = [".gitignore", ".rspec", ".travis.yml", "CHANGELOG.md", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "VERSION", "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/persist_resolution_mixin.rb", "lib/librarian/action/resolve.rb", "lib/librarian/action/update.rb", "lib/librarian/algorithms.rb", "lib/librarian/cli.rb", "lib/librarian/cli/manifest_presenter.rb", "lib/librarian/config.rb", "lib/librarian/config/database.rb", "lib/librarian/config/file_source.rb", "lib/librarian/config/hash_source.rb", "lib/librarian/config/source.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/environment/runtime_cache.rb", "lib/librarian/error.rb", "lib/librarian/helpers.rb", "lib/librarian/linter/source_linter.rb", "lib/librarian/lockfile.rb", "lib/librarian/lockfile/compiler.rb", "lib/librarian/lockfile/parser.rb", "lib/librarian/logger.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/mock/version.rb", "lib/librarian/posix.rb", "lib/librarian/resolution.rb", "lib/librarian/resolver.rb", "lib/librarian/resolver/implementation.rb", "lib/librarian/rspec/support/cli_macro.rb", "lib/librarian/source.rb", "lib/librarian/source/basic_api.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/cli_spec.rb", "spec/functional/posix_spec.rb", "spec/functional/source/git/repository_spec.rb", "spec/functional/source/git_spec.rb", "spec/support/fakefs.rb", "spec/support/method_patch_macro.rb", "spec/support/project_path_macro.rb", "spec/support/with_env_macro.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/algorithms_spec.rb", "spec/unit/config/database_spec.rb", "spec/unit/dependency/requirement_spec.rb", "spec/unit/dependency_spec.rb", "spec/unit/dsl_spec.rb", "spec/unit/environment/runtime_cache_spec.rb", "spec/unit/environment_spec.rb", "spec/unit/lockfile/parser_spec.rb", "spec/unit/lockfile_spec.rb", "spec/unit/manifest/version_spec.rb", "spec/unit/manifest_set_spec.rb", "spec/unit/manifest_spec.rb", "spec/unit/mock/environment_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 = "https://github.com/applicationsonline/librarian"
15
+ s.licenses = ["MIT"]
14
16
  s.require_paths = ["lib"]
15
- s.rubygems_version = "2.0.3"
17
+ s.rubygems_version = "2.1.3"
16
18
  s.summary = "A Framework for Bundlers."
17
- s.test_files = ["spec/functional/cli_spec.rb", "spec/functional/posix_spec.rb", "spec/functional/source/git/repository_spec.rb", "spec/functional/source/git_spec.rb", "spec/support/fakefs.rb", "spec/support/method_patch_macro.rb", "spec/support/with_env_macro.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/config/database_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/environment_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"]
19
+ s.test_files = ["spec/functional/cli_spec.rb", "spec/functional/posix_spec.rb", "spec/functional/source/git/repository_spec.rb", "spec/functional/source/git_spec.rb", "spec/support/fakefs.rb", "spec/support/method_patch_macro.rb", "spec/support/project_path_macro.rb", "spec/support/with_env_macro.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/algorithms_spec.rb", "spec/unit/config/database_spec.rb", "spec/unit/dependency/requirement_spec.rb", "spec/unit/dependency_spec.rb", "spec/unit/dsl_spec.rb", "spec/unit/environment/runtime_cache_spec.rb", "spec/unit/environment_spec.rb", "spec/unit/lockfile/parser_spec.rb", "spec/unit/lockfile_spec.rb", "spec/unit/manifest/version_spec.rb", "spec/unit/manifest_set_spec.rb", "spec/unit/manifest_spec.rb", "spec/unit/mock/environment_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"]
18
20
 
19
21
  if s.respond_to? :specification_version then
20
22
  s.specification_version = 4