IMPL_PTR_TYPE(ProblemSolutionIgnoreConflicts);
IMPL_PTR_TYPE(ProblemSolutionIgnoreRequires);
IMPL_PTR_TYPE(ProblemSolutionIgnoreArchitecture);
+IMPL_PTR_TYPE(ProblemSolutionIgnoreVendor);
IMPL_PTR_TYPE(ProblemSolutionIgnoreInstalled);
//---------------------------------------------------------------------------
ResolverInfo::toString (item).c_str());
addAction ( new InjectSolutionAction (item, ARCHITECTURE));
}
+
+ProblemSolutionIgnoreVendor::ProblemSolutionIgnoreVendor( ResolverProblem_Ptr parent,
+ PoolItem_Ref item)
+ : ProblemSolution (parent, "", "")
+{
+ // TranslatorExplanation %s = name of package, patch, selection ...
+ _description = str::form(_("Install %s although it would change the vendor"),
+ item->name().c_str());
+ // TranslatorExplanation %s = name of package, patch, selection ...
+ _details = str::form(_("%s provides this dependency, but would change the vendor of the installed item"),
+ ResolverInfo::toString (item).c_str());
+ addAction ( new InjectSolutionAction (item, VENDOR));
+}
ProblemSolutionIgnoreConflicts::ProblemSolutionIgnoreConflicts( ResolverProblem_Ptr parent,
PoolItem_Ref item,
**/
ProblemSolutionIgnoreArchitecture( ResolverProblem_Ptr parent,
PoolItem_Ref item);
- };
+ };
+
+ class ProblemSolutionIgnoreVendor : public ProblemSolution
+ {
+ public:
+
+ /**
+ * Constructor.
+ **/
+ ProblemSolutionIgnoreVendor( ResolverProblem_Ptr parent,
+ PoolItem_Ref item);
+ };
class ProblemSolutionIgnoreObsoletes : public ProblemSolution
{
}
}
+ // checking vendor
+ bool vendorFit = true;
+ if ( provider
+ && upgrades
+ && provider->vendor() != upgrades->vendor()) {
+ // checking if there is already an ignore
+ MIL << "provider " << provider << " has ANOTHER vendor '" << provider->vendor() << "' than the updated item "
+ << upgrades << endl;
+ PoolItemList ignore = _context->getIgnoreVendorItem();
+ PoolItemList::iterator it;
+ for (it = ignore.begin(); it != ignore.end(); ++it) {
+ if (provider == *it) break;
+ }
+ if (it != ignore.end()) {
+ MIL << " ---> will be ignored " << endl;
+ } else {
+ vendorFit = false;
+ }
+ }
+
if (! (status.isToBeUninstalled() || status.isImpossible())
&& ! _context->isParallelInstall( provider )
&& _context->itemIsPossible( provider )
&& ! provider.status().isLocked()
- && ( (!provider || !upgrades) || (provider->vendor() == upgrades->vendor()) )
+ && vendorFit
&& ! (provider.status().isKept()
&&provider.status().isByUser())
) {
} else if (provider.status().isKept() && provider.status().isByUser()) {
misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_KEEP_PROVIDER, requirer, RESOLVER_INFO_PRIORITY_VERBOSE, match);
misc_info->setOtherPoolItem (provider);
- } else if (provider->arch().compatibleWith( context->architecture() )) {
- misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER,
+ } else if (provider->vendor() != requirer->vendor()) {
+ misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_OTHER_VENDOR_PROVIDER,
requirer, RESOLVER_INFO_PRIORITY_VERBOSE, match);
misc_info->setOtherPoolItem (provider);
}
-
+ else if (provider->arch().compatibleWith( context->architecture() )) {
+ misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER,
+ requirer, RESOLVER_INFO_PRIORITY_VERBOSE, match);
+ misc_info->setOtherPoolItem (provider);
+ }
+
if (misc_info != NULL) {
context->addInfo (misc_info);
}
_ignoreArchitectureItem.push_back (item);
}
+void
+Resolver::addIgnoreVendorItem (const PoolItem_Ref item)
+{
+ _ignoreVendorItem.push_back (item);
+}
//---------------------------------------------------------------------------
_ignoreRequires,
_ignoreObsoletes,
_ignoreInstalledItem,
- _ignoreArchitectureItem);
+ _ignoreArchitectureItem,
+ _ignoreVendorItem);
context->setForceResolve( _forceResolve );
context->setEstablishContext( _establish_context );
context->setPreferHighestVersion ( _preferHighestVersion );
_ignoreRequires,
_ignoreObsoletes,
_ignoreInstalledItem,
- _ignoreArchitectureItem );
+ _ignoreArchitectureItem,
+ _ignoreVendorItem);
context->setForceResolve( _forceResolve );
context->setEstablishContext( _establish_context );
context->setPreferHighestVersion( _preferHighestVersion );
ignoreRequires,
_ignoreObsoletes,
_ignoreInstalledItem,
- _ignoreArchitectureItem);
+ _ignoreArchitectureItem,
+ _ignoreVendorItem);
initial_queue->context()->setForceResolve( _forceResolve );
initial_queue->context()->setEstablishContext( _establish_context );
initial_queue->context()->setPreferHighestVersion( _preferHighestVersion );
_ignoreInstalledItem.clear();
// Ignore the architecture of the item
_ignoreArchitectureItem.clear();
+ // Ignore the vendor of the item
+ _ignoreVendorItem.clear();
return;
PoolItemList _ignoreInstalledItem;
// Ignore the architecture of the item
PoolItemList _ignoreArchitectureItem;
-
+ // Ignore the vendor of the item
+ PoolItemList _ignoreVendorItem;
ResolverQueueList _pending_queues;
ResolverQueueList _pruned_queues;
const Capability & capability);
void addIgnoreInstalledItem (const PoolItem_Ref item);
void addIgnoreArchitectureItem (const PoolItem_Ref item);
+ void addIgnoreVendorItem (const PoolItem_Ref item);
void setForceResolve (const bool force) { _forceResolve = force; }
const bool forceResolve() { return _forceResolve; }
_ignoreRequires = parent->_ignoreRequires;
_ignoreObsoletes = parent->_ignoreObsoletes;
_ignoreInstalledItem = parent->_ignoreInstalledItem;
- _ignoreArchitectureItem = parent->_ignoreArchitectureItem;
+ _ignoreArchitectureItem = parent->_ignoreArchitectureItem;
+ _ignoreVendorItem = parent->_ignoreVendorItem;
_forceResolve = parent->_forceResolve;
_upgradeMode = parent->_upgradeMode;
_preferHighestVersion = parent->_preferHighestVersion;
PoolItemList _ignoreInstalledItem;
// Ignore the architecture of the item
PoolItemList _ignoreArchitectureItem;
+ // Ignore the vendor of the item
+ PoolItemList _ignoreVendorItem;
// Items which has been selected NOT by the solver
// This will be stored while a solver run in order to save time
const IgnoreMap ignoreRequires,
const IgnoreMap ignoreObsoletes,
const PoolItemList ignoreInstalledItem,
- const PoolItemList ignoreArchitectureItem)
+ const PoolItemList ignoreArchitectureItem,
+ const PoolItemList ignoreVendorItem)
{_ignoreConflicts = ignoreConflicts;
_ignoreRequires = ignoreRequires;
_ignoreObsoletes = ignoreObsoletes;
_ignoreInstalledItem = ignoreInstalledItem;
- _ignoreArchitectureItem = ignoreArchitectureItem;}
+ _ignoreArchitectureItem = ignoreArchitectureItem;
+ _ignoreVendorItem = ignoreVendorItem;
+ }
const IgnoreMap getIgnoreConflicts() const { return _ignoreConflicts; }
const IgnoreMap getIgnoreRequires() const { return _ignoreRequires; }
const IgnoreMap getIgnoreObsoletes() const { return _ignoreObsoletes; }
const PoolItemList getIgnoreInstalledItem() const { return _ignoreInstalledItem; }
const PoolItemList getIgnoreArchitectureItem() const { return _ignoreArchitectureItem; }
-
+ const PoolItemList getIgnoreVendorItem() const { return _ignoreVendorItem; }
void setForceResolve (const bool force) { _forceResolve = force; }
const bool forceResolve() { return _forceResolve; }
{ RIT(NOT_INSTALLABLE_PROVIDER), "p provides c but is uninstallable" },
{ RIT(LOCKED_PROVIDER), "p provides c but is locked" },
{ RIT(OTHER_ARCH_PROVIDER), "p provides c but has other architecture" },
+ { RIT(OTHER_VENDOR_PROVIDER), "p provides c but has other vendor" },
{ RIT(CANT_SATISFY), "Can't satisfy requirement c" },
// from QueueItemUninstall
{ RIT(UNINSTALL_TO_BE_INSTALLED), "p is to-be-installed, so it won't be unlinked." },
RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER, // p provides c but is uninstallable
RESOLVER_INFO_TYPE_LOCKED_PROVIDER, // p provides c but is locked
RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER, // p provides c but has other architecture
+ RESOLVER_INFO_TYPE_OTHER_VENDOR_PROVIDER, // p provides c but has other vendor
RESOLVER_INFO_TYPE_CANT_SATISFY, // Can't satisfy requirement c
// from QueueItemUninstall
RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED, // p is to-be-installed, so it won't be unlinked.
cap_str.c_str());
}
break;
-
+
+ //-------------------
+ // p provides c but has other vendor
+
+ case RESOLVER_INFO_TYPE_OTHER_VENDOR_PROVIDER: {
+ // affected() = requirer of capability
+ // _capability = provided by other()
+ // other() = provider of capability
+ // other_capability() = - empty -
+
+ string other_str = ResolverInfo::toString(other());
+ string cap_str = ResolverInfo::toString (_capability);
+ // Translator: 1.%s = name of package,patch,...; 2.%s = dependency; 3.%s = vendor ID
+ msg = str::form (_("%s provides %s, but has another vendor (%s)."),
+ other_str.c_str(),
+ cap_str.c_str(),
+ (other()->vendor()).c_str());
+ }
+ break;
//-------------------
// Can't satisfy requirement
struct FindProviders
{
FindMap providers; // the best providers which matched
-
- FindProviders ()
+ PoolItem forItem;
+ bool otherVendorFound;
+ FindProviders (PoolItem item)
+ :forItem(item),
+ otherVendorFound(false)
{ }
bool operator()( const CapAndItem & cai )
{
PoolItem provider( cai.item );
- if ( provider.status().isToBeUninstalled() ) {
+ if ( provider->vendor() != forItem->vendor() )
+ {
+ MIL << "Discarding '" << provider << "' from vendor '"
+ << provider->vendor() << "' different to uninstalled '"
+ << forItem->vendor() << "' vendor." << endl;
+ otherVendorFound = true;
+ } else if ( provider.status().isToBeUninstalled() ) {
MIL << " IGNORE relation match (package is tagged to delete): " << cai.cap << " ==> " << provider << endl;
}
else {
if (cand_it == candidatemap.end() // not in map yet
|| (cand_it->second->arch().compare( candidate->arch() ) < 0) // or the new has better architecture
|| ((cand_it->second->arch().compare( candidate->arch() ) == 0) // or the new has the same architecture
- && (cand_it->second->edition().compare( candidate->edition() ) < 0) // and a better edition (-> 157501)
- && (cand_it->second->vendor() == candidate->vendor() ) ) )// and same vendor
+ && (cand_it->second->edition().compare( candidate->edition() ) < 0)) // and a better edition (-> 157501)
+ )
{
candidatemap[installed] = candidate; // put it in !
}
CapFactory factory;
Capability installedCap = factory.parse( installed->kind(), installed->name(), Rel::GE, installed->edition() );
- FindProviders info;
+ FindProviders info(installed);
invokeOnEach( _pool.byCapabilityIndexBegin( installed->name(), dep ),
_pool.byCapabilityIndexEnd( installed->name(), dep ),
switch ( info.providers.size() ) {
case 0:
- MIL << " ==> (dropped)" << endl;
- // wait untill splits are processed. Might be a split obsoletes
- // this one (i.e. package replaced but not provided by new one).
- // otherwise it's finaly dropped.
- probably_dropped = true;
+ if (info.otherVendorFound) {
+ MIL << " only resolvable with other vendor found ==> do nothing" << endl;
+ } else {
+ MIL << " ==> (dropped)" << endl;
+ // wait untill splits are processed. Might be a split obsoletes
+ // this one (i.e. package replaced but not provided by new one).
+ // otherwise it's finaly dropped.
+ probably_dropped = true;
+ }
break;
case 1:
addProvided[installed] = providers;
ItemCapabilityMap provideAndLockMap;
// A map of PoolItems which provides a capability but have another architecture
ItemCapabilityMap provideAndOtherArchMap;
+ // A map of PoolItems which provides a capability but have another vendor
+ ItemCapabilityMap provideAndOtherVendorMap;
// A map of conflicting Items
ConflictMap conflictMap;
} ResItemCollector;
collector->provideAndOtherArchMap.insert (make_pair( misc_info->other(), misc_info->capability()));
}
}
-
-
+ // Collecting items which are providing requirements but they
+ // have another vendor
+ if (info->type() == RESOLVER_INFO_TYPE_OTHER_VENDOR_PROVIDER) {
+ ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
+ // does entry already exists ?
+ ItemCapabilityMap::iterator pos = find_if (collector->provideAndOtherVendorMap.begin(),
+ collector->provideAndOtherVendorMap.end(),
+ cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
+
+ if (pos == collector->provideAndOtherVendorMap.end()) {
+ _XDEBUG ("Inserting " << misc_info->capability() << "/" << misc_info->other()
+ << " into provideAndOtherVendorMap map");
+ collector->provideAndOtherVendorMap.insert (make_pair( misc_info->other(), misc_info->capability()));
+ }
+ }
// Collecting all conflicting Items
if (info->type() == RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE
|| info->type() == RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL) {
problem->addSolution (new ProblemSolutionIgnoreArchitecture (problem, it->first));
}
}
+ // Searching for another item which provides this requires BUT has another vendor
+ for (ItemCapabilityMap::const_iterator it = collector.provideAndOtherVendorMap.begin();
+ it != collector.provideAndOtherVendorMap.end(); ++it) {
+ if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
+ // ignoring vendor
+ problem->addSolution (new ProblemSolutionIgnoreVendor (problem, it->first));
+ }
+ }
// Searching for another item which provides this requires BUT has been set to be kept
for (ItemCapabilityMap::const_iterator it = collector.provideAndKeptMap.begin();
it != collector.provideAndKeptMap.end(); ++it) {
case CONFLICTS: os << "Conflicts"; break;
case OBSOLETES: os << "Obsoletes"; break;
case INSTALLED: os << "Installed"; break;
- case ARCHITECTURE: os << "Architecture"; break;
+ case ARCHITECTURE: os << "Architecture"; break;
+ case VENDOR: os << "Vendor"; break;
default: os << "Wrong kind"; break;
}
os << " ";
case ARCHITECTURE:
// This item is for ALL architectures available
resolver.addIgnoreArchitectureItem (_item);
- break;
+ break;
+ case VENDOR:
+ // This item is for ALL vendor available
+ resolver.addIgnoreVendorItem (_item);
+ break;
case OBSOLETES:
// removing the obsoletes dependency from the item
resolver.addIgnoreObsoletes (_otherItem, _capability);
/**
- * Type of ignoring dependencies and architectures
+ * Type of ignoring dependencies, architectures and vendor
**/
typedef enum
CONFLICTS,
OBSOLETES,
INSTALLED,
- ARCHITECTURE
+ ARCHITECTURE,
+ VENDOR
} InjectSolutionKind;