tpkg 2.2.2 → 2.2.3
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.
- 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
|