Fix Patch::interactive patch (c56a7818)
[platform/upstream/libzypp.git] / zypp / Patch.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Patch.cc
10  *
11 */
12 #include <iostream>
13
14 #include "zypp/base/LogTools.h"
15 #include "zypp/Patch.h"
16 #include "zypp/sat/WhatProvides.h"
17
18 using std::endl;
19
20 ///////////////////////////////////////////////////////////////////
21 namespace zypp
22 { /////////////////////////////////////////////////////////////////
23
24   IMPL_PTR_TYPE( Patch );
25
26   ///////////////////////////////////////////////////////////////////
27   //
28   //    METHOD NAME : Patch::Patch
29   //    METHOD TYPE : Ctor
30   //
31   Patch::Patch( const sat::Solvable & solvable_r )
32   : ResObject( solvable_r )
33   {}
34
35   ///////////////////////////////////////////////////////////////////
36   //
37   //    METHOD NAME : Patch::~Patch
38   //    METHOD TYPE : Dtor
39   //
40   Patch::~Patch()
41   {}
42
43   ///////////////////////////////////////////////////////////////////
44   //
45   //    Patch interface forwarded to implementation
46   //
47   ///////////////////////////////////////////////////////////////////
48
49   Patch::Category Patch::categoryEnum() const
50   {
51     static const IdString cat_yast              ( "yast" );
52     static const IdString cat_security          ( "security" );
53     static const IdString cat_recommended       ( "recommended" );
54     static const IdString cat_bugfix            ( "bugfix" );           // rhn
55     static const IdString cat_optional          ( "optional" );
56     static const IdString cat_feature           ( "feature" );
57     static const IdString cat_enhancement       ( "enhancement" );      // rnh
58     static const IdString cat_document          ( "document" );
59
60     // patch category is not poolized in the solv file (i.e. an IdString) ;(
61     IdString cat( sat::LookupAttr( sat::SolvAttr::patchcategory, satSolvable() ).begin().c_str() );
62
63     if ( cat == cat_yast )
64       return CAT_YAST;
65     if ( cat == cat_security )
66       return CAT_SECURITY;
67     if ( cat == cat_recommended || cat == cat_bugfix )
68       return CAT_RECOMMENDED;
69     if ( cat == cat_optional || cat == cat_enhancement || cat == cat_feature )
70       return CAT_OPTIONAL;
71     if ( cat == cat_document )
72       return CAT_DOCUMENT;
73
74     return CAT_OTHER;
75   }
76
77   std::string Patch::message( const Locale & lang_r ) const
78   { return lookupStrAttribute( sat::SolvAttr::message, lang_r ); }
79
80   std::string Patch::category() const
81   { return lookupStrAttribute( sat::SolvAttr::patchcategory ); }
82
83   bool Patch::rebootSuggested() const
84   { return lookupBoolAttribute( sat::SolvAttr::rebootSuggested ); }
85
86   bool Patch::restartSuggested() const
87   { return lookupBoolAttribute( sat::SolvAttr::restartSuggested ); }
88
89   bool Patch::reloginSuggested() const
90   { return lookupBoolAttribute( sat::SolvAttr::reloginSuggested ); }
91
92
93   bool Patch::interactive( bool ignoreRebootFlag_r ) const
94   {
95     if ( ( ! ignoreRebootFlag_r && rebootSuggested() )
96          || ! message().empty()
97          || ! licenseToConfirm().empty() )
98     {
99       return true;
100     }
101
102     Patch::Contents c( contents() );
103     for_( it, c.begin(), c.end() )
104     {
105       if ( ! makeResObject(*it)->licenseToConfirm().empty() )
106       {
107         return true;
108       }
109     }
110
111     return false;
112   }
113
114   Patch::Contents Patch::contents() const
115   {
116     Contents result;
117     // DBG << *this << endl;
118     sat::LookupAttr updateCollection( sat::SolvAttr::updateCollection, satSolvable() );
119     for_( entry, updateCollection.begin(), updateCollection.end() )
120     {
121       IdString name    ( entry.subFind( sat::SolvAttr::updateCollectionName ).idStr() );
122       Edition  edition ( entry.subFind( sat::SolvAttr::updateCollectionEvr ).idStr() );
123       Arch     arch    ( entry.subFind( sat::SolvAttr::updateCollectionArch ).idStr() );
124       if ( name.empty() )
125       {
126         WAR << "Ignore malformed updateCollection entry: " << name << "-" << edition << "." << arch << endl;
127         continue;
128       }
129
130       // The entry is relevant if there is an installed
131       // package with the same name and arch.
132       bool relevant = false;
133       sat::WhatProvides providers( (Capability( name.id() )) );
134       for_( it, providers.begin(), providers.end() )
135       {
136         if ( it->isSystem() && it->ident() == name && it->arch() == arch )
137         {
138           relevant = true;
139           break;
140         }
141       }
142       if ( ! relevant )
143       {
144         // DBG << "Not relevant: " << name << "-" << edition << "." << arch << endl;
145         continue;
146       }
147
148 #warning definition of patch contents is poor - needs review
149       /* find exact providers first (this matches the _real_ 'collection content' of the patch */
150       providers = sat::WhatProvides( Capability( arch, name.c_str(), Rel::EQ, edition, ResKind::package ) );
151       if ( providers.empty() )
152       {
153         /* no exact providers: find 'best' providers: those with a larger evr */
154         providers = sat::WhatProvides( Capability( arch, name.c_str(), Rel::GT, edition, ResKind::package ) );
155         if ( providers.empty() )
156         {
157           // Hmm, this patch is not installable, no one is providing the package in the collection
158           // FIXME: raise execption ? fake a solvable ?
159           WAR << "Missing provider: " << name << "-" << edition << "." << arch << endl;
160           continue;
161         }
162       }
163
164       // FIXME ?! loop over providers and try to find installed ones ?
165       // DBG << "Found " << name << "-" << edition << "." << arch << ": " << *(providers.begin()) << endl;
166       result.get().insert( *(providers.begin()) );
167     }
168
169     return result;
170   }
171
172   ///////////////////////////////////////////////////////////////////
173   //
174   //    CLASS NAME : Patch::ReferenceIterator
175   //
176   ///////////////////////////////////////////////////////////////////
177
178   Patch::ReferenceIterator::ReferenceIterator( const sat::Solvable & val_r )
179   { base_reference() = sat::LookupAttr( sat::SolvAttr::updateReference, val_r ).begin(); }
180
181   std::string Patch::ReferenceIterator::id() const
182   { return base_reference().subFind( sat::SolvAttr::updateReferenceId ).asString(); }
183   std::string Patch::ReferenceIterator::href() const
184   { return base_reference().subFind( sat::SolvAttr::updateReferenceHref ).asString(); }
185   std::string Patch::ReferenceIterator::title() const
186   { return base_reference().subFind( sat::SolvAttr::updateReferenceTitle ).asString(); }
187   std::string Patch::ReferenceIterator::type() const
188   { return base_reference().subFind( sat::SolvAttr::updateReferenceType ).asString(); }
189
190   /////////////////////////////////////////////////////////////////
191 } // namespace zypp
192 ///////////////////////////////////////////////////////////////////