8 Commits

Author SHA1 Message Date
9619657f17 update man-page to document the sync command 2023-12-04 01:04:14 +00:00
de7e9b6a1e add sync function (alternative to ports -u)
fix printf when used with --regex
2023-12-02 13:59:40 +00:00
d9ec1c1e98 add support for rmlog_on_uninst 2023-09-04 19:19:24 -04:00
d1060afc5c refresh the man-page examples 2023-09-01 13:09:56 -04:00
c029a01d00 prune unreachable code paths; update man-page with fresh examples
expand the discussion of --install-root
2023-08-24 10:30:53 -04:00
af59c55bed revise the softdeps calculation 2023-08-22 15:03:21 -04:00
e7d2481dcb support more format codes in the argument to 'dup'
expand man-page to explain some asymmetries

report pre- and post-install scripts in test mode
2023-06-23 15:18:43 -04:00
934e044f86 fix misc compile warnings
document the interaction between --install-root and 'runscripts yes'
2023-06-19 14:44:03 -04:00
20 changed files with 451 additions and 217 deletions

View File

@@ -1,3 +1,11 @@
* 31.08.2023 John McQuah
- allow prt-get to remove build log when uninstalling a package (feature
requested by samsep10l)
* 31.03.2023 John McQuah
- respect the user's choice of --install-root when running pre- or
post-install scripts
* 10.03.2023 John McQuah
- make it possible to consider optional dependencies when updating
- bump version of the cache file format, to warn users about the

View File

@@ -1,6 +1,6 @@
Installing prt-get
------------------
Installing prt-get is just a matter of
./configure
make
make install
meson setup bld --prefix=/usr
ninja -C bld
ninja -C bld install

View File

