autoproj 2.0.0.rc37 → 2.0.0.rc38
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 +4 -4
- data/.travis.yml +4 -2
- data/Rakefile +1 -1
- data/bin/autoproj_bootstrap +34 -2
- data/bin/autoproj_bootstrap.in +4 -2
- data/bin/autoproj_install +34 -2
- data/bin/autoproj_install.in +4 -2
- data/lib/autoproj.rb +9 -2
- data/lib/autoproj/autobuild.rb +13 -742
- data/lib/autoproj/autobuild_extensions/archive_importer.rb +44 -0
- data/lib/autoproj/autobuild_extensions/dsl.rb +439 -0
- data/lib/autoproj/autobuild_extensions/git.rb +116 -0
- data/lib/autoproj/autobuild_extensions/package.rb +159 -0
- data/lib/autoproj/autobuild_extensions/svn.rb +11 -0
- data/lib/autoproj/cli/base.rb +17 -18
- data/lib/autoproj/cli/clean.rb +1 -2
- data/lib/autoproj/cli/envsh.rb +1 -2
- data/lib/autoproj/cli/inspection_tool.rb +12 -21
- data/lib/autoproj/cli/locate.rb +130 -73
- data/lib/autoproj/cli/main.rb +31 -5
- data/lib/autoproj/cli/main_plugin.rb +79 -0
- data/lib/autoproj/cli/main_test.rb +19 -5
- data/lib/autoproj/cli/osdeps.rb +1 -2
- data/lib/autoproj/cli/patcher.rb +21 -0
- data/lib/autoproj/cli/query.rb +34 -41
- data/lib/autoproj/cli/show.rb +121 -52
- data/lib/autoproj/cli/status.rb +4 -5
- data/lib/autoproj/cli/tag.rb +1 -1
- data/lib/autoproj/cli/test.rb +7 -6
- data/lib/autoproj/cli/update.rb +8 -22
- data/lib/autoproj/cli/versions.rb +1 -2
- data/lib/autoproj/configuration.rb +1 -1
- data/lib/autoproj/environment.rb +2 -7
- data/lib/autoproj/exceptions.rb +10 -8
- data/lib/autoproj/find_workspace.rb +46 -12
- data/lib/autoproj/installation_manifest.rb +34 -25
- data/lib/autoproj/local_package_set.rb +86 -0
- data/lib/autoproj/manifest.rb +448 -503
- data/lib/autoproj/metapackage.rb +31 -5
- data/lib/autoproj/ops/configuration.rb +46 -45
- data/lib/autoproj/ops/import.rb +150 -60
- data/lib/autoproj/ops/install.rb +25 -1
- data/lib/autoproj/ops/loader.rb +4 -1
- data/lib/autoproj/ops/main_config_switcher.rb +4 -4
- data/lib/autoproj/ops/snapshot.rb +4 -3
- data/lib/autoproj/os_package_installer.rb +105 -46
- data/lib/autoproj/os_package_resolver.rb +63 -36
- data/lib/autoproj/package_definition.rb +1 -0
- data/lib/autoproj/package_managers/apt_dpkg_manager.rb +30 -27
- data/lib/autoproj/package_managers/bundler_manager.rb +64 -18
- data/lib/autoproj/package_managers/gem_manager.rb +4 -2
- data/lib/autoproj/package_managers/manager.rb +26 -7
- data/lib/autoproj/package_managers/shell_script_manager.rb +4 -4
- data/lib/autoproj/package_managers/zypper_manager.rb +1 -1
- data/lib/autoproj/package_manifest.rb +154 -137
- data/lib/autoproj/package_selection.rb +16 -2
- data/lib/autoproj/package_set.rb +352 -309
- data/lib/autoproj/query.rb +13 -1
- data/lib/autoproj/system.rb +2 -2
- data/lib/autoproj/test.rb +164 -11
- data/lib/autoproj/variable_expansion.rb +15 -42
- data/lib/autoproj/vcs_definition.rb +93 -76
- data/lib/autoproj/version.rb +1 -1
- data/lib/autoproj/workspace.rb +116 -80
- metadata +10 -2
data/lib/autoproj/query.rb
CHANGED
@@ -54,6 +54,14 @@ class Query
|
|
54
54
|
attr_predicate :use_dir_prefix?
|
55
55
|
attr_predicate :partial?
|
56
56
|
|
57
|
+
class All
|
58
|
+
def match(pkg); true end
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.all
|
62
|
+
All.new
|
63
|
+
end
|
64
|
+
|
57
65
|
def initialize(fields, value, partial)
|
58
66
|
@fields = fields
|
59
67
|
@value = value
|
@@ -158,7 +166,11 @@ def self.parse_query(query)
|
|
158
166
|
Query.parse(str)
|
159
167
|
end
|
160
168
|
end
|
161
|
-
|
169
|
+
if query.size == 1
|
170
|
+
query.first
|
171
|
+
else
|
172
|
+
And.new(query)
|
173
|
+
end
|
162
174
|
end
|
163
175
|
|
164
176
|
# Match object that combines multiple matches using a logical OR
|
data/lib/autoproj/system.rb
CHANGED
@@ -112,8 +112,8 @@ def self.run_as_user(*args)
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
# Run the provided command as root, using sudo to gain root access
|
115
|
-
def self.run_as_root(*args)
|
116
|
-
if !system(Autobuild.tool_in_path('sudo'), *args)
|
115
|
+
def self.run_as_root(*args, env: self.workspace.env)
|
116
|
+
if !system(Autobuild.tool_in_path('sudo', env: env), *args)
|
117
117
|
raise "failed to run #{args.join(" ")} as root"
|
118
118
|
end
|
119
119
|
end
|
data/lib/autoproj/test.rb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
begin
|
5
5
|
require 'simplecov'
|
6
6
|
SimpleCov.start do
|
7
|
+
command_name 'master'
|
7
8
|
add_filter "/test/"
|
8
9
|
end
|
9
10
|
rescue LoadError
|
@@ -18,6 +19,7 @@
|
|
18
19
|
require 'minitest/autorun'
|
19
20
|
require 'autoproj'
|
20
21
|
require 'flexmock/minitest'
|
22
|
+
FlexMock.partials_are_based = true
|
21
23
|
require 'minitest/spec'
|
22
24
|
|
23
25
|
if ENV['TEST_ENABLE_PRY'] != '0'
|
@@ -40,15 +42,27 @@ module Autoproj
|
|
40
42
|
# end
|
41
43
|
#
|
42
44
|
module SelfTest
|
45
|
+
# Define package managers for the next workspace created by {#ws_create}
|
46
|
+
#
|
47
|
+
# Use {#ws_define_package_manager}
|
48
|
+
#
|
49
|
+
# Two package managers called 'os' and 'os_indep' are always created,
|
50
|
+
# 'os' is used as the os package manager.
|
51
|
+
#
|
52
|
+
# @return [Hash<String,PackageManagers::Manager>]
|
53
|
+
attr_reader :ws_package_managers
|
54
|
+
# The workspace created by the last call to #ws_create
|
43
55
|
attr_reader :ws
|
44
56
|
|
45
57
|
def setup
|
58
|
+
FileUtils.rm_rf fixture_gem_home
|
46
59
|
@gem_server_pid = nil
|
47
60
|
@tmpdir = Array.new
|
48
|
-
@ws =
|
49
|
-
|
50
|
-
|
51
|
-
|
61
|
+
@ws = nil
|
62
|
+
@ws_package_managers = Hash.new
|
63
|
+
Autobuild.logdir = make_tmpdir
|
64
|
+
ws_define_package_manager 'os'
|
65
|
+
ws_define_package_manager 'os_indep'
|
52
66
|
|
53
67
|
super
|
54
68
|
end
|
@@ -59,6 +73,7 @@ def teardown
|
|
59
73
|
FileUtils.remove_entry_secure dir
|
60
74
|
end
|
61
75
|
Autobuild::Package.clear
|
76
|
+
Autoproj.silent = false
|
62
77
|
|
63
78
|
if @gem_server_pid
|
64
79
|
stop_gem_server
|
@@ -68,12 +83,11 @@ def teardown
|
|
68
83
|
end
|
69
84
|
|
70
85
|
def create_bootstrap
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
Workspace.new(dir)
|
86
|
+
ws_create
|
87
|
+
end
|
88
|
+
|
89
|
+
def skip_long_tests?
|
90
|
+
ENV['AUTOPROJ_SKIP_LONG_TESTS'] == '1'
|
77
91
|
end
|
78
92
|
|
79
93
|
def make_tmpdir
|
@@ -140,8 +154,13 @@ def invoke_test_script(name, *arguments,
|
|
140
154
|
end
|
141
155
|
result = nil
|
142
156
|
stdout, stderr = capture_subprocess_io do
|
157
|
+
default_env = Hash[
|
158
|
+
'TEST_COMMAND_NAME' => self.to_s.gsub(/[^\w]/, '_'),
|
159
|
+
'PACKAGE_BASE_DIR' => package_base_dir,
|
160
|
+
'RUBY' => Gem.ruby
|
161
|
+
]
|
143
162
|
result = Bundler.clean_system(
|
144
|
-
|
163
|
+
default_env.merge(env),
|
145
164
|
script, *arguments, in: :close, **Hash[chdir: dir].merge(system_options))
|
146
165
|
end
|
147
166
|
|
@@ -200,6 +219,16 @@ def stop_gem_server
|
|
200
219
|
@gem_server_pid = nil
|
201
220
|
end
|
202
221
|
|
222
|
+
def capture_deprecation_message(&block)
|
223
|
+
level = Autoproj.warn_deprecated_level
|
224
|
+
Autoproj.warn_deprecated_level = -1
|
225
|
+
capture_subprocess_io do
|
226
|
+
yield
|
227
|
+
end
|
228
|
+
ensure
|
229
|
+
Autoproj.warn_deprecated_level = level
|
230
|
+
end
|
231
|
+
|
203
232
|
def find_bundled_gem_path(bundler, gem_name, gemfile)
|
204
233
|
out_r, out_w = IO.pipe
|
205
234
|
result = Bundler.clean_system(
|
@@ -217,6 +246,130 @@ def workspace_env(varname)
|
|
217
246
|
stdout.chomp
|
218
247
|
end
|
219
248
|
|
249
|
+
attr_reader :ws_os_package_resolver
|
250
|
+
|
251
|
+
def ws_define_package_manager(name, strict: false, call_while_empty: false)
|
252
|
+
manager = Class.new(PackageManagers::Manager)
|
253
|
+
manager.class_eval do
|
254
|
+
define_method(:strict?) { strict }
|
255
|
+
define_method(:call_while_empty?) { call_while_empty }
|
256
|
+
end
|
257
|
+
manager = flexmock(manager),
|
258
|
+
ws_package_managers[name] = manager
|
259
|
+
end
|
260
|
+
|
261
|
+
def ws_create_os_package_resolver
|
262
|
+
@ws_os_package_resolver = OSPackageResolver.new(
|
263
|
+
operating_system: [['test_os_family'], ['test_os_version']],
|
264
|
+
package_managers: ws_package_managers.keys,
|
265
|
+
os_package_manager: 'os')
|
266
|
+
end
|
267
|
+
|
268
|
+
def ws_create
|
269
|
+
dir = make_tmpdir
|
270
|
+
require 'autoproj/ops/main_config_switcher'
|
271
|
+
FileUtils.cp_r Ops::MainConfigSwitcher::MAIN_CONFIGURATION_TEMPLATE, File.join(dir, 'autoproj')
|
272
|
+
FileUtils.mkdir_p File.join(dir, '.autoproj')
|
273
|
+
|
274
|
+
ws_create_os_package_resolver
|
275
|
+
@ws = Workspace.new(
|
276
|
+
dir, os_package_resolver: ws_os_package_resolver,
|
277
|
+
package_managers: ws_package_managers)
|
278
|
+
ws.config.set 'osdeps_mode', 'all'
|
279
|
+
ws.config.set 'gems_install_path', File.join(dir, 'gems')
|
280
|
+
ws.config.save
|
281
|
+
ws.prefix_dir = make_tmpdir
|
282
|
+
ws
|
283
|
+
end
|
284
|
+
|
285
|
+
def ws_clear_layout
|
286
|
+
ws.manifest.clear_layout
|
287
|
+
end
|
288
|
+
|
289
|
+
def ws_define_package_set(name, vcs = VCSDefinition.from_raw(type: 'none'), **options)
|
290
|
+
package_set = PackageSet.new(ws, vcs, name: name, **options)
|
291
|
+
ws.manifest.register_package_set(package_set)
|
292
|
+
package_set
|
293
|
+
end
|
294
|
+
|
295
|
+
def ws_add_package_set_to_layout(name, vcs = VCSDefinition.from_raw(type: 'none'), **options)
|
296
|
+
package_set = ws_define_package_set(name, vcs, **options)
|
297
|
+
ws.manifest.add_package_set_to_layout(package_set)
|
298
|
+
package_set
|
299
|
+
end
|
300
|
+
|
301
|
+
def ws_define_osdep_entries(entries)
|
302
|
+
ws_os_package_resolver.add_entries(entries)
|
303
|
+
end
|
304
|
+
|
305
|
+
def ws_add_osdep_entries_to_layout(entries)
|
306
|
+
ws_os_package_resolver.add_entries(entries)
|
307
|
+
entries.each_key do |pkg_name|
|
308
|
+
ws.manifest.add_package_to_layout(pkg_name)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def ws_define_package(package_type, package_name, package_set: ws.manifest.main_package_set, create: true)
|
313
|
+
package = Autobuild.send(package_type, package_name)
|
314
|
+
package.srcdir = File.join(ws.root_dir, package_name.to_s)
|
315
|
+
if create
|
316
|
+
FileUtils.mkdir_p package.srcdir
|
317
|
+
end
|
318
|
+
autoproj_package = ws.register_package(package, nil, package_set)
|
319
|
+
yield(package) if block_given?
|
320
|
+
autoproj_package
|
321
|
+
end
|
322
|
+
|
323
|
+
def ws_define_package_vcs(package, vcs_spec)
|
324
|
+
package.package_set.add_version_control_entry(package.name, vcs_spec)
|
325
|
+
end
|
326
|
+
|
327
|
+
def ws_define_package_overrides(package, package_set, vcs_spec)
|
328
|
+
package_set.add_overrides_entry(package.name, vcs_spec)
|
329
|
+
end
|
330
|
+
|
331
|
+
def ws_add_package_to_layout(package_type, package_name, package_set: ws.manifest.main_package_set, &block)
|
332
|
+
pkg = ws_define_package(package_type, package_name, package_set: package_set, &block)
|
333
|
+
ws.manifest.add_package_to_layout(pkg)
|
334
|
+
pkg
|
335
|
+
end
|
336
|
+
|
337
|
+
def ws_set_version_control_entry(package, entry)
|
338
|
+
package.package_set.add_version_control_entry(package.name, entry)
|
339
|
+
end
|
340
|
+
|
341
|
+
def ws_set_overrides_entry(package, package_set, entry)
|
342
|
+
package_set.add_overrides_entry(package.name, entry)
|
343
|
+
end
|
344
|
+
|
345
|
+
def ws_setup_package_dirs(package, create_srcdir: true)
|
346
|
+
package.autobuild.srcdir = srcdir = File.join(ws.root_dir, package.name)
|
347
|
+
if create_srcdir
|
348
|
+
FileUtils.mkdir_p srcdir
|
349
|
+
elsif File.directory?(srcdir)
|
350
|
+
FileUtils.rm_rf srcdir
|
351
|
+
end
|
352
|
+
package.autobuild.builddir = builddir = File.join(ws.root_dir, 'build', package.name)
|
353
|
+
package.autobuild.prefix = prefix = File.join(ws.root_dir, 'prefix', package.name)
|
354
|
+
return srcdir, builddir, prefix
|
355
|
+
end
|
356
|
+
|
357
|
+
def ws_create_git_package_set(name, source_data = Hash.new)
|
358
|
+
dir = make_tmpdir
|
359
|
+
if !system('git', 'init', chdir: dir, out: :close)
|
360
|
+
raise "failed to run git init"
|
361
|
+
end
|
362
|
+
File.open(File.join(dir, 'source.yml'), 'w') do |io|
|
363
|
+
YAML.dump(Hash['name' => name].merge(source_data), io)
|
364
|
+
end
|
365
|
+
if !system('git', 'add', 'source.yml', chdir: dir, out: :close)
|
366
|
+
raise "failed to add the source.yml"
|
367
|
+
end
|
368
|
+
if !system('git', 'commit', '-m', 'add source.yml', chdir: dir, out: :close)
|
369
|
+
raise "failed to commit the source.yml"
|
370
|
+
end
|
371
|
+
dir
|
372
|
+
end
|
220
373
|
end
|
221
374
|
end
|
222
375
|
|
@@ -26,40 +26,15 @@ def self.flatten_recursive_hash(hash, prefix = "")
|
|
26
26
|
result
|
27
27
|
end
|
28
28
|
|
29
|
-
# Expand build options in +value+.
|
30
|
-
#
|
31
|
-
# The method will expand in +value+ patterns of the form $NAME, replacing
|
32
|
-
# them with the corresponding build option.
|
33
|
-
def self.expand_environment(value)
|
34
|
-
return value if !contains_expansion?(value)
|
35
|
-
|
36
|
-
# Perform constant expansion on the defined environment variables,
|
37
|
-
# including the option set
|
38
|
-
options = flatten_recursive_hash(config.validated_values)
|
39
|
-
|
40
|
-
loop do
|
41
|
-
new_value = single_expansion(value, options)
|
42
|
-
if new_value == value
|
43
|
-
break
|
44
|
-
else
|
45
|
-
value = new_value
|
46
|
-
end
|
47
|
-
end
|
48
|
-
value
|
49
|
-
end
|
50
|
-
|
51
29
|
# Does a non-recursive expansion in +data+ of configuration variables
|
52
30
|
# ($VAR_NAME) listed in +definitions+
|
53
31
|
#
|
54
32
|
# If the values listed in +definitions+ also contain configuration
|
55
33
|
# variables, they do not get expanded
|
56
|
-
def self.single_expansion(data, definitions
|
57
|
-
options = Kernel.validate_options options, config: Autoproj.config
|
58
|
-
|
34
|
+
def self.single_expansion(data, definitions)
|
59
35
|
if !data.respond_to?(:to_str)
|
60
36
|
return data
|
61
37
|
end
|
62
|
-
definitions = { 'HOME' => ENV['HOME'] }.merge(definitions)
|
63
38
|
|
64
39
|
data = data.gsub(/(.|^)\$(\w+)/) do |constant_name|
|
65
40
|
prefix = constant_name[0, 1]
|
@@ -72,11 +47,10 @@ def self.single_expansion(data, definitions, options = Hash.new)
|
|
72
47
|
constant_name = constant_name[2..-1]
|
73
48
|
end
|
74
49
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
50
|
+
value = definitions[constant_name]
|
51
|
+
if value.nil?
|
52
|
+
if !block_given? || !(value = yield(constant_name))
|
53
|
+
raise ArgumentError, "cannot find a definition for $#{constant_name}"
|
80
54
|
end
|
81
55
|
end
|
82
56
|
"#{prefix}#{value}"
|
@@ -109,8 +83,9 @@ def self.expand(value, definitions = Hash.new)
|
|
109
83
|
def self.contains_expansion?(string); string =~ /\$/ end
|
110
84
|
|
111
85
|
def self.resolve_one_constant(name, value, result, definitions)
|
112
|
-
result[name]
|
113
|
-
result[missing_name] =
|
86
|
+
result[name] ||= single_expansion(value, result) do |missing_name|
|
87
|
+
result[missing_name] =
|
88
|
+
resolve_one_constant(missing_name, definitions[missing_name], result, definitions)
|
114
89
|
end
|
115
90
|
end
|
116
91
|
|
@@ -118,17 +93,15 @@ def self.resolve_one_constant(name, value, result, definitions)
|
|
118
93
|
#
|
119
94
|
# I.e. replaces variables by their values, so that no value in +constants+
|
120
95
|
# refers to variables defined in +constants+
|
121
|
-
def self.resolve_constant_definitions(constants)
|
122
|
-
|
123
|
-
constants['HOME'] = ENV['HOME']
|
96
|
+
def self.resolve_constant_definitions(constants, definitions = Hash.new)
|
97
|
+
definitions = definitions.merge(constants)
|
124
98
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
resolve_one_constant(name, value, result, constants)
|
99
|
+
all_resolutions = Hash.new
|
100
|
+
resolution_cache = Hash.new
|
101
|
+
constants.each do |key, value|
|
102
|
+
all_resolutions[key] = resolve_one_constant(key, value, resolution_cache, definitions)
|
130
103
|
end
|
131
|
-
|
104
|
+
all_resolutions
|
132
105
|
end
|
133
106
|
end
|
134
107
|
|
@@ -22,36 +22,39 @@ class VCSDefinition
|
|
22
22
|
# i.e. the list of VCSDefinition objects that led to this one by means
|
23
23
|
# of calls to {#update}
|
24
24
|
#
|
25
|
-
# @return [Array<
|
25
|
+
# @return [Array<HistoryEntry>]
|
26
26
|
attr_reader :history
|
27
27
|
|
28
28
|
# The original spec in hash form
|
29
29
|
#
|
30
|
-
#
|
31
|
-
# VCSDefinition.from_raw
|
32
|
-
#
|
33
|
-
# @return [nil,Hash]
|
30
|
+
# @return [Array<RawEntry>]
|
34
31
|
attr_reader :raw
|
35
32
|
|
36
|
-
|
37
|
-
|
33
|
+
HistoryEntry = Struct.new :package_set, :vcs
|
34
|
+
RawEntry = Struct.new :package_set, :file, :vcs
|
35
|
+
|
36
|
+
def initialize(type, url, vcs_options, from: nil, raw: Array.new, history: Array.new)
|
37
|
+
if !raw.respond_to?(:to_ary)
|
38
38
|
raise ArgumentError, "wrong format for the raw field (#{raw.inspect})"
|
39
39
|
end
|
40
|
-
if !options.kind_of?(Hash)
|
41
|
-
options = Hash[raw: options]
|
42
|
-
end
|
43
|
-
if vcs_options[:raw]
|
44
|
-
raise
|
45
|
-
end
|
46
|
-
options = validate_options options, from: nil, raw: nil, history: nil
|
47
40
|
|
48
41
|
@type, @url, @options = type, url, vcs_options
|
49
42
|
if type != "none" && type != "local" && !Autobuild.respond_to?(type)
|
50
43
|
raise ConfigError.new, "version control #{type} is unknown to autoproj"
|
51
44
|
end
|
52
45
|
|
53
|
-
@history =
|
54
|
-
@raw
|
46
|
+
@history = history + [HistoryEntry.new(from, self)]
|
47
|
+
@raw = raw
|
48
|
+
end
|
49
|
+
|
50
|
+
# Create a null VCS object
|
51
|
+
def self.none
|
52
|
+
from_raw(type: 'none')
|
53
|
+
end
|
54
|
+
|
55
|
+
# Whether there is actually a version control definition
|
56
|
+
def none?
|
57
|
+
@type == 'none'
|
55
58
|
end
|
56
59
|
|
57
60
|
# Whether this points to a local directory
|
@@ -70,21 +73,16 @@ def to_hash
|
|
70
73
|
# the updated definition
|
71
74
|
#
|
72
75
|
# @return [VCSDefinition]
|
73
|
-
def update(spec,
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
from, options = filter_options options, from: nil, raw: nil
|
78
|
-
from = from[:from]
|
79
|
-
new = self.class.vcs_definition_to_hash(spec)
|
80
|
-
new_raw = options[:raw] || [[from, spec]]
|
76
|
+
def update(spec, from: nil, raw: Array.new)
|
77
|
+
new = self.class.normalize_vcs_hash(spec)
|
78
|
+
new_raw = Array.new
|
81
79
|
new_history = Array.new
|
82
80
|
|
83
81
|
# If the type changed, we replace the old definition by the new one
|
84
82
|
# completely. Otherwise, we append it to the current one
|
85
83
|
if !new.has_key?(:type) || (type == new[:type])
|
86
84
|
new = to_hash.merge(new)
|
87
|
-
new_raw = self.raw +
|
85
|
+
new_raw = self.raw + raw
|
88
86
|
new_history = self.history
|
89
87
|
end
|
90
88
|
self.class.from_raw(new, from: from, history: new_history, raw: new_raw)
|
@@ -95,9 +93,9 @@ def update(spec, options = Hash.new)
|
|
95
93
|
#
|
96
94
|
# Both +old+ and +new+ are supposed to be in hash form. It is assumed
|
97
95
|
# that +old+ has already been normalized by a call to
|
98
|
-
# {.
|
96
|
+
# {.normalize_vcs_hash}. +new+ can be in "raw" form.
|
99
97
|
def self.update_raw_vcs_spec(old, new)
|
100
|
-
new =
|
98
|
+
new = normalize_vcs_hash(new)
|
101
99
|
if new.has_key?(:type) && (old[:type] != new[:type])
|
102
100
|
# The type changed. We replace the old definition by the new one
|
103
101
|
# completely, and we make sure that the new definition is valid
|
@@ -115,7 +113,7 @@ def self.update_raw_vcs_spec(old, new)
|
|
115
113
|
#
|
116
114
|
# - package_name
|
117
115
|
# branch: value
|
118
|
-
def self.
|
116
|
+
def self.normalize_vcs_hash(spec, base_dir: nil)
|
119
117
|
plain = Array.new
|
120
118
|
filtered_spec = Hash.new
|
121
119
|
|
@@ -141,24 +139,26 @@ def self.vcs_definition_to_hash(spec)
|
|
141
139
|
# shortcut. If it is not, look for a local directory called
|
142
140
|
# short_url
|
143
141
|
if Autobuild.respond_to?(vcs)
|
144
|
-
spec.merge!(:
|
142
|
+
spec.merge!(type: vcs, url: url.join(':'))
|
145
143
|
elsif Autoproj.has_source_handler?(vcs)
|
146
144
|
spec = Autoproj.call_source_handler(vcs, url.join(':'), spec)
|
147
145
|
else
|
148
146
|
source_dir =
|
149
147
|
if Pathname.new(short_url).absolute?
|
150
148
|
File.expand_path(short_url)
|
149
|
+
elsif base_dir
|
150
|
+
File.expand_path(short_url, base_dir)
|
151
151
|
else
|
152
|
-
|
152
|
+
raise ArgumentError, "VCS path '#{short_url}' is relative and no base_dir was given"
|
153
153
|
end
|
154
154
|
if !File.directory?(source_dir)
|
155
|
-
raise
|
155
|
+
raise ArgumentError, "'#{short_url}' is neither a remote source specification, nor an existing local directory"
|
156
156
|
end
|
157
|
-
spec.merge!(:
|
157
|
+
spec.merge!(type: 'local', url: source_dir)
|
158
158
|
end
|
159
159
|
end
|
160
160
|
|
161
|
-
spec, vcs_options = Kernel.filter_options spec, :
|
161
|
+
spec, vcs_options = Kernel.filter_options spec, type: nil, url: nil
|
162
162
|
spec.merge!(vcs_options)
|
163
163
|
if !spec[:url]
|
164
164
|
# Verify that none of the keys are source handlers. If it is the
|
@@ -176,6 +176,13 @@ def self.vcs_definition_to_hash(spec)
|
|
176
176
|
spec
|
177
177
|
end
|
178
178
|
|
179
|
+
# @api private
|
180
|
+
#
|
181
|
+
# Converts a raw spec (a hash, really) into a nicely formatted string
|
182
|
+
def self.raw_spec_to_s(spec)
|
183
|
+
"{ #{spec.sort_by(&:first).map { |k, v| "#{k}: #{v}" }.join(", ")} }"
|
184
|
+
end
|
185
|
+
|
179
186
|
# Converts a 'raw' VCS representation to a normalized hash.
|
180
187
|
#
|
181
188
|
# The raw definition can have three forms:
|
@@ -186,29 +193,30 @@ def self.vcs_definition_to_hash(spec)
|
|
186
193
|
# @return [VCSDefinition]
|
187
194
|
# @raise ArgumentError if the raw specification does not match an
|
188
195
|
# expected format
|
189
|
-
def self.from_raw(spec,
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
spec = vcs_definition_to_hash(spec)
|
199
|
-
if !(spec[:type] && (spec[:type] == 'none' || spec[:url]))
|
200
|
-
raise ConfigError.new, "the source specification #{spec.inspect} misses either the VCS type or an URL"
|
196
|
+
def self.from_raw(spec, from: nil, raw: Array.new, history: Array.new)
|
197
|
+
normalized_spec = normalize_vcs_hash(spec)
|
198
|
+
if !(type = normalized_spec.delete(:type))
|
199
|
+
raise ArgumentError, "the source specification #{raw_spec_to_s(spec)} normalizes into #{raw_spec_to_s(normalized_spec)}, which does not have a VCS type"
|
200
|
+
elsif !(url = normalized_spec.delete(:url))
|
201
|
+
if type != 'none'
|
202
|
+
raise ArgumentError, "the source specification #{raw_spec_to_s(spec)} normalizes into #{raw_spec_to_s(normalized_spec)}, which does not have a URL. Only VCS of type 'none' do not require one"
|
203
|
+
end
|
201
204
|
end
|
202
205
|
|
203
|
-
|
204
|
-
return VCSDefinition.new(spec[:type], spec[:url], vcs_options, from: from, history: history, raw: raw)
|
206
|
+
VCSDefinition.new(type, url, normalized_spec, from: from, history: history, raw: raw)
|
205
207
|
end
|
206
208
|
|
207
209
|
def ==(other_vcs)
|
208
210
|
return false if !other_vcs.kind_of?(VCSDefinition)
|
209
211
|
if local?
|
210
|
-
other_vcs.local? && url ==
|
211
|
-
elsif
|
212
|
+
other_vcs.local? && url == other_vcs.url
|
213
|
+
elsif other_vcs.local?
|
214
|
+
false
|
215
|
+
elsif none?
|
216
|
+
other_vcs.none?
|
217
|
+
elsif other_vcs.none?
|
218
|
+
false
|
219
|
+
else
|
212
220
|
this_importer = create_autobuild_importer
|
213
221
|
other_importer = other_vcs.create_autobuild_importer
|
214
222
|
this_importer.source_id == other_importer.source_id
|
@@ -223,14 +231,11 @@ def eql?(other_vcs)
|
|
223
231
|
to_hash == other_vcs.to_hash
|
224
232
|
end
|
225
233
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
url = Autoproj.single_expansion(url, 'HOME' => ENV['HOME'])
|
232
|
-
if url && url !~ /^(\w+:\/)?\/|^[:\w]+\@|^(\w+\@)?[\w\.-]+:/
|
233
|
-
url = File.expand_path(url, root_dir || Autoproj.root_dir)
|
234
|
+
ABSOLUTE_PATH_OR_URI = /^([\w+]+:\/)?\/|^[:\w]+\@|^(\w+\@)?[\w\.-]+:/
|
235
|
+
|
236
|
+
def self.to_absolute_url(url, root_dir)
|
237
|
+
if url && url !~ ABSOLUTE_PATH_OR_URI
|
238
|
+
url = File.expand_path(url, root_dir)
|
234
239
|
end
|
235
240
|
url
|
236
241
|
end
|
@@ -240,6 +245,15 @@ def needs_import?
|
|
240
245
|
type != 'none' && type != 'local'
|
241
246
|
end
|
242
247
|
|
248
|
+
def overrides_key
|
249
|
+
return if none?
|
250
|
+
if local?
|
251
|
+
"local:#{url}"
|
252
|
+
else
|
253
|
+
create_autobuild_importer.repository_id
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
243
257
|
# Returns a properly configured instance of a subclass of
|
244
258
|
# Autobuild::Importer that match this VCS definition
|
245
259
|
#
|
@@ -247,13 +261,13 @@ def needs_import?
|
|
247
261
|
def create_autobuild_importer
|
248
262
|
return if !needs_import?
|
249
263
|
|
250
|
-
url = VCSDefinition.to_absolute_url(self.url)
|
251
264
|
importer = Autobuild.send(type, url, options)
|
252
265
|
if importer.respond_to?(:declare_alternate_repository)
|
253
|
-
history.each do |
|
254
|
-
|
255
|
-
|
256
|
-
|
266
|
+
history.each do |entry|
|
267
|
+
package_set = entry.package_set
|
268
|
+
vcs = entry.vcs
|
269
|
+
next if !package_set || package_set.main?
|
270
|
+
importer.declare_alternate_repository(package_set.name, vcs.url, vcs.options)
|
257
271
|
end
|
258
272
|
end
|
259
273
|
importer
|
@@ -295,30 +309,33 @@ def self.call_source_handler(vcs, url, options)
|
|
295
309
|
end
|
296
310
|
end
|
297
311
|
|
298
|
-
# call-seq:
|
299
|
-
# Autoproj.add_source_handler name do |url, options|
|
300
|
-
# # build a hash that represent source configuration
|
301
|
-
# # and return it
|
302
|
-
# end
|
303
|
-
#
|
304
312
|
# Add a custom source handler named +name+
|
305
313
|
#
|
306
314
|
# Custom source handlers are shortcuts that can be used to represent VCS
|
307
|
-
# information. For instance, the
|
308
|
-
#
|
309
|
-
#
|
310
|
-
# gitorious_server_configuration 'GITORIOUS', 'gitorious.org'
|
315
|
+
# information. For instance, the {Autoproj.git_server_configuration} helper defines a
|
316
|
+
# source handler that allows to easily add new github packages:
|
311
317
|
#
|
312
|
-
#
|
318
|
+
# Autoproj.git_server_configuration('GITHUB', 'github.com',
|
319
|
+
# http_url: 'https://github.com',
|
320
|
+
# default: 'http,ssh')
|
313
321
|
#
|
322
|
+
# Defines a 'github' custom handler that expands into the full VCS
|
323
|
+
# configuration to access github
|
314
324
|
#
|
315
325
|
# version_control:
|
316
|
-
# - tools/orocos.rb
|
317
|
-
#
|
326
|
+
# - tools/orocos.rb:
|
327
|
+
# github: rock-core/base-types
|
318
328
|
# branch: test
|
319
|
-
#
|
320
329
|
#
|
330
|
+
# @yieldparam [String] url the url given to the handler
|
331
|
+
# @yieldparam [Hash] the rest of the VCS hash
|
332
|
+
# @return [Hash] a VCS hash with the information expanded
|
321
333
|
def self.add_source_handler(name, &handler)
|
322
334
|
@custom_source_handlers[name.to_s] = lambda(&handler)
|
323
335
|
end
|
336
|
+
|
337
|
+
# Deregister a source handler defined with {.add_source_handler}
|
338
|
+
def self.remove_source_handler(name)
|
339
|
+
@custom_source_handlers.delete(name)
|
340
|
+
end
|
324
341
|
end
|