autoproj 2.3.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -3
  3. data/.vscode/launch.json +25 -0
  4. data/Gemfile +10 -3
  5. data/autoproj.gemspec +1 -1
  6. data/bin/autoproj_bootstrap +5 -3
  7. data/bin/autoproj_bootstrap.in +5 -3
  8. data/bin/autoproj_install +2 -2
  9. data/bin/autoproj_install.in +2 -2
  10. data/lib/autoproj.rb +3 -1
  11. data/lib/autoproj/build_option.rb +4 -4
  12. data/lib/autoproj/cli.rb +10 -1
  13. data/lib/autoproj/cli/base.rb +14 -4
  14. data/lib/autoproj/cli/bootstrap.rb +2 -2
  15. data/lib/autoproj/cli/cache.rb +4 -10
  16. data/lib/autoproj/cli/clean.rb +1 -1
  17. data/lib/autoproj/cli/commit.rb +1 -1
  18. data/lib/autoproj/cli/exec.rb +11 -5
  19. data/lib/autoproj/cli/locate.rb +12 -12
  20. data/lib/autoproj/cli/log.rb +1 -2
  21. data/lib/autoproj/cli/main.rb +23 -4
  22. data/lib/autoproj/cli/main_plugin.rb +2 -2
  23. data/lib/autoproj/cli/manifest.rb +6 -3
  24. data/lib/autoproj/cli/query.rb +71 -10
  25. data/lib/autoproj/cli/reset.rb +4 -4
  26. data/lib/autoproj/cli/switch_config.rb +2 -2
  27. data/lib/autoproj/cli/tag.rb +2 -2
  28. data/lib/autoproj/cli/update.rb +2 -0
  29. data/lib/autoproj/cli/which.rb +17 -0
  30. data/lib/autoproj/exceptions.rb +9 -4
  31. data/lib/autoproj/git_server_configuration.rb +80 -53
  32. data/lib/autoproj/manifest.rb +1 -1
  33. data/lib/autoproj/ops/cache.rb +21 -10
  34. data/lib/autoproj/ops/main_config_switcher.rb +6 -9
  35. data/lib/autoproj/os_package_query.rb +99 -0
  36. data/lib/autoproj/package_managers/bundler_manager.rb +8 -1
  37. data/lib/autoproj/package_managers/yum_manager.rb +2 -2
  38. data/lib/autoproj/package_managers/zypper_manager.rb +2 -2
  39. data/lib/autoproj/query_base.rb +128 -0
  40. data/lib/autoproj/reporter.rb +12 -0
  41. data/lib/autoproj/{query.rb → source_package_query.rb} +15 -81
  42. data/lib/autoproj/version.rb +1 -1
  43. data/lib/autoproj/workspace.rb +38 -0
  44. metadata +8 -5
  45. data/lib/autoproj/cli/snapshot.rb +0 -66
@@ -5,7 +5,7 @@ class MainPlugin < Thor
5
5
 
6
6
  no_commands do
7
7
  def ws
8
- @ws ||= Workspace.from_pwd
8
+ @ws ||= Workspace.default
9
9
  end
10
10
 
11
11
  def install_plugins
@@ -37,7 +37,7 @@ def install(name)
37
37
 
38
38
  gem_options = Hash.new
39
39
  if options[:git] && options[:path]
40
- raise ArgumentError, "you can provide only one of --git or --path"
40
+ raise CLIInvalidArguments, "you can provide only one of --git or --path"
41
41
  elsif options[:git]
42
42
  gem_options[:git] = options[:git]
43
43
  elsif options[:path]
@@ -15,7 +15,7 @@ def run(name, options = Hash.new)
15
15
  name = name.first
16
16
  if File.file?(full_path = File.expand_path(name))
17
17
  if File.dirname(full_path) != ws.config_dir
18
- raise ArgumentError, "#{full_path} is not part of #{ws.config_dir}"
18
+ raise CLIInvalidArguments, "#{full_path} is not part of #{ws.config_dir}"
19
19
  end
20
20
  else
21
21
  full_path = File.join(ws.config_dir, name)
@@ -24,7 +24,7 @@ def run(name, options = Hash.new)
24
24
  if !File.file?(full_path)
