name matching it was split out.. */
bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache,
pkgProblemResolver &Fix,bool Remove,bool BrokenFix,
- unsigned int &ExpectedInst,bool AllowFail = true)
+ bool AllowFail = true)
{
- /* This is a pure virtual package and there is a single available
- candidate providing it. */
- if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0)
- {
- pkgCache::PkgIterator Prov;
- bool found_one = false;
-
- for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; P++)
- {
- pkgCache::VerIterator const PVer = P.OwnerVer();
- pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
-
- /* Ignore versions that are not a candidate. */
- if (Cache[PPkg].CandidateVer != PVer)
- continue;
-
- if (found_one == false)
- {
- Prov = PPkg;
- found_one = true;
- }
- else if (PPkg != Prov)
- {
- found_one = false; // we found at least two
- break;
- }
- }
-
- if (found_one == true)
- {
- ioprintf(c1out,_("Note, selecting %s instead of %s\n"),
- Prov.FullName(true).c_str(),Pkg.FullName(true).c_str());
- Pkg = Prov;
- }
- }
// Handle the no-upgrade case
if (_config->FindB("APT::Get::upgrade",true) == false &&
Pkg.FullName(true).c_str());
}
}
- else
- ExpectedInst++;
-
+
// Install it with autoinstalling enabled (if we not respect the minial
// required deps or the policy)
if ((State.InstBroken() == true || State.InstPolicyBroken() == true) && BrokenFix == false)
return InstallPackages(Cache,true);
}
/*}}}*/
+// CacheSetHelperAPTGet - responsible for message telling from the CacheSets/*{{{*/
+class CacheSetHelperAPTGet : public APT::CacheSetHelper {
+ /** \brief stream message should be printed to */
+ std::ostream &out;
+ /** \brief were things like Task or RegEx used to select packages? */
+ bool explicitlyNamed;
+
+public:
+ CacheSetHelperAPTGet(std::ostream &out) : APT::CacheSetHelper(true), out(out) {
+ explicitlyNamed = true;
+ }
+
+ virtual void showTaskSelection(APT::PackageSet const &pkgset, string const &pattern) {
+ for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ ioprintf(out, _("Note, selecting '%s' for task '%s'\n"),
+ Pkg.FullName(true).c_str(), pattern.c_str());
+ explicitlyNamed = false;
+ }
+ virtual void showRegExSelection(APT::PackageSet const &pkgset, string const &pattern) {
+ for (APT::PackageSet::const_iterator Pkg = pkgset.begin(); Pkg != pkgset.end(); ++Pkg)
+ ioprintf(out, _("Note, selecting '%s' for regex '%s'\n"),
+ Pkg.FullName(true).c_str(), pattern.c_str());
+ explicitlyNamed = false;
+ }
+ virtual void showSelectedVersion(pkgCache::PkgIterator const &Pkg, pkgCache::VerIterator const Ver,
+ string const &ver, bool const &verIsRel) {
+ if (ver != Ver.VerStr())
+ ioprintf(out, _("Selected version '%s' (%s) for '%s'\n"),
+ Ver.VerStr(), Ver.RelStr().c_str(), Pkg.FullName(true).c_str());
+ }
+
+ virtual APT::VersionSet canNotFindCandInstVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ return tryVirtualPackage(Cache, Pkg, APT::VersionSet::CANDINST);
+ }
+
+ virtual APT::VersionSet canNotFindInstCandVer(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg) {
+ return tryVirtualPackage(Cache, Pkg, APT::VersionSet::INSTCAND);
+ }
+
+ APT::VersionSet tryVirtualPackage(pkgCacheFile &Cache, pkgCache::PkgIterator const &Pkg,
+ APT::VersionSet::Version const &select) {
+ /* This is a pure virtual package and there is a single available
+ candidate providing it. */
+ if (unlikely(Cache[Pkg].CandidateVer != 0) || Pkg->ProvidesList == 0) {
+ if (select == APT::VersionSet::CANDINST)
+ return APT::CacheSetHelper::canNotFindCandInstVer(Cache, Pkg);
+ return APT::CacheSetHelper::canNotFindInstCandVer(Cache, Pkg);
+ }
+
+ pkgCache::PkgIterator Prov;
+ bool found_one = false;
+ for (pkgCache::PrvIterator P = Pkg.ProvidesList(); P; ++P) {
+ pkgCache::VerIterator const PVer = P.OwnerVer();
+ pkgCache::PkgIterator const PPkg = PVer.ParentPkg();
+
+ /* Ignore versions that are not a candidate. */
+ if (Cache[PPkg].CandidateVer != PVer)
+ continue;
+
+ if (found_one == false) {
+ Prov = PPkg;
+ found_one = true;
+ } else if (PPkg != Prov) {
+ found_one = false; // we found at least two
+ break;
+ }
+ }
+
+ if (found_one == true) {
+ ioprintf(out, _("Note, selecting '%s' instead of '%s'\n"),
+ Prov.FullName(true).c_str(), Pkg.FullName(true).c_str());
+ return APT::VersionSet::FromPackage(Cache, Prov, select, *this);
+ }
+ if (select == APT::VersionSet::CANDINST)
+ return APT::CacheSetHelper::canNotFindCandInstVer(Cache, Pkg);
+ return APT::CacheSetHelper::canNotFindInstCandVer(Cache, Pkg);
+ }
+
+ inline bool allPkgNamedExplicitly() const { return explicitlyNamed; }
+
+};
+ /*}}}*/
// DoInstall - Install packages from the command line /*{{{*/
// ---------------------------------------------------------------------
/* Install named packages */
BrokenFix = true;
unsigned int AutoMarkChanged = 0;
- unsigned int ExpectedInst = 0;
pkgProblemResolver Fix(Cache);
- unsigned short fallback = 0;
+ static const unsigned short MOD_REMOVE = 1;
+ static const unsigned short MOD_INSTALL = 2;
+
+ unsigned short fallback = MOD_INSTALL;
if (strcasecmp(CmdL.FileList[0],"remove") == 0)
- fallback = 1;
+ fallback = MOD_REMOVE;
else if (strcasecmp(CmdL.FileList[0], "purge") == 0)
{
_config->Set("APT::Get::Purge", true);
- fallback = 1;
+ fallback = MOD_REMOVE;
}
else if (strcasecmp(CmdL.FileList[0], "autoremove") == 0)
{
_config->Set("APT::Get::AutomaticRemove", "true");
- fallback = 1;
+ fallback = MOD_REMOVE;
}
- // new scope for the ActionGroup
- {
- // TODO: Howto get an ExpectedInst count ?
- pkgDepCache::ActionGroup group(Cache);
- std::list<APT::VersionSet::Modifier> mods;
- mods.push_back(APT::VersionSet::Modifier(0, "+",
+
+ std::list<APT::VersionSet::Modifier> mods;
+ mods.push_back(APT::VersionSet::Modifier(MOD_INSTALL, "+",
APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::CANDINST));
- mods.push_back(APT::VersionSet::Modifier(1, "-",
+ mods.push_back(APT::VersionSet::Modifier(MOD_REMOVE, "-",
APT::VersionSet::Modifier::POSTFIX, APT::VersionSet::INSTCAND));
- std::map<unsigned short, APT::VersionSet> verset = APT::VersionSet::GroupedFromCommandLine(Cache,
- CmdL.FileList + 1, mods, fallback, c0out);
+ CacheSetHelperAPTGet helper(c0out);
+ std::map<unsigned short, APT::VersionSet> verset = APT::VersionSet::GroupedFromCommandLine(Cache,
+ CmdL.FileList + 1, mods, fallback, helper);
- if (_error->PendingError() == true)
- return false;
+ if (_error->PendingError() == true)
+ return false;
- for (APT::VersionSet::const_iterator Ver = verset[0].begin();
- Ver != verset[0].end(); ++Ver)
- {
- pkgCache::PkgIterator Pkg = Ver.ParentPkg();
- Cache->SetCandidateVersion(Ver);
-
- if (TryToInstall(Pkg, Cache, Fix, false, BrokenFix, ExpectedInst) == false)
- return false;
-
- // see if we need to fix the auto-mark flag
- // e.g. apt-get install foo
- // where foo is marked automatic
- if (Cache[Pkg].Install() == false &&
- (Cache[Pkg].Flags & pkgCache::Flag::Auto) &&
- _config->FindB("APT::Get::ReInstall",false) == false &&
- _config->FindB("APT::Get::Only-Upgrade",false) == false &&
- _config->FindB("APT::Get::Download-Only",false) == false)
- {
- ioprintf(c1out,_("%s set to manually installed.\n"),
- Pkg.FullName(true).c_str());
- Cache->MarkAuto(Pkg,false);
- AutoMarkChanged++;
- }
- }
+ unsigned short order[] = { 0, 0, 0 };
+ if (fallback == MOD_INSTALL) {
+ order[0] = MOD_INSTALL;
+ order[1] = MOD_REMOVE;
+ } else {
+ order[0] = MOD_REMOVE;
+ order[1] = MOD_INSTALL;
+ }
- for (APT::VersionSet::const_iterator Ver = verset[1].begin();
- Ver != verset[1].end(); ++Ver)
+ // new scope for the ActionGroup
+ {
+ pkgDepCache::ActionGroup group(Cache);
+ for (unsigned short i = 0; order[i] != 0; ++i)
{
- pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+ if (order[i] == MOD_INSTALL)
+ for (APT::VersionSet::const_iterator Ver = verset[MOD_INSTALL].begin();
+ Ver != verset[MOD_INSTALL].end(); ++Ver)
+ {
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
+ Cache->SetCandidateVersion(Ver);
+
+ if (TryToInstall(Pkg, Cache, Fix, false, BrokenFix) == false)
+ return false;
+
+ // see if we need to fix the auto-mark flag
+ // e.g. apt-get install foo
+ // where foo is marked automatic
+ if (Cache[Pkg].Install() == false &&
+ (Cache[Pkg].Flags & pkgCache::Flag::Auto) &&
+ _config->FindB("APT::Get::ReInstall",false) == false &&
+ _config->FindB("APT::Get::Only-Upgrade",false) == false &&
+ _config->FindB("APT::Get::Download-Only",false) == false)
+ {
+ ioprintf(c1out,_("%s set to manually installed.\n"),
+ Pkg.FullName(true).c_str());
+ Cache->MarkAuto(Pkg,false);
+ AutoMarkChanged++;
+ }
+ }
+ else if (order[i] == MOD_REMOVE)
+ for (APT::VersionSet::const_iterator Ver = verset[MOD_REMOVE].begin();
+ Ver != verset[MOD_REMOVE].end(); ++Ver)
+ {
+ pkgCache::PkgIterator Pkg = Ver.ParentPkg();
- if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix, ExpectedInst) == false)
- return false;
+ if (TryToInstall(Pkg, Cache, Fix, true, BrokenFix) == false)
+ return false;
+ }
}
if (_error->PendingError() == true)
/* Print out a list of packages that are going to be installed extra
to what the user asked */
- if (Cache->InstCount() != ExpectedInst)
+ if (Cache->InstCount() != verset[MOD_INSTALL].size())
{
string List;
string VersionsList;
Cache->writeStateFile(NULL);
// See if we need to prompt
- if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0)
+ // FIXME: check if really the packages in the set are going to be installed
+ if (Cache->InstCount() == verset[MOD_INSTALL].size() && Cache->DelCount() == 0)
return InstallPackages(Cache,false,false);
return InstallPackages(Cache,false);
}
// Install the requested packages
- unsigned int ExpectedInst = 0;
vector <pkgSrcRecords::Parser::BuildDepRec>::iterator D;
pkgProblemResolver Fix(Cache);
bool skipAlternatives = false; // skip remaining alternatives in an or group
*/
if (IV.end() == false &&
Cache->VS().CheckDep(IV.VerStr(),(*D).Op,(*D).Version.c_str()) == true)
- TryToInstall(Pkg,Cache,Fix,true,false,ExpectedInst);
+ TryToInstall(Pkg,Cache,Fix,true,false);
}
else // BuildDep || BuildDepIndep
{
if (_config->FindB("Debug::BuildDeps",false) == true)
cout << " Trying to install " << (*D).Package << endl;
- if (TryToInstall(Pkg,Cache,Fix,false,false,ExpectedInst) == true)
+ if (TryToInstall(Pkg,Cache,Fix,false,false) == true)
{
// We successfully installed something; skip remaining alternatives
skipAlternatives = hasAlternatives;
}
// Deal with stdout not being a tty
- if (!isatty(STDOUT_FILENO) && _config->FindI("quiet",0) < 1)
+ if (!isatty(STDOUT_FILENO) && _config->FindI("quiet", -1) == -1)
_config->Set("quiet","1");
// Setup the output streams
CmdL.DispatchArg(Cmds);
// Print any errors or warnings found during parsing
- if (_error->empty() == false)
- {
- bool Errors = _error->PendingError();
+ bool const Errors = _error->PendingError();
+ if (_config->FindI("quiet",0) > 0)
_error->DumpErrors();
- return Errors == true?100:0;
- }
-
- return 0;
+ else
+ _error->DumpErrors(GlobalError::DEBUG);
+ return Errors == true ? 100 : 0;
}
/*}}}*/