librarianp 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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.rspec +1 -0
- data/.travis.yml +10 -0
- data/CHANGELOG.md +255 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +235 -0
- data/LICENSE.txt +22 -0
- data/README.md +55 -0
- data/Rakefile +28 -0
- data/VERSION +1 -0
- data/lib/librarian/action/base.rb +24 -0
- data/lib/librarian/action/clean.rb +44 -0
- data/lib/librarian/action/ensure.rb +24 -0
- data/lib/librarian/action/install.rb +95 -0
- data/lib/librarian/action/persist_resolution_mixin.rb +51 -0
- data/lib/librarian/action/resolve.rb +46 -0
- data/lib/librarian/action/update.rb +44 -0
- data/lib/librarian/action.rb +5 -0
- data/lib/librarian/algorithms.rb +133 -0
- data/lib/librarian/cli/manifest_presenter.rb +89 -0
- data/lib/librarian/cli.rb +225 -0
- data/lib/librarian/config/database.rb +205 -0
- data/lib/librarian/config/file_source.rb +47 -0
- data/lib/librarian/config/hash_source.rb +33 -0
- data/lib/librarian/config/source.rb +149 -0
- data/lib/librarian/config.rb +7 -0
- data/lib/librarian/dependency.rb +153 -0
- data/lib/librarian/dsl/receiver.rb +42 -0
- data/lib/librarian/dsl/target.rb +171 -0
- data/lib/librarian/dsl.rb +102 -0
- data/lib/librarian/environment/runtime_cache.rb +101 -0
- data/lib/librarian/environment.rb +230 -0
- data/lib/librarian/error.rb +4 -0
- data/lib/librarian/helpers.rb +29 -0
- data/lib/librarian/linter/source_linter.rb +55 -0
- data/lib/librarian/lockfile/compiler.rb +66 -0
- data/lib/librarian/lockfile/parser.rb +123 -0
- data/lib/librarian/lockfile.rb +29 -0
- data/lib/librarian/logger.rb +46 -0
- data/lib/librarian/manifest.rb +146 -0
- data/lib/librarian/manifest_set.rb +150 -0
- data/lib/librarian/mock/cli.rb +19 -0
- data/lib/librarian/mock/dsl.rb +15 -0
- data/lib/librarian/mock/environment.rb +21 -0
- data/lib/librarian/mock/extension.rb +9 -0
- data/lib/librarian/mock/source/mock/registry.rb +83 -0
- data/lib/librarian/mock/source/mock.rb +80 -0
- data/lib/librarian/mock/source.rb +1 -0
- data/lib/librarian/mock/version.rb +5 -0
- data/lib/librarian/mock.rb +1 -0
- data/lib/librarian/posix.rb +129 -0
- data/lib/librarian/resolution.rb +46 -0
- data/lib/librarian/resolver/implementation.rb +238 -0
- data/lib/librarian/resolver.rb +94 -0
- data/lib/librarian/rspec/support/cli_macro.rb +120 -0
- data/lib/librarian/source/basic_api.rb +45 -0
- data/lib/librarian/source/git/repository.rb +193 -0
- data/lib/librarian/source/git.rb +172 -0
- data/lib/librarian/source/local.rb +54 -0
- data/lib/librarian/source/path.rb +56 -0
- data/lib/librarian/source.rb +2 -0
- data/lib/librarian/spec.rb +13 -0
- data/lib/librarian/spec_change_set.rb +173 -0
- data/lib/librarian/specfile.rb +19 -0
- data/lib/librarian/support/abstract_method.rb +21 -0
- data/lib/librarian/ui.rb +64 -0
- data/lib/librarian/version.rb +3 -0
- data/lib/librarian.rb +11 -0
- data/librarian.gemspec +47 -0
- data/spec/functional/cli_spec.rb +27 -0
- data/spec/functional/posix_spec.rb +32 -0
- data/spec/functional/source/git/repository_spec.rb +199 -0
- data/spec/functional/source/git_spec.rb +174 -0
- data/spec/support/fakefs.rb +37 -0
- data/spec/support/method_patch_macro.rb +30 -0
- data/spec/support/project_path_macro.rb +14 -0
- data/spec/support/with_env_macro.rb +22 -0
- data/spec/unit/action/base_spec.rb +18 -0
- data/spec/unit/action/clean_spec.rb +102 -0
- data/spec/unit/action/ensure_spec.rb +37 -0
- data/spec/unit/action/install_spec.rb +111 -0
- data/spec/unit/algorithms_spec.rb +131 -0
- data/spec/unit/config/database_spec.rb +320 -0
- data/spec/unit/dependency/requirement_spec.rb +12 -0
- data/spec/unit/dependency_spec.rb +212 -0
- data/spec/unit/dsl_spec.rb +173 -0
- data/spec/unit/environment/runtime_cache_spec.rb +73 -0
- data/spec/unit/environment_spec.rb +209 -0
- data/spec/unit/lockfile/parser_spec.rb +162 -0
- data/spec/unit/lockfile_spec.rb +65 -0
- data/spec/unit/manifest/version_spec.rb +11 -0
- data/spec/unit/manifest_set_spec.rb +202 -0
- data/spec/unit/manifest_spec.rb +36 -0
- data/spec/unit/mock/environment_spec.rb +25 -0
- data/spec/unit/mock/source/mock_spec.rb +22 -0
- data/spec/unit/resolver_spec.rb +299 -0
- data/spec/unit/source/git_spec.rb +29 -0
- data/spec/unit/spec_change_set_spec.rb +169 -0
- metadata +257 -0
@@ -0,0 +1,230 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require 'net/http'
|
3
|
+
require "uri"
|
4
|
+
require "etc"
|
5
|
+
|
6
|
+
require "librarian/helpers"
|
7
|
+
require "librarian/support/abstract_method"
|
8
|
+
|
9
|
+
require "librarian/error"
|
10
|
+
require "librarian/config"
|
11
|
+
require "librarian/lockfile"
|
12
|
+
require "librarian/logger"
|
13
|
+
require "librarian/specfile"
|
14
|
+
require "librarian/resolver"
|
15
|
+
require "librarian/dsl"
|
16
|
+
require "librarian/source"
|
17
|
+
require "librarian/version"
|
18
|
+
require "librarian/environment/runtime_cache"
|
19
|
+
|
20
|
+
module Librarian
|
21
|
+
class Environment
|
22
|
+
|
23
|
+
include Support::AbstractMethod
|
24
|
+
|
25
|
+
attr_accessor :ui
|
26
|
+
attr_reader :runtime_cache
|
27
|
+
|
28
|
+
abstract_method :specfile_name, :dsl_class, :install_path
|
29
|
+
|
30
|
+
def initialize(options = { })
|
31
|
+
@pwd = options.fetch(:pwd) { Dir.pwd }
|
32
|
+
@env = options.fetch(:env) { ENV.to_hash }
|
33
|
+
@home = options.fetch(:home) { default_home }
|
34
|
+
@project_path = options[:project_path]
|
35
|
+
@runtime_cache = RuntimeCache.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def logger
|
39
|
+
@logger ||= Logger.new(self)
|
40
|
+
end
|
41
|
+
|
42
|
+
def config_db
|
43
|
+
@config_db ||= begin
|
44
|
+
Config::Database.new(adapter_name,
|
45
|
+
:pwd => @pwd,
|
46
|
+
:env => @env,
|
47
|
+
:home => @home,
|
48
|
+
:project_path => @project_path,
|
49
|
+
:specfile_name => default_specfile_name
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def default_specfile_name
|
55
|
+
@default_specfile_name ||= begin
|
56
|
+
capped = adapter_name.capitalize
|
57
|
+
"#{capped}file"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def project_path
|
62
|
+
config_db.project_path
|
63
|
+
end
|
64
|
+
|
65
|
+
def specfile_name
|
66
|
+
config_db.specfile_name
|
67
|
+
end
|
68
|
+
|
69
|
+
def specfile_path
|
70
|
+
config_db.specfile_path
|
71
|
+
end
|
72
|
+
|
73
|
+
def specfile
|
74
|
+
Specfile.new(self, specfile_path)
|
75
|
+
end
|
76
|
+
|
77
|
+
def adapter_module
|
78
|
+
implementation? or return
|
79
|
+
self.class.name.split("::")[0 ... -1].inject(Object, &:const_get)
|
80
|
+
end
|
81
|
+
|
82
|
+
def adapter_name
|
83
|
+
implementation? or return
|
84
|
+
Helpers.camel_cased_to_dasherized(self.class.name.split("::")[-2])
|
85
|
+
end
|
86
|
+
|
87
|
+
def adapter_version
|
88
|
+
implementation? or return
|
89
|
+
adapter_module::VERSION
|
90
|
+
end
|
91
|
+
|
92
|
+
def lockfile_name
|
93
|
+
config_db.lockfile_name
|
94
|
+
end
|
95
|
+
|
96
|
+
def lockfile_path
|
97
|
+
config_db.lockfile_path
|
98
|
+
end
|
99
|
+
|
100
|
+
def lockfile
|
101
|
+
Lockfile.new(self, lockfile_path)
|
102
|
+
end
|
103
|
+
|
104
|
+
def ephemeral_lockfile
|
105
|
+
Lockfile.new(self, nil)
|
106
|
+
end
|
107
|
+
|
108
|
+
def resolver(options = { })
|
109
|
+
Resolver.new(self, resolver_options.merge(options))
|
110
|
+
end
|
111
|
+
|
112
|
+
def resolver_options
|
113
|
+
{
|
114
|
+
:cyclic => resolver_permit_cyclic_reslutions?,
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
def resolver_permit_cyclic_reslutions?
|
119
|
+
false
|
120
|
+
end
|
121
|
+
|
122
|
+
def tmp_path
|
123
|
+
part = config_db["tmp"] || "tmp"
|
124
|
+
project_path.join(part)
|
125
|
+
end
|
126
|
+
|
127
|
+
def cache_path
|
128
|
+
tmp_path.join("librarian/cache")
|
129
|
+
end
|
130
|
+
|
131
|
+
def scratch_path
|
132
|
+
tmp_path.join("librarian/scratch")
|
133
|
+
end
|
134
|
+
|
135
|
+
def project_relative_path_to(path)
|
136
|
+
Pathname.new(path).relative_path_from(project_path)
|
137
|
+
end
|
138
|
+
|
139
|
+
def spec
|
140
|
+
specfile.read
|
141
|
+
end
|
142
|
+
|
143
|
+
def lock
|
144
|
+
lockfile.read
|
145
|
+
end
|
146
|
+
|
147
|
+
def dsl(*args, &block)
|
148
|
+
dsl_class.run(self, *args, &block)
|
149
|
+
end
|
150
|
+
|
151
|
+
def dsl_class
|
152
|
+
adapter_module::Dsl
|
153
|
+
end
|
154
|
+
|
155
|
+
def version
|
156
|
+
VERSION
|
157
|
+
end
|
158
|
+
|
159
|
+
def config_keys
|
160
|
+
%[
|
161
|
+
]
|
162
|
+
end
|
163
|
+
|
164
|
+
# The HTTP proxy specified in the environment variables:
|
165
|
+
# * HTTP_PROXY
|
166
|
+
# * HTTP_PROXY_USER
|
167
|
+
# * HTTP_PROXY_PASS
|
168
|
+
# Adapted from:
|
169
|
+
# https://github.com/rubygems/rubygems/blob/v1.8.24/lib/rubygems/remote_fetcher.rb#L276-293
|
170
|
+
def http_proxy_uri
|
171
|
+
@http_proxy_uri ||= begin
|
172
|
+
keys = %w( HTTP_PROXY HTTP_PROXY_USER HTTP_PROXY_PASS )
|
173
|
+
env = Hash[ENV.
|
174
|
+
map{|k, v| [k.upcase, v]}.
|
175
|
+
select{|k, v| keys.include?(k)}.
|
176
|
+
reject{|k, v| v.nil? || v.empty?}]
|
177
|
+
|
178
|
+
uri = env["HTTP_PROXY"] or return
|
179
|
+
uri = "http://#{uri}" unless uri =~ /^(https?|ftp|file):/
|
180
|
+
uri = URI.parse(uri)
|
181
|
+
uri.user ||= env["HTTP_PROXY_USER"]
|
182
|
+
uri.password ||= env["HTTP_PROXY_PASS"]
|
183
|
+
uri
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def net_http_class(host)
|
188
|
+
no_proxy?(host) ? Net::HTTP : net_http_default_class
|
189
|
+
end
|
190
|
+
|
191
|
+
def inspect
|
192
|
+
"#<#{self.class}:0x#{__id__.to_s(16)}>"
|
193
|
+
end
|
194
|
+
|
195
|
+
private
|
196
|
+
|
197
|
+
def environment
|
198
|
+
self
|
199
|
+
end
|
200
|
+
|
201
|
+
def implementation?
|
202
|
+
self.class != ::Librarian::Environment
|
203
|
+
end
|
204
|
+
|
205
|
+
def default_home
|
206
|
+
File.expand_path(ENV["HOME"] || Etc.getpwnam(Etc.getlogin).dir)
|
207
|
+
end
|
208
|
+
|
209
|
+
def no_proxy_list
|
210
|
+
@no_proxy_list ||= begin
|
211
|
+
list = ENV['NO_PROXY'] || ENV['no_proxy'] || ""
|
212
|
+
list.split(/\s*,\s*/) + %w(localhost 127.0.0.1)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def no_proxy?(host)
|
217
|
+
no_proxy_list.any? do |host_addr|
|
218
|
+
host.end_with?(host_addr)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def net_http_default_class
|
223
|
+
@net_http_default_class ||= begin
|
224
|
+
p = http_proxy_uri
|
225
|
+
p ? Net::HTTP::Proxy(p.host, p.port, p.user, p.password) : Net::HTTP
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Librarian
|
2
|
+
|
3
|
+
# PRIVATE
|
4
|
+
#
|
5
|
+
# Adapters must not rely on these methods since they will change.
|
6
|
+
#
|
7
|
+
# Adapters requiring similar methods ought to re-implement them.
|
8
|
+
module Helpers
|
9
|
+
extend self
|
10
|
+
|
11
|
+
# [active_support/core_ext/string/strip]
|
12
|
+
def strip_heredoc(string)
|
13
|
+
indent = string.scan(/^[ \t]*(?=\S)/).min
|
14
|
+
indent = indent.respond_to?(:size) ? indent.size : 0
|
15
|
+
string.gsub(/^[ \t]{#{indent}}/, '')
|
16
|
+
end
|
17
|
+
|
18
|
+
# [active_support/inflector/methods]
|
19
|
+
def camel_cased_to_dasherized(camel_cased_word)
|
20
|
+
word = camel_cased_word.to_s.dup
|
21
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1-\2')
|
22
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1-\2')
|
23
|
+
word.downcase!
|
24
|
+
word
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Librarian
|
2
|
+
module Linter
|
3
|
+
class SourceLinter
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def lint!(klass)
|
7
|
+
new(klass).lint!
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_accessor :klass
|
12
|
+
private :klass=
|
13
|
+
|
14
|
+
def initialize(klass)
|
15
|
+
self.klass = klass
|
16
|
+
end
|
17
|
+
|
18
|
+
def lint!
|
19
|
+
lint_class_responds_to! *[
|
20
|
+
:lock_name,
|
21
|
+
:from_spec_args,
|
22
|
+
:from_lock_options,
|
23
|
+
]
|
24
|
+
|
25
|
+
lint_instance_responds_to! *[
|
26
|
+
:to_spec_args,
|
27
|
+
:to_lock_options,
|
28
|
+
:manifests,
|
29
|
+
:fetch_version,
|
30
|
+
:fetch_dependencies,
|
31
|
+
:pinned?,
|
32
|
+
:unpin!,
|
33
|
+
:install!,
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def lint_class_responds_to!(*names)
|
40
|
+
missing = names.reject{|name| klass.respond_to?(name)}
|
41
|
+
return if missing.empty?
|
42
|
+
|
43
|
+
raise "class must respond to #{missing.join(', ')}"
|
44
|
+
end
|
45
|
+
|
46
|
+
def lint_instance_responds_to!(*names)
|
47
|
+
missing = names - klass.public_instance_methods.map(&:to_sym)
|
48
|
+
return if missing.empty?
|
49
|
+
|
50
|
+
raise "instance must respond to #{missing.join(', ')}"
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Librarian
|
2
|
+
class Lockfile
|
3
|
+
class Compiler
|
4
|
+
|
5
|
+
attr_accessor :environment
|
6
|
+
private :environment=
|
7
|
+
|
8
|
+
def initialize(environment)
|
9
|
+
self.environment = environment
|
10
|
+
end
|
11
|
+
|
12
|
+
def compile(resolution)
|
13
|
+
out = StringIO.new
|
14
|
+
save_sources(out, resolution.manifests)
|
15
|
+
save_dependencies(out, resolution.dependencies)
|
16
|
+
out.string
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def save_sources(out, manifests)
|
22
|
+
dsl_class.source_types.map{|t| t[1]}.each do |type|
|
23
|
+
type_manifests = manifests.select{|m| type === m.source}
|
24
|
+
sources = type_manifests.map{|m| m.source}.uniq.sort_by{|s| s.to_s}
|
25
|
+
sources.each do |source|
|
26
|
+
source_manifests = type_manifests.select{|m| source == m.source}
|
27
|
+
save_source(out, source, source_manifests)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def save_source(out, source, manifests)
|
33
|
+
out.puts "#{source.class.lock_name}"
|
34
|
+
options = source.to_lock_options
|
35
|
+
remote = options.delete(:remote)
|
36
|
+
out.puts " remote: #{remote}"
|
37
|
+
options.to_a.sort_by{|a| a[0].to_s}.each do |o|
|
38
|
+
out.puts " #{o[0]}: #{o[1]}"
|
39
|
+
end
|
40
|
+
out.puts " specs:"
|
41
|
+
manifests.sort_by{|a| a.name}.each do |manifest|
|
42
|
+
out.puts " #{manifest.name} (#{manifest.version})"
|
43
|
+
manifest.dependencies.sort_by{|a| a.name}.each do |dependency|
|
44
|
+
out.puts " #{dependency.name} (#{dependency.requirement})"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
out.puts ""
|
48
|
+
end
|
49
|
+
|
50
|
+
def save_dependencies(out, dependencies)
|
51
|
+
out.puts "DEPENDENCIES"
|
52
|
+
dependencies.sort_by{|a| a.name}.each do |d|
|
53
|
+
res = "#{d.name}"
|
54
|
+
res << " (#{d.requirement})" if d.requirement
|
55
|
+
out.puts " #{res}"
|
56
|
+
end
|
57
|
+
out.puts ""
|
58
|
+
end
|
59
|
+
|
60
|
+
def dsl_class
|
61
|
+
environment.dsl_class
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'librarian/manifest'
|
2
|
+
require 'librarian/dependency'
|
3
|
+
require 'librarian/manifest_set'
|
4
|
+
|
5
|
+
module Librarian
|
6
|
+
class Lockfile
|
7
|
+
class Parser
|
8
|
+
|
9
|
+
class ManifestPlaceholder
|
10
|
+
attr_reader :source, :name, :version, :dependencies
|
11
|
+
def initialize(source, name, version, dependencies)
|
12
|
+
@source, @name, @version, @dependencies = source, name, version, dependencies
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :environment
|
17
|
+
private :environment=
|
18
|
+
|
19
|
+
def initialize(environment)
|
20
|
+
self.environment = environment
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse(string)
|
24
|
+
lines = string.lines.map{|l| l.sub(/\s+\z/, '')}.reject(&:empty?)
|
25
|
+
sources = extract_and_parse_sources(lines)
|
26
|
+
manifests = compile(sources)
|
27
|
+
manifests_index = Hash[manifests.map{|m| [m.name, m]}]
|
28
|
+
raise StandardError, "Expected DEPENDENCIES topic!" unless lines.shift == "DEPENDENCIES"
|
29
|
+
dependencies = extract_and_parse_dependencies(lines, manifests_index)
|
30
|
+
Resolution.new(dependencies, manifests)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def extract_and_parse_sources(lines)
|
36
|
+
sources = []
|
37
|
+
while source_type_names.include?(lines.first)
|
38
|
+
source = {}
|
39
|
+
source_type_name = lines.shift
|
40
|
+
source[:type] = source_type_names_map[source_type_name]
|
41
|
+
options = {}
|
42
|
+
while lines.first =~ /^ {2}([\w-]+):\s+(.+)$/
|
43
|
+
lines.shift
|
44
|
+
options[$1.to_sym] = $2
|
45
|
+
end
|
46
|
+
source[:options] = options
|
47
|
+
lines.shift # specs
|
48
|
+
manifests = {}
|
49
|
+
while lines.first =~ /^ {4}([\w-]+) \((.*)\)$/
|
50
|
+
lines.shift
|
51
|
+
name = $1
|
52
|
+
manifests[name] = {:version => $2, :dependencies => {}}
|
53
|
+
while lines.first =~ /^ {6}([\w-]+) \((.*)\)$/
|
54
|
+
lines.shift
|
55
|
+
manifests[name][:dependencies][$1] = $2.split(/,\s*/)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
source[:manifests] = manifests
|
59
|
+
sources << source
|
60
|
+
end
|
61
|
+
sources
|
62
|
+
end
|
63
|
+
|
64
|
+
def extract_and_parse_dependencies(lines, manifests_index)
|
65
|
+
dependencies = []
|
66
|
+
while lines.first =~ /^ {2}([\w-]+)(?: \((.*)\))?$/
|
67
|
+
lines.shift
|
68
|
+
name, requirement = $1, $2.split(/,\s*/)
|
69
|
+
dependencies << Dependency.new(name, requirement, manifests_index[name].source)
|
70
|
+
end
|
71
|
+
dependencies
|
72
|
+
end
|
73
|
+
|
74
|
+
def compile_placeholder_manifests(sources_ast)
|
75
|
+
manifests = {}
|
76
|
+
sources_ast.each do |source_ast|
|
77
|
+
source_type = source_ast[:type]
|
78
|
+
source = source_type.from_lock_options(environment, source_ast[:options])
|
79
|
+
source_ast[:manifests].each do |manifest_name, manifest_ast|
|
80
|
+
manifests[manifest_name] = ManifestPlaceholder.new(
|
81
|
+
source,
|
82
|
+
manifest_name,
|
83
|
+
manifest_ast[:version],
|
84
|
+
manifest_ast[:dependencies].map{|k, v| Dependency.new(k, v, nil)}
|
85
|
+
)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
manifests
|
89
|
+
end
|
90
|
+
|
91
|
+
def compile(sources_ast)
|
92
|
+
manifests = compile_placeholder_manifests(sources_ast)
|
93
|
+
manifests = manifests.map do |name, manifest|
|
94
|
+
dependencies = manifest.dependencies.map do |d|
|
95
|
+
Dependency.new(d.name, d.requirement, manifests[d.name].source)
|
96
|
+
end
|
97
|
+
real = Manifest.new(manifest.source, manifest.name)
|
98
|
+
real.version = manifest.version
|
99
|
+
real.dependencies = manifest.dependencies
|
100
|
+
real
|
101
|
+
end
|
102
|
+
ManifestSet.sort(manifests)
|
103
|
+
end
|
104
|
+
|
105
|
+
def dsl_class
|
106
|
+
environment.dsl_class
|
107
|
+
end
|
108
|
+
|
109
|
+
def source_type_names_map
|
110
|
+
@source_type_names_map ||= begin
|
111
|
+
Hash[dsl_class.source_types.map{|t| [t[1].lock_name, t[1]]}]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def source_type_names
|
116
|
+
@source_type_names ||= begin
|
117
|
+
dsl_class.source_types.map{|t| t[1].lock_name}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'librarian/lockfile/compiler'
|
2
|
+
require 'librarian/lockfile/parser'
|
3
|
+
|
4
|
+
module Librarian
|
5
|
+
class Lockfile
|
6
|
+
|
7
|
+
attr_accessor :environment
|
8
|
+
private :environment=
|
9
|
+
attr_reader :path
|
10
|
+
|
11
|
+
def initialize(environment, path)
|
12
|
+
self.environment = environment
|
13
|
+
@path = path
|
14
|
+
end
|
15
|
+
|
16
|
+
def save(resolution)
|
17
|
+
Compiler.new(environment).compile(resolution)
|
18
|
+
end
|
19
|
+
|
20
|
+
def load(string)
|
21
|
+
Parser.new(environment).parse(string)
|
22
|
+
end
|
23
|
+
|
24
|
+
def read
|
25
|
+
load(path.read)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Librarian
|
2
|
+
class Logger
|
3
|
+
|
4
|
+
librarian_path = Pathname(__FILE__)
|
5
|
+
librarian_path = librarian_path.dirname until librarian_path.join("lib").directory?
|
6
|
+
LIBRARIAN_PATH = librarian_path
|
7
|
+
|
8
|
+
attr_accessor :environment
|
9
|
+
private :environment=
|
10
|
+
|
11
|
+
def initialize(environment)
|
12
|
+
self.environment = environment
|
13
|
+
end
|
14
|
+
|
15
|
+
def info(string = nil, &block)
|
16
|
+
return unless ui
|
17
|
+
|
18
|
+
ui.info(string || yield)
|
19
|
+
end
|
20
|
+
|
21
|
+
def debug(string = nil, &block)
|
22
|
+
return unless ui
|
23
|
+
|
24
|
+
if ui.respond_to?(:debug_line_numbers) && ui.debug_line_numbers
|
25
|
+
loc = caller.find{|l| !(l =~ /in `debug'$/)}
|
26
|
+
if loc =~ /^(.+):(\d+):in `(.+)'$/
|
27
|
+
loc = "#{Pathname.new($1).relative_path_from(LIBRARIAN_PATH)}:#{$2}:in `#{$3}'"
|
28
|
+
end
|
29
|
+
ui.debug { "[Librarian] #{string || yield} [#{loc}]" }
|
30
|
+
else
|
31
|
+
ui.debug { "[Librarian] #{string || yield}" }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def relative_path_to(path)
|
36
|
+
environment.project_relative_path_to(path)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def ui
|
42
|
+
environment.ui
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|