Skip to content

Commit

Permalink
Support asking the user about rpm header downloads
Browse files Browse the repository at this point in the history
Adds possibility to show filelists without installing the package(fixes #164)
Adds possibility to show changelog of packages (fixes #138)
  • Loading branch information
bzeller committed Jun 27, 2018
1 parent 7caff54 commit 14706c0
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 13 deletions.
9 changes: 9 additions & 0 deletions doc/zypper.8.txt
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ Package Management Commands
*--suggests*::
Show symbols the package suggests.

*--filelist*::
Show the full filelist of the package.

*--changelog*::
If a update candidate is available show the new changelog entries, otherwise show the first 10.

*--full-changelog*::
Show the full changelog.

Examples: :: {nop}

$ *zypper info workrave*;;
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ SET (zypper_HEADERS
callbacks/rpm.h
callbacks/repo.h
callbacks/job.h
callbacks/package.h
)

SET( zypper_SRCS
Expand Down
12 changes: 10 additions & 2 deletions src/Zypper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2979,12 +2979,17 @@ void Zypper::processCommandOptions()
{"conflicts", no_argument, 0, 0},
{"obsoletes", no_argument, 0, 0},
{"recommends", no_argument, 0, 0},
{"changelog", no_argument, 0, 0},
{"full-changelog", no_argument, 0, 0},
{"filelist", no_argument, 0, 0},
{"suggests", no_argument, 0, 0},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
specific_options = info_options;
_command_help = str::form(_(

_command_help = (CommandHelpFormater()
<< str::form(_(
"info (if) [options] <name> ...\n"
"\n"
"Show detailed information for specified packages.\n"
Expand All @@ -3003,7 +3008,10 @@ void Zypper::processCommandOptions()
" --obsoletes Show obsoletes.\n"
" --recommends Show recommends.\n"
" --suggests Show suggests.\n"
), "package, patch, pattern, product", "package");
), "package, patch, pattern, product", "package") )
.option( "--filelist", _("Show the full filelist of the package.") )
.option( "--changelog", _("If a update candidate is available show the new changelog entries, otherwise show the first 10."))
.option( "--full-changelog", _("Show the full changelog."));

break;
}
Expand Down
65 changes: 65 additions & 0 deletions src/callbacks/package.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*---------------------------------------------------------------------------*\
____ _ _ __ _ __ ___ _ _
|_ / || | '_ \ '_ \/ -_) '_|
/__|\_, | .__/ .__/\___|_|
|__/|_| |_|
\*---------------------------------------------------------------------------*/

#ifndef ZMART_PACKAGE_CALLBACKS_H
#define ZMART_PACKAGE_CALLBACKS_H

#include <zypp/ZYppCallbacks.h>
#include <zypp/base/Logger.h>

#include "Zypper.h"

namespace ZmartRecipients
{
struct PackageHeadReportReceiver : public zypp::callback::ReceiveReport<zypp::PackageHeadReport>
{
virtual void report ( const UserData &data_r )
{
if ( data_r.type() == zypp::ContentType( zypp::PackageHeadReport::ACCEPT_PACKAGE_HEAD_DOWNLOAD ) ) {
if ( !data_r.hasvalue("PackageName") ) {
WAR << "Missing arguments in report call for content type: " << data_r.type() << endl;
return;
}
const std::string &name = data_r.get<std::string>("PackageName");
bool res = askUserAboutPackageHeadDownload( name );
data_r.set("Response", res);
return;
}
WAR << "Unhandled report() call" << endl;
}

bool askUserAboutPackageHeadDownload( const std::string &packageName_r ) {

Zypper::instance().out().info(
str::form( _("Some information is not available for package %s."), packageName_r.c_str() )
);

return read_bool_answer(
PROMPT_YN_DOWNLOAD_RPM_HEADER, _("Do you want to download the RPM header?"), true);
}
};
}

class PackageCallbacks {

private:
ZmartRecipients::PackageHeadReportReceiver _packageHeadDownloadReport;

public:
PackageCallbacks()
{
MIL << "Set package callbacks.." << std::endl;
_packageHeadDownloadReport.connect();
}

~PackageCallbacks()
{
_packageHeadDownloadReport.disconnect();
}
};

#endif
88 changes: 77 additions & 11 deletions src/info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
\*---------------------------------------------------------------------------*/

#include <iostream>
#include <sstream>

#include <zypp/base/Algorithm.h>
#include <zypp/ZYpp.h>
Expand All @@ -27,6 +28,7 @@

extern ZYpp::Ptr God;

void printHeader ( Zypper &zypper_r, const ui::Selectable &s_r );
void printPkgInfo( Zypper & zypper, const ui::Selectable & s );
void printPatchInfo( Zypper & zypper, const ui::Selectable & s );
void printPatternInfo( Zypper & zypper, const ui::Selectable & s );
Expand Down Expand Up @@ -253,17 +255,6 @@ void printInfo( Zypper & zypper, ResKindSet kinds_r )
{
const ui::Selectable & sel( *(*it) );

if ( zypper.out().type() != Out::TYPE_XML )
{
// TranslatorExplanation E.g. "Information for package zypper:"
std::string info = str::Format(_("Information for %s %s:"))
% kind_to_string_localized( sel.kind(), 1 )
% sel.name();

cout << endl << info << endl;
cout << std::string( mbs_width(info), '-' ) << endl;
}

if ( sel.kind() == ResKind::package ) { printPkgInfo( zypper, sel ); }
else if ( sel.kind() == ResKind::patch ) { printPatchInfo( zypper, sel ); }
else if ( sel.kind() == ResKind::pattern ) { printPatternInfo( zypper, sel ); }
Expand Down Expand Up @@ -294,9 +285,24 @@ void printDefaultInfo( Zypper & zypper, const ui::Selectable & s )
printCommonData( theone, p );

printSummaryDescDeps( theone, p );
printHeader ( zypper, s );
zypper.out().info( str::Str() << p );
}

void printHeader (Zypper &zypper_r, const ui::Selectable &s_r )
{
if ( zypper_r.out().type() != Out::TYPE_XML )
{
// TranslatorExplanation E.g. "Information for package zypper:"
std::string info = str::Format(_("Information for %s %s:"))
% kind_to_string_localized( s_r.kind(), 1 )
% s_r.name();

cout << endl << info << endl;
cout << std::string( mbs_width(info), '-' ) << endl;
}
}

/**
* Print package information.
* <p>
Expand All @@ -318,6 +324,7 @@ Description :
*/
void printPkgInfo( Zypper & zypper, const ui::Selectable & s )
{
const auto & cOpts( zypper.cOpts() );
PoolItem installed( s.installedObj() );
PoolItem updateCand( s.updateCandidateObj() );
// An updateCandidate is always better than any installed object.
Expand Down Expand Up @@ -358,6 +365,59 @@ void printPkgInfo( Zypper & zypper, const ui::Selectable & s )
p.add( _("Source package"), package->sourcePkgLongName() );

printSummaryDescDeps( theone, p );

if ( cOpts.count( "filelist" ) ) {
p.lst ( _("Filelist"), asKind<Package>( installed ? installed : theone )->filelist() );
}

if ( cOpts.count("changelog") || cOpts.count("full-changelog") ) {

std::list< std::string > entries;
bool fullChangelog = cOpts.count("full-changelog");

//show only the new entries if we have a installed and upgrade candidate
if ( !fullChangelog && updateCand && installed && !updateCand.identical(installed) ) {
Changelog installedLog = asKind<Package>( installed )->changelog();
Changelog updateLog = asKind<Package>( updateCand )->changelog();

Changelog::const_iterator instIt = installedLog.begin();
for ( Changelog::const_iterator updateIt = updateLog.begin();
updateIt != updateLog.end();
updateIt++) {

std::stringstream str;
str << *updateIt;
entries.push_back( str.str() );

if ( (*updateIt).date().operator time_t() == instIt->date() )
break;

// show max of 10 entries
if ( entries.size() >= 10 )
break;
}
} else {
Changelog log = asKind<Package>( theone )->changelog();

for ( const ChangelogEntry &entry : log ) {
std::stringstream str;
str << entry;
entries.push_back( str.str() );

// show max of 10 entries
if ( !fullChangelog && entries.size() >= 10 )
break;
}
}

if ( entries.size() ) {
p.lst ( _("Changelog"), entries );
} else {
p.addDetail ( _("Changelog"), _("No changelog available.") );
}
}

printHeader ( zypper, s );
zypper.out().info( str::Str() << p );
}

Expand Down Expand Up @@ -403,6 +463,7 @@ void printPatchInfo( Zypper & zypper, const ui::Selectable & s )
p.add( _("Interactive"), patchInteractiveFlags( *patch ) ); // print interactive flags the same style as list-patches

printSummaryDescDeps( theone, p );
printHeader ( zypper, s );
zypper.out().info( str::Str() << p );
}

