Merged changes from development branch

- Updated man-pages and README
- Updated copyright year
- Replaced external processes with native Perl routines
- Changed the interpretation of pkg-repgen's optional @ARGV to
  start with the target directory, like httpup-repgen
- Fixed PKGINST to accommodate ports with dashes in their names
This commit is contained in:
John McQuah 2025-01-13 19:43:32 +00:00
parent 98a2df234e
commit 1f479e5397
13 changed files with 1385 additions and 1591 deletions

View File

@ -1,5 +1,17 @@
ChangeLog for pkg-get
0.5.0 - Fix doscript() to accommodate rootfs other than "/",
and ports with dashes in their names
- Use native Perl routines to reduce the number of external processes
- Consolidate code
- Do more tasks in parallel when generating the metadata
- Update the html index too, when individual packages are passed to
pkg-repgen
- Replace wget by curl, to avoid depending on packages outside 'core'
- Update man-pages and README
0.4.7 - Fix man-page location
0.4.6 - Fixed warnings on output of diff command
- Use compression-mode defined in pkgmk.conf
- pkg-repgen.pl: Improved prt-get commands and added --prtdir switch

View File

@ -1,5 +1,5 @@
NAME=pkg-get
VERSION="0.4.6"
VERSION="0.5.0"
PREFIX=/usr
CFGDIR=/etc
@ -8,27 +8,18 @@ MANDIR=/usr/share/man
all:
@echo "Use 'make install' to install pkg-get"
man:
#makeman doc/pkg-get.8.txt
#makeman doc/pkg-repgen.8.txt
#man2ps doc/pkg-get.8 | ps2pdf14 - > doc/pkg-get.pdf
dist: man
dist:
rm -rf ${NAME}-${VERSION}
mkdir ${NAME}-${VERSION}
cp -r doc scripts Makefile ChangeLog COPYING README TODO ${NAME}-${VERSION}
rm -f ${NAME}-${VERSION}/doc/*.txt
rm -f ${NAME}-${VERSION}/doc/*.pdf
mkdir -p ${NAME}-${VERSION}/doc
cp -r scripts Makefile ChangeLog COPYING README TODO ${NAME}-${VERSION}
cp doc/*.* ${NAME}-${VERSION}/doc
tar cvzf ${NAME}-${VERSION}.tar.gz ${NAME}-${VERSION}
rm -rf ${NAME}-${VERSION}
install:
install -D -m 755 scripts/pkg-get.pl ${PREFIX}/bin/pkg-get
install -D -m 755 scripts/pkg-repgen.pl ${PREFIX}/bin/pkg-repgen
install -D -m 755 scripts/pkg-get.pl ${PREFIX}/bin/pkg-get
install -D -m 644 doc/pkg-get.8 ${MANDIR}/man8/pkg-get.8
install -D -m 644 doc/pkg-get.conf ${CFGDIR}/pkg-get.conf
install -D -m 644 doc/pkg-repgen.8 ${MANDIR}/man8/pkg-repgen.8
install -D -m 644 doc/pkg-get.8 ${MANDIR}/man8/pkg-get.8
install -D -m 644 doc/pkg-get.conf ${CFGDIR}/pkg-get.conf
install -D -m 644 doc/style.html ${PREFIX}/share/pkg-get/style.html

89
README
View File

@ -1,8 +1,8 @@
INTRODUCTION
----------------------------------------------------------------------------
pkg-get is a package / repository management tool for CRUX Linux.
Syntax and features are very close (often a carbon copy)
to the ones found in the port management tool 'prt-get'
pkg-get is a package / repository management tool for CRUX.
Syntax and features are very close to (often a carbon copy of)
the ones found in the port management tool 'prt-get'
by Johannes Winkelmann.
In fact pkg-get was developed as a prt-get/ports drop-in replacement
for systems in which it is preferable to handle binary packages instead
@ -11,10 +11,10 @@ of compiling ports.
ARCHITECTURE
----------------------------------------------------------------------------
The local machines sync metadata files (available packages,
readme files, dependencies, etc) from a remote (http or ftp)
The client machines sync metadata files (available packages,
readme files, dependencies, etc) from a remote server (http or ftp)
OR a local path.
Once the metadata is present on the local machine, the usual
Once the metadata files are on the client machine, the usual
operations of installing, removing, getting info on packages
are available.
@ -22,17 +22,19 @@ are available.
QUICK START
----------------------------------------------------------------------------
Server:
A repository can be generated using 'pkg-repgen' in a
dir containing packages. It will take a while since md5sums
have to be calculated.
A repository can be generated using 'pkg-repgen' in a directory
containing packages. It will take a while since md5sums have to be
calculated. Alternatively, you can pass arguments to 'pkg-repgen',
specifying a repository other than $PWD, optionally followed by the
individual packages for which metadata will be created.
Client:
Adjust settings in /etc/pkg-get.conf, then use the 'pkg-get sync'
command to gather metadata from the server (if remote). You can now
use the commands as described in the manual, i.e.:
use the commands as described in the manual, e.g.:
pkg-get info apache
pkg-get depinst kdebase
pkg-get depinst qt6-base
pkg-get listinst
See the manual page for a detailed list of commands and options.
@ -40,5 +42,68 @@ See the manual page for a detailed list of commands and options.
REQUIREMENTS
----------------------------------------------------------------------------
For the client nothing outside the CRUX 'core' collection
For the client, nothing outside the CRUX 'core' collection
For the server, prt-get
LIMITATIONS
----------------------------------------------------------------------------
The pkg-get configuration file does not offer as many settings as the one
for prt-get. In particular, you cannot change "addcommand", "rmcommand", or
"runscriptscommand"; these are hard-coded as /usr/bin/pkgadd, /usr/bin/pkgrm,
and /bin/bash, respectively.
There is also no intelligent version comparator as in prt-get; the
repository and html index are sorted lexographically according to the
current setting for $LANG. When multiple versions of a package are found
within the active collections, pkg-get will install the latest version in
the first collection that contains any such package. This behaviour is akin
to how prt-get handles dups, but with additional logic to account for
different versions of the built package within the same collection.
'pkg-get dependent' does not support the --recursive option. Other
useful prt-get commands (grpinst, fsearch, deptree, listorphans, ls,
cat, edit, cache) have no counterpart in pkg-get. Of these omissions,
only the 'grpinst' command is of possible interest for binary package
management; the unimplemented commands and options are better handled
by prt-get itself.
pkg-get only makes use of the hard dependencies listed by the port
maintainer, not any of the eager linking that might have occurred on the
build machine. As a result, 'pkg-get depinst $foo' might omit some of the
packages needed by $foo. User ppetrov^ has contributed some helper scripts
to facilitate the fixing of these broken binaries; visit the site [1] to
download them.
Further omissions related to dependencies are the absence of any mechanism
for declaring aliases (e.g., package openjdk16-bin can serve as a drop-in
replacement for the listed dependency openjdk16), and the lack of an --ignore
switch (to exclude certain packages from being installed in a 'depinst'
operation). You can work around these omissions by avoiding 'depinst'
entirely, and manually performing the desired 'install' transactions (once
you have a clear sense of what the actual runtime dependencies are).
These gaps in pkg-get's design highlight an awkward fact about trying to
erect an infrastructure for binary package management upon a foundation
designed for compiling source code (the ports tree). Inheriting the
Pkgfile's lack of separation between build-time and runtime dependencies,
pkg-get will unwittingly recurse through all the dependencies (in a 'depinst'
transaction) and install packages that you might not really need. Hence the
suggestion to consider avoiding 'depinst'. But pairing 'install' with the
helper script written by ppetrov^ [1] might not be enough to ensure zero
breakage, since revdep does not detect every runtime dependency. In the
end, you might have to manually interpolate between the footprint
recommended by 'pkg-get depends' and the (smaller) footprint
recommended by 'revlibpkg'.
In handling any new hard dependencies added by the maintainer since
the previous version of a package, pkg-get performs a sysup in the same
manner as the original prt-get (i.e., new dependencies are not injected
by default). With binary packages there's no need to carry out the
installation in any particular order, so the lack of dependency injection is
actually less of a problem for pkg-get than it was for prt-get. Combining
'pkg-get depends $foo | grep "\[ \]"' with the output of 'revlibpkg $foo'
should help identify the packages you will need to install to fix any
breakage in $foo.
[1] https://github.com/slackalaxy/depsck

13
TODO
View File

@ -4,8 +4,15 @@ TODO file for pkg-get
- add more commands:
- deptree (?)
- lock/unlock/listlocked (?)
- grpinst (?)
- optimize the pkg-repgen script
- let the user control whether pkg-repgen prints the metadata only for the
latest built package, or for all the versions in the directory
- improve pkg-get help information
- allow 'sysup' to inject new dependencies (?)
- add a --test switch (?)
- add an --ignore switch (?)
- switch from MD5 to a different hash function (?)

View File

@ -1,75 +1,79 @@
." Text automatically generated by txt2man-1.4.7
.TH pkg-get 8 "July 13, 2006" "" ""
.TH pkg\-get 8 "January 13, 2025" "" ""
.SH NAME
\fBpkg-get \fP- a package management tool for CRUX Linux
\fBpkg\-get\fP \- a package management tool for CRUX
\fB
.SH SYNOPSIS
.nf
.fam C
\fBpkg-get\fP \fIcommand\fP <arguments> [\fIoptions\fP]
\fBpkg\-get\fP \fIcommand\fP <arguments> [\fIoptions\fP]
.fam T
.fi
.SH DESCRIPTION
\fBpkg-get\fP is a simple package management tool for CRUX Linux.
\fBpkg\-get\fP is a simple package management tool for CRUX.
It tries to replicate some of the most useful features of the
port management tool \fBprt-get\fP(8) to be used with binary packages.
\fBpkg-get\fP requires a remote or local package repository that
can be generated by repository maintainers with the
\fBpkg-repgen\fP(8) script.
port management tool \fBprt\-get\fP(8) to be used with binary packages.
\fBpkg\-get\fP requires a remote or local package repository that
can be generated by the \fBpkg\-repgen\fP(8) script.
.SH COMMANDS
.TP
.B
install <package1> [<package2>..<packageN>]
Install given packages,
download if necessary.
Install given packages, download if necessary.
.TP
.B
update <package1> [<package2>..<packageN>]
Update given packages,
download if necessary.
update [\fB\-fr\fP] <package1> [<package2>..<packageN>]
Update given packages, download if necessary. Pass the flag \fB\-fr\fP
to force a fresh download, even if a package of the expected name
already exists in the local directory.
.TP
.B
diff [\fB--all\fP]
Show a list of outdated packages. The \fB--all\fP option also displays locked packages.
diff [\fB\-\-all\fP]
Show a list of outdated packages.
The \fB\-\-all\fP option also displays locked packages.
.TP
.B
quickdiff
Show a compact list of outdated packages.
.TP
.B
sysup
Update all outdated packages. Download if necessary.
sysup [\fB\-\-all\fP]
Update all outdated packages, download if necessary.
Locked packages are excluded from the operation
unless \fB\-\-all\fP is passed.
.TP
.B
depinst <package1> [<package2>..<packageN>]
Install given packages
and relative dependencies.
Install given packages and their dependencies.
.TP
.B
depends <package>
Show a recursive list of dependencies for package
Show a recursive list of dependencies for <package>
and their installation status.
.TP
.B
dependent <package> [\fB--all\fP]
Show installed (or all with the \fB--all\fP option) packages
that depend from package.
quickdep <package>
Show a brief list of dependencies for <package>.
.TP
.B
quickdep <package>
Show a brief list of dependencies for package.
dependent <package> [\fB\-\-all\fP]
Show installed (or all with the \fB\-\-all\fP option) packages
that depend on <package>.
.TP
.B
path <package>
Show local path of <package>.
.TP
.B
info <package>
Show information about package.
Show information about <package>.
.TP
.B
current <package>
Show currently installed version of package.
.TP
.B
path <package>
Show local path of package.
isinst <package>
Display whether a package is installed.
.TP
.B
readme <package>
@ -77,33 +81,32 @@ Print README information (if available) for the package.
.TP
.B
list
List all packages in the repository.
List all packages in the active repositories.
.TP
.B
listinst
List all installed packages.
.TP
.B
isinst <package>
Display whether a package is installed.
.TP
.B
dsearch <string>
Search for packages which name or description contain <string>.
Search for packages whose name or description contains <string>.
.TP
.B
search <string>
Search for packages which name contains <string>.
Search for packages whose name contains <string>.
.TP
.B
dup
List all duplicates ports (present in more than one repository).
List all duplicate ports (present in more than one repository).
Multiple versions of a port appearing in the same repository
are NOT considered dups; only the most recently-built package gets
an entry in the listing for that repository.
.TP
.B
printf <format string1> [\fB--filter\fP=<filter>]
Description blatantly
stolen from prt-get man file. Print formatted port list. Format string can
contain variables, which are replaced like this:
printf <format string> [\fB\-\-filter\fP=<filter>]
Description blatantly stolen from \fBprt\-get\fP(8).
Print formatted port list. Format string can contain variables,
which are replaced like this:
.RS
.IP \(bu 3
%n -> name
@ -122,13 +125,13 @@ contain variables, which are replaced like this:
.IP \(bu 3
%R -> Readme ("yes"/"no")
.IP \(bu 3
%E -> pre-install script ("yes"/"no")
%E -> pre\-install script ("yes"/"no")
.IP \(bu 3
%O -> post-install script ("yes"/"no")
%O -> post\-install script ("yes"/"no")
.IP \(bu 3
%M -> "Nobody". for compatibility with prt-get
%M -> "None". for compatibility with prt\-get
.IP \(bu 3
%P -> "Nobody". for compatibility with prt-get
%P -> "None". for compatibility with prt\-get
.IP \(bu 3
%l -> is locked ("yes"/"no")
.IP \(bu 3
@ -138,97 +141,118 @@ repository.
.RE
.PP
Use "\\n" and "\\t" to format your output (no additional format
specified suported). The optional format string2 can contain the
same variables as format string1 and is used to sort the output.
You can specify a wildcard filter to filter by package name.
codes suported). You can specify a wildcard <filter> to filter
by package name.
.TP
.B
lock <package1> [<package2>..<packageN>]
Lock a package (ignore updates).
Lock a package (exclude it from being updated in a \fBsysup\fP).
\fBpkg\-get\fP and \fBprt\-get\fP read their locked packages
from \fIdifferent\fP locations, allowing you to exclude certain
packages from \fBprt\-get sysup\fP but not from \fBpkg\-get sysup\fP,
or vice\-versa.
.TP
.B
unlock <package1> [<package2>..<packageN>]
Unlock a package.
Unlock a package. Only affects the \fBpkg\-get\fP database.
.TP
.B
listlocked
Display a list of locked packages.
Display a list of locked packages. Only the \fBpkg\-get\fP database
is considered.
.TP
.B
sync
Syncronize local packages with the ones from the remote repository.
If the repository is local, this \fIcommand\fP does nothing.
.TP
.B
sysup
Update all outdated packages.
If the repository is local, this command does nothing.
.TP
.B
help
Display brief help screen.
Display brief help screen.
.TP
.B
version
Show \fBpkg-get\fP version.
Show \fBpkg\-get\fP version.
.SH OPTIONS
.TP
.B
\fB-r\fP <root>
Use <root> directory when wrapping pkgadd. Note that
this only works with update / install !
\fB\-do\fP
Download only. Applicable to: sysup, install, depinst, update.
.TP
.B
\fB-do\fP
Download only. Applicable to: sysup, depinst, install, update.
.TP
.B
\fB-f\fP
\fB\-f\fP
Force installing / upgrading. This is passed to \fBpkgadd\fP(8).
.TP
.B
\fB-im\fP
\fB\-im\fP
Ignore md5sum mismatches.
.TP
.B
\fB--aargs\fP="arguments"
pass the specified arguments to \fBpkgadd\fP(8).
\fB\-\-aargs\fP="arguments"
Pass the specified arguments to \fBpkgadd\fP(8).
.TP
.B
\fB--config\fP=/path/to/file
\fB\-\-config\fP=/path/to/file
Use the specified configuration file.
.TP
.B
\fB--pre-install\fP
executes pre-install script if available.
\fB\-r\fP <root>
Use <root> directory for operations involving the package database
(install, depinst, update, isinst, current, listinst, diff, quickdiff, sysup).
This option does not affect the directories from which \fBpkg\-get\fP loads the
metadata or tarballs; those settings are still governed by the entries in
the configuration file.
When using \fB\-r\fP <root>, the relevant pkgadd.conf is the one on the
target filesystem, not the one where \fBpkg\-get\fP is running. Any custom
directives in your pkgadd.conf should be copied to the corresponding
location under the new root, or else you should pass the \fB\-\-aargs\fP
option to tell \fBpkgadd\fP to read its configuration from a non\-standard
location.
When combined with \fB\-\-pre\-install\fP or \fB\-\-post\-install\fP or
\fB\-\-install\-scripts\fP, setting a root directory other than '/' has the
side effect of copying the PKGINST shell script into the corresponding
location under the new root. This action (and the subsequent chroot command)
is the most direct way to accommodate the user's intention. Unfortunately it
clutters the mounted volume with a small fragment of shell script. If such
clutter is not desired, the option \fB\-r\fP <root> should always be paired
with the configuration setting 'runscripts no', leaving it up to the
administrator of the mounted volume to perform any pre\- or post\-install
tasks separately.
.TP
.B
\fB--post-install\fP
executes post-install script if available.
\fB\-\-pre\-install\fP
Execute pre-install script if available.
.TP
.B
\fB--install-scripts\fP
executes pre-install and post-install
\fB\-\-post\-install\fP
Execute post-install script if available.
.TP
.B
\fB\-\-install\-scripts\fP
Execute pre\-install and post\-install
scripts if available.
.RE
.PP
.SH CONFIGURATION
Configuration is handled by the /etc/pkg-get.conf file,
Configuration is handled by the /etc/pkg\-get.conf file,
\fIoptions\fP are explained in the file itself.
.SH EXAMPLES
.TP
.B
\fBpkg-get\fP install sqlite pysqlite
Install sqlite and pysqlite.
\fBpkg\-get\fP install sqlite3 php\-sqlite3
Install sqlite3 and php\-sqlite3.
.TP
.B
\fBpkg-get\fP depinst kdebase \fB-f\fP
Install kdebase and all its dependencies, forcing upgrade.
\fBpkg\-get\fP depinst qt6\-base \fB\-f\fP
Install qt6\-base and all its dependencies, forcing any pkgadd operation if conflicting files are found.
.TP
.B
\fBpkg-get\fP sysup \fB-do\fP
\fBpkg\-get\fP sysup \fB\-do\fP
Download new releases of all the outdated packages.
.SH AUTHORS
Simone Rota <sip@varlock.com>
Simone Rota <sip@varlock.com>, John McQuah <jmcquah@disroot.org>
.SH SEE ALSO
\fBpkgadd\fP(8), \fBprt-get\fP(8)
\fBpkgadd\fP(8), \fBprt\-get\fP(8), \fBpkg\-repgen\fP(8)

View File

@ -1,101 +0,0 @@
NAME
pkg-get - a package management tool for CRUX Linux
SYNOPSIS
pkg-get command <arguments> [options]
DESCRIPTION
pkg-get is a simple package management tool for CRUX Linux.
It tries to replicate some of the most useful features of the
port management tool prt-get(8) to be used with binary packages.
pkg-get requires a remote or local package repository that
can be generated by repository maintainers with the
pkg-repgen(8) script.
COMMANDS
install <package1> [<package2>..<packageN>] Install given packages,
download if necessary.
update <package1> [<package2>..<packageN>] Update given packages,
download if necessary.
diff [--all] Show a list of outdated packages. The --all option also displays locked packages.
quickdiff Show a compact list of outdated packages.
sysup Update all outdated packages. Download if necessary.
depinst <package1> [<package2>..<packageN>] Install given packages
and relative dependencies.
depends <package> Show a recursive list of dependencies for package
and their installation status.
dependent <package> [--all] Show installed (or all with the --all option) packages
that depend from package.
quickdep <package> Show a brief list of dependencies for package.
info <package> Show information about package.
current <package> Show currently installed version of package.
path <package> Show local path of package.
readme <package> Print README information (if available) for the package.
list List all packages in the repository.
listinst List all installed packages.
isinst <package> Display whether a package is installed.
dsearch <string> Search for packages which name or description contain <string>.
search <string> Search for packages which name contains <string>.
dup List all duplicates ports (present in more than one repository).
printf <format string1> [--filter=<filter>] Description blatantly
stolen from prt-get man file. Print formatted port list. Format string can
contain variables, which are replaced like this:
- %n -> name
- %p -> path
- %v -> version
- %r -> release
- %d -> description
- %e -> dependencies
- %u -> url
- %R -> Readme ("yes"/"no")
- %E -> pre-install script ("yes"/"no")
- %O -> post-install script ("yes"/"no")
- %M -> "Nobody". for compatibility with prt-get
- %P -> "Nobody". for compatibility with prt-get
- %l -> is locked ("yes"/"no")
- %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
repository.
Use "\\n" and "\\t" to format your output (no additional format
specified suported). The optional format string2 can contain the
same variables as format string1 and is used to sort the output.
You can specify a wildcard filter to filter by package name.
lock <package1> [<package2>..<packageN>] Lock a package (ignore updates).
unlock <package1> [<package2>..<packageN>] Unlock a package.
listlocked Display a list of locked packages.
sync Syncronize local packages with the ones from the remote repository.
If the repository is local, this command does nothing.
sysup Update all outdated packages.
help Display brief help screen.
version Show pkg-get version.
OPTIONS
-r <root> Use <root> directory when wrapping pkgadd. Note that
this only works with update / install !
-do Download only. Applicable to: sysup, depinst, install, update.
-f Force installing / upgrading. This is passed to pkgadd(8).
-im Ignore md5sum mismatches.
--aargs="arguments" pass the specified arguments to pkgadd(8).
--config=/path/to/file Use the specified configuration file.
--pre-install executes pre-install script if available.
--post-install executes post-install script if available.
--install-scripts executes pre-install and post-install
scripts if available.
CONFIGURATION
Configuration is handled by the /etc/pkg-get.conf file,
options are explained in the file itself.
EXAMPLES
pkg-get install sqlite pysqlite Install sqlite and pysqlite.
pkg-get depinst kdebase -f Install kdebase and all its dependencies, forcing upgrade.
pkg-get sysup -do Download new releases of all the outdated packages.
AUTHORS
Simone Rota <sip@varlock.com>
SEE ALSO
pkgadd(8), prt-get(8)

View File

@ -3,7 +3,7 @@
# pkg-get configuration file
# package repositories (remote)
# The first two are remote repoistories, the last is a local one
# The first two are remote repositories, the last is a local one
pkgdir /usr/packages/server|http://www.somesite.com/packages
pkgdir /usr/packages/java|http://www.foobar.com/java
pkgdir /usr/packages/games

View File

@ -1,47 +1,72 @@
." Text automatically generated by txt2man-1.4.7
.TH pkg-repgen 8 "July 13, 2006" "" ""
.TH pkg\-repgen 8 "January 13, 2025" "" ""
.SH NAME
\fBpkg-repgen \fP- generate a package repository for pkg-get
\fBpkg\-repgen\fP \- generate a package repository for pkg\-get
\fB
.SH SYNOPSIS
.nf
.fam C
\fBpkg-repgen\fP [options][package1\.\.\.packageN]
\fBpkg\-repgen\fP [options] [directory [package1\.\.\.packageN]]
.fam T
.fi
.SH DESCRIPTION
\fBpkg-repgen\fP generates files needed by a \fBpkg-get\fP(8) package
repository. It also generates a html index of the packages.
\fBpkg\-repgen\fP generates files needed by a \fBpkg\-get\fP(8) package
repository. It also generates a package index suitable for web browsing.
.SH USAGE
run \fBpkg-repgen\fP from the directory containing packages to
generate the whole repository.
Specify a list of package names to update only those packages
(this is expecially useful with large repositories).
Note that the html index is not updated when single
packages are specified.
Run \(cqpkg\-repgen <dir>\(cq to generate the whole repository of packages
found in \fB<dir>\fP. Or to accomplish the same, \(cqcd <dir> &&
pkg\-repgen\(cq. Any additional arguments after \fB<dir>\fP will be interpreted
as the specific package names you want updated (this is especially useful with
large repositories). Even when individual packages are specified, the entire
directory is still processed to collect all the readmes and {pre,post}\-install
scripts.
.SH OPTIONS
.TP
.B
\fB--header\fP=FILE
\fB\-\-header\fP=FILE
insert FILE at the beginning of the html index
.TP
.B
\fB--header\fP=FILE
insert FILE at the beginning of the html index
.TP
.B
\fB--title\fP=title
\fB\-\-title\fP=title
use the specified title for the index page
.TP
.B
\fB--prtdir\fP=DIR
use alternative prtdir for prt-get commands
\fB\-\-prtdir\fP=DIR
use alternative prtdir for the prt\-get metadata lookup (dependencies,
description, install scripts, readme). This option tells prt\-get to behave
as if its config file contained the single line \fIprtdir DIR\fP; all other
directives in /etc/prt\-get.conf are ignored.
.IP
If multiple ports collections all dump their built packages into the common
directory where you are running \fBpkg\-repgen\fP, then this option will omit
metadata, readmes, and install scripts for any ports not found in \fIDIR\fP.
(Every package will still be indexed, but placeholder metadata \(dqNone\(dq
and \(dqN.A.\(dq will appear for Maintainer, Description, and Dependencies
when the corresponding port is outside \fIDIR\fP.) These omissions lead to
bogus output on the client machine running \(cqpkg\-get depends\(cq or
\(cqpkg\-get printf\(cq. Use \fBpkg_installed(1)\fP in conjunction with
\-\-prtdir=/usr/ports/installed to avoid an incomplete repository index.
.TP
.B
\fB\-\-no\-pkgmk\-conf\fP
look for packages matching any supported compression mode, not just the
current setting in pkgmk.conf
.SH EXAMPLES
\fBpkg-repgen\fP
cd /home/sip/packages && \fBpkg\-repgen\fP
.PP
\fBpkg-repgen\fP kdebase kdelibs
\fBpkg\-repgen\fP /home/sip/packages
.PP
\fBpkg\-repgen\fP . qt6\-base qt6\-tools
.SH FILES
\fB/usr/share/pkg\-get/style.html\fP
.PP
To use a common style for both \fBportspage\fP and \fBpkg\-get\fP, you can
create under /usr/share/pkg\-get a symbolic link to ../portspage/style.html,
or vice\-versa. Keeping independent directories allows you to make the two
types of repositories more visually distinguishable when viewed in a web browser,
even though \fBprt\-utils\fP and \fBpkg\-get\fP install initially identical style sheets.
.SH AUTHORS
Simone Rota <sip@varlock.com>
index generation code adapted from Jukka Heino's portspage
Simone Rota <sip@varlock.com>, John McQuah <jmcquah@disroot.org>
.TP
html index code adapted from Jukka Heino's portspage
.SH SEE ALSO
\fBpkg-get\fP(8), \fBprt-get\fP(8)
\fBhttpup\-repgen\fP(8), \fBpkg\-get\fP(8), \fBprt\-get\fP(8)

View File

@ -1,35 +0,0 @@
NAME
pkg-repgen - generate a package repository for pkg-get
SYNOPSIS
pkg-repgen [options][package1...packageN]
DESCRIPTION
pkg-repgen generates files needed by a pkg-get(8) package
repository. It also generates a html index of the packages.
USAGE
run pkg-repgen from the directory containing packages to
generate the whole repository.
Specify a list of package names to update only those packages
(this is expecially useful with large repositories).
Note that the html index is not updated when single
packages are specified.
OPTIONS
--header=FILE insert FILE at the beginning of the html index
--header=FILE insert FILE at the beginning of the html index
--title=title use the specified title for the index page
--prtdir=DIR use alternative prtdir for prt-get commands
EXAMPLES
pkg-repgen
pkg-repgen kdebase kdelibs
AUTHORS
Simone Rota <sip@varlock.com>
index generation code adapted from Jukka Heino's portspage
SEE ALSO
pkg-get(8), prt-get(8)

26
doc/style.html Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
body {
font-family: Verdana, sans-serif;
font-size: 85%;
padding: 2em;
}
table {
border: solid #CAD4E9 1px;
font-size: 85%;
}
td { padding: 6px; }
tr.header { background-color: #CAD4E9; }
tr.odd { background-color: #ECF0F7; }
tr.even { background-color: #F7F9FC; }
a { color: black; }
</style>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
</head>
<body>
<h2></h2>

File diff suppressed because it is too large Load Diff

View File

@ -2,17 +2,16 @@
# derived form Johannes Winkelmann's prt-get completion
# problems: options ending on = should not add a space afterwards
_pkg-get()
{
local cur prev
local cur prev
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}
if [ $COMP_CWORD -eq 1 ]; then
COMPREPLY=( $( compgen -W ' \
if [ $COMP_CWORD -eq 1 ]; then
COMPREPLY=( $( compgen -W ' \
install depinst update help \
version readme list info path \
search dsearch printf sync \
@ -24,14 +23,13 @@ _pkg-get()
if [ $COMP_CWORD '>' 1 ]; then
if [[ "$cur" != -* ]]; then
case ${COMP_WORDS[1]} in
case ${COMP_WORDS[1]} in
"install" | "depinst" | "path" | "dependent" | \
"depends" | "quickdep" | "info" | "readme" | \
"isinst" )
plist=`pkg-get list`
if [ ! "$plist" == "" ]; then
COMPREPLY=( $( compgen -W '$plist' $cur ) )
fi
"depends" | "quickdep" | "info" | "readme" | "isinst" )
plist=`pkg-get list`
if [ -n "$plist" ]; then
COMPREPLY=( $( compgen -W '$plist' $cur ) )
fi
;;
"current"|"lock"|"remove")
plist=`pkg-get listinst`
@ -48,12 +46,23 @@ _pkg-get()
esac
else
case ${COMP_WORDS[1]} in
"install" | "update" | "sysup")
"install" | "sysup")
COMPREPLY=( $( compgen -W '-do \
-im \
--pre-install \
--post-install \
--install-scripts' \
-- $cur ) )
-- $cur ) )
;;
"update")
COMPREPLY=( $( compgen -W '-do \
-im \
-fr \
--pre-install \
--pre-install \
--post-install \
--install-scripts' \
-- $cur ) )
;;
"dependent" )
COMPREPLY=( $( compgen -W '--all' -- $cur ) )
@ -65,6 +74,6 @@ _pkg-get()
fi
fi
return 0
return 0
}
complete -F _pkg-get -o default pkg-get

View File

@ -6,340 +6,477 @@
#
# html index generation code adapted from Jukka Heino's portspage
#
# usage: pkg-repgen [<pkgname1>..<pkgnameN>]
# usage: pkg-repgen [options] [directory [pkgname1..pkgnameN]]
#
use warnings;
use strict;
use Getopt::Long;
use Digest::file qw(digest_file_hex);
our $prtget = "/usr/bin/prt-get"; our $prtdir;
our $title = "CRUX Packages"; our $header; our $footer;
GetOptions("prtdir=s"=>\$prtdir, "title=s"=>\$title, "header=s"=>\$header, "footer=s"=>\$footer);
our $prtget = "/usr/bin/prt-get"; our $prtdir; our $compress;
our $title = "CRUX Packages"; our $header; our $footer; our $help=0; our $noconf;
GetOptions("prtdir=s"=>\$prtdir, "title=s"=>\$title, "header=s"=>\$header, "footer=s"=>\$footer,
"h"=>\$help, "help"=>\$help, "no-pkgmk-conf"=>\$noconf);
# Use compression-mode defined in pkgmk-conf
our $compress = "gz";
open CONFIG, "/etc/pkgmk.conf" or die "Could not open /etc/pkgmk.conf";
while (<CONFIG>) {
$compress = $1 if m/^PKGMK_COMPRESSION_MODE="(.*)"\n/;
}
close CONFIG;
if ($#ARGV >= 0) { # single packages
pkgrepo_single();
pkgdeps_single();
pkgread();
pkginst();
} else {
if ($prtdir) {
$prtget = "$prtget --no-std-config --config-set=\"prtdir $prtdir\"";
if ($noconf) {
$compress = "{gz,lz,xz,bz2,zst}";
} else { # Use compression-mode defined in pkgmk-conf
$compress = "gz";
open CONFIG, "/etc/pkgmk.conf" or die "Could not open /etc/pkgmk.conf";
while (<CONFIG>) {
$compress = $1 if m/^PKGMK_COMPRESSION_MODE=(.*)(\#|$)/;
}
pkgrepo();
pkgdeps();
pkgread();
pkginst();
close CONFIG;
$compress =~ s/["' ]//g;
}
######################## single packages ########################
$prtget .= " --no-std-config --config-set=\"prtdir $prtdir\"" if ($prtdir);
# generate dependencies
sub pkgdeps_single {
print "+ Generating dependencies\n";
my $hasnew = 0;
foreach my $p (@ARGV) {
my @packages = glob("$p#*.pkg.tar.$compress");
if ($#packages == 0) {
my $found = 0;
my $package = $packages[0];
$package =~ s/#.*//;
my $deps = `$prtget printf "%e" --filter="$package"`;
if ($deps ne "") {
my $isnew = `grep "$p .*:" PKGDEPS`;
if ($isnew eq ""){ # package is new, put deps at the end.
open (my $fh, '>>PKGDEPS');
printf $fh "%-30s : %-s\n", $package, $deps;
close $fh;
$hasnew = 1;
} else {
system("sed -i \"/^$p /s/: .*\$/: $deps/\" PKGDEPS");
}
}
} else {
print "Package '$p' not found or duplicate\n"
}
}
if ($hasnew == 1){system("sort -o PKGDEPS PKGDEPS")};
my @packages; my %isDup;
sub pkg_mtime {
my $aName = $a; my $bName = $b;
my $aTime; my $bTime;
$aName =~ s/#.*//;
$bName =~ s/#.*//;
if ($aName lt $bName) { return -1; }
elsif ($aName gt $bName) { return 1; }
else {
$aTime = (stat $a)[9];
$bTime = (stat $b)[9];
}
if ($aTime le $bTime) { return -1; }
else { return 1; }
}
# generate the main repository file
sub pkgrepo_single {
print "+ Generating repository\n";
my $hasnew = 0;
foreach my $p (@ARGV) {
my @packages = glob("$p#*.pkg.tar.$compress");
if ($#packages == 0) {
my $found = 0;
my $package = $packages[0];
my $name = $package;
$name =~ s/#.*//;
my $du = (-s $package);
my $md5 = `md5sum $package`;
$md5 =~ s/ .*$|\n//g;
my $des=`$prtget printf %d --filter="$name"`;
$des =~ s/:/ /g;
if ($des eq ""){$des = "N.A."};
my $flags=`$prtget printf %E:%O:%R --filter="$name"`;
if ($flags eq "") {$flags = "no:no:no"}
my $isnew = `grep "$p#" PKGREPO`;
if ($isnew eq ""){ # package is new, put it at the end
open (my $fh, '>>PKGREPO');
printf $fh "%-s:%-s:%-s:%-s:%-s\n", $package,$du,$md5,$des,$flags;
close $fh;
$hasnew = 1;
} else {
my $newp = "$package:$du:$md5:$des:$flags";
system("sed -i \"s/^$p#.*\$/$newp/\" PKGREPO");
}
#printf $fh "%-s:%-s:%-s:%-s\n", $du,$md5,$des,$flags;
} else {
print "Package '$p' not found or duplicate\n"
sub print_usage {
print "usage: pkg-repgen [options] [directory [pkgname1..pkgnameN]]\n";
print " toggle option: --no-pkgmk-conf\n";
print " string option: --title=\n";
print " file/path options: --header=, --footer=, --prtdir=\n";
exit(1-$help);
}
($help==0) or print_usage();
my $pkgdir = shift @ARGV; my $quickMode=0;
(! $pkgdir) or (-d $pkgdir) or print_usage();
$pkgdir = "." if (! $pkgdir);
my @dirlist = glob("$pkgdir/*.pkg.tar.$compress");
@dirlist = sort pkg_mtime @dirlist;
%isDup = map { $_ => 0 } @dirlist;
if (@ARGV) { # individual packages
$quickMode=1;
my @updates = sort @ARGV;
while (my $name = shift @updates) {
push @packages, grep { m/$name#.*\.pkg\.tar\./ } @dirlist;
}
} else { # the entire directory
@packages = @dirlist;
}
# hashes to determine the package name ...
our %pname = map { $_ => (split /\//, $_)[-1] } @dirlist;
foreach my $p (@dirlist) { $pname{$p} =~ s/\#.*//; }
# ... or to look up the successor when merging old metadata files
my %followR; my %followH; my %followD; my @queue = @dirlist;
while (my $q = shift @queue) {
($#queue < 0) or ($pname{$q} ne $pname{$queue[0]}) or $isDup{$q} = 1;
}
# Populate some other hashes using a single run of prt-get
our %path; our %depends; our %descrip; our %flags;
my @validkeys = map { (split /\//, $_)[-1] } @dirlist;
map { s/\#.*// } @validkeys;
my %printme = map { $_ => 1 } @validkeys;
open (my $ppf, "$prtget printf '%n^%p^%e^%d^%E:%O:%R\n' |");
while (<$ppf>) {
chomp;
my ($name,$repo,$deps,$desc,$prepostread) = split /\^/;
next if (! $printme{$name});
$path{$name} = $repo . "/" . $name;
$depends{$name} = $deps;
$depends{$name} =~ s/,/ /g;
$descrip{$name} = $desc;
$desc =~ s/:/ /g;
$flags{$name} = $prepostread;
}
close ($ppf);
# Needed for alternating colors in the html index
my %parity = ( 0 => "even", 1 => "odd" );
# Generate the metadata files
($quickMode) ? pkg_single() : pkg_dir();
# Generate README and PKGINST
pkgreadscripts();
###################### individual packages ##########################
sub pkg_single {
my ($oR, $oD, $oH, $nR, $nD, $nH, $oline, $oname);
my $count = 0; # needed for the html index
my @dep_packages = @packages;
my @idx_packages = @packages;
my %firstrun = map { $_ => 0 } ("PKGREPO", "PKGDEPS", "index.html");
open ($oR, "$pkgdir/PKGREPO") or $firstrun{"PKGREPO"} = 1;
open ($oD, "$pkgdir/PKGDEPS") or $firstrun{"PKGDEPS"} = 1;
open ($oH, "$pkgdir/index.html") or $firstrun{"index.html"} = 1;
open ($nR, ">$pkgdir/PKGREPO.new");
print "+ Updating specified entries in repository\n";
RPKG: while (my $p =shift @packages) {
my ($basename, $du, $md5, $ppr) = repodata($p);
my $desc = (! $descrip{$pname{$p}}) ? "N.A." : $descrip{$pname{$p}};
if ($firstrun{"PKGREPO"}==1) {
printf $nR "%-s:%-s:%-s:%-s:%-s\n",$basename, $du, $md5, $desc, $ppr;
next RPKG;
}
# Shift entries from the old repository until we find
# a successor to the current package.
while ( (! $followR{$pname{$p}}) and $oline = <$oR> ) {
chomp($oline); $oname = $oline;
$oname =~ s/\#.*//;
print $nR "$oline\n" if ($oname lt $pname{$p});
# before breaking out of the loop, append all the packages
# from the globbed queue that are lexographically earlier
# than the current entry in the old repository.
while ($pname{$p} le $oname) {
printf $nR "%-s:%-s:%-s:%-s:%-s\n", $basename, $du, $md5, $desc, $ppr;
next RPKG if (! $isDup{$p});
$p = shift @packages;
($basename, $du, $md5, $ppr) = repodata($p);
$desc = (! $descrip{$pname{$p}}) ? "N.A." : $descrip{$pname{$p}};
# save what got shifted from the repository if we're not going to
# print it now, but don't save packages that match the same glob.
$followR{$pname{$p}} = "$oline\n" if ($pname{$p} lt $oname);
}
}
# if the current package comes after everything in the old repository,
# just append its metadata
($followR{$pname{$p}}) or printf $nR "%-s:%-s:%-s:%-s:%-s\n", $basename, $du, $md5, $desc, $ppr;
next RPKG if (($isDup{$p}) or (! $followR{$pname{$p}}));
# Arriving here means the current package is not a dup, and
# definitely has a successor in the old repository. But the
# next globbed package might be a more immediate successor.
# Decide which of the two possible successors comes first.
# By defining a successor for the next package in the queue,
# we delay shifting entries off the old repo.
if ((@packages) and ($pname{$packages[0]} le $followR{$pname{$p}})) {
$followR{$pname{$packages[0]}} = $followR{$pname{$p}};
next RPKG;
} else {
print $nR $followR{$pname{$p}};
}
# Shift another package from the queue
}
# Likewise for the html index
printheader(1);
open ($nH, ">>$pkgdir/index.html.new");
print "+ Updating specified entries in the html index\n";
HPKG: while (my $p =shift @idx_packages) {
my ($pver, $desc, $date) = htmldata($p);
my $url = $p;
$url =~ s/#/%23/;
if ($firstrun{"index.html"} == 1) {
$count++;
htmlrow($nH,$count,$pname{$p},$url,$pver,$desc,$date);
next HPKG;
}
# Shift entries from the old html index until we find
# a successor to the current package.
while ( (! $followH{$pname{$p}}) and $oline=<$oH> ) {
chomp($oline);
# no need to copy the header, it should already be there
next if ($oline !~ m/^<tr class="(odd|even)"/);
$oname = $oline;
$oname =~ s/.*a href="(.*)"/$1/; $oname =~ s/\%23.*//;
if ($oname lt $pname{$p}) { $count++; print $nH "$oline\n"; }
# before breaking out of the loop, append all the packages
# from the globbed queue that are lexographically earlier
# than the current entry in the old html index.
while ($pname{$p} le $oname) {
$count++;
htmlrow($nH,$count,$pname{$p},$url,$pver,$desc,$date);
next HPKG if (! $isDup{$p});
$p = shift @idx_packages;
($pver, $desc, $date) = htmldata($p);
$url = $p;
$url =~ s/#/%23/;
# save what got shifted from the index if we're not going to print
# it now, but ignore packages that match the same glob.
$followH{$pname{$p}} = "$oline\n" if ($pname{$p} lt $oname);
}
}
if ($hasnew == 1){system("sort -o PKGREPO PKGREPO")};
}
# if the current package comes after everything in the old html index,
# just append its metadata
if (! $followH{$pname{$p}}) {
$count++;
htmlrow($nH,$count,$pname{$p},$url,$pver,$desc,$date);
}
next HPKG if (($isDup{$p}) or (! $followH{$pname{$p}}));
# Arriving here means the current package is not a dup, and
# definitely has a successor in the old html index. But the
# next globbed package might be a more immediate successor.
# Decide which of the two possible successors comes first. If the
# globbed package is the more immediate successor, use its name
# as a key to retain the most recent entry from the html index.
if ((@packages) and ($pname{$packages[0]} le $followH{$pname{$p}})) {
$followH{$pname{$packages[0]}} = $followH{$pname{$p}};
next HPKG;
} else {
$count++;
$followH{$pname{$p}} =~ s/class="(even|odd)"/class="$parity{($count %2)}"/;
print $nH $followH{$pname{$p}};
}
# Shift another package from the queue
}
# Likewise for the dependency map, but avoid creating duplicate entries
open ($nD, ">$pkgdir/PKGDEPS.new");
print "+ Updating specified entries in the depmap\n";
DPKG: while (my $p =shift @dep_packages) {
if ($firstrun{"PKGDEPS"}==1) {
(! $depends{$pname{$p}}) or ($isDup{$p})
or printf $nD "%-30s : %-s\n", $pname{$p}, $depends{$pname{$p}};
next DPKG;
}
# Shift entries from the old depmap until we find a successor
# to the current package
while ( (! $followD{$pname{$p}}) and $oline = <$oD> ) {
chomp($oline); $oname = $oline;
$oname =~ s/\s*\:.*//;
print $nD "$oline\n" if ($oname lt $pname{$p});
while ($pname{$p} le $oname) {
if (! $isDup{$p}) {
printf $nD "%-30s : %-s\n", $pname{$p}, $depends{$pname{$p}};
next DPKG;
} else {
$p = shift @dep_packages;
}
# save what got shifted from the depmap if we're not going to print
# it now, but ignore packages that match the same glob.
$followD{$pname{$p}} = $oline if ($pname{$p} lt $oname);
}
}
# if the current package comes after everything in the old depmap
# and is not a dup, just append its metadata
($followD{$pname{$p}}) or ($isDup{$p}) or (! $depends{$pname{$p}})
or printf $nD "%-30s : %-s\n", $pname{$p}, $depends{$pname{$p}};
next DPKG if (($isDup{$p}) or (! $followD{$pname{$p}}));
# Arriving here means the current package is not a dup, and
# definitely has a successor entry in the old depmap.
# But the next globbed package might be a more immediate successor.
# Decide which of the two possible successors comes first. If it's the
# globbed package that comes next, save the old depmap entry.
if ((@packages) and ($pname{$packages[0]} le $followD{$pname{$p}})) {
$followD{$pname{$packages[0]}} = $followD{$pname{$p}};
next DPKG;
} else {
printf $nD $followD{$pname{$p}};
}
# Shift another package from the queue
}
# Done with all the packages that match command-line arguments.
# Now append the tails of the old metadata files to their new counterparts.
# Remember to update the count, in case new packages were inserted.
while ($firstrun{"index.html"}==0 and $oline = <$oH>) {
if ($oline =~ m/class="(even|odd)"/) {
$count++;
$oline =~ s/class="(even|odd)"/class="$parity{($count % 2)}"/;
print $nH $oline;
}
}
while ($firstrun{"PKGDEPS"}==0 and $oline = <$oD>) { print $nD $oline; }
while ($firstrun{"PKGREPO"}==0 and $oline = <$oR>) { print $nR $oline; }
close($nH);
close($nD);
close($nR);
($firstrun{"PKGREPO"}==1) or close($oR);
($firstrun{"PKGDEPS"}==1) or close($oD);
($firstrun{"index.html"}==1) or close($oH);
foreach my $db (keys %firstrun) { rename("$pkgdir/$db.new", "$pkgdir/$db"); }
printfooter($count);
}
######################## full repository ########################
# generate dependencies
sub pkgdeps {
sub pkg_dir {
print "+ Generating dependencies\n";
my @packages = glob("*#*.pkg.tar.$compress");
open (my $fh, '>PKGDEPS');
foreach my $package (@packages) {
$package =~ s/#.*//;
my $deps = `$prtget printf "%e" --filter="$package"`;
if ($deps ne "") {
printf $fh "%-30s : %-s\n", $package, $deps;
}
}
close $fh;
}
# generate the main repository file and index page
sub pkgrepo {
open (my $iD, ">$pkgdir/PKGDEPS");
print "+ Generating repository\n";
my @packages = glob("*#*.pkg.tar.$compress");
our $odd = "odd";
my $count = 0;
open (my $fh, '>PKGREPO');
printheader();
open (my $ih, '>>index.html');
foreach my $package (@packages) {
my $date = (stat($package))[9];
$count++;
$package =~ s/\n//g;
my $name = $package;
$name =~ s/#.*//;
my $du = (-s $package);
my $md5 = `md5sum $package`;
$md5 =~ s/ .*$|\n//g;
my $des=`$prtget printf %d --filter="$name"`;
$des =~ s/:/ /g;
if ($des eq ""){$des = "N.A."};
my $flags=`$prtget printf %E:%O:%R --filter="$name"`;
if ($flags eq "") {$flags = "no:no:no"}
printf $fh "%-s:%-s:%-s:%-s:%-s\n", $package,$du,$md5,$des,$flags;
my $version = $package;
$version =~ s/^.*\#//;
$version =~ s/\.pkg\.tar\.[gbx]z*//;
print $ih "<tr class=\"$odd\">";
print $ih "<td>$name</td>";
my $url = $package;
$url =~ s/\#/\%23/;
print $ih "<td><a href=\"$url\">$version</a></td>";
print $ih "<td>$des</td>";
print $ih "<td>" . isotime($date, 1) . "</td>";
print $ih "</tr>\n";
if ($odd eq "odd") { $odd = "even"; }
else { $odd = "odd"; }
open (my $iR, ">$pkgdir/PKGREPO");
printheader(0);
my $count = 0;
open (my $ih, ">>$pkgdir/index.html");
foreach my $p (@packages) {
my ($basename, $du, $md5, $ppr) = repodata($p);
my ($pver, $desc, $date) = htmldata($p);
my $url = $basename;
$url =~ s/#/%23/;
(! $depends{$pname{$p}}) or ($isDup{$p})
or printf $iD "%-30s : %-s\n", $pname{$p}, $depends{$pname{$p}};
printf $iR "%-s:%-s:%-s:%-s:%-s\n", $basename,$du,$md5,$desc,$ppr;
$count++;
htmlrow($ih,$count,$pname{$p},$url,$pver,$desc,$date);
}
close $fh;
close $ih;
printfooter($count);
close($ih);
printfooter($count);
close($iR);
close($iD);
}
# generate README file
sub pkgread {
# consolidate all the README and install scripts for the available packages
sub pkgreadscripts {
print "+ Generating README\n";
my @packages = glob("*#*.pkg.tar.$compress");
open (my $fh, '>PKGREAD');
print $fh "# README files for repository. Do NOT remove this line.\n";
foreach my $package (@packages) {
$package =~ s/#.*//;
my $path = `$prtget path $package`;
$path =~ s/\n//g;
if (-f "$path/README"){
print $fh "##### PKGREADME: $package\n";
open(my $readme, "$path/README");
while (<$readme>){
my $line = $_;
print $fh $line;
}
open (my $fR, ">$pkgdir/PKGREAD");
print $fR "# README files for repository. Do NOT remove this line.\n";
print "+ Generating scripts\n";
open (my $fS, ">$pkgdir/PKGINST");
print $fS '#!/usr/bin/env bash
#
# PKGINST: pre- and post-install scripts for CRUX packages
#
run_script() {
case "$1" in
';
my %seen;
foreach my $name (@dirlist) {
$name =~ s/\#.*//; $name = (split /\//, $name)[-1];
next if ($seen{$name});
$seen{$name} = 1;
next if (! $path{$name});
if (-f "$path{$name}/README"){
print $fR "##### PKGREADME: $name\n";
open(my $readme, "$path{$name}/README");
while (<$readme>){ print $fR $_; }
close($readme);
}
}
close $fh;
}
# generate pre-post install scripts file
sub pkginst {
print "+ Generating scripts\n";
open (my $fh, '>PKGINST');
print $fh
"
#!/bin/bash
#
# PKGINST: pre-post install scripts for CRUX packages
";
my @packages = glob("*#*.pkg.tar.$compress");
foreach my $package (@packages) {
$package =~ s/#.*//;
my $path = `$prtget path $package`;
$path =~ s/\n//g;
my $normal= $package;
$normal =~ s/[^[:alnum:]]/_/g;
if (-f "$path/pre-install"){
print $fh "${normal}_pre_install() {\n";
open(my $pre, "$path/pre-install");
while (<$pre>){
my $line = $_;
print $fh $line;
foreach my $when ("pre", "post") {
if (-f "$path{$name}/${when}-install"){
print $fS " $name.$when)\n";
open(my $rs, "$path{$name}/${when}-install");
while (<$rs>){
chomp;
(m/^\#(!.*sh|\s*EOF|\s*End)/) or print $fS " $_\n";
}
close($rs);
print $fS " ;;\n";
}
close($pre);
print $fh "}\n\n";
}
if (-f "$path/post-install"){
print $fh "${normal}_post_install() {\n";
open(my $post, "$path/post-install");
while (<$post>){
my $line = $_;
print $fh $line;
}
close($post);
print $fh "}\n\n";
}
}
print $fh "\n\n";
print $fh 'if [ ! -z "$1" ]; then $1; fi';
print $fh "\n";
close $fh;
print $fS " esac\n}\n\n";
print $fS '[ "$1" ] && [[ "$2" == @(pre|post) ]] && run_script "$1.$2"';
print $fS "\n";
close $fS;
close $fR;
}
######################## html index subs ########################
sub printheader {
open (my $ih, '>index.html');
print $ih <<EOH;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
EOH
my $isTemp = shift; my $ih; my $fS;
my $stylePage = "/usr/share/pkg-get/style.html";
($isTemp == 0) ? open ($ih, ">$pkgdir/index.html") : open ($ih, ">$pkgdir/index.html.new");
open ($fS, $stylePage) or die "cannot find html template. Please install $stylePage and try again.";
while (my $sline = <$fS>) {
if ($sline =~ m/<(title|h[1-3])>/) {
$sline =~ s/(title|h[1-3])>[^<]*</$1>$title</;
}
print $ih $sline;
}
print $ih " <title>$title</title>\n";
if ($header) {
open(FILE, $header) or die "Couldn't open header file";
while (<FILE>) { print $ih " " . $_; }
close(FILE);
}
print $ih <<EOH;
<style type="text/css">
body
{
font-family: Verdana, sans-serif;
font-size: 85%;
padding: 2em;
}
a
{
color: #67550d;
}
table
{
border: solid #e5dccf 1px;
font-size: 85%;
}
td
{
padding: 6px;
}
tr.header
{
background-color: #e5dccf;
}
tr.odd
{
background-color: #f7f3ed;
}
tr.even
{
background-color: #fcf9f8;
}
</style>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
</head>
<body>
EOH
print $ih " <table width=\"100%\" cellspacing=\"0\">\n";
print $ih " <tr class=\"header\"><td><b>Port</b></td><td><b>Version</b></td><td><b>Description</b></td>";
print $ih "<td><b>Last modified</b></td>";
print $ih "</tr>\n";
close($ih);
}
print $ih " <h2>$title</h2>\n";
if ($header) {
open(FILE, $header) or die "Couldn't open header file";
while (<FILE>) {
print $ih " " . $_;
}
close(FILE);
}
print $ih " <table width=\"100%\" cellspacing=\"0\">\n";
print $ih " <tr class=\"header\"><td><b>Port</b></td><td><b>Version</b></td><td><b>Description</b></td>";
print $ih "<td><b>Last modified</b></td>";
print $ih "</tr>\n";
close($ih);
sub htmlrow {
my ($ih, $count, $name, $url, $version, $desc, $date) = @_;
print $ih "<tr class=\"$parity{($count % 2)}\"><td>$name</td>";
print $ih "<td><a href=\"$url\">$version</a></td>";
print $ih "<td>$desc</td><td>$date</td></tr>\n";
}
sub printfooter {
my $count = $_[0];
open (my $ih, '>>index.html');
print $ih " </table>\n";
print $ih " <p><b>$count packages</b></p>\n";
if ($footer) {
open(FILE, $footer) or die "Couldn't open footer file";
while (<FILE>) {
print $ih " " . $_;
}
close(FILE);
}
print $ih " <p><i>Generated by <a href=\"http://www.varlock.com\">pkg-repgen</a> on " . isotime() . ".</i></p>\n";
print $ih <<EOH;
my $count = shift;
open (my $ih, ">>$pkgdir/index.html");
print $ih " </table>\n";
print $ih " <p><b>$count packages</b></p>\n";
if ($footer) {
open(FILE, $footer) or die "Couldn't open footer file";
while (<FILE>) { print $ih " " . $_; }
close(FILE);
}
print $ih " <p><em>Generated by <a href=\"http://www.varlock.com\">pkg-repgen</a> on " . isotime() . ".</em></p>\n";
print $ih <<EOH;
</body>
</html>
EOH
close($ih);
close($ih);
}
sub htmldata {
my $p = shift;
my $pver = $1 if ($p =~ m/.*\#(.*)\.pkg\.tar\.*/);
my $date = isotime( (stat($p))[9] );
my $desc = (! $descrip{$pname{$p}}) ? "N.A." : $descrip{$pname{$p}};
return $pver, $desc, $date;
}
sub repodata {
my $p = shift;
my $basename = (split /\//, $p)[-1];
my $du = (-s $p);
my $md5 = digest_file_hex($p,"MD5");
my $ppr = (! $flags{$pname{$p}}) ? "no:no:no" : $flags{$pname{$p}};
return $basename, $du, $md5, $ppr;
}
sub isotime {
my $time = (shift or time);
my $accuracy = (shift or 2);
my @t = gmtime ($time);
my $year = $t[5] + 1900;
my $month = sprintf("%02d", $t[4] + 1);
my $day = sprintf("%02d", $t[3]);
my $time = (shift or time);
my @t = gmtime ($time);
my $year = $t[5] + 1900;
my $month = sprintf("%02d", $t[4] + 1);
my $day = sprintf("%02d", $t[3]);
if ($accuracy == 1) {
return "$year-$month-$day";
}
return "$year-$month-$day " . sprintf("%02d:%02d:%02d UTC", $t[2], $t[1], $t[0]);
return "$year-$month-$day";
}