prt-get: warn about unclear version decisions when using "prefer higher"

git-svn-id: https://crux.nu/svn/tools/prt-get/trunk@1806 0b5ae1c7-2405-0410-a7fc-ba219f786e1e
This commit is contained in:
Johannes Winkelmann 2006-09-03 16:12:55 +00:00
parent dba4b5e64e
commit 01f7f05e78
5 changed files with 172 additions and 76 deletions

View File

@ -1,3 +1,8 @@
* 0.5.13 00.09.2006 Johannes Winkelmann
- Show undecided versions in diff and sysup when using "prefer higher"
- fix display bug in "dependent"
- fix bug in version comparator
* 0.5.12 00.04.2006 Johannes Winkelmann * 0.5.12 00.04.2006 Johannes Winkelmann
- Add 'depinst' in 'help' (thanks Simone) - Add 'depinst' in 'help' (thanks Simone)
- Fix compilation on OpenBSD - Fix compilation on OpenBSD

View File

@ -130,6 +130,13 @@ const bool Package::hasReadme() const
return m_data->hasReadme; return m_data->hasReadme;
} }
/*! \return a typically formatted version-release string */
string Package::versionReleaseString() const
{
load();
return m_data->versionReleaseString;
}
const bool Package::hasPreInstall() const const bool Package::hasPreInstall() const
{ {
return m_data->hasPreInstall; return m_data->hasPreInstall;
@ -162,10 +169,10 @@ void Package::load() const
const int length = BUFSIZ; const int length = BUFSIZ;
char input[length]; char input[length];
string line; string line;
time_t timeNow; time_t timeNow;
time(&timeNow); time(&timeNow);
struct utsname unameBuf; struct utsname unameBuf;
if (uname(&unameBuf) != 0) { if (uname(&unameBuf) != 0) {
unameBuf.release[0] = '\0'; unameBuf.release[0] = '\0';
@ -235,6 +242,7 @@ void Package::load() const
} }
fclose( fp ); fclose( fp );
m_data->generateVersionReleaseString();
string file = m_data->path + "/" + m_data->name + "/README"; string file = m_data->path + "/" + m_data->name + "/README";
struct stat buf; struct stat buf;
@ -282,29 +290,36 @@ PackageData::PackageData( const string& name_,
maintainer( maintainer_ ) maintainer( maintainer_ )
{ {
generateVersionReleaseString();
hasReadme = ( stripWhiteSpace( hasReadme_ ) == "yes" ); hasReadme = ( stripWhiteSpace( hasReadme_ ) == "yes" );
hasPreInstall = ( stripWhiteSpace( hasPreInstall_ ) == "yes" ); hasPreInstall = ( stripWhiteSpace( hasPreInstall_ ) == "yes" );
hasPostInstall = ( stripWhiteSpace( hasPostInstall_ ) == "yes" ); hasPostInstall = ( stripWhiteSpace( hasPostInstall_ ) == "yes" );
} }
void PackageData::generateVersionReleaseString()
{
versionReleaseString = version + "-" + release;
}
void Package::expandShellCommands(std::string& input,
void Package::expandShellCommands(std::string& input,
const time_t& timeNow, const time_t& timeNow,
const struct utsname unameBuf) const struct utsname unameBuf)
{ {
// TODO: consider dropping either of the tagsets, depending on feedback // TODO: consider dropping either of the tagsets, depending on feedback
static const int TAG_COUNT = 2; static const int TAG_COUNT = 2;
string startTag[TAG_COUNT] = { "`", "$(" }; string startTag[TAG_COUNT] = { "`", "$(" };
string endTag[TAG_COUNT] = { "`", ")" }; string endTag[TAG_COUNT] = { "`", ")" };
for (int i = 0; i < TAG_COUNT; ++i) { for (int i = 0; i < TAG_COUNT; ++i) {
string::size_type pos; string::size_type pos;
while ((pos = input.find(startTag[i])) != string::npos) { while ((pos = input.find(startTag[i])) != string::npos) {
if (unameBuf.release) { if (unameBuf.release) {
input = replaceAll(input, input = replaceAll(input,
startTag[i] + "uname -r" + endTag[i], startTag[i] + "uname -r" + endTag[i],
unameBuf.release); unameBuf.release);
} }
@ -314,9 +329,9 @@ void Package::expandShellCommands(std::string& input,
string::size_type startpos, endpos; string::size_type startpos, endpos;
endpos = input.find(endTag[i], pos+1); endpos = input.find(endTag[i], pos+1);
startpos = input.find('+', pos+1); startpos = input.find('+', pos+1);
string format = input.substr(startpos+1, endpos-startpos-1); string format = input.substr(startpos+1, endpos-startpos-1);
// support date '+...' and date "+..." // support date '+...' and date "+..."
int len = format.length(); int len = format.length();
if (format[len-1] == '\'' || format[len-1] == '"') { if (format[len-1] == '\'' || format[len-1] == '"') {
@ -325,7 +340,7 @@ void Package::expandShellCommands(std::string& input,
char timeBuf[32]; char timeBuf[32];
strftime(timeBuf, 32, format.c_str(), localtime(&timeNow)); strftime(timeBuf, 32, format.c_str(), localtime(&timeNow));
input = input.substr(0, pos) + timeBuf + input = input.substr(0, pos) + timeBuf +
input.substr(endpos+1); input.substr(endpos+1);
} }
} }

View File

@ -55,14 +55,16 @@ public:
const bool hasReadme() const; const bool hasReadme() const;
const bool hasPreInstall() const; const bool hasPreInstall() const;
const bool hasPostInstall() const; const bool hasPostInstall() const;
std::string versionReleaseString() const;
void setDependencies( const std::string& dependencies ); void setDependencies( const std::string& dependencies );
private: private:
void load() const; void load() const;
static void expandShellCommands(std::string& input, static void expandShellCommands(std::string& input,
const time_t& timeNow, const time_t& timeNow,
const struct utsname unameBuf); const struct utsname unameBuf);
@ -96,9 +98,13 @@ struct PackageData
std::string packager; std::string packager;
std::string maintainer; std::string maintainer;
std::string versionReleaseString;
bool hasReadme; bool hasReadme;
bool hasPreInstall; bool hasPreInstall;
bool hasPostInstall; bool hasPostInstall;
void generateVersionReleaseString();
}; };
#endif /* _PACKAGE_H_ */ #endif /* _PACKAGE_H_ */

View File

@ -40,6 +40,12 @@ using namespace std;
using namespace StringHelper; using namespace StringHelper;
using VersionComparator::COMP_RESULT;
using VersionComparator::GREATER;
using VersionComparator::LESS;
using VersionComparator::EQUAL;
using VersionComparator::UNDEFINED;
const string PrtGet::CONF_FILE = SYSCONFDIR"/prt-get.conf"; const string PrtGet::CONF_FILE = SYSCONFDIR"/prt-get.conf";
const string PrtGet::DEFAULT_CACHE_FILE = LOCALSTATEDIR"/lib/pkg/prt-get.cache"; const string PrtGet::DEFAULT_CACHE_FILE = LOCALSTATEDIR"/lib/pkg/prt-get.cache";
@ -148,7 +154,7 @@ void PrtGet::printUsage()
cout << " --all list all dependent packages, not " cout << " --all list all dependent packages, not "
<< "only installed" << endl; << "only installed" << endl;
cout << " --recursive print recursive listing" << endl; cout << " --recursive print recursive listing" << endl;
cout << " --tree print recursive tree listing" cout << " --tree print recursive tree listing"
<< endl; << endl;
cout << "\nSEARCHING" << endl; cout << "\nSEARCHING" << endl;
@ -792,14 +798,17 @@ void PrtGet::printQuickDiff()
const map<string, string>& installed = m_pkgDB->installedPackages(); const map<string, string>& installed = m_pkgDB->installedPackages();
map<string, string>::const_iterator it = installed.begin(); map<string, string>::const_iterator it = installed.begin();
const Package* p = 0; const Package* p = 0;
COMP_RESULT result;
for ( ; it != installed.end(); ++it ) { for ( ; it != installed.end(); ++it ) {
if ( !m_locker.isLocked( it->first ) ) { if ( !m_locker.isLocked( it->first ) ) {
p = m_repo->getPackage( it->first ); p = m_repo->getPackage( it->first );
if ( p ) { if ( p ) {
if (greaterThan(p->version() + "-" + p->release(), result = compareVersions(p->versionReleaseString(),
it->second)) { it->second);
if (result == GREATER) {
cout << it->first.c_str() << " "; cout << it->first.c_str() << " ";
} }
// we don't care about undefined diffs here
} }
} }
} }
@ -807,6 +816,28 @@ void PrtGet::printQuickDiff()
} }
void PrtGet::printFormattedDiffLine(const string& name,
const string& version1,
const string& version2,
bool isLocked)
{
cout.setf( ios::left, ios::adjustfield );
cout.width( 20 );
cout.fill( ' ' );
cout << name;
cout.width( 20 );
cout.fill( ' ' );
cout << version1;
string locked = "";
if ( isLocked ) {
locked = "locked";
}
cout.width( 20 );
cout.fill( ' ' );
cout << version2 << locked << endl;
}
/*! /*!
print an overview of port which are installed in a different version print an overview of port which are installed in a different version
than they are in the repository than they are in the repository
@ -843,6 +874,7 @@ void PrtGet::printDiff()
map<string, string>::const_iterator it = installed.begin(); map<string, string>::const_iterator it = installed.begin();
const Package* p = 0; const Package* p = 0;
int count = 0; int count = 0;
COMP_RESULT result;
for ( ; it != installed.end(); ++it ) { for ( ; it != installed.end(); ++it ) {
p = m_repo->getPackage( it->first ); p = m_repo->getPackage( it->first );
@ -851,8 +883,9 @@ void PrtGet::printDiff()
continue; continue;
} }
if ( greaterThan( p->version() + "-" + p->release(), result = compareVersions( p->versionReleaseString(),
it->second ) ) { it->second );
if (result == GREATER ) {
if ( !m_locker.isLocked( it->first ) || if ( !m_locker.isLocked( it->first ) ||
m_parser->otherArgs().size() > 0 || m_parser->otherArgs().size() > 0 ||
m_parser->all() ) { m_parser->all() ) {
@ -862,39 +895,46 @@ void PrtGet::printDiff()
if ( count == 1 ) { if ( count == 1 ) {
cout << "Differences between installed packages " cout << "Differences between installed packages "
<< "and ports tree:\n" << endl; << "and ports tree:\n" << endl;
cout.setf( ios::left, ios::adjustfield ); printFormattedDiffLine("Port",
cout.width( 20 ); "Installed",
cout.fill( ' ' ); "Available in the ports tree",
cout << "Ports"; false);
cout.width( 20 ); cout << endl;
cout.fill( ' ' );
cout << "Installed";
cout.width( 20 );
cout.fill( ' ' );
cout << "Available in the ports tree" << endl << endl;
} }
cout.setf( ios::left, ios::adjustfield );
cout.width( 20 );
cout.fill( ' ' );
cout << it->first.c_str();
cout.width( 20 ); printFormattedDiffLine(it->first,
cout.fill( ' ' ); it->second,
cout << it->second.c_str(); p->versionReleaseString(),
m_locker.isLocked( it->first ));
string locked = "";
if ( m_locker.isLocked( it->first ) ) {
locked = "locked";
}
cout.width( 20 );
cout.fill( ' ' );
cout << (p->version()+"-"+p->release()).c_str()
<< locked << endl;
} }
} else if (result == UNDEFINED) {
m_undefinedVersionComp.push_back(make_pair(p, it->second));
} }
} }
} }
if (m_undefinedVersionComp.size()) {
cout << "\n\n" << "Undecidable version differences (use --strict-diff)"
<< endl << endl;
printFormattedDiffLine("Port",
"Installed",
"Available in the ports tree",
false);
cout << endl;
list< pair< const Package*, string > >::iterator it =
m_undefinedVersionComp.begin();
const Package* p;
for (; it != m_undefinedVersionComp.end(); ++it) {
p = it->first;
printFormattedDiffLine(p->name(),
p->versionReleaseString(),
it->second,
false);
}
}
if ( count == 0 ) { if ( count == 0 ) {
cout << "No differences found" << endl; cout << "No differences found" << endl;
} }
@ -920,8 +960,8 @@ void PrtGet::printPath()
/*! helper method to print the result of an InstallTransaction */ /*! helper method to print the result of an InstallTransaction */
void PrtGet::evaluateResult( InstallTransaction& transaction, void PrtGet::evaluateResult( InstallTransaction& transaction,
bool update, bool update,
bool interrupted ) bool interrupted )
{ {
int errors = 0; int errors = 0;
@ -942,7 +982,6 @@ void PrtGet::evaluateResult( InstallTransaction& transaction,
} }
} }
const list< pair<string, string> >& missing = transaction.missing(); const list< pair<string, string> >& missing = transaction.missing();
if ( missing.size() ) { if ( missing.size() ) {
++errors; ++errors;
@ -1017,6 +1056,7 @@ void PrtGet::evaluateResult( InstallTransaction& transaction,
cout << endl; cout << endl;
} }
// readme's // readme's
if ( atLeastOnePackageHasReadme ) { if ( atLeastOnePackageHasReadme ) {
if ( m_config->readmeMode() == Configuration::VERBOSE_README ) { if ( m_config->readmeMode() == Configuration::VERBOSE_README ) {
@ -1031,9 +1071,25 @@ void PrtGet::evaluateResult( InstallTransaction& transaction,
} }
} }
} }
cout << endl;
} }
if ( m_undefinedVersionComp.size() ) {
cout << endl
<< "-- Packages with undecidable version "
<< "difference (use --strict-diff)"
<< endl;
list< pair<const Package*, string> >::const_iterator uit =
m_undefinedVersionComp.begin();
const Package * p;
for ( ; uit != m_undefinedVersionComp.end(); ++uit ) {
p = uit->first;
cout << p->name() << " ("
<< p->versionReleaseString()
<< " vs "
<< uit->second << ")" << endl;
}
}
cout << endl;
if ( errors == 0 && !interrupted ) { if ( errors == 0 && !interrupted ) {
cout << "prt-get: " << command[1] << " successfully" << endl; cout << "prt-get: " << command[1] << " successfully" << endl;
@ -1093,23 +1149,23 @@ void PrtGet::createCache()
/*! /*!
\return true if v1 is greater than v2 \return true if v1 is greater than v2
*/ */
bool PrtGet::greaterThan( const string& v1, const string& v2 ) COMP_RESULT PrtGet::compareVersions( const string& v1, const string& v2 )
{ {
using namespace VersionComparator;
if (v1 == v2) { if (v1 == v2) {
return false; return EQUAL;
} }
if (m_parser->preferHigher() || if (m_parser->preferHigher() ||
(m_config->preferHigher() && !m_parser->strictDiff())) { (m_config->preferHigher() && !m_parser->strictDiff())) {
COMP_RESULT result = compareVersions(v1, v2); COMP_RESULT result = VersionComparator::compareVersions(v1, v2);
return (result == GREATER); return result;
} }
return v1 != v2; if (v1 != v2)
return GREATER;
return LESS;
} }
int PrtGet::returnValue() const int PrtGet::returnValue() const
@ -1172,7 +1228,7 @@ void PrtGet::printf()
if ( m_pkgDB->isInstalled( p->name() ) ) { if ( m_pkgDB->isInstalled( p->name() ) ) {
string ip = p->name() + "-" + string ip = p->name() + "-" +
m_pkgDB->getPackageVersion( p->name() ); m_pkgDB->getPackageVersion( p->name() );
if ( ip == p->name() + "-" + p->version() + "-" + p->release() ) { if ( ip == p->name() + "-" + p->versionReleaseString() ) {
isInst = "yes"; isInst = "yes";
} else { } else {
isInst = "diff"; isInst = "diff";
@ -1255,15 +1311,15 @@ void PrtGet::printDependent()
initRepo(); initRepo();
string arg = *(m_parser->otherArgs().begin()); string arg = *(m_parser->otherArgs().begin());
if (m_parser) { if (m_parser->printTree()) {
cout << arg << endl; cout << arg << endl;
printDependent(arg, 2); printDependent(arg, 2);
} else { } else {
printDependent(arg, 0); printDependent(arg, 0);
} }
} }
void PrtGet::printDependent(const string& dep, int level) void PrtGet::printDependent(const string& dep, int level)
{ {
map<string, Package*>::const_iterator it = m_repo->packages().begin(); map<string, Package*>::const_iterator it = m_repo->packages().begin();
@ -1294,7 +1350,7 @@ void PrtGet::printDependent(const string& dep, int level)
// a -> b -> d // a -> b -> d
// \ ^ // \ ^
// > c / // > c /
// //
// trying to rebuild 'd' before 'c' might possibly fail // trying to rebuild 'd' before 'c' might possibly fail
string indent = ""; string indent = "";
if (m_parser->printTree()) { if (m_parser->printTree()) {
@ -1305,26 +1361,26 @@ void PrtGet::printDependent(const string& dep, int level)
set<const Package*>::iterator it2 = dependent.begin(); set<const Package*>::iterator it2 = dependent.begin();
for ( ; it2 != dependent.end(); ++it2 ) { for ( ; it2 != dependent.end(); ++it2 ) {
const Package* p = *it2; const Package* p = *it2;
if (m_parser->recursive() && !m_parser->printTree()) { if (m_parser->recursive() && !m_parser->printTree()) {
if (shownMap[p->name()]) { if (shownMap[p->name()]) {
continue; continue;
} }
shownMap[p->name()] = true; shownMap[p->name()] = true;
} }
if ( m_parser->all() || m_pkgDB->isInstalled( p->name() ) ) { if ( m_parser->all() || m_pkgDB->isInstalled( p->name() ) ) {
cout << indent << p->name(); cout << indent << p->name();
if ( m_parser->verbose() > 0 ) { if ( m_parser->verbose() > 0 ) {
cout << " " << p->version() << "-" << p->release(); cout << " " << p->versionReleaseString();
} }
if ( m_parser->verbose() > 1 ) { if ( m_parser->verbose() > 1 ) {
cout << ": " << p->description(); cout << ": " << p->description();
} }
cout << endl; cout << endl;
if (m_parser->recursive()) { if (m_parser->recursive()) {
printDependent( p->name(), level+2 ); printDependent( p->name(), level+2 );
} }
@ -1338,7 +1394,7 @@ void PrtGet::listOrphans()
map<string, string> installed = m_pkgDB->installedPackages(); map<string, string> installed = m_pkgDB->installedPackages();
map<string, bool> required; map<string, bool> required;
map<string, string>::iterator it = installed.begin(); map<string, string>::iterator it = installed.begin();
for (; it != installed.end(); ++it) { for (; it != installed.end(); ++it) {
list<string> tokens; list<string> tokens;
const Package* p = m_repo->getPackage(it->first); const Package* p = m_repo->getPackage(it->first);
@ -1349,12 +1405,12 @@ void PrtGet::listOrphans()
required[*lit] = true; required[*lit] = true;
} }
} }
} }
// - we could store the package pointer in another map to avoid // - we could store the package pointer in another map to avoid
// another getPackage lockup, but it seems better to optimized for // another getPackage lockup, but it seems better to optimized for
// memory since it's only used when called with -vv // memory since it's only used when called with -vv
it = installed.begin(); it = installed.begin();
for (; it != installed.end(); ++it) { for (; it != installed.end(); ++it) {
if (!required[it->first]) { if (!required[it->first]) {
@ -1393,13 +1449,17 @@ void PrtGet::sysup()
const map<string, string>& installed = m_pkgDB->installedPackages(); const map<string, string>& installed = m_pkgDB->installedPackages();
map<string, string>::const_iterator it = installed.begin(); map<string, string>::const_iterator it = installed.begin();
const Package* p = 0; const Package* p = 0;
COMP_RESULT result;
for ( ; it != installed.end(); ++it ) { for ( ; it != installed.end(); ++it ) {
if ( !m_locker.isLocked( it->first ) ) { if ( !m_locker.isLocked( it->first ) ) {
p = m_repo->getPackage( it->first ); p = m_repo->getPackage( it->first );
if ( p ) { if ( p ) {
if ( greaterThan( p->version() + "-" + p->release(), result = compareVersions( p->versionReleaseString(),
it->second ) ) { it->second );
if (result == GREATER ) {
packagesToUpdate.push_back( it->first ); packagesToUpdate.push_back( it->first );
} else if (result == UNDEFINED ) {
m_undefinedVersionComp.push_back(make_pair(p, it->second));
} }
} }
} }
@ -1906,7 +1966,7 @@ void PrtGet::printDepsLevel(int indent, const Package* package)
} }
const Package* p = m_repo->getPackage( *it ); const Package* p = m_repo->getPackage( *it );
if (p) { if (p) {
if (p->dependencies().length() > 0) { if (p->dependencies().length() > 0) {
map<string, bool>::iterator shownIt = shownMap.find(*it); map<string, bool>::iterator shownIt = shownMap.find(*it);
if (shownIt != shownMap.end()) { if (shownIt != shownMap.end()) {
cout << " -->" << endl;; cout << " -->" << endl;;

View File

@ -25,6 +25,7 @@ using namespace std;
#include "signaldispatcher.h" #include "signaldispatcher.h"
#include "locker.h" #include "locker.h"
#include "installtransaction.h" #include "installtransaction.h"
#include "versioncomparator.h"
/*! /*!
\class PrtGet \class PrtGet
@ -44,7 +45,7 @@ public:
PG_INSTALL_ERROR, PG_INSTALL_ERROR,
PG_PARTIAL_INSTALL_ERROR PG_PARTIAL_INSTALL_ERROR
}; };
PrtGet( const ArgParser* parser ); PrtGet( const ArgParser* parser );
~PrtGet(); ~PrtGet();
@ -97,7 +98,7 @@ public:
protected: protected:
void printDepsLevel(int indent, const Package* package); void printDepsLevel(int indent, const Package* package);
void printDependent(const std::string& dep, int level); void printDependent(const std::string& dep, int level);
void executeTransaction( InstallTransaction& transaction, void executeTransaction( InstallTransaction& transaction,
@ -116,6 +117,12 @@ protected:
list<string>& target ); list<string>& target );
void warnPackageNotFound(InstallTransaction& transaction); void warnPackageNotFound(InstallTransaction& transaction);
static void printFormattedDiffLine(const string& name,
const string& version1,
const string& version2,
bool locked);
Repository* m_repo; Repository* m_repo;
PkgDB* m_pkgDB; PkgDB* m_pkgDB;
@ -144,8 +151,11 @@ protected:
void assertExactArgCount(int count); void assertExactArgCount(int count);
void argCountFailure(int count, const string& specifier); void argCountFailure(int count, const string& specifier);
bool greaterThan( const string& v1, const string& v2 ); VersionComparator::COMP_RESULT
compareVersions( const string& v1, const string& v2 );
static bool printFile(const string& file); static bool printFile(const string& file);
std::list< std::pair<const Package*, std::string> > m_undefinedVersionComp;
}; };
#endif /* _PRTGET_H_ */ #endif /* _PRTGET_H_ */