tpkg 1.25.1 → 1.27.1

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 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('ddao-kwalify')
8
- s.version = '1.25.1'
8
+ s.version = '1.27.1'
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/bin/tpkg CHANGED
@@ -270,8 +270,7 @@ opts.on('--debug', 'Print lots of messages about what tpkg is doing') do |opt|
270
270
  Tpkg::set_debug(@debug)
271
271
  end
272
272
  opts.on('--version', 'Show tpkg version') do |opt|
273
- puts Tpkg::VERSION
274
- exit
273
+ @action = :query_version
275
274
  end
276
275
  opts.on_tail("-h", "--help", "Show this message") do
277
276
  puts opts
@@ -491,6 +490,8 @@ when :query_info
491
490
  end
492
491
  end
493
492
  end
493
+ tpkg_version = metadata[:tpkg_version] || "< 1.26.1"
494
+ puts "This package was built with tpkg version #{tpkg_version}."
494
495
  if metadata[:dependencies]
495
496
  puts "This package depends on other packages, use --qd/--qld to view the dependencies."
496
497
  end
@@ -631,5 +632,7 @@ when :query_env
631
632
  when :query_history
632
633
  tpkg = instantiate_tpkg(@tpkg_options)
633
634
  tpkg.installation_history
635
+ when :query_version
636
+ puts Tpkg::VERSION
634
637
  end
635
638
  exit ret_val
@@ -56,7 +56,7 @@ require 'kwalify' # for validating yaml
56
56
 
57
57
  class Tpkg
58
58
 
59
- VERSION = '1.25.1'
59
+ VERSION = '1.27.1'
60
60
  CONFIGDIR = '/etc'
61
61
 
62
62
  GENERIC_ERR = 1
@@ -93,6 +93,9 @@ class Tpkg
93
93
  def self.find_tar
94
94
  if !@@tar
95
95
  catch :tar_found do
96
+ if !ENV['PATH']
97
+ raise "tpkg cannot run because the PATH env variable is not set."
98
+ end
96
99
  ENV['PATH'].split(':').each do |path|
97
100
  TARNAMES.each do |tarname|
98
101
  if File.executable?(File.join(path, tarname))
@@ -308,10 +311,15 @@ class Tpkg
308
311
  raise "Failed to create package." unless options[:force]
309
312
  end
310
313
 
311
- # file_metadata.yml hold information for files that are installed
314
+ # file_metadata hold information for files that are installed
312
315
  # by the package. For example, checksum, path, relocatable or not, etc.
313
316
  File.open(File.join(tpkgdir, "file_metadata.bin"), "w") do |file|
314
317
  filemetadata = get_filemetadata_from_directory(tpkgdir)
318
+ filemetadata[:files].each do |file1|
319
+ if metadata[:files][:files] && metadata[:files][:files].any?{|file2|file2[:path] == file1[:path] && file2[:config]}
320
+ file1[:config] = true
321
+ end
322
+ end
315
323
  data = filemetadata.to_hash.recursively{|h| h.stringify_keys }
316
324
  Marshal::dump(data, file)
317
325
  end
@@ -378,7 +386,7 @@ class Tpkg
378
386
  end
379
387
 
380
388
  # update metadata file with the tpkg version
381
- # TODO
389
+ metadata.add_tpkg_version(VERSION)
382
390
 
383
391
  # Tar up the tpkg directory
384
392
  tpkgfile = File.join(package_directory, 'tpkg.tar')
@@ -484,12 +492,12 @@ class Tpkg
484
492
  #return FileMetadata.new(YAML::dump(filemetadata),'yml')
485
493
  return FileMetadata.new(Marshal::dump(filemetadata),'bin')
486
494
  end
487
-
488
- def self.verify_package_checksum(package_file)
489
- topleveldir = package_toplevel_directory(package_file)
495
+
496
+ def self.verify_package_checksum(package_file, options = {})
497
+ topleveldir = options[:topleveldir] || package_toplevel_directory(package_file)
490
498
  # Extract checksum.xml from the package
491
499
  checksum_xml = nil
492
- IO.popen("#{find_tar} -xf #{package_file} -O #{File.join(topleveldir, 'checksum.xml')} #{@@taroptions}") do |pipe|
500
+ IO.popen("#{find_tar} #{@@taroptions} -xf #{package_file} -O #{File.join(topleveldir, 'checksum.xml')}") do |pipe|
493
501
  checksum_xml = REXML::Document.new(pipe.read)
494
502
  end
495
503
  if !$?.success?
@@ -536,8 +544,8 @@ class Tpkg
536
544
  end
537
545
 
538
546
  # Extracts and returns the metadata from a package file
539
- def self.metadata_from_package(package_file)
540
- topleveldir = package_toplevel_directory(package_file)
547
+ def self.metadata_from_package(package_file, options = {})
548
+ topleveldir = options[:topleveldir] || package_toplevel_directory(package_file)
541
549
  # Verify checksum
542
550
  verify_package_checksum(package_file)
543
551
  # Extract and parse tpkg.xml
@@ -880,10 +888,7 @@ class Tpkg
880
888
  end
881
889
 
882
890
  def self.files_in_package(package_file, options = {})
883
- file_lists = []
884
- files = {}
885
- files[:root] = []
886
- files[:reloc] = []
891
+ files = {:root => [], :reloc => []}
887
892
 
