tpkg 1.25.1 → 1.27.1

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