summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/statechanges.cc88
-rw-r--r--apt-pkg/statechanges.h18
-rw-r--r--apt-private/private-cmndline.cc28
-rw-r--r--cmdline/apt-mark.cc102
-rw-r--r--doc/apt-mark.8.xml110
-rw-r--r--doc/apt-verbatim.ent41
-rwxr-xr-xtest/integration/test-apt-mark40
7 files changed, 297 insertions, 130 deletions
diff --git a/apt-pkg/statechanges.cc b/apt-pkg/statechanges.cc
index a20319d2d..dc446a665 100644
--- a/apt-pkg/statechanges.cc
+++ b/apt-pkg/statechanges.cc
@@ -14,46 +14,62 @@ class StateChanges::Private
{
public:
APT::VersionVector hold;
+ APT::VersionVector unhold;
APT::VersionVector install;
+ APT::VersionVector deinstall;
+ APT::VersionVector purge;
APT::VersionVector error;
};
-void StateChanges::Hold(pkgCache::VerIterator const &Ver)
-{
- d->hold.push_back(Ver);
-}
-APT::VersionVector& StateChanges::Hold()
-{
- return d->hold;
-}
-void StateChanges::Unhold(pkgCache::VerIterator const &Ver)
-{
- d->install.push_back(Ver);
-}
-APT::VersionVector& StateChanges::Unhold()
-{
- return d->install;
+#define APT_GETTERSETTER(Name, Container) \
+void StateChanges::Name(pkgCache::VerIterator const &Ver) \
+{ \
+ Container.push_back(Ver); \
+}\
+APT::VersionVector& StateChanges::Name() \
+{ \
+ return Container; \
}
+APT_GETTERSETTER(Hold, d->hold)
+APT_GETTERSETTER(Unhold, d->unhold)
+APT_GETTERSETTER(Install, d->install)
+APT_GETTERSETTER(Remove, d->deinstall)
+APT_GETTERSETTER(Purge, d->purge)
+#undef APT_GETTERSETTER
APT::VersionVector& StateChanges::Error()
{
return d->error;
}
-void StateChanges::Discard()
+void StateChanges::clear()
{
d->hold.clear();
+ d->unhold.clear();
d->install.clear();
+ d->deinstall.clear();
+ d->purge.clear();
d->error.clear();
}
+bool StateChanges::empty() const
+{
+ return d->hold.empty() &&
+ d->unhold.empty() &&
+ d->install.empty() &&
+ d->deinstall.empty() &&
+ d->purge.empty() &&
+ d->error.empty();
+}
+
bool StateChanges::Save(bool const DiscardOutput)
{
d->error.clear();
- if (d->hold.empty() && d->install.empty())
+ if (d->hold.empty() && d->unhold.empty() && d->install.empty() && d->deinstall.empty() && d->purge.empty())
return true;
std::vector<std::string> Args = debSystem::GetDpkgBaseCommand();
// ensure dpkg knows about the package so that it keeps the status we set
+ if (d->hold.empty() == false || d->install.empty() == false)
{
APT::VersionVector makeDpkgAvailable;
auto const notInstalled = [](pkgCache::VerIterator const &V) { return V.ParentPkg()->CurrentVer == 0; };
@@ -94,6 +110,24 @@ bool StateChanges::Save(bool const DiscardOutput)
else
fprintf(dpkg, "%s:%s %s\n", P.Name(), V.Arch(), state.c_str());
};
+ for (auto const &V: d->unhold)
+ {
+ if (V.ParentPkg()->CurrentVer != 0)
+ state = "install";
+ else
+ state = "deinstall";
+ dpkgName(V);
+ }
+ if (d->purge.empty() == false)
+ {
+ state = "purge";
+ std::for_each(d->purge.begin(), d->purge.end(), dpkgName);
+ }
+ if (d->deinstall.empty() == false)
+ {
+ state = "deinstall";
+ std::for_each(d->deinstall.begin(), d->deinstall.end(), dpkgName);
+ }
if (d->hold.empty() == false)
{
state = "hold";
@@ -108,16 +142,16 @@ bool StateChanges::Save(bool const DiscardOutput)
if (ExecWait(dpkgSelections, "dpkg --set-selections") == false)
{
- if (d->hold.empty())
- std::swap(d->install, d->error);
- else if (d->install.empty())
- std::swap(d->hold, d->error);
- else
- {
- std::swap(d->hold, d->error);
- std::move(d->install.begin(), d->install.end(), std::back_inserter(d->error));
- d->install.clear();
- }
+ std::move(d->purge.begin(), d->purge.end(), std::back_inserter(d->error));
+ d->purge.clear();
+ std::move(d->deinstall.begin(), d->deinstall.end(), std::back_inserter(d->error));
+ d->deinstall.clear();
+ std::move(d->hold.begin(), d->hold.end(), std::back_inserter(d->error));
+ d->hold.clear();
+ std::move(d->unhold.begin(), d->unhold.end(), std::back_inserter(d->error));
+ d->unhold.clear();
+ std::move(d->install.begin(), d->install.end(), std::back_inserter(d->error));
+ d->install.clear();
}
return d->error.empty();
}
diff --git a/apt-pkg/statechanges.h b/apt-pkg/statechanges.h
index fa60c5864..1eaf21a3a 100644
--- a/apt-pkg/statechanges.h
+++ b/apt-pkg/statechanges.h
@@ -14,14 +14,20 @@ class APT_PUBLIC StateChanges
{
public:
// getter/setter for the different states
- APT::VersionVector& Hold();
- void Hold(pkgCache::VerIterator const &Ver);
- APT::VersionVector& Unhold();
- void Unhold(pkgCache::VerIterator const &Ver);
+#define APT_GETTERSETTER(Name) \
+ APT::VersionVector& Name(); \
+ void Name(pkgCache::VerIterator const &Ver)
+ APT_GETTERSETTER(Hold);
+ APT_GETTERSETTER(Unhold);
+ APT_GETTERSETTER(Install);
+ APT_GETTERSETTER(Remove);
+ APT_GETTERSETTER(Purge);
APT::VersionVector& Error();
+#undef APT_GETTERSETTER
- // forgets all unsaved changes
- void Discard();
+ // operate on all containers at once
+ void clear();
+ bool empty() const;
/** commit the staged changes to the database(s).
*
diff --git a/apt-private/private-cmndline.cc b/apt-private/private-cmndline.cc
index 7190fe50b..5d6fd3c2e 100644
--- a/apt-private/private-cmndline.cc
+++ b/apt-private/private-cmndline.cc
@@ -227,19 +227,31 @@ static bool addArgumentsAPTGet(std::vector<CommandLine::Args> &Args, char const
static bool addArgumentsAPTMark(std::vector<CommandLine::Args> &Args, char const * const Cmd)/*{{{*/
{
if (CmdMatches("auto", "manual", "hold", "unhold", "showauto",
- "showmanual", "showhold", "showholds", "install",
+ "showmanual", "showhold", "showholds",
"markauto", "unmarkauto"))
+ {
+ addArg('f',"file","Dir::State::extended_states",CommandLine::HasArg);
+ }
+ else if (CmdMatches("install", "remove", "deinstall", "purge",
+ "showinstall", "showinstalls", "showremove", "showremoves",
+ "showdeinstall", "showdeinstalls", "showpurge", "showpurges"))
;
else
return false;
- addArg('v',"verbose","APT::MarkAuto::Verbose",0);
- addArg('s',"simulate","APT::Mark::Simulate",0);
- addArg('s',"just-print","APT::Mark::Simulate",0);
- addArg('s',"recon","APT::Mark::Simulate",0);
- addArg('s',"dry-run","APT::Mark::Simulate",0);
- addArg('s',"no-act","APT::Mark::Simulate",0);
- addArg('f',"file","Dir::State::extended_states",CommandLine::HasArg);
+ if (CmdMatches("markauto", "unmarkauto"))
+ {
+ addArg('v',"verbose","APT::MarkAuto::Verbose",0);
+ }
+
+ if (strncmp(Cmd, "show", strlen("show")) != 0)
+ {
+ addArg('s',"simulate","APT::Mark::Simulate",0);
+ addArg('s',"just-print","APT::Mark::Simulate",0);
+ addArg('s',"recon","APT::Mark::Simulate",0);
+ addArg('s',"dry-run","APT::Mark::Simulate",0);
+ addArg('s',"no-act","APT::Mark::Simulate",0);
+ }
return true;
}
diff --git a/cmdline/apt-mark.cc b/cmdline/apt-mark.cc
index 9d1d0863e..6080c7ea3 100644
--- a/cmdline/apt-mark.cc
+++ b/cmdline/apt-mark.cc
@@ -167,8 +167,8 @@ static bool ShowAuto(CommandLine &CmdL)
return true;
}
/*}}}*/
-/* DoHold - mark packages as hold by dpkg {{{*/
-static bool DoHold(CommandLine &CmdL)
+// DoSelection - wrapping around dpkg selections /*{{{*/
+static bool DoSelection(CommandLine &CmdL)
{
pkgCacheFile CacheFile;
pkgCache *Cache = CacheFile.GetPkgCache();
@@ -179,29 +179,39 @@ static bool DoHold(CommandLine &CmdL)
if (pkgset.empty() == true)
return _error->Error(_("No packages found"));
- bool const MarkHold = strcasecmp(CmdL.FileList[0],"hold") == 0;
-
- auto const part = std::stable_partition(pkgset.begin(), pkgset.end(),
- [](pkgCache::VerIterator const &V) { return V.ParentPkg()->SelectedState == pkgCache::State::Hold; });
-
- auto const doneBegin = MarkHold ? pkgset.begin() : part;
- auto const doneEnd = MarkHold ? part : pkgset.end();
-
- std::for_each(doneBegin, doneEnd, [&MarkHold](pkgCache::VerIterator const &V) {
- if (MarkHold == true)
- ioprintf(c1out, _("%s was already set on hold.\n"), V.ParentPkg().FullName(true).c_str());
- else
- ioprintf(c1out, _("%s was already not hold.\n"), V.ParentPkg().FullName(true).c_str());
- });
-
- if (doneBegin == pkgset.begin() && doneEnd == pkgset.end())
- return true;
-
- auto const changeBegin = MarkHold ? part : pkgset.begin();
- auto const changeEnd = MarkHold ? pkgset.end() : part;
-
APT::StateChanges marks;
- std::move(changeBegin, changeEnd, std::back_inserter(MarkHold ? marks.Hold() : marks.Unhold()));
+ if (strcasecmp(CmdL.FileList[0], "hold") == 0 || strcasecmp(CmdL.FileList[0], "unhold") == 0)
+ {
+ auto const part = std::stable_partition(pkgset.begin(), pkgset.end(),
+ [](pkgCache::VerIterator const &V) { return V.ParentPkg()->SelectedState == pkgCache::State::Hold; });
+
+ bool const MarkHold = strcasecmp(CmdL.FileList[0],"hold") == 0;
+ auto const doneBegin = MarkHold ? pkgset.begin() : part;
+ auto const doneEnd = MarkHold ? part : pkgset.end();
+ std::for_each(doneBegin, doneEnd, [&MarkHold](pkgCache::VerIterator const &V) {
+ if (MarkHold == true)
+ ioprintf(c1out, _("%s was already set on hold.\n"), V.ParentPkg().FullName(true).c_str());
+ else
+ ioprintf(c1out, _("%s was already not hold.\n"), V.ParentPkg().FullName(true).c_str());
+ });
+
+ if (doneBegin == pkgset.begin() && doneEnd == pkgset.end())
+ return true;
+
+ auto const changeBegin = MarkHold ? part : pkgset.begin();
+ auto const changeEnd = MarkHold ? pkgset.end() : part;
+ std::move(changeBegin, changeEnd, std::back_inserter(MarkHold ? marks.Hold() : marks.Unhold()));
+ }
+ else
+ {
+ // FIXME: Maybe show a message for unchanged states here as well?
+ if (strcasecmp(CmdL.FileList[0], "purge") == 0)
+ std::swap(marks.Purge(), pkgset);
+ else if (strcasecmp(CmdL.FileList[0], "deinstall") == 0 || strcasecmp(CmdL.FileList[0], "remove") == 0)
+ std::swap(marks.Remove(), pkgset);
+ else //if (strcasecmp(CmdL.FileList[0], "install") == 0)
+ std::swap(marks.Install(), pkgset);
+ }
pkgset.clear();
bool success = true;
@@ -211,30 +221,44 @@ static bool DoHold(CommandLine &CmdL)
if (success == false)
_error->Error(_("Executing dpkg failed. Are you root?"));
}
-
for (auto Ver : marks.Hold())
ioprintf(c1out,_("%s set on hold.\n"), Ver.ParentPkg().FullName(true).c_str());
for (auto Ver : marks.Unhold())
ioprintf(c1out,_("Canceled hold on %s.\n"), Ver.ParentPkg().FullName(true).c_str());
-
+ for (auto Ver : marks.Purge())
+ ioprintf(c1out,_("Selected %s for purge.\n"), Ver.ParentPkg().FullName(true).c_str());
+ for (auto Ver : marks.Remove())
+ ioprintf(c1out,_("Selected %s for removal.\n"), Ver.ParentPkg().FullName(true).c_str());
+ for (auto Ver : marks.Install())
+ ioprintf(c1out,_("Selected %s for installation.\n"), Ver.ParentPkg().FullName(true).c_str());
return success;
}
/*}}}*/
-/* ShowHold - show packages set on hold in dpkg status {{{*/
-static bool ShowHold(CommandLine &CmdL)
+static bool ShowSelection(CommandLine &CmdL) /*{{{*/
{
pkgCacheFile CacheFile;
pkgCache *Cache = CacheFile.GetPkgCache();
if (unlikely(Cache == NULL))
return false;
+ pkgCache::State::PkgSelectedState selector;
+ if (strncasecmp(CmdL.FileList[0], "showpurge", strlen("showpurge")) == 0)
+ selector = pkgCache::State::Purge;
+ else if (strncasecmp(CmdL.FileList[0], "showdeinstall", strlen("showdeinstall")) == 0 ||
+ strncasecmp(CmdL.FileList[0], "showremove", strlen("showremove")) == 0)
+ selector = pkgCache::State::DeInstall;
+ else if (strncasecmp(CmdL.FileList[0], "showhold", strlen("showhold")) == 0)
+ selector = pkgCache::State::Hold;
+ else //if (strcasecmp(CmdL.FileList[0], "showinstall", strlen("showinstall")) == 0)
+ selector = pkgCache::State::Install;
+
std::vector<string> packages;
if (CmdL.FileList[1] == 0)
{
packages.reserve(50); // how many holds are realistic? I hope just a few…
for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
- if (P->SelectedState == pkgCache::State::Hold)
+ if (P->SelectedState == selector)
packages.push_back(P.FullName(true));
}
else
@@ -243,7 +267,7 @@ static bool ShowHold(CommandLine &CmdL)
APT::PackageSet pkgset = APT::PackageSet::FromCommandLine(CacheFile, CmdL.FileList + 1, helper);
packages.reserve(pkgset.size());
for (APT::PackageSet::const_iterator P = pkgset.begin(); P != pkgset.end(); ++P)
- if (P->SelectedState == pkgCache::State::Hold)
+ if (P->SelectedState == selector)
packages.push_back(P.FullName(true));
}
@@ -295,15 +319,19 @@ int main(int argc,const char *argv[]) /*{{{*/
CommandLine::Dispatch Cmds[] = {{"help",&ShowHelp},
{"auto",&DoAuto},
{"manual",&DoAuto},
- {"hold",&DoHold},
- {"unhold",&DoHold},
+ {"hold",&DoSelection},
+ {"unhold",&DoSelection},
+ {"install",&DoSelection},
+ {"remove",&DoSelection}, // dpkg uses deinstall, but we use remove everywhere else
+ {"deinstall",&DoSelection},
+ {"purge",&DoSelection},
{"showauto",&ShowAuto},
{"showmanual",&ShowAuto},
- {"showhold",&ShowHold},
- // be nice and forgive the typo
- {"showholds",&ShowHold},
- // be nice and forgive it as it is technical right
- {"install",&DoHold},
+ {"showhold",&ShowSelection}, {"showholds",&ShowSelection},
+ {"showinstall",&ShowSelection}, {"showinstalls",&ShowSelection},
+ {"showdeinstall",&ShowSelection}, {"showdeinstalls",&ShowSelection},
+ {"showremove",&ShowSelection}, {"showremoves",&ShowSelection},
+ {"showpurge",&ShowSelection}, {"showpurges",&ShowSelection},
// obsolete commands for compatibility
{"markauto", &DoMarkAuto},
{"unmarkauto", &DoMarkAuto},
diff --git a/doc/apt-mark.8.xml b/doc/apt-mark.8.xml
index 94f24437e..8dd157a60 100644
--- a/doc/apt-mark.8.xml
+++ b/doc/apt-mark.8.xml
@@ -14,7 +14,7 @@
&apt-email;
&apt-product;
<!-- The last update date -->
- <date>2012-06-09T00:00:00Z</date>
+ <date>2015-09-25T00:00:00Z</date>
</refentryinfo>
<refmeta>
@@ -26,31 +26,37 @@
<!-- Man page title -->
<refnamediv>
<refname>apt-mark</refname>
- <refpurpose>mark/unmark a package as being automatically-installed</refpurpose>
+ <refpurpose>show, set and unset various settings for a package</refpurpose>
</refnamediv>
&synopsis-command-apt-mark;
<refsect1><title>Description</title>
- <para><command>apt-mark</command> will change whether a package has
- been marked as being automatically installed.
+ <para><command>apt-mark</command> can be used as a unified frontend to set
+ various settings for a package like marking a package as being
+ automatically/manually installed or changing <command>dpkg</command>
+ selections such as hold, install, deinstall and purge which are respected
+ e.g. by <command>apt-get dselect-upgrade</command> or <command>aptitude</command>.
</para>
+ </refsect1><refsect1><title>Automatically and manually installed packages</title>
<para>
When you request that a package is installed, and as a result
other packages are installed to satisfy its dependencies, the
- dependencies are marked as being automatically installed. Once
- these automatically installed packages are no longer depended on
- by any manually installed packages, they will be removed by e.g.
- <command>apt-get</command> or <command>aptitude</command>.
+ dependencies are marked as being automatically installed, while
+ package you installed explicitely is marked as manually installed.
+ Once a automatically installed package is no longer depended on
+ by any manually installed package it is considered no longer needed
+ and e.g. <command>apt-get</command> or <command>aptitude</command>
+ will at least suggest removing them.
</para>
- <variablelist>
+ <variablelist>
<varlistentry><term><option>auto</option></term>
<listitem><para><literal>auto</literal> is used to mark a
package as being automatically installed, which will cause the
package to be removed when no more manually installed packages
depend on this package.
</para></listitem>
- </varlistentry>
+ </varlistentry>
<varlistentry><term><option>manual</option></term>
<listitem><para><literal>manual</literal> is used to mark a
@@ -58,23 +64,7 @@
package from being automatically removed if no other packages
depend on it.
</para></listitem>
- </varlistentry>
-
- <varlistentry><term><option>hold</option></term>
- <listitem><para><literal>hold</literal> is used to mark a
- package as held back, which will prevent the package from being
- automatically installed, upgraded or removed.
- The command is only a wrapper around <command>dpkg --set-selections</command>
- and the state is therefore maintained by &dpkg; and not affected
- by the <option>--file</option> option.
- </para></listitem>
- </varlistentry>
-
- <varlistentry><term><option>unhold</option></term>
- <listitem><para><literal>unhold</literal> is used to cancel a
- previously set hold on a package to allow all actions again.
- </para></listitem>
- </varlistentry>
+ </varlistentry>
<varlistentry><term><option>showauto</option></term>
<listitem><para><literal>showauto</literal> is used to print a
@@ -82,38 +72,66 @@
All automatically installed packages will be listed if no package is given.
If packages are given only those which are automatically installed will be shown.
</para></listitem>
- </varlistentry>
+ </varlistentry>
<varlistentry><term><option>showmanual</option></term>
<listitem><para><literal>showmanual</literal> can be used in
the same way as <literal>showauto</literal> except that it will print
a list of manually installed packages instead.
</para></listitem>
+ </varlistentry>
+ </variablelist>
+
+ <refsect2><title>Options</title>
+ <variablelist>
+ <varlistentry>
+ <term><option>-f=&synopsis-param-filename;</option></term>
+ <term><option>--file=&synopsis-param-filename;</option></term>
+ <listitem><para>
+ Read/Write package stats from the filename given with the parameter
+ &synopsis-param-filename; instead of from the default location, which
+ is <filename>extended_status</filename> in the directory defined
+ by the Configuration Item: <literal>Dir::State</literal>.
+ </para></listitem>
</varlistentry>
+ </variablelist>
+ </refsect2>
- <varlistentry><term><option>showhold</option></term>
- <listitem><para><literal>showhold</literal> is used to print a list
- of packages on hold in the same way as for the other show commands.
+ </refsect1><refsect1><title>Prevent changes for a package</title>
+ <variablelist>
+ <varlistentry><term><option>hold</option></term>
+ <listitem><para><literal>hold</literal> is used to mark a
+ package as held back, which will prevent the package from being
+ automatically installed, upgraded or removed.
</para></listitem>
- </varlistentry>
+ </varlistentry>
+ <varlistentry><term><option>unhold</option></term>
+ <listitem><para><literal>unhold</literal> is used to cancel a
+ previously set hold on a package to allow all actions again.
+ </para></listitem>
+ </varlistentry>
- </variablelist>
- </refsect1>
-
- <refsect1><title>options</title>
-
- <variablelist>
- <varlistentry>
- <term><option>-f=&synopsis-param-filename;</option></term>
- <term><option>--file=&synopsis-param-filename;</option></term>
- <listitem><para>
- Read/Write package stats from the filename given with the parameter
- &synopsis-param-filename; instead of from the default location, which
- is <filename>extended_status</filename> in the directory defined
- by the Configuration Item: <literal>Dir::State</literal>.</para></listitem>
+ <varlistentry><term><option>showhold</option></term>
+ <listitem><para><literal>showhold</literal> is used to print a list
+ of packages on hold in the same way as for the other show commands.
+ </para></listitem>
</varlistentry>
+ </variablelist>
+ </refsect1><refsect1><title>Shedule packages for install, remove and purge</title>
+ <para>
+ Some frontends like <command>apt-get dselect-upgrade</command> can be used to
+ apply previously sheduled changes to the install state of packages. Such changes
+ can be sheduled with the <option>install</option>, <option>remove</option>
+ (also known as <option>deinstall</option>) and <option>purge</option> commands.
+ Packages with a specific selection can be displayed with <option>showinstall</option>,
+ <option>showremove</option> and <option>showpurge</option> respectively.
+ More information about these so called dpkg selections can be found in &dpkg;.
+ </para>
+ </refsect1>
+ <refsect1><title>Options</title>
+ <variablelist>
&apt-commonoptions;
</variablelist>
</refsect1>
diff --git a/doc/apt-verbatim.ent b/doc/apt-verbatim.ent
index 448e6c2df..f5e322e11 100644
--- a/doc/apt-verbatim.ent
+++ b/doc/apt-verbatim.ent
@@ -394,18 +394,47 @@
</cmdsynopsis></refsynopsisdiv>">
<!ENTITY synopsis-command-apt-mark "<refsynopsisdiv><cmdsynopsis>
<command>apt-mark</command>
- <arg><option>-f=&synopsis-param-filename;</option></arg>
+ <group choice='plain'>
+ <group choice='req'>
+ <arg choice='plain'><option>-f=&synopsis-param-filename;</option></arg>
+ <arg choice='plain'>
+ <group choice='req'>
+ <arg choice='plain'>auto</arg>
+ <arg choice='plain'>manual</arg>
+ </group>
+ &synopsis-arg-pkg;
+ </arg>
+ <arg choice='plain'>
+ <group choice='req'>
+ <arg choice='plain'>showauto</arg>
+ <arg choice='plain'>showmanual</arg>
+ </group>
+ <arg choice='opt' rep='repeat'><replaceable>&synopsis-pkg;</replaceable></arg>
+ </arg>
+ </group>
+ &synopsis-help;
+ </group>
+</cmdsynopsis><cmdsynopsis><command>apt-mark</command>
<group choice='plain'>
<arg choice='plain'>
<group choice='req'>
- <arg choice='plain'>auto</arg>
- <arg choice='plain'>manual</arg>
- <arg choice='plain'>showauto</arg>
- <arg choice='plain'>showmanual</arg>
+ <arg choice='plain'>hold</arg>
+ <arg choice='plain'>unhold</arg>
+ <arg choice='plain'>install</arg>
+ <arg choice='plain'>remove</arg>
+ <arg choice='plain'>purge</arg>
</group>
&synopsis-arg-pkg;
</arg>
- &synopsis-help;
+ <arg choice='plain'>
+ <group choice='req'>
+ <arg choice='plain'>showhold</arg>
+ <arg choice='plain'>showinstall</arg>
+ <arg choice='plain'>showremove</arg>
+ <arg choice='plain'>showpurge</arg>
+ </group>
+ <arg choice='opt' rep='repeat'><replaceable>&synopsis-pkg;</replaceable></arg>
+ </arg>
</group>
</cmdsynopsis></refsynopsisdiv>">
<!ENTITY synopsis-command-apt-sortpkgs "<refsynopsisdiv><cmdsynopsis>
diff --git a/test/integration/test-apt-mark b/test/integration/test-apt-mark
index ec4ed8316..47ade45b1 100755
--- a/test/integration/test-apt-mark
+++ b/test/integration/test-apt-mark
@@ -112,3 +112,43 @@ Inst uninstalled (1 unstable [all])
Inst uninstalled-native (1 unstable [amd64])
Conf uninstalled (1 unstable [all])
Conf uninstalled-native (1 unstable [amd64])' aptget install uninstalled uninstalled-native -s
+testsuccess aptmark unhold uninstalled uninstalled-native
+
+testselections() {
+ testsuccess aptmark hold "$1"
+ testsuccessequal "$1" aptmark showholds "$1"
+ testsuccess aptmark unhold "$1"
+ testsuccessequal "$1" aptmark showinstalls "$1"
+ testsuccess aptmark hold "$1"
+ testsuccessequal "$1" aptmark showholds "$1"
+ testsuccess aptmark install "$1"
+ testsuccessequal "$1" aptmark showinstalls "$1"
+ testsuccess aptmark remove "$1"
+ testsuccessequal "$1" aptmark showremoves "$1"
+ testsuccess aptmark purge "$1"
+ testsuccessequal "$1" aptmark showpurges "$1"
+}
+testselections 'foo'
+testselections 'bar'
+
+testsuccessequal 'Reading package lists...
+Building dependency tree...
+Reading state information...
+The following packages will be REMOVED:
+ bar* foo*
+0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
+Purg bar [1]
+Purg foo [1]' aptget dselect-upgrade -s
+
+testuninstalledselections() {
+ testsuccess aptmark hold "$1"
+ testsuccessequal "$1" aptmark showholds "$1"
+ testsuccess aptmark unhold "$1"
+ testsuccessequal "$1" aptmark showremoves "$1"
+ testsuccess aptmark hold "$1"
+ testsuccessequal "$1" aptmark showholds "$1"
+ testsuccess aptmark install "$1"
+ testsuccessequal "$1" aptmark showinstalls "$1"
+}
+testuninstalledselections 'uninstalled'
+testuninstalledselections 'uninstalled-native'