888
893
  # If the metadata_directory option is available, it means this package
889
894
  # has been installed and the file_metadata might be available in that directory.
@@ -903,6 +908,7 @@ class Tpkg
903
908
  end
904
909
  end
905
910
  else
911
+ file_lists = []
906
912
  topleveldir = package_toplevel_directory(package_file)
907
913
  extract_tpkg_tar_cmd = cmd_to_extract_tpkg_tar(package_file, topleveldir)
908
914
  IO.popen("#{extract_tpkg_tar_cmd} | #{find_tar} #{@@taroptions} -tf -") do |pipe|
@@ -1137,7 +1143,7 @@ class Tpkg
1137
1143
  # Return what type of compression. If tpkg.tar wasn't compressed, then return nil.
1138
1144
  def self.get_compression(package_file)
1139
1145
  compression = nil
1140
- IO.popen("#{find_tar} -tf #{package_file} #{@@taroptions}") do |pipe|
1146
+ IO.popen("#{find_tar} #{@@taroptions} -tf #{package_file}") do |pipe|
1141
1147
  pipe.each do |file|
1142
1148
  if file =~ /tpkg.tar.gz$/
1143
1149
  compression = "gzip"
@@ -1154,11 +1160,11 @@ class Tpkg
1154
1160
  def self.cmd_to_extract_tpkg_tar(package_file, topleveldir)
1155
1161
  compression = get_compression(package_file)
1156
1162
  if compression == "gzip"
1157
- cmd = "#{find_tar} -xf #{package_file} -O #{File.join(topleveldir, 'tpkg.tar.gz')} #{@@taroptions} | gunzip -c"
1163
+ cmd = "#{find_tar} #{@@taroptions} -xf #{package_file} -O #{File.join(topleveldir, 'tpkg.tar.gz')} | gunzip -c"
1158
1164
  elsif compression == "bz2"
1159
- cmd = "#{find_tar} -xf #{package_file} -O #{File.join(topleveldir, 'tpkg.tar.bz2')} #{@@taroptions} | bunzip2 -c"
1165
+ cmd = "#{find_tar} #{@@taroptions} -xf #{package_file} -O #{File.join(topleveldir, 'tpkg.tar.bz2')} | bunzip2 -c"
1160
1166
  else
1161
- cmd = "#{find_tar} -xf #{package_file} -O #{File.join(topleveldir, 'tpkg.tar')} #{@@taroptions}"
1167
+ cmd = "#{find_tar} #{@@taroptions} -xf #{package_file} -O #{File.join(topleveldir, 'tpkg.tar')}"
1162
1168
  end
1163
1169
  end
1164
1170
 
@@ -1759,7 +1765,7 @@ class Tpkg
1759
1765
  ret = {}
1760
1766
 
1761
1767
  if package_files
1762
- packages_files.collect!{|package_file| File.basename(package_file, File.extname(package_file))}
1768
+ package_files.collect!{|package_file| File.basename(package_file, File.extname(package_file))}
1763
1769
  end
1764
1770
 
1765
1771
  if File.directory?(@metadata_directory)
@@ -2459,7 +2465,6 @@ class Tpkg
2459
2465
  # calling this method.
2460
2466
  def unpack(package_file, options={})
2461
2467
  ret_val = 0
2462
- metadata = Tpkg::metadata_from_package(package_file)
2463
2468
 
2464
2469
  # set env variable to let pre/post install know whether this unpack
2465
2470
  # is part of an install or upgrade
@@ -2483,24 +2488,20 @@ class Tpkg
2483
2488
  files_info = {} # store perms, uid, gid, etc. for files
2484
2489
  checksums_of_decrypted_files = {}
2485
2490
 
2486
- # Get list of conflicting files/directories & store their perm/ownership. That way, we can
2487
- # set them to the correct values later on in order to preserve them.
2488
- rel_root_dir = File.join('tpkg', 'root')
2489
- rel_reloc_dir = File.join('tpkg', 'reloc')
2490
- files = `#{extract_tpkg_tar_cmd} | #{@tar} #{@@taroptions} -tf -`
2491
- files = files.split("\n")
2491
+ metadata = Tpkg::metadata_from_package(package_file, {:topleveldir => topleveldir})
2492
+
2493
+ # Get list of files/directories that already exist in the system. Store their perm/ownership.
2494
+ # That way, when we copy over the new files, we can set the new files to have the same perm/owernship.
2492
2495
  conflicting_files = {}
2493
- files.each do | file |
2494
- if file =~ /^#{rel_root_dir}/
2495
- possible_conflicting_file = File.join(@file_system_root, file[rel_root_dir.length ..-1])
2496
- elsif file =~ /^#{rel_reloc_dir}/
2497
- possible_conflicting_file = File.join(@base, file[rel_reloc_dir.length + 1..-1])
2498
- end
2499
- if possible_conflicting_file && (File.exists?(possible_conflicting_file) && !File.symlink?(possible_conflicting_file))
2500
- conflicting_files[File.join(workdir, file)] = File.stat(possible_conflicting_file)
2496
+ fip = Tpkg::files_in_package(package_file)
2497
+ (fip[:root] | fip[:reloc]).each do |file|
2498
+ file_in_staging = normalize_path(file, File.join(workdir, 'tpkg', 'root'), File.join(workdir, 'tpkg', 'reloc'))
2499
+ file_in_system = normalize_path(file)
2500
+ if File.exists?(file_in_system) && !File.symlink?(file_in_system)
2501
+ conflicting_files[file] = {:normalized => file_in_staging, :stat => File.stat(file_in_system)}
2501
2502
  end
