autobuild 1.17.0 → 1.21.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 +107 -0
- data/.travis.yml +3 -2
- data/Gemfile +2 -1
- data/Rakefile +1 -4
- data/autobuild.gemspec +18 -13
- data/bin/autobuild +4 -3
- data/lib/autobuild.rb +4 -5
- data/lib/autobuild/build_logfile.rb +6 -4
- data/lib/autobuild/config.rb +104 -41
- data/lib/autobuild/configurable.rb +32 -18
- data/lib/autobuild/environment.rb +126 -120
- data/lib/autobuild/exceptions.rb +48 -31
- data/lib/autobuild/import/archive.rb +134 -82
- data/lib/autobuild/import/cvs.rb +28 -24
- data/lib/autobuild/import/darcs.rb +13 -16
- data/lib/autobuild/import/git-lfs.rb +37 -30
- data/lib/autobuild/import/git.rb +246 -182
- data/lib/autobuild/import/hg.rb +23 -18
- data/lib/autobuild/import/svn.rb +48 -29
- data/lib/autobuild/importer.rb +534 -499
- data/lib/autobuild/mail_reporter.rb +77 -77
- data/lib/autobuild/package.rb +200 -122
- data/lib/autobuild/packages/autotools.rb +47 -42
- data/lib/autobuild/packages/cmake.rb +77 -65
- data/lib/autobuild/packages/dummy.rb +9 -8
- data/lib/autobuild/packages/genom.rb +1 -1
- data/lib/autobuild/packages/gnumake.rb +74 -31
- data/lib/autobuild/packages/import.rb +2 -6
- data/lib/autobuild/packages/orogen.rb +32 -31
- data/lib/autobuild/packages/pkgconfig.rb +2 -2
- data/lib/autobuild/packages/python.rb +12 -8
- data/lib/autobuild/packages/ruby.rb +22 -17
- data/lib/autobuild/parallel.rb +50 -46
- data/lib/autobuild/pkgconfig.rb +25 -13
- data/lib/autobuild/progress_display.rb +149 -64
- data/lib/autobuild/rake_task_extension.rb +12 -7
- data/lib/autobuild/reporting.rb +51 -26
- data/lib/autobuild/subcommand.rb +72 -65
- data/lib/autobuild/test.rb +9 -7
- data/lib/autobuild/test_utility.rb +12 -10
- data/lib/autobuild/timestamps.rb +28 -23
- data/lib/autobuild/tools.rb +17 -16
- data/lib/autobuild/utility.rb +67 -23
- data/lib/autobuild/version.rb +1 -1
- metadata +53 -37
data/lib/autobuild/test.rb
CHANGED
@@ -44,7 +44,7 @@ def setup
|
|
44
44
|
@temp_dirs = Array.new
|
45
45
|
|
46
46
|
@tempdir = make_tmpdir
|
47
|
-
FileUtils.mkdir_p(@tempdir, :
|
47
|
+
FileUtils.mkdir_p(@tempdir, mode: 0o700)
|
48
48
|
Autobuild.logdir = "#{tempdir}/log"
|
49
49
|
FileUtils.mkdir_p Autobuild.logdir
|
50
50
|
Autobuild.silent = true
|
@@ -57,6 +57,7 @@ def teardown
|
|
57
57
|
|
58
58
|
Autobuild::Package.clear
|
59
59
|
Rake::Task.clear
|
60
|
+
Autobuild.reset_gnumake_detection
|
60
61
|
|
61
62
|
@temp_dirs.each do |dir|
|
62
63
|
FileUtils.rm_rf dir
|
@@ -75,20 +76,21 @@ def data_dir
|
|
75
76
|
attr_reader :tempdir
|
76
77
|
|
77
78
|
def build_config(bind, template)
|
78
|
-
|
79
|
-
ryml = File.open(File.join(data_dir, "#{template}.ryml")
|
79
|
+
bind.local_variable_set(:basedir, tempdir.to_s)
|
80
|
+
ryml = File.open(File.join(data_dir, "#{template}.ryml"), &:readlines)
|
81
|
+
.join('')
|
80
82
|
result = ERB.new(ryml).result(bind)
|
81
83
|
|
82
84
|
yml = File.join(tempdir, "#{template}.yml")
|
83
85
|
File.open(yml, 'w+') { |f| f.write(result) }
|
84
|
-
|
85
|
-
|
86
|
+
|
87
|
+
yml
|
86
88
|
end
|
87
89
|
|
88
90
|
def untar(file)
|
89
91
|
file = File.expand_path(file, data_dir)
|
90
|
-
dir =
|
91
|
-
Dir.chdir(dir) do
|
92
|
+
dir = tempdir
|
93
|
+
Dir.chdir(dir) do
|
92
94
|
system("tar xf #{file}")
|
93
95
|
end
|
94
96
|
|
@@ -29,16 +29,14 @@ def coverage_enabled?
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def coverage_available?
|
32
|
-
|
32
|
+
@coverage_source_dir
|
33
33
|
end
|
34
34
|
|
35
35
|
# Controls whether code coverage should be measured
|
36
36
|
#
|
37
37
|
# @param [Boolean,nil] flag enable or disable code coverage. If set to
|
38
38
|
# nil, will use the default from {TestUtility.coverage?}
|
39
|
-
|
40
|
-
@coverage_enabled = flag
|
41
|
-
end
|
39
|
+
attr_writer :coverage_enabled
|
42
40
|
|
43
41
|
# Where the code coverage will be generated
|
44
42
|
#
|
@@ -75,7 +73,8 @@ def coverage_source_dir
|
|
75
73
|
def coverage_target_dir
|
76
74
|
if @coverage_target_dir
|
77
75
|
File.expand_path(@coverage_target_dir, package.prefix)
|
78
|
-
|
76
|
+
elsif (target_dir = self.target_dir)
|
77
|
+
File.join(target_dir, 'coverage')
|
79
78
|
end
|
80
79
|
end
|
81
80
|
|
@@ -85,21 +84,24 @@ def install
|
|
85
84
|
if !coverage_enabled?
|
86
85
|
return
|
87
86
|
elsif !coverage_available?
|
88
|
-
package.warn "%s: #coverage_source_dir not set on #test_utility,
|
87
|
+
package.warn "%s: #coverage_source_dir not set on #test_utility, "\
|
88
|
+
"skipping installation of the code coverage results"
|
89
89
|
end
|
90
90
|
|
91
91
|
coverage_target_dir = self.coverage_target_dir
|
92
92
|
coverage_source_dir = self.coverage_source_dir
|
93
93
|
if "#{coverage_source_dir}/".start_with?("#{source_dir}/")
|
94
|
-
raise ArgumentError, "#coverage_source_dir cannot be a subdirectory
|
94
|
+
raise ArgumentError, "#coverage_source_dir cannot be a subdirectory "\
|
95
|
+
"of #source_dir in #{package.name}"
|
95
96
|
elsif target_dir == coverage_target_dir
|
96
|
-
raise ArgumentError, "#coverage_target_dir cannot be the same than of
|
97
|
+
raise ArgumentError, "#coverage_target_dir cannot be the same than of "\
|
98
|
+
"#target_dir in #{package.name}"
|
97
99
|
end
|
98
100
|
|
99
101
|
FileUtils.mkdir_p File.dirname(coverage_target_dir)
|
100
102
|
FileUtils.cp_r coverage_source_dir, coverage_target_dir
|
101
|
-
package.message "%s: copied test coverage results for #{package.name} from
|
103
|
+
package.message "%s: copied test coverage results for #{package.name} from "\
|
104
|
+
"#{coverage_source_dir} to #{coverage_target_dir}"
|
102
105
|
end
|
103
106
|
end
|
104
107
|
end
|
105
|
-
|
data/lib/autobuild/timestamps.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Autobuild
|
2
|
-
STAMPFILE = "autobuild-stamp"
|
2
|
+
STAMPFILE = "autobuild-stamp".freeze
|
3
3
|
|
4
4
|
class << self
|
5
5
|
# The set of global ignores for SourceTreeTask
|
@@ -15,17 +15,18 @@ class << self
|
|
15
15
|
# The matching paths will not be considered when looking if a source tree
|
16
16
|
# has been updated or not.
|
17
17
|
def self.ignore(path)
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
ignored_files <<
|
19
|
+
if path.kind_of?(Regexp)
|
20
|
+
path
|
21
|
+
else
|
22
|
+
Regexp.new("^#{Regexp.quote(path)}")
|
23
|
+
end
|
23
24
|
end
|
24
25
|
|
25
26
|
def self.tree_timestamp(path, *exclude)
|
26
27
|
# Exclude autobuild timestamps
|
27
|
-
exclude <<
|
28
|
-
exclude <<
|
28
|
+
exclude << /#{Regexp.quote(STAMPFILE)}$/
|
29
|
+
exclude << /\.autobuild-patches$/
|
29
30
|
|
30
31
|
Autobuild.message "getting tree timestamp for #{path}" if Autobuild.debug
|
31
32
|
latest = Time.at(0)
|
@@ -33,13 +34,15 @@ def self.tree_timestamp(path, *exclude)
|
|
33
34
|
|
34
35
|
Find.find(path) do |p|
|
35
36
|
Find.prune if File.basename(p) =~ /^\./
|
36
|
-
exclude.each do |pattern|
|
37
|
+
exclude.each do |pattern|
|
37
38
|
if pattern === p
|
38
|
-
|
39
|
+
if Autobuild.debug
|
40
|
+
Autobuild.message " excluding #{p} because of #{pattern}"
|
41
|
+
end
|
39
42
|
Find.prune
|
40
43
|
end
|
41
44
|
end
|
42
|
-
next
|
45
|
+
next unless File.file?(p)
|
43
46
|
|
44
47
|
p_time = File.mtime(p)
|
45
48
|
if latest < p_time
|
@@ -49,7 +52,7 @@ def self.tree_timestamp(path, *exclude)
|
|
49
52
|
end
|
50
53
|
|
51
54
|
Autobuild.message " newest file: #{latest_file} at #{latest}" if Autobuild.debug
|
52
|
-
|
55
|
+
[latest_file, latest]
|
53
56
|
end
|
54
57
|
|
55
58
|
class SourceTreeTask < Rake::Task
|
@@ -62,26 +65,28 @@ def initialize(*args, &block)
|
|
62
65
|
@exclude = Autobuild.ignored_files.dup
|
63
66
|
super
|
64
67
|
end
|
65
|
-
|
68
|
+
|
66
69
|
def timestamp
|
67
|
-
if @newest_time
|
68
|
-
return @newest_time
|
69
|
-
end
|
70
|
+
return @newest_time if @newest_time
|
70
71
|
|
71
72
|
@newest_file, @newest_time =
|
72
|
-
Autobuild.tree_timestamp(name,
|
73
|
+
Autobuild.tree_timestamp(name,
|
74
|
+
%r{(?:^|/)(?:CVS|_darcs|\.svn)$}, *@exclude)
|
73
75
|
@newest_time
|
74
76
|
end
|
75
77
|
end
|
76
78
|
def self.source_tree(path, &block)
|
77
79
|
task = SourceTreeTask.define_task(path)
|
78
|
-
block
|
80
|
+
block&.call(task)
|
79
81
|
task
|
80
82
|
end
|
81
|
-
|
83
|
+
|
82
84
|
def self.get_stamp(stampfile)
|
83
|
-
|
84
|
-
|
85
|
+
if File.exist?(stampfile)
|
86
|
+
File.mtime(stampfile)
|
87
|
+
else
|
88
|
+
Time.at(0)
|
89
|
+
end
|
85
90
|
end
|
86
91
|
|
87
92
|
def self.hires_modification_time?
|
@@ -103,9 +108,10 @@ def self.touch_stamp(stampfile)
|
|
103
108
|
elsif !File.exist?(dir)
|
104
109
|
FileUtils.mkdir_p dir
|
105
110
|
end
|
111
|
+
|
106
112
|
FileUtils.touch(stampfile)
|
107
113
|
|
108
|
-
|
114
|
+
unless hires_modification_time?
|
109
115
|
# File modification times on most Unix filesystems have a granularity of
|
110
116
|
# one second, so we (unfortunately) have to sleep 1s to make sure that
|
111
117
|
# time comparisons will work as expected.
|
@@ -113,4 +119,3 @@ def self.touch_stamp(stampfile)
|
|
113
119
|
end
|
114
120
|
end
|
115
121
|
end
|
116
|
-
|
data/lib/autobuild/tools.rb
CHANGED
@@ -2,7 +2,7 @@ module Autobuild
|
|
2
2
|
class << self
|
3
3
|
# Configure the programs used by different packages
|
4
4
|
attr_reader :programs
|
5
|
-
# A cache of entries in programs to their resolved full path
|
5
|
+
# A cache of entries in programs to their resolved full path
|
6
6
|
#
|
7
7
|
# @return [{String=>[String,String,String]}] the triplet (full path,
|
8
8
|
# tool name, value of ENV['PATH']). The last two values are used to
|
@@ -13,7 +13,7 @@ class << self
|
|
13
13
|
|
14
14
|
# Get a given program, using its name as default value. For
|
15
15
|
# instance
|
16
|
-
# tool('automake')
|
16
|
+
# tool('automake')
|
17
17
|
# will return 'automake' unless the autobuild script defined
|
18
18
|
# another automake program in Autobuild.programs by doing
|
19
19
|
# Autobuild.programs['automake'] = 'automake1.9'
|
@@ -30,29 +30,30 @@ def find_in_path(file, envvar = 'PATH')
|
|
30
30
|
def tool_in_path(name, env: self.env)
|
31
31
|
path, path_name, path_env = programs_in_path[name]
|
32
32
|
current = tool(name)
|
33
|
-
|
34
|
-
if (path_env !=
|
33
|
+
env_path = env.resolved_env['PATH']
|
34
|
+
if (path_env != env_path) || (path_name != current)
|
35
35
|
# Delete the current entry given that it is invalid
|
36
36
|
programs_in_path.delete(name)
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
path =
|
38
|
+
if current[0, 1] == "/"
|
39
|
+
# This is already a full path
|
40
|
+
current
|
41
|
+
else
|
42
|
+
env.find_executable_in_path(current)
|
43
|
+
end
|
44
|
+
|
45
|
+
unless path
|
46
|
+
raise ArgumentError, "tool #{name}, set to #{current}, "\
|
47
|
+
"can not be found in PATH=#{env_path}"
|
42
48
|
end
|
43
49
|
|
44
|
-
|
45
|
-
raise ArgumentError, "tool #{name}, set to #{current}, can not be found in PATH=#{env_PATH}"
|
46
|
-
end
|
47
|
-
|
48
|
-
programs_in_path[name] = [path, current, env_PATH]
|
50
|
+
programs_in_path[name] = [path, current, env_path]
|
49
51
|
end
|
50
52
|
|
51
|
-
|
53
|
+
path
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
55
57
|
@programs = Hash.new
|
56
58
|
@programs_in_path = Hash.new
|
57
59
|
end
|
58
|
-
|
data/lib/autobuild/utility.rb
CHANGED
@@ -28,7 +28,12 @@ def initialize(name, package, install_on_error: false)
|
|
28
28
|
@source_ref_dir = nil
|
29
29
|
@source_dir = nil
|
30
30
|
@target_dir = nil
|
31
|
-
@install_on_error =
|
31
|
+
@install_on_error = install_on_error
|
32
|
+
|
33
|
+
@no_results = false
|
34
|
+
@invoked = false
|
35
|
+
@success = false
|
36
|
+
@installed = false
|
32
37
|
end
|
33
38
|
|
34
39
|
# Directory in which the utility will generate some files The
|
@@ -43,9 +48,7 @@ def initialize(name, package, install_on_error: false)
|
|
43
48
|
# Absolute path to where this utulity should output its results. Returns nil if
|
44
49
|
# {source_dir} has not been set.
|
45
50
|
def source_dir
|
46
|
-
if @source_dir
|
47
|
-
File.expand_path(@source_dir, source_ref_dir || package.srcdir)
|
48
|
-
end
|
51
|
+
File.expand_path(@source_dir, source_ref_dir || package.srcdir) if @source_dir
|
49
52
|
end
|
50
53
|
|
51
54
|
# Directory in which the utility would install some files.
|
@@ -56,13 +59,32 @@ def source_dir
|
|
56
59
|
# not install anything
|
57
60
|
attr_writer :target_dir
|
58
61
|
|
62
|
+
# Controls whether this utility generates results or not
|
63
|
+
#
|
64
|
+
# By default, Autobuild assumes that utilities generate report or
|
65
|
+
# artifact files, that are saved in {#target_dir}. Set this flag to
|
66
|
+
# true to disable this behavior, in which case the only report will
|
67
|
+
# be the console output during run
|
68
|
+
#
|
69
|
+
# @see no_results?
|
70
|
+
attr_writer :no_results
|
71
|
+
|
72
|
+
# Whether this utility generates results or not
|
73
|
+
#
|
74
|
+
# @see no_results=
|
75
|
+
def no_results?
|
76
|
+
@no_results
|
77
|
+
end
|
78
|
+
|
59
79
|
# Absolute path to where the utility product files have to be installed.
|
60
80
|
# Returns nil if {target_dir} is not set.
|
61
81
|
#
|
62
82
|
# @return [String,nil]
|
63
83
|
def target_dir
|
64
84
|
if @target_dir
|
65
|
-
|
85
|
+
utility_prefix = Autobuild.send("#{name}_prefix") || name
|
86
|
+
File.expand_path(@target_dir,
|
87
|
+
File.expand_path(utility_prefix, package.prefix))
|
66
88
|
else
|
67
89
|
File.join(package.logdir, "#{name}-results", package.name)
|
68
90
|
end
|
@@ -79,6 +101,7 @@ def target_dir
|
|
79
101
|
# @return [Rake::Task]
|
80
102
|
def task(&block)
|
81
103
|
return if @task
|
104
|
+
|
82
105
|
@task = package.task task_name do
|
83
106
|
# This flag allows to disable this utility's task
|
84
107
|
# once {task} has been called
|
@@ -92,25 +115,26 @@ def task(&block)
|
|
92
115
|
end
|
93
116
|
end
|
94
117
|
|
95
|
-
package.task name => task_name
|
118
|
+
package.task name => task_name
|
96
119
|
@task
|
97
120
|
end
|
98
121
|
|
99
122
|
def call_task_block
|
100
|
-
|
123
|
+
@invoked = true
|
101
124
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
125
|
+
begin
|
126
|
+
yield if block_given?
|
127
|
+
@success = true
|
128
|
+
rescue StandardError => e
|
129
|
+
install if install_on_error? && !@installed && !no_results?
|
130
|
+
raise
|
106
131
|
end
|
107
132
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
end
|
133
|
+
# Allow the user to install manually in the task
|
134
|
+
# block
|
135
|
+
install if !@installed && !no_results?
|
136
|
+
rescue StandardError => e
|
137
|
+
@success = false
|
114
138
|
|
115
139
|
if Autobuild.send("pass_#{name}_errors")
|
116
140
|
raise
|
@@ -132,7 +156,7 @@ def call_task_block
|
|
132
156
|
#
|
133
157
|
# @return [Boolean]
|
134
158
|
def available?
|
135
|
-
@available &&
|
159
|
+
@available && @task && (no_results? || source_dir)
|
136
160
|
end
|
137
161
|
|
138
162
|
# True if this utility should be executed
|
@@ -154,8 +178,10 @@ def enabled?
|
|
154
178
|
attr_writer :enabled
|
155
179
|
|
156
180
|
def install
|
157
|
-
|
158
|
-
raise "#{source_dir} was expected to be a directory, but it is not.
|
181
|
+
unless File.directory?(source_dir)
|
182
|
+
raise "#{source_dir} was expected to be a directory, but it is not. "\
|
183
|
+
"Check the package's #{name} generation. "\
|
184
|
+
"The generated #{name} products should be in #{source_dir}"
|
159
185
|
end
|
160
186
|
|
161
187
|
target_dir = self.target_dir
|
@@ -163,11 +189,30 @@ def install
|
|
163
189
|
FileUtils.rm_rf target_dir
|
164
190
|
FileUtils.mkdir_p File.dirname(target_dir)
|
165
191
|
FileUtils.cp_r source_dir, target_dir
|
166
|
-
Autoproj.message " copied #{name} results for #{package.name}
|
192
|
+
Autoproj.message " copied #{name} results for #{package.name} "\
|
193
|
+
"from #{source_dir} to #{target_dir}"
|
167
194
|
|
168
195
|
@installed = true
|
169
196
|
end
|
170
197
|
|
198
|
+
# True if the utility has been invoked
|
199
|
+
def invoked?
|
200
|
+
@invoked
|
201
|
+
end
|
202
|
+
|
203
|
+
# True if the utility has been successful
|
204
|
+
#
|
205
|
+
# Combine with {#invoked?} to determine whether 'false' means 'not run'
|
206
|
+
# or 'failed'
|
207
|
+
def success?
|
208
|
+
@success
|
209
|
+
end
|
210
|
+
|
211
|
+
# True if the utility's results have been installed
|
212
|
+
def installed?
|
213
|
+
@installed
|
214
|
+
end
|
215
|
+
|
171
216
|
# Can be called in the block given to {task} to announce that the
|
172
217
|
# utility is to be disabled for that package. This is mainly used
|
173
218
|
# when a runtime check is necessary to know if a package can run
|
@@ -188,8 +233,7 @@ def task_name
|
|
188
233
|
#
|
189
234
|
# @return [Boolean]
|
190
235
|
def has_task?
|
191
|
-
|
236
|
+
Rake.application.lookup(task_name)
|
192
237
|
end
|
193
238
|
end
|
194
239
|
end
|
195
|
-
|
data/lib/autobuild/version.rb
CHANGED