Expand Down Expand Up @@ -488,6 +549,8 @@ void printPatternInfo( Zypper & zypper, const ui::Selectable & s )
p.addDetail( _("Contents"), str::Str() << t );
}
}

printHeader ( zypper, s );
zypper.out().info( str::Str() << p );
}

Expand Down Expand Up @@ -628,6 +691,8 @@ void printProductInfo( Zypper & zypper, const ui::Selectable & s )
p.add( _("Short Name"), product->shortName() );

printSummaryDescDeps( theone, p );

printHeader ( zypper, s );
zypper.out().info( str::Str() << p );
}

Expand Down Expand Up @@ -713,5 +778,6 @@ void printSrcPackageInfo( Zypper & zypper, const ui::Selectable & s )
}
///////////////////////////////////////////////////////////////////

printHeader ( zypper, s );
zypper.out().info( str::Str() << p );
}
2 changes: 2 additions & 0 deletions src/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "callbacks/media.h"
#include "callbacks/locks.h"
#include "callbacks/job.h"
#include "callbacks/package.h"
#include "output/OutNormal.h"
#include "utils/messages.h"

Expand Down Expand Up @@ -94,6 +95,7 @@ int main( int argc, char **argv )
static DigestCallbacks digest_callbacks;
static LocksCallbacks locks_callbacks;
static JobCallbacks job_callbacks;
static PackageCallbacks package_callbacks;
}
catch ( const Exception & e )
{
Expand Down
1 change: 1 addition & 0 deletions src/output/prompt.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ typedef enum
PR_ENUM(PROMPT_MEDIA_EJECT, 22)
PR_ENUM(PROMPT_PACKAGEKIT_QUIT, 23)
PR_ENUM(PROMPT_YN_CONTINUE_ON_FILECONFLICT, 24)
PR_ENUM(PROMPT_YN_DOWNLOAD_RPM_HEADER, 25)

#ifndef PROMPT_H_
#define PROMPT_H_
Expand Down

0 comments on commit 14706c0

Please sign in to comment.