--- toast 2003/08/31 20:18:38 1.187 +++ toast 2003/08/31 23:03:34 1.188 @@ -160,6 +160,7 @@ "postarmprog" => superuser ? "/sbin/ldconfig" : "", "verbose" => true, "autofind" => true, + "autochange" => true, "autorename" => true, "autoclean" => true, "autopurge" => false, @@ -1369,6 +1370,18 @@ return map { chomp; $_ } readfile($urlfile); } +sub setpkgurls($$@) +{ + my($name, $version, @urls) = @_; + error unless defined($name); + error unless defined($version); + error unless @urls; + + my($verdir) = pkgpath($name, $version); + my($urlfile) = path($verdir, urlfile); + writefile($urlfile, map("$_\n", @urls)); +} + ############################################################################## sub add(@) @@ -1390,7 +1403,6 @@ my($goodver) = defined($version); $version = "unknown" unless $goodver; my($verdir) = pkgpath($name, $version); - my($urlfile) = path($verdir, urlfile); if($goodver) { @@ -1435,7 +1447,7 @@ announce("mkdir", $verdir); } - writefile($urlfile, map { "$_\n" } @urls); + setpkgurls($name, $version, @urls); ($name, $version); } @@ -1482,7 +1494,7 @@ } close(FILE) || error("close $file: $!"); - return true unless $redir; + return $url unless $redir; rm($file); $url = $redir; @@ -1492,11 +1504,32 @@ error("too many links: $url"); } -sub autorenamepkg($$) +sub renamepkg($$$$) { - my($name, $version) = @_; + my($oldname, $oldversion, $newname, $newversion) = @_; - my($namedir) = pkgpath($name); + my($oldnamedir) = pkgpath($oldname); + my($newnamedir) = pkgpath($newname); + my($oldverdir) = pkgpath($oldname, $oldversion); + my($newverdir) = pkgpath($newname, $newversion); + + optmd($newnamedir); + mv($oldverdir, $newverdir); + rmdir($oldnamedir) && announce("rmdir", $oldnamedir); + return ($newname, $newversion); +} + +sub autorenamepkg($$@) +{ + my($name, $version, @urls) = @_; + + if(@urls) + { + my($newname, $newversion) = guessnv(@urls); + return renamepkg($name, $version, $newname, $newversion) + if defined($newname) && defined($newversion); + } + my($verdir) = pkgpath($name, $version); my($archivedir) = path($verdir, archivedir); @@ -1507,15 +1540,8 @@ next unless defined($extractname); my($newname, $newversion) = guessnv($extractname); - if(defined($newname) && defined($newversion)) - { - my($newnamedir) = pkgpath($newname); - my($newverdir) = pkgpath($newname, $newversion); - optmd($newnamedir); - mv($verdir, $newverdir); - rmdir($namedir) && announce("rmdir", $namedir); - return ($newname, $newversion); - } + return renamepkg($name, $version, $newname, $newversion) + if defined($newname) && defined($newversion); } ($name, $version); @@ -1539,9 +1565,22 @@ my($tempdir) = addtmp($realdir); optmd($tempdir); - smartgeturl($_, $tempdir) foreach @urls; + + my($changed) = false; + for(@urls) + { + my($newurl) = smartgeturl($_, $tempdir); + if($newurl ne $_ && autochange) + { + $_ = $newurl; + $changed = true; + } + } + setpkgurls($name, $version, @urls) if $changed; + mv($tempdir, $realdir); - ($name, $version) = autorenamepkg($name, $version) if $autorename; + ($name, $version) = autorenamepkg($name, $version, $changed ? @urls : ()) + if $autorename; ($name, $version); } @@ -2918,6 +2957,20 @@ ############################################################################## +sub change(@) +{ + my($name, $version, $build, @urls) = @_; + error unless defined($name); + error unless defined($version); + error if defined($build); + error unless @urls; + + setpkgurls($name, $version, @urls); + ($name, $version); +} + +############################################################################## + BEGIN { my($checkresult); @@ -3383,6 +3436,16 @@ @_; } +sub requireurls(@) +{ + for(@_) + { + my($name, $version, $build, @urls) = @$_; + @urls || error("filename or URL expected for " . + pkgname($name, $version, $build)); + } +} + sub uselatestversion(@) { my(@result); @@ -3423,6 +3486,7 @@ sub parse_purge(@) { rejectempty(rejectmissing(rejectbuilds(parse(@_)))); } sub parse_remove(@) { rejectempty(rejectmissing(parse(@_))); } sub parse_rename(@); +sub parse_change(@) { requireurls(rejectempty(rejectmissing(uselatestversion(rejectbuilds(parse(@_)))))); } sub parse_status(@) { allowempty(rejectmissing(parse(@_))); } sub parse_check(@) { rejectall(@_); } sub parse_help(@) { allowall(@_); } @@ -3844,6 +3908,27 @@ and the B<autodisarm> option is disabled, B<toast remove> reports an error and nothing is removed; otherwise B<toast disarm> is implied. +=item S<B<toast rename> I<PACKAGE> ... I<NEWNAME>> + +Renames an existing package or set of packages. The package or packages +must already exist. I<NEWNAME> uses the same syntax used to refer to +an existing package or build, except that the destination package must +not already exist and must contain the same number of slash characters as +I<PACKAGE>. Attempting to rename an armed package causes B<toast rename> +to report an error. Otherwise, renaming a package that contains builds +should be OK, though it could conceivably break ill-behaved packages. +This command can also be used to renumber builds. + +=item S<B<toast change> I<PACKAGE> ...> + +Changes the stored URLs for an existing package or packages. Use with +caution! Each package must already exist, and at least one URL must be +given explicitly for each. The URL or URLs previously stored for each +package by B<toast add> will be discarded and replaced by the given URL +or URLs. No further action is taken; in particular, neither B<toast get> +nor B<toast purge> is implied. Note that it is often simpler and safer to +remove and then re-create a package than it would be to use this command. + =item S<B<toast status> [ I<BUILD> | I<PACKAGE> ] ...> Displays information about packages and builds. If invoked without @@ -3857,17 +3942,6 @@ be marked C<(not clean)> if intermediate files created by B<toast build> have not yet been removed by C<toast clean>. -=item S<B<toast rename> I<PACKAGE> ... I<NEWNAME>> - -Renames an existing package or set of packages. The package or packages -must already exist. I<NEWNAME> uses the same syntax used to refer to -an existing package or build, except that the destination package must -not already exist and must contain the same number of slash characters as -I<PACKAGE>. Attempting to rename an armed package causes B<toast rename> -to report an error. Otherwise, renaming a package that contains builds -should be OK, though it could conceivably break ill-behaved packages. -This command can also be used to renumber builds. - =item S<B<toast help> [ I<TOPIC> ] ...> Summarizes usage information from the B<toast> man page. If invoked @@ -4035,19 +4109,35 @@ given either, the latest version listed on freshmeat.net will be used. Default: enabled. +=item S<B<--autochange> | B<--noautochange>> + +When B<autochange> is enabled, B<toast get> may replace the URLs +stored by B<toast add> with the actual URLs of the files it downloaded. +This matters if an URL given on the command line points to an HTML page or +FTP directory rather than to an actual archive to be extracted and built. +In order to ensure consistent results, it is often desirable to store the +more specific URLs, especially if B<autopurge> is enabled. If this option +is disabled, B<toast get> will still follow links in the usual way, but +stored URLs will be left untouched, and future invocations of B<toast get> +may end up downloading different files for the same package if new files +or links have since been added to a page or directory. Default: enabled. + =item S<B<--autorename> | B<--noautorename>> -When B<autorename> is enabled, B<toast get> may try to use the contents of -the files it downloads to attempt to guess a new name for any implicitly -added package for which no name and/or version number was specified on -the command line or could be guessed from the URLs given. If this method -results in a new name being guessed, the package is renamed automatically -as if by B<toast rename>, and any further processing continues under -the new name. If B<autorename> is disabled, packages with unguessed -or partially guessed names always keep the unique names automatically -assigned by B<toast add> based on URLs alone (version number will be -C<unknown> optionally followed by a serial number for uniqueness; name -may have been guessed or may also be C<unknown>). Default: enabled. +When B<autorename> is enabled, B<toast get> may try to use information +gained after downloading files to attempt to guess a new name for any +implicitly added package for which no name and/or version number was +specified on the command line or could be guessed from the URLs given. +If B<autochange> is also enabled, new URLs are first used to try to +guess a new name; if this fails, the contents of the downloaded files +are examined. If either method results in a new name being guessed, +the package is renamed automatically as if by B<toast rename>, and +any further processing continues under the new name. If B<autorename> +is disabled, packages with unguessed or partially guessed names always +keep the unique names automatically assigned by B<toast add> based on +URLs alone (version number will be C<unknown> optionally followed by +a serial number for uniqueness; name may have been guessed or may also +be C<unknown>). Default: enabled. =item S<B<--autoclean> | B<--noautoclean>>