[csw-devel] SF.net SVN: opencsw:[613] buildfarm/cgi-bin

dmichelsen at users.sourceforge.net dmichelsen at users.sourceforge.net
Wed Feb 22 21:43:08 CET 2012


Revision: 613
          http://opencsw.svn.sourceforge.net/opencsw/?rev=613&view=rev
Author:   dmichelsen
Date:     2012-02-22 20:43:08 +0000 (Wed, 22 Feb 2012)
Log Message:
-----------
Add CGI scripts for dependency graphs and ATOM feeds

Added Paths:
-----------
    buildfarm/cgi-bin/OpenCSW/
    buildfarm/cgi-bin/OpenCSW/Catalog.pm
    buildfarm/cgi-bin/dograph
    buildfarm/cgi-bin/experimental.atom
    buildfarm/cgi-bin/testing.atom

Added: buildfarm/cgi-bin/OpenCSW/Catalog.pm
===================================================================
--- buildfarm/cgi-bin/OpenCSW/Catalog.pm	                        (rev 0)
+++ buildfarm/cgi-bin/OpenCSW/Catalog.pm	2012-02-22 20:43:08 UTC (rev 613)
@@ -0,0 +1,244 @@
+package OpenCSW::Catalog;
+
+sub new {
+  my ($class,$catalogfile) = @_;
+
+  my %catalog;
+  my %pkg2catalog;
+
+  open F, $catalogfile or die "Cannot open $catalogfile";
+  while( <F> ) {
+    # 9menu 1.8,REV=2006.05.19 CSW9menu 9menu-1.8,REV=2006.05.19-SunOS5.8-i386-CSW.pkg.gz 51eaeee15a71a4290789729feb956759 12196 CSWcommon non
+
+    last if( /^-----BEGIN PGP SIGNATURE-----/ );
+    next if( /^(----.*|Hash:.*|#.*|)$/ );
+
+    chomp;
+    my @fields = split(/\s+/);
+    if( @fields < 5 || @fields > 10 ) {
+      print "ERROR: ", scalar( @fields ), " $_\n";
+      next;
+    }
+    
+    my ($cname,$version,$pkgname,$pkgfile,$md5,$size,$deps,$ideps,$category, $bundle) = split(/\s+/);
+    $catalog{$cname} = {
+	catalogname => $cname,
+	version => $version,
+	pkgname => $pkgname,
+	pkgfile => $pkgfile,
+	md5 => $md5,
+	size => $size,
+	deps => ($deps eq 'none' ? [] : [ split( /\|/, $deps ) ]),
+	ideps => ($ideps eq 'none' ? [] : [ split( /\|/, $ideps ) ]),
+	category => $category,
+	bundle => $bundle,
+    };
+    $pkg2catalog{$pkgname} = $cname;
+  }
+  close F;
+
+  return bless {
+    catalog => \%catalog,
+    pkg2catalog => \%pkg2catalog,
+  }, ref( $class ) || $class;
+}
+
+sub catalogname {
+  my ($this,%args) = @_;
+  my $line = $this->_getline( %args );
+  my $catalogname = $line ? $line->{catalogname} : undef;
+  return $catalogname;
+}
+
+sub pkgname {
+  my ($this,%args) = @_;
+  my $line = $this->_getline( %args );
+  my $pkgname = $line ? $line->{pkgname} : undef;
+  return $pkgname;
+}
+
+sub size {
+  my ($this,%args) = @_;
+  my $line = $this->_getline( %args );
+  my $size = $line ? $line->{size} : undef;
+  return $size;
+}
+
+sub deps {
+  my ($this,%args) = @_;
+  my $line = $this->_getline( %args );
+  my @deps = $line ? @{$line->{deps}} : ();
+  return @deps;
+}
+
+sub bundle {
+  my ($this,%args) = @_;
+  my $line = $this->_getline( %args );
+  my $bundle = $line ? $line->{bundle} : undef;
+  return $bundle;
+}
+
+sub _getline {
+  my ($this,%args) = @_;
+  if( exists $args{name} ) {
+    my $name = $args{name};
+    if( exists $this->{catalog}->{$name} ) {
+      return $this->{catalog}->{$name};
+    } elsif( exists $this->{pkg2catalog}->{$name} ) {
+      return $this->{catalog}->{$this->{pkg2catalog}->{$name}};
+    } else {
+      return undef;
+    }
+  } elsif( exists $args{catalogname} ) {
+    return $this->{catalog}->{$args{catalogname}};
+  } elsif( exists $args{pkg} ) {
+    return $this->{catalog}->{$this->{pkg2catalog}->{$args{pkg}}};
+  } else {
+    print "Option unknown\n";
+  }
+}
+
+1;
+
+__END__
+
+sub _equal {
+  my ($e1, $e2) = @_;
+  return ($e1->{version} eq $e2->{version} &&
+	$e1->{pkgname} eq $e2->{pkgname} &&
+	$e1->{pkgfile} eq $e2->{pkgfile} &&
+	$e1->{md5} eq $e2->{md5} &&
+	$e1->{size} eq $e2->{size} &&
+	join('|', @{$e1->{deps}}) eq join('|', @{$e2->{deps}}) &&
+	join('|', @{$e1->{ideps}}) eq join('|', @{$e2->{ideps}})
+	);
+}
+
+sub _depcompare {
+  my ($a1, $a2) = @_;
+
+  my %a1;
+  my (@additions, at removals);
+  foreach my $a1 (@$a1) {
+    $a1{$a1} = 1;
+  }
+  foreach my $a2 (@$a2) {
+    if( exists $a1{$a2} ) {
+      delete $a1{$a2};
+    } else {
+      push @additions, $a2;
+    }
+  }
+  @removals = keys %a1;
+  return [\@removals,\@additions];
+}
+
+sub _extract_version {
+  my ($v) = @_;
+  $v =~ s/,REV=\d{4}\.\d{2}\.\d{2}//;
+  return $v;
+}
+
+sub _eq_version {
+  # 2009.09.09,REV=2009.09.09
+  my ($v1,$v2) = @_;
+  $v1 = _extract_version( $v1 );
+  $v2 = _extract_version( $v2 );
+
+  return $v1 eq $v2;
+}
+
+sub _compare_rev {
+  # 2009.09.09,REV=2009.09.09
+  my ($v1,$v2) = @_;
+
+  my ($y1,$m1,$d1) = ($v1 =~ /,REV=(\d{4})\.(\d{2})\.(\d{2})/);
+  my ($y2,$m2,$d2) = ($v2 =~ /,REV=(\d{4})\.(\d{2})\.(\d{2})/);
+
+  if( !defined $y1 || !defined $m1 || !defined $d1 ) {
+    return 0 if( !defined $y2 || !defined $m2 || !defined $d2 );
+    return 1;
+  }
+  return -1 if( !defined $y2 || !defined $m2 || !defined $d2 );
+
+  return ($y1 cmp $y2)*4 + ($m1 cmp $m2)*2 + ($d1 cmp $d2);
+}
+
+sub compare {
+  my ($co1, $co2) = @_;
+  my %c1 = %$co1;
+  my %c2 = %$co2;
+
+  my %hchanges;
+
+  my (%pc1, %pc2);
+  $pc1{$_->{pkgname}} = $_ foreach (values %c1);
+  $pc2{$_->{pkgname}} = $_ foreach (values %c2);
+
+  # 1. Find differences in attributes for packages with same catalog name
+  #    (additions, updates, removals)
+  foreach my $p1 (keys %c1) {
+    if( exists( $c2{$p1} ) ) {
+      # Entries with same catalog name exist in catalog 1 and 2
+      if( !_equal( $c1{$p1}, $c2{$p1} ) ) {
+        # Package as been updated
+        $hchanges{$p1}->{_pkgname} = $c1{$p1}->{pkgname};
+        my %e1 = %{$c1{$p1}};
+        my %e2 = %{$c2{$p1}};
+	my $versiondiff = $e1{version} ne $e2{version};
+	my $pkgnamediff = $e1{pkgname} ne $e2{pkgname};
+	my $pkgfilediff = $e1{pkgfile} ne $e2{pkgfile};
+	my $md5diff = $e1{md5} ne $e2{md5};
+	my $sizediff = $e1{size} ne $e2{size};
+        if( $versiondiff ) {
+          my ($v1,$v2) = ($e1{version}, $e2{version});
+          if( _eq_version( $v1, $v2 ) ) {
+            $hchanges{$p1}->{version} = { type => "Respin", from => $e1{version}, to => $e2{version} };
+          } elsif( _compare_rev( $v1, $v2 ) ) {
+            $hchanges{$p1}->{version} = { type => "Update", from => $e1{version}, to => $e2{version} };
+          } else {
+            $hchanges{$p1}->{version} = { type => "Sameday update", from => $e1{version}, to => $e2{version} };
+          }
+        } else {
+	  # If the version has been updated we have another package, so differences on the other fields are pretty obvious
+          $hchanges{$p1}->{pkgname} = { type => "Changed", from => $e1{pkgname}, to => $e2{pkgname} } if( $pkgnamediff );
+          $hchanges{$p1}->{pkgfile} = { type => "Changed", from => $e1{pkgfile}, to => $e2{pkgfile} } if( $pkgfilediff );
+          $hchanges{$p1}->{md5} = { type => "Changed", from => $e1{md5}, to => $e2{md5} } if( $md5diff );
+          $hchanges{$p1}->{size} = { type => "Changed", from => $e1{size}, to => $e2{size} } if( $sizediff );
+	}
+        my $dep = _depcompare( $e1{deps}, $e2{deps} );
+        if( @{$dep->[0]} > 0 || @{$dep->[1]} > 0 ) {
+          $hchanges{$p1}->{deps} = { type => "Changed", removed => $dep->[0], added => $dep->[1] };
+	}
+        my $idep = _depcompare( $e1{ideps}, $e2{ideps} );
+        if( @{$idep->[0]} > 0 || @{$idep->[1]} > 0 ) {
+          $hchanges{$p1}->{ideps} = { type => "Changed", removed => $idep->[0], added => $idep->[1] };
+        }
+      } else {
+        # Package is same, ignore.
+      }
+      delete $c2{$p1};
+    } else {
+      # Catalogname is in catalog 1 only, deletion
+      my $pkgname = $c1{$p1}->{pkgname};
+      $hchanges{$p1}->{_pkgname} = $pkgname;
+      if( exists $pc2{$pkgname} && $pc2{$pkgname}->{catalogname} ne $c1{$p1}->{catalogname} ) {
+        $hchanges{$p1}->{catalogname} = { type => "Changed", from => $c1{$p1}->{catalogname}, to => $pc2{$pkgname}->{catalogname} };
+        # If it was a rename we processed it, so remove it here
+        delete $c2{$pc2{$pkgname}->{catalogname}};
+      } else {
+        $hchanges{$p1}->{package} = { type => "Deleted", pkg => $c1{$p1}->{pkgname} };
+      }
+    }
+  }
+
+  # What is left in catalog 2 are additions
+  foreach my $p2 (keys %c2) {
+    $hchanges{$p2}->{_pkgname} = $c2{$p2}->{pkgname};
+    $hchanges{$p2}->{package} = { type => "Added", pkg => $c2{$p2}->{pkgname} };
+  }
+
+  return \%hchanges;
+}
+
+1;


Property changes on: buildfarm/cgi-bin/OpenCSW/Catalog.pm
___________________________________________________________________
Added: svn:executable
   + *

Added: buildfarm/cgi-bin/dograph
===================================================================
--- buildfarm/cgi-bin/dograph	                        (rev 0)
+++ buildfarm/cgi-bin/dograph	2012-02-22 20:43:08 UTC (rev 613)
@@ -0,0 +1,286 @@
+#!/bin/sh
+#! -*- perl -*-
+eval 'PATH=/opt/csw/bin:$PATH:/usr/perl5/bin exec perl -x -w $0 ${1+"$@"}'
+  if 0;
+
+# TBD:
+# - Add number of packages to collapsed bundles
+# - Add total size of packages to collapsed bundles
+
+use strict;
+use warnings;
+use Getopt::Long;
+use OpenCSW::Catalog;
+
+my $_catalog = OpenCSW::Catalog->new( "/home/web/bin/rest-interface/catalog" );
+
+sub format_byte {
+    my ($size) = @_;
+    my $suffix = "B";
+
+    if ( $size > 1024 ) {
+        $size /= 1024;
+        $suffix = "KB";
+    }
+    if ( $size > 1024 ) {
+        $size /= 1024;
+        $suffix = "MB";
+    }
+    if ( $size > 1024 ) {
+        $size /= 1024;
+        $suffix = "GB";
+    }
+    return sprintf( "%1.1f %s", $size, $suffix );
+}
+
+
+# Direct dependencies for package
+sub deps {
+  my ($pkg) = @_;
+  return $_catalog->deps( name => $pkg );
+}
+
+sub size {
+  my ($pkg) = @_;
+  return $_catalog->size( name => $pkg );
+}
+
+# This package plus all its dependencies
+sub _depsize {
+  my ($pkg, $total) = @_;
+
+  $total = {} if( !defined $total );
+  return $total if( exists $total->{$pkg} );
+  if( $pkg eq "CSWcommon" || $pkg eq "CSWisaexec" || $pkg =~ /^CSWcas-/ ) {
+    $total->{$pkg} = 0;
+  } else {
+    $total->{$pkg} = size( $pkg );
+  }
+  foreach (deps( $pkg )) {
+    next if( exists $total->{$_} );
+    depsize( $_, $total );
+    $total->{$pkg} += $total->{$_} || 0;
+  }
+
+  return $total;
+}
+
+# Return for a given package the depth of all packages { <pkg> => <depth>, ... }
+sub fulldeps {
+  my (@pkglist) = @_;
+
+  my %depth;
+  $depth{$_} = 0 foreach (@pkglist);
+  my @todo = @pkglist;
+
+  #my $maxdep = 0;
+  foreach (@todo) {
+    my @deps = deps($_);
+    foreach my $d (@deps) {
+      next if( exists $depth{$d} );
+      $depth{$d} = $depth{$_} + 1;
+      #$maxdep = $depth{$d} if( $depth{$d} > $maxdep );
+      push @todo, $d;
+    }
+  }
+  return \%depth;
+}
+
+sub depsize {
+  my (@pkglist) = @_;
+
+  my $total = 0;
+  my $deps = fulldeps( @pkglist );
+  foreach (keys %$deps) {
+    next if( $_ eq "CSWcommon" || $_ eq "CSWisaexec" || $_ =~ /^CSWcas-/ );
+    $total += size( $_ );
+  }
+  return $total;
+}
+
+
+
+# Display package dependencies as DOT graph
+sub depgraph {
+  my (%args) = @_;
+  my %done;	# If package is in this hash it is processed
+  my %size;	# Size in bytes of the package
+  my @todo = @{$args{pkg}};
+  my %collapse_bundles = ();
+  %collapse_bundles = %{$args{collapse_bundles}} if( exists $args{collapse_bundles} );
+  my $autocollapse = $args{autocollapse};
+  my $collapseall = $args{collapseall};
+
+  print "digraph \"Package Dependencies ", join( ", ", @todo ), "\" {\n";
+
+  # Make sure we have package names
+  @todo = map { $_catalog->pkgname( name => $_ ) } @todo;
+
+  # Lets see how far we can dive
+  my $show_up_to = 0;
+  my %showpkg;
+  my %bundle;
+  my %bundles;
+  my %node2print;
+  foreach (@todo) {
+    my $fulldeps = fulldeps( $_ );
+    my %depthcount;
+    while( my ($pkg, $depth) = each %$fulldeps ) {
+      push @{$depthcount{$depth}}, $pkg;
+    }
+    my @showpkgs;
+    foreach my $i (sort keys %depthcount) {
+      my @levelpkg = @{$depthcount{$i}};
+      if( scalar @showpkgs + scalar @levelpkg > 1000 ) {
+        $show_up_to = $i;
+        last;
+      }
+      push @showpkgs, @levelpkg;
+    };
+    @showpkgs = grep { $_catalog->pkgname( name => $_ ) } @showpkgs;	# Exclude SUNW packages not in catalog
+    foreach (@showpkgs) {
+      next if( $_ eq "CSWcommon" || $_ eq "CSWisaexec" || $_ =~ /^CSWcas-/ );
+      $showpkg{$_} = 1;
+      $node2print{$_} = $_;
+      my $b = $_catalog->bundle( name => $_ );
+      if( defined $b && $b ne 'none' ) {
+        push @{$bundles{$b}}, $_;
+        $bundle{$_} = $b;
+        # $node2print{$_} = $b if( $collapse_bundles{$b} );
+      }
+    }
+  }
+
+  foreach my $b (keys %bundles) {
+    my @pkgs4bundle = @{$bundles{$b}};
+    $collapse_bundles{$b} = 1 if( $autocollapse && @pkgs4bundle > 3 || $collapseall && @pkgs4bundle > 1 );
+    foreach my $p (@pkgs4bundle) {
+      $node2print{$p} = $b if( $collapse_bundles{$b} );
+    }
+  }
+
+  # Now iterate over all dependencies
+  my $sizes;
+  foreach (@todo) {
+    my $catalog = $_catalog->catalogname( name => $_ );
+    my $pkg  = $_catalog->pkgname( name => $_ );
+    next if( !defined $pkg );
+    $size{$pkg} = $_catalog->size( name => $_ );
+
+    $done{$pkg} = 1;
+
+    foreach my $p (deps($pkg)) {
+      my $s = $_catalog->size( name => $p );
+      next if( $p eq "CSWcommon" || $p eq "CSWisaexec" || $p =~ /^CSWcas-/ );
+
+      # The edge is between nodes in the same bundle. Print only if the bundle is not collapsed.
+      if( $node2print{$pkg} ne $node2print{$p} &&
+          # Show edge only if target node is shown
+          exists $showpkg{$p} ) {
+        print "  \"", $node2print{$pkg}, "\"";
+        print " -> ";
+        print '"', $node2print{$p}, '";', "\n";
+      }
+      if( !exists $done{$p} ) {
+        push @todo, $p;
+        $done{$p} = 1;
+      }
+    }
+  }
+
+  my $total = 0;
+  $total += $size{$_} foreach (keys %size);
+
+  print "  label = \"Number of packages: ", scalar keys( %size ), "\\n\"\n";
+  print "        + \"Total size of packages: ", format_byte( $total ), "\\n\"\n";
+  print "        + \" Clipped to ", $show_up_to + 1, " levels\\n\"\n" if( $show_up_to );
+  print "  labelloc = t\n";
+  print "  labeljust = l\n";
+
+  # We are traversing all the packages. When a bundle is collapsed for a package we remember
+  # that and do not print the bundle again next time we visist another package from it.
+  my %bundle_done;
+
+#  foreach (keys %done) {
+  foreach (keys %node2print) {
+    next if( !exists $showpkg{$_} );
+
+    if( $node2print{$_} ne $_ ) {
+      # Collapsed node
+      my $b = $node2print{$_};				# Bundle name
+      next if( $bundle_done{$b} );		# We printed this before
+
+      my $obsoleted = 0;
+      foreach (@{$bundles{$b}}) {
+        $obsoleted = 1 if( $_catalog->catalogname( name => $_ ) =~ /_stub$/ );
+      }
+
+      print "  \"", $b, "\" [ shape=box; ";
+      print " label=\"", $b, "\\n",  scalar( grep { exists $showpkg{$_} } @{$bundles{$b}} ), " packages\\n";
+      print "[", format_byte( depsize( @{$bundles{$b}} ) ), "]\"; ";
+      print " style=filled fillcolor=\"#ff8080\"" if( $obsoleted );
+      print " URL=\"/cgi-bin/depgraph2?pkg=", $todo[0], "&collapse_bundles=", join( ',', grep { $_ ne $b } keys %collapse_bundles ), "\"; ";
+      print " ]\n";
+      $bundle_done{$b} = 1;
+    } else {
+      print "  \"$_\" [";
+      my $catalog  = $_catalog->catalogname( name => $_ );
+      next if( !$catalog );
+      if( $catalog =~ /_stub$/ ) {
+        print " style=filled fillcolor=\"#ff8080\"" if( $catalog =~ /_stub$/ );
+      } else {
+        print " URL=\"http://www.opencsw.org/p/$_\"";
+        print " comment=\"$_\"";
+        print " label=\"$_\\n(", format_byte( $size{$_} ), ")";
+        my $depsize = depsize( $_ );
+        print "\\n[", format_byte( $depsize ), "]" if( $size{$_} != $depsize );
+        print "\"";
+      }
+      print "]\n";
+    }
+  }
+
+#QUERY_STRING=pkg=gnuplot_wx&collapse_bundles=gtk2
+#REQUEST_URI=/cgi-bin/depgraph2?pkg=gnuplot_wx&collapse_bundles=gtk2
+
+  foreach (keys %bundles) {
+    my @b = @{$bundles{$_}};		# These are the packages for the bundle
+    next if( @b <= 1 );			# Do not show a bundle if there is only one package from it drawn
+    next if( $collapse_bundles{$_} );	# Do not show this bundle as it is collapsed
+    print "  subgraph \"cluster_$_\" { label=\"$_\\n",  scalar( grep { exists $showpkg{$_} } @b ), " packages\\n";
+    print "[", format_byte( depsize( @b ) ), "]\"; ";
+    # print " bgcolor=lightgrey";
+    print " URL=\"/cgi-bin/depgraph2?pkg=", $todo[0], "&collapse_bundles=", join( ',', $_, keys %collapse_bundles ), "\"; ";
+    foreach my $pp (@b) {
+      next if( !exists $showpkg{$pp} );
+      print "\"$pp\"; ";
+    }
+    print "}\n";
+  }
+
+  print "}\n";
+}
+
+my $color_stubs;
+my $collapse_bundles = undef;
+my %collapse_bundles;
+
+use Data::Dumper;
+# print STDERR "D: ", Dumper( @ARGV );
+
+my $result = GetOptions (
+  "color_stubs" => \$color_stubs,    # numeric
+  "collapse_bundles:s" => \$collapse_bundles,
+);  # flag
+
+if( !defined $collapse_bundles ) {
+  # Auto-detect
+  depgraph( pkg => \@ARGV, autocollapse => 1 );
+} elsif( $collapse_bundles eq "all" ) {
+  depgraph( pkg => \@ARGV, collapseall => 1 );
+} else {
+  $collapse_bundles{$_} = 1 foreach (split /,/, $collapse_bundles);
+  depgraph( pkg => \@ARGV, collapse_bundles => \%collapse_bundles );
+}
+
+


Property changes on: buildfarm/cgi-bin/dograph
___________________________________________________________________
Added: svn:executable
   + *

Added: buildfarm/cgi-bin/experimental.atom
===================================================================
--- buildfarm/cgi-bin/experimental.atom	                        (rev 0)
+++ buildfarm/cgi-bin/experimental.atom	2012-02-22 20:43:08 UTC (rev 613)
@@ -0,0 +1,58 @@
+#!/opt/csw/bin/perl -w
+
+use strict;
+use POSIX qw( strftime );
+use XML::Atom::SimpleFeed;
+
+my $DIR = "/home/experimental";
+
+my $feed = XML::Atom::SimpleFeed->new(
+  title    => "OpenCSW Experimental Packages",
+  subtitle => "Test at your own risk",
+  logo     => "http://gar.opencsw.org/trac/chrome/common/trac_banner.png",
+  link     => "http://mirror.opencsw.org/experimental.html",
+  link     => {
+    rel  => 'self',
+    href => 'http://buildfarm.opencsw.org/cgi-bin/experimental.atom',
+  },
+  id       => "http://mirror.opencsw.org/testing.html",
+  author   => "OpenCSW Maintainers",
+#  updated  => $updated,
+);
+
+
+opendir T, $DIR || die "Can't open $DIR";
+my @projects = grep { !/^\./ && -d "$DIR/$_" } readdir T;
+closedir T;
+
+foreach my $project (@projects) {
+  opendir T, "$DIR/$project" || die "Can't open $DIR/$project";
+  my @pkgs = grep { !/^\./ && -f "$DIR/$project/$_" } readdir T;
+  closedir T;
+
+  foreach my $pkg (@pkgs) {
+    # rubytk-1.8.7,REV=2008.09.19_p72-SunOS5.8-sparc-CSW.pkg.gz
+    my ($cname,$vers,$y,$m,$d,$os,$arch) = ($pkg =~ /^([^-]+)-([^-]+),REV=(\d{4})\.(\d{2})\.(\d{2})[^-]*-SunOS([^-]+)-([^-]+)-CSW\./);
+
+    my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)
+      = stat( "$DIR/$project/$pkg" );
+
+
+    next if( !defined $cname || !defined $y || !defined $m || !defined $d );
+    # my $date = "${y}-${m}-${d}T00:00:00Z";
+  
+    my $date = strftime '%Y-%m-%dT%H:%M:%SZ', gmtime( $mtime );
+
+
+    $feed->add_entry(
+      title   => "Project $project: $cname $vers for Solaris $os $arch",
+      link    => "http://mirror.opencsw.org/experimental/$project/$pkg",
+      id      => "http://mirror.opencsw.org/experimental/$project/$pkg",
+      summary => "$pkg",
+      updated => $date,
+    );
+  }
+}
+
+print "Content-type: text/xml; charset=us-ascii\n\n";
+$feed->print();


Property changes on: buildfarm/cgi-bin/experimental.atom
___________________________________________________________________
Added: svn:executable
   + *

Added: buildfarm/cgi-bin/testing.atom
===================================================================
--- buildfarm/cgi-bin/testing.atom	                        (rev 0)
+++ buildfarm/cgi-bin/testing.atom	2012-02-22 20:43:08 UTC (rev 613)
@@ -0,0 +1,49 @@
+#!/opt/csw/bin/perl -w
+
+use strict;
+use POSIX qw( strftime );
+use XML::Atom::SimpleFeed;
+
+my $feed = XML::Atom::SimpleFeed->new(
+  title    => "OpenCSW Testing Packages",
+  subtitle => "Test at your own risk",
+  logo     => "http://gar.opencsw.org/trac/chrome/common/trac_banner.png",
+  link     => "http://buildfarm.opencsw.org/testing.html",
+  link     => {
+    rel  => 'self',
+    href => 'http://buildfarm.opencsw.org/cgi-bin/testing.atom',
+  },
+  id       => "http://buildfarm.opencsw.org/testing.html",
+  author   => "OpenCSW Maintainers",
+#  updated  => $updated,
+);
+
+opendir T, "/home/testing";
+my @pkgs = readdir T;
+closedir T;
+
+foreach my $pkg (@pkgs) {
+  # rubytk-1.8.7,REV=2008.09.19_p72-SunOS5.8-sparc-CSW.pkg.gz
+  my ($cname,$vers,$y,$m,$d,$os,$arch) = ($pkg =~ /^([^-]+)-([^-]+),REV=(\d{4})\.(\d{2})\.(\d{2})[^-]*-SunOS([^-]+)-([^-]+)-CSW\./);
+
+  my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks)
+    = stat( "/home/testing/$pkg" );
+
+
+  next if( !defined $cname || !defined $y || !defined $m || !defined $d );
+  # my $date = "${y}-${m}-${d}T00:00:00Z";
+
+  my $date = strftime '%Y-%m-%dT%H:%M:%SZ', gmtime( $mtime );
+
+
+  $feed->add_entry(
+    title   => "$cname $vers for Solaris $os $arch",
+    link    => "http://buildfarm.opencsw.org/testing/$pkg",
+    id      => "http://buildfarm.opencsw.org/testing/$pkg",
+    summary => "$pkg",
+    updated => $date,
+  );
+}
+
+print "Content-type: text/xml; charset=us-ascii\n\n";
+$feed->print();


Property changes on: buildfarm/cgi-bin/testing.atom
___________________________________________________________________
Added: svn:executable
   + *

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the devel mailing list