tpkg 2.2.4 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +7 -7
- data/bin/cpan2tpkg +37 -42
- data/bin/gem2tpkg +60 -52
- data/bin/tpkg +636 -205
- data/bin/tpkg_xml_to_yml +5 -3
- data/lib/tpkg.rb +229 -75
- data/lib/tpkg/deployer.rb +0 -1
- data/lib/tpkg/metadata.rb +0 -1
- data/lib/tpkg/thread_pool.rb +0 -1
- data/lib/tpkg/versiontype.rb +0 -1
- metadata +5 -16
data/bin/tpkg_xml_to_yml
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
#!/usr/bin/ruby -w
|
2
2
|
##############################################################################
|
3
3
|
# tpkg package management system
|
4
|
-
# Copyright 2009, 2010, 2011 AT&T Interactive
|
5
4
|
# License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
6
5
|
##############################################################################
|
7
6
|
|
8
|
-
#
|
9
|
-
|
7
|
+
# When run from the source repository or from an unpacked copy of the
|
8
|
+
# distribution we want to find the local library, even if there's a copy
|
9
|
+
# installed on the system. The installed copy is likely older, and the API
|
10
|
+
# may be out of sync with this executable.
|
11
|
+
$:.unshift(File.expand_path('../lib', File.dirname(__FILE__)))
|
10
12
|
|
11
13
|
# This script expects one argument, which is the tpkg.xml file
|
12
14
|
# that you want to convert to yml format.
|
data/lib/tpkg.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
##############################################################################
|
2
2
|
# tpkg package management system
|
3
|
-
# Copyright 2009, 2010, 2011 AT&T Interactive
|
4
3
|
# License: MIT (http://www.opensource.org/licenses/mit-license.php)
|
5
4
|
##############################################################################
|
6
5
|
|
@@ -20,27 +19,30 @@ Silently.silently do
|
|
20
19
|
require 'facter'
|
21
20
|
end
|
22
21
|
require 'digest/sha2' # Digest::SHA256#hexdigest, etc.
|
23
|
-
require '
|
24
|
-
require 'net/http' # Net::HTTP
|
25
|
-
require 'net/https' # Net::HTTP#use_ssl, etc.
|
26
|
-
require 'time' # Time#httpdate
|
27
|
-
require 'rexml/document' # REXML::Document
|
22
|
+
require 'etc' # Etc.getpwnam, getgrnam
|
28
23
|
require 'fileutils' # FileUtils.cp, rm, etc.
|
29
|
-
require 'tempfile' # Tempfile
|
30
24
|
require 'find' # Find
|
31
|
-
require '
|
25
|
+
require 'net/http' # Net::HTTP
|
26
|
+
require 'net/https' # Net::HTTP#use_ssl, etc.
|
32
27
|
require 'openssl' # OpenSSL
|
33
28
|
require 'open3' # Open3
|
34
29
|
require 'set' # Enumerable#to_set
|
30
|
+
require 'rexml/document' # REXML::Document
|
31
|
+
require 'stringio' # StringIO
|
32
|
+
require 'tempfile' # Tempfile
|
33
|
+
require 'time' # Time#httpdate
|
34
|
+
require 'uri' # URI
|
35
35
|
require 'yaml' # YAML
|
36
36
|
end
|
37
|
-
require 'tpkg/versiontype' # Version
|
38
37
|
require 'tpkg/deployer'
|
39
38
|
require 'tpkg/metadata'
|
39
|
+
require 'tpkg/versiontype' # Version
|
40
|
+
|
41
|
+
OpenSSLCipherError = OpenSSL::Cipher.const_defined?(:CipherError) ? OpenSSL::Cipher::CipherError : OpenSSL::CipherError
|
40
42
|
|
41
43
|
class Tpkg
|
42
44
|
|
43
|
-
VERSION = '2.
|
45
|
+
VERSION = '2.3.0'
|
44
46
|
|
45
47
|
GENERIC_ERR = 1
|
46
48
|
POSTINSTALL_ERR = 2
|
@@ -82,17 +84,40 @@ class Tpkg
|
|
82
84
|
if !ENV['PATH']
|
83
85
|
raise "tpkg cannot run because the PATH env variable is not set."
|
84
86
|
end
|
85
|
-
ENV['PATH'].split(
|
87
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
86
88
|
TARNAMES.each do |tarname|
|
87
|
-
|
88
|
-
|
89
|
-
|
89
|
+
tarpath = nil
|
90
|
+
if RUBY_PLATFORM == 'i386-mingw32'
|
91
|
+
# Turns out that File.join is fairly pointless, at least as far
|
92
|
+
# as Windows compatibility. Ruby always uses '/' as the path
|
93
|
+
# separator, even on Windows. I.e. File::SEPARATOR is '/' on
|
94
|
+
# Windows (yes, really!). File::ALT_SEPARATOR is '\' but
|
95
|
+
# File.join and its ilk will never use it. The forward slash
|
96
|
+
# works fine for API-level file operations, Windows will accept
|
97
|
+
# either forward slashes or backslashes at the API level. But
|
98
|
+
# you can't execute a path with forward slashes, apparently due
|
99
|
+
# to some backwards-compatibility thing with cmd.exe. Sigh.
|
100
|
+
tarpath = path.gsub('/', '\\') + '\\' + tarname + '.exe'
|
101
|
+
else
|
102
|
+
tarpath = File.join(path, tarname)
|
103
|
+
end
|
104
|
+
if File.executable?(tarpath)
|
105
|
+
# Particularly on Windows it is possible that the path contains
|
106
|
+
# spaces. I.e. C:\Program Files (x86)\GnuWin32\bin\bsdtar.exe
|
107
|
+
# It looks like that needs to be wrapped in quotes to execute
|
108
|
+
# properly.
|
109
|
+
if tarpath.include?(' ')
|
110
|
+
tarpath = '"' + tarpath + '"'
|
111
|
+
end
|
112
|
+
Open3.popen3("#{tarpath} --version") do |stdin, stdout, stderr|
|
113
|
+
stdin.close
|
114
|
+
stdout.each_line do |line|
|
90
115
|
if line.include?('GNU tar')
|
91
116
|
@@tarinfo[:type] = 'gnu'
|
92
|
-
@@tar =
|
117
|
+
@@tar = tarpath
|
93
118
|
elsif line.include?('bsdtar')
|
94
119
|
@@tarinfo[:type] = 'bsd'
|
95
|
-
@@tar =
|
120
|
+
@@tar = tarpath
|
96
121
|
end
|
97
122
|
if line =~ /(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)/
|
98
123
|
@@tarinfo[:version] = [$1, $2, $3].compact.join(".")
|
@@ -103,7 +128,6 @@ class Tpkg
|
|
103
128
|
end
|
104
129
|
end
|
105
130
|
end
|
106
|
-
# Raise an exception if we didn't find a suitable tar
|
107
131
|
raise "Unable to find GNU tar or bsdtar in PATH"
|
108
132
|
end
|
109
133
|
end
|
@@ -163,10 +187,13 @@ class Tpkg
|
|
163
187
|
File.chown(st.uid, st.gid, tmpfile.path)
|
164
188
|
rescue Errno::EPERM
|
165
189
|
raise if Process.euid == 0
|
190
|
+
rescue Errno::EINVAL
|
191
|
+
raise if RUBY_PLATFORM != 'i386-cygwin'
|
166
192
|
end
|
167
193
|
tmpfile.write(MAGIC)
|
168
194
|
tmpfile.write(salt)
|
169
|
-
|
195
|
+
content = IO.read(filename)
|
196
|
+
tmpfile.write(c.update(content) + c.final) unless content.empty?
|
170
197
|
tmpfile.close
|
171
198
|
File.rename(tmpfile.path, filename)
|
172
199
|
end
|
@@ -207,8 +234,11 @@ class Tpkg
|
|
207
234
|
File.chown(st.uid, st.gid, tmpfile.path)
|
208
235
|
rescue Errno::EPERM
|
209
236
|
raise if Process.euid == 0
|
237
|
+
rescue Errno::EINVAL
|
238
|
+
raise if RUBY_PLATFORM != 'i386-cygwin'
|
210
239
|
end
|
211
|
-
|
240
|
+
content = file.read
|
241
|
+
tmpfile.write(c.update(content) + c.final) unless content.empty?
|
212
242
|
tmpfile.close
|
213
243
|
File.rename(tmpfile.path, filename)
|
214
244
|
end
|
@@ -433,22 +463,12 @@ class Tpkg
|
|
433
463
|
# blocks) and see if tar succeeds in listing a file.
|
434
464
|
1.upto(10) do |numblocks|
|
435
465
|
tarblocks = File.read(package_file, 512*numblocks)
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
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?
|
466
|
+
Open3.popen3("#{find_tar} -tf - #{@@taroptions}") do |stdin, stdout, stderr|
|
467
|
+
stdin.write(tarblocks)
|
468
|
+
stdin.close
|
469
|
+
toplevel = stdout.read
|
470
|
+
end
|
471
|
+
if !toplevel.empty?
|
452
472
|
break
|
453
473
|
else
|
454
474
|
toplevel = nil
|
@@ -711,6 +731,13 @@ class Tpkg
|
|
711
731
|
# Extract 7 from 7.1-RELEASE, for example
|
712
732
|
fbver = Facter['operatingsystemrelease'].value
|
713
733
|
osver = fbver.split('.').first
|
734
|
+
elsif Facter['operatingsystem'] &&
|
735
|
+
Facter['operatingsystem'].value == 'windows'
|
736
|
+
# Extract 6.1 from 6.1.7601, for example
|
737
|
+
# That seems like the right level to split at
|
738
|
+
# based on http://en.wikipedia.org/wiki/Ver_(command)
|
739
|
+
winver = Facter['operatingsystemrelease'].value
|
740
|
+
osver = winver.split('.')[0,2].join('.')
|
714
741
|
elsif Facter['operatingsystemrelease'] &&
|
715
742
|
Facter['operatingsystemrelease'].value &&
|
716
743
|
!Facter['operatingsystemrelease'].value.empty?
|
@@ -772,6 +799,14 @@ class Tpkg
|
|
772
799
|
same_min_ver_req = true
|
773
800
|
end
|
774
801
|
end
|
802
|
+
if req[:version_greater_than]
|
803
|
+
pkgver = Version.new(metadata[:version])
|
804
|
+
reqver = Version.new(req[:version_greater_than])
|
805
|
+
if pkgver <= reqver
|
806
|
+
puts "Package fails version_greater_than (#{pkgver} <= #{reqver})" if @@debug
|
807
|
+
result = false
|
808
|
+
end
|
809
|
+
end
|
775
810
|
if req[:maximum_version]
|
776
811
|
pkgver = Version.new(metadata[:version])
|
777
812
|
reqver = Version.new(req[:maximum_version])
|
@@ -782,6 +817,14 @@ class Tpkg
|
|
782
817
|
same_max_ver_req = true
|
783
818
|
end
|
784
819
|
end
|
820
|
+
if req[:version_less_than]
|
821
|
+
pkgver = Version.new(metadata[:version])
|
822
|
+
reqver = Version.new(req[:version_less_than])
|
823
|
+
if pkgver >= reqver
|
824
|
+
puts "Package fails version_less_than (#{pkgver} >= #{reqver})" if @@debug
|
825
|
+
result = false
|
826
|
+
end
|
827
|
+
end
|
785
828
|
if same_min_ver_req && req[:minimum_package_version]
|
786
829
|
pkgver = Version.new(metadata[:package_version])
|
787
830
|
reqver = Version.new(req[:minimum_package_version])
|
@@ -790,6 +833,14 @@ class Tpkg
|
|
790
833
|
result = false
|
791
834
|
end
|
792
835
|
end
|
836
|
+
if same_min_ver_req && req[:package_version_greater_than]
|
837
|
+
pkgver = Version.new(metadata[:package_version])
|
838
|
+
reqver = Version.new(req[:package_version_greater_than])
|
839
|
+
if pkgver <= reqver
|
840
|
+
puts "Package fails package_version_greater_than (#{pkgver} <= #{reqver})" if @@debug
|
841
|
+
result = false
|
842
|
+
end
|
843
|
+
end
|
793
844
|
if same_max_ver_req && req[:maximum_package_version]
|
794
845
|
pkgver = Version.new(metadata[:package_version])
|
795
846
|
reqver = Version.new(req[:maximum_package_version])
|
@@ -798,6 +849,14 @@ class Tpkg
|
|
798
849
|
result = false
|
799
850
|
end
|
800
851
|
end
|
852
|
+
if same_max_ver_req && req[:package_version_less_than]
|
853
|
+
pkgver = Version.new(metadata[:package_version])
|
854
|
+
reqver = Version.new(req[:package_version_less_than])
|
855
|
+
if pkgver >= reqver
|
856
|
+
puts "Package fails package_version_less_than (#{pkgver} >= #{reqver})" if @@debug
|
857
|
+
result = false
|
858
|
+
end
|
859
|
+
end
|
801
860
|
# The empty? check ensures that a package with no operatingsystem
|
802
861
|
# field matches all clients.
|
803
862
|
if metadata[:operatingsystem] &&
|
@@ -1005,37 +1064,100 @@ class Tpkg
|
|
1005
1064
|
# foo
|
1006
1065
|
# foo=1.0
|
1007
1066
|
# foo=1.0=1
|
1008
|
-
# foo
|
1009
|
-
|
1010
|
-
|
1067
|
+
# foo>1.0
|
1068
|
+
# foo<=1.0=2
|
1069
|
+
# foo<=1.0>=3
|
1070
|
+
# foo=1.0<=6
|
1071
|
+
# foo-1.0-1.tpkg
|
1072
|
+
def self.parse_request(request)
|
1011
1073
|
req = {}
|
1012
|
-
|
1013
|
-
|
1074
|
+
# Note that the ordering in the regex is important. <= and >= have to
|
1075
|
+
# appear before others so that they match rather than two separate matches
|
1076
|
+
# for the '>' and '=' characters. I.e. '1>=2'.split(/(>=|>|=)/) ==
|
1077
|
+
# ['1', '>=', '2'] but '1>=2'.split(/(>|=|>=)/) == ['1', '>', '=', '2']
|
1078
|
+
parts = request.split(/(<=|>=|<|>|=)/)
|
1079
|
+
|
1014
1080
|
# upgrade/remove/query options could take package filenames
|
1015
1081
|
# We're assuming that the filename ends in .tpkg and has a version number that starts
|
1016
1082
|
# with a digit. For example: foo-1.0.tpkg, foo-bar-1.0-1.tpkg
|
1017
1083
|
if request =~ /\.tpkg$/
|
1018
1084
|
req = {:filename => request, :name => request.split(/-\d/)[0]}
|
1019
|
-
elsif parts.length > 2 && parts[-2] =~ /^[\d\.]/ && parts[-1] =~ /^[\d\.]/
|
1020
|
-
package_version = parts.pop
|
1021
|
-
version = parts.pop
|
1022
|
-
req[:name] = parts.join('-')
|
1023
|
-
req[:minimum_version] = version
|
1024
|
-
req[:maximum_version] = version
|
1025
|
-
req[:minimum_package_version] = package_version
|
1026
|
-
req[:maximum_package_version] = package_version
|
1027
|
-
elsif parts.length > 1 && parts[-1] =~ /^[\d\.]/
|
1028
|
-
version = parts.pop
|
1029
|
-
req[:name] = parts.join('-')
|
1030
|
-
req[:minimum_version] = version
|
1031
|
-
req[:maximum_version] = version
|
1032
1085
|
else
|
1033
|
-
|
1086
|
+
if parts.length > 4 && parts[-3] =~ /^[\d\.]/ && parts[-1] =~ /^[\d\.]/
|
1087
|
+
package_version = parts.pop
|
1088
|
+
package_version_sign = parts.pop
|
1089
|
+
version = parts.pop
|
1090
|
+
version_sign = parts.pop
|
1091
|
+
|
1092
|
+
case version_sign
|
1093
|
+
when '<'
|
1094
|
+
# E.g. foo<1.0
|
1095
|
+
req[:version_less_than] = version
|
1096
|
+
when '<='
|
1097
|
+
# E.g. foo<=1.0
|
1098
|
+
req[:maximum_version] = version
|
1099
|
+
when '='
|
1100
|
+
# E.g. foo=1.0
|
1101
|
+
req[:minimum_version] = version
|
1102
|
+
req[:maximum_version] = version
|
1103
|
+
when '>'
|
1104
|
+
# E.g. foo>1.0
|
1105
|
+
req[:version_greater_than] = version
|
1106
|
+
when '>='
|
1107
|
+
# E.g. foo>=1.0
|
1108
|
+
req[:minimum_version] = version
|
1109
|
+
end
|
1110
|
+
|
1111
|
+
case package_version_sign
|
1112
|
+
when '<'
|
1113
|
+
# E.g. foo=1.0<2.0
|
1114
|
+
req[:package_version_less_than] = package_version
|
1115
|
+
when '<='
|
1116
|
+
# E.g. foo=1.0<=2.0
|
1117
|
+
req[:maximum_package_version] = package_version
|
1118
|
+
when '='
|
1119
|
+
# E.g. foo=1.0=2.0
|
1120
|
+
req[:minimum_package_version] = package_version
|
1121
|
+
req[:maximum_package_version] = package_version
|
1122
|
+
when '>'
|
1123
|
+
# E.g. foo=1.0>2.0
|
1124
|
+
req[:package_version_greater_than] = package_version
|
1125
|
+
when '>='
|
1126
|
+
# E.g. foo=1.0>=2.0
|
1127
|
+
req[:minimum_package_version] = package_version
|
1128
|
+
end
|
1129
|
+
elsif parts.length > 1 && parts[-1] =~ /^[\d\.]/
|
1130
|
+
version = parts.pop
|
1131
|
+
version_sign = parts.pop
|
1132
|
+
if version_sign == '=' && version.include?('*')
|
1133
|
+
req[:allowed_versions] = version
|
1134
|
+
else
|
1135
|
+
case version_sign
|
1136
|
+
when '<'
|
1137
|
+
# E.g. foo<1.0
|
1138
|
+
req[:version_less_than] = version
|
1139
|
+
when '<='
|
1140
|
+
# E.g. foo<=1.0
|
1141
|
+
req[:maximum_version] = version
|
1142
|
+
when '='
|
1143
|
+
# E.g. foo=1.0
|
1144
|
+
req[:minimum_version] = version
|
1145
|
+
req[:maximum_version] = version
|
1146
|
+
when '>'
|
1147
|
+
# E.g. foo>1.0
|
1148
|
+
req[:version_greater_than] = version
|
1149
|
+
when '>='
|
1150
|
+
# E.g. foo>=1.0
|
1151
|
+
req[:minimum_version] = version
|
1152
|
+
end
|
1153
|
+
end
|
1154
|
+
end
|
1155
|
+
req[:name] = parts.join('')
|
1034
1156
|
end
|
1035
1157
|
req[:type] = :tpkg
|
1036
1158
|
req
|
1037
1159
|
end
|
1038
|
-
|
1160
|
+
|
1039
1161
|
# deploy_options is used for configuration the deployer. It is a map of option_names => option_values. Possible
|
1040
1162
|
# options are: use-ssh-key, deploy-as, worker-count, abort-on-fail
|
1041
1163
|
#
|
@@ -1355,17 +1477,25 @@ class Tpkg
|
|
1355
1477
|
name = metadata_yml[:name]
|
1356
1478
|
metadata[name] = [] if !metadata[name]
|
1357
1479
|
metadata[name] << metadata_yml
|
1358
|
-
elsif File.directory?(source)
|
1359
|
-
if
|
1360
|
-
|
1361
|
-
|
1480
|
+
elsif source[0,1] == File::SEPARATOR || File.directory?(source)
|
1481
|
+
if File.directory?(source)
|
1482
|
+
if !File.exists?(File.join(source, 'metadata.yml'))
|
1483
|
+
warn "Source directory #{source} has no metadata.yml file. Try running tpkg -x #{source} first."
|
1484
|
+
next
|
1485
|
+
end
|
1486
|
+
metadata_contents = File.read(File.join(source, 'metadata.yml'))
|
1487
|
+
Metadata::get_pkgs_metadata_from_yml_doc(metadata_contents, metadata, source)
|
1488
|
+
else
|
1489
|
+
warn "Source directory #{source} does not exist, skipping."
|
1362
1490
|
end
|
1363
|
-
|
1364
|
-
metadata_contents = File.read(File.join(source, 'metadata.yml'))
|
1365
|
-
Metadata::get_pkgs_metadata_from_yml_doc(metadata_contents, metadata, source)
|
1366
1491
|
else
|
1367
1492
|
uri = http = localdate = remotedate = localdir = localpath = nil
|
1368
1493
|
|
1494
|
+
if !URI.parse(source).absolute?
|
1495
|
+
warn "Source #{source} is not a file, directory, or absolute URI, skipping"
|
1496
|
+
next
|
1497
|
+
end
|
1498
|
+
|
1369
1499
|
uri = URI.join(source, 'metadata.yml')
|
1370
1500
|
http = gethttp(uri)
|
1371
1501
|
|
@@ -1880,6 +2010,10 @@ class Tpkg
|
|
1880
2010
|
end
|
1881
2011
|
pkgs
|
1882
2012
|
end
|
2013
|
+
|
2014
|
+
# Returns an array (possibly empty) of the packages that meet the given
|
2015
|
+
# requirement. If the given requirement is nil or not specified then all
|
2016
|
+
# installed packages are returned.
|
1883
2017
|
def installed_packages_that_meet_requirement(req=nil)
|
1884
2018
|
pkgs = []
|
1885
2019
|
if req && req[:type] == :native
|
@@ -2334,6 +2468,7 @@ class Tpkg
|
|
2334
2468
|
File.chmod(0644, tmpfile.path)
|
2335
2469
|
File.rename(tmpfile.path, localpath)
|
2336
2470
|
rescue
|
2471
|
+
# FIXME: should include original exception message to help user debug
|
2337
2472
|
raise "Unable to download and/or verify the package."
|
2338
2473
|
end
|
2339
2474
|
|
@@ -2620,6 +2755,8 @@ class Tpkg
|
|
2620
2755
|
end
|
2621
2756
|
rescue Errno::EPERM
|
2622
2757
|
raise if Process.euid == 0
|
2758
|
+
rescue Errno::EINVAL
|
2759
|
+
raise if RUBY_PLATFORM != 'i386-cygwin'
|
2623
2760
|
end
|
2624
2761
|
if File.symlink?(f)
|
2625
2762
|
if default_perms
|
@@ -2644,7 +2781,13 @@ class Tpkg
|
|
2644
2781
|
stat = info[:stat]
|
2645
2782
|
file_path = info[:normalized]
|
2646
2783
|
File.chmod(stat.mode, file_path)
|
2647
|
-
|
2784
|
+
begin
|
2785
|
+
File.chown(stat.uid, stat.gid, file_path)
|
2786
|
+
rescue Errno::EPERM
|
2787
|
+
raise if Process.euid == 0
|
2788
|
+
rescue Errno::EINVAL
|
2789
|
+
raise if RUBY_PLATFORM != 'i386-cygwin'
|
2790
|
+
end
|
2648
2791
|
end
|
2649
2792
|
|
2650
2793
|
# Handle any decryption, ownership/permissions, and other issues for specific files
|
@@ -2681,6 +2824,8 @@ class Tpkg
|
|
2681
2824
|
end
|
2682
2825
|
rescue Errno::EPERM
|
2683
2826
|
raise if Process.euid == 0
|
2827
|
+
rescue Errno::EINVAL
|
2828
|
+
raise if RUBY_PLATFORM != 'i386-cygwin'
|
2684
2829
|
end
|
2685
2830
|
end
|
2686
2831
|
if tpkgfile[:posix][:perms]
|
@@ -2710,7 +2855,7 @@ class Tpkg
|
|
2710
2855
|
begin
|
2711
2856
|
Tpkg::decrypt(metadata[:name], working_path, options[:passphrase], *([tpkgfile[:encrypt][:algorithm]].compact))
|
2712
2857
|
break
|
2713
|
-
rescue
|
2858
|
+
rescue OpenSSLCipherError
|
2714
2859
|
@@passphrase = nil
|
2715
2860
|
if i == 3
|
2716
2861
|
raise "Incorrect passphrase."
|
@@ -2937,6 +3082,8 @@ class Tpkg
|
|
2937
3082
|
else
|
2938
3083
|
raise e
|
2939
3084
|
end
|
3085
|
+
rescue Errno::EINVAL
|
3086
|
+
raise if RUBY_PLATFORM != 'i386-cygwin'
|
2940
3087
|
end
|
2941
3088
|
# Insert the contents of the current crontab file
|
2942
3089
|
File.open(destination[:file]) { |file| tmpfile.write(file.read) }
|
@@ -3029,6 +3176,8 @@ class Tpkg
|
|
3029
3176
|
else
|
3030
3177
|
raise
|
3031
3178
|
end
|
3179
|
+
rescue Errno::EINVAL
|
3180
|
+
raise if RUBY_PLATFORM != 'i386-cygwin'
|
3032
3181
|
end
|
3033
3182
|
# Remove section associated with this package
|
3034
3183
|
skip = false
|
@@ -3267,7 +3416,8 @@ class Tpkg
|
|
3267
3416
|
# requirements << { :name => 'bar' }, packages['bar'] = { :source => 'http://server/pkgs/bar-2.3.pkg' }
|
3268
3417
|
# requirements << { :name => 'blat', :minimum_version => '0.5', :maximum_version => '0.5' }, packages['blat'] populated with available packages meeting that requirement
|
3269
3418
|
# Note: the requirements and packages arguments are modified by this method
|
3270
|
-
|
3419
|
+
# FIXME: This method has a terrible API, can we fix it?
|
3420
|
+
def parse_requests(requests, requirements, packages, options = {})
|
3271
3421
|
newreqs = []
|
3272
3422
|
|
3273
3423
|
requests.each do |request|
|
@@ -3313,14 +3463,16 @@ class Tpkg
|
|
3313
3463
|
else # basic package specs ('foo' or 'foo=1.0')
|
3314
3464
|
puts "parse_requests request looks like package spec" if @@debug
|
3315
3465
|
|
3316
|
-
|
3317
|
-
# So we have to tell it ourselves.
|
3318
|
-
req = Tpkg::parse_request(request, @installed_directory)
|
3466
|
+
req = Tpkg::parse_request(request)
|
3319
3467
|
newreqs << req
|
3320
3468
|
|
3321
3469
|
puts "Initializing the list of possible packages for this req" if @@debug
|
3322
3470
|
if !packages[req[:name]]
|
3323
|
-
|
3471
|
+
if !options[:installed_only]
|
3472
|
+
packages[req[:name]] = available_packages_that_meet_requirement(req)
|
3473
|
+
else
|
3474
|
+
packages[req[:name]] = installed_packages_that_meet_requirement(req)
|
3475
|
+
end
|
3324
3476
|
end
|
3325
3477
|
end
|
3326
3478
|
end
|
@@ -3657,7 +3809,7 @@ class Tpkg
|
|
3657
3809
|
puts "Running '/opt/local/bin/port install #{pkgname}' to install native package" if @@debug
|
3658
3810
|
system("/opt/local/bin/port install #{pkgname}")
|
3659
3811
|
else
|
3660
|
-
# Fink support would be nice
|
3812
|
+
# Fink, Homebrew support would be nice
|
3661
3813
|
raise "No supported native package tool available on #{Tpkg::get_os}"
|
3662
3814
|
end
|
3663
3815
|
else
|
@@ -3900,8 +4052,8 @@ class Tpkg
|
|
3900
4052
|
end
|
3901
4053
|
|
3902
4054
|
if prompt_for_conflicting_files(pkgfile, CHECK_UPGRADE)
|
3903
|
-
# If the old and new packages have overlapping externals flag
|
3904
|
-
# to be skipped so that the external isn't removed and then
|
4055
|
+
# If the old and new packages have overlapping externals then flag
|
4056
|
+
# them to be skipped so that the external isn't removed and then
|
3905
4057
|
# immediately re-added
|
3906
4058
|
oldpkgs = installed_packages_that_meet_requirement({:name => pkg[:metadata][:name], :type => :tpkg})
|
3907
4059
|
externals_to_skip = []
|
@@ -3909,7 +4061,7 @@ class Tpkg
|
|
3909
4061
|
if oldpkgs.all? {|oldpkg| oldpkg[:metadata][:externals] && oldpkg[:metadata][:externals].include?(external)}
|
3910
4062
|
externals_to_skip << external
|
3911
4063
|
end
|
3912
|
-
end if pkg[:metadata][:externals]
|
4064
|
+
end if pkg[:metadata][:externals] && !oldpkgs.empty?
|
3913
4065
|
|
3914
4066
|
# Remove the old package if we haven't done so
|
3915
4067
|
unless oldpkgs.nil? or oldpkgs.empty? or removed_pkgs.include?(pkg[:metadata][:name])
|
@@ -3969,7 +4121,7 @@ class Tpkg
|
|
3969
4121
|
requests.uniq! if requests.is_a?(Array)
|
3970
4122
|
packages_to_remove = []
|
3971
4123
|
requests.each do |request|
|
3972
|
-
req = Tpkg::parse_request(request
|
4124
|
+
req = Tpkg::parse_request(request)
|
3973
4125
|
packages_to_remove.concat(installed_packages_that_meet_requirement(req))
|
3974
4126
|
end
|
3975
4127
|
else
|
@@ -4063,7 +4215,7 @@ class Tpkg
|
|
4063
4215
|
end
|
4064
4216
|
|
4065
4217
|
# Stop the services if there's init script
|
4066
|
-
if !options[:upgrade]
|
4218
|
+
if !options[:upgrade] && !options[:skip_remove_stop]
|
4067
4219
|
packages_to_remove.each do |pkg|
|
4068
4220
|
init_scripts_metadata = init_scripts(pkg[:metadata])
|
4069
4221
|
if init_scripts_metadata && !init_scripts_metadata.empty?
|
@@ -4539,6 +4691,8 @@ class Tpkg
|
|
4539
4691
|
original_dir = Dir.pwd
|
4540
4692
|
|
4541
4693
|
workdir = Tpkg::tempdir("tpkg_download")
|
4694
|
+
# FIXME: should use begin/ensure to make sure we chdir back when done
|
4695
|
+
# But I also wonder why we have to chdir at all...
|
4542
4696
|
Dir.chdir(workdir)
|
4543
4697
|
parse_requests(requests, requirements, packages)
|
4544
4698
|
packages = packages.values.flatten
|