25
25
  alternative_full_path = File.join(ws.config_dir, "manifest.#{name}")
26
26
  if !File.file?(alternative_full_path)
27
- raise ArgumentError, "neither #{full_path} nor #{alternative_full_path} exist"
27
+ raise CLIInvalidArguments, "neither #{full_path} nor #{alternative_full_path} exist"
28
28
  end
29
29
  full_path = alternative_full_path
30
30
  end
@@ -38,9 +38,12 @@ def run(name, options = Hash.new)
38
38
  ws.save_config
39
39
  Autoproj.message "set manifest to #{full_path}"
40
40
  else
41
- raise ArgumentError, "expected zero or one argument, but got #{name.size}"
41
+ raise CLIInvalidArguments, "expected zero or one argument, but got #{name.size}"
42
42
  end
43
43
  end
44
+
45
+ def notify_env_sh_updated
46
+ end
44
47
  end
45
48
  end
46
49
  end
@@ -4,6 +4,10 @@
4
4
  module Autoproj
5
5
  module CLI
6
6
  class Query < InspectionTool
7
+ def os_package_resolver
8
+ ws.os_package_resolver
9
+ end
10
+
7
11
  def find_all_matches(query, packages)
8
12
  matches = packages.map do |pkg|
9
13
  if priority = query.match(pkg)
@@ -13,35 +17,92 @@ def find_all_matches(query, packages)
13
17
  matches.sort_by { |priority, pkg| [priority, pkg.name] }
14
18
  end
15
19
 
16
- def run(query_string, format: '$NAME', search_all: false, only_present: false)
20
+ def run(query_string, format: '$NAME', search_all: false, only_present: false, osdeps: false)
17
21
  initialize_and_load
18
- all_selected_packages, * = finalize_setup([], non_imported_packages: :return)
22
+ all_selected_packages, all_selected_osdeps_packages, * =
23
+ finalize_setup([], non_imported_packages: :return)
24
+
25
+ if osdeps
26
+ query_os_packages(query_string, all_selected_osdeps_packages, format: format, search_all: search_all)
27
+ else
28
+ query_source_packages(query_string, all_selected_packages, format: format, search_all: search_all, only_present: only_present)
29
+ end
30
+ end
31
+
32
+ def query_os_packages(query_string, selected_packages, format: '$NAME', search_all: false)
33
+ if query_string.empty?
34
+ query = OSPackageQuery.all
35
+ else
36
+ query = OSPackageQuery.parse_query(query_string.first, os_package_resolver)
37
+ end
38
+
39
+ if search_all
40
+ packages = os_package_resolver.all_package_names
41
+ else
42
+ packages = selected_packages
43
+ end
44
+
45
+ matches = find_all_matches(query, packages.to_a)
46
+
47
+ needs_real_package = (/\$REAL_PACKAGE\b/ === format)
48
+ needs_handler = (/\$HANDLER\b/ === format)
49
+
50
+ matches.each do |priority, pkg_name|
51
+ if needs_real_package || needs_handler
52
+ resolved = os_package_resolver.resolve_os_packages([pkg_name])
53
+ resolved.each do |handler, real_packages|
54
+ if needs_real_package
55
+ real_packages.each do |real_package_name|
56
+ puts format_osdep_package(format, priority, pkg_name, handler, real_package_name)
57
+ end
58
+ else
59
+ puts format_osdep_package(format, priority, pkg_name, handler, nil)
60
+ end
61
+ end
62
+ else
63
+ puts format_osdep_package(format, priority, pkg_name, nil, nil)
64
+ end
65
+ end
66
+ end
67
+
68
+ def format_osdep_package(format, priority, name, handler, real_package_name)
69
+ fields = Hash.new
70
+ fields['NAME'] = name
71
+ fields['PRIORITY'] = priority
72
+ fields['HANDLER'] = handler
73
+ fields['REAL_PACKAGE'] = real_package_name
74
+ Autoproj.expand(format, fields)
75
+ end
76
+
77
+ def query_source_packages(query_string, selected_packages, format: '$NAME', search_all: false, only_present: false)
78
+ if query_string.empty?
79
+ query = SourcePackageQuery.all
80
+ else
81
+ query = SourcePackageQuery.parse_query(query_string.first)
82
+ end
83
+
19
84
  if search_all
