I saw someone who posted that they used the output of out-of-date to
automatically do updates. I was looking at doing that, and found that
it would be easier to do correctly if I knew what depended on what.
What I did was turn out-of-date into a "modulino"[1], then I wrote a
script that uses most of out-of-date, but instead of printing the
out-of-date ports, it runs make update.
This shouldn't change any of the current functionality of out-of-date,
but it does allow me to extend it.
I am sure there is probably a better way to write the "sort_by_depends"
sub, but I haven't spent enough time on the modules that are available
to know what it would be. I did look at some of them, like
OpenBSD::Dependencies, but I didn't see how to get that to work with the
list of ports to give me a sorted SUBDIR list.
[1] http://www.perlmonks.org/?node_id=396759
l8rZ,
--
andrew - ICQ# 253198 - Jabber: [EMAIL PROTECTED]
BOFH excuse of the day: nesting roaches shorted out the ether cable
Index: out-of-date
===================================================================
RCS file: /cvs/ports/infrastructure/build/out-of-date,v
retrieving revision 1.16
diff -u -p -r1.16 out-of-date
--- out-of-date 1 Jun 2007 15:01:50 -0000 1.16
+++ out-of-date 2 May 2008 22:04:40 -0000
@@ -1,4 +1,5 @@
#!/usr/bin/perl
+package OpenBSD::OutOfDate;
# $OpenBSD: out-of-date,v 1.16 2007/06/01 15:01:50 espie Exp $
#
@@ -27,15 +28,11 @@ use OpenBSD::ProgressMeter;
use File::Temp;
our $opt_q;
-set_usage('out-of-date [-q]');
-try {
- getopts('q');
-} catchall {
- Usage($_);
-};
+
sub collect_installed
{
+ my $class = shift;
my $pkg = {};
for my $name (installed_packages(1)) {
my ($stem, $version) = OpenBSD::PackageName::splitname($name);
@@ -60,6 +57,7 @@ sub collect_installed
sub fh_open
{
+ my $class = shift;
open(my $fh, shift);
my $old = select $fh;
$| = 1;
@@ -69,6 +67,7 @@ sub fh_open
sub fh_close
{
+ my $class = shift;
my ($fh, $old) = @_;
close($fh);
select $old;
@@ -76,6 +75,7 @@ sub fh_close
sub collect_port_versions
{
+ my $class = shift;
my ($pkg, $portsdir, $notfound) = @_;
my @subdirs = ();
@@ -99,7 +99,7 @@ sub collect_port_versions
my $progress = OpenBSD::ProgressMeter->new;
$progress->set_header("Collecting port versions");
- my ($fh, $old) = fh_open($cmd);
+ my ($fh, $old) = $class->fh_open($cmd);
my $subdir = "";
while (<$fh>) {
chomp;
@@ -122,7 +122,7 @@ sub collect_port_versions
$port->{$subdir}->{stem} = $stem;
$port->{$subdir}->{version} = $version;
}
- fh_close($fh, $old);
+ $class->fh_close($fh, $old);
$progress->next;
return $port, $error;
@@ -130,10 +130,10 @@ sub collect_port_versions
sub collect_port_signatures
{
+ my $class = shift;
my $pkg = shift;
my $port = shift;
my $portsdir = shift;
- my $output = shift;
my @subdirs = ();
for my $dir (keys %$port) {
@@ -156,7 +156,7 @@ sub collect_port_signatures
my $total = scalar @subdirs;
my $progress = OpenBSD::ProgressMeter->new;
$progress->set_header("Collecting port signatures");
- my ($fh, $old) = fh_open($cmd);
+ my ($fh, $old) = $class->fh_open($cmd);
my $subdir = "";
while (<$fh>) {
chomp;
@@ -169,12 +169,13 @@ sub collect_port_signatures
next unless $_ or $subdir;
$port->{$subdir}->{signature} = $_;
}
- fh_close($fh, $old);
+ $class->fh_close($fh, $old);
$progress->next;
}
sub split_sig
{
+ my $class = shift;
my $sig = shift;
my $ret = {};
@@ -187,10 +188,11 @@ sub split_sig
sub diff_sig
{
+ my $class = shift;
my ($dir, $pkg, $port) = @_;
- my $old = split_sig($pkg->{$dir}->{signature});
- my $new = split_sig($port->{$dir}->{signature});
+ my $old = $class->split_sig($pkg->{$dir}->{signature});
+ my $new = $class->split_sig($port->{$dir}->{signature});
for my $key (keys %$old) {
if (defined $new->{$key}) {
@@ -204,56 +206,75 @@ sub diff_sig
sub find_outdated
{
- my ($pkg, $port, $output) = @_;
+ my $class = shift;
+ my ($pkg, $port, $outdated) = @_;
for my $dir (keys %$pkg) {
next unless $port->{$dir};
if ($pkg->{$dir}->{name} ne $port->{$dir}->{name}) {
- push(@$output, sprintf("%-30s # %s -> %s\n", $dir,
- $pkg->{$dir}->{version}, $port->{$dir}->{version}));
+ $outdated->{$dir} = sprintf("%s -> %s",
+ $pkg->{$dir}->{version}, $port->{$dir}->{version});
next;
}
next if $opt_q;
if ($pkg->{$dir}->{signature} ne $port->{$dir}->{signature}) {
- push(@$output, sprintf("%-30s # %s -> %s\n", $dir,
- diff_sig($dir, $pkg, $port)));
+ $outdated->{$dir} = $class->diff_sig($dir, $pkg, $port);
+ next;
}
}
}
my $portsdir = $ENV{PORTSDIR} || "/usr/ports";
+__PACKAGE__->run() unless caller();
-print STDERR "Collecting installed packages\n";
-my $pkg = collect_installed();
+sub run {
+ my $class = shift;
-my @output = ();
-my @notfound = ();
-my ($port, $errors) = collect_port_versions($pkg, $portsdir, [EMAIL
PROTECTED]);
-
-collect_port_signatures($pkg, $port, $portsdir, [EMAIL PROTECTED]) unless
$opt_q;
-find_outdated($pkg, $port, [EMAIL PROTECTED]);
-
-print STDERR "Outdated ports:\n\n";
-print $_ for sort @output;
-
-if ($opt_q) {
- print STDERR "\nWARNING: You've used the -q option. With this,\n"
- . "out-of-date only looks for changed package names\nbut not "
- . "for changed package signatures. If you\nwant to see ALL "
- . "of your outdated packages,\ndon't use -q.\n";
-}
+ set_usage('out-of-date [-q]');
+ try {
+ getopts('q');
+ }
+ catchall {
+ Usage($_);
+ };
+
+ print STDERR "Collecting installed packages\n";
+ my $pkg = $class->collect_installed();
+
+ my %outdated = ();
+ my @notfound = ();
+ my ( $port, $errors ) =
+ $class->collect_port_versions( $pkg, $portsdir, [EMAIL PROTECTED] );
+
+ $class->collect_port_signatures( $pkg, $port, $portsdir ) unless $opt_q;
+ $class->find_outdated( $pkg, $port, \%outdated );
+
+ print STDERR "Outdated ports:\n\n";
+ foreach my $dir (sort keys %outdated) {
+ printf("%-30s # %s\n", $dir, $outdated{$dir});
+ }
-if (@notfound > 0) {
- print STDERR "\nPorts that can't be found in the official "
- . "ports tree:\n";
- for (sort @notfound) {
- print STDERR " $_\n";
+ if ($opt_q) {
+ print STDERR "\nWARNING: You've used the -q option. With
this,\n"
+ . "out-of-date only looks for changed package names\nbut not "
+ . "for changed package signatures. If you\nwant to see ALL "
+ . "of your outdated packages,\ndon't use -q.\n";
}
-}
-if ((keys %$errors) > 0) {
- print STDERR "\nErrors:\n";
- for (sort keys %$errors) {
- print STDERR " $_\n";
- print STDERR " $_\n" for @{$errors->{$_}};
+
+ if ( @notfound > 0 ) {
+ print STDERR "\nPorts that can't be found in the official "
+ . "ports tree:\n";
+ for ( sort @notfound ) {
+ print STDERR " $_\n";
+ }
+ }
+ if ( ( keys %$errors ) > 0 ) {
+ print STDERR "\nErrors:\n";
+ for ( sort keys %$errors ) {
+ print STDERR " $_\n";
+ print STDERR " $_\n" for @{ $errors->{$_} };
+ }
}
}
+
+1;
#!/usr/bin/perl
package OpenBSD::OutOfDate::Update;
# $OpenBSD$
#
# Copyright (c) 2008 Andrew Fresh <[EMAIL PROTECTED]>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
my $portsdir = $ENV{PORTSDIR} || "/usr/ports";
do $portsdir . '/infrastructure/build/out-of-date';
use base qw{ OpenBSD::OutOfDate };
__PACKAGE__->run() unless caller();
sub run {
my $class = shift;
print STDERR "Collecting installed packages\n";
my $pkg = $class->collect_installed();
my @outdated = ();
my @notfound = ();
my ( $port, $errors ) =
$class->collect_port_versions( $pkg, $portsdir, [EMAIL PROTECTED] );
$class->collect_port_signatures( $pkg, $port, $portsdir ) unless $opt_q;
$class->find_outdated( $pkg, $port, \%outdated );
print STDERR "Updating ports:\n\n";
my @subdirs = $class->sort_by_depends( $port, keys %outdated );
my $cmd =
"cd $portsdir && SUBDIR=\""
. join( q{ }, @subdirs )
. "\" REPORT_PROBLEM=true make update 2>&1 |";
print $cmd, "\n";
my ($fh, $old) = $class->fh_open($cmd);
while (my $line = <$fh>) {
print $line;
}
$class->fh_close($fh, $old);
return 1;
}
sub sort_by_depends {
my $class = shift;
my ( $port, @keys ) = @_;
@keys = sort @keys;
my @sorted;
KEY: while ( my $key = shift @keys ) {
foreach my $subkey (@keys) {
my $stem = $port->{$key}->{stem};
my $signature = $port->{$key}->{signature};
my $substem = $port->{$subkey}->{stem};
$signature =~ s/^$stem//xms;
if ( defined $substem
&& defined $signature
&& $signature =~ /$substem/xms )
{
push @keys, $key;
next KEY;
}
}
push @sorted, $key;
}
return @sorted;
}
1;