2502
2503
  end
2503
-
2504
+
2504
2505
  run_preinstall(package_file, workdir)
2505
2506
 
2506
2507
  run_externals_for_install(metadata, workdir, options[:externals_to_skip])
@@ -2568,12 +2569,14 @@ class Tpkg
2568
2569
  # Reset the permission/ownership of the conflicting files as how they were before.
2569
2570
  # This needs to be done after the default permission/ownership is applied, but before
2570
2571
  # the handling of ownership/permissions on specific files
2571
- conflicting_files.each do | file, stat |
2572
- File.chmod(stat.mode, file)
2573
- File.chown(stat.uid, stat.gid, file)
2572
+ conflicting_files.each do | file, info |
2573
+ stat = info[:stat]
2574
+ file_path = info[:normalized]
2575
+ File.chmod(stat.mode, file_path)
2576
+ File.chown(stat.uid, stat.gid, file_path)
2574
2577
  end
2575
2578
 
2576
- # Handle any decryption and ownership/permissions on specific files
2579
+ # Handle any decryption, ownership/permissions, and other issues for specific files
2577
2580
  metadata[:files][:files].each do |tpkgfile|
2578
2581
  tpkg_path = tpkgfile[:path]
2579
2582
  working_path = normalize_path(tpkg_path, File.join(workdir, 'tpkg', 'root'), File.join(workdir, 'tpkg', 'reloc'))
@@ -2639,6 +2642,12 @@ class Tpkg
2639
2642
  end
2640
2643
  end
2641
2644
  end
2645
+
2646
+ # If a conf file already exists on the file system, don't overwrite it. Rename
2647
+ # the new one with .tpkgnew file extension.
2648
+ if tpkgfile[:config] && conflicting_files[tpkgfile[:path]]
2649
+ FileUtils.mv(conflicting_files[tpkgfile[:path]][:normalized], "#{conflicting_files[tpkgfile[:path]][:normalized]}.tpkgnew")
2650
+ end
2642
2651
  end if metadata[:files] && metadata[:files][:files]
2643
2652
 
2644
2653
  # We should get the perms, gid, uid stuff here since all the files
@@ -3515,6 +3524,8 @@ class Tpkg
3515
3524
  else
3516
3525
  if prompt_for_conflicting_files(pkgfile)
3517
3526
  ret_val |= unpack(pkgfile, :passphrase => passphrase)
3527
+ # create and install stubbed native package if needed
3528
+ stub_native_pkg(pkg)
3518
3529
  end
3519
3530
  end
3520
3531
  end
@@ -3588,8 +3599,10 @@ class Tpkg
3588
3599
  if dep[:name] == req[:name]
3589
3600
  # Package metadata is almost usable as-is as a req, just need to
3590
3601
  # set :type
3591
- addreq = metadata.to_hash
3602
+ # and remove filename (since we're not explicitly requesting the exact file)
3603
+ addreq = metadata.to_hash.clone
3592
3604
  addreq[:type] = :tpkg
3605
+ addreq[:filename] = nil
3593
3606
  additional_requirements << addreq
3594
3607
  end
3595
3608
  end if metadata[:dependencies]
@@ -3768,7 +3781,8 @@ class Tpkg
3768
3781
  ret_val |= unpack(pkgfile, :passphrase => passphrase, :externals_to_skip => externals_to_skip,
3769
3782
  :is_doing_upgrade => is_doing_upgrade)
3770
3783
  end
3771
-
3784
+ # create and install stubbed native package if needed
3785
+ stub_native_pkg(pkg)
3772
3786
  has_updates = true
3773
3787
  end
3774
3788
  end
@@ -3946,13 +3960,36 @@ class Tpkg
3946
3960
  run_external(pkg[:metadata][:filename], :remove, external[:name], external[:data])
3947
3961
  end
3948
3962
  end if pkg[:metadata][:externals]
3949
-
3963
+
3964
+ # determine which configuration files have been modified
3965
+ modified_conf_files = []
3966
+ file_metadata = file_metadata_for_installed_packages([pkg[:metadata][:filename]]).values[0]
3967
+ file_metadata[:files].each do |file|
3968
+ if file[:config]
3969
+ # get expected checksum. For files that were encrypted, we're interested in the
3970
+ # checksum of the decrypted version
3971
+ chksum_expected = file[:checksum][:digests].first[:value]
3972
+ file[:checksum][:digests].each do | digest |
3973
+ if digest[:decrypted] == true
3974
+ chksum_expected = digest[:value].to_s
3975
+ end
3976
+ end
3977
+ fp = normalize_path(file[:path])
3978
+ chksum_actual = Digest::SHA256.hexdigest(File.read(fp))
3979
+ if chksum_actual != chksum_expected
3980
+ modified_conf_files << fp
3981
+ end
3982
+ end
3983
+ end if file_metadata
3984
+
3950
3985
  # Remove files
