librarian 0.0.20 → 0.0.21
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/.travis.yml +1 -0
- data/CHANGELOG.md +16 -0
- data/README.md +25 -18
- data/features/chef/cli/show.feature +65 -0
- data/features/support/env.rb +5 -1
- data/lib/librarian/action/clean.rb +0 -12
- data/lib/librarian/action/install.rb +1 -1
- data/lib/librarian/chef/manifest_reader.rb +47 -0
- data/lib/librarian/chef/source/local.rb +51 -3
- data/lib/librarian/chef/source/site.rb +318 -109
- data/lib/librarian/cli.rb +24 -9
- data/lib/librarian/cli/manifest_presenter.rb +79 -0
- data/lib/librarian/dependency.rb +2 -2
- data/lib/librarian/dsl/target.rb +1 -1
- data/lib/librarian/environment.rb +4 -3
- data/lib/librarian/manifest.rb +38 -24
- data/lib/librarian/manifest_set.rb +36 -20
- data/lib/librarian/mock/source/mock.rb +33 -21
- data/lib/librarian/resolution.rb +11 -0
- data/lib/librarian/source/git.rb +14 -2
- data/lib/librarian/source/git/repository.rb +79 -58
- data/lib/librarian/source/local.rb +19 -5
- data/lib/librarian/source/path.rb +13 -1
- data/lib/librarian/specfile.rb +1 -1
- data/lib/librarian/version.rb +1 -1
- data/librarian.gemspec +1 -1
- data/spec/unit/action/clean_spec.rb +0 -31
- data/spec/unit/action/install_spec.rb +7 -3
- data/spec/unit/dsl_spec.rb +14 -0
- data/spec/unit/manifest_set_spec.rb +202 -0
- data/spec/unit/resolver_spec.rb +36 -16
- data/spec/unit/source/git_spec.rb +29 -0
- metadata +28 -25
- data/lib/librarian/chef/manifest.rb +0 -43
- data/lib/librarian/chef/source/local/manifest.rb +0 -82
- data/lib/librarian/chef/source/site/manifest.rb +0 -94
data/lib/librarian/cli.rb
CHANGED
@@ -9,6 +9,8 @@ require "librarian/ui"
|
|
9
9
|
module Librarian
|
10
10
|
class Cli < Thor
|
11
11
|
|
12
|
+
autoload :ManifestPresenter, "librarian/cli/manifest_presenter"
|
13
|
+
|
12
14
|
include Thor::Actions
|
13
15
|
|
14
16
|
module Particularity
|
@@ -50,17 +52,17 @@ module Librarian
|
|
50
52
|
end
|
51
53
|
|
52
54
|
desc "clean", "Cleans out the cache and install paths."
|
53
|
-
|
54
|
-
|
55
|
+
option "verbose"
|
56
|
+
option "line-numbers"
|
55
57
|
def clean
|
56
58
|
ensure!
|
57
59
|
clean!
|
58
60
|
end
|
59
61
|
|
60
62
|
desc "install", "Resolves and installs all of the dependencies you specify."
|
61
|
-
|
62
|
-
|
63
|
-
|
63
|
+
option "verbose"
|
64
|
+
option "line-numbers"
|
65
|
+
option "clean"
|
64
66
|
def install
|
65
67
|
ensure!
|
66
68
|
clean! if options["clean"]
|
@@ -69,8 +71,8 @@ module Librarian
|
|
69
71
|
end
|
70
72
|
|
71
73
|
desc "update", "Updates and installs the dependencies you specify."
|
72
|
-
|
73
|
-
|
74
|
+
option "verbose"
|
75
|
+
option "line-numbers"
|
74
76
|
def update(*names)
|
75
77
|
ensure!
|
76
78
|
if names.empty?
|
@@ -82,8 +84,8 @@ module Librarian
|
|
82
84
|
end
|
83
85
|
|
84
86
|
desc "outdated", "Lists outdated dependencies."
|
85
|
-
|
86
|
-
|
87
|
+
option "verbose"
|
88
|
+
option "line-numbers"
|
87
89
|
def outdated
|
88
90
|
ensure!
|
89
91
|
resolution = environment.lock
|
@@ -96,6 +98,15 @@ module Librarian
|
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
101
|
+
desc "show", "Shows dependencies"
|
102
|
+
option "verbose"
|
103
|
+
option "line-numbers"
|
104
|
+
option "detailed", :type => :boolean
|
105
|
+
def show(*names)
|
106
|
+
ensure!
|
107
|
+
manifest_presenter.present(names, :detailed => options["detailed"])
|
108
|
+
end
|
109
|
+
|
99
110
|
desc "init", "Initializes the current directory."
|
100
111
|
def init
|
101
112
|
puts "Nothing to do."
|
@@ -127,5 +138,9 @@ module Librarian
|
|
127
138
|
Action::Update.new(environment, options).run
|
128
139
|
end
|
129
140
|
|
141
|
+
def manifest_presenter
|
142
|
+
ManifestPresenter.new(self, environment.lock.manifests)
|
143
|
+
end
|
144
|
+
|
130
145
|
end
|
131
146
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Librarian
|
2
|
+
class Cli
|
3
|
+
class ManifestPresenter
|
4
|
+
|
5
|
+
attr_accessor :cli, :manifests
|
6
|
+
private :cli=, :manifests=
|
7
|
+
|
8
|
+
def initialize(cli, manifests)
|
9
|
+
self.cli = cli or raise ArgumentError, "cli required"
|
10
|
+
self.manifests = manifests or raise ArgumentError, "manifests required"
|
11
|
+
self.manifests_index = Hash[manifests.map{|m| [m.name, m]}]
|
12
|
+
|
13
|
+
self.scope_level = 0
|
14
|
+
end
|
15
|
+
|
16
|
+
def present(names = [], options = { })
|
17
|
+
full = options[:detailed]
|
18
|
+
full = !names.empty? if full.nil?
|
19
|
+
|
20
|
+
if names.empty?
|
21
|
+
names = manifests.map(&:name).sort if names.empty?
|
22
|
+
else
|
23
|
+
missing_names = names.reject{|name| manifest(name)}
|
24
|
+
unless missing_names.empty?
|
25
|
+
raise Error, "not found: #{missing_names.map(&:inspect).join(', ')}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
names.each do |name|
|
30
|
+
manifest = manifest(name)
|
31
|
+
present_one(manifest, :detailed => full)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def present_one(manifest, options = { })
|
36
|
+
full = options[:detailed]
|
37
|
+
|
38
|
+
say "#{manifest.name} (#{manifest.version})" do
|
39
|
+
if full
|
40
|
+
say "source: #{manifest.source}"
|
41
|
+
unless manifest.dependencies.empty?
|
42
|
+
say "dependencies:" do
|
43
|
+
manifest.dependencies.sort_by(&:name).each do |dependency|
|
44
|
+
say "#{dependency.name} (#{dependency.requirement})"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
attr_accessor :scope_level, :manifests_index
|
55
|
+
|
56
|
+
def manifest(name)
|
57
|
+
manifests_index[name]
|
58
|
+
end
|
59
|
+
|
60
|
+
def say(string)
|
61
|
+
cli.say " " * scope_level << string
|
62
|
+
if block_given?
|
63
|
+
scope do
|
64
|
+
yield
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def scope
|
70
|
+
original_scope_level = scope_level
|
71
|
+
self.scope_level = scope_level + 1
|
72
|
+
yield
|
73
|
+
ensure
|
74
|
+
self.scope_level = original_scope_level
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/librarian/dependency.rb
CHANGED
data/lib/librarian/dsl/target.rb
CHANGED
@@ -146,7 +146,7 @@ module Librarian
|
|
146
146
|
def source_from_params(name, param, options)
|
147
147
|
source_cache[[name, param, options]] ||= begin
|
148
148
|
type = source_types_map[name]
|
149
|
-
type.
|
149
|
+
type.from_spec_args(environment, param, options)
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
@@ -8,6 +8,7 @@ require "librarian/lockfile"
|
|
8
8
|
require "librarian/specfile"
|
9
9
|
require "librarian/resolver"
|
10
10
|
require "librarian/dsl"
|
11
|
+
require "librarian/source"
|
11
12
|
|
12
13
|
module Librarian
|
13
14
|
class Environment
|
@@ -106,12 +107,12 @@ module Librarian
|
|
106
107
|
lockfile.read
|
107
108
|
end
|
108
109
|
|
109
|
-
def dsl(&block)
|
110
|
-
dsl_class.run(self, &block)
|
110
|
+
def dsl(*args, &block)
|
111
|
+
dsl_class.run(self, *args, &block)
|
111
112
|
end
|
112
113
|
|
113
114
|
def dsl_class
|
114
|
-
self.class.name.split("::")[0 ... -1].inject(Object
|
115
|
+
self.class.name.split("::")[0 ... -1].inject(Object, &:const_get)::Dsl
|
115
116
|
end
|
116
117
|
|
117
118
|
private
|
data/lib/librarian/manifest.rb
CHANGED
@@ -42,22 +42,17 @@ module Librarian
|
|
42
42
|
include Support::AbstractMethod
|
43
43
|
include Helpers::Debug
|
44
44
|
|
45
|
-
attr_accessor :source, :name
|
46
|
-
private :source=, :name=
|
45
|
+
attr_accessor :source, :name, :extra
|
46
|
+
private :source=, :name=, :extra=
|
47
47
|
|
48
48
|
abstract_method :fetch_version!, :fetch_dependencies!
|
49
|
-
abstract_method :install!
|
50
49
|
|
51
|
-
def initialize(source, name)
|
50
|
+
def initialize(source, name, extra = nil)
|
52
51
|
assert_name_valid! name
|
53
52
|
|
54
53
|
self.source = source
|
55
54
|
self.name = name
|
56
|
-
|
57
|
-
@fetched_version = nil
|
58
|
-
@defined_version = nil
|
59
|
-
@fetched_dependencies = nil
|
60
|
-
@defined_dependencies = nil
|
55
|
+
self.extra = extra
|
61
56
|
end
|
62
57
|
|
63
58
|
def to_s
|
@@ -65,35 +60,32 @@ module Librarian
|
|
65
60
|
end
|
66
61
|
|
67
62
|
def version
|
68
|
-
|
63
|
+
defined_version || fetched_version
|
69
64
|
end
|
70
65
|
|
71
66
|
def version=(version)
|
72
|
-
|
67
|
+
self.defined_version = _normalize_version(version)
|
73
68
|
end
|
74
69
|
|
75
70
|
def version?
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
71
|
+
return unless defined_version
|
72
|
+
|
73
|
+
defined_version == fetched_version
|
80
74
|
end
|
81
75
|
|
82
76
|
def dependencies
|
83
|
-
|
77
|
+
defined_dependencies || fetched_dependencies
|
84
78
|
end
|
85
79
|
|
86
80
|
def dependencies=(dependencies)
|
87
|
-
|
81
|
+
self.defined_dependencies = _normalize_dependencies(dependencies)
|
88
82
|
end
|
89
83
|
|
90
84
|
def dependencies?
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
a.name == b.name && a.requirement == b.requirement
|
96
|
-
end
|
85
|
+
return unless defined_dependencies
|
86
|
+
|
87
|
+
defined_dependencies.zip(fetched_dependencies).all? do |(a, b)|
|
88
|
+
a.name == b.name && a.requirement == b.requirement
|
97
89
|
end
|
98
90
|
end
|
99
91
|
|
@@ -101,12 +93,34 @@ module Librarian
|
|
101
93
|
dependency.requirement.satisfied_by?(version)
|
102
94
|
end
|
103
95
|
|
96
|
+
def install!
|
97
|
+
source.install!(self)
|
98
|
+
end
|
99
|
+
|
104
100
|
private
|
105
101
|
|
102
|
+
attr_accessor :defined_version, :defined_dependencies
|
103
|
+
|
106
104
|
def environment
|
107
105
|
source.environment
|
108
106
|
end
|
109
107
|
|
108
|
+
def fetched_version
|
109
|
+
@fetched_version ||= _normalize_version(fetch_version!)
|
110
|
+
end
|
111
|
+
|
112
|
+
def fetched_dependencies
|
113
|
+
@fetched_dependencies ||= _normalize_dependencies(fetch_dependencies!)
|
114
|
+
end
|
115
|
+
|
116
|
+
def fetch_version!
|
117
|
+
source.fetch_version(name, extra)
|
118
|
+
end
|
119
|
+
|
120
|
+
def fetch_dependencies!
|
121
|
+
source.fetch_dependencies(name, version, extra)
|
122
|
+
end
|
123
|
+
|
110
124
|
def _normalize_version(version)
|
111
125
|
Version.new(version)
|
112
126
|
end
|
@@ -115,7 +129,7 @@ module Librarian
|
|
115
129
|
if Hash === dependencies
|
116
130
|
dependencies = dependencies.map{|k, v| Dependency.new(k, v, nil)}
|
117
131
|
end
|
118
|
-
dependencies.sort_by
|
132
|
+
dependencies.sort_by(&:name)
|
119
133
|
end
|
120
134
|
|
121
135
|
def assert_name_valid!(name)
|
@@ -63,6 +63,8 @@ module Librarian
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def shallow_strip!(names)
|
66
|
+
assert_strings!(names)
|
67
|
+
|
66
68
|
names.each do |name|
|
67
69
|
index.delete(name)
|
68
70
|
end
|
@@ -75,15 +77,11 @@ module Librarian
|
|
75
77
|
|
76
78
|
def deep_strip!(names)
|
77
79
|
names = Array === names ? names.dup : names.to_a
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
names << dependency.name
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
80
|
+
assert_strings!(names)
|
81
|
+
|
82
|
+
strippables = dependencies_of(names)
|
83
|
+
shallow_strip!(strippables)
|
84
|
+
|
87
85
|
self
|
88
86
|
end
|
89
87
|
|
@@ -92,6 +90,8 @@ module Librarian
|
|
92
90
|
end
|
93
91
|
|
94
92
|
def shallow_keep!(names)
|
93
|
+
assert_strings!(names)
|
94
|
+
|
95
95
|
names = Set.new(names) unless Set === names
|
96
96
|
index.reject! { |k, v| !names.include?(k) }
|
97
97
|
self
|
@@ -103,17 +103,12 @@ module Librarian
|
|
103
103
|
|
104
104
|
def deep_keep!(names)
|
105
105
|
names = Array === names ? names.dup : names.to_a
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
names << d.name
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
shallow_keep!(marks)
|
106
|
+
assert_strings!(names)
|
107
|
+
|
108
|
+
keepables = dependencies_of(names)
|
109
|
+
shallow_keep!(keepables)
|
110
|
+
|
111
|
+
self
|
117
112
|
end
|
118
113
|
|
119
114
|
def consistent?
|
@@ -129,5 +124,26 @@ module Librarian
|
|
129
124
|
|
130
125
|
attr_accessor :index
|
131
126
|
|
127
|
+
def assert_strings!(names)
|
128
|
+
non_strings = names.reject{|name| String === name}
|
129
|
+
non_strings.empty? or raise TypeError, "names must all be strings"
|
130
|
+
end
|
131
|
+
|
132
|
+
# Straightforward breadth-first graph traversal algorithm.
|
133
|
+
def dependencies_of(names)
|
134
|
+
names = Array === names ? names.dup : names.to_a
|
135
|
+
assert_strings!(names)
|
136
|
+
|
137
|
+
deps = Set.new
|
138
|
+
until names.empty?
|
139
|
+
name = names.shift
|
140
|
+
next if deps.include?(name)
|
141
|
+
|
142
|
+
deps << name
|
143
|
+
names.concat index[name].dependencies.map(&:name)
|
144
|
+
end
|
145
|
+
deps.to_a
|
146
|
+
end
|
147
|
+
|
132
148
|
end
|
133
149
|
end
|
@@ -6,30 +6,26 @@ module Librarian
|
|
6
6
|
module Source
|
7
7
|
class Mock
|
8
8
|
|
9
|
-
class Manifest < Manifest
|
10
|
-
attr_reader :manifest
|
11
|
-
def initialize(source, name, manifest)
|
12
|
-
super(source, name)
|
13
|
-
@manifest = manifest
|
14
|
-
end
|
15
|
-
def fetch_version!
|
16
|
-
manifest[:version]
|
17
|
-
end
|
18
|
-
def fetch_dependencies!
|
19
|
-
manifest[:dependencies]
|
20
|
-
end
|
21
|
-
def install!
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
9
|
class << self
|
10
|
+
|
26
11
|
LOCK_NAME = 'MOCK'
|
12
|
+
|
27
13
|
def lock_name
|
28
14
|
LOCK_NAME
|
29
15
|
end
|
16
|
+
|
30
17
|
def from_lock_options(environment, options)
|
31
18
|
new(environment, options[:remote], options.reject{|k, v| k == :remote})
|
32
19
|
end
|
20
|
+
|
21
|
+
def from_spec_args(environment, name, options)
|
22
|
+
recognized_options = []
|
23
|
+
unrecognized_options = options.keys - recognized_options
|
24
|
+
unrecognized_options.empty? or raise Error, "unrecognized options: #{unrecognized_options.join(", ")}"
|
25
|
+
|
26
|
+
new(environment, name, options)
|
27
|
+
end
|
28
|
+
|
33
29
|
end
|
34
30
|
|
35
31
|
attr_accessor :environment
|
@@ -64,24 +60,40 @@ module Librarian
|
|
64
60
|
end
|
65
61
|
|
66
62
|
def manifest(name, version, dependencies)
|
67
|
-
Manifest.new(self, name
|
63
|
+
manifest = Manifest.new(self, name)
|
64
|
+
manifest.version = version
|
65
|
+
manifest.dependencies = dependencies
|
66
|
+
manifest
|
68
67
|
end
|
69
68
|
|
70
|
-
def manifests(
|
71
|
-
if d = registry[
|
72
|
-
d.map{|v|
|
69
|
+
def manifests(name)
|
70
|
+
if d = registry[name]
|
71
|
+
d.map{|v| manifest(name, v[:version], v[:dependencies])}
|
73
72
|
else
|
74
73
|
nil
|
75
74
|
end
|
76
75
|
end
|
77
76
|
|
78
|
-
def cache!(
|
77
|
+
def cache!(names)
|
78
|
+
end
|
79
|
+
|
80
|
+
def install!(manifest)
|
79
81
|
end
|
80
82
|
|
81
83
|
def to_s
|
82
84
|
name
|
83
85
|
end
|
84
86
|
|
87
|
+
def fetch_version(name, extra)
|
88
|
+
extra
|
89
|
+
end
|
90
|
+
|
91
|
+
def fetch_dependencies(name, version, extra)
|
92
|
+
d = registry[name]
|
93
|
+
m = d.find{|v| v[:version] == version.to_s}
|
94
|
+
m[:dependencies]
|
95
|
+
end
|
96
|
+
|
85
97
|
end
|
86
98
|
end
|
87
99
|
end
|