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