simp-rake-helpers 3.0.2 → 3.1.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/CHANGELOG.md +4 -0
- data/lib/simp/rake/build/auto.rb +673 -253
- data/lib/simp/rake/build/build.rb +63 -27
- data/lib/simp/rake/build/clean.rb +5 -1
- data/lib/simp/rake/build/code.rb +24 -24
- data/lib/simp/rake/build/constants.rb +94 -15
- data/lib/simp/rake/build/deps.rb +2 -0
- data/lib/simp/rake/build/helpers.rb +1 -1
- data/lib/simp/rake/build/iso.rb +34 -13
- data/lib/simp/rake/build/pkg.rb +162 -141
- data/lib/simp/rake/build/spec.rb +13 -6
- data/lib/simp/rake/build/tar.rb +62 -21
- data/lib/simp/rake/build/unpack.rb +5 -4
- data/lib/simp/rake/build/upload.rb +11 -5
- data/lib/simp/rake/helpers/version.rb +1 -1
- data/lib/simp/rake/pkg.rb +135 -60
- data/lib/simp/rpm.rb +16 -3
- metadata +65 -65
data/lib/simp/rake/build/pkg.rb
CHANGED
@@ -13,6 +13,7 @@ module Simp::Rake::Build
|
|
13
13
|
|
14
14
|
def initialize( base_dir )
|
15
15
|
init_member_vars( base_dir )
|
16
|
+
|
16
17
|
@mock = ENV['mock'] || '/usr/bin/mock'
|
17
18
|
define_tasks
|
18
19
|
end
|
@@ -27,13 +28,17 @@ module Simp::Rake::Build
|
|
27
28
|
end
|
28
29
|
|
29
30
|
namespace :pkg do
|
30
|
-
|
31
31
|
##############################################################################
|
32
32
|
# Main tasks
|
33
33
|
##############################################################################
|
34
34
|
|
35
35
|
# Have to get things set up inside the proper namespace
|
36
36
|
task :prep,[:method] do |t,args|
|
37
|
+
|
38
|
+
if $simp6
|
39
|
+
@build_dir = $simp6_build_dir
|
40
|
+
end
|
41
|
+
|
37
42
|
args.with_defaults(:method => 'tracking')
|
38
43
|
|
39
44
|
@build_dirs = {
|
@@ -57,12 +62,11 @@ module Simp::Rake::Build
|
|
57
62
|
@build_dirs[:aux].delete_if{|f| !File.directory?(f)}
|
58
63
|
|
59
64
|
@pkg_dirs = {
|
60
|
-
:simp => "#{@build_dir}/SIMP"
|
61
|
-
:ext => "#{@build_dir}/Ext_*"
|
65
|
+
:simp => "#{@build_dir}/SIMP"
|
62
66
|
}
|
63
67
|
end
|
64
68
|
|
65
|
-
task :mock_prep do
|
69
|
+
task :mock_prep => [:prep] do
|
66
70
|
chown_everything = ENV.fetch( 'SIMP_RAKE_CHOWN_EVERYTHING', 'Y' ).chomp.index( %r{^(1|Y|true|yes)$}i ) || false
|
67
71
|
|
68
72
|
verbose(true) do
|
@@ -121,7 +125,6 @@ module Simp::Rake::Build
|
|
121
125
|
|
122
126
|
clean_failures = []
|
123
127
|
clean_failures_lock = Mutex.new
|
124
|
-
chroot_scrub_lock = Mutex.new
|
125
128
|
|
126
129
|
task :clean,[:chroot] => [:prep] do |t,args|
|
127
130
|
validate_in_mock_group?
|
@@ -180,127 +183,130 @@ module Simp::Rake::Build
|
|
180
183
|
ENV vars:
|
181
184
|
- Set `SIMP_PKG_verbose=yes` to report file operations as they happen.
|
182
185
|
EOM
|
183
|
-
task :key_prep,[:key] do |t,args|
|
186
|
+
task :key_prep,[:key] => [:prep] do |t,args|
|
184
187
|
require 'securerandom'
|
185
188
|
_verbose = ENV.fetch('SIMP_PKG_verbose','no') == 'yes'
|
186
189
|
|
187
190
|
args.with_defaults(:key => 'dev')
|
188
191
|
|
189
|
-
|
192
|
+
FileUtils.mkdir_p("#{@build_dir}/build_keys")
|
193
|
+
|
194
|
+
Dir.chdir("#{@build_dir}/build_keys") do
|
190
195
|
if (args.key != 'dev')
|
191
196
|
fail("Could not find GPG keydir '#{args[:key]}' in '#{Dir.pwd}'") unless File.directory?(args[:key])
|
192
|
-
|
197
|
+
else
|
193
198
|
|
194
|
-
|
195
|
-
|
199
|
+
mkdir('dev') unless File.directory?('dev')
|
200
|
+
chmod(0700,'dev')
|
196
201
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
202
|
+
Dir.chdir('dev') do
|
203
|
+
dev_email = 'gatekeeper@simp.development.key'
|
204
|
+
current_key = `gpg --homedir=#{Dir.pwd} --list-keys #{dev_email} 2>/dev/null`
|
205
|
+
days_left = 0
|
206
|
+
unless current_key.empty?
|
207
|
+
lasts_until = current_key.lines.first.strip.split("\s").last.delete(']')
|
208
|
+
days_left = (Date.parse(lasts_until) - DateTime.now).to_i
|
209
|
+
end
|
205
210
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
211
|
+
if days_left > 0
|
212
|
+
puts "GPG key will expire in #{days_left} days."
|
213
|
+
else
|
214
|
+
puts "Generating new GPG key"
|
210
215
|
|
211
|
-
|
212
|
-
|
213
|
-
|
216
|
+
Dir.glob('*').each do |todel|
|
217
|
+
rm_rf(todel, :verbose => _verbose)
|
218
|
+
end
|
214
219
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
220
|
+
expire_date = (DateTime.now + 14)
|
221
|
+
now = Time.now.to_i.to_s
|
222
|
+
dev_email = 'gatekeeper@simp.development.key'
|
223
|
+
passphrase = SecureRandom.base64(500)
|
224
|
+
|
225
|
+
gpg_infile = <<-EOM
|
226
|
+
%echo Generating Development GPG Key
|
227
|
+
%echo
|
228
|
+
%echo This key will expire on #{expire_date}
|
229
|
+
%echo
|
230
|
+
Key-Type: RSA
|
231
|
+
Key-Length: 4096
|
232
|
+
Key-Usage: sign
|
233
|
+
Name-Real: SIMP Development
|
234
|
+
Name-Comment: Development key #{now}
|
235
|
+
Name-Email: #{dev_email}
|
236
|
+
Expire-Date: 2w
|
237
|
+
Passphrase: #{passphrase}
|
238
|
+
%pubring pubring.gpg
|
239
|
+
%secring secring.gpg
|
240
|
+
# The following creates the key, so we can print "Done!" afterwards
|
241
|
+
%commit
|
242
|
+
%echo New GPG Development Key Created
|
243
|
+
EOM
|
244
|
+
|
245
|
+
gpg_agent_script = <<-EOM
|
246
|
+
#!/bin/sh
|
247
|
+
|
248
|
+
gpg-agent --homedir=#{Dir.pwd} --batch --daemon --pinentry-program /usr/bin/pinentry-curses < /dev/null &
|
249
|
+
EOM
|
250
|
+
|
251
|
+
File.open('gengpgkey','w'){ |fh| fh.puts(gpg_infile) }
|
252
|
+
File.open('run_gpg_agent','w'){ |fh| fh.puts(gpg_agent_script) }
|
253
|
+
chmod(0755,'run_gpg_agent')
|
254
|
+
|
255
|
+
gpg_agent_pid = nil
|
256
|
+
gpg_agent_socket = nil
|
257
|
+
|
258
|
+
if File.exist?(%(#{ENV['HOME']}/.gnupg/S.gpg-agent))
|
259
|
+
gpg_agent_socket = %(#{ENV['HOME']}/.gnupg/S.gpg-agent)
|
260
|
+
gpg_agent_socket = %(#{ENV['HOME']}/.gnupg/S.gpg-agent)
|
261
|
+
end
|
257
262
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
263
|
+
begin
|
264
|
+
unless gpg_agent_socket
|
265
|
+
gpg_agent_output = %x(./run_gpg_agent).strip
|
266
|
+
|
267
|
+
if gpg_agent_output.empty?
|
268
|
+
# This is a working version of gpg-agent, that means we need to
|
269
|
+
# connect to it to figure out what's going on
|
270
|
+
|
271
|
+
gpg_agent_socket = %(#{Dir.pwd}/S.gpg-agent)
|
272
|
+
gpg_agent_pid_info = %x(gpg-agent --homedir=#{Dir.pwd} /get serverpid).strip
|
273
|
+
gpg_agent_pid_info =~ %r(\[(\d+)\])
|
274
|
+
gpg_agent_pid = $1
|
275
|
+
else
|
276
|
+
# Are we running a broken version of the gpg-agent? If so, we'll
|
277
|
+
# get back info on the command line.
|
278
|
+
|
279
|
+
gpg_agent_info = gpg_agent_output.split(';').first.split('=').last.split(':')
|
280
|
+
gpg_agent_socket = gpg_agent_info[0]
|
281
|
+
gpg_agent_pid = gpg_agent_info[1].strip.to_i
|
282
|
+
|
283
|
+
unless File.exist?(%(#{Dir.pwd}/#{File.basename(gpg_agent_socket)}))
|
284
|
+
ln_s(gpg_agent_socket,%(#{Dir.pwd}/#{File.basename(gpg_agent_socket)}))
|
285
|
+
end
|
280
286
|
end
|
281
287
|
end
|
282
|
-
end
|
283
288
|
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
+
sh %{gpg --homedir=#{Dir.pwd} --batch --gen-key gengpgkey}
|
290
|
+
%x{gpg --homedir=#{Dir.pwd} --armor --export #{dev_email} > RPM-GPG-KEY-SIMP-Dev}
|
291
|
+
ensure
|
292
|
+
begin
|
293
|
+
rm('S.gpg-agent') if File.symlink?('S.gpg-agent')
|
289
294
|
|
290
|
-
|
291
|
-
|
292
|
-
|
295
|
+
if gpg_agent_pid
|
296
|
+
Process.kill(0,gpg_agent_pid)
|
297
|
+
Process.kill(15,gpg_agent_pid)
|
298
|
+
end
|
299
|
+
rescue Errno::ESRCH
|
300
|
+
# Not Running, Nothing to do!
|
293
301
|
end
|
294
|
-
rescue Errno::ESRCH
|
295
|
-
# Not Running, Nothing to do!
|
296
302
|
end
|
297
303
|
end
|
298
304
|
end
|
299
|
-
|
305
|
+
end
|
300
306
|
|
301
|
-
Dir.chdir(args[:key])
|
307
|
+
Dir.chdir(args[:key]) do
|
302
308
|
rpm_build_keys = Dir.glob('RPM-GPG-KEY-*')
|
303
|
-
target_dir = '
|
309
|
+
target_dir = File.join(@build_dir, 'GPGKEYS')
|
304
310
|
|
305
311
|
fail("Could not find any RPM-GPG-KEY files in '#{Dir.pwd}'") if rpm_build_keys.empty?
|
306
312
|
fail("No GPGKEYS directory at '#{Dir.pwd}/#{target_dir}") unless File.directory?(target_dir)
|
@@ -314,8 +320,8 @@ module Simp::Rake::Build
|
|
314
320
|
|
315
321
|
dkfh.flush
|
316
322
|
dkfh.close
|
317
|
-
|
318
|
-
|
323
|
+
end
|
324
|
+
end
|
319
325
|
end
|
320
326
|
|
321
327
|
desc <<-EOM
|
@@ -330,6 +336,7 @@ module Simp::Rake::Build
|
|
330
336
|
- Set `SIMP_PKG_verbose=yes` to report file operations as they happen.
|
331
337
|
EOM
|
332
338
|
task :build,[:chroot,:docs,:key,:snapshot_release] => [:prep,:mock_prep,:key_prep] do |t,args|
|
339
|
+
|
333
340
|
validate_in_mock_group?
|
334
341
|
_verbose = ENV.fetch('SIMP_PKG_verbose','no') == 'yes'
|
335
342
|
|
@@ -502,7 +509,7 @@ module Simp::Rake::Build
|
|
502
509
|
|
503
510
|
desc "Sign the RPMs."
|
504
511
|
task :signrpms,[:key,:rpm_dir,:force] => [:prep,:key_prep,:mock_prep] do |t,args|
|
505
|
-
which('rpmsign') || raise(
|
512
|
+
which('rpmsign') || raise(StandardError, 'Could not find rpmsign on your system. Exiting.')
|
506
513
|
|
507
514
|
args.with_defaults(:key => 'dev')
|
508
515
|
args.with_defaults(:rpm_dir => "#{@build_dir}/SIMP/*RPMS")
|
@@ -541,7 +548,7 @@ module Simp::Rake::Build
|
|
541
548
|
EOM
|
542
549
|
task :checksig,[:rpm_dir,:key_dir] => [:prep] do |t,args|
|
543
550
|
begin
|
544
|
-
args.with_defaults(:rpm_dir => @pkg_dirs[:
|
551
|
+
args.with_defaults(:rpm_dir => @pkg_dirs[:simp])
|
545
552
|
args.with_defaults(:key_dir => "#{@build_dir}/GPGKEYS")
|
546
553
|
|
547
554
|
rpm_dirs = Dir.glob(args[:rpm_dir])
|
@@ -552,11 +559,14 @@ module Simp::Rake::Build
|
|
552
559
|
|
553
560
|
rpm_cmd = %{rpm --dbpath #{temp_gpg_dir}}
|
554
561
|
|
555
|
-
|
562
|
+
%x{#{rpm_cmd} --initdb}
|
563
|
+
|
564
|
+
public_keys = Dir.glob(File.join(args[:key_dir], '*'))
|
565
|
+
public_keys += Dir.glob(File.join(@build_dir, 'build_keys', '*', 'RPM-GPG-KEY*'))
|
556
566
|
|
557
567
|
# Only import thngs that look like GPG keys...
|
558
|
-
|
559
|
-
next if File.directory?(key) or
|
568
|
+
public_keys.each do |key|
|
569
|
+
next if File.directory?(key) or !File.readable?(key)
|
560
570
|
|
561
571
|
File.read(key).each_line do |line|
|
562
572
|
if line =~ /-----BEGIN PGP PUBLIC KEY BLOCK-----/
|
@@ -578,7 +588,7 @@ module Simp::Rake::Build
|
|
578
588
|
end
|
579
589
|
end
|
580
590
|
|
581
|
-
|
591
|
+
unless bad_rpms.empty?
|
582
592
|
bad_rpms.map!{|x| x = " * #{x}"}
|
583
593
|
bad_rpms.unshift("ERROR: Untrusted RPMs found in the repository:")
|
584
594
|
|
@@ -587,7 +597,7 @@ module Simp::Rake::Build
|
|
587
597
|
puts "Checksig succeeded"
|
588
598
|
end
|
589
599
|
ensure
|
590
|
-
remove_entry_secure temp_gpg_dir
|
600
|
+
remove_entry_secure temp_gpg_dir if (temp_gpg_dir && File.exist?(temp_gpg_dir))
|
591
601
|
end
|
592
602
|
end
|
593
603
|
|
@@ -608,11 +618,10 @@ module Simp::Rake::Build
|
|
608
618
|
EOM
|
609
619
|
task :repoclosure,[:target_dir,:aux_dir] => [:prep] do |t,args|
|
610
620
|
default_target = @pkg_dirs[:simp]
|
611
|
-
args.with_defaults(:target_dir => default_target)
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
args.with_defaults(:aux_dir => '')
|
621
|
+
args.with_defaults(:target_dir => File.expand_path(default_target))
|
622
|
+
|
623
|
+
if args[:aux_dir]
|
624
|
+
args[:aux_dir] = File.expand_path(args[:aux_dir])
|
616
625
|
end
|
617
626
|
|
618
627
|
_verbose = ENV.fetch('SIMP_PKG_verbose','no') == 'yes'
|
@@ -646,32 +655,32 @@ protect=1
|
|
646
655
|
|
647
656
|
fail("#{args[:target_dir]} does not exist!") unless File.directory?(args[:target_dir])
|
648
657
|
|
649
|
-
|
650
|
-
temp_pkg_dir
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
658
|
+
Dir.mktmpdir do |temp_pkg_dir|
|
659
|
+
Dir.chdir(temp_pkg_dir) do
|
660
|
+
mkdir_p('repos/base')
|
661
|
+
mkdir_p('repos/lookaside')
|
662
|
+
mkdir_p('repodata')
|
663
|
+
|
664
|
+
Dir.glob(args[:target_dir]).each do |base_dir|
|
665
|
+
Find.find(base_dir) do |path|
|
666
|
+
if (path =~ /.*\.rpm$/) and (path !~ /.*.src\.rpm$/)
|
667
|
+
sym_path = "repos/base/#{File.basename(path)}"
|
668
|
+
ln_s(path,sym_path, :verbose => _verbose) unless File.exists?(sym_path)
|
669
|
+
end
|
661
670
|
end
|
662
671
|
end
|
663
|
-
end
|
664
672
|
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
673
|
+
if args[:aux_dir]
|
674
|
+
Dir.glob(args[:aux_dir]).each do |aux_dir|
|
675
|
+
Find.find(aux_dir) do |path|
|
676
|
+
if (path =~ /.*\.rpm$/) and (path !~ /.*.src\.rpm$/)
|
677
|
+
sym_path = "repos/lookaside/#{File.basename(path)}"
|
678
|
+
ln_s(path,sym_path, :verbose => _verbose) unless File.exists?(sym_path)
|
679
|
+
end
|
680
|
+
end
|
670
681
|
end
|
671
682
|
end
|
672
|
-
end
|
673
683
|
|
674
|
-
Dir.chdir(temp_pkg_dir) do
|
675
684
|
repo_files = []
|
676
685
|
Dir.glob('repos/*').each do |repo|
|
677
686
|
if File.directory?(repo)
|
@@ -710,8 +719,6 @@ protect=1
|
|
710
719
|
fail(errmsg.join("\n"))
|
711
720
|
end
|
712
721
|
end
|
713
|
-
ensure
|
714
|
-
remove_entry_secure temp_pkg_dir
|
715
722
|
end
|
716
723
|
end
|
717
724
|
|
@@ -731,8 +738,6 @@ protect=1
|
|
731
738
|
# Default package metadata for reference
|
732
739
|
default_metadata = YAML.load(File.read("#{@src_dir}/build/package_metadata_defaults.yaml"))
|
733
740
|
|
734
|
-
reenable_lock = Mutex.new
|
735
|
-
|
736
741
|
metadata = Parallel.map(
|
737
742
|
# Allow for shell globs
|
738
743
|
Array(dirs),
|
@@ -808,6 +813,11 @@ protect=1
|
|
808
813
|
raise("No SRPMs generated for #{dir}") if srpms.empty?
|
809
814
|
raise("No RPMs generated for #{dir}") if rpms.empty?
|
810
815
|
|
816
|
+
last_build = {
|
817
|
+
'git_hash' => %x{git show-ref --head HEAD}.chomp,
|
818
|
+
'rpms' => {}
|
819
|
+
}
|
820
|
+
|
811
821
|
# Glob all generated rpms, and add their metadata to a result array.
|
812
822
|
rpms.each do |rpm|
|
813
823
|
# get_info from each generated rpm, not the spec file, so macros in the
|
@@ -818,8 +828,19 @@ protect=1
|
|
818
828
|
metadata.merge!(YAML.load_file('build/package_metadata.yaml'))
|
819
829
|
end
|
820
830
|
|
831
|
+
rpm_stat = File.stat(rpm)
|
832
|
+
|
833
|
+
last_build['rpms'][rpm] = {
|
834
|
+
'metadata' => metadata,
|
835
|
+
'size' => rpm_stat.size
|
836
|
+
}
|
837
|
+
|
821
838
|
result << metadata
|
822
839
|
end
|
840
|
+
|
841
|
+
File.open('dist/.last_build_metadata', 'w') do |fh|
|
842
|
+
fh.puts(last_build.to_yaml)
|
843
|
+
end
|
823
844
|
end
|
824
845
|
|
825
846
|
if _verbose
|
data/lib/simp/rake/build/spec.rb
CHANGED
@@ -9,29 +9,36 @@ module Simp::Rake::Build
|
|
9
9
|
|
10
10
|
def initialize( base_dir )
|
11
11
|
init_member_vars( base_dir )
|
12
|
+
|
12
13
|
@mock = ENV['mock'] || '/usr/bin/mock'
|
13
14
|
define_tasks
|
14
15
|
end
|
15
16
|
|
16
17
|
def define_tasks
|
17
18
|
namespace :spec do
|
19
|
+
task :prep do
|
20
|
+
if $simp6
|
21
|
+
@build_dir = $simp6_build_dir
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
18
25
|
|
19
26
|
desc "Bump spec files. Bump all spec files' release numbers up by one.
|
20
27
|
* :list - Flag to just print the current version numbers."
|
21
|
-
task :bump,[:list] do |t,args|
|
28
|
+
task :bump,[:list] => [:prep] do |t,args|
|
22
29
|
(
|
23
30
|
Dir.glob("#{@spec_dir}/*.spec") +
|
24
31
|
Dir.glob("#{@src_dir}/puppet/modules/*/pkg/pupmod-*.spec")
|
25
32
|
).each do |spec|
|
26
|
-
if args.list
|
33
|
+
if args.list
|
27
34
|
File.open(spec).each do |line|
|
28
|
-
if line =~ /Name:\s*(.*)/
|
35
|
+
if line =~ /Name:\s*(.*)/
|
29
36
|
print $1.chomp + ' -> '
|
30
37
|
next
|
31
|
-
elsif line =~ /Version:\s*(.*)/
|
38
|
+
elsif line =~ /Version:\s*(.*)/
|
32
39
|
print $1.chomp + '-'
|
33
40
|
next
|
34
|
-
elsif line =~ /Release:\s*(.*)/
|
41
|
+
elsif line =~ /Release:\s*(.*)/
|
35
42
|
puts $1.chomp
|
36
43
|
next
|
37
44
|
end
|
@@ -39,7 +46,7 @@ module Simp::Rake::Build
|
|
39
46
|
else
|
40
47
|
tmpfile = File.open("#{@spec_dir}/~#{File.basename(spec)}","w+")
|
41
48
|
File.open(spec).each do |line|
|
42
|
-
if line =~ /Release:/
|
49
|
+
if line =~ /Release:/
|
43
50
|
tmpfile.puts "Release: #{line.split(/\s/)[1].to_i + 1}"
|
44
51
|
else
|
45
52
|
tmpfile.puts line.chomp
|