autobuild 1.8.3 → 1.9.0.b1
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/Manifest.txt +16 -7
- data/Rakefile +2 -0
- data/lib/autobuild/config.rb +21 -6
- data/lib/autobuild/configurable.rb +2 -2
- data/lib/autobuild/environment.rb +52 -27
- data/lib/autobuild/exceptions.rb +48 -22
- data/lib/autobuild/import/archive.rb +37 -16
- data/lib/autobuild/import/cvs.rb +26 -28
- data/lib/autobuild/import/darcs.rb +9 -8
- data/lib/autobuild/import/git.rb +324 -217
- data/lib/autobuild/import/hg.rb +6 -9
- data/lib/autobuild/import/svn.rb +190 -47
- data/lib/autobuild/importer.rb +80 -35
- data/lib/autobuild/package.rb +16 -35
- data/lib/autobuild/packages/autotools.rb +8 -8
- data/lib/autobuild/packages/cmake.rb +18 -12
- data/lib/autobuild/packages/genom.rb +1 -1
- data/lib/autobuild/packages/gnumake.rb +11 -12
- data/lib/autobuild/packages/orogen.rb +1 -1
- data/lib/autobuild/packages/ruby.rb +9 -5
- data/lib/autobuild/reporting.rb +10 -6
- data/lib/autobuild/subcommand.rb +110 -50
- data/lib/autobuild/test.rb +104 -0
- data/lib/autobuild/timestamps.rb +3 -3
- data/lib/autobuild/tools.rb +1 -1
- data/lib/autobuild/utility.rb +22 -10
- data/lib/autobuild/version.rb +1 -1
- data/test/data/gitrepo-with-extra-commit-and-tag.tar +0 -0
- data/test/data/gitrepo.tar +0 -0
- data/test/data/gitrepo/test +0 -0
- data/test/data/gitrepo/test2 +0 -0
- data/test/data/gitrepo/test3 +0 -0
- data/test/data/svnroot.tar +0 -0
- data/test/import/test_cvs.rb +51 -0
- data/test/import/test_git.rb +364 -0
- data/test/import/test_svn.rb +144 -0
- data/test/import/test_tar.rb +76 -0
- data/test/suite.rb +7 -0
- data/test/test_config.rb +1 -5
- data/test/test_environment.rb +88 -0
- data/test/test_reporting.rb +2 -14
- data/test/test_subcommand.rb +7 -22
- metadata +17 -14
- data/test/test_import_cvs.rb +0 -59
- data/test/test_import_svn.rb +0 -56
- data/test/test_import_tar.rb +0 -83
- data/test/tools.rb +0 -44
data/lib/autobuild/import/hg.rb
CHANGED
@@ -49,16 +49,14 @@ module Autobuild
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
def update(package,
|
53
|
-
if only_local
|
54
|
-
|
52
|
+
def update(package, options = Hash.new)
|
53
|
+
if options[:only_local]
|
54
|
+
package.warn "%s: the Mercurial importer does not support local updates, skipping"
|
55
55
|
return
|
56
56
|
end
|
57
57
|
validate_importdir(package)
|
58
|
-
|
59
|
-
|
60
|
-
Subprocess.run(package, :import, Autobuild.tool('hg'), 'update', branch)
|
61
|
-
end
|
58
|
+
package.run(:import, Autobuild.tool('hg'), 'pull', repository, retry: true, working_directory: package.importdir)
|
59
|
+
package.run(:import, Autobuild.tool('hg'), 'update', branch, working_directory: package.importdir)
|
62
60
|
end
|
63
61
|
|
64
62
|
def checkout(package)
|
@@ -67,8 +65,7 @@ module Autobuild
|
|
67
65
|
FileUtils.mkdir_p base_dir
|
68
66
|
end
|
69
67
|
|
70
|
-
|
71
|
-
Autobuild.tool('hg'), 'clone', '-u', branch, repository, package.importdir)
|
68
|
+
package.run(:import, Autobuild.tool('hg'), 'clone', '-u', branch, repository, package.importdir, retry: true)
|
72
69
|
end
|
73
70
|
end
|
74
71
|
|
data/lib/autobuild/import/svn.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'autobuild/subcommand'
|
2
2
|
require 'autobuild/importer'
|
3
|
+
require 'rexml/document'
|
3
4
|
|
4
5
|
module Autobuild
|
5
6
|
class SVN < Importer
|
@@ -11,67 +12,209 @@ module Autobuild
|
|
11
12
|
# This importer uses the 'svn' tool to perform the import. It defaults
|
12
13
|
# to 'svn' and can be configured by doing
|
13
14
|
# Autobuild.programs['svn'] = 'my_svn_tool'
|
14
|
-
def initialize(
|
15
|
-
|
16
|
-
@source = [*source].join("/")
|
15
|
+
def initialize(svnroot, options = {})
|
16
|
+
svnroot = [*svnroot].join("/")
|
17
17
|
svnopts, common = Kernel.filter_options options,
|
18
18
|
:svnup => [], :svnco => [], :revision => nil,
|
19
|
-
:repository_id => "svn:#{
|
20
|
-
|
21
|
-
|
22
|
-
@options_co = [*svnopts[:svnco]]
|
23
|
-
if rev = svnopts[:revision]
|
24
|
-
@options_up << "--revision" << rev
|
25
|
-
@options_co << "--revision" << rev
|
26
|
-
end
|
19
|
+
:repository_id => "svn:#{svnroot}"
|
20
|
+
common[:repository_id] = svnopts.delete(:repository_id)
|
21
|
+
relocate(svnroot, svnopts)
|
27
22
|
super(common.merge(repository_id: svnopts[:repository_id]))
|
28
23
|
end
|
29
24
|
|
30
|
-
|
25
|
+
# @deprecated use {svnroot} instead
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
def source; svnroot end
|
29
|
+
|
30
|
+
# Returns the SVN root
|
31
|
+
#
|
32
|
+
# @return [String]
|
33
|
+
attr_reader :svnroot
|
31
34
|
|
32
|
-
|
35
|
+
attr_reader :revision
|
36
|
+
|
37
|
+
def relocate(root, options = Hash.new)
|
38
|
+
@svnroot = [*root].join("/")
|
39
|
+
@options_up = [*options[:svnup]]
|
40
|
+
@options_co = [*options[:svnco]]
|
41
|
+
@revision = options[:revision]
|
42
|
+
if revision
|
43
|
+
@options_co << '--revision' << revision
|
44
|
+
# We do not add it to @options_up as the behaviour depends on
|
45
|
+
# the parameters given to {update} and to the state of the
|
46
|
+
# working copy
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the SVN revision of the package
|
51
|
+
#
|
52
|
+
# @param [Package] package
|
53
|
+
# @return [Integer]
|
54
|
+
# @raises ConfigException if 'svn info' did not return a Revision field
|
55
|
+
# @raises (see svn_info)
|
56
|
+
def svn_revision(package)
|
57
|
+
svninfo = svn_info(package)
|
58
|
+
revision = svninfo.grep(/^Revision: /).first
|
59
|
+
if !revision
|
60
|
+
raise ConfigException.new(package, 'import'), "cannot get SVN information for #{package.importdir}"
|
61
|
+
end
|
62
|
+
revision =~ /Revision: (\d+)/
|
63
|
+
Integer($1)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns the URL of the remote SVN repository
|
67
|
+
#
|
68
|
+
# @param [Package] package
|
69
|
+
# @return [String]
|
70
|
+
# @raises ConfigException if 'svn info' did not return a URL field
|
71
|
+
# @raises (see svn_info)
|
72
|
+
def svn_url(package)
|
73
|
+
svninfo = svn_info(package)
|
74
|
+
url = svninfo.grep(/^URL: /).first
|
75
|
+
if !url
|
76
|
+
raise ConfigException.new(package, 'import'), "cannot get SVN information for #{package.importdir}"
|
77
|
+
end
|
78
|
+
url.chomp =~ /URL: (.+)/
|
79
|
+
$1
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns true if the SVN working copy at package.importdir has local
|
83
|
+
# modifications
|
84
|
+
#
|
85
|
+
# @param [Package] package the package we want to test against
|
86
|
+
# @param [Boolean] with_untracked_files if true, the presence of files
|
87
|
+
# neither ignored nor under version control will count has local
|
88
|
+
# modification.
|
89
|
+
# @return [Boolean]
|
90
|
+
def has_local_modifications?(package, with_untracked_files = false)
|
91
|
+
status = run_svn(package, 'status', '--xml')
|
92
|
+
|
93
|
+
not_modified = %w{external ignored none normal}
|
94
|
+
if !with_untracked_files
|
95
|
+
not_modified << "unversioned"
|
96
|
+
end
|
97
|
+
|
98
|
+
REXML::Document.new(status.join("")).
|
99
|
+
elements.enum_for(:each, '//wc-status').
|
100
|
+
any? do |status_item|
|
101
|
+
!not_modified.include?(status_item.attributes['item'].to_s)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns status information for package
|
106
|
+
#
|
107
|
+
# Given that subversion is not a distributed VCS, the only status
|
108
|
+
# returned are either {Status::UP_TO_DATE} or {Status::SIMPLE_UPDATE}.
|
109
|
+
# Moreover, if the status is local-only,
|
110
|
+
# {Package::Status#remote_commits} will not be filled (querying the log
|
111
|
+
# requires accessing the SVN server)
|
112
|
+
#
|
113
|
+
# @return [Package::Status]
|
114
|
+
def status(package, only_local = false)
|
115
|
+
status = Status.new
|
116
|
+
status.uncommitted_code = has_local_modifications?(package)
|
33
117
|
if only_local
|
34
|
-
|
118
|
+
status.status = Status::UP_TO_DATE
|
119
|
+
else
|
120
|
+
log = run_svn(package, 'log', '-r', 'BASE:HEAD', '--xml', '.')
|
121
|
+
log = REXML::Document.new(log.join("\n"))
|
122
|
+
missing_revisions = log.elements.enum_for(:each, 'log/logentry').map do |l|
|
123
|
+
rev = l.attributes['revision']
|
124
|
+
date = l.elements['date'].first.to_s
|
125
|
+
author = l.elements['author'].first.to_s
|
126
|
+
msg = l.elements['msg'].first.to_s.split("\n").first
|
127
|
+
"#{rev} #{DateTime.parse(date)} #{author} #{msg}"
|
128
|
+
end
|
129
|
+
status.remote_commits = missing_revisions[1..-1]
|
130
|
+
status.status =
|
131
|
+
if missing_revisions.empty?
|
132
|
+
Status::UP_TO_DATE
|
133
|
+
else
|
134
|
+
Status::SIMPLE_UPDATE
|
135
|
+
end
|
136
|
+
end
|
137
|
+
status
|
138
|
+
end
|
139
|
+
|
140
|
+
# Helper method to run a SVN command on a package's working copy
|
141
|
+
def run_svn(package, *args, &block)
|
142
|
+
options = Hash.new
|
143
|
+
if args.last.kind_of?(Hash)
|
144
|
+
options = args.pop
|
145
|
+
end
|
146
|
+
options, other_options = Kernel.filter_options options,
|
147
|
+
working_directory: package.importdir, retry: true
|
148
|
+
options = options.merge(other_options)
|
149
|
+
package.run(:import, Autobuild.tool(:svn), *args, options, &block)
|
150
|
+
end
|
151
|
+
|
152
|
+
def validate_importdir(package)
|
153
|
+
# This upgrades the local SVN filesystem if needed and checks that
|
154
|
+
# it actually is a SVN repository in the first place
|
155
|
+
svn_info(package)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Returns the result of the 'svn info' command
|
159
|
+
#
|
160
|
+
# It automatically runs svn upgrade if needed
|
161
|
+
#
|
162
|
+
# @param [Package] package
|
163
|
+
# @return [Array<String>] the lines returned by svn info, with the
|
164
|
+
# trailing newline removed
|
165
|
+
# @raises [SubcommandFailed] if svn info failed
|
166
|
+
# @raises [ConfigException] if the working copy is not a subversion
|
167
|
+
# working copy
|
168
|
+
def svn_info(package)
|
169
|
+
old_lang, ENV['LC_ALL'] = ENV['LC_ALL'], 'C'
|
170
|
+
begin
|
171
|
+
svninfo = run_svn(package, 'info')
|
172
|
+
rescue SubcommandFailed => e
|
173
|
+
if e.output.find { |l| l =~ /svn upgrade/ }
|
174
|
+
# Try svn upgrade and info again
|
175
|
+
run_svn(package, 'upgrade', retry: false)
|
176
|
+
svninfo = run_svn(package, 'info')
|
177
|
+
else raise
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
if !svninfo.grep(/is not a working copy/).empty?
|
182
|
+
raise ConfigException.new(package, 'import'),
|
183
|
+
"#{package.importdir} does not appear to be a Subversion working copy"
|
184
|
+
end
|
185
|
+
svninfo
|
186
|
+
ensure
|
187
|
+
ENV['LC_ALL'] = old_lang
|
188
|
+
end
|
189
|
+
|
190
|
+
def update(package, options = Hash.new) # :nodoc:
|
191
|
+
if options[:only_local]
|
192
|
+
package.warn "%s: the svn importer does not support local updates, skipping"
|
35
193
|
return
|
36
194
|
end
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
52
|
-
else raise
|
53
|
-
end
|
195
|
+
|
196
|
+
url = svn_url(package)
|
197
|
+
if url != svnroot
|
198
|
+
raise ConfigException.new(package, 'import'), "current checkout found at #{package.importdir} is from #{url}, was expecting #{svnroot}"
|
199
|
+
end
|
200
|
+
|
201
|
+
options_up = @options_up.dup
|
202
|
+
if revision
|
203
|
+
if options[:reset] || svn_revision(package) < revision
|
204
|
+
options_up << '--revision' << revision
|
205
|
+
elsif revision
|
206
|
+
# Don't update if the current revision is greater-or-equal
|
207
|
+
# than the target revision
|
208
|
+
return
|
54
209
|
end
|
55
|
-
ENV['LC_ALL'] = old_lang
|
56
|
-
unless url = svninfo.grep(/^URL: /).first
|
57
|
-
if svninfo.grep(/is not a working copy/).empty?
|
58
|
-
raise ConfigException.new(package, 'import'), "#{package.importdir} is not a Subversion working copy"
|
59
|
-
else
|
60
|
-
raise ConfigException.new(package, 'import'), "Bug: cannot get SVN information for #{package.importdir}"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
url.chomp =~ /URL: (.+)/
|
64
|
-
source = $1
|
65
|
-
if source != @source
|
66
|
-
raise ConfigException.new(package, 'import'), "current checkout found at #{package.importdir} is from #{source}, was expecting #{@source}"
|
67
|
-
end
|
68
|
-
Subprocess.run(package, :import, @program, 'up', "--non-interactive", *@options_up)
|
69
210
|
end
|
211
|
+
|
212
|
+
run_svn(package, 'up', "--non-interactive", *options_up)
|
70
213
|
end
|
71
214
|
|
72
215
|
def checkout(package) # :nodoc:
|
73
|
-
|
74
|
-
|
216
|
+
run_svn(package, 'co', "--non-interactive", *@options_co, svnroot, package.importdir,
|
217
|
+
working_directory: nil)
|
75
218
|
end
|
76
219
|
end
|
77
220
|
|
data/lib/autobuild/importer.rb
CHANGED
@@ -53,8 +53,8 @@ class Importer
|
|
53
53
|
# repository and not in the remote one (would be pushed by an update)
|
54
54
|
attr_accessor :local_commits
|
55
55
|
|
56
|
-
def initialize
|
57
|
-
@status =
|
56
|
+
def initialize(status = -1)
|
57
|
+
@status = status
|
58
58
|
@uncommitted_code = false
|
59
59
|
@remote_commits = Array.new
|
60
60
|
@local_commits = Array.new
|
@@ -141,6 +141,18 @@ class Importer
|
|
141
141
|
end
|
142
142
|
end
|
143
143
|
|
144
|
+
def update_retry_count(original_error, retry_count)
|
145
|
+
if !original_error.respond_to?(:retry?) ||
|
146
|
+
!original_error.retry?
|
147
|
+
return
|
148
|
+
end
|
149
|
+
|
150
|
+
retry_count += 1
|
151
|
+
if retry_count <= self.retry_count
|
152
|
+
retry_count
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
144
156
|
def perform_update(package,only_local=false)
|
145
157
|
cur_patches = currently_applied_patches(package)
|
146
158
|
needed_patches = self.patches
|
@@ -176,10 +188,8 @@ class Importer
|
|
176
188
|
end
|
177
189
|
end
|
178
190
|
|
179
|
-
retry_count
|
180
|
-
if retry_count
|
181
|
-
raise
|
182
|
-
end
|
191
|
+
retry_count = update_retry_count(original_error, retry_count)
|
192
|
+
raise if !retry_count
|
183
193
|
package.message "update failed in #{package.importdir}, retrying (#{retry_count}/#{self.retry_count})"
|
184
194
|
retry
|
185
195
|
ensure
|
@@ -201,9 +211,9 @@ class Importer
|
|
201
211
|
checkout(package)
|
202
212
|
rescue Interrupt
|
203
213
|
raise
|
204
|
-
rescue ::Exception
|
205
|
-
retry_count
|
206
|
-
if retry_count
|
214
|
+
rescue ::Exception => original_error
|
215
|
+
retry_count = update_retry_count(original_error, retry_count)
|
216
|
+
if !retry_count
|
207
217
|
raise
|
208
218
|
end
|
209
219
|
package.message "checkout of %s failed, deleting the source directory #{package.importdir} and retrying (#{retry_count}/#{self.retry_count})"
|
@@ -225,13 +235,43 @@ class Importer
|
|
225
235
|
fallback(e, package, :import, package)
|
226
236
|
end
|
227
237
|
|
228
|
-
#
|
229
|
-
|
238
|
+
# Imports the given package
|
239
|
+
#
|
240
|
+
# The importer will checkout or update code in package.importdir. No update
|
241
|
+
# will be done if {update?} returns false.
|
242
|
+
#
|
243
|
+
# @raises ConfigException if package.importdir exists and is not a directory
|
244
|
+
#
|
245
|
+
# @option options [Boolean] :only_local (false) if true, will only perform
|
246
|
+
# actions that do not require network access. Importers that do not
|
247
|
+
# support this mode will simply do nothing
|
248
|
+
# @option options [Boolean] :reset (false) if true, the importer's
|
249
|
+
# configuration is interpreted as a hard state in which it should put the
|
250
|
+
# working copy. Otherwise, it tries to update the local repository with
|
251
|
+
# the remote information. For instance, a git importer for which a commit
|
252
|
+
# ID is given will, in this mode, reset the repository to the requested ID
|
253
|
+
# (if that does not involve losing commits). Otherwise, it will only
|
254
|
+
# ensure that the requested commit ID is present in the current HEAD.
|
255
|
+
def import(package, options = Hash.new)
|
256
|
+
# Backward compatibility
|
257
|
+
if !options.kind_of?(Hash)
|
258
|
+
options = !!options
|
259
|
+
Autoproj.warn "calling #import with a boolean as second argument is deprecated, switch to the named argument interface instead"
|
260
|
+
Autoproj.warn " e.g. call import(package, only_local: #{options})"
|
261
|
+
Autoproj.warn " #{caller(1).first}"
|
262
|
+
options = Hash[only_local: !!options]
|
263
|
+
end
|
264
|
+
|
265
|
+
options = Kernel.validate_options options,
|
266
|
+
only_local: false,
|
267
|
+
reset: false,
|
268
|
+
checkout_only: false
|
269
|
+
|
230
270
|
importdir = package.importdir
|
231
271
|
if File.directory?(importdir)
|
232
272
|
package.isolate_errors(false) do
|
233
|
-
if package.update?
|
234
|
-
perform_update(package,
|
273
|
+
if !options[:checkout_only] && package.update?
|
274
|
+
perform_update(package, options)
|
235
275
|
else
|
236
276
|
if Autobuild.verbose
|
237
277
|
package.message "%s: not updating"
|
@@ -240,7 +280,7 @@ class Importer
|
|
240
280
|
end
|
241
281
|
end
|
242
282
|
|
243
|
-
elsif File.
|
283
|
+
elsif File.exist?(importdir)
|
244
284
|
raise ConfigException.new(package, 'import'), "#{importdir} exists but is not a directory"
|
245
285
|
else
|
246
286
|
perform_checkout(package)
|
@@ -275,23 +315,22 @@ class Importer
|
|
275
315
|
end
|
276
316
|
|
277
317
|
def call_patch(package, reverse, file, patch_level)
|
278
|
-
patch
|
279
|
-
|
280
|
-
|
281
|
-
end
|
318
|
+
package.run(:patch, Autobuild.tool('patch'),
|
319
|
+
"-p#{patch_level}", (reverse ? '-R' : nil), '--forward', input: file,
|
320
|
+
working_directory: package.importdir)
|
282
321
|
end
|
283
322
|
|
284
323
|
def apply(package, path, patch_level = 0); call_patch(package, false, path, patch_level) end
|
285
324
|
def unapply(package, path, patch_level = 0); call_patch(package, true, path, patch_level) end
|
286
325
|
|
287
|
-
def parse_patch_list(patches_file)
|
326
|
+
def parse_patch_list(package, patches_file)
|
288
327
|
File.readlines(patches_file).map do |line|
|
289
328
|
line = line.rstrip
|
290
329
|
if line =~ /^(.*)\s+(\d+)$/
|
291
|
-
path = $1
|
330
|
+
path = File.expand_path($1, package.srcdir)
|
292
331
|
level = Integer($2)
|
293
332
|
else
|
294
|
-
path = line
|
333
|
+
path = File.expand_path(line, package.srcdir)
|
295
334
|
level = 0
|
296
335
|
end
|
297
336
|
[path, level, File.read(path)]
|
@@ -300,13 +339,13 @@ class Importer
|
|
300
339
|
|
301
340
|
def currently_applied_patches(package)
|
302
341
|
patches_file = patchlist(package)
|
303
|
-
if File.
|
304
|
-
return parse_patch_list(patches_file)
|
342
|
+
if File.exist?(patches_file)
|
343
|
+
return parse_patch_list(package, patches_file)
|
305
344
|
end
|
306
345
|
|
307
346
|
patches_file = File.join(package.importdir, "patches-autobuild-stamp")
|
308
|
-
if File.
|
309
|
-
cur_patches = parse_patch_list(patches_file)
|
347
|
+
if File.exist?(patches_file)
|
348
|
+
cur_patches = parse_patch_list(package, patches_file)
|
310
349
|
save_patch_state(package, cur_patches)
|
311
350
|
FileUtils.rm_f patches_file
|
312
351
|
return currently_applied_patches(package)
|
@@ -319,7 +358,9 @@ class Importer
|
|
319
358
|
# Get the list of already applied patches
|
320
359
|
cur_patches = currently_applied_patches(package)
|
321
360
|
|
322
|
-
|
361
|
+
cur_patches_state = cur_patches.map { |_, level, content| [level, content] }
|
362
|
+
patches_state = patches.map { |_, level, content| [level, content] }
|
363
|
+
if cur_patches_state == patches_state
|
323
364
|
return false
|
324
365
|
end
|
325
366
|
|
@@ -342,9 +383,9 @@ class Importer
|
|
342
383
|
cur_patches.pop
|
343
384
|
end
|
344
385
|
|
345
|
-
patches.to_a.each do |
|
346
|
-
apply(package,
|
347
|
-
cur_patches << [
|
386
|
+
patches.to_a.each do |new_patch, new_patch_level, content|
|
387
|
+
apply(package, new_patch, new_patch_level)
|
388
|
+
cur_patches << [new_patch, new_patch_level, content]
|
348
389
|
end
|
349
390
|
ensure
|
350
391
|
save_patch_state(package, cur_patches)
|
@@ -357,14 +398,18 @@ class Importer
|
|
357
398
|
patch_dir = patchdir(package)
|
358
399
|
FileUtils.mkdir_p patch_dir
|
359
400
|
cur_patches = cur_patches.each_with_index.map do |(path, level, content), idx|
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
401
|
+
path = File.join(patch_dir, idx.to_s)
|
402
|
+
File.open(path, 'w') do |patch_io|
|
403
|
+
patch_io.write content
|
404
|
+
end
|
405
|
+
[path, level]
|
365
406
|
end
|
366
407
|
File.open(patchlist(package), 'w') do |f|
|
367
|
-
|
408
|
+
patch_state = cur_patches.map do |path, level|
|
409
|
+
path = Pathname.new(path).relative_path_from( Pathname.new(package.srcdir) ).to_s
|
410
|
+
"#{path} #{level}"
|
411
|
+
end
|
412
|
+
f.write(patch_state.join("\n"))
|
368
413
|
end
|
369
414
|
end
|
370
415
|
|