autoproj 2.11.0 → 2.14.0
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/.rubocop.yml +5 -8
- data/.travis.yml +5 -3
- data/autoproj.gemspec +6 -6
- data/bin/alog +1 -0
- data/bin/autoproj +1 -1
- data/bin/autoproj_bootstrap +130 -67
- data/bin/autoproj_bootstrap.in +9 -7
- data/bin/autoproj_install +129 -63
- data/bin/autoproj_install.in +8 -3
- data/lib/autoproj/autobuild_extensions/dsl.rb +27 -12
- data/lib/autoproj/base.rb +18 -0
- data/lib/autoproj/cli/base.rb +1 -1
- data/lib/autoproj/cli/build.rb +8 -3
- data/lib/autoproj/cli/cache.rb +79 -7
- data/lib/autoproj/cli/inspection_tool.rb +5 -6
- data/lib/autoproj/cli/main.rb +33 -9
- data/lib/autoproj/cli/show.rb +12 -18
- data/lib/autoproj/cli/status.rb +15 -9
- data/lib/autoproj/cli/test.rb +1 -1
- data/lib/autoproj/cli/update.rb +72 -17
- data/lib/autoproj/cli/utility.rb +25 -28
- data/lib/autoproj/configuration.rb +15 -4
- data/lib/autoproj/default.osdeps +29 -3
- data/lib/autoproj/environment.rb +17 -13
- data/lib/autoproj/installation_manifest.rb +7 -5
- data/lib/autoproj/manifest.rb +14 -6
- data/lib/autoproj/ops/build.rb +23 -21
- data/lib/autoproj/ops/cache.rb +151 -33
- data/lib/autoproj/ops/cached_env.rb +2 -2
- data/lib/autoproj/ops/import.rb +23 -4
- data/lib/autoproj/ops/install.rb +121 -60
- data/lib/autoproj/ops/phase_reporting.rb +49 -0
- data/lib/autoproj/ops/snapshot.rb +2 -1
- data/lib/autoproj/ops/tools.rb +2 -2
- data/lib/autoproj/os_package_installer.rb +19 -11
- data/lib/autoproj/package_definition.rb +1 -1
- data/lib/autoproj/package_managers/apt_dpkg_manager.rb +49 -28
- data/lib/autoproj/package_managers/bundler_manager.rb +102 -19
- data/lib/autoproj/package_managers/homebrew_manager.rb +2 -2
- data/lib/autoproj/package_managers/pip_manager.rb +34 -22
- data/lib/autoproj/package_managers/shell_script_manager.rb +44 -24
- data/lib/autoproj/package_manifest.rb +43 -31
- data/lib/autoproj/package_set.rb +2 -2
- data/lib/autoproj/python.rb +285 -0
- data/lib/autoproj/test.rb +26 -10
- data/lib/autoproj/variable_expansion.rb +3 -1
- data/lib/autoproj/vcs_definition.rb +25 -12
- data/lib/autoproj/version.rb +1 -1
- data/lib/autoproj/workspace.rb +60 -16
- data/lib/autoproj.rb +3 -0
- metadata +17 -28
@@ -15,7 +15,7 @@ module Autoproj
|
|
15
15
|
# somewhere else
|
16
16
|
packages = packages.uniq
|
17
17
|
command_line = "brew info --json=v1 #{packages.join(' ')}"
|
18
|
-
result =
|
18
|
+
result = Autoproj.bundler_with_unbundled_env do
|
19
19
|
(Autobuild::Subprocess.run 'autoproj', 'osdeps', command_line).first
|
20
20
|
end
|
21
21
|
|
@@ -30,7 +30,7 @@ module Autoproj
|
|
30
30
|
end
|
31
31
|
return packages
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# fall back if something else went wrong
|
35
35
|
if packages.size != result.size
|
36
36
|
Autoproj.warn "brew info returns less or more packages when requested. Falling back to install all packages"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'autoproj/python'
|
2
|
+
|
1
3
|
module Autoproj
|
2
4
|
module PackageManagers
|
3
5
|
# Using pip to install python packages
|
@@ -25,30 +27,40 @@ module Autoproj
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def guess_pip_program
|
28
|
-
|
29
|
-
|
30
|
+
unless ws.config.has_value_for?('USE_PYTHON')
|
31
|
+
Autoproj::Python.setup_python_configuration_options(ws: ws)
|
32
|
+
end
|
33
|
+
unless ws.config.get('USE_PYTHON')
|
34
|
+
raise ConfigError, "Your current package selection" \
|
35
|
+
" requires the use of pip, but" \
|
36
|
+
" the use of python is either unspecified or has been denied, see" \
|
37
|
+
" setting of USE_PYTHON in your workspace configuration." \
|
38
|
+
" Either remove all packages depending on pip packages " \
|
39
|
+
" from the workspace layout (manifest) or " \
|
40
|
+
" call 'autoproj reconfigure' to change the setting."
|
41
|
+
|
30
42
|
end
|
31
43
|
|
32
|
-
Autobuild.programs['pip'] = "pip"
|
44
|
+
Autobuild.programs['pip'] = "pip" unless Autobuild.programs['pip']
|
45
|
+
Autobuild.programs['pip']
|
33
46
|
end
|
34
47
|
|
48
|
+
# rubocop:disable Lint/UnusedMethodArgument
|
35
49
|
def install(pips, filter_uptodate_packages: false, install_only: false)
|
36
50
|
guess_pip_program
|
37
|
-
if pips.is_a?(String)
|
38
|
-
pips = [pips]
|
39
|
-
end
|
51
|
+
pips = [pips] if pips.is_a?(String)
|
40
52
|
|
41
|
-
base_cmdline = [Autobuild.tool('pip'), 'install','--user']
|
53
|
+
base_cmdline = [Autobuild.tool('pip'), 'install', '--user']
|
42
54
|
|
43
55
|
cmdlines = [base_cmdline + pips]
|
44
56
|
|
45
|
-
if pips_interaction(
|
46
|
-
Autoproj.message " installing/updating Python dependencies:
|
47
|
-
"#{pips.sort.join(
|
57
|
+
if pips_interaction(cmdlines)
|
58
|
+
Autoproj.message " installing/updating Python dependencies:" \
|
59
|
+
" #{pips.sort.join(', ')}"
|
48
60
|
|
49
61
|
cmdlines.each do |c|
|
50
62
|
Autobuild::Subprocess.run 'autoproj', 'osdeps', *c,
|
51
|
-
|
63
|
+
env: ws.env.resolved_env
|
52
64
|
end
|
53
65
|
|
54
66
|
pips.each do |p|
|
@@ -56,8 +68,9 @@ module Autoproj
|
|
56
68
|
end
|
57
69
|
end
|
58
70
|
end
|
59
|
-
|
60
|
-
|
71
|
+
# rubocop:enable Lint/UnusedMethodArgument
|
72
|
+
|
73
|
+
def pips_interaction(cmdlines)
|
61
74
|
if OSPackageInstaller.force_osdeps
|
62
75
|
return true
|
63
76
|
elsif enabled?
|
@@ -69,24 +82,23 @@ module Autoproj
|
|
69
82
|
# We're not supposed to install rubygem packages but silent is not
|
70
83
|
# set, so display information about them anyway
|
71
84
|
puts <<-EOMSG
|
72
|
-
#{Autoproj.color(
|
73
|
-
#{Autoproj.color(
|
85
|
+
#{Autoproj.color('The build process and/or the packages require some Python packages to be installed', :bold)}
|
86
|
+
#{Autoproj.color('and you required autoproj to not do it itself', :bold)}
|
74
87
|
The following command line can be used to install them manually
|
75
|
-
|
76
|
-
#{cmdlines.map { |c| c.join(
|
77
|
-
|
88
|
+
#{' '}
|
89
|
+
#{cmdlines.map { |c| c.join(' ') }.join("\n ")}
|
90
|
+
#{' '}
|
78
91
|
Autoproj expects these Python packages to be installed in #{pip_home} This can
|
79
92
|
be overridden by setting the AUTOPROJ_PYTHONUSERBASE environment variable manually
|
80
93
|
|
81
94
|
EOMSG
|
82
|
-
print " #{Autoproj.color(
|
95
|
+
print " #{Autoproj.color('Press ENTER to continue ', :bold)}"
|
83
96
|
|
84
|
-
|
85
|
-
|
97
|
+
$stdout.flush
|
98
|
+
$stdin.readline
|
86
99
|
puts
|
87
100
|
false
|
88
101
|
end
|
89
102
|
end
|
90
103
|
end
|
91
104
|
end
|
92
|
-
|
@@ -7,8 +7,10 @@ module Autoproj
|
|
7
7
|
if with_locking
|
8
8
|
File.open('/tmp/autoproj_osdeps_lock', 'w') do |lock_io|
|
9
9
|
begin
|
10
|
-
|
11
|
-
Autoproj.message " waiting for other autoproj
|
10
|
+
until lock_io.flock(File::LOCK_EX | File::LOCK_NB)
|
11
|
+
Autoproj.message " waiting for other autoproj "\
|
12
|
+
"instances to finish their osdeps "\
|
13
|
+
"installation"
|
12
14
|
sleep 5
|
13
15
|
end
|
14
16
|
return execute(command_line, false, with_root, env: env)
|
@@ -17,7 +19,7 @@ module Autoproj
|
|
17
19
|
end
|
18
20
|
end
|
19
21
|
end
|
20
|
-
|
22
|
+
|
21
23
|
if with_root
|
22
24
|
sudo = Autobuild.tool_in_path('sudo', env: env)
|
23
25
|
command_line = [sudo, *command_line]
|
@@ -34,10 +36,12 @@ module Autoproj
|
|
34
36
|
# This declares if this package manager cannot be used concurrently.
|
35
37
|
# If it is the case, autoproj will ensure that there is no two
|
36
38
|
# autoproj instances running this package manager at the same time
|
37
|
-
#
|
39
|
+
#
|
38
40
|
# @return [Boolean]
|
39
41
|
# @see needs_locking=
|
40
|
-
def needs_locking
|
42
|
+
def needs_locking?
|
43
|
+
@needs_locking
|
44
|
+
end
|
41
45
|
|
42
46
|
# Overrides the {#needs_root?} flag
|
43
47
|
attr_writer :needs_root
|
@@ -45,10 +49,12 @@ module Autoproj
|
|
45
49
|
#
|
46
50
|
# This declares if the command line(s) for this package manager
|
47
51
|
# should be started as root. Root access is provided using sudo
|
48
|
-
#
|
52
|
+
#
|
49
53
|
# @return [Boolean]
|
50
54
|
# @see needs_root=
|
51
|
-
def needs_root
|
55
|
+
def needs_root?
|
56
|
+
@needs_root
|
57
|
+
end
|
52
58
|
|
53
59
|
# Command line used by autoproj to install packages
|
54
60
|
#
|
@@ -83,10 +89,13 @@ module Autoproj
|
|
83
89
|
# itself, see {#auto_install_cmd}.
|
84
90
|
# @param [Boolean] needs_root if the command lines should be started
|
85
91
|
# as root or not. See {#needs_root?}
|
86
|
-
def initialize(ws, needs_locking, user_install_cmd,
|
92
|
+
def initialize(ws, needs_locking, user_install_cmd,
|
93
|
+
auto_install_cmd, needs_root = true)
|
87
94
|
super(ws)
|
88
|
-
@needs_locking
|
89
|
-
|
95
|
+
@needs_locking = needs_locking
|
96
|
+
@user_install_cmd = user_install_cmd
|
97
|
+
@auto_install_cmd = auto_install_cmd
|
98
|
+
@needs_root = needs_root
|
90
99
|
end
|
91
100
|
|
92
101
|
# Generate the shell script that would allow the user to install
|
@@ -98,7 +107,8 @@ module Autoproj
|
|
98
107
|
# command-line pattern that should be used to generate the script.
|
99
108
|
# If given, it overrides the default value stored in
|
100
109
|
# {#user_install_cmd]
|
101
|
-
def generate_user_os_script(os_packages,
|
110
|
+
def generate_user_os_script(os_packages,
|
111
|
+
user_install_cmd: self.user_install_cmd)
|
102
112
|
if user_install_cmd
|
103
113
|
user_install_cmd.join(" ") + " " + os_packages.join("' '")
|
104
114
|
else generate_auto_os_script(os_packages)
|
@@ -114,7 +124,8 @@ module Autoproj
|
|
114
124
|
# command-line pattern that should be used to generate the script.
|
115
125
|
# If given, it overrides the default value stored in
|
116
126
|
# {#auto_install_cmd]
|
117
|
-
def generate_auto_os_script(os_packages,
|
127
|
+
def generate_auto_os_script(os_packages,
|
128
|
+
auto_install_cmd: self.auto_install_cmd)
|
118
129
|
auto_install_cmd.join(" ") + " " + os_packages.join("' '")
|
119
130
|
end
|
120
131
|
|
@@ -139,9 +150,9 @@ module Autoproj
|
|
139
150
|
# anyway, do so now
|
140
151
|
puts <<-EOMSG
|
141
152
|
|
142
|
-
#{Autoproj.color(
|
143
|
-
#{Autoproj.color(
|
144
|
-
#{Autoproj.color(
|
153
|
+
#{Autoproj.color('The build process and/or the packages require some other software to be installed', :bold)}
|
154
|
+
#{Autoproj.color('and you required autoproj to not install them itself', :bold)}
|
155
|
+
#{Autoproj.color('\nIf these packages are already installed, simply ignore this message\n', :red) unless respond_to?(:filter_uptodate_packages)}
|
145
156
|
The following packages are available as OS dependencies, i.e. as prebuilt
|
146
157
|
packages provided by your distribution / operating system. You will have to
|
147
158
|
install them manually if they are not already installed
|
@@ -152,8 +163,8 @@ module Autoproj
|
|
152
163
|
|
153
164
|
#{shell_script.split("\n").join("\n| ")}
|
154
165
|
|
155
|
-
|
156
|
-
print " #{Autoproj.color(
|
166
|
+
EOMSG
|
167
|
+
print " #{Autoproj.color('Press ENTER to continue ', :bold)}"
|
157
168
|
STDOUT.flush
|
158
169
|
STDIN.readline
|
159
170
|
puts
|
@@ -172,23 +183,33 @@ module Autoproj
|
|
172
183
|
# packages. See the option in {#generate_auto_os_script}
|
173
184
|
# @return [Boolean] true if packages got installed, false otherwise
|
174
185
|
def install(packages, filter_uptodate_packages: false, install_only: false,
|
175
|
-
auto_install_cmd: self.auto_install_cmd,
|
186
|
+
auto_install_cmd: self.auto_install_cmd,
|
187
|
+
user_install_cmd: self.user_install_cmd)
|
176
188
|
return if packages.empty?
|
177
189
|
|
178
190
|
handled_os = ws.supported_operating_system?
|
179
191
|
if handled_os
|
180
|
-
shell_script = generate_auto_os_script(
|
181
|
-
|
192
|
+
shell_script = generate_auto_os_script(
|
193
|
+
packages, auto_install_cmd: auto_install_cmd
|
194
|
+
)
|
195
|
+
user_shell_script = generate_user_os_script(
|
196
|
+
packages, user_install_cmd: user_install_cmd
|
197
|
+
)
|
182
198
|
end
|
183
199
|
if osdeps_interaction(packages, user_shell_script)
|
184
|
-
Autoproj.message " installing OS packages:
|
200
|
+
Autoproj.message " installing OS packages: "\
|
201
|
+
"#{packages.sort.join(', ')}"
|
185
202
|
|
186
203
|
if Autoproj.verbose
|
187
|
-
Autoproj.message "Generating installation script for
|
204
|
+
Autoproj.message "Generating installation script for "\
|
205
|
+
"non-ruby OS dependencies"
|
188
206
|
Autoproj.message shell_script
|
189
207
|
end
|
190
208
|
|
191
|
-
ShellScriptManager.execute(
|
209
|
+
ShellScriptManager.execute(
|
210
|
+
[*auto_install_cmd, *packages], needs_locking?,
|
211
|
+
needs_root?, env: ws.env
|
212
|
+
)
|
192
213
|
return true
|
193
214
|
end
|
194
215
|
false
|
@@ -196,4 +217,3 @@ module Autoproj
|
|
196
217
|
end
|
197
218
|
end
|
198
219
|
end
|
199
|
-
|
@@ -30,13 +30,15 @@ module Autoproj
|
|
30
30
|
# @param [Boolean] ros_manifest whether the file follows the ROS format
|
31
31
|
# @return [PackageManifest]
|
32
32
|
# @see load
|
33
|
-
def self.parse(package, contents,
|
33
|
+
def self.parse(package, contents,
|
34
|
+
path: '<loaded from string>', loader_class: Loader)
|
34
35
|
manifest = PackageManifest.new(package, path)
|
35
36
|
loader = loader_class.new(path, manifest)
|
36
37
|
begin
|
37
38
|
REXML::Document.parse_stream(contents, loader)
|
38
39
|
rescue REXML::ParseException => e
|
39
|
-
raise Autobuild::PackageException.new(package.name, 'prepare'),
|
40
|
+
raise Autobuild::PackageException.new(package.name, 'prepare'),
|
41
|
+
"invalid #{file}: #{e.message}"
|
40
42
|
end
|
41
43
|
manifest
|
42
44
|
end
|
@@ -45,7 +47,7 @@ module Autoproj
|
|
45
47
|
Dependency = Struct.new :name, :optional, :modes
|
46
48
|
|
47
49
|
# The Autobuild::Package instance this manifest applies on
|
48
|
-
|
50
|
+
attr_accessor :package
|
49
51
|
attr_reader :path
|
50
52
|
attr_accessor :description
|
51
53
|
attr_accessor :brief_description
|
@@ -64,7 +66,7 @@ module Autoproj
|
|
64
66
|
end
|
65
67
|
|
66
68
|
def has_documentation?
|
67
|
-
|
69
|
+
description
|
68
70
|
end
|
69
71
|
|
70
72
|
def documentation
|
@@ -72,7 +74,7 @@ module Autoproj
|
|
72
74
|
end
|
73
75
|
|
74
76
|
def has_short_documentation?
|
75
|
-
|
77
|
+
brief_description
|
76
78
|
end
|
77
79
|
|
78
80
|
def short_documentation
|
@@ -95,11 +97,12 @@ module Autoproj
|
|
95
97
|
# Whether this is a null manifest (used for packages that have actually
|
96
98
|
# no manifest) or not
|
97
99
|
def null?
|
98
|
-
|
100
|
+
@null
|
99
101
|
end
|
100
102
|
|
101
|
-
def each_dependency(in_modes =
|
102
|
-
return enum_for(__method__, in_modes)
|
103
|
+
def each_dependency(in_modes = [])
|
104
|
+
return enum_for(__method__, in_modes) unless block_given?
|
105
|
+
|
103
106
|
dependencies.each do |dep|
|
104
107
|
if dep.modes.empty? || in_modes.any? { |m| dep.modes.include?(m) }
|
105
108
|
yield(dep.name, dep.optional)
|
@@ -108,24 +111,28 @@ module Autoproj
|
|
108
111
|
end
|
109
112
|
|
110
113
|
def each_os_dependency(modes = Array.new, &block)
|
111
|
-
Autoproj.warn_deprecated "#{self.class}##{__method__}",
|
112
|
-
|
114
|
+
Autoproj.warn_deprecated "#{self.class}##{__method__}",
|
115
|
+
"call #each_dependency instead"
|
116
|
+
each_dependency(modes, &block)
|
113
117
|
end
|
114
118
|
|
115
119
|
def each_package_dependency(modes = Array.new, &block)
|
116
|
-
Autoproj.warn_deprecated "#{self.class}##{__method__}",
|
117
|
-
|
120
|
+
Autoproj.warn_deprecated "#{self.class}##{__method__}",
|
121
|
+
"call #each_dependency instead"
|
122
|
+
each_dependency(modes, &block)
|
118
123
|
end
|
119
124
|
|
120
125
|
def each_rock_maintainer
|
121
|
-
return enum_for(__method__)
|
126
|
+
return enum_for(__method__) unless block_given?
|
127
|
+
|
122
128
|
rock_maintainers.each do |m|
|
123
129
|
yield(m.name, m.email)
|
124
130
|
end
|
125
131
|
end
|
126
132
|
|
127
133
|
def each_maintainer
|
128
|
-
return enum_for(__method__)
|
134
|
+
return enum_for(__method__) unless block_given?
|
135
|
+
|
129
136
|
maintainers.each do |m|
|
130
137
|
yield(m.name, m.email)
|
131
138
|
end
|
@@ -134,7 +141,8 @@ module Autoproj
|
|
134
141
|
# Enumerates the name and email of each author. If no email is present,
|
135
142
|
# yields (name, nil)
|
136
143
|
def each_author
|
137
|
-
return enum_for(__method__)
|
144
|
+
return enum_for(__method__) unless block_given?
|
145
|
+
|
138
146
|
authors.each do |m|
|
139
147
|
yield(m.name, m.email)
|
140
148
|
end
|
@@ -178,11 +186,13 @@ module Autoproj
|
|
178
186
|
|
179
187
|
def parse_depend_tag(tag_name, attributes, modes: [], optional: false)
|
180
188
|
package = attributes['package'] || attributes['name']
|
181
|
-
|
182
|
-
raise InvalidPackageManifest,
|
189
|
+
unless package
|
190
|
+
raise InvalidPackageManifest,
|
191
|
+
"found '#{tag_name}' tag in #{path} "\
|
192
|
+
"without a 'package' attribute"
|
183
193
|
end
|
184
194
|
|
185
|
-
if tag_modes = attributes['modes']
|
195
|
+
if (tag_modes = attributes['modes'])
|
186
196
|
modes += tag_modes.split(',')
|
187
197
|
end
|
188
198
|
|
@@ -195,7 +205,7 @@ module Autoproj
|
|
195
205
|
def parse_contact_field(text)
|
196
206
|
text.strip.split(',').map do |str|
|
197
207
|
name, email = str.split('/').map(&:strip)
|
198
|
-
email = nil if email
|
208
|
+
email = nil if email&.empty?
|
199
209
|
ContactInfo.new(name, email)
|
200
210
|
end
|
201
211
|
end
|
@@ -213,7 +223,7 @@ module Autoproj
|
|
213
223
|
elsif name =~ /^(\w+)_depend$/
|
214
224
|
parse_depend_tag(name, attributes, modes: [$1])
|
215
225
|
elsif name == 'description'
|
216
|
-
if brief = attributes['brief']
|
226
|
+
if (brief = attributes['brief'])
|
217
227
|
manifest.brief_description = brief
|
218
228
|
end
|
219
229
|
@tag_text = ''
|
@@ -225,14 +235,13 @@ module Autoproj
|
|
225
235
|
@tag_text = nil
|
226
236
|
end
|
227
237
|
end
|
238
|
+
|
228
239
|
def toplevel_tag_end(name)
|
229
240
|
if AUTHOR_FIELDS.include?(name)
|
230
241
|
manifest.send("#{name}s").concat(parse_contact_field(@tag_text))
|
231
242
|
elsif TEXT_FIELDS.include?(name)
|
232
243
|
field = @tag_text.strip
|
233
|
-
|
234
|
-
manifest.send("#{name}=", field)
|
235
|
-
end
|
244
|
+
manifest.send("#{name}=", field) unless field.empty?
|
236
245
|
elsif name == 'tags'
|
237
246
|
manifest.tags.concat(@tag_text.strip.split(',').map(&:strip))
|
238
247
|
end
|
@@ -245,10 +254,10 @@ module Autoproj
|
|
245
254
|
# REXML stream parser object used to load the XML contents into a
|
246
255
|
# {PackageManifest} object
|
247
256
|
class RosLoader < Loader
|
248
|
-
SUPPORTED_MODES = [
|
249
|
-
DEPEND_TAGS =
|
250
|
-
|
251
|
-
|
257
|
+
SUPPORTED_MODES = %w[test doc].freeze
|
258
|
+
DEPEND_TAGS = %w[depend build_depend build_export_depend
|
259
|
+
buildtool_depend buildtool_export_depend
|
260
|
+
exec_depend test_depend run_depend doc_depend].to_set.freeze
|
252
261
|
|
253
262
|
def toplevel_tag_start(name, attributes)
|
254
263
|
if DEPEND_TAGS.include?(name)
|
@@ -265,18 +274,21 @@ module Autoproj
|
|
265
274
|
|
266
275
|
def toplevel_tag_end(name)
|
267
276
|
if DEPEND_TAGS.include?(name)
|
268
|
-
|
277
|
+
if @tag_text.strip.empty?
|
278
|
+
raise InvalidPackageManifest, "found '#{name}' tag in #{path} "\
|
279
|
+
"without content"
|
280
|
+
end
|
269
281
|
|
270
282
|
mode = []
|
271
|
-
if
|
272
|
-
mode = SUPPORTED_MODES & [
|
283
|
+
if (m = /^(\w+)_depend$/.match(name))
|
284
|
+
mode = SUPPORTED_MODES & [m[1]]
|
273
285
|
end
|
274
286
|
|
275
287
|
manifest.add_dependency(@tag_text, modes: mode)
|
276
288
|
elsif AUTHOR_FIELDS.include?(name)
|
277
289
|
author_name = @tag_text.strip
|
278
290
|
email = @author_email ? @author_email.strip : nil
|
279
|
-
email = nil if email
|
291
|
+
email = nil if email&.empty?
|
280
292
|
contact = ContactInfo.new(author_name, email)
|
281
293
|
manifest.send("#{name}s").concat([contact])
|
282
294
|
elsif TEXT_FIELDS.include?(name)
|