Skip to content

Commit

Permalink
Show locked packages in summary of patch, up and dup command (FATE#31…
Browse files Browse the repository at this point in the history
…8299)
  • Loading branch information
mlandres committed Oct 7, 2015
1 parent 31c01ce commit 0299c37
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 92 deletions.
23 changes: 17 additions & 6 deletions doc/zypper.8
Original file line number Diff line number Diff line change
Expand Up @@ -2504,15 +2504,26 @@ Package locks serve the purpose of preventing changes to the set of installed pa
\fBlocks\fR (\fBll\fR)
.RS 4
List currently active package locks\&.
.PP
\fB\-m\fR, \fB\-\-matches\fR
.RS 4
Show the number of resolvables matched by each lock\&. This option requires loading the repositories\&.
.RE
.PP
\fBaddlock\fR (\fBal\fR) [\fIoptions\fR] \fIpackage\-name\fR\&...
\fB\-s\fR, \fB\-\-solvables\fR
.RS 4
Add a package lock\&. Specify packages to lock by exact name or by a glob pattern using
\fB*\fR
and
\fI\fB?\fR\fR
wildcard characters\&.
List the resolvables matched by each lock\&. This option requires loading the repositories\&.
.RE
.sp
.if n \{\
.RS 4
.\}
.nf
Add a package lock\&. Specify packages to lock by exact name or by a glob pattern using *** and \*(Aq*?*\*(Aq wildcard characters\&.
.fi
.if n \{\
.RE
.\}
.PP
\fB\-r\fR, \fB\-\-repo\fR \fIalias\fR|\fIname\fR|\fI#\fR|\fIURI\fR
.RS 4
Expand Down
9 changes: 8 additions & 1 deletion doc/zypper.8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1297,8 +1297,15 @@ Package locks serve the purpose of preventing changes to the set of installed pa

*locks* (*ll*)::
List currently active package locks.
+
--
*-m*, *--matches*::
Show the number of resolvables matched by each lock. This option requires loading the repositories.

*-s*, *--solvables*::
List the resolvables matched by each lock. This option requires loading the repositories.
--

*addlock* (*al*) ['options'] 'package-name'...::
Add a package lock. Specify packages to lock by exact name or by a glob pattern using *** and '*?*' wildcard characters.
+
--
Expand Down
121 changes: 79 additions & 42 deletions src/Summary.cc
Original file line number Diff line number Diff line change
Expand Up @@ -351,19 +351,21 @@ unsigned Summary::packagesToRemove() const { return numberOfPackagesIn( _toremov
///////////////////////////////////////////////////////////////////
namespace
{
inline std::string ResPair2Name( const Summary::ResPairSet::value_type & resp_r )
inline std::string ResPair2Name( const Summary::ResPairSet::value_type & resp_r, bool withKind_r = false )
{
if ( resp_r.second->kind() == ResKind::product )
// If two products are involved, show the old ones summary.
// (The following product is going to be upgraded/downgraded:)
return resp_r.first ? resp_r.first->summary() : resp_r.second->summary();

return resp_r.second->name();
return( withKind_r ? resp_r.second->ident().asString() : resp_r.second->name() );
}
} // namespace
///////////////////////////////////////////////////////////////////
void Summary::writeResolvableList(ostream & out, const ResPairSet & resolvables, ansi::Color color)
bool Summary::writeResolvableList(ostream & out, const ResPairSet & resolvables, ansi::Color color, unsigned maxEntires_r, bool withKind_r )
{
bool ret = true; // whether the complete list was written, or maxEntires_r clipped

if ((_viewop & DETAILS) == 0)
{
static const ColorString quoteCh( "\"", ColorContext::HIGHLIGHT );
Expand All @@ -373,12 +375,13 @@ void Summary::writeResolvableList(ostream & out, const ResPairSet & resolvables,
char firstCh = 0;

ostringstream s;
for (ResPairSet::const_iterator resit = resolvables.begin();
resit != resolvables.end(); ++resit)
unsigned relevant_entries = 0;
for ( const ResPair & respair : resolvables )
{
// name
const std::string & name( ResPair2Name( *resit ) );
if ( name.empty() )
const std::string & name( ResPair2Name( respair, withKind_r ) );
++relevant_entries;
if ( maxEntires_r && relevant_entries > maxEntires_r )
continue;

// quote names with spaces
Expand All @@ -403,76 +406,102 @@ void Summary::writeResolvableList(ostream & out, const ResPairSet & resolvables,
if ( quote ) s << quoteCh;

// version (if multiple versions are present)
if (_multiInstalled.find(resit->second->name()) != _multiInstalled.end())
if (_multiInstalled.find(respair.second->name()) != _multiInstalled.end())
{
if (resit->first && resit->first->edition() != resit->second->edition())
s << "-" << resit->first->edition().asString()
<< "->" << resit->second->edition().asString();
if (respair.first && respair.first->edition() != respair.second->edition())
s << "-" << respair.first->edition().asString()
<< "->" << respair.second->edition().asString();
else
s << "-" << resit->second->edition().asString();
s << "-" << respair.second->edition().asString();
}

s << " ";
}
if ( maxEntires_r && relevant_entries > maxEntires_r )
{
relevant_entries -= maxEntires_r;
// translators: Appended when clipping a long enumeration:
// "ConsoleKit-devel ConsoleKit-doc ... and 20828 more items."
s << ( color << format(PL_(
"... and %1% more item.",
"... and %1% more items.",
relevant_entries) ) % relevant_entries );
ret = false;
}
mbs_write_wrapped(out, s.str(), 2, _wrap_width);
out << endl;
return;
return ret;
}

Table t; t.lineStyle(none); t.wrap(0); t.margin(2);
unsigned relevant_entries = 0;

for (ResPairSet::const_iterator resit = resolvables.begin();
resit != resolvables.end(); ++resit)
for ( const ResPair & respair : resolvables )
{
TableRow tr;

string name = ResPair2Name( *resit );
string name = ResPair2Name( respair, withKind_r );
++relevant_entries;
if ( maxEntires_r && relevant_entries > maxEntires_r )
continue;

// version (if multiple versions are present)
if (!(_viewop & SHOW_VERSION) && _multiInstalled.find(resit->second->name()) != _multiInstalled.end())
if (!(_viewop & SHOW_VERSION) && _multiInstalled.find(respair.second->name()) != _multiInstalled.end())
{
if (resit->first && resit->first->edition() != resit->second->edition())
name += string("-") + resit->first->edition().asString()
+ "->" + resit->second->edition().asString();
if (respair.first && respair.first->edition() != respair.second->edition())
name += string("-") + respair.first->edition().asString()
+ "->" + respair.second->edition().asString();
else
name += string("-") + resit->second->edition().asString();
name += string("-") + respair.second->edition().asString();
}

TableRow tr;
tr << name;

if (_viewop & SHOW_VERSION)
{
if (resit->first && resit->first->edition() != resit->second->edition())
tr << resit->first->edition().asString() + " -> " +
resit->second->edition().asString();
if (respair.first && respair.first->edition() != respair.second->edition())
tr << respair.first->edition().asString() + " -> " +
respair.second->edition().asString();
else
tr << resit->second->edition().asString();
tr << respair.second->edition().asString();
}
if (_viewop & SHOW_ARCH)
{
if (resit->first && resit->first->arch() != resit->second->arch())
tr << resit->first->arch().asString() + " -> " +
resit->second->arch().asString();
if (respair.first && respair.first->arch() != respair.second->arch())
tr << respair.first->arch().asString() + " -> " +
respair.second->arch().asString();
else
tr << resit->second->arch().asString();
tr << respair.second->arch().asString();
}
if (_viewop & SHOW_REPO)
{
// we do not know about repository changes, only show the repo from
// which the package will be installed
tr << resit->second->repoInfo().asUserString();
tr << respair.second->repoInfo().asUserString();
}
if (_viewop & SHOW_VENDOR)
{
if (resit->first && ! VendorAttr::instance().equivalent(resit->first->vendor(), resit->second->vendor()))
tr << resit->first->vendor() + " -> " + resit->second->vendor();
if (respair.first && ! VendorAttr::instance().equivalent(respair.first->vendor(), respair.second->vendor()))
tr << respair.first->vendor() + " -> " + respair.second->vendor();
else
tr << resit->second->vendor();
tr << respair.second->vendor();
}
t << tr;
}
out << t;
if ( maxEntires_r && relevant_entries > maxEntires_r )
{
relevant_entries -= maxEntires_r;
// translators: Appended when clipping a long enumeration:
// "ConsoleKit-devel ConsoleKit-doc ... and 20828 more items."
out << ( color << format(PL_(
"... and %1% more item.",
"... and %1% more items.",
relevant_entries) ) % relevant_entries ) << endl;
ret = false;
}
out << endl;

out << t << endl;
return ret;
}

// --------------------------------------------------------------------------
Expand Down Expand Up @@ -1151,19 +1180,18 @@ void Summary::writeNotUpdated(std::ostream & out)

void Summary::writeLocked(std::ostream & out)
{
return;
ResPairSet instlocks; // locked + installed
ResPairSet avidents; // avaialble locked
ResPoolProxy selPool( ResPool::instance().proxy() );
for_( it, selPool.begin(), selPool.end() )
{
if ( (*it)->locked() )
if ( (*it)->locked() ) // NOTE: this does not cover partial locks (not all instances locked)
{
if ( (*it)->hasInstalledObj() )
for_( iit, (*it)->installedBegin(), (*it)->installedEnd() )
instlocks.insert( ResPair( nullptr, *iit ) );
else
;//avidents.insert( ResPair( nullptr, (*it)->theObj() ) );
avidents.insert( ResPair( nullptr, (*it)->theObj() ) );
}
}
if ( ! ( instlocks.empty() && avidents.empty() ) )
Expand All @@ -1176,19 +1204,27 @@ void Summary::writeLocked(std::ostream & out)
label = str::form( label.c_str(), instlocks.size() + avidents.size() );
out << endl << ( ColorContext::HIGHLIGHT << label ) << endl;

bool wroteAll = true;
if ( ! avidents.empty() )
{
DtorReset guard( _viewop );
_viewop = DEFAULT; // always as plain name list
// translators: used as 'tag:' (i.e. followed by ':')
out << " " << _("Available") << ':' << endl;
writeResolvableList( out, avidents, ColorContext::HIGHLIGHT );
wroteAll &= writeResolvableList( out, avidents, ColorContext::HIGHLIGHT, 100, /*withKind*/true );

// translators: %1% is a zypper command line
N_("Run '%1%' to see the complete list of locked items.");
}
if ( ! instlocks.empty() )
{
// translators: used as 'tag:' (i.e. followed by ':')
out << " " << _("Installed") << ':' << endl;
writeResolvableList( out, instlocks, ColorContext::HIGHLIGHT );
wroteAll &= writeResolvableList( out, instlocks, ColorContext::HIGHLIGHT, 100, /*withKind*/true );
}
if ( !wroteAll )
{
out << " " << format(_("Run '%1%' to see the complete list of locked items.")) % "zypper locks -s" << endl;
}
}
}
Expand Down Expand Up @@ -1379,7 +1415,8 @@ void Summary::dumpTo(ostream & out)

_wrap_width = get_screen_width();

writeLocked(out);
if (_viewop & SHOW_LOCKS )
writeLocked(out);
if (_viewop & SHOW_NOT_UPDATED)
writeNotUpdated(out);
writeNewlyInstalled(out);
Expand Down
7 changes: 6 additions & 1 deletion src/Summary.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class Summary : private zypp::base::NonCopyable
SHOW_RECOMMENDED = 0x0200,
SHOW_UNSUPPORTED = 0x0400,
SHOW_NOT_UPDATED = 0x0800,
SHOW_LOCKS = 0x1000,

SHOW_ALL = 0xffff
};
Expand Down Expand Up @@ -114,7 +115,11 @@ class Summary : private zypp::base::NonCopyable

private:
void readPool(const zypp::ResPool & pool);
void writeResolvableList(std::ostream & out, const ResPairSet & resolvables, ansi::Color = ansi::Color::nocolor() );

bool writeResolvableList(std::ostream & out, const ResPairSet & resolvables, ansi::Color = ansi::Color::nocolor(), unsigned maxEntries_r = 0U, bool withKind_r = false );
bool writeResolvableList(std::ostream & out, const ResPairSet & resolvables, unsigned maxEntries_r, bool withKind_r = false )
{ return writeResolvableList( out, resolvables, ansi::Color::nocolor(), maxEntries_r, withKind_r ); }

void writeXmlResolvableList(std::ostream & out, const KindToResPairSet & resolvables);

void collectInstalledRecommends(const zypp::ResObject::constPtr & obj);
Expand Down
53 changes: 44 additions & 9 deletions src/Zypper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,11 @@ void Zypper::safeDoCommand()
ZYPP_CAUGHT(e);
MIL << "Caught exit request: exitCode " << exitCode() << endl;
}
catch ( const Out::Error & error_r )
{
error_r.report( *this );
report_a_bug(out());
}
catch (const Exception & ex)
{
ZYPP_CAUGHT(ex);
Expand Down Expand Up @@ -2630,19 +2635,29 @@ void Zypper::processCommandOptions()

case ZypperCommand::LIST_LOCKS_e:
{
shared_ptr<ListLocksOptions> myOpts( new ListLocksOptions() );
_commandOptions = myOpts;
static struct option options[] =
{
{"help", no_argument, 0, 'h'},
{"help", no_argument, 0, 'h'},
{"matches", no_argument, 0, 'm'},
{"solvables", no_argument, 0, 's'},
{0, 0, 0, 0}
};
specific_options = options;
_command_help = _(
"locks (ll)\n"
"\n"
"List current package locks.\n"
"\n"
"This command has no additional options.\n"
);
_command_help = CommandHelpFormater()
.synopsis( // translators: command synopsis; do not translate the command 'name (abbreviations)' or '-option' names
_("locks (ll) [options]")
)
.description( // translators: command description
_("List current package locks.")
)
.optionSectionCommandOptions()
.option( "-m, --matches", // translators: -m, --matches
_("Show the number of resolvables matched by each lock.") )
.option( "-s, --solvables", // translators: -s, --solvables
_("List the resolvables matched by each lock.") )
;
break;
}

Expand Down Expand Up @@ -3266,7 +3281,7 @@ void Zypper::doCommand()
}

initRepoManager();
RepoManager & rm = repoManager();
RepoManager & rm = repoManager(); // ?? UNUSED VAR OR CALL NEEDED ??

// force specific repository type.
string type = copts.count("type") ? copts["type"].front() : "";
Expand Down Expand Up @@ -4972,6 +4987,26 @@ void Zypper::doCommand()
{
if (runningHelp()) { out().info(_command_help, Out::QUIET); return; }

shared_ptr<ListLocksOptions> listLocksOptions = commandOptionsAs<ListLocksOptions>();
if ( !listLocksOptions )
throw( Out::Error( ZYPPER_EXIT_ERR_BUG, "Wrong or missing options struct." ) );

bool needLoadSystem = false;

if ( copts.count("matches") )
{
listLocksOptions->_withMatches = true;
needLoadSystem = true;
}
if ( copts.count("solvables") )
{
listLocksOptions->_withSolvables = true;
needLoadSystem = true;
}

if ( needLoadSystem )
defaultLoadSystem();

list_locks(*this);

break;
Expand Down

0 comments on commit 0299c37

Please sign in to comment.