3951
3986
  files_to_remove = conflicting_files(package_file, CHECK_REMOVE)
3952
3987
  # Reverse the order of the files, as directories will appear first
3953
3988
  # in the listing but we want to remove any files in them before
3954
3989
  # trying to remove the directory.
3955
3990
  files_to_remove.reverse.each do |file|
3991
+ # don't remove conf files that have been modified
3992
+ next if modified_conf_files.include?(file)
3956
3993
  begin
3957
3994
  if !File.directory?(file)
3958
3995
  File.delete(file)
@@ -4006,6 +4043,9 @@ class Tpkg
4006
4043
  package_metadata_dir = File.join(@metadata_directory, File.basename(package_file, File.extname(package_file)))
4007
4044
  FileUtils.rm_rf(package_metadata_dir)
4008
4045
 
4046
+ # remove native dependency stub packages if needed
4047
+ remove_native_stub_pkg(pkg)
4048
+
4009
4049
  # Cleanup
4010
4050
  FileUtils.rm_rf(workdir)
4011
4051
  end
@@ -4079,12 +4119,7 @@ class Tpkg
4079
4119
  perms_expected = file[:perms].to_s
4080
4120
  end
4081
4121
 
4082
- # normalize file path
4083
- if file[:relocatable] == true
4084
- fp = File.join(@base, fp)
4085
- else
4086
- fp = File.join(@file_system_root, fp)
4087
- end
4122
+ fp = normalize_path(fp)
4088
4123
 
4089
4124
  # can't handle symlink
4090
4125
  if File.symlink?(fp)
@@ -4463,6 +4498,102 @@ class Tpkg
4463
4498
  puts "Failed to send update to reporter server"
4464
4499
  end
4465
4500
  end
4501
+
4502
+ # create and install native stub package if needed
4503
+ # this stub package helps prevent user from removing native packages that
4504
+ # our tpkg packages depend on
4505
+ def stub_native_pkg(pkg)
4506
+ # gather all of the native dependencies
4507
+ native_deps = pkg[:metadata].get_native_deps
4508
+
4509
+ return if native_deps.nil? or native_deps.empty?
4510
+
4511
+ if Tpkg::get_os =~ /RedHat|CentOS|Fedora/
4512
+ rpm = create_rpm("stub_for_#{pkg[:metadata][:name]}", native_deps)
4513
+ return if rpm.nil?
4514
+
4515
+ # install the rpm
4516
+ cmd = "rpm -i #{rpm}"
4517
+ puts cmd if @@debug
4518
+ system(cmd)
4519
+ if !$?.success?
4520
+ warn "Warning: Failed to install native stub package for #{pkg[:metadata][:name]}"
4521
+ end
4522
+ else
4523
+ # TODO: support other OSes
4524
+ end
4525
+ end
4526
+
4527
+ # remove the native dependency stub packages if there's any
4528
+ def remove_native_stub_pkg(pkg)
4529
+ # Don't have to do anything if this package has no native dependencies
4530
+ native_deps = pkg[:metadata].get_native_deps
4531
+ return if native_deps.nil? or native_deps.empty?
4532
+
4533
+ # the convention is that stub package is named as "stub_for_pkgname"
4534
+ stub_pkg_name = "stub_for_#{pkg[:metadata][:name]}"
4535
+
4536
+ if Tpkg::get_os =~ /RedHat|CentOS|Fedora/
4537
+ cmd = "yum -y remove #{stub_pkg_name}"
4538
+ puts cmd if @@debug
4539
+ system(cmd)
4540
+ if !$?.success?
4541
+ warn "Warning: Failed to remove native stub package for #{pkg[:metadata][:name]}"
4542
+ end
4543
+ else
4544
+ # TODO: support other OSes
4545
+ end
4546
+ end
4466
4547
 
4548
+ def create_rpm(name, deps=[])
4549
+ # setup directories for rpmbuild
4550
+ topdir = Tpkg::tempdir('rpmbuild')
4551
+ %w[BUILD RPMS SOURCES SPECS SRPMS].each do |dir|
4552
+ FileUtils.mkdir_p(File.join(topdir, dir))
4553
+ end
4554
+
4555
+ dep_list = deps.collect{|dep|dep[:name]}.join(",")
4556
+
4557
+ # create rpm spec file
4558
+ spec = <<-EOS.gsub(/^\s+/, "")
4559
+ Name: #{name}
4560
+ Summary: stub pkg created by tpkg
4561
+ Version: 1
4562
+ Release: 1
4563
+ buildarch: noarch
4564
+ Requires: #{dep_list}
4565
+ Group: Applications/System
4566
+ License: MIT
4567
+ BuildRoot: %{_builddir}/%{name}-buildroot
4568
+ %description
4569
+ stub pkg created by tpkg for the following dependencies: #{dep_list}
4570
+ %files
4571
+ EOS
4572
+ spec_file = File.join(topdir, 'SPECS', 'pkg.spec')
4573
+ File.open(spec_file, 'w') do |file|
4574
+ file.puts(spec)
4575
+ end
4576
+
4577
+ # run rpmbuild
4578
+ system("rpmbuild -bb --define '_topdir #{topdir}' #{spec_file}")
4579
+ if !$?.success?
4580
+ warn "Warning: Failed to create native stub package for #{name}"
4581
+ return nil
4582
+ end
4583
+
4584
+ # copy result over to tmpfile
4585
+ result = File.join(topdir, 'RPMS', 'noarch', "#{name}-1-1.noarch.rpm")
4586
+ rpm = nil
4587
+ if File.exists?(result)
4588
+ tmpfile = Tempfile.new(File.basename(result))
4589
+ FileUtils.cp(result, tmpfile.path)
4590
+ rpm = tmpfile.path
4591
+ end
4592
+
4593
+ # cleanup
4594
+ FileUtils.rm_rf(topdir)
4595
+
4596
+ return rpm
4597
+ end
4467
4598
  end
