chdir "$FindBin::Bin/..";
$ENV{TOPDIR}=getcwd();
+my $mk=`which gmake`; # select the right 'make' program
+chomp($mk); # trim trailing newline
+$mk or $mk = "make"; # default to 'make'
+
my @feeds;
my %build_packages;
my %installed;
my $line = 0;
my %name;
- open FEEDS, "feeds.conf";
+ open FEEDS, "feeds.conf" or
+ open FEEDS, "feeds.conf.default" or
+ die "Unable to open feeds configuration";
while (<FEEDS>) {
chomp;
s/#.+$//;
next unless /\S/;
my @line = split /\s+/, $_, 3;
+ my @src;
$line++;
my $valid = 1;
$line[0] =~ /^src-\w+$/ or $valid = 0;
$line[1] =~ /^\w+$/ or $valid = 0;
- $line[2] =~ /\s/ and $valid = 0;
+ @src = split /\s+/, $line[2];
$valid or die "Syntax error in feeds.list, line: $line\n";
$name{$line[1]} and die "Duplicate feed name '$line[1]', line: $line\n";
$name{$line[1]} = 1;
- push @feeds, [@line];
+ push @feeds, [$line[0], $line[1], \@src];
}
close FEEDS;
}
+sub update_location($$)
+{
+ my $name = shift;
+ my $url = shift;
+ my $old_url;
+
+ -d "./feeds/$name.tmp" or mkdir "./feeds/$name.tmp" or return 1;
+
+ if( open LOC, "< ./feeds/$name.tmp/location" )
+ {
+ chomp($old_url = readline LOC);
+ close LOC;
+ }
+
+ if( !$old_url || $old_url ne $url )
+ {
+ if( open LOC, "> ./feeds/$name.tmp/location" )
+ {
+ print LOC $url, "\n";
+ close LOC;
+ }
+ return $old_url ? 1 : 0;
+ }
+
+ return 0;
+}
+
sub update_index($)
{
my $name = shift;
-d "./feeds/$name.tmp" or mkdir "./feeds/$name.tmp" or return 1;
-d "./feeds/$name.tmp/info" or mkdir "./feeds/$name.tmp/info" or return 1;
- system("make -s prepare-mk TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
- system("make -s -f include/scan.mk IS_TTY=1 SCAN_TARGET=\"packageinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"package\" SCAN_DEPS=\"$ENV{TOPDIR}/include/package*.mk\" SCAN_DEPTH=4 SCAN_EXTRA=\"\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
+ system("$mk -s prepare-mk TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
+ system("$mk -s -f include/scan.mk IS_TTY=1 SCAN_TARGET=\"packageinfo\" SCAN_DIR=\"feeds/$name\" SCAN_NAME=\"package\" SCAN_DEPS=\"$ENV{TOPDIR}/include/package*.mk\" SCAN_DEPTH=4 SCAN_EXTRA=\"\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\"");
system("ln -sf $name.tmp/.packageinfo ./feeds/$name.index");
return 0;
}
-sub update_svn($$) {
+sub update_svn($$$) {
my $name = shift;
my $src = shift;
+ my $relocate = shift;
- if (-d "./feeds/$name/.svn" ) {
+ if ( !$relocate && -d "./feeds/$name/.svn" ) {
system("(cd \"./feeds/$name\"; svn up)") == 0 or return 1;
} else {
system("rm -rf \"./feeds/$name\"");
return 0;
}
-sub update_cpy($$) {
+sub update_cpy($$$) {
my $name = shift;
my $src = shift;
+ my $relocate = shift;
+ $relocate && system("rm -rf \"./feeds/$name\"");
system("mkdir -p ./feeds/$name");
system("cp -Rf $src ./feeds");
return 0;
}
-sub update_link($$) {
+sub update_link($$$) {
my $name = shift;
my $src = abs_path(shift);
+ my $relocate = shift; # no-op
- system("ln -sf $src ./feeds/$name");
+ system("rm -f ./feeds/$name; ln -s $src ./feeds/$name");
return 0;
}
-sub update_git($$) {
+sub update_git($$$) {
my $name = shift;
my $src = shift;
+ my $relocate = shift;
- if (-d "./feeds/$name/.git" ) {
+ if ( !$relocate && -d "./feeds/$name/.git" ) {
system("GIT_DIR=./feeds/$name/.git git pull") == 0 or return 1;
} else {
system("rm -rf \"./feeds/$name\"");
- system("git-clone --depth 1 $src ./feeds/$name") == 0 or return 1;
+ system("git clone --depth 1 $src ./feeds/$name") == 0 or return 1;
}
return 0;
sub get_feed($) {
my $feed = shift;
+ my $file = "./feeds/$feed.index";
clear_packages();
- parse_package_metadata("./feeds/$feed.index") or return;
+
+ -f $file or do {
+ print "Ignoring feed '$feed' - index missing\n";
+ return;
+ };
+ parse_package_metadata($file) or return;
return { %package };
}
sub get_installed() {
- system("make -s prepare-tmpinfo");
+ system("$mk -s prepare-tmpinfo");
clear_packages();
parse_package_metadata("./tmp/.packageinfo");
%installed = %package;
}
if ($opts{s}) {
foreach my $feed (@feeds) {
- printf "\%-32s\tURL: %s\n", $feed->[1], $feed->[2];
+ printf "\%-32s\tURL: %s\n", $feed->[1], join(", ", @{$feed->[2]});
}
return 0;
}
$feed = lookup_package($feed, $name);
$feed or do {
$installed{$name} and return 0;
- warn "WARNING: No feed for package '$name' found.\n";
- return 1;
+ # TODO: check if it's already installed within ./package directory
+ $srcpackage{$name} or -d "./package/$name" or warn "WARNING: No feed for package '$name' found, maybe it's already part of the standard packages?\n";
+ return 0;
};
my $pkg = $feed{$feed->[1]}->{$name} or return 1;
$pkg->{name} or do {
$installed{$name} and return 0;
+ # TODO: check if this is an alias package, maybe it's known by another name
warn "WARNING: Package '$name' is not available in feed $feed->[1].\n";
- return 1;
+ return 0;
};
my $src = $pkg->{src};
my $type = $feed->[0];
# newly installed packages set the source package
$installed{$src} and return 0;
- # install all dependencies
- foreach my $dep (@{$pkg->{depends}}) {
- next if $dep =~ /@/;
- $dep =~ s/^\+//;
- install_package($feed, $dep) == 0 or $ret = 1;
- }
-
# check previously installed packages
$installed{$name} and return 0;
$installed{$src} = 1;
return 1;
};
+ # install all dependencies
+ foreach my $vpkg (@{$srcpackage{$src}}, $pkg) {
+ foreach my $dep (@{$vpkg->{depends}}, @{$vpkg->{builddepends}}) {
+ next if $dep =~ /@/;
+ $dep =~ s/^\+//;
+ $dep =~ s/^.+://;
+ next unless $dep;
+ install_package($feed, $dep) == 0 or $ret = 1;
+ }
+ }
+
return $ret;
}
# refresh the config
if ($default) {
- system("make oldconfig CONFDEFAULT=\"$default\" Config.in >/dev/null 2>/dev/null");
+ system("$mk oldconfig CONFDEFAULT=\"$default\" Config.in >/dev/null 2>/dev/null");
} else {
- system("make defconfig Config.in >/dev/null 2>/dev/null");
+ system("$mk defconfig Config.in >/dev/null 2>/dev/null");
}
}
my $p = $package{$name};
if( $p->{name} ) {
install_package($feed, $p->{name}) == 0 or $ret = 1;
- } else {
- warn "WARNING: Package '$name' is not available\n";
}
}
}
my $name=shift;
my $src=shift;
my $perform_update=shift;
+ my $force_relocate=update_location( $name, "@$src" );
+ if( $force_relocate ) {
+ warn "Source of feed $name has changed, replacing copy\n";
+ }
$update_method{$type} or do {
warn "Unknown type '$type' in feed $name\n";
return 1;
};
$perform_update and do {
- warn "Updating feed '$name' from '$src' ...\n";
- &{$update_method{$type}}($name, $src) == 0 or do {
+ my $failed = 1;
+ foreach my $feedsrc (@$src) {
+ warn "Updating feed '$name' from '$feedsrc' ...\n";
+ next unless &{$update_method{$type}}($name, $feedsrc, $force_relocate) == 0;
+ $failed = 0;
+ last;
+ }
+ $failed and do {
warn "failed.\n";
return 1;
};