librarian 0.0.9 → 0.0.10
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/CHANGELOG.md +4 -0
- data/lib/librarian.rb +5 -178
- data/lib/librarian/action.rb +5 -0
- data/lib/librarian/action/base.rb +22 -0
- data/lib/librarian/action/clean.rb +56 -0
- data/lib/librarian/action/ensure.rb +24 -0
- data/lib/librarian/action/install.rb +101 -0
- data/lib/librarian/action/resolve.rb +81 -0
- data/lib/librarian/action/update.rb +76 -0
- data/lib/librarian/chef/cli.rb +7 -2
- data/lib/librarian/chef/dsl.rb +0 -3
- data/lib/librarian/chef/environment.rb +19 -0
- data/lib/librarian/chef/extension.rb +1 -16
- data/lib/librarian/chef/integration/knife.rb +9 -16
- data/lib/librarian/chef/source/git.rb +0 -2
- data/lib/librarian/chef/source/local.rb +1 -74
- data/lib/librarian/chef/source/local/manifest.rb +82 -0
- data/lib/librarian/chef/source/path.rb +0 -2
- data/lib/librarian/chef/source/site.rb +9 -89
- data/lib/librarian/chef/source/site/manifest.rb +94 -0
- data/lib/librarian/cli.rb +56 -17
- data/lib/librarian/dependency.rb +2 -2
- data/lib/librarian/dsl.rb +15 -5
- data/lib/librarian/dsl/receiver.rb +2 -0
- data/lib/librarian/dsl/target.rb +13 -1
- data/lib/librarian/environment.rb +94 -0
- data/lib/librarian/error.rb +4 -0
- data/lib/librarian/helpers/debug.rb +6 -6
- data/lib/librarian/lockfile.rb +7 -5
- data/lib/librarian/lockfile/compiler.rb +5 -4
- data/lib/librarian/lockfile/parser.rb +6 -5
- data/lib/librarian/manifest.rb +2 -2
- data/lib/librarian/mock/cli.rb +6 -1
- data/lib/librarian/mock/dsl.rb +0 -3
- data/lib/librarian/mock/environment.rb +24 -0
- data/lib/librarian/mock/extension.rb +1 -20
- data/lib/librarian/mock/source/mock.rb +7 -7
- data/lib/librarian/mock/source/mock/registry.rb +16 -12
- data/lib/librarian/resolver.rb +5 -116
- data/lib/librarian/resolver/implementation.rb +117 -0
- data/lib/librarian/source/git.rb +8 -7
- data/lib/librarian/source/git/repository.rb +7 -5
- data/lib/librarian/source/local.rb +1 -1
- data/lib/librarian/source/path.rb +7 -6
- data/lib/librarian/spec_change_set.rb +6 -5
- data/lib/librarian/specfile.rb +10 -4
- data/lib/librarian/version.rb +1 -1
- data/librarian.gemspec +1 -0
- data/spec/functional/chef/source/git_spec.rb +177 -89
- data/spec/functional/chef/source/site_spec.rb +111 -52
- data/spec/unit/action/base_spec.rb +18 -0
- data/spec/unit/action/clean_spec.rb +133 -0
- data/spec/unit/action/ensure_spec.rb +37 -0
- data/spec/unit/action/install_spec.rb +113 -0
- data/spec/unit/dsl_spec.rb +15 -13
- data/spec/unit/environment_spec.rb +9 -0
- data/spec/unit/lockfile_spec.rb +15 -4
- data/spec/unit/mock/source/mock.rb +22 -0
- data/spec/unit/resolver_spec.rb +24 -24
- data/spec/unit/spec_change_set_spec.rb +29 -25
- metadata +47 -19
- data/lib/librarian/chef/particularity.rb +0 -9
- data/lib/librarian/mock/particularity.rb +0 -9
- data/lib/librarian/particularity.rb +0 -7
data/CHANGELOG.md
CHANGED
data/lib/librarian.rb
CHANGED
@@ -1,188 +1,15 @@
|
|
1
|
-
require 'pathname'
|
2
|
-
|
3
|
-
require 'librarian/helpers/debug'
|
4
|
-
require 'librarian/support/abstract_method'
|
5
|
-
|
6
1
|
require 'librarian/version'
|
7
|
-
require 'librarian/
|
8
|
-
require 'librarian/manifest_set'
|
9
|
-
require 'librarian/particularity'
|
10
|
-
require 'librarian/resolver'
|
11
|
-
require 'librarian/source'
|
12
|
-
require 'librarian/spec_change_set'
|
13
|
-
require 'librarian/specfile'
|
14
|
-
require 'librarian/lockfile'
|
15
|
-
require 'librarian/ui'
|
2
|
+
require 'librarian/environment'
|
16
3
|
|
17
4
|
module Librarian
|
18
5
|
extend self
|
19
6
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
class Error < StandardError
|
24
|
-
end
|
25
|
-
|
26
|
-
attr_accessor :ui
|
27
|
-
|
28
|
-
abstract_method :specfile_name, :dsl_class, :install_path
|
29
|
-
|
30
|
-
def project_path
|
31
|
-
@project_path ||= begin
|
32
|
-
root = Pathname.new(Dir.pwd)
|
33
|
-
root = root.dirname until root.join(specfile_name).exist? || root.dirname == root
|
34
|
-
path = root.join(specfile_name)
|
35
|
-
path.exist? ? root : nil
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def specfile_path
|
40
|
-
project_path.join(specfile_name)
|
41
|
-
end
|
42
|
-
|
43
|
-
def specfile
|
44
|
-
Specfile.new(self, specfile_path)
|
45
|
-
end
|
46
|
-
|
47
|
-
def lockfile_name
|
48
|
-
"#{specfile_name}.lock"
|
49
|
-
end
|
50
|
-
|
51
|
-
def lockfile_path
|
52
|
-
project_path.join(lockfile_name)
|
53
|
-
end
|
54
|
-
|
55
|
-
def lockfile
|
56
|
-
Lockfile.new(self, lockfile_path)
|
57
|
-
end
|
58
|
-
|
59
|
-
def ephemeral_lockfile
|
60
|
-
Lockfile.new(self, nil)
|
61
|
-
end
|
62
|
-
|
63
|
-
def resolver
|
64
|
-
Resolver.new(self)
|
65
|
-
end
|
66
|
-
|
67
|
-
def cache_path
|
68
|
-
project_path.join('tmp/librarian/cache')
|
7
|
+
def environment_class
|
8
|
+
self::Environment
|
69
9
|
end
|
70
10
|
|
71
|
-
def
|
72
|
-
|
73
|
-
end
|
74
|
-
|
75
|
-
def spec_change_set(spec, lock)
|
76
|
-
SpecChangeSet.new(self, spec, lock)
|
77
|
-
end
|
78
|
-
|
79
|
-
def version
|
80
|
-
VERSION
|
81
|
-
end
|
82
|
-
|
83
|
-
def ensure!
|
84
|
-
unless project_path
|
85
|
-
raise Error, "Cannot find #{specfile_name}!"
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def clean!
|
90
|
-
if cache_path.exist?
|
91
|
-
debug { "Deleting #{project_relative_path_to(cache_path)}" }
|
92
|
-
cache_path.rmtree
|
93
|
-
end
|
94
|
-
if install_path.exist?
|
95
|
-
install_path.children.each do |c|
|
96
|
-
debug { "Deleting #{project_relative_path_to(c)}" }
|
97
|
-
c.rmtree unless c.file?
|
98
|
-
end
|
99
|
-
end
|
100
|
-
if lockfile_path.exist?
|
101
|
-
debug { "Deleting #{project_relative_path_to(lockfile_path)}" }
|
102
|
-
lockfile_path.rmtree
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def install!
|
107
|
-
resolve!
|
108
|
-
manifests = ManifestSet.sort(lockfile.load(lockfile_path.read).manifests)
|
109
|
-
manifests.each do |manifest|
|
110
|
-
manifest.source.cache!([manifest])
|
111
|
-
end
|
112
|
-
install_path.mkpath unless install_path.exist?
|
113
|
-
manifests.each do |manifest|
|
114
|
-
manifest.install!
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def update!(dependency_names)
|
119
|
-
unless lockfile_path.exist?
|
120
|
-
raise Error, "Lockfile missing!"
|
121
|
-
end
|
122
|
-
previous_resolution = lockfile.load(lockfile_path.read)
|
123
|
-
partial_manifests = ManifestSet.deep_strip(previous_resolution.manifests, dependency_names)
|
124
|
-
spec = specfile.read(previous_resolution.sources)
|
125
|
-
spec_changes = spec_change_set(spec, previous_resolution)
|
126
|
-
raise Error, "Cannot update when the specfile has been changed." unless spec_changes.same?
|
127
|
-
resolution = resolver.resolve(spec, partial_manifests)
|
128
|
-
unless resolution.correct?
|
129
|
-
ui.info { "Could not resolve the dependencies." }
|
130
|
-
else
|
131
|
-
lockfile_text = lockfile.save(resolution)
|
132
|
-
debug { "Bouncing #{lockfile_name}" }
|
133
|
-
bounced_lockfile_text = lockfile.save(lockfile.load(lockfile_text))
|
134
|
-
unless bounced_lockfile_text == lockfile_text
|
135
|
-
debug { "lockfile_text: \n#{lockfile_text}"}
|
136
|
-
debug { "bounced_lockfile_text: \n#{bounced_lockfile_text}"}
|
137
|
-
raise Error, "Cannot bounce #{lockfile_name}!"
|
138
|
-
end
|
139
|
-
lockfile_path.open('wb') { |f| f.write(lockfile_text) }
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def resolve!(options = {})
|
144
|
-
if options[:force] || !lockfile_path.exist?
|
145
|
-
spec = specfile.read
|
146
|
-
manifests = []
|
147
|
-
else
|
148
|
-
lock = lockfile.read
|
149
|
-
spec = specfile.read(lock.sources)
|
150
|
-
changes = spec_change_set(spec, lock)
|
151
|
-
if changes.same?
|
152
|
-
debug { "The specfile is unchanged: nothing to do." }
|
153
|
-
return
|
154
|
-
end
|
155
|
-
manifests = changes.analyze
|
156
|
-
end
|
157
|
-
|
158
|
-
resolution = resolver.resolve(spec, manifests)
|
159
|
-
unless resolution.correct?
|
160
|
-
raise Error, "Could not resolve the dependencies."
|
161
|
-
else
|
162
|
-
lockfile_text = lockfile.save(resolution)
|
163
|
-
debug { "Bouncing #{lockfile_name}" }
|
164
|
-
bounced_lockfile_text = lockfile.save(lockfile.load(lockfile_text))
|
165
|
-
unless bounced_lockfile_text == lockfile_text
|
166
|
-
debug { "lockfile_text: \n#{lockfile_text}"}
|
167
|
-
debug { "bounced_lockfile_text: \n#{bounced_lockfile_text}"}
|
168
|
-
raise Error, "Cannot bounce #{lockfile_name}!"
|
169
|
-
end
|
170
|
-
lockfile_path.open('wb') { |f| f.write(lockfile_text) }
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
def dsl(&block)
|
175
|
-
dsl_class.run(&block)
|
176
|
-
end
|
177
|
-
|
178
|
-
def dsl_class
|
179
|
-
self::Dsl
|
180
|
-
end
|
181
|
-
|
182
|
-
private
|
183
|
-
|
184
|
-
def root_module
|
185
|
-
self
|
11
|
+
def environment
|
12
|
+
@environment ||= environment_class.new
|
186
13
|
end
|
187
14
|
|
188
15
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "librarian/helpers/debug"
|
2
|
+
|
3
|
+
module Librarian
|
4
|
+
module Action
|
5
|
+
class Base
|
6
|
+
|
7
|
+
include Helpers::Debug
|
8
|
+
|
9
|
+
attr_accessor :environment
|
10
|
+
private :environment=
|
11
|
+
|
12
|
+
attr_accessor :options
|
13
|
+
private :options=
|
14
|
+
|
15
|
+
def initialize(environment, options = { })
|
16
|
+
self.environment = environment
|
17
|
+
self.options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "librarian/action/base"
|
2
|
+
|
3
|
+
module Librarian
|
4
|
+
module Action
|
5
|
+
class Clean < Base
|
6
|
+
|
7
|
+
def run
|
8
|
+
clean_cache_path
|
9
|
+
clean_install_path
|
10
|
+
clean_lockfile_path
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def clean_cache_path
|
16
|
+
if cache_path.exist?
|
17
|
+
debug { "Deleting #{project_relative_path_to(cache_path)}" }
|
18
|
+
cache_path.rmtree
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def clean_install_path
|
23
|
+
if install_path.exist?
|
24
|
+
install_path.children.each do |c|
|
25
|
+
debug { "Deleting #{project_relative_path_to(c)}" }
|
26
|
+
c.rmtree unless c.file?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def clean_lockfile_path
|
32
|
+
if lockfile_path.exist?
|
33
|
+
debug { "Deleting #{project_relative_path_to(lockfile_path)}" }
|
34
|
+
lockfile_path.rmtree
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def cache_path
|
39
|
+
environment.cache_path
|
40
|
+
end
|
41
|
+
|
42
|
+
def install_path
|
43
|
+
environment.install_path
|
44
|
+
end
|
45
|
+
|
46
|
+
def lockfile_path
|
47
|
+
environment.lockfile_path
|
48
|
+
end
|
49
|
+
|
50
|
+
def project_relative_path_to(path)
|
51
|
+
environment.project_relative_path_to(path)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "librarian/error"
|
2
|
+
require "librarian/action/base"
|
3
|
+
|
4
|
+
module Librarian
|
5
|
+
module Action
|
6
|
+
class Ensure < Base
|
7
|
+
|
8
|
+
def run
|
9
|
+
raise Error, "Cannot find #{specfile_name}!" unless project_path
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def specfile_name
|
15
|
+
environment.specfile_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def project_path
|
19
|
+
environment.project_path
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "librarian/manifest_set"
|
2
|
+
require "librarian/spec_change_set"
|
3
|
+
require "librarian/action/base"
|
4
|
+
|
5
|
+
module Librarian
|
6
|
+
module Action
|
7
|
+
class Install < Base
|
8
|
+
|
9
|
+
def run
|
10
|
+
check_preconditions
|
11
|
+
|
12
|
+
perform_installation
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def check_preconditions
|
18
|
+
check_specfile
|
19
|
+
check_lockfile
|
20
|
+
check_consistent
|
21
|
+
end
|
22
|
+
|
23
|
+
def check_specfile
|
24
|
+
raise Error, "#{specfile_name} missing!" unless specfile_path.exist?
|
25
|
+
end
|
26
|
+
|
27
|
+
def check_lockfile
|
28
|
+
raise Error, "#{lockfile_name} missing!" unless lockfile_path.exist?
|
29
|
+
end
|
30
|
+
|
31
|
+
def check_consistent
|
32
|
+
raise Error, "#{specfile_name} and #{lockfile_name} are out of sync!" unless spec_consistent_with_lock?
|
33
|
+
end
|
34
|
+
|
35
|
+
def perform_installation
|
36
|
+
manifests = sorted_manifests
|
37
|
+
|
38
|
+
cache_manifests(manifests)
|
39
|
+
create_install_path
|
40
|
+
install_manifests(manifests)
|
41
|
+
end
|
42
|
+
|
43
|
+
def cache_manifests(manifests)
|
44
|
+
manifests.each do |manifest|
|
45
|
+
manifest.source.cache!([manifest])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_install_path
|
50
|
+
install_path.mkpath unless install_path.exist?
|
51
|
+
end
|
52
|
+
|
53
|
+
def install_manifests(manifests)
|
54
|
+
manifests.each do |manifest|
|
55
|
+
manifest.install!
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def sorted_manifests
|
60
|
+
ManifestSet.sort(lock.manifests)
|
61
|
+
end
|
62
|
+
|
63
|
+
def specfile_name
|
64
|
+
environment.specfile_name
|
65
|
+
end
|
66
|
+
|
67
|
+
def specfile_path
|
68
|
+
environment.specfile_path
|
69
|
+
end
|
70
|
+
|
71
|
+
def lockfile_name
|
72
|
+
environment.lockfile_name
|
73
|
+
end
|
74
|
+
|
75
|
+
def lockfile_path
|
76
|
+
environment.lockfile_path
|
77
|
+
end
|
78
|
+
|
79
|
+
def spec
|
80
|
+
environment.spec
|
81
|
+
end
|
82
|
+
|
83
|
+
def lock
|
84
|
+
environment.lock
|
85
|
+
end
|
86
|
+
|
87
|
+
def spec_change_set(spec, lock)
|
88
|
+
SpecChangeSet.new(environment, spec, lock)
|
89
|
+
end
|
90
|
+
|
91
|
+
def spec_consistent_with_lock?
|
92
|
+
spec_change_set(spec, lock).same?
|
93
|
+
end
|
94
|
+
|
95
|
+
def install_path
|
96
|
+
environment.install_path
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "librarian/error"
|
2
|
+
require "librarian/resolver"
|
3
|
+
require "librarian/spec_change_set"
|
4
|
+
require "librarian/action/base"
|
5
|
+
|
6
|
+
module Librarian
|
7
|
+
module Action
|
8
|
+
class Resolve < Base
|
9
|
+
|
10
|
+
def run
|
11
|
+
if force? || !lockfile_path.exist?
|
12
|
+
spec = specfile.read
|
13
|
+
manifests = []
|
14
|
+
else
|
15
|
+
lock = lockfile.read
|
16
|
+
spec = specfile.read(lock.sources)
|
17
|
+
changes = spec_change_set(spec, lock)
|
18
|
+
if changes.same?
|
19
|
+
debug { "The specfile is unchanged: nothing to do." }
|
20
|
+
return
|
21
|
+
end
|
22
|
+
manifests = changes.analyze
|
23
|
+
end
|
24
|
+
|
25
|
+
resolution = resolver.resolve(spec, manifests)
|
26
|
+
unless resolution.correct?
|
27
|
+
raise Error, "Could not resolve the dependencies."
|
28
|
+
else
|
29
|
+
lockfile_text = lockfile.save(resolution)
|
30
|
+
debug { "Bouncing #{lockfile_name}" }
|
31
|
+
bounced_lockfile_text = lockfile.save(lockfile.load(lockfile_text))
|
32
|
+
unless bounced_lockfile_text == lockfile_text
|
33
|
+
debug { "lockfile_text: \n#{lockfile_text}"}
|
34
|
+
debug { "bounced_lockfile_text: \n#{bounced_lockfile_text}"}
|
35
|
+
raise Error, "Cannot bounce #{lockfile_name}!"
|
36
|
+
end
|
37
|
+
lockfile_path.open('wb') { |f| f.write(lockfile_text) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def force?
|
44
|
+
options[:force]
|
45
|
+
end
|
46
|
+
|
47
|
+
def specfile_name
|
48
|
+
environment.specfile_name
|
49
|
+
end
|
50
|
+
|
51
|
+
def lockfile_name
|
52
|
+
environment.lockfile_name
|
53
|
+
end
|
54
|
+
|
55
|
+
def specfile_path
|
56
|
+
environment.specfile_path
|
57
|
+
end
|
58
|
+
|
59
|
+
def lockfile_path
|
60
|
+
environment.lockfile_path
|
61
|
+
end
|
62
|
+
|
63
|
+
def specfile
|
64
|
+
environment.specfile
|
65
|
+
end
|
66
|
+
|
67
|
+
def lockfile
|
68
|
+
environment.lockfile
|
69
|
+
end
|
70
|
+
|
71
|
+
def resolver
|
72
|
+
Resolver.new(environment)
|
73
|
+
end
|
74
|
+
|
75
|
+
def spec_change_set(spec, lock)
|
76
|
+
SpecChangeSet.new(environment, spec, lock)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|