4468
4599
 
@@ -221,8 +221,8 @@ end
221
221
  # is that you can give it a metadata file of any format, such as yaml or xml,
222
222
  # and it will provide you a uniform interface for accessing/dealing with the metadata.
223
223
  class Metadata
224
- attr_accessor :source
225
- REQUIRED_FIELDS = [:name, :version, :maintainer]
224
+ attr_accessor :source, :file_path
225
+ REQUIRED_FIELDS = [:name, :version, :maintainer, :description]
226
226
 
227
227
  # Cleans up a string to make it suitable for use in a filename
228
228
  def self.clean_for_filename(dirtystring)
@@ -248,8 +248,10 @@ class Metadata
248
248
  metadata = nil
249
249
  if File.exist?(File.join(dir, 'tpkg.yml'))
250
250
  metadata = Metadata.new(File.read(File.join(dir, 'tpkg.yml')), 'yml')
251
+ metadata.file_path = File.join(dir, 'tpkg.yml')
251
252
  elsif File.exists?(File.join(dir, 'tpkg.xml'))
252
253
  metadata = Metadata.new(File.read(File.join(dir, 'tpkg.xml')), 'xml')
254
+ metadata.file_path = File.join(dir, 'tpkg.xml')
253
255
  end
254
256
  return metadata
255
257
  end
@@ -330,6 +332,33 @@ class Metadata
330
332
  file.close
331
333
  end
332
334
 
335
+ # Add tpkg_version to the existing tpkg.xml or tpkg.yml file
336
+ def add_tpkg_version(version)
337
+ if @format == 'xml'
338
+ metadata_xml = REXML::Document.new(@metadata_text)
339
+ if metadata_xml.root.elements["tpkg_version"] && (tpkg_version = metadata_xml.root.elements["tpkg_version"].text) != Tpkg::VERSION
340
+ warn "Warning: tpkg_version is specified as #{tpkg_version}, which doesn't match with the actual tpkg version being used (#{Tpkg::VERSION})."
341
+ elsif !metadata_xml.root.elements["tpkg_version"]
342
+ tpkg_version_ele = REXML::Element.new("tpkg_version")
343
+ tpkg_version_ele.text = Tpkg::VERSION
344
+ metadata_xml.root.add_element(tpkg_version_ele)
345
+ File.open(@file_path, 'w') do |file|
346
+ metadata_xml.write(file)
347
+ end
348
+ end
349
+ elsif @format == 'yml'
350
+ if (tpkg_version = to_hash[:tpkg_version]) && tpkg_version != Tpkg::VERSION
351
+ warn "Warning: tpkg_version is specified as #{tpkg_version}, which doesn't match with the actual tpkg version being used (#{Tpkg::VERSION})."
352
+ elsif !tpkg_version
353
+ File.open(@file_path, 'a') do |file|
354
+ file.puts "tpkg_version: #{Tpkg::VERSION}"
355
+ end
356
+ end
357
+ else
358
+ raise "Unknown metadata format"
359
+ end
360
+ end
361
+
333
362
  def generate_package_filename
334
363
  name = to_hash[:name]
335
364
  version = to_hash[:version]
@@ -454,7 +483,7 @@ class Metadata
454
483
  end
455
484
  end
456
485
 
457
- [:package_version, :description, :bugreporting].each do |optfield|
486
+ [:tpkg_version, :package_version, :description, :bugreporting].each do |optfield|
458
487
  if metadata_xml.elements["/tpkg/#{optfield.to_s}"]
459
488
  metadata_hash[optfield] =
460
489
  metadata_xml.elements["/tpkg/#{optfield.to_s}"].text
@@ -596,6 +625,7 @@ class Metadata
596
625
  metadata_xml.elements.each('/tpkg/files/file') do |filexml|
597
626
  file = {}
598
627
  file[:path] = filexml.elements['path'].text
628
+ file[:config] = true if filexml.elements['config']
599
629
  if filexml.elements['encrypt']
600
630
  encrypt = {}
601
631
  if filexml.elements['encrypt'].attribute('precrypt') &&
@@ -656,6 +686,13 @@ class Metadata
656
686
 
657
687
  return metadata_hash
658
688
  end
689
+
690
+ def get_native_deps
691
+ dependencies = to_hash[:dependencies]
692
+ return nil if dependencies.nil? or dependencies.empty?
693
+
694
+ return dependencies.select{|dep| dep[:type] == :native}
695
+ end
659
696
  end
660
697
 
661
698
  class FileMetadata < Metadata
