cut down on duplicate code; fix FS#1930; expand man-page examples

This commit is contained in:
John McQuah 2023-03-19 16:47:11 -04:00
parent 8ac36484c5
commit f2c0f370d4
13 changed files with 848 additions and 1156 deletions

View File

@ -1,5 +1,14 @@
* 19.03.2023 John McQuah
- switch between install and update on a port-by-port basis, whichever is needed
- allow dependency injection during sysup (controllable via --nodeps)
- check whether a built package already exists before calling pkgmk
- consolidate printDependent and printDepTree
- consolidate sysup, printQuickDiff, and printDiff
- let the argParser recognize some synonyms for old commands
- assign meanings to --nodeps and --depsort for other subroutines
* 10.03.2023 John McQuah
- make it possible to consider optional dependencies when updating
- make it possible for the dependency resolver to consider optionals
- bump version of the cache file format, to warn users about the
'Packager' field being replaced by 'Optional'

View File

@ -75,33 +75,26 @@ non-option argument passed. This is very similar to
.TP
.B install [\-\-margs] [\-\-aargs] [\-\-log] <package1> [<package2> ...]
install all packages in the listed order. Note that you can do this
from any directory.
.B install [\-\-margs] [\-\-aargs] [\-\-log] [\-\-nodeps] [\-\-softdeps] <package1> [<package2> ...]
install or update the packages given on the command line. Note that you can do
this from any directory. Pass the --nodeps flag to prevent \fBprt\-get\fP from
resolving dependencies and injecting any needed ports into the list of targets.
Pass the --softdeps flag if you want the dependency resolver to also consider
the "Optional" relationships among the packages given on the command line.
.TP
.B depinst [\-\-margs] [\-\-aargs] [\-\-log] [\-\-softdeps] <package1> [<package2> ...]
install all packages given on the command line, including their dependencies.
Passing the --softdeps flag tells \fBprt-get\fP to consider also the optional
dependencies when sorting. Note that already-installed packages will be left
at their current version, even if out of date. prt\-get depinst behaves this
way because all of its child pkgadd processes will \fBlack\fP the \-u flag,
which is needed when updating an already-installed package.
Basically a synonym for install (without the --nodeps flag).
.TP
.B update [\-\-margs] [\-\-aargs] [\-\-log] <package1> [<package2> ...]
update all packages listed in this order. Note: if the latest version of
a package has acquired dependencies that were not needed by the currently-installed
version and are not present on the system, the update command will not attempt to
resolve this omission. prt-get update behaves this way because pkgadd invocations
inherit the flag -u for every package in the transaction, causing an error if
the package is not already installed. You can follow the CRUX mailing list or the
IRC channels to stay informed of the situations where an update will require manual
intervention, or filter the output of
.B prt\-get quickdep $(prt\-get quickdiff)
through \fBprt\-get isinst\fP to get a list of packages suitable for an
\fBinstall\fP or \fBupdate\fP command.
See the \fBEXAMPLES\fP section below for details.
.B update [\-\-margs] [\-\-aargs] [\-\-log] [\-\-softdeps] <package1> [<package2> ...]
Basically a synonym for install. Earlier versions of \fBprt\-get\fP did not adjust
the \fBpkgadd(8)\fP arguments on a package-by-package basis, but applied "install
mode" or "update mode" to the entire transaction. This latest \fBprt\-get\fP
interprets the install command less rigidly, and tries to sync your installed
ports with their repository versions unless instructed otherwise (using
\fBprt\-get lock\fP, the --prefer-higher option, or the \fIprt-get.aliases\fP
file).
.TP
.B remove <package1> [<package2> ...]
@ -112,14 +105,13 @@ remove packages listed in this order
Update all installed packages which are outdated. Sorts by hard dependencies
by default. Passing the --softdeps switch tells \fBprt\-get\fP to also consider
optional dependencies when sorting. Passing the --nodeps switch tells prt-get
not to sort by dependencies at all, for approximately the same effect as
.B prt\-get update $(prt\-get quickdiff).
As with an \fBupdate\fP command, the child \fBpkgadd\fP processes will
inherit the \-u flag, so if a port has acquired new dependencies since
its last successful build, those new dependencies will be omitted from
the transaction (unless they happen to be installed for some other reason and
are also in need of an update). See the \fBEXAMPLES\fP section for a way to
automate the resolution of such omissions. Also see the
not to sort by dependencies at all.
.B Breaking Change:
If a port has acquired new dependencies since its last successful build,
those new dependencies will be injected into the transaction. This feature
lingered many years on the TODO list, and its absence was the motivation for
many clever workarounds (documented in the \fBEXAMPLES\fP section below).
You can use the
.B lock
and
.B unlock
@ -166,15 +158,9 @@ prints a simple list of packages which have a different version in the
ports tree than what is installed. The output is sorted alphabetically,
but you can generate a (larger) list sorted by dependencies using
.B prt\-get quickdep $(prt\-get quickdiff).
Note that the resulting list is usually a mix of installed and
not-installed packages, so it must be filtered by
.B prt\-get isinst
before being passed as argument to prt\-get install or prt\-get update. See the
.B EXAMPLES
section below.
If you want to see only diffs which have a lower version installed than the one in
the ports tree, use the --prefer-higher option.
If you want to see only diffs which have a lower version installed than
the one in the ports tree, use the --prefer-higher option.
.TP
.B search [\-v|\-vv] [\-\-path] [\-\-regex] <expr>
@ -202,7 +188,6 @@ will change in prt-get 0.6, where full path search will be the
default. Pattern can be a shell-like wildcard pattern (e.g. prt-get
fsearch "*.h") or a regular expression (e.g. prt-get fsearch --regex 'liblz(o2|ma).*')
.TP
.B info <port>
Print available info for a port
@ -231,7 +216,7 @@ if you don't want to filter out manually the ports that are invalid targets for
installation. For example, instead of
.B prt\-get depinst xorg-server
you might micromanage the process as follows:
.B for i in $(prt\-get quickdep xorg-server); do if prt\-get isinst $i 2>/dev/null; then prt\-get update \-fr $i; else prt\-get install $i; fi; done
.B for i in $(prt\-get quickdep xorg-server); do prt\-get install \-fr \-\-nodeps $i; done
which ensures that the latest version of each dependency is built.
Note: It might be useful to run
@ -409,13 +394,9 @@ but does not print the version information. This command has a return value of
greater than 0.
.TP
.B current <package>
.B current <package1> [<package2> ...]
Shows the currently-installed version of <package>, or a message
that <package> is not installed. Unlike
.B prt\-get isinst package1 package2,
this command does \fBnot\fP accept more than one package as argument. Use
.B pkginfo \-i| grep \-E '^(package1|package2|...)'
to work around this limitation.
that <package> is not installed.
.TP
.B ls [\-\-path] <package>
@ -423,7 +404,8 @@ Prints out a listing of the port's directory
.TP
.B cat <package> [<file>]
Prints out the file to stdout. If <file> is not specified, 'Pkgfile' is used. If set, uses $PAGER.
Prints out the file to stdout. If <file> is not specified, 'Pkgfile' is used.
If set, uses $PAGER.
.TP
.B edit <package> [<file>]
@ -465,14 +447,6 @@ Force install; Implies 'pkgadd -f'; same as --aargs=-f
.B \-fr
Force rebuild, Implies 'pkgmk -f'; same as --margs=-f
.TP
.B \-um
Update md5sum, implies 'pkgmk -um'; same as --margs=-um
.TP
.B \-im
Ignore md5sum, implies 'pkgmk -im'; same as --margs=-im
.TP
.B \-us
Update signature, implies 'pkgmk -us'; same as --margs=-us
@ -515,6 +489,11 @@ future uses and consistency reasons
.B \-\-ignore=<package1,package2,...>
Don't install these packages, even if they're listed as dependencies
.TP
.B \-\-nodeps
Leave the list of requested ports as-is, without sorting by dependencies
or injecting missing dependencies.
.TP
.B \-\-softdeps
Consider optional dependencies when determining the order in which to build
@ -623,29 +602,38 @@ See man prt\-get.conf(5)
.SH "EXAMPLES"
.TP
.B prt\-get install irssi
Download, build and install irssi, with one simple command
Download, build and install irssi (and any of its missing dependencies), with
one simple command
.TP
.B prt\-get install paper yasm
Install paper and yasm. Abort with an informative error message if either package is already
installed, allowing you to issue a revised command.
.B prt\-get install --nodeps jasper
Install jasper, without trying to resolve dependencies.
.TP
.B prt\-get update bmake cmake
Update bmake and cmake. Abort with an informative error message if either package is not yet
installed, allowing you to issue a revised command.
.B prt\-get update --softdeps webkitgtk
Get the latest version of webkitgtk, rebuilding any of its outdated dependencies
(hard and soft) in the optimal order.
.TP
.B prt\-get update -fr openssh
Update your current version of openssh, forcing a rebuild even if no version difference is detected.
Useful if there was a major version change in one of its dependencies, and \fBrevdep openssh\fP
indicates a broken package. :\-)
Update your current version of openssh, forcing a rebuild even if no version
difference is detected.
Useful if there was a major soversion change in one of its dependencies,
and \fBrevdep openssh\fP indicates a broken package. :\-)
.TP
.B MISSLIBS=$(revdep -vvv mpv | awk -v FS=: '/(missing library)/ {print $3}'); [ -n \(dq${MISSLIBS[@]}\(dq ] && for i in ${MISSLIBS[@]}; do prt\-get fsearch $i; done
(adapted from a script by ppetrov^) Check for the presence of the runtime libraries needed by mpv.
If any are absent, search the footprints to determine which ports provide the missing libraries.
.TP
.B prt\-get printf '%i:%p:%n\en' | awk -v FS=: '/^diff:\e/usr\e/ports\e/core/ { print $3 }' | xargs prt\-get update
Basically a \fBsysup\fP operation, but restricted to the core collection.
Because core ports are often omitted from the dependency line if they aren't
dynamically linked in, the \fBsysup\fP sorting algorithm might not put them
at the front of the queue. Run this command before a regular \fBsysup\fP in
order to ensure that core ports are updated first.
.TP
.B prt\-get isinst $(prt-get info ffmpeg | awk -v FS=: '/^Optional/ {gsub(/,/,\(dq \(dq,$2); print $2}') | awk -v FS=\(dq \(dq '/not installed/ {print $2}'
Show all the optional dependencies of ffmpeg that are not currently installed.
@ -663,12 +651,13 @@ place.
Extension of the above (addressing a use case envisioned by ivandi). The
user can create the file /etc/prt-get.softdeps containing a line like
.B ffmpeg: x264 x265
and then the above command will perform a depinst --group operation to ensure that
at least x264 and x265 (but not necessarily any of the other optional
dependencies) are present before trying to build ffmpeg. In the absence of such
a .softdeps config, the operation reverts to the behaviour of the preceding
example (maximal feature set). Implementing Gentoo USE flags with such an
awkward one-liner might draw criticism from advocates of the KISS principle.
and then the above command will perform a depinst --group operation to
ensure that at least x264 and x265 (but not necessarily any of the other
optional dependencies) are present before trying to build ffmpeg. In the
absence of such a .softdeps config, the operation reverts to the behaviour
of the preceding example (maximal feature set). Implementing Gentoo USE
flags with such an awkward one-liner might draw criticism from advocates of
the KISS principle.
.TP
.B prt\-get search \-\-regex '^(m|n|p)c.*'
@ -686,46 +675,45 @@ shells (like bash) that support process substitution
.TP
.B comm -13 <(cat ~/.keepers <(ls /usr/ports/core) | sort) <(prt\-get listorphans) | xargs prt\-get remove
(system-hosing extension of the above) A one-liner inspired by \fBpkg\-clean\fP
and \fBpkgfoster\fP, but without the safeguard of interactivity. \fBDo not try this on a
mission-critical system.\fP
and \fBpkgfoster\fP, but without the safeguard of interactivity.
\fBDo not try this on a mission-critical system.\fP
.TP
.B prt\-get isinst $(prt\-get quickdep $(prt\-get quickdiff)) | awk '/not installed/ {print $2}'
(adapted from a comment by Fun) After updating your ports tree, print out a list of dependencies
that were not needed the last time you built your currently-installed ports, but are needed now by
the newer versions of these ports. The output of this command is sorted by dependencies, therefore
(adapted from a comment by Fun) After updating your ports tree, print out a
list of dependencies that were not needed the last time you built your
currently-installed ports, but are needed now by the newer versions of
these ports. The output of this command is sorted by dependencies, therefore
suitable for piping to \fBxargs prt\-get install\fP.
.TP
.B prt\-get isinst $(prt\-get quickdep $(prt\-get quickdiff)) | awk '/is installed/ {print $2}'
Same as above, but only print the dependencies that are already installed. The output of this
command is suitable for piping to \fBxargs prt\-get update\fP.
.TP
.B prt\-get printf \(dq%p\et%u\en\(dq | grep myrepo | cut -f 2
Print the upstream URL for each port in the collection \(dqmyrepo\(dq, perhaps as the first step in
keeping your personal overlay up to date.
Print the upstream URL for each port in the collection \(dqmyrepo\(dq,
perhaps as the first step in keeping your personal overlay up to date.
.TP
.B prt\-get printf \(dq%M\et%n\en\(dq | grep ^Tim | wc -l
Count how many ports our most-overworked core team member claims responsibility for.
Count how many ports our most-overworked core team member claims
responsibility for.
.TP
.B comm -13 <(prt\-get depends firefox-bin |tail -n +2 |sort) <(prt\-get depends firefox |tail -n +2 |sort)
Find the build-time dependencies of firefox. Runtime dependencies would also appear in the list generated by
the first process substitution, and \fBcomm -13\fP will suppress what the two lists have in common.
Find the build-time dependencies of firefox. Runtime dependencies would
also appear in the list generated by the first process substitution, and
\fBcomm -13\fP will suppress what the two lists have in common.
.TP
.B prt-get listinst \-\-depsort | xargs prt-get install \-\-install\-root=/mnt
Sort the list of installed packages by dependencies, and then install all
those packages onto a backup filesystem (mounted at /mnt). If you have a customized
pkgadd.conf that you want applied to this operation, either copy it to
/mnt/etc where pkgadd will be looking for it, or pass the additional option \-\-aargs=\(dq\-c
/etc/pkgadd.conf\(dq to the install command.
those packages onto a backup filesystem (mounted at /mnt). If you have a
customized pkgadd.conf that you want applied to this operation, either copy
it to /mnt/etc where pkgadd will be looking for it, or pass the additional
option \-\-aargs=\(dq\-c /etc/pkgadd.conf\(dq to the install command.
.TP
.B prt-get list --path --regex '^xorg.*' | grep -v \(dq/usr/ports/xorg\(dq
Show the ports whose names begin with xorg, but which appear outside the xorg port collection.
Show the ports whose names begin with xorg, but which appear outside the
xorg port collection.
(At the time of writing, this command returned at least two font ports.)
.SH "AUTHORS"

View File

@ -27,26 +27,28 @@ ArgParser::ArgParser( int argc, char** argv )
m_hasFilter( false ),
m_noStdConfig( false ),
m_writeLog( false ),
m_nodeps( false ),
m_depSort( true ),
m_softdeps( false ),
m_revdep(false),
m_all( false ),
m_printPath( false ),
m_execPreInstall( false ),
m_execPostInstall( false ),
m_preferHigher( false ),
m_strictDiff( false ),
m_sysup( false ),
m_group( false ),
m_useRegex(false),
m_fullPath(false),
m_quick(false),
m_recursive(false),
m_printTree(false),
m_depSort(false),
m_alternateConfigFile( "" ),
m_pkgmkArgs( "" ),
m_pkgaddArgs( "" ),
m_pkgrmArgs( "" ),
m_sortArgs( "" ),
m_filter( "" ),
m_sortArgs( "" ),
m_commandName( "" ),
m_unknownOption( "" ),
m_installRoot( "" ),
@ -80,7 +82,7 @@ bool ArgParser::isCommandGiven() const
/*!
\return a list of arguments not processed by ArgParser
*/
const list<char*>& ArgParser::otherArgs() const
const list<string>& ArgParser::otherArgs() const
{
return m_otherArgs;
}
@ -103,7 +105,6 @@ const string& ArgParser::pkgmkArgs() const
return m_pkgmkArgs;
}
/*!
\return addtional arguments to pkgadd
*/
@ -112,7 +113,6 @@ const string& ArgParser::pkgaddArgs() const
return m_pkgaddArgs;
}
/*!
\return the name of the alternative configuration file
*/
@ -121,36 +121,34 @@ const string& ArgParser::alternateConfigFile() const
return m_alternateConfigFile;
}
/*!
parse the arguments
\return true on success
*/
bool ArgParser::parse()
{
const int commandCount = 34;
string commands[commandCount] = { "list", "search", "dsearch",
"info", "version", "cache",
"depends", "install", "depinst",
"help", "isinst", "dup", "update",
"quickdep", "diff", "quickdiff",
"path", "listinst", "printf", "readme",
"dependent", "sysup", "current",
"fsearch", "lock", "unlock",
"listlocked", "cat", "ls", "edit",
"remove", "deptree", "dumpconfig",
"listorphans" };
bool ArgParser::parse() {
const int commandCount = 28;
string commands[commandCount] = { "help", "info", "version",
"search", "dsearch", "fsearch",
"cache", "install", "remove",
"current", "isinst", "diff",
"path", "printf", "readme",
"list", "listinst", "listorphans",
"lock", "unlock", "listlocked",
"cat", "ls", "edit", "dumpconfig",
"dup", "depends", "deptree"
};
Type commandID[commandCount] = { HELP, INFO, SHOW_VERSION,
SEARCH, DSEARCH, FSEARCH,
CREATE_CACHE, INSTALL, REMOVE,
CURRENT, ISINST, DIFF,
PATH, PRINTF, README,
LIST, LISTINST, LISTORPHANS,
LOCK, UNLOCK, LISTLOCKED,
CAT, LS, EDIT, DUMPCONFIG,
DUP, DEPENDS, DEPTREE
};
Type commandID[commandCount] = { LIST, SEARCH, DSEARCH, INFO,
SHOW_VERSION, CREATE_CACHE,
DEPENDS, INSTALL, DEPINST,
HELP, ISINST, DUP, UPDATE,
QUICKDEP, DIFF, QUICKDIFF,
PATH, LISTINST, PRINTF, README,
DEPENDENT, SYSUP, CURRENT,
FSEARCH, LOCK, UNLOCK, LISTLOCKED,
CAT, LS, EDIT, REMOVE, DEPTREE,
DUMPCONFIG, LISTORPHANS };
if ( m_argc < 2 ) {
return false;
}
@ -170,71 +168,42 @@ bool ArgParser::parse()
for ( int i = 1; i < m_argc; ++i ) {
if ( m_argv[i][0] == '-' ) {
string s = m_argv[i];
if ( s == "-v" ) {
m_verbose += 1;
} else if ( s == "-vv" ) {
m_verbose += 2;
} else if ( s == "--test" ) {
m_isTest = true;
} else if ( s == "--cache" ) {
m_useCache = true;
} else if ( s == "--nodeps" ) {
m_nodeps = true;
} else if ( s == "--softdeps" ) {
m_softdeps = true;
} else if ( s == "--all" ) {
m_all = true;
} else if ( s == "--path" ) {
m_printPath = true;
} else if ( s == "--log" ) {
m_writeLog = true;
} else if ( s == "--pre-install" ) {
m_execPreInstall = true;
} else if ( s == "--post-install" ) {
if ( s == "-v" ) { m_verbose += 1;
} else if ( s == "-vv" ) { m_verbose += 2;
} else if ( s == "--test" ) { m_isTest = true;
} else if ( s == "--cache" ) { m_useCache = true;
} else if ( s == "--depsort" ) { m_depSort = true;
} else if ( s == "--nodeps" ) { m_depSort = false;
} else if ( s == "--softdeps" ) { m_softdeps = true;
} else if ( s == "--all" ) { m_all = true;
} else if ( s == "--path" ) { m_printPath = true;
} else if ( s == "--log" ) { m_writeLog = true;
} else if ( s == "--pre-install" ) { m_execPreInstall = true;
} else if ( s == "--post-install" ) { m_execPostInstall = true;
} else if ( s == "--install-scripts" ) { m_execPreInstall = true;
m_execPostInstall = true;
} else if ( s == "--install-scripts" ) {
m_execPreInstall = true;
m_execPostInstall = true;
} else if ( s == "--no-std-config" ) {
m_noStdConfig = true;
} else if ( s == "--no-std-config" ) { m_noStdConfig = true;
} else if ( s == "--prefer-higher" || s == "-ph" ) {
m_preferHigher = true;
} else if ( s == "--strict-diff" || s == "-sd" ) {
m_strictDiff = true;
} else if ( s == "--group" || s == "-g" ) {
m_group = true;
} else if ( s == "--regex" ) {
m_useRegex = true;
} else if ( s == "--full" ) {
m_fullPath = true;
} else if ( s == "--recursive" ) {
m_recursive = true;
} else if ( s == "--tree" ) {
m_printTree = true;
} else if ( s == "--depsort" ) {
m_depSort = true;
} else if ( s == "-f" ) {
m_pkgaddArgs += " " + s;
} else if ( s == "-fr" ) {
m_pkgmkArgs += " -f";
} else if ( s == "-if" ) {
m_pkgmkArgs += " " + s;
} else if ( s == "-uf" ) {
m_pkgmkArgs += " " + s;
} else if ( s == "-im" ) {
m_pkgmkArgs += " " + s;
} else if ( s == "-um" ) {
m_pkgmkArgs += " " + s;
} else if ( s == "-is" ) {
m_pkgmkArgs += " " + s;
} else if ( s == "-us" ) {
m_pkgmkArgs += " " + s;
} else if ( s == "-kw" ) {
m_pkgmkArgs += " " + s;
} else if ( s == "-ns" ) {
m_pkgmkArgs += " " + s;
} else if ( s == "-fi" ) {
m_pkgaddArgs += " -f";
} else if ( s == "--group" || s == "-g" ) { m_group = true;
} else if ( s == "--quick" || s == "-Q" ) { m_quick = true;
} else if ( s == "--regex" ) { m_useRegex = true;
} else if ( s == "--full" ) { m_fullPath = true;
} else if ( s == "--recursive" || s == "-R" ) { m_recursive = true;
} else if ( s == "--tree" || s == "-T" ) { m_printTree = true;
} else if ( s == "-f" ) { m_pkgaddArgs += " " + s;
} else if ( s == "-fi" ) { m_pkgaddArgs += " -f";
} else if ( s == "-fr" ) { m_pkgmkArgs += " -f";
} else if ( s == "-if" ) { m_pkgmkArgs += " " + s;
} else if ( s == "-uf" ) { m_pkgmkArgs += " " + s;
} else if ( s == "-im" ) { m_pkgmkArgs += " " + s;
} else if ( s == "-um" ) { m_pkgmkArgs += " " + s;
} else if ( s == "-is" ) { m_pkgmkArgs += " " + s;
} else if ( s == "-us" ) { m_pkgmkArgs += " " + s;
} else if ( s == "-kw" ) { m_pkgmkArgs += " " + s;
} else if ( s == "-ns" ) { m_pkgmkArgs += " " + s;
}
// substrings
@ -244,11 +213,11 @@ bool ArgParser::parse()
m_pkgaddArgs += " " + s.substr( 8 );
} else if ( s.substr( 0, 8 ) == "--rargs=" ) {
m_pkgrmArgs = s.substr( 8 );
} else if ( s.substr( 0, 7 ) == "--sort=" ) {
m_sortArgs = s.substr( 7 );
} else if ( s.substr( 0, 9 ) == "--filter=" ) {
m_filter = s.substr( 9 );
m_hasFilter = true;
} else if ( s.substr( 0, 7 ) == "--sort=" ) {
m_sortArgs = s.substr( 7 );
} else if ( s.substr( 0, 9 ) == "--config=" ) {
m_alternateConfigFile = s.substr( 9 );
m_isAlternateConfigGiven = true;
@ -271,22 +240,45 @@ bool ArgParser::parse()
} else {
if (!m_isCommandGiven) {
string s = m_argv[i];
m_commandName = s;
if ( s == "grpinst" ) {
m_isCommandGiven = true;
m_commandType = commandID[7];
m_group = true;
cout << "Warning: grpinst is obsolescent";
cout << "; using install --group" << endl;
} else {
for ( int i = 0; i < commandCount; ++i ) {
if ( s == commands[i] ) {
m_isCommandGiven = true;
m_commandType = commandID[i];
break;
}
}
}
if ( s == "grpinst") {
m_isCommandGiven = true;
m_commandType = INSTALL;
m_group = true;
cout << "Warning: grpinst is obsolescent";
cout << "; using install --group" << endl;
} else if (s == "depinst") {
m_isCommandGiven = true;
m_commandType = INSTALL;
m_depSort = true;
} else if (s == "update") {
m_isCommandGiven = true;
m_commandType = INSTALL;
} else if (s == "sysup") {
m_isCommandGiven = true;
m_commandType = DIFF;
m_sysup = true;
} else if (s == "quickdiff") {
m_isCommandGiven = true;
m_commandType = DIFF;
m_quick = true;
} else if (s == "quickdep") {
m_isCommandGiven = true;
m_commandType = DEPENDS;
m_quick = true;
} else if (s == "dependent") {
m_isCommandGiven = true;
m_commandType = DEPTREE;
m_revdep = true;
} else {
for ( int i = 0; i < commandCount; ++i ) {
if ( s == commands[i] ) {
m_isCommandGiven = true;
m_commandName = s;
m_commandType = commandID[i];
break;
}
}
}
// first argument must be command
if ( !m_isCommandGiven ) {
return false;
@ -297,12 +289,9 @@ bool ArgParser::parse()
}
}
return m_isCommandGiven;
}
/*!
\return true whether --test has been specified
*/
@ -311,7 +300,6 @@ bool ArgParser::isTest() const
return m_isTest;
}
/*!
\return the level of verbose: -v -> 1, -vv -> 2
*/
@ -320,7 +308,6 @@ int ArgParser::verbose() const
return m_verbose;
}
/*!
\return whether --cache has been specified
*/
@ -329,7 +316,6 @@ bool ArgParser::useCache() const
return m_useCache;
}
/*!
\return whether prt-get was called as 'prt-cache' or not
*/
@ -346,14 +332,6 @@ bool ArgParser::writeLog() const
return m_writeLog;
}
/*!
\return the --sort="..." string
*/
const string& ArgParser::sortArgs() const
{
return m_sortArgs;
}
/*!
\return whether there was a --filter argument
*/
@ -362,7 +340,6 @@ bool ArgParser::hasFilter() const
return m_hasFilter;
}
/*!
\return whether there was a --no-std-config argument
*/
@ -371,7 +348,6 @@ bool ArgParser::noStdConfig() const
return m_noStdConfig;
}
/*!
\return the --filter="..." string
*/
@ -381,16 +357,18 @@ const string& ArgParser::filter() const
}
/*!
\return whether there was a --nodeps argument
\return the --sort="..." string
*/
bool ArgParser::nodeps() const
const string& ArgParser::sortArgs() const
{
return m_nodeps;
return m_sortArgs;
}
bool ArgParser::depSort() const
{
return m_depSort;
}
/*!
\return whether there was a --softdeps argument
*/
bool ArgParser::followSoftdeps() const
{
return m_softdeps;
@ -409,6 +387,16 @@ bool ArgParser::printPath() const
return m_printPath;
}
bool ArgParser::revdep() const
{
return m_revdep;
}
bool ArgParser::quick() const
{
return m_quick;
}
bool ArgParser::recursive() const
{
return m_recursive;
@ -416,12 +404,7 @@ bool ArgParser::recursive() const
bool ArgParser::printTree() const
{
return m_printTree;
}
bool ArgParser::depSort() const
{
return m_depSort;
return (m_printTree || m_commandName == "deptree");
}
const string& ArgParser::commandName() const
@ -470,6 +453,11 @@ bool ArgParser::strictDiff() const
return m_strictDiff;
}
bool ArgParser::sysup() const
{
return m_sysup;
}
bool ArgParser::group() const
{
return m_group;
@ -485,7 +473,6 @@ bool ArgParser::fullPath() const
return m_fullPath;
}
const string& ArgParser::ignore() const
{
return m_ignore;

View File

@ -31,14 +31,15 @@ public:
bool parse();
/*! Command type */
enum Type { HELP, LIST, SEARCH, DSEARCH, INSTALL, DEPINST,
INFO, DEPENDS, ISINST, DUP, UPDATE,
QUICKDEP, DIFF,
QUICKDIFF, SHOW_VERSION, CREATE_CACHE, PATH,
LISTINST, PRINTF, README, DEPENDENT, SYSUP,
CURRENT, FSEARCH, LOCK, UNLOCK, LISTLOCKED,
CAT, LS, EDIT, REMOVE,
DEPTREE, DUMPCONFIG, LISTORPHANS };
enum Type { HELP, INFO, SHOW_VERSION,
SEARCH, DSEARCH, FSEARCH,
CREATE_CACHE, INSTALL, REMOVE,
CURRENT, ISINST, DIFF,
PATH, PRINTF, README,
LIST, LISTINST, LISTORPHANS,
LOCK, UNLOCK, LISTLOCKED,
CAT, LS, EDIT, DUMPCONFIG,
DUP, DEPENDS, DEPTREE };
bool isCommandGiven() const;
bool isTest() const;
@ -48,27 +49,29 @@ public:
bool writeLog() const;
bool hasFilter() const;
bool noStdConfig() const;
bool nodeps() const;
bool depSort() const;
bool followSoftdeps() const;
bool all() const;
bool printPath() const;
bool execPreInstall() const;
bool execPostInstall() const;
bool preferHigher() const;
bool strictDiff() const;
bool sysup() const;
bool group() const;
bool useRegex() const;
bool fullPath() const;
bool revdep() const;
bool quick() const;
bool recursive() const;
bool printTree() const;
bool depSort() const;
bool followSoftdeps() const;
const string& alternateConfigFile() const;
const string& pkgmkArgs() const;
const string& pkgaddArgs() const;
const string& pkgrmArgs() const;
const string& sortArgs() const;
const string& filter() const;
const string& sortArgs() const;
const string& installRoot() const;
const string& ignore() const;
@ -78,7 +81,7 @@ public:
const string& commandName() const;
const string& unknownOption() const;
const list<char*>& otherArgs() const;
const list<string>& otherArgs() const;
int verbose() const;
@ -99,8 +102,9 @@ private:
bool m_writeLog;
bool m_nodeps;
bool m_depSort;
bool m_softdeps;
bool m_revdep;
bool m_all;
bool m_printPath;
@ -109,20 +113,19 @@ private:
bool m_execPostInstall;
bool m_preferHigher;
bool m_strictDiff;
bool m_sysup;
bool m_group;
bool m_useRegex;
bool m_fullPath;
bool m_quick;
bool m_recursive;
bool m_printTree;
bool m_depSort;
string m_alternateConfigFile;
string m_pkgmkArgs;
string m_pkgaddArgs;
string m_pkgrmArgs;
string m_sortArgs;
string m_filter;
string m_commandName;
string m_unknownOption;
@ -136,7 +139,8 @@ private:
int m_verbose;
list<char*> m_otherArgs;
string m_sortArgs;
list<string> m_otherArgs;
list< pair<char*, ConfigArgType> > m_configData;
};

View File

@ -27,6 +27,7 @@ using namespace std;
#include "pkgdb.h"
#include "stringhelper.h"
#include "argparser.h"
#include "versioncomparator.h"
#include "process.h"
#include "configuration.h"
@ -71,38 +72,6 @@ InstallTransaction::InstallTransaction( const list<string>& names,
}
/*!
Create a nice InstallTransaction
\param names a list of port names to be installed
\param repo the repository to look for packages
\param pkgDB the pkgDB with already installed packages
*/
InstallTransaction::InstallTransaction( const list<char*>& names,
const Repository* repo,
PkgDB* pkgDB,
const Configuration* config )
: m_pkgDB( pkgDB ),
m_resolver(),
m_repo( repo ),
m_depCalced( false ),
m_installedPackages(),
m_alreadyInstalledPackages(),
m_ignoredPackages(),
m_depNameList(),
m_depList(),
m_missingPackages(),
m_installErrors(),
m_config( config )
{
list<char*>::const_iterator it = names.begin();
for ( ; it != names.end(); ++it ) {
m_packages.push_back( make_pair( *it, m_repo->getPackage( *it ) ) );
}
}
/*!
Create a nice InstallTransaction
\param names a list of port names to be installed
@ -142,18 +111,17 @@ InstallTransaction::installError() const
/*!
install (commit) a transaction
\param parser the argument parser
\param update whether this is an update operation
\param group whether this is a group transaction (stops transaction on error)
\return returns an InstallResult telling whether installation worked
*/
InstallTransaction::InstallResult
InstallTransaction::install( const ArgParser* parser,
bool update )
InstallTransaction::install( const ArgParser* parser )
{
if ( m_packages.empty() ) {
return NO_PACKAGE_GIVEN;
}
bool update;
const string forceRebuild = "-fr";
list<string> ignoredPackages;
StringHelper::split(parser->ignore(), ',', ignoredPackages);
@ -176,12 +144,28 @@ InstallTransaction::install( const ArgParser* parser,
continue;
}
// consider aliases here, but don't show them specifically
if ( !update && m_pkgDB->isInstalled( package->name(), true ) ) {
// ignore
m_alreadyInstalledPackages.push_back( package->name() );
continue;
}
// Set the update flag if the package is installed and out of date,
// or if the user has forced a rebuild.
// Proceed to the next target if package is installed and up to date.
if ( m_pkgDB->isInstalled( package->name(), false ) ) {
VersionComparator::COMP_RESULT
rpDiff = VersionComparator::compareVersions(
m_repo->getPackageVersion( package->name() ),
m_pkgDB->getPackageVersion( package->name() ) );
if ( rpDiff == VersionComparator::EQUAL &&
parser->pkgmkArgs().find(forceRebuild) == string::npos ) {
m_alreadyInstalledPackages.push_back( package->name() );
continue;
} else if ( (! m_config->preferHigher())
|| parser->strictDiff()
|| rpDiff == VersionComparator::GREATER
|| parser->pkgmkArgs().find(forceRebuild) !=
string::npos ) {
update = true;
} else {
continue;
}
}
InstallTransaction::InstallResult result;
InstallInfo info( package->hasReadme() );
@ -191,13 +175,12 @@ InstallTransaction::install( const ArgParser* parser,
m_installedPackages.push_back( make_pair( package->name(), info));
} else {
// log failures are critical
// log failures and pkgdest errors are critical,
// don't proceed to the next install target if encountered
if ( result == LOG_DIR_FAILURE ||
result == LOG_FILE_FAILURE ||
result == NO_LOG_FILE ||
result == CANT_LOCK_LOG_FILE ||
// or pkgdest
result == PKGDEST_ERROR ) {
return result;
}
@ -224,8 +207,7 @@ InstallTransaction::installPackage( const Package* package,
const ArgParser* parser,
bool update,
InstallTransaction::InstallInfo& info )
const
{
const {
InstallTransaction::InstallResult result = SUCCESS;
#ifdef USE_LOCKING
@ -241,7 +223,7 @@ InstallTransaction::installPackage( const Package* package,
commandName = "prt-cache";
}
// - initial information about the package to be build
// - initial information about the package to be built
string message;
message = commandName + ": ";
if (update) {
@ -299,8 +281,8 @@ InstallTransaction::installPackage( const Package* package,
write( fdlog, timestamp.c_str(), timestamp.length());
}
string pkgdir = package->path() + "/" + package->name();
chdir( pkgdir.c_str() );
string portdir = package->path() + "/" + package->name();
chdir( portdir.c_str() );
string runscriptCommand = "sh";
if (m_config->runscriptCommand() != "") {
@ -308,11 +290,11 @@ InstallTransaction::installPackage( const Package* package,
}
// -- pre-install
struct stat statData;
struct stat statData; struct stat fstatData;
if ((parser->execPreInstall() || m_config->runScripts()) &&
stat((pkgdir + "/" + "pre-install").c_str(), &statData) == 0) {
stat((portdir + "/pre-install").c_str(), &statData) == 0) {
Process preProc( runscriptCommand,
pkgdir + "/" + "pre-install",
portdir + "/pre-install",
fdlog );
if (preProc.executeShell()) {
info.preState = FAILED;
@ -322,22 +304,32 @@ InstallTransaction::installPackage( const Package* package,
}
// -- build
string pkgdest = getPkgmkPackageDir();
const string builtPkg = package->name() + "#" + package->version() + "-" +
package->release() + ".pkg.tar." + getPkgmkCompressionMode();
string builtPkgPath = ( pkgdest != "" ) ? pkgdest + "/" + builtPkg :
portdir + "/" + builtPkg ;
string cmd = PKGMK_DEFAULT_COMMAND;
if (m_config->makeCommand() != "") {
cmd = m_config->makeCommand();
}
// skip the build if a package exists newer than Pkgfile
// (e.g., created by running pkgmk manually)
if ( stat(builtPkgPath.c_str(), &statData) +
stat((portdir + "/Pkgfile").c_str(), &fstatData) == 0) {
time_t pkgMtime = statData.st_mtime;
time_t pfMtime = fstatData.st_mtime;
if ( difftime(pkgMtime,pfMtime) > 0 ) { cmd = "/bin/true"; }
}
string args = "-d " + parser->pkgmkArgs();
Process makeProc( cmd, args, fdlog );
if ( makeProc.executeShell() ) {
result = PKGMK_FAILURE;
} else {
// -- update
string pkgdest = getPkgmkPackageDir();
if ( pkgdest != "" ) {
// TODO: don't manipulate pkgdir
pkgdir = pkgdest;
string message = "prt-get: Using PKGMK_PACKAGE_DIR: " + pkgdir;
string message = ( pkgdest == "" ) ? "" :
commandName + ": Using PKGMK_PACKAGE_DIR " + pkgdest;
if (parser->verbose() > 0) {
cout << message << endl;
}
@ -345,94 +337,78 @@ InstallTransaction::installPackage( const Package* package,
write( fdlog, message.c_str(), message.length() );
write( fdlog, "\n", 1 );
}
}
}
// the following chdir is a noop if usePkgDest() returns false
if ( chdir( pkgdir.c_str() ) != 0 ) {
result = PKGDEST_ERROR;
// no need to chdir if we provide absolute paths to pkgadd
cmd = PKGADD_DEFAULT_COMMAND;
if (m_config->addCommand() != "") {
cmd = m_config->addCommand();
}
args = "";
if (parser->installRoot() != "") {
args = "-r " + parser->installRoot() + " ";
}
if ( update ) {
args += "-u ";
}
if ( !parser->pkgaddArgs().empty() ) {
args += parser->pkgaddArgs() + " ";
}
args += builtPkgPath;
// - inform the user about what's happening
string fullCommand = commandName + ": " + cmd + args;
string summary;
if (update) {
string from = m_pkgDB->getPackageVersion(package->name());
string to = m_repo->getPackageVersion(package->name());
if (from == to) {
summary = commandName + ": " + "reinstalling " +
package->name() + " " + to;
} else {
cmd = PKGADD_DEFAULT_COMMAND;
if (m_config->addCommand() != "") {
cmd = m_config->addCommand();
}
summary = commandName + ": " + "updating " +
package->name() + " from " + from + " to " + to;
}
} else {
summary = commandName + ": " + "installing " + package->name() +
" " + package->version() + "-" + package->release();
}
args = "";
if (parser->installRoot() != "") {
args = "-r " + parser->installRoot() + " ";
}
// - print and log
cout << summary << endl;
if (parser->verbose() > 0) {
cout << fullCommand << endl;
}
if ( m_config->writeLog() ) {
time_t endTime;
time(&endTime);
timestamp = ctime(&endTime);
timestamp = commandName + ": build done " + timestamp;
write( fdlog, summary.c_str(), summary.length() );
write( fdlog, "\n", 1 );
write( fdlog, fullCommand.c_str(), fullCommand.length() );
write( fdlog, "\n", 1 );
write( fdlog, timestamp.c_str(), timestamp.length());
write( fdlog, "\n", 1 );
}
if ( update ) {
args += "-u ";
}
if ( !parser->pkgaddArgs().empty() ) {
args += parser->pkgaddArgs() + " ";
}
args +=
package->name() + "#" +
package->version() + "-" +
package->release() + ".pkg.tar." + getPkgmkCompressionMode();
// - inform the user about what's happening
string fullCommand = commandName + ": " + cmd + " " + args;
string summary;
if (update) {
string from = m_pkgDB->getPackageVersion(package->name());
string to = package->version() + "-" + package->release();
if (from == to) {
summary = commandName + ": " + "reinstalling " +
package->name() + " " + to;
Process installProc( cmd, args, fdlog );
if ( installProc.executeShell() ) {
result = PKGADD_FAILURE;
} else {
// exec post install
if ((parser->execPostInstall() || m_config->runScripts() ) &&
stat((portdir + "/post-install").c_str(), &statData) == 0) {
Process postProc( runscriptCommand,
portdir + "/post-install", fdlog );
if (postProc.executeShell()) {
info.postState = FAILED;
} else {
summary = commandName + ": " + "updating " +
package->name() + " from " + from + " to " + to;
info.postState = EXEC_SUCCESS;
}
} else {
summary = commandName + ": " + "installing " +
package->name() + " " +
package->version() + "-" + package->release();
}
// - print and log
cout << summary << endl;
if (parser->verbose() > 0) {
cout << fullCommand << endl;
}
if ( m_config->writeLog() ) {
time_t endTime;
time(&endTime);
timestamp = ctime(&endTime);
timestamp = commandName + ": build done " + timestamp;
write( fdlog, summary.c_str(), summary.length() );
write( fdlog, "\n", 1 );
write( fdlog, fullCommand.c_str(), fullCommand.length() );
write( fdlog, "\n", 1 );
write( fdlog, timestamp.c_str(), timestamp.length());
write( fdlog, "\n", 1 );
}
Process installProc( cmd, args, fdlog );
if ( installProc.executeShell() ) {
result = PKGADD_FAILURE;
} else {
// exec post install
if ((parser->execPostInstall() || m_config->runScripts() ) &&
stat((package->path() + "/" + package->name() +
"/" + "post-install").c_str(), &statData)
== 0) {
// Work around the pkgdir variable change
Process postProc( runscriptCommand,
package->path() + "/" + package->name()+
"/" + "post-install",
fdlog );
if (postProc.executeShell()) {
info.postState = FAILED;
} else {
info.postState = EXEC_SUCCESS;
}
}
}
}
}
@ -568,7 +544,7 @@ void InstallTransaction::checkDependencies( bool greedy,
if ( pos != string::npos && (pos+1) < softdep.length() ) {
softdep = softdep.substr( pos + 1 );
}
if ( m_pkgDB->isInstalled(softdep, true) ) {
if ( m_pkgDB->isInstalled(softdep, false) or isRequested(softdep) ) {
const Package* p = m_repo->getPackage( softdep );
if ( p ) {
checkDependencies( true, p, index );
@ -586,6 +562,16 @@ void InstallTransaction::checkDependencies( bool greedy,
treeWalk.pop_back();
}
/*!
Method to determine whether a package was passed on the command line
*/
bool InstallTransaction::isRequested(const string pname) {
list< pair<string, const Package*> >::iterator it = m_packages.begin();
for ( ; it != m_packages.end(); ++it ) {
if ( it->first == pname ) { return true; }
}
return false;
}
/*!
This method returns a list of packages which should be installed to
@ -638,11 +624,11 @@ InstallTransaction::installedPackages() const
/*!
calculate dependendencies for this package
*/
InstallTransaction::InstallResult
InstallTransaction::calcDependencies( )
bool InstallTransaction::calcDependencies( )
{
if ( m_packages.empty() ) {
return NO_PACKAGE_GIVEN;
cout << "No packages given for this transaction" << endl;
return false;
}
bool validPackages = false;
@ -656,13 +642,15 @@ InstallTransaction::calcDependencies( )
}
}
if ( !validPackages ) {
return PACKAGE_NOT_FOUND;
cout << "No valid packages in this transaction" << endl;
return false;
}
if ( !calculateDependencies() ) {
return CYCLIC_DEPEND;
cout << "Could not resolve dependencies for this transaction" << endl;
return false;
}
return SUCCESS;
return true;
}

View File

@ -33,10 +33,6 @@ class Configuration;
class InstallTransaction
{
public:
InstallTransaction( const list<char*>& names,
const Repository* repo,
PkgDB* pkgDB,
const Configuration* config );
InstallTransaction( const list<string>& names,
const Repository* repo,
PkgDB* pkgDB,
@ -54,12 +50,12 @@ public:
/*! Result of an installation */
enum InstallResult {
SUCCESS, /*!< yeah, success */
NO_PACKAGE_GIVEN, /*!< no package give to install */
NO_PACKAGE_GIVEN, /*!< no package given to install */
PACKAGE_NOT_FOUND, /*!< package not found */
PKGMK_EXEC_ERROR, /*!< can't execute pkgmk */
PKGMK_FAILURE, /*!< error while pkgmk */
PKGADD_EXEC_ERROR, /*!< can't execute pkgadd */
PKGDEST_ERROR, /*!< can't change to PKGDEST */
PKGDEST_ERROR, /*!< can't change to PKGDEST */
PKGADD_FAILURE, /*!< error while pkgadd */
CYCLIC_DEPEND, /*!< cyclic dependencies found */
LOG_DIR_FAILURE, /*!< couldn't create log directory */
@ -84,15 +80,13 @@ public:
bool hasReadme;
};
InstallResult install( const ArgParser* parser,
bool update );
InstallResult calcDependencies();
InstallResult install( const ArgParser* parser );
bool calcDependencies();
const list< pair<string, InstallInfo> >& installedPackages() const;
const list<string>& alreadyInstalledPackages() const;
const list<string>& ignoredPackages() const;
const list<string>& dependencies() const;
const list< pair<string,string> >& missing() const;
const list< pair<string, InstallInfo> >& installError() const;
@ -108,6 +102,7 @@ private:
const ArgParser* parser,
bool update,
InstallInfo& info ) const;
bool isRequested(const string pname);
static string getPkgmkSetting(const string& setting);
static string getPkgmkSettingFromFile(const string& setting,

View File

@ -57,17 +57,13 @@ int main( int argc, char** argv )
ArgParser::Type command = argParser.commandType();
switch ( command )
{
switch ( command ) {
case ArgParser::HELP:
prtGet.printUsage();
break;
case ArgParser::SHOW_VERSION:
prtGet.printVersion();
break;
case ArgParser::LIST:
prtGet.listPackages();
break;
case ArgParser::DUP:
prtGet.listShadowed();
break;
@ -84,25 +80,16 @@ int main( int argc, char** argv )
prtGet.isInstalled();
break;
case ArgParser::INSTALL:
prtGet.install();
prtGet.install( argParser.depSort() );
break;
case ArgParser::DEPINST:
prtGet.install( false, true );
break;
case ArgParser::DEPENDS:
prtGet.printDepends();
break;
case ArgParser::QUICKDEP:
prtGet.printDepends( true );
break;
case ArgParser::UPDATE:
prtGet.install( true );
prtGet.printDepends( argParser.quick() );
break;
case ArgParser::DEPTREE:
prtGet.printDepTree();
break;
case ArgParser::DIFF:
prtGet.printDiff();
break;
case ArgParser::QUICKDIFF:
prtGet.printQuickDiff();
prtGet.printDiff( argParser.quick() );
break;
case ArgParser::CREATE_CACHE:
prtGet.createCache();
@ -110,36 +97,36 @@ int main( int argc, char** argv )
case ArgParser::PATH:
prtGet.printPath();
break;
case ArgParser::LISTINST:
prtGet.listInstalled();
break;
case ArgParser::PRINTF:
prtGet.printf();
break;
case ArgParser::README:
prtGet.readme();
break;
case ArgParser::DEPENDENT:
prtGet.printDependent();
break;
case ArgParser::SYSUP:
prtGet.sysup();
break;
case ArgParser::CURRENT:
prtGet.current();
break;
case ArgParser::FSEARCH:
prtGet.fsearch();
break;
case ArgParser::LIST:
prtGet.listPackages();
break;
case ArgParser::LISTINST:
prtGet.listInstalled();
break;
case ArgParser::LISTORPHANS:
prtGet.listOrphans();
break;
case ArgParser::LISTLOCKED:
prtGet.listLocked();
break;
case ArgParser::LOCK:
prtGet.setLock( true );
break;
case ArgParser::UNLOCK:
prtGet.setLock( false );
break;
case ArgParser::LISTLOCKED:
prtGet.listLocked();
break;
case ArgParser::CAT:
prtGet.cat();
break;
@ -152,15 +139,9 @@ int main( int argc, char** argv )
case ArgParser::REMOVE:
prtGet.remove();
break;
case ArgParser::DEPTREE:
prtGet.printDependTree();
break;
case ArgParser::DUMPCONFIG:
prtGet.dumpConfig();
break;
case ArgParser::LISTORPHANS:
prtGet.listOrphans();
break;
default:
cerr << "unknown command" << endl;
break;

View File

@ -32,6 +32,7 @@ public:
bool useAlias = false,
bool* isAlias = 0,
string* aliasOrignalName = 0 ) const;
bool isOutdated( const std::string& name ) const;
std::string getPackageVersion( const std::string& name ) const;

File diff suppressed because it is too large Load Diff

View File

@ -55,22 +55,25 @@ public:
void listPackages();
void listShadowed();
void listInstalled();
void listOrphans();
void listLocked();
void setLock( bool lock );
void searchPackages( bool searchDesc=false );
void fsearch();
void printInfo();
void isInstalled();
bool isOutdated();
void current();
void readme();
void install( bool update=false,
bool dependencies=false );
void sysup();
void current();
void install( bool dependencies=false );
void remove();
void printDepends( bool simpleListing=false );
void printDependTree();
void printDependent();
void printDiff();
void printQuickDiff();
void listOrphans();
void printDiff( bool simpleListing=false );
void printDepTree();
void createCache();
@ -80,14 +83,6 @@ public:
void cat();
void ls();
void edit();
void remove();
void setLock( bool lock );
void listLocked();
void fsearch();
void dumpConfig();
int returnValue() const;
@ -96,14 +91,10 @@ public:
protected:
void printDepsLevel(int indent, const Package* package, bool greedy);
void printDepsLevel(int level, const Package* package, bool greedy);
void printDependent(const std::string& dep, int level);
void executeTransaction( InstallTransaction& transaction,
bool update );
void evaluateResult( InstallTransaction& transaction,
bool update,
void executeTransaction( InstallTransaction& transaction );
void evaluateResult( InstallTransaction& transaction,
bool interrupted=false );
void reportPrePost(const InstallTransaction::InstallInfo& info);
@ -122,7 +113,6 @@ protected:
const string& version2,
bool locked);
Repository* m_repo;
PkgDB* m_pkgDB;
Configuration* m_config;

View File

@ -86,12 +86,26 @@ const Package* Repository::getPackage( const string& name ) const
return it->second;
}
/*!
\param name the package name to be matched
\return the version-release in the repository
*/
std::string Repository::getPackageVersion( const string& name ) const
{
map<string, Package*>::const_iterator it = m_packageMap.find( name );
if ( it == m_packageMap.end() ) {
return "0";
}
const Package* p = it->second;
string result = p->version()+"-"+p->release();
return result;
}
/*!
Search packages for a match of \a pattern in name, and description of
Search packages for a match of \a pattern in name, or in description if
\a searchDesc is true.
\note Name searches can often done without opening the Pkgfiles, but not
description search. Therefore, the later is much slower
\note Name searches can often be done without opening the Pkgfiles, but not
description search. Therefore, the latter is much slower
\param pattern the pattern to be found
\param searchDesc whether descriptions should be searched as well
@ -188,11 +202,10 @@ void Repository::initFromFS( const list< pair<string, string> >& rootList,
// TODO: think about whether it would be faster (more
// efficient) to put all packages into a map, and the iterate
// over the list of allowed packages and copy them
// over. depending in the efficiency of find(), this might be
// faster
// TODO: think about whether it would be faster (more efficient)
// to put all packages into a map, and then iterate
// over the list of allowed packages and copy them over.
// Depending on the efficiency of find(), this might be faster.
d = opendir( path.c_str() );
while ( ( de = readdir( d ) ) != NULL ) {
name = de->d_name;
@ -390,6 +403,37 @@ bool Repository::createOutputDir( const string& path )
return true;
}
/*
look for any port mentioning \a pattern as a dependency or soft dependency.
searchOptionals=false (the default) only searches the "Depends on:" line.
The output will need to be trimmed afterward, because in this namespace we
can't check whether the matching ports are installed.
*/
void Repository::getDependentPackages( const string& pattern,
list<Package*>& target,
bool searchOptionals ) const {
map<string, Package*>::const_iterator im = m_packageMap.begin();
for ( ; im != m_packageMap.end(); ++im ) {
Package* q = im->second; string s;
if (searchOptionals) {
s = toLowerCase(q->optionals());
} else {
s = toLowerCase(q->dependencies());
}
if ( s.find( pattern ) != string::npos ) {
list<string> tokens;
split( s, ',', tokens );
list<string>::iterator ik = find( tokens.begin(),
tokens.end(), pattern );
if ( ik != tokens.end() ) {
target.push_back( q );
}
}
}
}
/*!
Search packages for a match of \a pattern in name. The name can

View File

@ -19,6 +19,7 @@
using namespace std;
#include "package.h"
#include "stringhelper.h"
/*!
\class Repository
@ -33,6 +34,7 @@ public:
~Repository();
const Package* getPackage( const string& name ) const;
std::string getPackageVersion( const string& name ) const;
const map<string, Package*>& packages() const;
const list<pair<Package*, Package*> >& shadowedPackages() const;
@ -40,6 +42,10 @@ public:
list<Package*>& target,
bool searchDesc ) const;
void getDependentPackages( const string& pattern,
list<Package*>& target,
bool searchOptionals ) const;
void getMatchingPackages( const string& pattern,
list<Package*>& target ) const;

View File

@ -155,5 +155,4 @@ string replaceAll( string& in,
return in;
}
}; // Namespace