summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <david@kalnischkies.de>2024-01-03 13:53:09 +0000
committerDavid Kalnischkies <david@kalnischkies.de>2024-01-03 13:53:09 +0000
commitc82f96210eb62c92d31ded7073f4cf5371cc9485 (patch)
treeb0ba92b152c2dae076a8f0d811af287084878a89
parentc555d8f1ae31d1f511bf811640423231b75a8e13 (diff)
Improve and test distclean implementation
The implementation as-is as various smaller/esoteric bugs and inconsistencies like apt-get not supporting them, the option -s being supported in code but not accepted on the command line, the regex not escaping the dot before the file extension and exposing more implementation details to public headers than we actually need. Also comes with a small test case to ensure it actually works. References: bd7c126e3fb1b94e76e0e632c657cea854586844
-rw-r--r--apt-pkg/acquire.cc24
-rw-r--r--apt-pkg/acquire.h17
-rw-r--r--apt-private/private-cmndline.cc5
-rw-r--r--apt-private/private-download.cc40
-rw-r--r--apt-private/private-download.h1
-rw-r--r--cmdline/apt-get.cc2
-rwxr-xr-xtest/integration/test-apt-get-clean40
7 files changed, 72 insertions, 57 deletions
diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc
index 727880e71..1cb55bf14 100644
--- a/apt-pkg/acquire.cc
+++ b/apt-pkg/acquire.cc
@@ -826,11 +826,11 @@ pkgAcquire::Worker *pkgAcquire::WorkerStep(Worker *I)
return I->NextAcquire;
}
/*}}}*/
-// Acquire::CleanDir - Cleans a directory /*{{{*/
+// CleanDir - Cleans a directory /*{{{*/
// ---------------------------------------------------------------------
/* This is a bit simplistic, it looks at every file in the dir and sees
if it matches the predicate or not. */
-bool pkgAcquire::CleanDir(string Dir, std::function<bool(char const*)> const &Keep, char const * const Caller)
+static bool CleanDir(std::string const &Dir, std::function<bool(std::string_view)> const &Keep, char const * const Caller)
{
// non-existing directories are by definition clean…
if (DirectoryExists(Dir) == false)
@@ -855,7 +855,7 @@ bool pkgAcquire::CleanDir(string Dir, std::function<bool(char const*)> const &Ke
strcmp(E->d_name, "lost+found") == 0 ||
strcmp(E->d_name, ".") == 0 ||
strcmp(E->d_name, "..") == 0 ||
- Keep(E->d_name) == true)
+ Keep(E->d_name))
continue;
RemoveFileAt(Caller, dirfd, E->d_name);
}
@@ -867,12 +867,12 @@ bool pkgAcquire::CleanDir(string Dir, std::function<bool(char const*)> const &Ke
// ---------------------------------------------------------------------
/* This is a bit simplistic, it looks at every file in the dir and sees
if it is part of the download set. */
-bool pkgAcquire::Clean(string Dir)
+bool pkgAcquire::Clean(std::string Dir)
{
return CleanDir(
Dir,
// Look in the get list and if found then keep
- [this](char const *FName) {
+ [this](std::string_view const FName) {
return std::any_of(Items.cbegin(), Items.cend(),
[FName](pkgAcquire::Item const * const I) {
return flNotDir(I->DestFile) == FName;
@@ -882,21 +882,19 @@ bool pkgAcquire::Clean(string Dir)
);
}
/*}}}*/
-// Acquire::CleanLists - Cleans a directory of list files /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-bool pkgAcquire::CleanLists(string Dir)
+// Acquire::CleanLists - Cleans a directory of list files /*{{{*/
+bool pkgAcquire::CleanLists(std::string const &Dir)
{
+ std::regex const KeepPattern(".*_(Release|Release\\.gpg|InRelease)");
return CleanDir(
Dir,
- [](char const *FName) noexcept {
- static const std::regex KeepPattern(".*_(Release|Release.gpg|InRelease)");
- return std::regex_match(FName, KeepPattern);
+ [&KeepPattern](std::string_view const FName) noexcept {
+ return std::regex_match(FName.begin(), FName.end(), KeepPattern);
},
"pkgAcquire::CleanLists"
);
}
- /*}}}*/
+ /*}}}*/
// Acquire::TotalNeeded - Number of bytes to fetch /*{{{*/
// ---------------------------------------------------------------------
/* This is the total number of bytes needed */
diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h
index a5f7a40c8..f7c40aa5f 100644
--- a/apt-pkg/acquire.h
+++ b/apt-pkg/acquire.h
@@ -70,7 +70,6 @@
#include <apt-pkg/weakptr.h>
#include <chrono>
-#include <functional>
#include <string>
#include <vector>
@@ -338,7 +337,7 @@ class APT_PUBLIC pkgAcquire
*
* \return \b true if the directory exists and is readable.
*/
- bool CleanLists(std::string Dir);
+ bool CleanLists(std::string const &Dir);
/** \return the total size in bytes of all the items included in
* this download.
@@ -381,20 +380,6 @@ class APT_PUBLIC pkgAcquire
private:
APT_HIDDEN void Initialize();
-
- /** Delete each entry in the given directory whose name does \em not match
- * a criterion.
- *
- * \param Dir The directory to be cleaned.
- *
- * \param KeepP A predicate telling to keep the named file; if it is
- * non-empty and returns true, the file is kept.
- *
- * \param Caller Log name of the caller.
- *
- * \return \b true if the directory exists and is readable.
- */
- APT_HIDDEN static bool CleanDir(std::string Dir, std::function<bool(char const*)> const &KeepP, char const * const Caller);
};
/** \brief Represents a single download source from which an item
diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc
index 980d00530..9e3938407 100644
--- a/apt-private/private-cmndline.cc
+++ b/apt-private/private-cmndline.cc
@@ -242,14 +242,15 @@ static bool addArgumentsAPTGet(std::vector<CommandLine::Args> &Args, char const
addArg(0,"format","APT::Get::IndexTargets::Format", CommandLine::HasArg);
addArg(0,"release-info","APT::Get::IndexTargets::ReleaseInfo", 0);
}
- else if (CmdMatches("clean", "autoclean", "auto-clean", "check", "download", "changelog") ||
+ else if (CmdMatches("clean", "autoclean", "auto-clean", "distclean", "dist-clean", "check", "download", "changelog") ||
CmdMatches("markauto", "unmarkauto")) // deprecated commands
;
else if (CmdMatches("moo"))
addArg(0, "color", "APT::Moo::Color", 0);
if (CmdMatches("install", "reinstall", "remove", "purge", "upgrade", "dist-upgrade",
- "dselect-upgrade", "autoremove", "auto-remove", "autopurge", "clean", "autoclean", "auto-clean", "check",
+ "dselect-upgrade", "autoremove", "auto-remove", "autopurge", "check",
+ "clean", "autoclean", "auto-clean", "distclean", "dist-clean",
"build-dep", "satisfy", "full-upgrade", "source"))
{
addArg('s', "simulate", "APT::Get::Simulate", 0);
diff --git a/apt-private/private-download.cc b/apt-private/private-download.cc
index b271ec03f..d95c8ef43 100644
--- a/apt-private/private-download.cc
+++ b/apt-private/private-download.cc
@@ -303,20 +303,8 @@ bool DoChangelog(CommandLine &CmdL)
return true;
}
/*}}}*/
-
-// DoClean - Remove download archives /*{{{*/
-bool DoClean(CommandLine &)
-{
- return DoDistClean(false);
-}
- /*}}}*/
-// DoDistClean - Remove download archives and lists /*{{{*/
-bool DoDistClean(CommandLine &)
-{
- return DoDistClean(true);
-}
-// DoDistClean - the worker
-bool DoDistClean(bool ListsToo)
+// DoClean & DoDistClean - Remove download archives and/or lists /*{{{*/
+static bool CleanDownloadDirectories(bool const ListsToo)
{
std::string const archivedir = _config->FindDir("Dir::Cache::archives");
std::string const listsdir = _config->FindDir("Dir::state::lists");
@@ -325,22 +313,24 @@ bool DoDistClean(bool ListsToo)
{
std::string const pkgcache = _config->FindFile("Dir::cache::pkgcache");
std::string const srcpkgcache = _config->FindFile("Dir::cache::srcpkgcache");
- std::cout << "Del " << archivedir << "* " << archivedir << "partial/*"<< std::endl
- << "Del " << listsdir << "partial/*" << (ListsToo ? " *_{Packages,Sources}{,.diff_Index}" : "") << std::endl
- << "Del " << pkgcache << " " << srcpkgcache << std::endl;
+ std::cout << "Del " << archivedir << "* " << archivedir << "partial/*" << std::endl
+ << "Del " << listsdir << "partial/*" << std::endl;
+ if (ListsToo)
+ std::cout << "Del " << listsdir << "*_{Packages,Sources,Translation-*}{,.diff_Index}" << std::endl;
+ std::cout << "Del " << pkgcache << " " << srcpkgcache << std::endl;
return true;
}
pkgAcquire Fetcher;
- if (archivedir.empty() == false && FileExists(archivedir) == true &&
- Fetcher.GetLock(archivedir) == true)
+ if (not archivedir.empty() && FileExists(archivedir) &&
+ Fetcher.GetLock(archivedir))
{
Fetcher.Clean(archivedir);
Fetcher.Clean(archivedir + "partial/");
}
- if (listsdir.empty() == false && FileExists(listsdir) == true &&
- Fetcher.GetLock(listsdir) == true)
+ if (not listsdir.empty() && FileExists(listsdir) &&
+ Fetcher.GetLock(listsdir))
{
Fetcher.Clean(listsdir + "partial/");
if (ListsToo)
@@ -351,6 +341,14 @@ bool DoDistClean(bool ListsToo)
return true;
}
+bool DoClean(CommandLine &)
+{
+ return CleanDownloadDirectories(false);
+}
+bool DoDistClean(CommandLine &)
+{
+ return CleanDownloadDirectories(true);
+}
/*}}}*/
// DoAutoClean - Smartly remove downloaded archives /*{{{*/
// ---------------------------------------------------------------------
diff --git a/apt-private/private-download.h b/apt-private/private-download.h
index 918828241..e13ade1c6 100644
--- a/apt-private/private-download.h
+++ b/apt-private/private-download.h
@@ -34,7 +34,6 @@ APT_PUBLIC bool DoChangelog(CommandLine &CmdL);
APT_PUBLIC bool DoClean(CommandLine &CmdL);
APT_PUBLIC bool DoDistClean(CommandLine &CmdL);
-bool DoDistClean(bool ListsToo);
APT_PUBLIC bool DoAutoClean(CommandLine &CmdL);
#endif
diff --git a/cmdline/apt-get.cc b/cmdline/apt-get.cc
index 95c4a85ab..d41e0f243 100644
--- a/cmdline/apt-get.cc
+++ b/cmdline/apt-get.cc
@@ -424,6 +424,8 @@ static std::vector<aptDispatchWithHelp> GetCommands() /*{{{*/
{"clean", &DoClean, _("Erase downloaded archive files")},
{"autoclean", &DoAutoClean, _("Erase old downloaded archive files")},
{"auto-clean", &DoAutoClean, nullptr},
+ {"distclean", &DoDistClean, nullptr},
+ {"dist-clean", &DoDistClean, nullptr},
{"check", &DoCheck, _("Verify that there are no broken dependencies")},
{"source", &DoSource, _("Download source archives")},
{"download", &DoDownload, _("Download the binary package into the current directory")},
diff --git a/test/integration/test-apt-get-clean b/test/integration/test-apt-get-clean
index d05073218..32dd3e852 100755
--- a/test/integration/test-apt-get-clean
+++ b/test/integration/test-apt-get-clean
@@ -13,13 +13,27 @@ insertpackage 'experimental' 'foo' 'all' '1:1'
insertinstalledpackage 'foo' 'all' '3'
setupaptarchive --no-update
+mkdir -p rootdir/var/lib/apt/lists/partial
+testsuccess test -d rootdir/var/lib/apt/lists/partial
+
+# nothing to do always works (part 1)
+for cmd in aptget apt; do
+ for sub in distclean dist-clean; do
+ testsuccess $cmd $sub
+ testsuccess $cmd $sub -s
+ done
+done
+testsuccess test -d rootdir/var/lib/apt/lists/partial
-mkdir -p rootdir/var/lib/apt/lists/lost+found
testsuccess apt update
-# nothing to do always works
-testsuccess aptget clean
-testsuccess aptget clean -s
+# nothing to do always works (part 2)
+for cmd in aptget apt; do
+ for sub in clean autoclean auto-clean; do
+ testsuccess $cmd $sub
+ testsuccess $cmd $sub -s
+ done
+done
# generate some dirt and clean it up
generatedirt() {
@@ -63,6 +77,23 @@ if [ "$(id -u)" != '0' ]; then
chmod 644 rootdir/var/cache/apt/archives/lock
fi
+msgmsg 'distclean'
+listcurrentlistsdirectory > aptdistclean.before
+testsuccessequal '3' grep -c -e 'Release$' aptdistclean.before
+testsuccess grep -e 'Packages$' -e 'Sources$' -e 'Translation-*$' aptdistclean.before
+testsuccess apt distclean
+listcurrentlistsdirectory > aptdistclean.after
+testfailure cmp aptdistclean.before aptdistclean.after
+testsuccessequal '3' grep -c -e 'Release$' aptdistclean.after
+testfailureequal '0' grep -c -e 'Packages$' -e 'Sources$' -e 'Translation-*$' aptdistclean.after
+for dirt in Packages.gz Sources.xz Release2gpg Release_Packages; do
+ touch "rootdir/var/lib/apt/lists/_foo_bar_$dirt"
+done
+listcurrentlistsdirectory > aptdistclean.before
+testsuccess apt distclean
+listcurrentlistsdirectory > aptdistclean.cleaned
+testsuccess cmp aptdistclean.after aptdistclean.cleaned
+
directorygone() {
rm -rf "$1"
testsuccess apt autoclean
@@ -86,3 +117,4 @@ directorygone 'rootdir/var/lib/apt/lists'
msgmsg 'apt directory missing'
directorygone 'rootdir/var/cache/apt'
directorygone 'rootdir/var/lib/apt'
+