tpkg 2.2.2 → 2.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/lib/tpkg.rb +77 -29
- data/lib/tpkg/metadata.rb +71 -67
- metadata +6 -6
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ spec = Gem::Specification.new do |s|
|
|
5
5
|
s.add_dependency('facter')
|
6
6
|
s.add_dependency('net-ssh')
|
7
7
|
s.add_dependency('kwalify')
|
8
|
-
s.version = '2.2.
|
8
|
+
s.version = '2.2.3'
|
9
9
|
s.authors = ['Darren Dao', 'Jason Heiss']
|
10
10
|
s.email = 'tpkg-users@lists.sourceforge.net'
|
11
11
|
s.homepage = 'http://tpkg.sourceforge.net'
|
data/lib/tpkg.rb
CHANGED
@@ -40,7 +40,7 @@ require 'tpkg/metadata'
|
|
40
40
|
|
41
41
|
class Tpkg
|
42
42
|
|
43
|
-
VERSION = '2.2.
|
43
|
+
VERSION = '2.2.3'
|
44
44
|
|
45
45
|
GENERIC_ERR = 1
|
46
46
|
POSTINSTALL_ERR = 2
|
@@ -372,10 +372,18 @@ class Tpkg
|
|
372
372
|
end
|
373
373
|
File.delete(pkgfile)
|
374
374
|
end
|
375
|
-
|
375
|
+
|
376
376
|
# update metadata file with the tpkg version
|
377
|
-
|
378
|
-
|
377
|
+
begin
|
378
|
+
metadata.add_tpkg_version(VERSION)
|
379
|
+
rescue Errno::EACCES => e
|
380
|
+
# The source directory from which the package is made may not be
|
381
|
+
# writeable by the user making the package. It is not critical that
|
382
|
+
# the tpkg version get added to the package metadata, so just warn the
|
383
|
+
# user if that happens.
|
384
|
+
warn "Failed to insert tpkg_version into tpkg.(xml|yml): #{e.message}"
|
385
|
+
end
|
386
|
+
|
379
387
|
# Tar up the tpkg directory
|
380
388
|
tpkgfile = File.join(package_directory, 'tpkg.tar')
|
381
389
|
system("#{find_tar} -C #{workdir} -cf #{tpkgfile} tpkg") || raise("tpkg.tar creation failed")
|
@@ -415,23 +423,41 @@ class Tpkg
|
|
415
423
|
# This assumes the first entry in the tarball is the top level directory.
|
416
424
|
# I think that is a safe assumption.
|
417
425
|
toplevel = nil
|
418
|
-
#
|
419
|
-
#
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
#
|
429
|
-
#
|
430
|
-
|
426
|
+
# We need one or more 512 byte tar blocks from the file to get the first
|
427
|
+
# filename. In most cases we'll just need one block, but if the top-level
|
428
|
+
# directory has an exceptionally long name it may be spread over multiple
|
429
|
+
# blocks. The trick is that we don't want any additional blocks because
|
430
|
+
# that will confuse tar and it will report that the archive is damaged.
|
431
|
+
# So start with one block and go up to an arbitrarily picked limit of 10
|
432
|
+
# blocks (I've been unable to make a test tarball that needed more than 3
|
433
|
+
# blocks) and see if tar succeeds in listing a file.
|
434
|
+
1.upto(10) do |numblocks|
|
435
|
+
tarblocks = File.read(package_file, 512*numblocks)
|
436
|
+
# Open3.popen3("#{find_tar} -tf - #{@@taroptions}") do |stdin, stdout, stderr|
|
437
|
+
# stdin.write(tarblocks)
|
438
|
+
# stdin.close
|
439
|
+
# toplevel = stdout.read
|
440
|
+
# end
|
441
|
+
# Unfortunately popen3 doesn't provide a mechanism for determining the
|
442
|
+
# success or failure of the command until ruby 1.9. ($? is never
|
443
|
+
# accurately set for popen3, the mechanism in ruby 1.9 for getting the
|
444
|
+
# exit status for popen3 is unique to popen3.) So we're left with this,
|
445
|
+
# which it rather Unix-specific.
|
446
|
+
IO.popen("#{find_tar} -tf - #{@@taroptions} 2> /dev/null", 'r+') do |pipe|
|
447
|
+
pipe.write(tarblocks)
|
448
|
+
pipe.close_write
|
449
|
+
toplevel = pipe.read
|
450
|
+
end
|
451
|
+
if $?.success?
|
452
|
+
break
|
453
|
+
else
|
454
|
+
toplevel = nil
|
455
|
+
end
|
431
456
|
end
|
432
|
-
if
|
457
|
+
if toplevel.nil?
|
433
458
|
raise "Error reading top level directory from #{package_file}"
|
434
459
|
end
|
460
|
+
toplevel.chomp!
|
435
461
|
# Strip off the trailing slash
|
436
462
|
toplevel.sub!(Regexp.new("#{File::SEPARATOR}$"), '')
|
437
463
|
if toplevel.include?(File::SEPARATOR)
|
@@ -1501,6 +1527,7 @@ class Tpkg
|
|
1501
1527
|
end
|
1502
1528
|
stderr_first_line = stderr.gets
|
1503
1529
|
end
|
1530
|
+
# FIXME: popen3 doesn't set $?
|
1504
1531
|
if !$?.success?
|
1505
1532
|
# Ignore 'no matching packages', raise anything else
|
1506
1533
|
if stderr_first_line != "Error: No matching Packages to list\n"
|
@@ -1538,6 +1565,7 @@ class Tpkg
|
|
1538
1565
|
end
|
1539
1566
|
stderr_first_line = stderr.gets
|
1540
1567
|
end
|
1568
|
+
# FIXME: popen3 doesn't set $?
|
1541
1569
|
if !$?.success?
|
1542
1570
|
# Ignore 'no matching packages', raise anything else
|
1543
1571
|
if stderr_first_line !~ 'No packages found matching'
|
@@ -2541,6 +2569,10 @@ class Tpkg
|
|
2541
2569
|
if (metadata[:files][:file_defaults][:posix][:group] rescue nil)
|
2542
2570
|
default_gid = Tpkg::lookup_gid(metadata[:files][:file_defaults][:posix][:group])
|
2543
2571
|
end
|
2572
|
+
# FIXME: Default file permissions aren't likely to be generally useful
|
2573
|
+
# since different classes of files often require different permissions.
|
2574
|
+
# I.e. executables should be 0555, links 0777, everything else 0444.
|
2575
|
+
# Something more like a umask would probably be more generally useful.
|
2544
2576
|
if (metadata[:files][:file_defaults][:posix][:perms] rescue nil)
|
2545
2577
|
default_perms = metadata[:files][:file_defaults][:posix][:perms]
|
2546
2578
|
end
|
@@ -2560,28 +2592,39 @@ class Tpkg
|
|
2560
2592
|
default_dir_perms = metadata[:files][:dir_defaults][:posix][:perms]
|
2561
2593
|
end
|
2562
2594
|
|
2563
|
-
# FIXME: attempt lchown/lchmod on symlinks
|
2564
2595
|
root_dir = File.join(workdir, 'tpkg', 'root')
|
2565
2596
|
reloc_dir = File.join(workdir, 'tpkg', 'reloc')
|
2566
2597
|
Find.find(*Tpkg::get_package_toplevels(File.join(workdir, 'tpkg'))) do |f|
|
2567
2598
|
begin
|
2568
|
-
if File.
|
2599
|
+
if File.symlink?(f)
|
2600
|
+
begin
|
2601
|
+
File.lchown(default_uid, default_gid, f)
|
2602
|
+
rescue NotImplementedError
|
2603
|
+
end
|
2604
|
+
elsif File.file?(f)
|
2569
2605
|
File.chown(default_uid, default_gid, f)
|
2570
|
-
elsif File.directory?(f)
|
2606
|
+
elsif File.directory?(f)
|
2571
2607
|
File.chown(default_dir_uid, default_dir_gid, f)
|
2572
2608
|
end
|
2573
2609
|
rescue Errno::EPERM
|
2574
2610
|
raise if Process.euid == 0
|
2575
2611
|
end
|
2576
|
-
if File.
|
2612
|
+
if File.symlink?(f)
|
2613
|
+
if default_perms
|
2614
|
+
begin
|
2615
|
+
File.lchmod(default_perms, f)
|
2616
|
+
rescue NotImplementedError
|
2617
|
+
end
|
2618
|
+
end
|
2619
|
+
elsif File.file?(f)
|
2577
2620
|
if default_perms
|
2578
2621
|
File.chmod(default_perms, f)
|
2579
2622
|
end
|
2580
|
-
elsif File.directory?(f)
|
2623
|
+
elsif File.directory?(f)
|
2581
2624
|
File.chmod(default_dir_perms, f)
|
2582
2625
|
end
|
2583
2626
|
end
|
2584
|
-
|
2627
|
+
|
2585
2628
|
# Reset the permission/ownership of the conflicting files as how they were before.
|
2586
2629
|
# This needs to be done after the default permission/ownership is applied, but before
|
2587
2630
|
# the handling of ownership/permissions on specific files
|
@@ -2619,7 +2662,10 @@ class Tpkg
|
|
2619
2662
|
if !File.symlink?(working_path)
|
2620
2663
|
File.chown(uid, gid, working_path)
|
2621
2664
|
else
|
2622
|
-
|
2665
|
+
begin
|
2666
|
+
File.lchown(uid, gid, working_path)
|
2667
|
+
rescue NotImplementedError
|
2668
|
+
end
|
2623
2669
|
end
|
2624
2670
|
rescue Errno::EPERM
|
2625
2671
|
raise if Process.euid == 0
|
@@ -2630,7 +2676,10 @@ class Tpkg
|
|
2630
2676
|
if !File.symlink?(working_path)
|
2631
2677
|
File.chmod(perms, working_path)
|
2632
2678
|
else
|
2633
|
-
|
2679
|
+
begin
|
2680
|
+
File.lchmod(perms, working_path)
|
2681
|
+
rescue NotImplementedError
|
2682
|
+
end
|
2634
2683
|
end
|
2635
2684
|
end
|
2636
2685
|
end
|
@@ -4581,8 +4630,7 @@ class Tpkg
|
|
4581
4630
|
def stub_native_pkg(pkg)
|
4582
4631
|
# gather all of the native dependencies
|
4583
4632
|
native_deps = pkg[:metadata].get_native_deps
|
4584
|
-
|
4585
|
-
return if native_deps.nil? or native_deps.empty?
|
4633
|
+
return if native_deps.empty?
|
4586
4634
|
|
4587
4635
|
if Tpkg::get_os =~ /RedHat|CentOS|Fedora/
|
4588
4636
|
rpm = create_rpm("stub_for_#{pkg[:metadata][:name]}", native_deps)
|
@@ -4604,7 +4652,7 @@ class Tpkg
|
|
4604
4652
|
def remove_native_stub_pkg(pkg)
|
4605
4653
|
# Don't have to do anything if this package has no native dependencies
|
4606
4654
|
native_deps = pkg[:metadata].get_native_deps
|
4607
|
-
return if native_deps.
|
4655
|
+
return if native_deps.empty?
|
4608
4656
|
|
4609
4657
|
# the convention is that stub package is named as "stub_for_pkgname"
|
4610
4658
|
stub_pkg_name = "stub_for_#{pkg[:metadata][:name]}"
|
data/lib/tpkg/metadata.rb
CHANGED
@@ -230,7 +230,8 @@ end
|
|
230
230
|
# is that you can give it a metadata file of any format, such as yaml or xml,
|
231
231
|
# and it will provide you a uniform interface for accessing/dealing with the metadata.
|
232
232
|
class Metadata
|
233
|
-
|
233
|
+
attr_reader :text, :format, :file
|
234
|
+
attr_accessor :source
|
234
235
|
REQUIRED_FIELDS = [:name, :version, :maintainer, :description]
|
235
236
|
|
236
237
|
# Cleans up a string to make it suitable for use in a filename
|
@@ -247,7 +248,7 @@ class Metadata
|
|
247
248
|
if metadata_text =~ /^:?name:(.+)/
|
248
249
|
name = $1.strip
|
249
250
|
metadata[name] ||= []
|
250
|
-
metadata[name] << Metadata.new(metadata_text,'yml', source)
|
251
|
+
metadata[name] << Metadata.new(metadata_text,'yml', nil, source)
|
251
252
|
end
|
252
253
|
end
|
253
254
|
return metadata
|
@@ -258,26 +259,31 @@ class Metadata
|
|
258
259
|
def self.instantiate_from_dir(dir)
|
259
260
|
metadata = nil
|
260
261
|
if File.exist?(File.join(dir, 'tpkg.yml'))
|
261
|
-
metadata = Metadata.new(File.read(File.join(dir, 'tpkg.yml')),
|
262
|
-
|
262
|
+
metadata = Metadata.new(File.read(File.join(dir, 'tpkg.yml')),
|
263
|
+
'yml',
|
264
|
+
File.join(dir, 'tpkg.yml'))
|
263
265
|
elsif File.exists?(File.join(dir, 'tpkg.xml'))
|
264
|
-
metadata = Metadata.new(File.read(File.join(dir, 'tpkg.xml')),
|
265
|
-
|
266
|
+
metadata = Metadata.new(File.read(File.join(dir, 'tpkg.xml')),
|
267
|
+
'xml',
|
268
|
+
File.join(dir, 'tpkg.xml'))
|
266
269
|
end
|
267
270
|
return metadata
|
268
271
|
end
|
269
272
|
|
270
|
-
#
|
273
|
+
# text = text representation of the metadata
|
271
274
|
# format = yml, xml, json, etc.
|
275
|
+
# file = Path to the metadata file that was the source of this metadata
|
272
276
|
# source = Source, in the tpkg sense, of the package described by this
|
273
277
|
# metadata. I.e. the filename of an individual package or a directory or
|
274
278
|
# URL containing multiple packages and a metadata.yml file. Used by tpkg to
|
275
279
|
# report on how many packages are available from various sources.
|
276
|
-
def initialize(
|
277
|
-
@
|
278
|
-
|
280
|
+
def initialize(text, format, file=nil, source=nil)
|
281
|
+
@text = text
|
282
|
+
# FIXME: should define enum of supported formats and reject others
|
279
283
|
@format = format
|
284
|
+
@file = file
|
280
285
|
@source = source
|
286
|
+
@hash = nil
|
281
287
|
end
|
282
288
|
|
283
289
|
def [](key)
|
@@ -287,16 +293,16 @@ class Metadata
|
|
287
293
|
def []=(key,value)
|
288
294
|
to_hash[key]=value
|
289
295
|
end
|
290
|
-
|
296
|
+
|
291
297
|
def to_hash
|
292
298
|
if @hash
|
293
299
|
return @hash
|
294
300
|
end
|
295
|
-
|
301
|
+
|
296
302
|
if @format == 'yml'
|
297
|
-
hash = YAML::load(@
|
303
|
+
hash = YAML::load(@text)
|
298
304
|
@hash = hash.with_indifferent_access
|
299
|
-
|
305
|
+
|
300
306
|
# We need this for backward compatibility. With xml, we specify
|
301
307
|
# native dependency as type: :native rather then native: true
|
302
308
|
@hash[:dependencies].each do | dep |
|
@@ -308,7 +314,7 @@ class Metadata
|
|
308
314
|
end
|
309
315
|
end
|
310
316
|
end if @hash[:dependencies]
|
311
|
-
|
317
|
+
|
312
318
|
@hash[:files][:files].each do |file|
|
313
319
|
# We need to do this for backward compatibility. In the old yml schema,
|
314
320
|
# the encrypt field can either be "true" or a string value. Now, it is
|
@@ -325,60 +331,55 @@ class Metadata
|
|
325
331
|
file[:posix][:perms] = "#{file[:posix][:perms]}".oct
|
326
332
|
end
|
327
333
|
end if @hash[:files] && @hash[:files][:files]
|
328
|
-
|
334
|
+
elsif @format == 'xml'
|
329
335
|
@hash = metadata_xml_to_hash.with_indifferent_access
|
336
|
+
else
|
337
|
+
raise "Unknown metadata format"
|
330
338
|
end
|
331
|
-
|
339
|
+
@hash
|
332
340
|
end
|
333
|
-
|
341
|
+
|
334
342
|
# Write the metadata to a file under the specified directory
|
335
|
-
# The file will be saved as tpkg.yml
|
336
|
-
def write(dir
|
337
|
-
|
338
|
-
if retain_format && @format == 'xml'
|
339
|
-
puts "TODO"
|
340
|
-
else
|
341
|
-
file = File.new(File.join(dir, "tpkg.yml"), "w")
|
343
|
+
# The file will be saved as tpkg.yml, even if originally loaded as XML.
|
344
|
+
def write(dir)
|
345
|
+
File.open(File.join(dir, "tpkg.yml"), "w") do |file|
|
342
346
|
# When we convert xml to hash, we store the key as symbol. So when we
|
343
347
|
# write back out to file, we should stringify all the keys for readability.
|
344
348
|
data = to_hash.recursively{|h| h.stringify_keys }
|
345
349
|
YAML::dump(data, file)
|
346
350
|
end
|
347
|
-
file.close
|
348
351
|
end
|
349
|
-
|
352
|
+
|
350
353
|
# Add tpkg_version to the existing tpkg.xml or tpkg.yml file
|
351
354
|
def add_tpkg_version(version)
|
352
|
-
|
353
|
-
if
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
355
|
+
if self[:tpkg_version]
|
356
|
+
if self[:tpkg_version] != version
|
357
|
+
warn "Warning: tpkg_version is specified as #{self[:tpkg_version]}, which doesn't match with the actual tpkg version being used (#{version})."
|
358
|
+
end
|
359
|
+
else
|
360
|
+
# Add to in-memory data
|
361
|
+
self[:tpkg_version] = version
|
362
|
+
# Update the metadata source file (if known)
|
363
|
+
if @file
|
364
|
+
if @format == 'yml'
|
365
|
+
File.open(@file, 'a') do |file|
|
366
|
+
file.puts "tpkg_version: #{version}"
|
367
|
+
end
|
368
|
+
elsif @format == 'xml'
|
369
|
+
metadata_xml = REXML::Document.new(@text)
|
370
|
+
tpkg_version_ele = REXML::Element.new('tpkg_version')
|
371
|
+
tpkg_version_ele.text = version
|
360
372
|
metadata_xml.root.add_element(tpkg_version_ele)
|
361
|
-
File.open(@
|
373
|
+
File.open(@file, 'w') do |file|
|
362
374
|
metadata_xml.write(file)
|
363
375
|
end
|
376
|
+
else
|
377
|
+
raise "Unknown metadata format"
|
364
378
|
end
|
365
|
-
elsif @format == 'yml'
|
366
|
-
if (tpkg_version = to_hash[:tpkg_version]) && tpkg_version != Tpkg::VERSION
|
367
|
-
warn "Warning: tpkg_version is specified as #{tpkg_version}, which doesn't match with the actual tpkg version being used (#{Tpkg::VERSION})."
|
368
|
-
elsif !tpkg_version
|
369
|
-
File.open(@file_path, 'a') do |file|
|
370
|
-
file.puts "tpkg_version: #{Tpkg::VERSION}"
|
371
|
-
end
|
372
|
-
end
|
373
|
-
else
|
374
|
-
raise "Unknown metadata format"
|
375
379
|
end
|
376
|
-
|
377
|
-
warn "Warning: Failed to insert tpkg_version into tpkg.(xml|yml)."
|
378
|
-
puts e
|
379
|
-
end
|
380
|
+
end
|
380
381
|
end
|
381
|
-
|
382
|
+
|
382
383
|
def generate_package_filename
|
383
384
|
name = to_hash[:name]
|
384
385
|
version = to_hash[:version]
|
@@ -445,7 +446,7 @@ class Metadata
|
|
445
446
|
warn "Warning: unable to validate metadata because #{schema_file} does not exist"
|
446
447
|
return
|
447
448
|
end
|
448
|
-
errors = verify_yaml(schema_file, @
|
449
|
+
errors = verify_yaml(schema_file, @text)
|
449
450
|
elsif @format == 'xml'
|
450
451
|
# TODO: use DTD to validate XML
|
451
452
|
errors = verify_required_fields
|
@@ -464,12 +465,14 @@ class Metadata
|
|
464
465
|
# Verify the yaml text against the given schema
|
465
466
|
# Return array of errors (if there are any)
|
466
467
|
def verify_yaml(schema, yaml_text)
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
468
|
+
errors = nil
|
469
|
+
# Kwalify generates lots of warnings, silence it
|
470
|
+
Silently.silently do
|
471
|
+
schema = Kwalify::Yaml.load_file(schema)
|
472
|
+
validator = Kwalify::Validator.new(schema.with_indifferent_access)
|
473
|
+
errors = validator.validate(YAML::load(yaml_text).with_indifferent_access)
|
474
|
+
end
|
475
|
+
errors
|
473
476
|
end
|
474
477
|
|
475
478
|
# Once we implement validating the XML using the DTD, we won't need
|
@@ -491,7 +494,7 @@ class Metadata
|
|
491
494
|
return if @format != "xml"
|
492
495
|
|
493
496
|
metadata_hash = {}
|
494
|
-
metadata_xml = REXML::Document.new(@
|
497
|
+
metadata_xml = REXML::Document.new(@text)
|
495
498
|
|
496
499
|
if metadata_xml.root.attributes['filename'] # && !metadata_xml.root.attributes['filename'].empty?
|
497
500
|
metadata_hash[:filename] = metadata_xml.root.attributes['filename']
|
@@ -719,12 +722,13 @@ class Metadata
|
|
719
722
|
|
720
723
|
return metadata_hash
|
721
724
|
end
|
722
|
-
|
725
|
+
|
723
726
|
def get_native_deps
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
727
|
+
native_deps = []
|
728
|
+
if self[:dependencies]
|
729
|
+
native_deps = self[:dependencies].select{|dep| dep[:type] == :native}
|
730
|
+
end
|
731
|
+
native_deps
|
728
732
|
end
|
729
733
|
end
|
730
734
|
|
@@ -749,10 +753,10 @@ class FileMetadata < Metadata
|
|
749
753
|
end
|
750
754
|
|
751
755
|
if @format == 'bin'
|
752
|
-
hash = Marshal::load(@
|
756
|
+
hash = Marshal::load(@text)
|
753
757
|
@hash = hash.with_indifferent_access
|
754
758
|
elsif @format == 'yml'
|
755
|
-
hash = YAML::load(@
|
759
|
+
hash = YAML::load(@text)
|
756
760
|
@hash = hash.with_indifferent_access
|
757
761
|
elsif @format == 'xml'
|
758
762
|
@hash = file_metadata_xml_to_hash
|
@@ -765,7 +769,7 @@ class FileMetadata < Metadata
|
|
765
769
|
|
766
770
|
file_metadata_hash = {}
|
767
771
|
files = []
|
768
|
-
file_metadata_xml = REXML::Document.new(@
|
772
|
+
file_metadata_xml = REXML::Document.new(@text)
|
769
773
|
file_metadata_hash[:package_file] = file_metadata_xml.root.attributes['package_file']
|
770
774
|
file_metadata_xml.elements.each("files/file") do | file_ele |
|
771
775
|
file = {}
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tpkg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 1
|
5
|
+
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 2.2.
|
9
|
+
- 3
|
10
|
+
version: 2.2.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Darren Dao
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-02-
|
19
|
+
date: 2011-02-20 00:00:00 -08:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -133,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
133
|
requirements: []
|
134
134
|
|
135
135
|
rubyforge_project: tpkg
|
136
|
-
rubygems_version: 1.
|
136
|
+
rubygems_version: 1.3.7
|
137
137
|
signing_key:
|
138
138
|
specification_version: 3
|
139
139
|
summary: tpkg Application Packaging & Deployment
|