autobuild 1.8.3 → 1.9.0.b1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|