Skip to content

Instantly share code, notes, and snippets.

@liangtai
Created October 13, 2010 13:13
Show Gist options
  • Save liangtai/624019 to your computer and use it in GitHub Desktop.
Save liangtai/624019 to your computer and use it in GitHub Desktop.
Shows task order of updates on ports
#! /usr/bin/env ruby -Ku
# -- An example to build the 'targetlist' file and 'preservinglist' file --
# List updates from "portversion -c" result
# sed -f portversion.sed RESULT_FILE > targetlist
require "optparse"
$fulllistname = "/usr/ports/INDEX-#{`uname -r`.split('.')[0]}"
$targetfilename = "targetlist.txt"
$preservingfilename = nil
$currentfilename = nil
if File.exist?("currentlist.txt")
$currentfile = File.new("currentlist.txt", "r")
else
$currentfile = nil
end
if File.exist?("pkg_versions.txt")
$pkg_version_file = File.new("pkg_versions.txt", "r")
else
$pkg_version_file = nil
end
$taskfilename = "#{ENV['HOME']}/tasklist#{Time.now.strftime("%Y%m%d-%H%M%S")}.txt"
#both of 'preservinglist' and 'targetlist' should be list of projects per line.
#This is the extraction of dependency list from /usr/ports/INDEX-*.
opts = OptionParser.new("FreeBSD ports dependency list generator")
opts.on("-o", "--targetlist FILENAME", String) {
|parameter|
$targetfilename = parameter.chomp
}
opts.on("-p", "--preservinglist FILENAME", String) {
|parameter|
$preservingfilename = parameter.chomp
}
opts.on("-c", "--currentlist FILENAME", String) {
|parameter|
$currentfilename = parameter.chomp
}
opts.on("-f", "--fulllist FILENAME", String) {
|parameter|
$fullfilename = parameter.chomp
}
opts.on("-t", "--tasklist FILENAME", String) {
|parameter|
$taskfilename = parameter.chomp
}
opts.parse!(ARGV)
new2oldhash = Hash.new
old2newhash = Hash.new
File.new($targetfilename, "r").readlines.each {|tt|
n = tt.chomp!.split('|')
new2oldhash[n[0]] = n[1]
old2newhash[n[0].split('-')[0..-2].join('-') + '-' + n[1]] = n[0] unless n[1].nil?
}
targetarray = new2oldhash.keys
if $currentfilename.nil?
currentpkgdblist = `pkg info -a`.split(/\n/).collect{|line| line.sub(/\s+[\S\s]+/, '')}
else
if $currentfile.nil?
currentpkgdblist = File.new($currentfilename, "r").readlines.each.collect {|tt|tt.chomp!}
else
currentpkgdblist = $currentfile.readlines.each.collect {|tt|tt.chomp!}
end
end
if $pkg_version_file.nil?
currentlist = currentpkgdblist
else
currentlist = $pkg_version_file.readlines.each.collect {|tt|tt.split(' ')[0]}
end
if $preservingfilename.nil?
preservinglist = currentlist - new2oldhash.keys - old2newhash.keys
else
preservinglist = File.new($preservingfilename, "r").readlines.each.collect {|tt|tt.chomp!}
end
$task_and_depends = Hash.new
printf("c:#{currentlist.count}, p:#{preservinglist.count}, t:#{targetarray.count}\n")
targets_stack = targetarray.dup
until targets_stack.empty?
remaining_targets = targets_stack.dup
File.new($fulllistname, "r").each do |port|
thisport = port.split('|')
break if remaining_targets.empty?
next unless remaining_targets.include?(thisport.at(0))
deplist = Array.new
currentversion = new2oldhash[thisport.at(0)]
if currentversion.nil?
cur_name_ver = thisport.at(0)
else
cur_name_ver = thisport.at(0).split('-')[0..-2].join('-') + '-' + currentversion
end
remaining_targets.delete(thisport.at(0))
if currentpkgdblist.include?(cur_name_ver)
dinfo = %x{pkg info -d #{cur_name_ver} | grep -v :}.split(/\n/)
dinfo.each {|dependency_info|
dependency = dependency_info.sub(/\s+/, '')
newver_dependency = old2newhash[dependency]
dependency = newver_dependency unless newver_dependency.nil?
deplist << dependency if targetarray.include?(dependency)
}
deplist = deplist | (thisport.at(8).split(' ') - thisport.at(7).split(' '))
else
deplist = (thisport.at(7).split(' ') | thisport.at(8).split(' '))
end
#p deplist.join(' ') + "##" + preservinglist.join(' ')
deplist = deplist - preservinglist
targets_stack.concat deplist
$task_and_depends[thisport.at(0)] =
[thisport.at(1).split('/')[-2..-1].join('/') + '/',
deplist.empty?, deplist]
end
targets_stack = targets_stack - targetarray
targetarray.concat targets_stack
unless remaining_targets.empty?
print "cannot found: ", remaining_targets.join(", "),"\non the fulllist. ABORTED\n"
exit 1
end
end
def smooth_deplist(thisport)
deplist = $task_and_depends[thisport].at(2)
if $task_and_depends[thisport].at(1)
deplist
else
deplist_full_a = deplist.each.collect {|port|
smooth_deplist(port)
}
deplist_full = (deplist_full_a.flatten + deplist).sort.uniq
thisportdir = $task_and_depends[thisport].at(0)
$task_and_depends[thisport] = [thisportdir, true, deplist_full]
$task_and_depends.rehash
deplist_full
end
end
$task_and_depends.keys.each { |portname|
smooth_deplist(portname)
}
tasklist = File.new($taskfilename, "a")
$task_and_depends.each { |portname, dir_and_deps|
directory = dir_and_deps.at(0)
deparray = []
dir_and_deps.at(2).each { |pn|
deparray << $task_and_depends[pn].at(0) }
tasklist.print "#{portname}|#{new2oldhash[portname]}| #{directory}|" +
"#{deparray.empty? ? '' : ' ' + deparray.join(' ')}\n"
}
tasklist.close
/^#$/d
/^$/d
/^# [^ ]*$/{
N
N
N
s/# \(.*\)\n# needs updating (port has \(.*\))\n#\npkgs="$pkgs \1-\(.*\)"$/\1-\2|\3/
}
/^if /,/^fi/d
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment