/usr/ports/UPDATING Suggestions and Script
thoran
null at thoran.com
Sat Mar 27 01:45:57 UTC 2010
Hi,
I found your email address in /usr/ports/UPDATING. I am emailing you
because you are one of a number of people who make entries into this
file and as such may have some control over either the formatting
conventions of /usr/ports/UPDATING or how well such conventions are
adhered to.
The reason I care is because I have the intention of parsing /usr/
ports/UPDATING with a view to comparing those ports noted in /usr/
ports/UPDATING with a list of the installed ports, rather than having
to look at everything in that very long file. (Note that this is no
longer an intention, since I just wrote something to do this. See
below...)
I understand that the instructions for /usr/ports/UPDATING are for it
to be "read", but given it's length it might be easier to be able to
check this file against installed ports automatically in the first
instance.
Already I have found cat UPDATING | grep AFFECTS: to be handy, but an
automated process (possibly including a cron?) to parse this and do
the matching with installed ports automatically is surely a save.
Does anyone agree?
However, if this is to be done, then may I suggest the following...
1. On the AFFECTS: line only use a list of affected ports and nothing
else, ie.
AFFECTS: category/port
AFFECTS: category/port, category/port
2. When there is a list of ports and that list is quite long, it may
be simpler to make reference to a meta port and exclude some specific
known ports which are in the meta package, but are not affected, ie.
AFFECTS: category/meta-port, [category/port, category/port]
3. On the AFFECTS: line put the version of the port(s) affected, ie.
AFFECTS: category/port-x.y.z
AFFECTS: category/port-x.y.z, category/port-a.b.c
That way checks against the installed ports for specific versions can
be made to ensure relevancy.
4. Alternately, either have the version number in the AFFECTS: line as
per 3. above, or have the date of the particular version of a port
readily accessible, so as relevancy can be checked by date rather than
by version. Version numbers are preferred however.
5. On the AFFECTS: line, please don't do this (no category/port format):
AFFECTS: all ports using libtool as part of the build process
AFFECTS: ports that use Display Postscript libraries and xorg-libraries
5. Also please don't do this (no AUTHOR: line):
20051002:
AFFECTS: users of x11-toolkits/py-wxPython26
6. Somewhat unimportantly, on the AUTHOR: line, please don't do this:
AUTHOR: ahze at FreeBSD.org and the FreeBSD GNOME team
Rather have an email address only, or a mailing list or alias address.
And after all that, so as to not be merely an irritating troll, here's
a first go tonight at a script to do some automation of the check
against installed ports below...
Lastly, I imagine a fair proportion of the older email addresses will
bounce, so I'm putting null at thoran.com as the from address. I haven't
put this up there yet, but try me at github instead.
Thanks,
thoran
#!/usr/bin/env ruby
# check_ports_updating
# 2010.03.26
# 0.3.0
# Description: This checks the /usr/ports/UPDATING file for matching
installed ports and outputs any entries for the last year.
# Copyright: (c) 2010, thoran. All rights reserved.
# Licence: Either Ruby's or the current 2-clause FreeBSD as you wish.
# Notes: This restricts output of matching ports to the last year of
notices, since I expect they are likely to be the most relevant.
require 'date'
class Array
alias_method :last!, :pop
def all_but_last
d = self.dup
d.last!
d
end
end
class Date
def self.last_year
begin
new(today.year, 2, 29)
new(today.year - 1, today.month, today.mday - 1)
rescue
new(today.year - 1, today.month, today.mday)
end
end
def self.parse(s, day_first = false)
require 'parsedate'
if day_first
a = ParseDate.parsedate(s).compact
a = [a[0], a[2], a[1]]
Date.new(*a)
else # assume day_second, and otherwise make best guess
begin
a = ParseDate.parsedate(s).compact
Date.new(*a)
rescue
a = [a[0], a[2], a[1]]
Date.new(*a)
end
end
end
end
class String
def last_char
self[self.length - 1, 1]
end
def last_char!
s = self[self.length - 1, 1]
chop!
s
end
def munch
while self.last_char == "\n"
self.last_char!
end
self
end
def lmunch
self.reverse.munch.reverse
end
end
class InstalledPorts
class << self
def list
pkg_info_bin = `which pkg_info`.chomp
raw_port_list = `#{pkg_info_bin} -ao`
raw_port_list.split("\n").inject([]){|a,line| a << line.match(/for
(.*):$/)[1] if line =~ /^Information/; a}
end
def list_without_version
list.collect{|e| e.split('-').all_but_last.join}
end
end
end
class PortsUpdatingItem
def initialize(item)
@item = item
end
def affects
md = @item.match(/^ AFFECTS: (.*$)/)
md[1] if md
end
def author
md = @item.match(/^ AUTHOR: (.*$)/)
md[1] if md
end
def date
md = @item.match(/^(\d\d\d\d\d\d\d\d):$/)
md[1] if md
end
def description
@item.gsub(/^ AFFECTS: .*$/, '').gsub(/^ AUTHOR: .*$/, '').gsub(/^\d
\d\d\d\d\d\d\d:$/, '')
end
end
class PortsUpdatingFile
class << self
def parse(filename = nil)
filename ||= '/usr/ports/UPDATING'
item = ''
updating_items = []
File.read(filename).each do |line|
if line =~ /^\d\d\d\d\d\d\d\d:$/
updating_items << PortsUpdatingItem.new(item)
item = line
else
item = item + line
end
end
updating_items.shift
updating_items
end
end
end
class PortsUpdating
class << self
def check(filename = nil)
matches = []
InstalledPorts.list_without_version.each do |port|
PortsUpdatingFile.parse(filename).each do |item|
if item.affects =~ /#{port}/
if Date.parse(item.date) > Date.last_year
matches << {:port => port, :date => item.date, :affects =>
item.affects, :author => item.author, :description => item.description}
end
end
end
end
show_results(matches)
end
def show_results(matches)
puts
m = matches.sort{|a,b| a[:port] <=> b[:port]}
m.each do |e|
puts "PORT: #{e[:port]}"
puts "DATE: #{e[:date]}"
puts "AFFECTS: #{e[:affects]}"
puts "AUTHOR: #{e[:author]}"
puts "DESCRIPTION: \n#{e[:description].lmunch}"
puts
end
puts
puts "Overview of Affected Installed Ports:"
puts
m = matches.sort{|a,b| a[:date] <=> b[:date]}
m.each{|e| puts " #{e[:date]}, #{e[:port]}"}
puts
end
end
end
if __FILE__ == $0
PortsUpdating.check(ARGV[0])
end
More information about the freebsd-gnome
mailing list