@@ -0,0 +1,93 @@
1
+ type: map
2
+ mapping:
3
+ "schema_file": { type: text }
4
+ "tpkg_version": { type: text }
5
+ "name": { type: str, required: yes }
6
+ "version": { type: text, required: yes }
7
+ "package_version": { type: text }
8
+ "maintainer": { type: str, required: yes }
9
+ "operatingsystem": { type: seq, sequence: [ {type: str} ] }
10
+ "architecture": { type: seq, sequence: [ {type: str} ] }
11
+ "description": { type: str }
12
+ "bugreporting": { type: str }
13
+ "dependencies":
14
+ type: seq
15
+ sequence:
16
+ - type: map
17
+ mapping:
18
+ "name": { type: str, required: yes }
19
+ "minimum_version": { type: text }
20
+ "maximum_version": { type: text }
21
+ "minimum_package_version": { type: text }
22
+ "maximum_package_version": { type: text }
23
+ "allowed_versions": { type: text }
24
+ "native": { type: bool }
25
+ "type": { type: any, pattern: /(native|tpkg)$/ }
26
+ "conflicts":
27
+ type: seq
28
+ sequence:
29
+ - type: map
30
+ mapping:
31
+ "name": { type: str, required: yes }
32
+ "minimum_version": { type: text }
33
+ "maximum_version": { type: text }
34
+ "minimum_package_version": { type: text }
35
+ "maximum_package_version": { type: text }
36
+ "native": { type: bool }
37
+ "type": { type: any, pattern: /(native|tpkg)$/ }
38
+ "externals":
39
+ type: seq
40
+ sequence:
41
+ - type: map
42
+ mapping:
43
+ "name": { type: text, required: yes }
44
+ "data": { type: text }
45
+ "datascript": { type: text }
46
+ "datafile": { type: text }
47
+ "files":
48
+ type: map
49
+ mapping:
50
+ "file_defaults":
51
+ type: map
52
+ mapping:
53
+ "posix":
54
+ type: map
55
+ mapping:
56
+ "owner": { type: text }
57
+ "group": { type: text }
58
+ "perms": { type: text }
59
+ "dirs_defaults":
60
+ type: map
61
+ mapping:
62
+ "posix":
63
+ type: map
64
+ mapping:
65
+ "owner": { type: text }
66
+ "group": { type: text }
67
+ "perms": { type: text }
68
+ "files":
69
+ type: seq
70
+ sequence:
71
+ - type: map
72
+ mapping:
73
+ "config": { type: bool, default: false }
74
+ "path": { type: text, required: yes }
75
+ "encrypt":
76
+ type: map
77
+ mapping:
78
+ "algorithm": { type: text }
79
+ "precrypt": { type: any, pattern: /^true$|^false$/ }
80
+ "init":
81
+ type: map
82
+ mapping:
83
+ "start": { type: int }
84
+ "levels": { type: seq, sequence: [ { type: int } ] }
85
+ "crontab":
86
+ type: map
87
+ mapping: { "user": { type: str } }
88
+ "posix":
89
+ type: map
90
+ mapping: { "owner": { type: text },
91
+ "group": { type: text },
92
+ "perms": { type: text } }
93
+
@@ -0,0 +1,93 @@
1
+ type: map
2
+ mapping:
3
+ "schema_file": { type: text }
4
+ "tpkg_version": { type: text }
5
+ "name": { type: str, required: yes }
6
+ "version": { type: text, required: yes }
7
+ "package_version": { type: text }
8
+ "maintainer": { type: str, required: yes }
9
+ "operatingsystem": { type: seq, sequence: [ {type: str} ] }
10
+ "architecture": { type: seq, sequence: [ {type: str} ] }
11
+ "description": { type: str, required: yes }
12
+ "bugreporting": { type: str }
13
+ "dependencies":
14
+ type: seq
15
+ sequence:
16
+ - type: map
17
+ mapping:
18
+ "name": { type: str, required: yes }
19
+ "minimum_version": { type: text }
20
+ "maximum_version": { type: text }
21
+ "minimum_package_version": { type: text }
22
+ "maximum_package_version": { type: text }
23
+ "allowed_versions": { type: text }
24
+ "native": { type: bool }
25
+ "type": { type: any, pattern: /(native|tpkg)$/ }
26
+ "conflicts":
27
+ type: seq
28
+ sequence:
29
+ - type: map
30
+ mapping:
31
+ "name": { type: str, required: yes }
32
+ "minimum_version": { type: text }
33
+ "maximum_version": { type: text }
34
+ "minimum_package_version": { type: text }
35
+ "maximum_package_version": { type: text }
36
+ "native": { type: bool }
37
+ "type": { type: any, pattern: /(native|tpkg)$/ }
38
+ "externals":
39
+ type: seq
40
+ sequence:
41
+ - type: map
42
+ mapping:
43
+ "name": { type: text, required: yes }
44
+ "data": { type: text }
45
+ "datascript": { type: text }
46
+ "datafile": { type: text }
47
+ "files":
48
+ type: map
49
+ mapping:
50
+ "file_defaults":
51
+ type: map
52
+ mapping:
53
+ "posix":
54
+ type: map
55
+ mapping:
56
+ "owner": { type: text }
57
+ "group": { type: text }
58
+ "perms": { type: text }
59
+ "dirs_defaults":
60
+ type: map
61
+ mapping:
62
+ "posix":
63
+ type: map
64
+ mapping:
65
+ "owner": { type: text }
66
+ "group": { type: text }
67
+ "perms": { type: text }
68
+ "files":
69
+ type: seq
70
+ sequence:
71
+ - type: map
72
+ mapping:
73
+ "config": { type: bool, default: false }
74
+ "path": { type: text, required: yes }
75
+ "encrypt":
76
+ type: map
77
+ mapping:
78
+ "algorithm": { type: text }
79
+ "precrypt": { type: any, pattern: /^true$|^false$/ }
80
+ "init":
81
+ type: map
82
+ mapping:
83
+ "start": { type: int }
84
+ "levels": { type: seq, sequence: [ { type: int } ] }
85
+ "crontab":
86
+ type: map
87
+ mapping: { "user": { type: str } }
88
+ "posix":
89
+ type: map
90
+ mapping: { "owner": { type: text },
91
+ "group": { type: text },
92
+ "perms": { type: text } }
93
+
@@ -1,13 +1,14 @@
1
1
  type: map
