port_upgrade 0.0.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/History.txt +7 -0
- data/Manifest.txt +8 -0
- data/PostInstall.txt +5 -0
- data/README.txt +58 -0
- data/Rakefile +31 -0
- data/bin/port_upgrade +10 -0
- data/lib/port_upgrade/cli.rb +29 -0
- data/lib/port_upgrade.rb +464 -0
- data/test/test_port_upgrade_cli.rb +15 -0
- metadata +119 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/PostInstall.txt
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
Port upgrade will recursively uninstall and reinstall your ports tree to get it fresh and clean and up to date. This gem installs a command "port_upgrade" which requires one option "-output". Portupgrade generates a shell script to do the actual work. To use port_upgrade do the following:
|
2
|
+
|
3
|
+
sudo port selfupdate (or sync)
|
4
|
+
port_upgrade -output upgrade.sh
|
5
|
+
sudo ./upgrade.sh # Watch it fly
|
data/README.txt
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
port_upgrade
|
2
|
+
2008-07-14
|
3
|
+
|
4
|
+
Copyright (C) 2008 Tony Doan (tdoan@tdoan.com)
|
5
|
+
|
6
|
+
= port_upgrade
|
7
|
+
|
8
|
+
* http://portupgrade.rubyforge.org/
|
9
|
+
|
10
|
+
== DESCRIPTION:
|
11
|
+
|
12
|
+
A clean way to keep your MacPorts up to date.
|
13
|
+
|
14
|
+
== FEATURES/PROBLEMS:
|
15
|
+
|
16
|
+
Updates your MacPorts while also removing old dependent versions of libraries and applications.
|
17
|
+
|
18
|
+
== SYNOPSIS:
|
19
|
+
|
20
|
+
1) Update your ports database from macports.org
|
21
|
+
sudo port selfupdate (or sync)
|
22
|
+
2) Run port_upgrade to generate a shell script
|
23
|
+
port_upgrade -output upgrade.sh
|
24
|
+
3) Run the shell script to update your ports tree
|
25
|
+
sudo ./upgrade.sh
|
26
|
+
4) There is no step 4
|
27
|
+
|
28
|
+
== REQUIREMENTS:
|
29
|
+
|
30
|
+
* ruby-sqlite3 gem
|
31
|
+
* libbz2 gem
|
32
|
+
* optiflag gem
|
33
|
+
|
34
|
+
== INSTALL:
|
35
|
+
|
36
|
+
* sudo gem install port_upgrade
|
37
|
+
|
38
|
+
== LICENSE:
|
39
|
+
|
40
|
+
Copyright (c) 2008 Tony Doan <tdoan@tdoan.com>
|
41
|
+
|
42
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
43
|
+
of this software and associated documentation files (the "Software"), to deal
|
44
|
+
in the Software without restriction, including without limitation the rights
|
45
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
46
|
+
copies of the Software, and to permit persons to whom the Software is
|
47
|
+
furnished to do so, subject to the following conditions:
|
48
|
+
|
49
|
+
The above copyright notice and this permission notice shall be included in
|
50
|
+
all copies or substantial portions of the Software.
|
51
|
+
|
52
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
53
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
54
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
55
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
56
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
57
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
58
|
+
THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
|
2
|
+
require File.dirname(__FILE__) + '/lib/port_upgrade.rb'
|
3
|
+
|
4
|
+
# Generate all the Rake tasks
|
5
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
6
|
+
$hoe = Hoe.new('port_upgrade','0.0.1') do |p|
|
7
|
+
p.developer('Tony Doan', 'tdoan@tdoan.com')
|
8
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
9
|
+
p.post_install_message = File.read('PostInstall.txt') # TODO remove if post-install message not required
|
10
|
+
p.rubyforge_name = "portupgrade" # TODO this is default value
|
11
|
+
p.summary = "Summary"
|
12
|
+
p.extra_deps = [
|
13
|
+
['sqlite3-ruby','>= 1.2.0'],
|
14
|
+
['libbz2','>= 0.4'],
|
15
|
+
['optiflag','>= 0.6.0'],
|
16
|
+
]
|
17
|
+
p.extra_dev_deps = [
|
18
|
+
['newgem', ">= #{::Newgem::VERSION}"]
|
19
|
+
]
|
20
|
+
|
21
|
+
p.clean_globs |= %w[**/.DS_Store tmp *.log]
|
22
|
+
path = (p.rubyforge_name == p.name) ? p.rubyforge_name : "\#{p.rubyforge_name}/\#{p.name}"
|
23
|
+
p.remote_rdoc_dir = File.join(path.gsub(/^#{p.rubyforge_name}\/?/,''), 'rdoc')
|
24
|
+
p.rsync_args = '-av --delete --ignore-errors'
|
25
|
+
end
|
26
|
+
|
27
|
+
require 'newgem/tasks' # load /tasks/*.rake
|
28
|
+
Dir['tasks/**/*.rake'].each { |t| load t }
|
29
|
+
|
30
|
+
# TODO - want other tests/tasks run by default? Add them to the list
|
31
|
+
# task :default => [:spec, :features]
|
data/bin/port_upgrade
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'optiflag'
|
2
|
+
|
3
|
+
module PortUpgrade extend OptiFlagSet
|
4
|
+
|
5
|
+
flag "output" do
|
6
|
+
description "Where to output the shell script that performs the upgrade."
|
7
|
+
end
|
8
|
+
|
9
|
+
optional_flag "outdated" do
|
10
|
+
description "Specify the list of outdated ports to upgrade."
|
11
|
+
end
|
12
|
+
|
13
|
+
optional_flag "receipts" do
|
14
|
+
end
|
15
|
+
|
16
|
+
and_process!
|
17
|
+
|
18
|
+
class CLI
|
19
|
+
def self.execute(stdout, arguments=[])
|
20
|
+
pdb = Ports::PortsDB.new(PortUpgrade.flags.receipts)
|
21
|
+
pdb.set_outdated(PortUpgrade.flags.outdated.split(" ")) if PortUpgrade.flags.outdated
|
22
|
+
$stderr.puts("Outdated: #{pdb.outdated.join(' ')}")
|
23
|
+
to_remove = pdb.to_remove
|
24
|
+
$stderr.puts "#{to_remove.size} ports to remove: #{to_remove.join(',')}"
|
25
|
+
pdb.upgrade(PortUpgrade.flags.output)
|
26
|
+
pdb.close
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/port_upgrade.rb
ADDED
@@ -0,0 +1,464 @@
|
|
1
|
+
#
|
2
|
+
# ports_helpers.rb: Utility classes for dealing with ports data.
|
3
|
+
#
|
4
|
+
# ====================================================================
|
5
|
+
# Copyright (c) 2008 Tony Doan <tdoan@tdoan.com>. All rights reserved.
|
6
|
+
#
|
7
|
+
# This software is licensed as described in the file COPYING, which
|
8
|
+
# you should have received as part of this distribution. The terms
|
9
|
+
# are also available at http://github.com/tdoan/port_upgrade/tree/master/COPYING.
|
10
|
+
# If newer versions of this license are posted there, you may use a
|
11
|
+
# newer version instead, at your option.
|
12
|
+
# ====================================================================
|
13
|
+
#
|
14
|
+
|
15
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
16
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
17
|
+
|
18
|
+
require 'bz2'
|
19
|
+
require 'find'
|
20
|
+
require 'sqlite3'
|
21
|
+
|
22
|
+
class String
|
23
|
+
def dot_clean
|
24
|
+
return self.gsub(/[ +\/\.-]/,"_")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module Ports
|
29
|
+
VERSION = '0.0.1'
|
30
|
+
RECEIPT_PATH = '/opt/local/var/macports/receipts'
|
31
|
+
MACPORTS_DB='/opt/local/var/macports/sources/rsync.macports.org/release/ports'
|
32
|
+
CONFIG_FILE = 'port_upgrade_conf.yml'
|
33
|
+
Struct.new('Edge',:port,:dep,:level)
|
34
|
+
class Struct::Edge
|
35
|
+
def <=>(other)
|
36
|
+
portdif = self.port <=> other.port
|
37
|
+
depdif = self.dep <=> other.dep
|
38
|
+
if self.port == other.port and self.dep == other.dep and self.level == other.level
|
39
|
+
return 0
|
40
|
+
elsif portdif != 0
|
41
|
+
return portdif
|
42
|
+
elsif depdif != 0
|
43
|
+
return depdif
|
44
|
+
else
|
45
|
+
return self.level <=> other.level
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Utilities
|
51
|
+
|
52
|
+
def breadth_first
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.cmp_vers(versa,versb)
|
57
|
+
sa = versa.tr("._-","")
|
58
|
+
sb = versb.tr("._-","")
|
59
|
+
a=sa.to_i
|
60
|
+
b=sb.to_i
|
61
|
+
#a==0 ? asize=0 : asize = Math.log10(a).to_i
|
62
|
+
asize=sa.length
|
63
|
+
#b==0 ? bsize=0 : bsize = Math.log10(b).to_i
|
64
|
+
bsize=sb.length
|
65
|
+
diff = asize-bsize
|
66
|
+
if diff < 0
|
67
|
+
a = a * (10 ** diff.abs)
|
68
|
+
elsif diff > 0
|
69
|
+
b = b * (10 ** diff.abs)
|
70
|
+
end
|
71
|
+
a <=> b
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
class Port
|
76
|
+
end
|
77
|
+
|
78
|
+
class PortTree
|
79
|
+
def initialize(pdb,path=nil)
|
80
|
+
@path=path
|
81
|
+
@edges_seen = []
|
82
|
+
@pdb = pdb
|
83
|
+
traverse_receipts
|
84
|
+
end
|
85
|
+
|
86
|
+
def size
|
87
|
+
s=nil
|
88
|
+
@pdb.db.query("select count(*) from ports") do |results|
|
89
|
+
s = results.first[0].to_i
|
90
|
+
end
|
91
|
+
return s
|
92
|
+
end
|
93
|
+
|
94
|
+
def receipt_path
|
95
|
+
@path || RECEIPT_PATH
|
96
|
+
end
|
97
|
+
def dump_tree
|
98
|
+
ports = nil
|
99
|
+
@pdb.db.query("select port,variant from ports order by port") do |results|
|
100
|
+
ports = results.to_a
|
101
|
+
end
|
102
|
+
ports
|
103
|
+
end
|
104
|
+
|
105
|
+
def installed
|
106
|
+
ports = nil
|
107
|
+
@pdb.db.query("select port from ports order by port") do |results|
|
108
|
+
ports = results.to_a.flatten
|
109
|
+
end
|
110
|
+
ports
|
111
|
+
end
|
112
|
+
|
113
|
+
def dump_seq(outdated)
|
114
|
+
#setup_remports(outdated) unless outdated.nil?
|
115
|
+
end
|
116
|
+
|
117
|
+
def setup_remports(outdated)
|
118
|
+
begin
|
119
|
+
@pdb.db.execute("drop table remports")
|
120
|
+
rescue SQLite3::SQLException
|
121
|
+
end
|
122
|
+
@pdb.db.execute("create table remports(port text, dep text)")
|
123
|
+
@pdb.db.execute("create unique index remportsdep on remports(port,dep)")
|
124
|
+
outdated.each do |a|
|
125
|
+
parents = get_parent_pairs(a)
|
126
|
+
begin
|
127
|
+
parents.each do |p|
|
128
|
+
@pdb.db.execute("insert or ignore into remports values(\"#{p.port}\",\"#{p.dep}\")")
|
129
|
+
end
|
130
|
+
rescue SQLite3::SQLException => exp
|
131
|
+
$stderr.puts "Dup insert into remports: #{exp}}" if $DEBUG
|
132
|
+
end
|
133
|
+
@pdb.db.execute("insert into remports values(\"#{a}\",\"\")")
|
134
|
+
end
|
135
|
+
@pdb.db.execute('delete from remports where port="gimp-app" and dep="gimp"')
|
136
|
+
#File.open("remtree.dot",'w') do |f|
|
137
|
+
# pt = table_to_tree('remports','remports','port','port','dep')
|
138
|
+
# f.write(pt.to_dot)
|
139
|
+
#end
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
def traverse_receipts
|
144
|
+
begin
|
145
|
+
@pdb.db.execute("drop table ports")
|
146
|
+
@pdb.db.execute("drop table deps")
|
147
|
+
rescue SQLite3::SQLException
|
148
|
+
end
|
149
|
+
@pdb.db.execute("create table ports(port text,version text, variant text)")
|
150
|
+
@pdb.db.execute("create table deps(port text, dep text)")
|
151
|
+
@pdb.db.execute("create unique index uniqdep on deps(port,dep)")
|
152
|
+
|
153
|
+
Find.find(receipt_path) do |filename|
|
154
|
+
next unless filename =~ /.bz2$/
|
155
|
+
next unless File.stat(filename).file?
|
156
|
+
pieces = filename.split("/")
|
157
|
+
next unless pieces.size == 9
|
158
|
+
original_portname = pieces[-3]
|
159
|
+
md = /([^+]+)((\+\w+)*)/.match(pieces[-2]) #seperate version from variants
|
160
|
+
version = md[1]
|
161
|
+
variant = md[2]
|
162
|
+
portname = filename.split("/")[-3].gsub(/(-|\.|\/)/,'_') #very unix centric
|
163
|
+
@pdb.db.execute("insert into ports values(?,?,?)",original_portname,version,variant)
|
164
|
+
#portnames << "#{portname}"
|
165
|
+
reader = BZ2::Reader.new(File.open(filename))
|
166
|
+
receipt_lines = reader.readlines
|
167
|
+
reader.close
|
168
|
+
receipt_lines.each do |l|
|
169
|
+
if l =~ /depends_lib (\{([^}]*)\}|([^ ]*))/
|
170
|
+
deps = $2||$3
|
171
|
+
deps.split(" ").each do |d|
|
172
|
+
original_depname = d.split(":").last
|
173
|
+
depname = d.split(":").last.gsub(/(-|\.|\/)/,'_')
|
174
|
+
begin
|
175
|
+
@pdb.db.execute("insert into deps values(?,?)",original_portname,original_depname)
|
176
|
+
rescue SQLite3::SQLException
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
if l =~ /depends_run (\{([^}]*)\}|([^ ]*))/
|
181
|
+
deps = $2||$3
|
182
|
+
deps.split(" ").each do |d|
|
183
|
+
original_depname = d.split(":")[1]
|
184
|
+
depname = d.split(":")[1].gsub(/(-|\.|\/)/,'_')
|
185
|
+
begin
|
186
|
+
@pdb.db.execute("insert into deps values(?,?)",original_portname,original_depname)
|
187
|
+
rescue SQLite3::SQLException
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def get_parent_pairs(portname,i=1)
|
196
|
+
$stderr.puts "get_parent_pairs: #{portname}, #{i}" if $DEBUG
|
197
|
+
rs = @pdb.db.query("select * from deps where dep = ?", portname)
|
198
|
+
res = rs.to_a
|
199
|
+
if res.size == 0
|
200
|
+
parents = []
|
201
|
+
else
|
202
|
+
parents = res.collect{|r| Struct::Edge.new(r[0],portname,i)}
|
203
|
+
res.each do |r|
|
204
|
+
if (@edges_seen.find{|o| o === [r[0],portname]}).nil?
|
205
|
+
@edges_seen << [r[0],portname]
|
206
|
+
gp = get_parent_pairs(r[0],i+1)
|
207
|
+
parents += gp unless gp.size == 0
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
rs.close
|
212
|
+
parents.uniq
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
class PortsDB
|
218
|
+
def initialize(path=nil,outdated=nil)
|
219
|
+
@db = SQLite3::Database.new(':memory:')#('port_tree.db')
|
220
|
+
@pt = PortTree.new(self,path)
|
221
|
+
@installed = @pt.installed
|
222
|
+
@outdated = outdated
|
223
|
+
@to_remove = nil
|
224
|
+
config_file = locate_config_file
|
225
|
+
begin
|
226
|
+
@config = YAML::load(File.open(config_file))
|
227
|
+
@config = {} if @config == false
|
228
|
+
rescue Errno::ENOENT
|
229
|
+
$stderr.puts("No configuration loaded.")
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def locate_config_file
|
234
|
+
to_search = []
|
235
|
+
local_dir = File.dirname($0).sub(/bin$/,"")
|
236
|
+
local_dir = local_dir == "" ? "." : local_dir
|
237
|
+
to_search << File.join(local_dir,"etc",Ports::CONFIG_FILE)
|
238
|
+
to_search << File.join(ENV['HOME'],"."+Ports::CONFIG_FILE)
|
239
|
+
to_search.each do |path|
|
240
|
+
$stderr.puts "PATH: #{path}"
|
241
|
+
return path if File.readable?(path)
|
242
|
+
end
|
243
|
+
return nil
|
244
|
+
end
|
245
|
+
|
246
|
+
def installed
|
247
|
+
@installed
|
248
|
+
end
|
249
|
+
|
250
|
+
def db
|
251
|
+
@db
|
252
|
+
end
|
253
|
+
|
254
|
+
def close
|
255
|
+
@db.close
|
256
|
+
end
|
257
|
+
|
258
|
+
def port_tree
|
259
|
+
@pt
|
260
|
+
end
|
261
|
+
|
262
|
+
def dump_tree
|
263
|
+
@installed.dump_tree
|
264
|
+
end
|
265
|
+
|
266
|
+
def to_remove
|
267
|
+
return @to_remove unless @to_remove.nil?
|
268
|
+
@pt.setup_remports(outdated)
|
269
|
+
@db.query("select distinct port from remports order by port") do |rs|
|
270
|
+
@to_remove = rs.to_a
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def get_leaves
|
275
|
+
$stderr.print "get_leaves " if $DEBUG
|
276
|
+
rs = @db.query('select port from remports')
|
277
|
+
ports = rs.to_a.flatten.sort.uniq
|
278
|
+
rs.close
|
279
|
+
$stderr.print "ports: #{ports.size} " if $DEBUG
|
280
|
+
rs = @db.query('select dep from remports')
|
281
|
+
deps = rs.to_a.flatten.sort.uniq
|
282
|
+
rs.close
|
283
|
+
$stderr.print "deps: #{deps.size} " if $DEBUG
|
284
|
+
diff = (ports - deps).sort
|
285
|
+
$stderr.puts "diff: #{diff.size}" if $DEBUG
|
286
|
+
diff.each{|p| @db.execute("delete from remports where port = ?",p)}
|
287
|
+
diff
|
288
|
+
end
|
289
|
+
|
290
|
+
def set_outdated(out)
|
291
|
+
@outdated = out
|
292
|
+
end
|
293
|
+
|
294
|
+
def outdated(reload = false)
|
295
|
+
return @outdated unless @outdated.nil? or reload == true
|
296
|
+
@outdated = []
|
297
|
+
@installed.each do |port|
|
298
|
+
d = File.join(@pt.receipt_path,port)
|
299
|
+
Dir.entries(d)[2..-1].each do |version|
|
300
|
+
d2 = File.join(d,version,'receipt.bz2')
|
301
|
+
reader = BZ2::Reader.new(File.new(d2))
|
302
|
+
lines = reader.readlines
|
303
|
+
cats = []
|
304
|
+
lines.collect do |line|
|
305
|
+
md = /categories (\{([^}]*)\}|([^ ]*))/.match(line)
|
306
|
+
unless md.nil?
|
307
|
+
cats << (md[2].nil? ? md[1] : md[2].split.first)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
portfile_path = File.join(MACPORTS_DB,cats.flatten,port,'Portfile')
|
311
|
+
e = File.exist?(portfile_path)
|
312
|
+
curver = Portfile.new(portfile_path).version
|
313
|
+
#puts "%-32s%s < %s" %[port,version.split('+').first,curver] if Ports::Utilities.cmp_vers(version.split('+').first,curver) < 0
|
314
|
+
@outdated << port if Ports::Utilities.cmp_vers(version.split('+').first,curver) < 0
|
315
|
+
end
|
316
|
+
end
|
317
|
+
@outdated.uniq
|
318
|
+
end
|
319
|
+
|
320
|
+
def upgrade(path='port_upgrade.sh')
|
321
|
+
@pt.setup_remports(outdated) if @to_remove.nil?
|
322
|
+
remports = []
|
323
|
+
remvariants = Hash.new {|h,k| h[k] = Array.new}
|
324
|
+
stmt = @db.prepare("select count(*) from remports")
|
325
|
+
dotsh = File.new(path,'w')
|
326
|
+
dotsh.chmod(0700)
|
327
|
+
$stderr.puts "port_upgrade.sh open for write" if $DEBUG
|
328
|
+
dotsh.puts("#!/bin/sh")
|
329
|
+
while stmt.execute.to_a.first[0].to_i > 0
|
330
|
+
temp = get_leaves
|
331
|
+
break if temp.size == 0
|
332
|
+
temp.each do |o|
|
333
|
+
@db.query("select port,version,variant from ports where port = ?",o) do |rs|
|
334
|
+
installed = rs.to_a
|
335
|
+
installed.each do |port|
|
336
|
+
bu = get_before_uninstall(port[0])
|
337
|
+
dotsh.puts(bu) unless bu.nil?
|
338
|
+
dotsh.puts("port uninstall #{port[0]} @#{port[1]}#{port[2]} || exit -1")
|
339
|
+
au = get_after_uninstall(port[0])
|
340
|
+
dotsh.puts(au) unless au.nil?
|
341
|
+
remports.push(port[0])
|
342
|
+
remvariants[port[0]].push(port[2])
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
remports.uniq!
|
348
|
+
while remports.size > 0
|
349
|
+
port = remports.pop
|
350
|
+
if remvariants[port].uniq.size > 1
|
351
|
+
$stderr.puts "Found multiple variants for #{port}."
|
352
|
+
variantindex = choose_variant(port,remvariants[port])
|
353
|
+
else
|
354
|
+
variantindex = 0
|
355
|
+
end
|
356
|
+
bi = get_before_install(port)
|
357
|
+
dotsh.puts(bi) unless bi.nil?
|
358
|
+
dotsh.puts("port install #{port} #{remvariants[port][variantindex]} || exit -1")
|
359
|
+
ai = get_after_install(port)
|
360
|
+
dotsh.puts(ai) unless ai.nil?
|
361
|
+
end
|
362
|
+
stmt.close
|
363
|
+
true
|
364
|
+
end
|
365
|
+
|
366
|
+
def get_before_uninstall(portname)
|
367
|
+
get_port_action(portname,:before_uninstall)
|
368
|
+
end
|
369
|
+
|
370
|
+
def get_after_uninstall(portname)
|
371
|
+
get_port_action(portname,:after_uninstall)
|
372
|
+
end
|
373
|
+
|
374
|
+
def get_before_install(portname)
|
375
|
+
get_port_action(portname,:before_install)
|
376
|
+
end
|
377
|
+
|
378
|
+
def get_after_install(portname)
|
379
|
+
get_port_action(portname,:after_install)
|
380
|
+
end
|
381
|
+
|
382
|
+
private
|
383
|
+
|
384
|
+
def get_port_action(portname,type)
|
385
|
+
unless @config.nil?
|
386
|
+
if @config.has_key?(:actions)
|
387
|
+
if @config[:actions].has_key?(portname)
|
388
|
+
if @config[:actions][portname].has_key?(type)
|
389
|
+
@config[:actions][portname][type]
|
390
|
+
else
|
391
|
+
nil
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
def choose_variant(portname,variants)
|
399
|
+
answer=false
|
400
|
+
while(!answer)
|
401
|
+
$stderr.puts "Please choose from list:"
|
402
|
+
variants.each_with_index{|v,i| $stderr.puts "#{i}: #{v=="" ? "(none)" : v}"}
|
403
|
+
$stderr.print "> "
|
404
|
+
reply = $stdin.gets
|
405
|
+
clean = (reply.strip =~ /-?[0-9]+/)
|
406
|
+
if (clean == 0)
|
407
|
+
answer = true
|
408
|
+
else
|
409
|
+
$stderr.puts "ERROR, try again."
|
410
|
+
end
|
411
|
+
end
|
412
|
+
return reply.to_i
|
413
|
+
end
|
414
|
+
|
415
|
+
end
|
416
|
+
|
417
|
+
class Portfile
|
418
|
+
def initialize(path)
|
419
|
+
@path = path
|
420
|
+
end
|
421
|
+
|
422
|
+
def version
|
423
|
+
@version ||= find_vers
|
424
|
+
end
|
425
|
+
|
426
|
+
private
|
427
|
+
def find_vers
|
428
|
+
v=nil
|
429
|
+
rev=nil
|
430
|
+
vars = {}
|
431
|
+
portfile = File.new(@path)
|
432
|
+
portfile.each do |line|
|
433
|
+
case line
|
434
|
+
when /^set\s+(\S+)\s+(\S+)/
|
435
|
+
vars[$1] = $2
|
436
|
+
#$stderr.puts "Var: #{$1} Val: #{$2}"
|
437
|
+
when /^version\s+([^\s]+)/
|
438
|
+
v = $1
|
439
|
+
while(v =~ /(\$\{([^}]+)\})/) do
|
440
|
+
if vars.has_key?($2)
|
441
|
+
v[$1] = vars[$2]
|
442
|
+
else
|
443
|
+
break
|
444
|
+
end
|
445
|
+
#$stderr.puts "\n\nREPLACE(#{@path}): #{$1} #{vars[$2]} #{v}\n"
|
446
|
+
end
|
447
|
+
#break
|
448
|
+
when /^revision\s+([^\s]+)/
|
449
|
+
rev = $1
|
450
|
+
#$stderr.puts "revision found #{rev}"
|
451
|
+
when /\w+\.setup\s+(\S+)? ([\S]+)/
|
452
|
+
v = $2 if v.nil?
|
453
|
+
break
|
454
|
+
when /(\S+)\s+([^$]+)$/
|
455
|
+
vars[$1] = $2
|
456
|
+
end
|
457
|
+
end
|
458
|
+
rev = "0" if rev.nil?
|
459
|
+
v = v +"_"+rev
|
460
|
+
return v
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "test_helper.rb")
|
2
|
+
require 'port_upgrade/cli'
|
3
|
+
|
4
|
+
class TestPortUpgradeCli < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@stdout_io = StringIO.new
|
7
|
+
PortUpgrade::CLI.execute(@stdout_io, [])
|
8
|
+
@stdout_io.rewind
|
9
|
+
@stdout = @stdout_io.read
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_not_print_default_output
|
13
|
+
assert_no_match(/To update this executable/, @stdout)
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: port_upgrade
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tony Doan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-21 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: sqlite3-ruby
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.2.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: libbz2
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0.4"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: optiflag
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.6.0
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: newgem
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.2.1
|
54
|
+
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: hoe
|
57
|
+
type: :development
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 1.8.0
|
64
|
+
version:
|
65
|
+
description: A clean way to keep your MacPorts up to date.
|
66
|
+
email:
|
67
|
+
- tdoan@tdoan.com
|
68
|
+
executables:
|
69
|
+
- port_upgrade
|
70
|
+
extensions: []
|
71
|
+
|
72
|
+
extra_rdoc_files:
|
73
|
+
- History.txt
|
74
|
+
- Manifest.txt
|
75
|
+
- PostInstall.txt
|
76
|
+
- README.txt
|
77
|
+
files:
|
78
|
+
- History.txt
|
79
|
+
- Manifest.txt
|
80
|
+
- PostInstall.txt
|
81
|
+
- README.txt
|
82
|
+
- Rakefile
|
83
|
+
- lib/port_upgrade.rb
|
84
|
+
- lib/port_upgrade/cli.rb
|
85
|
+
- bin/port_upgrade
|
86
|
+
has_rdoc: true
|
87
|
+
homepage: http://portupgrade.rubyforge.org/
|
88
|
+
post_install_message: |-
|
89
|
+
Port upgrade will recursively uninstall and reinstall your ports tree to get it fresh and clean and up to date. This gem installs a command "port_upgrade" which requires one option "-output". Portupgrade generates a shell script to do the actual work. To use port_upgrade do the following:
|
90
|
+
|
91
|
+
sudo port selfupdate (or sync)
|
92
|
+
port_upgrade -output upgrade.sh
|
93
|
+
sudo ./upgrade.sh # Watch it fly
|
94
|
+
rdoc_options:
|
95
|
+
- --main
|
96
|
+
- README.txt
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: "0"
|
104
|
+
version:
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: "0"
|
110
|
+
version:
|
111
|
+
requirements: []
|
112
|
+
|
113
|
+
rubyforge_project: portupgrade
|
114
|
+
rubygems_version: 1.3.1
|
115
|
+
signing_key:
|
116
|
+
specification_version: 2
|
117
|
+
summary: Summary
|
118
|
+
test_files:
|
119
|
+
- test/test_port_upgrade_cli.rb
|