@@ -76,28 +76,36 @@ 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
Install all packages in the listed order. Note that you can do this
from any directory.
.TP
.B depinst [\-\-margs] [\-\-aargs] [\-\-log] [\-\-softdeps] <package1> [<package2> ...]
install all packages given on the command line, including their dependencies.
Install all packages given on the command line, including their dependencies.
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.
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.
dependencies when sorting. The --softdeps flag does NOT affect the
calculation of the minimal set of packages needed to satisfy the
transaction; only hard dependencies are used when constructing this set. But
if there are any optional dependency relationships among the ports in the
resulting set, they will be respected when prt-get determines the sequence
in which to build.
.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
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.
@@ -105,7 +113,19 @@ See the \fBEXAMPLES\fP section below for details.
.TP
.B remove <package1> [<package2> ...]
remove packages listed in this order
Remove packages listed in this order
.TP
.B sync [\-\-install\-root=<dir>] [collection1 ... collectionN]
Reach out to remote servers defined in \fB/etc/ports\fP (or \fB<dir>/etc/ports\fP if
\-\-install\-root is given), and bring the local ports collections up to date. The sync
command processes all sync files whose suffix matches an executable file in
\fB/etc/ports/drivers\fP, unless specific collections are passed as arguments, in which case
only those collections are synchronized. If the same collection is listed in \fB/etc/ports\fP
with different suffixes, then the matching drivers are called in lexographic order. This
feature allows for multi-stage processing, e.g. if you want to apply local patches and then
update the manifests. For further details on the ports system and the format of the
{httpup,rsync,git} files, see \fBports(8)\fB.
.TP
.B sysup [\-\-softdeps] [\-\-nodeps]
@@ -150,7 +170,7 @@ switch will slow down the operation remarkably.
.TP
.B diff [\-\-all] [\-\-prefer\-higher] [<package1> <package2> ...]
show differences between installed packages and ports in the ports
Show differences between installed packages and ports in the ports
tree. If arguments are given, shows only differences for these
packages, otherwise all differences are shown. It's also possible to use
shell-like
@@ -162,7 +182,7 @@ the ports tree, use the --prefer-higher option.
.TP
.B quickdiff
prints a simple list of packages which have a different version in the
Print 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).
@@ -188,19 +208,18 @@ Search the ports tree (both name and description) for the pattern
.B expr
(which can be a shell-like wildcard pattern or a regexp). The search in
the description is not case sensitive. Note that this requires prt\-get
to read every Pkgfile, which makes it rather slow; if you like this,
consider using the cache functionality, so you only have to spend this
time once after updating the ports tree has been updated.
to read every Pkgfile, which makes it rather slow. If you like searching by
description, consider using the cache functionality, so you only have to
read all the Pkgfiles after each update of the ports tree.
.TP
.B fsearch [\-\-full] [\-\-regex] <pattern>
Search the ports tree for
.B pattern
as file name in their footprint. When called without '--full', strips
the directories from the file names before matching; this behaviour
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).*')
the directories from the file names before matching.
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
@@ -217,18 +236,19 @@ Print the port's README file if it exists; if set, uses $PAGER
.TP
.B depends [\-\-softdeps] <package1> [<package2> ...]
print a recursive list of dependencies needed to install the packages passed
as argument. It shows a list of the dependencies that were found in the ports tree,
plus a list of the dependencies that could not be found. Pass the --softdeps flag
if you want the sorting algorithm to consider optional dependencies too.
Print a recursive list of dependencies needed to install the packages
passed as argument. It shows a list of the dependencies that were found in
the ports tree, plus a list of the dependencies that could not be found.
Pass the --softdeps flag if you want the sorting algorithm to consider
optional dependencies too.
.TP
.B quickdep [\-\-softdeps] <package1> [<package2> ...]
same output as \fBdepends\fP, but separated by spaces rather than newlines, and
stripped of any dependencies that could not be found in the ports tree.
Useful in case the list of dependencies is too large to fit on one screen, or
if you don't want to filter out manually the ports that are invalid targets for
installation. For example, instead of
Same output as \fBdepends\fP, but separated by spaces rather than newlines,
and stripped of any dependencies that could not be found in the ports tree.
Useful in case the list of dependencies is too large to fit on one screen,
or 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
@@ -241,55 +261,77 @@ for successful builds.
.TP
.B deptree [\-\-softdeps] <package>
print a tree of the dependencies of the package
Print a tree of the dependencies of the package
.B <package>.
Pass the --softdeps flag to also show the installed packages that mention
Pass the --softdeps flag to also show the installed packages that might
have been eagerly linked, if they were present when
.B <package>
as an optional dependency.
(or its dependencies) were built.
Subtrees already shown are marked with '-->' to save some space. In
order to show them all, add the --all switch.
.SH ""
.TP
.B dependent [\-\-softdeps] <package>
print a list of ports which have
.B dependent [\-\-recursive] [\-\-softdeps] [\-\-all] [\-\-tree] <package>
Print a list of ports whose "Depends on:" line contains
.B <package>
in their "Depends on:" line. Use the --softdeps flag to also search the
"Optional:" lines for \fB<package>\fP.
(or its dependents, if --recursive was passed). Use the --softdeps flag to
also search the "Optional:" lines for \fB<package>\fP.
By default, output is restricted to ports that are installed. To see all
the dependencies, add the --all switch; use --recursive to get a recursive
list (without duplication), and --tree to get a nicely indented one.
the dependencies, use the --all switch. Use --tree to get a nicely indented
list.
.TP
.B dup [-v] [format]
List ports which can be found in multiple directories configured in
.B /etc/prt-get.conf
Use the verbose switch to simulate the output of version 5.12 and older (likely
to go away in the future). The format string can be used to create user
specified formats. The following symbols are currently replaced:
Use the \fB\-v\fP switch to see a verbose report, which will show for each
dup the port that takes precedence, and the port that is hidden (including
full path and version info). The verbose switch is basically an alias for a
particular combination of the recognized format symbols, namely
.B '* %n\en %p1 %v1 precedes over\en %p2 %v2\en'.
You can customize the output by passing a different format string, whose
symbols will be replaced as follows.
.TP
\ \ \ \(bu
%n \-> name of the port
%n -> name of the port
.TP
\ \ \ \(bu
%p1 \-> Full path (including name) to port taking precendence
%p1 -> Full path (including name) to port taking precedence
.TP
\ \ \ \(bu
%p2 \-> Full path (including name) to port being hidden
%p2 -> Full path (including name) to port being hidden
.TP
\ \ \ \(bu
%v1 \-> Version of port taking precendence
%v1 -> Version of port taking precedence
.TP
\ \ \ \(bu
%v2 \-> Version of port being hidden
%v2 -> Version of port being hidden
.TP
\ \ \ \(bu
%M1 -> maintainer of port taking precedence
.TP
\ \ \ \(bu
%M2 -> maintainer of port being hidden
.TP
\ \ \ \(bu
%u1 -> URL of port taking precedence
.TP
\ \ \ \(bu
%u2 -> URL of port being hidden
.TP
.B list [\-v|\-vv] [\-\-path] [\-\-regex] [filter]
@@ -307,27 +349,27 @@ Print formatted port list format string can contain variables, which
are replaced like this:
.TP
\ \ \ \(bu
%n \-> name
%n -> name
.TP
\ \ \ \(bu
%p \-> path
%p -> path
.TP
\ \ \ \(bu
%v \-> version
%v -> version
.TP
\ \ \ \(bu
%r \-> release
%r -> release
.TP
\ \ \ \(bu
%d \-> description
%d -> description
.TP
\ \ \ \(bu
%e \-> dependencies
%e -> dependencies
.TP
\ \ \ \(bu
@@ -335,7 +377,7 @@ are replaced like this:
.TP
\ \ \ \(bu
%u \-> URL
%u -> URL
.TP
\ \ \ \(bu
@@ -359,11 +401,11 @@ are replaced like this:
.TP
\ \ \ \(bu
%i \-> "no" if not installed, "yes" if it's installed and
%i -> "no" if not installed, "yes" if it's installed and
up to date and "diff" if it's installed and a new version is in the
ports tree.
Use "\\n" and "\\t" to format your output (no additional format specified
Use "\\n" and "\\t" to format your output (no additional format symbols
suported). The optional format string2 can contain the same variables
as format string1 and is used to sort the output. You can specify a
.B wildcard filter
@@ -374,16 +416,16 @@ to filter by package name.
.B listinst [\-v|\-vv] [\-\-regex] [\-\-depsort] [filter]
List installed ports. It's basically the same as
.B pkginfo \-i,
but omits version when called without verbose (\-v, \-vv) switch. Plus
it is notably faster in my tests. \-v adds version information, \-vv
but omits version when called without verbose (-v, -vv) switch. Plus
it is notably faster in my tests. -v adds version information, -vv
adds version and description.
.B Warning:
\-vv will slow down the process because it requires prt\-get to scan
-vv will slow down the process because it requires prt-get to scan
both the ports database and the ports tree.
It's also possible to use shell-like
.B wildcards
for the listinst command. Make sure you escape where needed. By default
it's sorted alphabetically; use the \-\-depsort switch to sort by
it's sorted alphabetically; use the --depsort switch to sort by
dependencies.
.TP
@@ -410,7 +452,7 @@ greater than 0.
.TP
.B current <package>
Shows the currently-installed version of <package>, or a message
Show 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
@@ -419,11 +461,11 @@ to work around this limitation.
.TP
.B ls [\-\-path] <package>
Prints out a listing of the port's directory
List the contents 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.
Print the file to stdout. If <file> is not specified, 'Pkgfile' is used. If set, uses $PAGER.
.TP
.B edit <package> [<file>]
@@ -433,7 +475,7 @@ If <file> is not specified, 'Pkgfile' is used.
.TP
.B help
Shows a help screen
Show a help screen
.TP
.B dumpconfig
@@ -441,11 +483,11 @@ Dump the configuration to the current terminal
.TP
.B version
Shows the current version of prt-get
Show the current version of prt-get
.TP
.B cache
create a cache file from the ports tree to be used by prt-get using the
Create a cache file from the ports tree to be used by prt-get using the
--cache option. Remember to run prt-get cache each time you update the
ports tree.
@@ -542,6 +584,14 @@ Execute post-install script if it's there
.B \-\-install-scripts
Execute pre-install and post-install script if they're there
The options --pre-install, --post-install, and --install-scripts offer a
convenient way to temporarily override the prt-get.conf directive 'runscripts
no', which was the historical default. Starting with CRUX 3.7, prt-get.conf is
being shipped with 'runscripts yes'. To override this default at the command
line, you have to pass the more cumbersome option --config-set=\(dqrunscripts
no\(dq, or point prt-get to an alternative configuration file using
--config=<file>. (see below for the documentation of these options)
.TP
.B \-\-install-root=<dir>
Use <dir> as root directory for your installation; allows you to install
@@ -549,30 +599,41 @@ the requested packages onto a different directory than '/'. In daily usage,
this option is not required; it's primarily interesting if you're developing
an independent installation.
Some pre- or post-install scripts might not have the intended effect if
invoked as
.B chroot <dir> /bin/sh <path/to/script>
(the naive way to respect --install-root).
So if you're maintaining an installation on a volume mounted somewhere
other than '/', it might be safer to ensure that your \fBprt\-get.conf(5)\fP
has the line
.B runscripts no
and then run any pre- or post-install scripts by hand.
Pre- and post-install scripts will not be executed if the target root directory
lacks a copy of the ports tree. So if you're maintaining an installation on a
volume mounted somewhere other than '/', it's not enough to have the
line 'runscripts yes' in your prt-get.conf; you also have to ensure that
the pre- and post-install scripts can be found in the same location
relative to <dir>.
The setting for --install-root determines which package database is used for
reading/writing (so <dir>/var/lib/pkg/db must exist), and where the pkg.tar.?z
archives get unpacked, but the relevant prt\-get.conf and ports tree are those
archives get unpacked, but the relevant prt-get.conf and ports tree are those
on the parent filesystem. Therefore it is not necessary for <dir> to contain
its own copy of the ports tree, or even a copy of prt-get.conf.
However, if <dir>/etc/pkgadd.conf exists and is different from /etc/pkgadd.conf,
then install or update commands might behave unexpectedly. In order to preserve
the \fBpkgadd.conf(5)\fP settings from the host system, append the option
--aargs='-c /etc/pkgadd.conf' to your \fBprt-get install\fP
command, or just copy the desired directives into <dir>/etc/pkgadd.conf .
its own copy of the ports tree (unless 'runscripts yes' is desired, as
explained above). But each \fBpkgmk(8)\fP process will take place on the parent
filesystem, inspecting \fIthe parent filesystem\fP's environment for
information about installed ports and available shared libraries. The
\fBpkgmk(8)\fP process might therefore draw the wrong conclusions about what
functionality should be enabled for an installation to <dir>. If the parent
filesystem is more richly populated than <dir>, with respect to installed
packages, then the built package might exhibit breakage when \fBpkgadd\fP
unpacks it into <dir>.
When setting --install-root=<dir>, install or update commands might behave
unexpectedly if <dir>/etc/pkgadd.conf exists and is different from
/etc/pkgadd.conf . In order to preserve the \fBpkgadd.conf(5)\fP settings from
the host system, append the option --aargs='-c /etc/pkgadd.conf' to your
\fBprt-get install\fP command, or just copy the desired directives into
<dir>/etc/pkgadd.conf .
.TP
.B \-\-log
Write build output to log file
Write build output to log file. Basically a convenient alias for
\fB\-\-config\-set=\(dqwritelog enabled\(dq\fP. Note that there is no similar
alias allowing you to temporarily override the one configuration directive
\(dqwritelog enabled\(dq; you have to resort to \fB\-\-config\-set=\(dqwritelog
disabled\(dq\fP if that is your intention.
.TP
.B \-\-no-std-config
@@ -592,7 +653,7 @@ Set <string> in configuration, overriding configuration file
.TP
.B \-\-config=<file>
Use alternative configuration file to read ports directories from
Use <file> to read configuration directives, rather than /etc/prt-get.conf.
.SH ""
@@ -637,31 +698,26 @@ Download, build and install irssi, 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.
.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.
Install paper and yasm. Abort with an informative error message if either
package is already installed, allowing you to issue a revised command.
.TP
.B prt\-get update -fr openssh
.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. :\-)
.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
.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 isinst $(prt-get info ffmpeg | awk -v FS=: '/^Optional/ {gsub(/,/,\(dq \(dq,$2); print $2}') | awk -v FS=\(dq \(dq '/not installed/ {print $2}'
.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.
.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}' | xargs prt\-get depinst \-\-group \-\-softdeps ffmpeg
.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}' | xargs prt\-get depinst \-\-group \-\-softdeps ffmpeg
Extension of the above. Installs ffmpeg and all its optional dependencies, in
the order that guarantees a maximal feature set. The --group flag tells
\fBprt\-get\fP to abort the operation if any port fails to build, so as not to
@@ -669,7 +725,7 @@ spend any resources on ffmpeg until all of its optional dependencies are in
place.
.TP
.B prt\-get isinst $(if grep -qE '^ffmpeg:' /etc/prt-get.softdeps 2>/dev/null; then grep -E '^ffmpeg:' /etc/prt-get.softdeps | cut -d: -f2 | tr ',' ' '; else prt-get info ffmpeg | awk -v FS=: '/^Optional/ {gsub(/,/,\(dq \(dq,$2); print $2}'; fi) | awk -v FS=\(dq \(dq '/not installed/ {print $2}' | xargs prt\-get depinst \-\-group \-\-softdeps ffmpeg
.B prt\-get isinst $(if grep \-qE '^ffmpeg:' /etc/prt\-get.softdeps 2>/dev/null; then grep \-E '^ffmpeg:' /etc/prt\-get.softdeps | cut \-d: \-f2 | tr ',' ' '; else prt\-get info ffmpeg | awk \-v FS=: '/^Optional/ {gsub(/,/,\(dq \(dq,$2); print $2}'; fi) | awk \-v FS=\(dq \(dq '/not installed/ {print $2}' | xargs prt\-get depinst \-\-group \-\-softdeps ffmpeg
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
@@ -689,12 +745,17 @@ Return a list of all ports whose names start with "mc", "nc", or "pc"
Return a list of all ports having "irc" in their name or description
.TP
.B comm -13 <(ls /usr/ports/core) <(prt-get listorphans)
.B prt\-get fsearch \-\-full \(dq/usr/etc/*\(dq | awk '/^Found in/ { $0=gensub(/Found in .*\e/(.+):/,\(dq\e\e1\(dq,\(dqg\(dq); print;}'
Return a list of all ports that store their configs in /usr/etc. Omit the
pipe to awk if you also want a detailed list of the files that matched.
.TP
.B comm \-13 <(ls /usr/ports/core) <(prt\-get listorphans)
(based on comments from Romster and jue) Filter out the core ports from the list of orphans, in
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
.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
@@ -712,7 +773,15 @@ Same as above, but only print the dependencies that are already installed. The o
command is suitable for piping to \fBxargs prt\-get update\fP.
.TP
.B comm -3 <(prt\-get printf \(dq%i:%n %v-%r\en\(dq | grep -v ^no | cut -d: -f2 | sort) <(pkginfo -i | sort)
.B prt\-get isinst $(prt\-get quickdep i3) | awk '/not installed/ { print $2 }' | xargs prt\-get depinst \-\-softdeps \-\-test
(inspired by a troubleshooting session with hestia) Assemble a set of install
targets needed to build the i3 window manager; sort the list, respecting both
hard and soft dependencies; then print how the installation would proceed. The
awk filter in the middle is needed to prevent the command from failing with the
error message "already installed".
.TP
.B comm \-3 <(prt\-get printf \(dq%i:%n %v\-%r\en\(dq | grep \-v ^no | cut \-d: \-f2 | sort) <(pkginfo \-i | sort)
(inspired by a bug report from teodor) an alternative to \fBprt\-get diff\fP.
In the output, left-justified lines show the version available in the
repositories, while indented lines show the version installed. On a
@@ -720,22 +789,35 @@ reasonably up-to-date system, the two processes in the above command will
return many identical lines; these are suppressed by the -3 flag to
\fBcomm(1)\fP.
.TP
.B for L in /var/log/pkgbuild/*.log; do P=${L%__*}; P=${P##*/}; VR=${L##*__}; VR=${VR%.log}; if ! prt\-get isinst $P >/dev/null; then mv $L /var/log/uninstalled/; elif [ \(dq$(prt\-get current $P)\(dq != \(dq$VR\(dq ]; then mv $L /var/log/oldbuild/; fi; done
(based on a feature request by samsep10l) a command you can put into a script
called by root's crontab, in order to mimic Slackware's tidy directory listings
(the main logdir only contains build logs of the latest installed packages;
other logs are moved to a separate directory). This particular command relies
on declaring \(dqlogfile /var/log/pkgbuild/%n__%v-%r.log\(dq and \(dqwritelog
enabled\(dq in \fBprt\-get.conf(5)\fP. Logs saved with a different filename
pattern will require slight adjustments to the command.
.TP
.B prt\-get printf \(dq%p\et%u\en\(dq | awk '($1 ~ /\e/myrepo$/) { print $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.
.TP
.B prt\-get printf \(dq%M\et%n\en\(dq | grep ^Tim | wc -l
.B prt\-get printf \(dq%M\et%n\en\(dq | grep \-c ^Tim
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.
.TP
.B for u in $(prt\-get printf \(dq%M:%p/%n\en\(dq | grep \-i ^unmaintained | cut \-d: \-f2); do cd ${u%/*}; printf \(dq||%s ||\(dq ${u##*/}; git log ${u##*/} | head \-n 5 | awk '/^Date/ { $0=gensub(/^Date:\es+/,"","g"); printf(\(dq %s ||\en\(dq,$0); }'; cd \- >/dev/null; done
Generate a table of unmaintained ports and the dates of their most recent
commit, in PmWiki syntax (left-justified port names, centered dates).
Requires that your repositories are synchronized using the \fBgit(1)\fP driver.
Subsequent sorting by date may be done using \fBsort(1)\fP with the flags
-k, -M, and -n (the appropriate key defs will depend on your locale).
.TP
.B prt-get listinst \-\-depsort | xargs prt-get install \-\-install\-root=/mnt
.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
@@ -743,7 +825,7 @@ pkgadd.conf that you want applied to this operation, either copy it to
/etc/pkgadd.conf\(dq to the install command.
.TP
.B prt-get list --path --regex '^xorg.*' | grep -v \(dq/usr/ports/xorg\(dq
.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.
(At the time of writing, this command returned at least two font ports.)

View File

@@ -20,7 +20,7 @@ It might look like this:
# prt-get.conf
# root directories
prtdir /usr/ports/base
prtdir /usr/ports/core
prtdir /usr/ports/opt
prtdir /usr/ports/contrib
@@ -128,9 +128,31 @@ replaced with the port's path, e.g. for port gcc in core, %p would be
and %n would be
.B gcc.
This allows you to have separate log files per port.
Separate log files for each version and release can be achieved
using the placeholders %v and %r, respectively. But if you want to
enable \fBrmlog_on_uninst\fP, it is best to avoid %p, %v, and %r
when specifying \fBlogfile\fP (as explained below).
.B rmlog_on_uninst
which can be set to 'yes' or 'no'; when set to yes, uninstalling a
package will also try to delete its build log. Replacements in the template
\fBlogfile\fP will be made using the \fIcurrent values\fP from the database
of installed packages, and from the active repositories. If log files exist
with different values of %p, %v, or %r than what the database and repositories
provide, then the pattern substitutions will fail to match the names of those
logs, and this feature will be a no-op. For example, suppose you specify
the logfile pattern \(dq%p/.buildlogs/%n-%v-%r.log\(dq, and you have a package
installed on your system through many versions, or after it has been
moved from opt to contrib. Uninstalling that package would leave behind all the
build logs except the latest. This pattern is also fragile with respect to
repository purges; if one of your installed ports is dropped from the official
repos, then either \(dq%p\(dq will expand to the path of your personal overlay
(you did make a copy, right?), or it will not expand at all! See the EXAMPLES
section of \fBprt\-get(8)\fP for an alternative way to tidy up your directory
of build logs.
.B readme
which can be set to 'disabled', to suppress the notification after
can be set to 'disabled', to suppress the notification after
installing a port with a README file; 'compact', to collect all the READMEs
into one post-transaction output; or 'verbose', to print separate
information about each port with a README file. See
@@ -149,13 +171,13 @@ append a comma separated list of ports to be used after the path,
using a colon (':') character to separate the two components
.B path:package1, package2,...
Note that this slows down prt-get a lot if you list a lot of packages.
If you become aware of speed problems due to this, create a separate
ports directory instead and use symlinks for the ports you want to use.
If you become aware of speed problems due to this feature, create a separate
ports directory instead and fill it with symlinks to the ports you want.
.LP
You can write comments after a '#' character. If you have '#'
characters in your paths, there's no way to escape them (as there is no
way to escape ':' characters). Complain to the author if this is a
characters in your paths, there's no way to escape them (likewise there is
no way to escape ':' characters). Complain to the author if this is a
problem :-)

View File

@@ -17,7 +17,8 @@ prtdir /usr/ports/opt
### log options:
# writelog enabled # (enabled|disabled)
# logmode overwrite # (append|overwrite)
# rm_on_success no # (yes|no)
# rmlog_on_success no # (yes|no)
# rmlog_on_uninst no # (yes|no)
logfile /var/log/pkgbuild/%n.log
# path, %p=path to port dir, %n=port name
# %v=version, %r=release

View File

@@ -128,7 +128,7 @@ const string& ArgParser::alternateConfigFile() const
*/
bool ArgParser::parse()
{
const int commandCount = 34;
const int commandCount = 35;
string commands[commandCount] = { "list", "search", "dsearch",
"info", "version", "cache",
"depends", "install", "depinst",
@@ -139,7 +139,7 @@ bool ArgParser::parse()
"fsearch", "lock", "unlock",
"listlocked", "cat", "ls", "edit",
"remove", "deptree", "dumpconfig",
"listorphans" };
"listorphans", "sync" };
Type commandID[commandCount] = { LIST, SEARCH, DSEARCH, INFO,
SHOW_VERSION, CREATE_CACHE,
@@ -150,7 +150,7 @@ bool ArgParser::parse()
DEPENDENT, SYSUP, CURRENT,
FSEARCH, LOCK, UNLOCK, LISTLOCKED,
CAT, LS, EDIT, REMOVE, DEPTREE,
DUMPCONFIG, LISTORPHANS };
DUMPCONFIG, LISTORPHANS, SYNC };
if ( m_argc < 2 ) {
return false;
}

View File

@@ -38,7 +38,7 @@ public:
LISTINST, PRINTF, README, DEPENDENT, SYSUP,
CURRENT, FSEARCH, LOCK, UNLOCK, LISTLOCKED,
CAT, LS, EDIT, REMOVE,
DEPTREE, DUMPCONFIG, LISTORPHANS };
DEPTREE, DUMPCONFIG, LISTORPHANS, SYNC };
bool isCommandGiven() const;
bool isTest() const;

View File

@@ -30,6 +30,7 @@ Configuration::Configuration( const std::string& configFile,
m_writeLog( false ),
m_appendLog( false ),
m_removeLogOnSuccess( false ),
m_removeLogOnUninst( false ),
m_readmeMode( VERBOSE_README ),
m_runScripts( false ),
m_preferHigher( false ),
@@ -84,6 +85,11 @@ bool Configuration::removeLogOnSuccess() const
return m_removeLogOnSuccess;
}
bool Configuration::removeLogOnUninst() const
{
return m_removeLogOnUninst;
}
string Configuration::logFilePattern() const
{
return m_logFilePattern;
@@ -171,6 +177,13 @@ void Configuration::parseLine(const string& line, bool prepend)
} else if ( s == "no" ) {
m_removeLogOnSuccess = false;
}
} else if ( startsWithNoCase( s, "rmlog_on_uninst" ) ) {
s = stripWhiteSpace( s.replace( 0, 15, "" ) );
if ( s == "yes" ) {
m_removeLogOnUninst = true;
} else if ( s == "no" ) {
m_removeLogOnUninst = false;
}
} else if ( startsWithNoCase( s, "readme" ) ) {
s = stripWhiteSpace( s.replace( 0, 6, "" ) );
if ( s == "compact" ) {
@@ -252,6 +265,6 @@ bool Configuration::useRegex() const
bool Configuration::followSoftdeps() const
{
return m_followSoftdeps;
return ( m_followSoftdeps || m_parser->followSoftdeps() );
}

View File

@@ -30,6 +30,7 @@ public:
bool writeLog() const;
bool appendLog() const;
bool removeLogOnSuccess() const;
bool removeLogOnUninst() const;
std::string logFilePattern() const;
const std::list< std::pair<std::string, std::string> >& rootList() const;
@@ -67,6 +68,7 @@ private:
bool m_writeLog;
bool m_appendLog;
bool m_removeLogOnSuccess;
bool m_removeLogOnUninst;
ReadmeMode m_readmeMode;

View File

@@ -184,8 +184,19 @@ InstallTransaction::install( const ArgParser* parser,
InstallTransaction::InstallResult result;
InstallInfo info( package->hasReadme() );
if ( parser->isTest() ||
(result = installPackage( package, parser, update, info )) == SUCCESS) {
if ( parser->isTest() ) {
info.preState = ( package->hasPreInstall() &&
(parser->execPreInstall() || m_config->runScripts())
) ? DEFERRED : NONEXISTENT;
info.postState = ( package->hasPostInstall() &&
(parser->execPostInstall() || m_config->runScripts())
) ? DEFERRED : NONEXISTENT;
m_installedPackages.push_back( make_pair( package->path()
+ "/" + package->name(), info));
continue;
}
if ((result = installPackage( package, parser, update, info )) == SUCCESS) {
m_installedPackages.push_back( make_pair( package->path()
+ "/" + package->name(), info));
@@ -313,7 +324,7 @@ InstallTransaction::installPackage( const Package* package,
// -- pre-install
struct stat statData;
if ((parser->execPreInstall() || m_config->runScripts()) &&
stat((pkgdir + "/" + "pre-install").c_str(), &statData) == 0) {
stat((parser->installRoot() + pkgdir + "/" + "pre-install").c_str(), &statData) == 0) {
Process preProc( runscriptCommand,
pkgdir + "/" + "pre-install",
fdlog );
@@ -421,9 +432,9 @@ InstallTransaction::installPackage( const Package* package,
} else {
// exec post install
if ((parser->execPostInstall() || m_config->runScripts() ) &&
stat((package->path() + "/" + package->name() +
"/" + "post-install").c_str(), &statData)
== 0) {
stat((parser->installRoot() + package->path()
+ "/" + package->name() + "/" + "post-install").c_str(),
&statData) == 0) {
// Work around the pkgdir variable change
Process postProc( runscriptCommand,
package->path() + "/" + package->name()+
@@ -470,7 +481,6 @@ bool InstallTransaction::calculateDependencies()
return false;
}
vector<string> treeWalk;
list< pair<string, const Package*> >::const_iterator it =
m_packages.begin();
for ( ; it != m_packages.end(); ++it ) {
@@ -516,8 +526,8 @@ void InstallTransaction::checkDependencies( bool greedy,
if ( index == -1 ) {
index = m_depList.size();
if (( not greedy ) or ( m_pkgDB->isInstalled(package->name(),false) )) {
m_depList.push_back( package->name() );
if ( (!greedy) or isRequired( package->name() ) ) {
m_depList.push_back( package->name() );
}
}
@@ -545,41 +555,31 @@ void InstallTransaction::checkDependencies( bool greedy,
list<string>::iterator it = deps.begin();
for ( ; it != deps.end(); ++it ) {
string dep = *it;
if ( !dep.empty() ) {
string::size_type pos = dep.find_last_of( '/' );
if ( pos != string::npos && (pos+1) < dep.length() ) {
dep = dep.substr( pos + 1 );
}
const Package* p = m_repo->getPackage( dep );
if ( p ) {
checkDependencies( greedy, p, index );
} else {
m_missingPackages.
push_back( make_pair( dep, package->name() ) );
}
if ( dep.empty() ) { continue; }
const Package* p = m_repo->getPackage( dep );
if ( p ) {
checkDependencies( greedy, p, index );
} else {
m_missingPackages.
push_back( make_pair( dep, package->name() ) );
}
}
}
if ( (m_config->followSoftdeps()) and (!package->optionals().empty()) ) {
list<string> softDeps;
split( package->optionals(), ',', softDeps );
list<string>::iterator it = softDeps.begin();
for ( ; it != softDeps.end(); ++it ) {
list<string> optionals;
split( package->optionals(), ',', optionals );
list<string>::iterator it = optionals.begin();
for ( ; it != optionals.end(); ++it ) {
string softdep = *it;
if ( !softdep.empty() ) {
string::size_type pos = softdep.find_last_of( '/' );
if ( pos != string::npos && (pos+1) < softdep.length() ) {
softdep = softdep.substr( pos + 1 );
if ( softdep.empty() ) { continue; }
if ( isRequired(softdep) ) {
const Package* p = m_repo->getPackage( softdep );
if ( p ) {
checkDependencies( true, p, index );
} else {
m_missingPackages.
push_back( make_pair( softdep, package->name() ) );
}
if ( m_pkgDB->isInstalled(softdep, false) or isRequested(softdep) ) {
const Package* p = m_repo->getPackage( softdep );
if ( p ) {
checkDependencies( true, p, index );
} else {
m_missingPackages.
push_back( make_pair( softdep, package->name() ) );
}
}
}
}
}
@@ -590,12 +590,13 @@ void InstallTransaction::checkDependencies( bool greedy,
}
/*!
Method to determine whether a package was passed on the command line
Method to determine whether a soft dependency should be part of the transaction
*/
bool InstallTransaction::isRequested(const string pname) {
bool InstallTransaction::isRequired(const string &pname) {
if ( m_pkgDB->isInstalled(pname,false) ) { return true; }
list< pair<string, const Package*> >::iterator it = m_packages.begin();
for ( ; it != m_packages.end(); ++it ) {
if ( it->first == pname ) { return true; }
if ( pname == it->first ) { return true; }
}
return false;
}
@@ -717,7 +718,7 @@ string InstallTransaction::getPkgmkSettingFromFile(const string& setting, const
if (p) {
fgets(line, 256, p);
value = StringHelper::stripWhiteSpace(line);
fclose(p);
pclose(p);
}
}

View File

@@ -56,9 +56,7 @@ public:
SUCCESS, /*!< yeah, success */
NO_PACKAGE_GIVEN, /*!< no package give 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 */
PKGADD_FAILURE, /*!< error while pkgadd */
CYCLIC_DEPEND, /*!< cyclic dependencies found */
@@ -71,6 +69,7 @@ public:
enum State {
EXEC_SUCCESS,
FAILED,
DEFERRED,
NONEXISTENT
};
struct InstallInfo {
@@ -108,7 +107,7 @@ private:
const ArgParser* parser,
bool update,
InstallInfo& info ) const;
bool isRequested(const string pname);
bool isRequired(const string &pname);
static string getPkgmkSetting(const string& setting);
static string getPkgmkSettingFromFile(const string& setting,

View File

@@ -161,6 +161,9 @@ int main( int argc, char** argv )
case ArgParser::LISTORPHANS:
prtGet.listOrphans();
break;
case ArgParser::SYNC:
prtGet.syncPorts();
break;
default:
cerr << "unknown command" << endl;
break;

View File

@@ -124,7 +124,7 @@ const string& Package::maintainer() const
}
/*! \return whether or not this package has a readme file */
const bool Package::hasReadme() const
bool Package::hasReadme() const
{
load();
return m_data->hasReadme;
@@ -137,12 +137,12 @@ string Package::versionReleaseString() const
return m_data->versionReleaseString;
}
const bool Package::hasPreInstall() const
bool Package::hasPreInstall() const
{
return m_data->hasPreInstall;
}
const bool Package::hasPostInstall() const
bool Package::hasPostInstall() const
{
return m_data->hasPostInstall;
}
@@ -345,11 +345,9 @@ void Package::expandShellCommands(std::string& input,
pos = 0;
while ((pos = input.find(startTag[i], pos)) != string::npos) {
if (unameBuf.release) {
input = replaceAll(input,
startTag[i] + "uname -r" + endTag[i],
unameBuf.release);
}
input = replaceAll(input,
startTag[i] + "uname -r" + endTag[i],
unameBuf.release);
dpos = input.find(startTag[i] + "date");
if (dpos != string::npos) {

View File

@@ -52,9 +52,9 @@ public:
const std::string& url() const;
const std::string& optionals() const;
const std::string& maintainer() const;
const bool hasReadme() const;
const bool hasPreInstall() const;
const bool hasPostInstall() const;
bool hasReadme() const;
bool hasPreInstall() const;
bool hasPostInstall() const;
std::string versionReleaseString() const;

View File

@@ -68,9 +68,9 @@ int Process::execute()
int status = 0;
if ( m_fdlog > 0 ) {
status = execLog(argc, argv);
status = execLog(argv);
} else {
status = exec(argc, argv);
status = exec(argv);
}
delete [] argv;
@@ -78,7 +78,7 @@ int Process::execute()
}
int Process::execLog(const int argc, char** argv)
int Process::execLog(char** argv)
{
int status = 0;
int fdpipe[2];
@@ -123,7 +123,7 @@ int Process::execLog(const int argc, char** argv)
}
int Process::exec(const int argc, char** argv)
int Process::exec(char** argv)
{
int status = 0;
pid_t pid = fork();

View File

@@ -32,8 +32,8 @@ public:
private:
int exec(const int argc, char** argv);
int execLog(const int argc, char** argv);
int exec(char** argv);
int execLog(char** argv);
int execShell(const char* shell);
int execShellLog(const char* shell);

View File

@@ -70,8 +70,8 @@ PrtGet::PrtGet( const ArgParser* parser )
m_pkgDB = new PkgDB(m_parser->installRoot());
readConfig();
m_useRegex = m_config->useRegex() || m_parser->useRegex();
m_followSoftdeps = m_config->followSoftdeps() || m_parser->followSoftdeps();
m_useRegex = ( m_config->useRegex() || m_parser->useRegex() );
m_followSoftdeps = ( m_config->followSoftdeps() || m_parser->followSoftdeps() );
}
/*! destruct PrtGet object */
@@ -271,7 +271,7 @@ void PrtGet::listShadowed()
if (m_parser->otherArgs().size() > 0)
format = *(m_parser->otherArgs().begin());
else if (m_parser->verbose() > 0)
format = "* %n\n %p1 %v1 preceeds over \n %p2 %v2\n";
format = "* %n\n %p1 %v1 precedes over \n %p2 %v2\n";
string output;
Package* p1;
@@ -289,8 +289,13 @@ void PrtGet::listShadowed()
StringHelper::replaceAll(output, "%p2", p2->path() + "/" + p2->name());
StringHelper::replaceAll(output, "%v1", p1->versionReleaseString());
StringHelper::replaceAll(output, "%v2", p2->versionReleaseString());
StringHelper::replaceAll(output, "%M1", p1->maintainer());
StringHelper::replaceAll(output, "%M2", p2->maintainer());
StringHelper::replaceAll(output, "%u1", p1->url());
StringHelper::replaceAll(output, "%u2", p2->url());
StringHelper::replaceAll(output, "\\n", "\n");
StringHelper::replaceAll(output, "\\t", "\t");
cout << output;
}
}
@@ -692,11 +697,6 @@ void PrtGet::executeTransaction( InstallTransaction& transaction,
case InstallTransaction::PACKAGE_NOT_FOUND:
cout << m_appName << ": package(s) not found" << endl;
break;
case InstallTransaction::PKGMK_EXEC_ERROR:
cout << m_appName << " couldn't excecute pkgmk "
<< "(or alternative command). "
<< "Make sure it's installed properly" << endl;
break;
case InstallTransaction::PKGMK_FAILURE:
cout << m_appName << ": error while " << command[0] << endl;
break;
@@ -704,10 +704,6 @@ void PrtGet::executeTransaction( InstallTransaction& transaction,
cout << m_appName << ": no package specified for "
<< command[0] << endl;
break;
case InstallTransaction::PKGADD_EXEC_ERROR:
cout << m_appName << " couldn't excecute pkgadd. "
<< "Make sure it's installed properly" << endl;
break;
case InstallTransaction::PKGDEST_ERROR:
cout << m_appName << ": error changing to PKGDEST directory "
<< transaction.getPkgmkPackageDir() << endl;
@@ -1186,20 +1182,19 @@ void PrtGet::evaluateResult( InstallTransaction& transaction,
void PrtGet::reportPrePost(const InstallTransaction::InstallInfo& info) {
if (info.preState != InstallTransaction::NONEXISTENT) {
string preString = "failed";
if (info.preState == InstallTransaction::EXEC_SUCCESS) {
preString = "ok";
string preString = (info.preState == InstallTransaction::FAILED) ? "failed" : "ok";
if (info.preState == InstallTransaction::DEFERRED){
preString = "deferred";
}
cout << " [pre: " << preString << "]";
}
if ( info.postState != InstallTransaction::NONEXISTENT) {
string postString = "failed";
if (info.postState == InstallTransaction::EXEC_SUCCESS){
postString = "ok";
string postString = (info.postState == InstallTransaction::FAILED) ? "failed" : "ok";
if (info.postState == InstallTransaction::DEFERRED){
postString = "deferred";
}
cout << " [post: " << postString << "]";
}
}
/*! create a cache */
@@ -1268,7 +1263,7 @@ void PrtGet::printf()
assertExactArgCount(1);
initRepo();
string filter = m_parser->useRegex() ? "." : "*";
string filter = m_useRegex ? ".*" : "*";
if ( m_parser->hasFilter() ) {
filter = m_parser->filter();
}
@@ -1676,7 +1671,7 @@ void PrtGet::current()
m_returnValue = 1;
}
SignalHandler::HandlerResult PrtGet::handleSignal( int signal )
SignalHandler::HandlerResult PrtGet::handleSignal()
{
// TODO: second argument could also be true:
// TODO: kill installtransaction
@@ -1926,12 +1921,17 @@ void PrtGet::remove()
{
assertMinArgCount(1);
bool needRepo = false;
list<string> removed;
list<string> failed;
list<string> notInstalled;
if ( m_parser->isTest() ) {
cout << "*** " << m_appName << ": test mode" << endl;
} else if ( m_config->removeLogOnUninst()
&& m_config->logFilePattern().find("%p") != string::npos ) {
needRepo = true;
initRepo();
}
string command = InstallTransaction::PKGRM_DEFAULT_COMMAND;
@@ -1943,20 +1943,46 @@ void PrtGet::remove()
list<char*>::const_iterator it = args.begin();
for ( ; it != args.end(); ++it ) {
if (m_pkgDB->isInstalled(*it)) {
// TODO: prettify
string args = "";
if (m_parser->installRoot() != "") {
args = "-r " + m_parser->installRoot() + " ";
}
args += (m_parser->pkgrmArgs() + " " + *it);
string rm_args = (m_parser->installRoot() == "") ? "" :
"-r " + m_parser->installRoot() + " ";
rm_args += (m_parser->pkgrmArgs() + " " + *it);
Process proc(command, args);
Process proc(command, rm_args);
if (m_parser->isTest() || proc.executeShell() == 0) {
removed.push_back(*it);
if (m_locker.isLocked(*it)) {
m_locker.unlock(*it);
m_locker.store();
}
if (m_config->removeLogOnUninst() && !m_parser->isTest()) {
string rm_logFile = m_config->logFilePattern();
bool doneSubs=false;
const string pkgname = *it;
StringHelper::replaceAll( rm_logFile, "%n", pkgname );
const string rm_ver = m_pkgDB->getPackageVersion( pkgname );
size_t pos = rm_ver.find_last_of('-');
if (pos != string::npos) {
const string rm_v = rm_ver.substr(0,pos);
const string rm_r = rm_ver.substr(pos+1);
StringHelper::replaceAll( rm_logFile, "%v", rm_v );
StringHelper::replaceAll( rm_logFile, "%r", rm_r );
}
if (! needRepo) {
doneSubs=true;
} else if (m_repo->getPackage( pkgname )) {
StringHelper::replaceAll( rm_logFile, "%p",
m_repo->getPackage( pkgname )->path() );
doneSubs=true;
} else {
cout << "Warning: unable to determine the logfile for "
+ pkgname + "; log removal aborted." << endl;
}
struct stat slF;
if ( doneSubs && stat(rm_logFile.c_str(), &slF)==0
&& (slF.st_mode & S_IFMT)==S_IFREG ) {
unlink( rm_logFile.c_str() );
}
}
} else {
failed.push_back(*it);
}
@@ -2268,3 +2294,81 @@ void PrtGet::dumpConfig()
cout << endl;
}
}
void PrtGet::syncPorts()
{
const string sup_path = m_parser->installRoot() + "/etc/ports";
const string driver_path = sup_path + "/drivers";
DIR* d = opendir(driver_path.c_str());
if (d == NULL) {
cerr << "Ports drivers directory " << driver_path.c_str()
<< " not found. Aborting sync." << endl;
m_returnValue = PG_GENERAL_ERROR;
return;
}
struct dirent* de;
struct stat buf;
list<string> drivers;
while ( (de = readdir(d)) ) {
string drvName = de->d_name;
if (drvName != "." && drvName != ".." && stat((driver_path + "/" + drvName).c_str(), &buf) == 0
&& buf.st_mode & S_IXUSR ) {
drivers.push_back(drvName);
}
}
closedir(d);
if (drivers.size() == 0) {
cerr << "No valid ports drivers. Aborting sync." << endl;
m_returnValue = PG_GENERAL_ERROR;
return;
}
if (m_parser->otherArgs().size()) { // sync selected repositories, with
drivers.sort(); // multi-stage processing done predictably
bool repo_active;
list<char*>::const_iterator itc = m_parser->otherArgs().begin();
list<string>::const_iterator itd;
for (; itc != m_parser->otherArgs().end(); ++itc) {
repo_active = false;
for (itd = drivers.begin(); itd != drivers.end(); ++itd) {
if (stat((sup_path + "/" + *itc + "." + *itd).c_str(),&buf) == 0) {
repo_active = true;
Process syncProc( driver_path + "/" + *itd,
sup_path + "/" + *itc + "." + *itd, -1 );
if (syncProc.execute()) {
m_returnValue = PG_GENERAL_ERROR;
}
}
}
if (! repo_active) {
cerr << *itc << ": not a valid port collection" << endl;
}
}
} else { // sync all active repositories
list<string> activeRepos;
size_t pos;
d = opendir(sup_path.c_str());
while ( (de = readdir(d)) ) {
string rName = de->d_name;
pos = rName.find_last_of(".");
if ( pos != string::npos && find(drivers.begin(), drivers.end(),
rName.substr(pos+1)) != drivers.end() ) {
activeRepos.push_back(rName);
}
}
closedir(d);
activeRepos.sort();
list<string>::const_iterator ite = activeRepos.begin();
for ( ; ite != activeRepos.end(); ++ite) {
pos = (*ite).find_last_of(".");
Process syncProc( driver_path + "/" + (*ite).substr(pos+1),
sup_path + "/" + *ite, -1 );
if (syncProc.execute()) {
m_returnValue = PG_GENERAL_ERROR;
}
}
}
}

View File

@@ -71,6 +71,7 @@ public:
void printDiff();
void printQuickDiff();
void listOrphans();
void syncPorts();
void createCache();
@@ -92,7 +93,7 @@ public:
int returnValue() const;
SignalHandler::HandlerResult handleSignal( int signal );
SignalHandler::HandlerResult handleSignal();
protected:

View File

@@ -36,7 +36,7 @@ void SignalDispatcher::dispatch( int signalNumber )
map<int, SignalHandler*>::iterator it =
SignalDispatcher::instance()->m_signalHandlers.find( signalNumber );
if ( it != SignalDispatcher::instance()->m_signalHandlers.end() ) {
it->second->handleSignal( signalNumber );
it->second->handleSignal();
} else {
cerr << "prt-get: caught signal " << signalNumber << endl;
}

View File

@@ -28,7 +28,7 @@ public:
EXIT, /*!< signal handled, exit now */
CONTINUE /*!< signal handled, don't exit */
};
virtual HandlerResult handleSignal( int signalNumber ) = 0;
virtual HandlerResult handleSignal() = 0;
};
/*!