#!/usr/bin/perl # vim: set ts=3 sw=3 ai et nu: # # Synchronizes repository configuration files with what's on the # openSUSE Build Service (using osc). # Needs an operational osc client. # # by Pascal Bleser # # This library is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or (at # your option) any later version. # # This library is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, # USA. use strict; use warnings; use Term::ProgressBar; use File::Spec; use File::Basename; use Getopt::Long; my $repos = "./repos.d"; my $cache_dir = "./cache.d"; my $verbose = undef; GetOptions( 'v|verbose' => \$verbose, ); my @projects = (); { print "Retrieving top-level project list\n" if $verbose; open(my $osc, 'osc ls|') or die "failed to run osc ls: $!"; while (<$osc>) { chomp(); push(@projects, $_) unless /^home:/; } close($osc); print scalar(@projects), " top-level projects\n" if $verbose; } my $progress = undef; my $count = 0; if ($verbose) { $progress = Term::ProgressBar->new({ count => scalar(@projects), name => 'projects', ETA => 'linear', }); #$progress->minor(0); } foreach my $p (@projects) { if (defined $progress) { $count++; $progress->update($count); } my $conf_file = File::Spec->catfile($repos, $p.".conf"); { my $dir = dirname($conf_file); mkdir($dir, 0750) unless -d $dir; } my @conf = (); if (-e $conf_file) { open(my $fh, '<', $conf_file) or die "failed to open $conf_file: $!"; while (<$fh>) { chomp; push(@conf, $_); } close($fh); } my @enabled_conf = (); foreach (grep { not /^$/ } map { s/#.*$//; s/^\s*//; s/\s*$//; $_ } @conf) { my ($id, $dist, $baseurl, $flags) = split(/\s+/); my $r = { repoid => $id, distribution=> $dist, baseurl => $baseurl, }; push(@enabled_conf, $r); } my %h = map { $_->{repoid} => $_ } @enabled_conf; my @dists = (); open(my $osc, 'osc repos "'.$p.'"|') or die "failed to run osc repos $p: $!"; while (<$osc>) { chomp; s/^\s*//; s/\s*$//; my ($dist, $arch) = split(/\s+/); push(@dists, $dist) if $dist =~ /^openSUSE_11\.[123]$/; } close($osc); my $changed = undef; my %unique_dists = map { $_ => 1 } @dists; foreach my $d (keys %unique_dists) { my $subdirs = $p; $subdirs =~ s|:|:/|g; my $repoid = $p.'-'.$distversion; my $baseurl = "http://download.opensuse.org/repositories/".$subdirs."/".$d; if (not exists $h{$repoid}) { push(@conf, join("\t", ($repoid, $d, $baseurl))); $changed = 1; } } if ($changed) { open(my $fh, '>', $conf_file) or die "failed to open $conf_file for writing: $!"; foreach (@conf) { print $fh $_, "\n"; } close($fh); } }