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