X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/3d6655b67f7827dd6a1c55a0a58605baa31b3e31..b2e1bfb056bca17d81fdcbf020d9948a88d17304:/scripts/feeds diff --git a/scripts/feeds b/scripts/feeds index 0586b429d..6121a6265 100755 --- a/scripts/feeds +++ b/scripts/feeds @@ -15,9 +15,21 @@ my $mk=`which gmake`; # select the right 'make' program chomp($mk); # trim trailing newline $mk or $mk = "make"; # default to 'make' +# check version of make +my @mkver = split /\s+/, `$mk -v`, 4; +my $valid_mk = 1; +$mkver[0] =~ /^GNU/ or $valid_mk = 0; +$mkver[1] =~ /^Make/ or $valid_mk = 0; +$mkver[2] >= "3.81" or $valid_mk = 0; +$valid_mk or die "Unsupported version of make found: $mk\n"; + my @feeds; my %build_packages; my %installed; +my %feed_cache; + +my $feed_package = {}; +my $feed_src = {}; sub parse_config() { my $line = 0; @@ -38,7 +50,7 @@ sub parse_config() { $line[0] =~ /^src-\w+$/ or $valid = 0; $line[1] =~ /^\w+$/ or $valid = 0; @src = split /\s+/, $line[2]; - $valid or die "Syntax error in feeds.list, line: $line\n"; + $valid or die "Syntax error in feeds.conf, line: $line\n"; $name{$line[1]} and die "Duplicate feed name '$line[1]', line: $line\n"; $name{$line[1]} = 1; @@ -72,7 +84,7 @@ sub update_location($$) return $old_url ? 1 : 0; } - return 0; + return 0; } sub update_index($) @@ -83,76 +95,93 @@ sub update_index($) -d "./feeds/$name.tmp/info" or mkdir "./feeds/$name.tmp/info" or return 1; 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("$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=5 SCAN_EXTRA=\"\" TMP_DIR=\"$ENV{TOPDIR}/feeds/$name.tmp\""); system("ln -sf $name.tmp/.packageinfo ./feeds/$name.index"); return 0; } -sub update_svn($$$) { - my $name = shift; - my $src = shift; - my $relocate = shift; - - if ( !$relocate && -d "./feeds/$name/.svn" ) { - system("(cd \"./feeds/$name\"; svn up)") == 0 or return 1; - } else { - system("rm -rf \"./feeds/$name\""); - system("svn co $src \"./feeds/$name\"") == 0 or return 1; - } - - return 0; -} - -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($$$) { - my $name = shift; - my $src = abs_path(shift); - my $relocate = shift; # no-op - - system("rm -f ./feeds/$name; ln -s $src ./feeds/$name"); +my %update_method = ( + 'src-svn' => { + 'init' => "svn checkout '%s' '%s'", + 'update' => "svn update", + 'controldir' => ".svn"}, + 'src-cpy' => { + 'init' => "cp -Rf '%s' '%s'", + 'update' => ""}, + 'src-link' => { + 'init' => "ln -s '%s' '%s'", + 'update' => ""}, + 'src-git' => { + 'init' => "git clone --depth 1 '%s' '%s'", + 'init_branch' => "git clone --depth 1 --branch '%s' '%s' '%s'", + 'update' => "git pull", + 'controldir' => ".git"}, + 'src-gitsvn' => { + 'init' => "git svn clone -r HEAD '%s' '%s'", + 'update' => "git svn rebase", + 'controldir' => ".git"}, + 'src-bzr' => { + 'init' => "bzr checkout --lightweight '%s' '%s'", + 'update' => "bzr update", + 'controldir' => ".bzr"}, + 'src-hg' => { + 'init' => "hg clone '%s' '%s'", + 'update' => "hg pull --update", + 'controldir' => ".hg"}, + 'src-darcs' => { + 'init' => "darcs get '%s' '%s'", + 'update' => "darcs pull -a", + 'controldir' => "_darcs"}, +); - return 0; -} +# src-git: pull broken +# src-cpy: broken if `basename $src` != $name -sub update_git($$$) { +sub update_feed_via($$$$) { + my $type = shift; my $name = shift; my $src = shift; my $relocate = shift; - - if ( !$relocate && -d "./feeds/$name/.git" ) { - system("GIT_DIR=./feeds/$name/.git git pull") == 0 or return 1; + + my $m = $update_method{$type}; + my $localpath = "./feeds/$name"; + my $safepath = $localpath; + $safepath =~ s/'/'\\''/; + my ($base, $branch) = split(/;/, $src, 2); + + if( $relocate || !$m->{'update'} || !-d "$localpath/$m->{'controldir'}" ) { + system("rm -rf '$safepath'"); + if ($m->{'init_branch'} and $branch) { + system(sprintf($m->{'init_branch'}, $branch, $base, $safepath)) == 0 or return 1; + } else { + system(sprintf($m->{'init'}, $src, $safepath)) == 0 or return 1; + } } else { - system("rm -rf \"./feeds/$name\""); - system("git clone --depth 1 $src ./feeds/$name") == 0 or return 1; + system("cd '$safepath'; $m->{'update'}") == 0 or return 1; } - + return 0; } sub get_feed($) { my $feed = shift; - my $file = "./feeds/$feed.index"; - clear_packages(); + if (!defined($feed_cache{$feed})) { + my $file = "./feeds/$feed.index"; - -f $file or do { - print "Ignoring feed '$feed' - index missing\n"; - return; - }; - parse_package_metadata($file) or return; - return { %package }; + clear_packages(); + -f $file or do { + print "Ignoring feed '$feed' - index missing\n"; + return; + }; + parse_package_metadata($file) or return; + $feed_cache{$feed} = [ { %package }, { %srcpackage } ]; + } + + $feed_package = $feed_cache{$feed}->[0]; + $feed_src = $feed_cache{$feed}->[1]; + return $feed_cache{$feed}->[0]; } sub get_installed() { @@ -169,14 +198,15 @@ sub search_feed { return unless @substr > 0; get_feed($feed); - foreach my $name (sort { lc($a) cmp lc($b) } keys %package) { - my $pkg = $package{$name}; + foreach my $name (sort { lc($a) cmp lc($b) } keys %$feed_package) { + my $pkg = $feed_package->{$name}; my $substr; my $pkgmatch = 1; + next if $pkg->{vdepends}; foreach my $substr (@substr) { my $match; - foreach my $key (qw(name title description)) { + foreach my $key (qw(name title description src)) { $pkg->{$key} and $substr and $pkg->{$key} =~ m/$substr/i and $match = 1; } $match or undef $pkgmatch; @@ -205,8 +235,9 @@ sub list_feed { my $feed = shift; get_feed($feed); - foreach my $name (sort { lc($a) cmp lc($b) } keys %package) { - my $pkg = $package{$name}; + foreach my $name (sort { lc($a) cmp lc($b) } keys %$feed_package) { + my $pkg = $feed_package->{$name}; + next if $pkg->{vdepends}; if($pkg->{name}) { printf "\%-32s\t\%s\n", $pkg->{name}, $pkg->{title}; } @@ -259,6 +290,10 @@ my %install_method = ( 'src-cpy' => \&install_generic, 'src-link' => \&install_generic, 'src-git' => \&install_generic, + 'src-gitsvn' => \&install_generic, + 'src-bzr' => \&install_generic, + 'src-hg' => \&install_generic, + 'src-darcs' => \&install_generic, ); my %feed; @@ -284,10 +319,13 @@ sub install_package { $feed or do { $installed{$name} and return 0; # 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"; + $feed_src->{$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; }; + # switch to the metadata for the selected feed + get_feed($feed->[1]); + my $pkg = $feed{$feed->[1]}->{$name} or return 1; $pkg->{name} or do { $installed{$name} and return 0; @@ -318,12 +356,13 @@ sub install_package { return 1; }; - # install all dependencies - foreach my $vpkg (@{$srcpackage{$src}}, $pkg) { - foreach my $dep (@{$vpkg->{depends}}, @{$vpkg->{builddepends}}) { + # install all dependencies referenced from the source package + foreach my $vpkg (@{$feed_src->{$src}}) { + foreach my $dep (@{$vpkg->{depends}}, @{$vpkg->{builddepends}}, @{$vpkg->{"builddepends/host"}}) { next if $dep =~ /@/; $dep =~ s/^\+//; $dep =~ s/^.+://; + $dep =~ s/\/.+$//; next unless $dep; install_package($feed, $dep) == 0 or $ret = 1; } @@ -339,7 +378,7 @@ sub refresh_config { system("rm -f tmp/.packageinfo"); # refresh the config - if ($default) { + if ($default) { system("$mk oldconfig CONFDEFAULT=\"$default\" Config.in >/dev/null 2>/dev/null"); } else { system("$mk defconfig Config.in >/dev/null 2>/dev/null"); @@ -374,10 +413,12 @@ sub install { if (!defined($opts{p}) or $opts{p} eq $f->[1]) { printf "Installing all packages from feed %s.\n", $f->[1]; get_feed($f->[1]); - foreach my $name (sort { lc($a) cmp lc($b) } keys %package) { - my $p = $package{$name}; + foreach my $name (sort { lc($a) cmp lc($b) } keys %$feed_package) { + my $p = $feed_package->{$name}; + next if $p->{vdepends}; if( $p->{name} ) { install_package($feed, $p->{name}) == 0 or $ret = 1; + get_feed($f->[1]); } } } @@ -435,13 +476,6 @@ sub uninstall { return 0; } -my %update_method = ( - 'src-svn' => \&update_svn, - 'src-cpy' => \&update_cpy, - 'src-link' => \&update_link, - 'src-git' => \&update_git -); - sub update_feed($$$$) { my $type=shift; @@ -461,7 +495,7 @@ sub update_feed($$$$) my $failed = 1; foreach my $feedsrc (@$src) { warn "Updating feed '$name' from '$feedsrc' ...\n"; - next unless &{$update_method{$type}}($name, $feedsrc, $force_relocate) == 0; + next unless update_feed_via($type, $name, $feedsrc, $force_relocate) == 0; $failed = 0; last; } @@ -551,7 +585,7 @@ Commands: update -a|: Update packages and lists of feeds in feeds.conf . Options: - -a : Update all feeds listed within feeds.conf. Otherwise the spezified feeds will be updated. + -a : Update all feeds listed within feeds.conf. Otherwise the specified feeds will be updated. -i : Recreate the index only. No feed update from repository is performed. clean: Remove downloaded/generated files.