20
85
  packages = ws.manifest.each_package_definition.to_a
21
86
  else
22
- packages = all_selected_packages.map do |pkg_name|
87
+ packages = selected_packages.map do |pkg_name|
23
88
  ws.manifest.find_package_definition(pkg_name)
24
89
  end
25
90
  end
91
+
26
92
  if only_present
27
93
  packages = packages.find_all do |pkg|
28
94
  File.directory?(pkg.autobuild.srcdir)
29
95
  end
30
96
  end
31
97
 
32
- if query_string.empty?
33
- query = Autoproj::Query.all
34
- else
35
- query = Autoproj::Query.parse_query(query_string.first)
36
- end
37
98
  matches = find_all_matches(query, packages)
38
99
 
39
100
  matches.each do |priority, pkg_def|
40
- puts format_package(format, priority, pkg_def)
101
+ puts format_source_package(format, priority, pkg_def)
41
102
  end
42
103
  end
43
104
 
44
- def format_package(format, priority, package)
105
+ def format_source_package(format, priority, package)
45
106
  autobuild_package = package.autobuild
46
107
  fields = Hash.new
47
108
  fields['SRCDIR'] = autobuild_package.srcdir
@@ -10,14 +10,14 @@ def run(ref_name, options)
10
10
  pkg = manifest.main_package_set.create_autobuild_package
11
11
  importer = pkg.importer
12
12
  if !importer || !importer.kind_of?(Autobuild::Git)
13
- raise ConfigError, "cannot use autoproj reset if the main configuration is not managed by git"
13
+ raise CLIInvalidArguments, "cannot use autoproj reset if the main configuration is not managed by git"
14
14
  end
15
15
 
16
16
  # Check if the reflog entry exists
17
17
  begin
18
18
  importer.rev_parse(pkg, ref_name)
19
19
  rescue Autobuild::PackageException
20
- raise InvalidArguments, "#{ref_name} does not exist, run autoproj log for log entries and autoproj tag without arguments for the tags"
20
+ raise CLIInvalidArguments, "#{ref_name} does not exist, run autoproj log for log entries and autoproj tag without arguments for the tags"
21
21
  end
22
22
 
23
23
  # Checkout the version file
@@ -26,13 +26,13 @@ def run(ref_name, options)
26
26
  Versions::DEFAULT_VERSIONS_FILE_BASENAME)
27
27
  begin
28
28
  file_data = importer.show(pkg, ref_name, versions_file)
29
- versions_path = File.join(Autoproj.config_dir, versions_file)
29
+ versions_path = File.join(ws.config_dir, versions_file)
30
30
  if File.file?(versions_path)
31
31
  old_versions_path = "#{versions_path}.old"
32
32
  FileUtils.rm_f old_versions_path
33
33
  FileUtils.cp versions_path, old_versions_path
34
34
  end
35
- FileUtils.mkdir_p File.join(Autoproj.config_dir, Workspace::OVERRIDES_DIR)
35
+ FileUtils.mkdir_p File.join(ws.config_dir, Workspace::OVERRIDES_DIR)
36
36
  File.open(versions_path, 'w') do |io|
37
37
  io.write file_data
38
38
  end
@@ -9,9 +9,9 @@ module CLI
9
9
  class SwitchConfig < Base
10
10
  def run(args, options = Hash.new)
11
11
  if !File.directory?(ws.config_dir)
12
- raise ConfigError, "there's no autoproj/ directory in this workspace, use autoproj bootstrap to check out one"
12
+ raise CLIInvalidArguments, "there's no autoproj/ directory in this workspace, use autoproj bootstrap to check out one"
13
13
  elsif Dir.pwd.start_with?(ws.remotes_dir) || Dir.pwd.start_with?(ws.config_dir)
14
- raise ConfigError, "you cannot run autoproj switch-config from autoproj's configuration directory or one of its subdirectories"
14
+ raise CLIInvalidArguments, "you cannot run autoproj switch-config from autoproj's configuration directory or one of its subdirectories"
15
15
  end