2
2
  mapping:
3
3
  "schema_file": { type: text }
4
+ "tpkg_version": { type: text }
4
5
  "name": { type: str, required: yes }
5
6
  "version": { type: text, required: yes }
6
7
  "package_version": { type: text }
7
8
  "maintainer": { type: str, required: yes }
8
9
  "operatingsystem": { type: seq, sequence: [ {type: str} ] }
9
10
  "architecture": { type: seq, sequence: [ {type: str} ] }
10
- "description": { type: str }
11
+ "description": { type: str, required: yes }
11
12
  "bugreporting": { type: str }
12
13
  "dependencies":
13
14
  type: seq
@@ -69,6 +70,7 @@ mapping:
69
70
  sequence:
70
71
  - type: map
71
72
  mapping:
73
+ "config": { type: bool, default: false }
72
74
  "path": { type: text, required: yes }
73
75
  "encrypt":
74
76
  type: map
@@ -0,0 +1,45 @@
1
+ <!ELEMENT tpkg (name, version, package_version?, maintainer+, operatingsystem*, architecture*, description?, bugreporting?, dependencies?, externals?, files?, tpkg_version?)>
2
+
3
+ <!ELEMENT name (#PCDATA)>
4
+ <!ELEMENT version (#PCDATA)>
5
+ <!ELEMENT package_version (#PCDATA)>
6
+ <!ELEMENT maintainer (#PCDATA)>
7
+ <!ELEMENT operatingsystem (#PCDATA)>
8
+ <!ELEMENT architecture (#PCDATA)>
9
+ <!ELEMENT description (#PCDATA)>
10
+ <!ELEMENT bugreporting (#PCDATA)>
11
+
12
+ <!ELEMENT dependencies (dependency*)>
13
+ <!ELEMENT dependency (name, minimum_version?, maximum_version?, minimum_package_version?, maximum_package_version?, allowed_versions?, native?)>
14
+ <!ELEMENT minimum_version (#PCDATA)>
15
+ <!ELEMENT maximum_version (#PCDATA)>
16
+ <!ELEMENT minimum_package_version (#PCDATA)>
17
+ <!ELEMENT maximum_package_version (#PCDATA)>
18
+ <!ELEMENT allowed_versions (#PCDATA)>
19
+ <!ELEMENT native EMPTY>
20
+
21
+ <!ELEMENT externals (external*)>
22
+ <!ELEMENT external (name, (data|datafile|datascript))>
23
+ <!ELEMENT data (#PCDATA)>
24
+ <!ELEMENT datafile (#PCDATA)>
25
+ <!ELEMENT datascript (#PCDATA)>
26
+
27
+ <!ELEMENT files (file_defaults?, file*)>
28
+ <!ELEMENT file_defaults (posix?)>
29
+ <!ELEMENT posix (owner?, group?, perms?)>
30
+ <!ELEMENT owner (#PCDATA)>
31
+ <!ELEMENT group (#PCDATA)>
32
+ <!ELEMENT perms (#PCDATA)>
33
+ <!ELEMENT file (path, config?, encrypt?, init?, crontab?, posix?)>
34
+ <!ELEMENT path (#PCDATA)>
35
+ <!ELEMENT config EMPTY>
36
+ <!ELEMENT encrypt EMPTY>
37
+ <!ATTLIST encrypt precrypt (true|false) #IMPLIED>
38
+ <!ATTLIST encrypt algorithm CDATA #IMPLIED>
39
+ <!ELEMENT init (start?, levels?)>
40
+ <!ELEMENT start (#PCDATA)>
41
+ <!ELEMENT levels (#PCDATA)>
42
+ <!ELEMENT crontab (user?)>
43
+ <!ELEMENT user (#PCDATA)>
44
+
45
+ <!ELEMENT tpkg_version (#PCDATA)>
@@ -0,0 +1,45 @@
1
+ <!ELEMENT tpkg (name, version, package_version?, maintainer+, operatingsystem*, architecture*, description, bugreporting?, dependencies?, externals?, files?, tpkg_version?)>
2
+
3
+ <!ELEMENT name (#PCDATA)>
4
+ <!ELEMENT version (#PCDATA)>
5
+ <!ELEMENT package_version (#PCDATA)>
6
+ <!ELEMENT maintainer (#PCDATA)>
7
+ <!ELEMENT operatingsystem (#PCDATA)>
8
+ <!ELEMENT architecture (#PCDATA)>
9
+ <!ELEMENT description (#PCDATA)>
10
+ <!ELEMENT bugreporting (#PCDATA)>
11
+
12
+ <!ELEMENT dependencies (dependency*)>
13
+ <!ELEMENT dependency (name, minimum_version?, maximum_version?, minimum_package_version?, maximum_package_version?, allowed_versions?, native?)>
14
+ <!ELEMENT minimum_version (#PCDATA)>
15
+ <!ELEMENT maximum_version (#PCDATA)>
16
+ <!ELEMENT minimum_package_version (#PCDATA)>
17
+ <!ELEMENT maximum_package_version (#PCDATA)>
18
+ <!ELEMENT allowed_versions (#PCDATA)>
19
+ <!ELEMENT native EMPTY>
20
+
21
+ <!ELEMENT externals (external*)>
22
+ <!ELEMENT external (name, (data|datafile|datascript))>
23
+ <!ELEMENT data (#PCDATA)>
24
+ <!ELEMENT datafile (#PCDATA)>
25
+ <!ELEMENT datascript (#PCDATA)>
26
+
27
+ <!ELEMENT files (file_defaults?, file*)>
28
+ <!ELEMENT file_defaults (posix?)>
29
+ <!ELEMENT posix (owner?, group?, perms?)>
30
+ <!ELEMENT owner (#PCDATA)>
31
+ <!ELEMENT group (#PCDATA)>
32
+ <!ELEMENT perms (#PCDATA)>
33
+ <!ELEMENT file (path, config?, encrypt?, init?, crontab?, posix?)>
34
+ <!ELEMENT path (#PCDATA)>
35
+ <!ELEMENT config EMPTY>
36
+ <!ELEMENT encrypt EMPTY>
37
+ <!ATTLIST encrypt precrypt (true|false) #IMPLIED>
38
+ <!ATTLIST encrypt algorithm CDATA #IMPLIED>
39
+ <!ELEMENT init (start?, levels?)>
40
+ <!ELEMENT start (#PCDATA)>
41
+ <!ELEMENT levels (#PCDATA)>
42
+ <!ELEMENT crontab (user?)>
43
+ <!ELEMENT user (#PCDATA)>
44
+
45
+ <!ELEMENT tpkg_version (#PCDATA)>
@@ -1,4 +1,4 @@
1
- <!ELEMENT tpkg (name, version, package_version?, maintainer+, operatingsystem*, architecture*, description?, bugreporting?, dependencies?, externals?, files?)>
1
+ <!ELEMENT tpkg (name, version, package_version?, maintainer+, operatingsystem*, architecture*, description, bugreporting?, dependencies?, externals?, files?, tpkg_version?)>
2
2
 
3
3
  <!ELEMENT name (#PCDATA)>
4
4
  <!ELEMENT version (#PCDATA)>
@@ -30,8 +30,9 @@
30
30
  <!ELEMENT owner (#PCDATA)>
31
31
  <!ELEMENT group (#PCDATA)>
32
32
  <!ELEMENT perms (#PCDATA)>
33
- <!ELEMENT file (path, encrypt?, init?, crontab?, posix?)>
33
+ <!ELEMENT file (path, config?, encrypt?, init?, crontab?, posix?)>
34
34
  <!ELEMENT path (#PCDATA)>
35
+ <!ELEMENT config EMPTY>
35
36
  <!ELEMENT encrypt EMPTY>
36
37
  <!ATTLIST encrypt precrypt (true|false) #IMPLIED>
37
38
  <!ATTLIST encrypt algorithm CDATA #IMPLIED>
@@ -41,3 +42,4 @@
41
42
  <!ELEMENT crontab (user?)>
42
43
  <!ELEMENT user (#PCDATA)>
43
44
 
45
+ <!ELEMENT tpkg_version (#PCDATA)>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tpkg
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.25.1
4
+ version: 1.27.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Darren Dao
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2010-07-14 00:00:00 +00:00
13
+ date: 2010-07-29 00:00:00 +00:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -61,9 +61,11 @@ files:
61
61
  - lib/tpkg/metadata.rb
62
62
  - lib/tpkg.rb
63
63
  - schema/tpkg-1.0.4.dtd
64
+ - schema/schema-1.0.9.yml
64
65
  - schema/tpkg-1.0.0.dtd
65
66
  - schema/tpkg-1.0.5.dtd
66
67
  - schema/schema-1.0.7.yml
68
+ - schema/tpkg-1.0.9.dtd
67
69
  - schema/tpkg.dtd
68
70
  - schema/tpkg-1.0.1.dtd
69
71
  - schema/tpkg-1.0.7.dtd
@@ -72,6 +74,8 @@ files:
72
74
  - schema/tpkg-1.0.2.dtd
73
75
  - schema/schema-1.0.6.yml
74
76
  - schema/schema-1.0.yml
77
+ - schema/tpkg-1.0.8.dtd
78
+ - schema/schema-1.0.8.yml
75
79
  - schema/tpkg-1.0.6.dtd
76
80
  - schema/schema-1.0.5.yml
77
81
  - bin/tpkg