16
16
 
17
17
  ws.load_config
@@ -14,7 +14,7 @@ def run(arguments, options = Hash.new)
14
14
  pkg = main_package_set.create_autobuild_package
15
15
  importer = pkg.importer
16
16
  if !importer || !importer.kind_of?(Autobuild::Git)
17
- raise ConfigError, "cannot use autoproj tag if the main configuration is not managed by git"
17
+ raise CLIInvalidArguments, "cannot use autoproj tag if the main configuration is not managed by git"
18
18
  end
19
19
 
20
20
  versions_file = File.join(
@@ -37,7 +37,7 @@ def run(arguments, options = Hash.new)
37
37
  # Check if the tag already exists
38
38
  begin
39
39
  importer.rev_parse(pkg, "refs/tags/#{tag_name}")
40
- raise InvalidArguments, "tag #{tag_name} already exists"
40
+ raise CLIInvalidArguments, "tag #{tag_name} already exists"
41
41
  rescue Autobuild::PackageException
42
42
  end
43
43
 
@@ -198,6 +198,8 @@ def update_packages(selected_packages,
198
198
  install_vcs_packages: (osdeps_options if osdeps),
199
199
  auto_exclude: auto_exclude)
200
200
  return source_packages, osdep_packages, nil
201
+ rescue ExcludedSelection => e
202
+ raise CLIInvalidSelection, e.message, e.backtrace
201
203
  rescue PackageImportFailed => import_failure
202
204
  if !keep_going
203
205
  raise
@@ -0,0 +1,17 @@
1
+ require 'autoproj/cli/inspection_tool'
2
+ module Autoproj
3
+ module CLI
4
+ class Which < InspectionTool
5
+ def run(cmd)
6
+ initialize_and_load
7
+ finalize_setup(Array.new)
8
+
9
+ puts ws.which(cmd)
10
+ rescue Workspace::ExecutableNotFound => e
11
+ raise CLIInvalidArguments, e.message, e.backtrace
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+
@@ -36,6 +36,9 @@ class PackageUnavailable < PackageNotFound; end
36
36
  class UnregisteredPackage < ArgumentError
37
37
  end
38
38
 
39
+ class UnregisteredPackageSet < ArgumentError
40
+ end
41
+
39
42
  class InvalidPackageManifest < RuntimeError; end
40
43
 
41
44
  class InputError < RuntimeError; end
@@ -67,18 +70,20 @@ def initialize(selection)
67
70
 
68
71
  class UserError < RuntimeError; end
69
72
 
70
- class WorkspaceAlreadyCreated < RuntimeError; end
73
+ class InvalidWorkspace < RuntimeError; end
74
+
75
+ class WorkspaceAlreadyCreated < InvalidWorkspace; end
71
76
 
72
77
  # Exception raised when looking for a workspace and it cannot be found
73
- class NotWorkspace < RuntimeError; end
78
+ class NotWorkspace < InvalidWorkspace; end
74
79
 
75
80
  # Exception raised when the autoproj workspace changes and the current
76
81
  # workspace is outdated
77
- class OutdatedWorkspace < RuntimeError; end
82
+ class OutdatedWorkspace < InvalidWorkspace; end
78
83
 
79
84
  # Exception raised when initializing on a workspace that is not the current
80
85
  # one
81
- class MismatchingWorkspace < RuntimeError; end
86
+ class MismatchingWorkspace < InvalidWorkspace; end
82
87
  end
83
88
 
84
89
 
@@ -1,4 +1,52 @@
1
1
  module Autoproj
2
+ GIT_SERVER_CONFIG_VARS = %w{_ROOT _PUSH_ROOT _PRIVATE_ROOT}
3
+
4
+ GIT_SERVER_ACCESS_METHODS = Hash[
5
+ 'git' => 'git,ssh',
6
+ 'ssh' => 'ssh,ssh',
7
+ 'http' => 'http,http']
8
+
9
+
10
+ # @api private
11
+ #
12
+ # Helper for {.git_server_configuration}
13
+ def self.git_server_validate_config_value(base_url, value, disabled_methods: )
14
+ values = (GIT_SERVER_ACCESS_METHODS[value] || value).split(",")
15
+ values.each do |access_method|
16
+ if !GIT_SERVER_ACCESS_METHODS.has_key?(access_method)
17
+ raise Autoproj::InputError, "#{access_method} is not a known access method"
18
+ elsif disabled_methods.include?(access_method)
19
+ raise Autoproj::InputError, "#{access_method} is disabled on #{base_url}"
20
+ end
21
+ end
22
+ value
23
+ end
24
+
25
+ # @api private
26
+ #
27
+ # Helper for {.git_server_configuration}
28
+ def self.git_server_resolve_master_config(name, config, base_url: , git_url: , http_url: , ssh_url: , disabled_methods: )
29
+ access_mode = config.get(name)
30
+ begin
31
+ git_server_validate_config_value(base_url, access_mode, disabled_methods: disabled_methods)
32
+ rescue Autoproj::InputError => e
33
+ Autoproj.warn e.message
34
+ config.reset(name)
35
+ access_mode = config.get(name)
36
+ end
37
+ access_mode = GIT_SERVER_ACCESS_METHODS[access_mode] || access_mode
38
+ pull, push, private_pull = access_mode.split(',')
39
+ private_pull ||= push
40
+ [[pull, "_ROOT"], [push, "_PUSH_ROOT"], [private_pull, "_PRIVATE_ROOT"]].each do |method, var_suffix|
41
+ url = if method == "git" then git_url
42
+ elsif method == "http" then http_url
43
+ elsif method == "ssh" then ssh_url
44
+ end
45
+ config.set("#{name}#{var_suffix}", url)
46
+ end
47
+ return pull, push, private_pull
48
+ end
49
+
2
50
  # Adds the relevant options to handle a gitorious server
3
51
  # What this does is ask the user how he would like to access the gitorious
4
52
  # server. Then, it sets
@@ -18,79 +66,57 @@ module Autoproj
18
66
  #
19
67
  # which would be expanded to the expected URLs for pull and push.
20
68
  #
21
- def self.git_server_configuration(name, base_url, options = Hash.new)
22
- options = Kernel.validate_options options,
69
+ def self.git_server_configuration(name, base_url,
23
70
  git_url: "git://#{base_url}",
24
71
  http_url: "https://git.#{base_url}",
25
72
  ssh_url: "git@#{base_url}:",
26
73
  default: 'http,ssh',
27
74
  disabled_methods: [],
28
75
  config: Autoproj.config,
29
- fallback_to_http: nil
30
-
31
- config = options.delete(:config)
32
- disabled_methods = Array(options[:disabled_methods])
76
+ fallback_to_http: nil,
77
+ lazy: false)
33
78
 
34
- access_methods = Hash[
35
- 'git' => 'git,ssh',
36
- 'ssh' => 'ssh,ssh',
37
- 'http' => 'http,http']
79
+ disabled_methods = Array(disabled_methods)
38
80
 
39
- gitorious_long_doc = [
40
- "How should I interact with #{base_url} (#{(access_methods.keys - disabled_methods).sort.join(", ")})",
81
+ long_doc = [
82
+ "How should I interact with #{base_url} (#{(GIT_SERVER_ACCESS_METHODS.keys - disabled_methods).sort.join(", ")})",
41
83
  "If you give one value, it's going to be the method used for all access",
42
84
  "If you give multiple values, comma-separated, the first one will be",
43
85
  "used for pulling and the second one for pushing. An optional third value",
44
86
  "will be used to pull from private repositories (the same than pushing is",
45
87
  "used by default)"]
46
88
 
47
- validator = lambda do |value|
48
- values = (access_methods[value] || value).split(",")
49
- values.each do |access_method|
50
- if !access_methods.has_key?(access_method)
51
- raise Autoproj::InputError, "#{access_method} is not a known access method"
52
- elsif disabled_methods.include?(access_method)
53
- raise Autoproj::InputError, "#{access_method} is disabled on #{base_url}"
54
- end
55
- end
56
- value
89
+ config.declare name, 'string', default: default, doc: long_doc do |value|
90
+ git_server_validate_config_value(base_url, value, disabled_methods: disabled_methods)
57
91
  end
58
92
 
59
- config.declare name, 'string',
60
- default: options[:default],
61
- doc: gitorious_long_doc, &validator
62
-
63
- access_mode = config.get(name)
64
- begin
65
- validator[access_mode]
66
- rescue Autoproj::InputError => e
67
- Autoproj.warn e.message
68
- config.reset(name)
69
- access_mode = config.get(name)
70
- end
71
- access_mode = access_methods[access_mode] || access_mode
72
- pull, push, private_pull = access_mode.split(',')
73
- private_pull ||= push
74
- [[pull, "_ROOT"], [push, "_PUSH_ROOT"], [private_pull, "_PRIVATE_ROOT"]].each do |method, var_suffix|
75
- url = if method == "git" then options[:git_url]
76
- elsif method == "http" then options[:http_url]
77
- elsif method == "ssh" then options[:ssh_url]
78
- end
79
- config.set("#{name}#{var_suffix}", url)
93
+ if !lazy
94
+ pull, push, private_pull = git_server_resolve_master_config(name, config,
95
+ base_url: base_url,
96
+ git_url: git_url,
97
+ http_url: http_url,
98
+ ssh_url: ssh_url,
99
+ disabled_methods: disabled_methods)
80
100
  end
81
101
 
82
- Autoproj.add_source_handler name.downcase do |url, vcs_options|
102
+ Autoproj.add_source_handler name.downcase do |url, private: false, **vcs_options|
83
103
  if url !~ /\.git$/
84
104
  url += ".git"
85
105
  end
86
106
  if url !~ /^\//
87
107
  url = "/#{url}"
88
108
  end
89
- github_options, vcs_options = Kernel.filter_options vcs_options,
90
- private: false
91
109
 
110
+ if !GIT_SERVER_CONFIG_VARS.all? { |v| config.has_value_for?("#{name}#{v}") }
111
+ pull, push, private_pull = git_server_resolve_master_config(name, config,
112
+ base_url: base_url,
113
+ git_url: git_url,
114
+ http_url: http_url,
115
+ ssh_url: ssh_url,
116
+ disabled_methods: disabled_methods)
117
+ end
92
118
  pull_base_url =
93
- if github_options[:private]
119
+ if private
94
120
  config.get("#{name}_PRIVATE_ROOT")
95
121
  else
96
122
  config.get("#{name}_ROOT")
@@ -99,21 +125,22 @@ def self.git_server_configuration(name, base_url, options = Hash.new)
99
125
  Hash[type: 'git',
100
126
  url: "#{pull_base_url}#{url}",
101
127
  push_to: "#{push_base_url}#{url}",
102
- interactive: (github_options[:private] && private_pull == 'http'),
128
+ interactive: (private && private_pull == 'http'),
103
129
  retry_count: 10,
104
130
  repository_id: "#{name.downcase}:#{url}"].merge(vcs_options)
105
131
  end
106
132
  end
107
133
 
108
- def self.gitorious_server_configuration(name, base_url, options = Hash.new)
134
+ def self.gitorious_server_configuration(name, base_url, **options)
109
135
  Autoproj.warn_deprecated "gitorious_server_configuration",
110
136
  "use require 'git_server_configuration' and
111
137
  Autoproj.git_server_configuration instead. note that the method call
112
138
  interface has not changed, you just have to change the name(s)"
113
- git_server_configuration(name, base_url, options)
139
+ git_server_configuration(name, base_url, **options)
114
140
  end
115
141
  end
116
142
 
117
- Autoproj.git_server_configuration('GITORIOUS', 'gitorious.org', default: 'http,ssh', disabled_methods: 'git')
118
- Autoproj.git_server_configuration('GITHUB', 'github.com', http_url: 'https://github.com', default: 'http,ssh')
119
-
143
+ if !$autoproj_disable_github_gitorious_definitions
144
+ Autoproj.git_server_configuration('GITORIOUS', 'gitorious.org', default: 'http,ssh', disabled_methods: 'git', lazy: true)
145
+ Autoproj.git_server_configuration('GITHUB', 'github.com', http_url: 'https://github.com', default: 'http,ssh')
146
+ end