1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/openpkg/dev.pod Tue Jul 31 12:23:42 2012 +0200 1.3 @@ -0,0 +1,543 @@ 1.4 +## 1.5 +## openpkg dev -- OpenPKG Package Development Tool 1.6 +## Copyright (c) 2008-2012 OpenPKG GmbH <http://openpkg.com/> 1.7 +## 1.8 +## This software is property of the OpenPKG GmbH, DE MUC HRB 160208. 1.9 +## All rights reserved. Licenses which grant limited permission to use, 1.10 +## copy, modify and distribute this software are available from the 1.11 +## OpenPKG GmbH. 1.12 +## 1.13 +## THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 1.14 +## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1.15 +## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1.16 +## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR 1.17 +## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.18 +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.19 +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 1.20 +## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 1.21 +## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 1.22 +## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 1.23 +## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1.24 +## SUCH DAMAGE. 1.25 +## 1.26 + 1.27 +=pod 1.28 + 1.29 +B<openpkg dev> - OpenPKG Package Development Tool 1.30 + 1.31 +=head1 DESCRIPTION 1.32 + 1.33 +B<openpkg dev> is a package development tool for B<OpenPKG>. 1.34 + 1.35 +=head2 SOURCE PACKAGE HANDLING 1.36 + 1.37 +=over 4 1.38 + 1.39 +=item B<openpkg dev unpack> 1.40 +[C<-l> I<layout>] 1.41 +[C<-b> I<basedir>] 1.42 +[C<-s>] 1.43 +[C<-d>] 1.44 +I<name>C<->I<version>C<->I<release>C<.src.rpm> 1.45 + 1.46 +Unpacks an OpenPKG source RPM package 1.47 +I<name>C<->I<version>C<->I<release>C<.src.rpm> into I<basedir> 1.48 +(default is I<name>C<->I<version>C<->I<release>) 1.49 +using I<layout> (default is I<structured>). 1.50 +Additionally, 1.51 +I<file-rpmmacros> 1.52 +configuration file is generated where 1.53 +C<-s> enables shared mode and 1.54 +C<-d> enables debug mode, see I<file-rpmmacros>. 1.55 + 1.56 +=back 1.57 + 1.58 +=head2 SOURCE PACKAGE DEVELOPMENT 1.59 + 1.60 +=over 4 1.61 + 1.62 +=item B<openpkg dev shell> 1.63 + 1.64 +This is a convenience command which enters an interactive B<GNU Bash> 1.65 +shell which provides the following work environment: 1.66 + 1.67 +=over 4 1.68 + 1.69 +=item B<Environment Variables:> 1.70 + 1.71 + OPENPKG_PREFIX "<prefix>" 1.72 + PS1 "\\[\\e[31;1m\\]\\u\\[\\e[0m\\]@\\h:\\w [OPENPKG_PREFIX=$OPENPKG_PREFIX]\n\\\$ " 1.73 + T %{_tmppath} 1.74 + S %{_specdir} 1.75 + D %{_sourcedir} 1.76 + 1.77 +=item B<Command-Line Aliases:> 1.78 + 1.79 + openpkg "${OPENPKG_PREFIX}/bin/openpkg" 1.80 + opd "${OPENPKG_PREFIX}/bin/openpkg dev" 1.81 + 1.82 +=item B<Command-Line Keystrokes:> 1.83 + 1.84 + ESC+x "opd unpack\n" 1.85 + ESC+v "opd edit\n" 1.86 + ESC+t "opd build -s track\n" 1.87 + ESC+f "opd build -s fetch\n" 1.88 + ESC+b "opd build\n" 1.89 + ESC+1 "opd build -s prep\n" 1.90 + ESC+2 "opd build -s compile\n" 1.91 + ESC+3 "opd build -s install\n" 1.92 + ESC+4 "opd build -s binary\n" 1.93 + ESC+s "opd build -s source\n" 1.94 + ESC+p "opd peek\n" 1.95 + ESC+d "opd diff\n" 1.96 + ESC+i "opd install\n" 1.97 + ESC+e "opd erase\n" 1.98 + ESC+l "opd lint\n" 1.99 + ESC+r "opd release\n" 1.100 + 1.101 +=back 1.102 + 1.103 +If option C<-s> is passed to B<openpkg dev shell> and screen(1) is 1.104 +available in C<$PATH>, the interactive development shell is started up 1.105 +in a convenient virtual screen environment. 1.106 + 1.107 +=item B<openpkg dev edit> 1.108 + 1.109 +Load spec file into editor. 1.110 + 1.111 +=over 4 1.112 + 1.113 +=item B<Environment Variables:> 1.114 + 1.115 + EDITOR "vi" 1.116 + 1.117 +=back 1.118 + 1.119 +=item B<openpkg dev build> 1.120 +[C<-s> I<step>] 1.121 +[C<-D> I<define>[=I<value>]] 1.122 +[C<-w> I<variant>] 1.123 + 1.124 +Builds package steps. Default I<step> is C<all>. Option C<-D> translated 1.125 +into "C<--define 'I<define> I<value>'>" while option C<-w> translated 1.126 +into "C<--with> I<variant>". The I<step> arguments translate into the 1.127 +following RPM options: 1.128 + 1.129 + track: -bt 1.130 + fetch: -bf 1.131 + prep: -bp 1.132 + compile: -bc --short-circuit 1.133 + install: -bi --short-circuit 1.134 + binary: -bb --short-circuit 1.135 + source: -bs 1.136 + all: -ba 1.137 + 1.138 +=item B<openpkg dev peek> 1.139 + 1.140 +Peeks file list from package and tags configuration and documentation files. 1.141 + 1.142 +=item B<openpkg dev diff> 1.143 + 1.144 +Shows modifications with the help of a possibly underlying Version 1.145 +Control System (VCS) like CVS, Subversion, Monotone, Git, Mercurial or 1.146 +(as a fallback ) OSSP svs. 1.147 + 1.148 +=item B<openpkg dev install> 1.149 +[C<-f>] 1.150 +[C<-o>] 1.151 +[C<-n>] 1.152 +[C<-s>] 1.153 + 1.154 +Installs package. 1.155 +Option 1.156 +C<-f> adds C<--force>, 1.157 +C<-n> adds C<--nodeps> and 1.158 +C<-o> adds C<--oldpackage> 1.159 +to the underlying C<rpm> call. 1.160 +Option C<-s> prefixes the command with sudo(1). 1.161 + 1.162 +=item B<openpkg dev erase> 1.163 +[C<-f>] 1.164 +[C<-o>] 1.165 +[C<-a>] 1.166 +[C<-s>] 1.167 + 1.168 +Erases package. 1.169 +Option 1.170 +C<-f> adds C<--force>, 1.171 +C<-n> adds C<--nodeps> and 1.172 +C<-a> adds C<--allmatches> 1.173 +to the underlying C<rpm> call. 1.174 +Option C<-s> prefixes the command with sudo(1). 1.175 + 1.176 +=item B<openpkg dev lint> 1.177 +[C<-v>] 1.178 +[C<-b>] 1.179 + 1.180 +Lints package sources C<*.spec>, C<fsl.*>, C<rc.*> and binary package files. 1.181 +Option C<-v> enables verboseness. 1.182 +Option C<-b> disables the linting of an existing binary package file. 1.183 + 1.184 +=item B<openpkg dev release> 1.185 +[C<-m> I<message>] 1.186 +[C<-n>] 1.187 + 1.188 +Releases package specification to the repository. Unlike previous 1.189 +incarnations of "openpkg dev" this one is not tied to any repository or 1.190 +structure. The default message is created using the difference between 1.191 +the previous and current version of the package specification. In order 1.192 +to grab the previous version, the working directory and three levels 1.193 +towards root are checked for signs of CVS, Subversion, Monotone, Git, 1.194 +Mercurial or SVS information, in that order. The appropriate command is 1.195 +then executed to retrieve the data and the VCS found is passed to the 1.196 +actual release command. 1.197 + 1.198 +Finally, the command specified by the environment variable 1.199 +C<OPENPKG_DEV_RELEASE> or, if omitted, specified by the rpm macro 1.200 +C<%{openpkg_dev_release}> is run and passed the following positional 1.201 +arguments: 1.202 + 1.203 +=over 4 1.204 + 1.205 + openpkg-prefix 1.206 + spec-dir 1.207 + source-dir 1.208 + binary-rpm-file 1.209 + source-rpm-file 1.210 + package-name 1.211 + package-version 1.212 + package-release 1.213 + package-version-old 1.214 + package-release-old 1.215 + commit-message 1.216 + vcs 1.217 + 1.218 +=back 1.219 + 1.220 +For a dry run, set C<$OPENPKG_DEV_RELEASE> to "echo" or use option "C<-n>". 1.221 + 1.222 +=back 1.223 + 1.224 +=head1 UNPACKED SOURCE RPM PACKAGE FILESYSTEM LAYOUT 1.225 + 1.226 +When an OpenPKG source RPM package 1.227 +I<name>C<->I<version>C<->I<release>C<.src.rpm> is unpacked to the 1.228 +filesystem, the following distinct filesystem layouts are known: 1.229 + 1.230 +=over 4 1.231 + 1.232 +=item B<global> 1.233 + 1.234 +=over 4 1.235 + 1.236 +=item I<prefix>C</RPM/SRC/>I<name>C</.openpkg/rpmmacros> 1.237 + 1.238 +=item I<prefix>C</RPM/SRC/>I<name>C</>I<name>C<.spec> 1.239 + 1.240 +=item I<prefix>C</RPM/SRC/>I<name>C</>I<packaging-source-file> 1.241 + 1.242 +=item I<prefix>C</RPM/SRC/>I<name>C</>I<thirdparty-distribution-file> 1.243 + 1.244 +=item I<prefix>C</RPM/PKG/>I<binary-rpm-package-file> 1.245 + 1.246 +=item I<prefix>C</RPM/PKG/>I<source-rpm-package-file> 1.247 + 1.248 +=item I<prefix>C</RPM/TMP/>I<temporary-file> 1.249 + 1.250 +=back 1.251 + 1.252 +This is just the "simple" filesystem layout (see below) with the 1.253 +I<base-dir> set to I<prefix>C</RPM/SRC/>. 1.254 + 1.255 +This is the filesystem layout used by default for building OpenPKG 1.256 +packages during C<openpkg build> or the underlying C<openpkg rpm 1.257 +--rebuild> commands. 1.258 + 1.259 +=item B<local> 1.260 + 1.261 +=over 4 1.262 + 1.263 +=item I<base-dir>C</.openpkg/rpmmacros> 1.264 + 1.265 +=item I<base-dir>C</>I<name>C<.spec> 1.266 + 1.267 +=item I<base-dir>C</>I<packaging-source-file> 1.268 + 1.269 +=item I<base-dir>C</>I<thirdparty-distribution-file> 1.270 + 1.271 +=item I<base-dir>C</>I<binary-rpm-package-file> 1.272 + 1.273 +=item I<base-dir>C</>I<source-rpm-package-file> 1.274 + 1.275 +=item I<base-dir>C</>I<temporary-file> 1.276 + 1.277 +=back 1.278 + 1.279 +This puts everything into one directory. 1.280 + 1.281 +=item B<simple> 1.282 + 1.283 +=over 4 1.284 + 1.285 +=item I<base-dir>C</>I<name>C</.openpkg/rpmmacros> 1.286 + 1.287 +=item I<base-dir>C</>I<name>C</>I<name>C<.spec> 1.288 + 1.289 +=item I<base-dir>C</>I<name>C</>I<packaging-source-file> 1.290 + 1.291 +=item I<base-dir>C</>I<name>C</>I<thirdparty-distribution-file> 1.292 + 1.293 +=item I<base-dir>C</>I<binary-rpm-package-file> 1.294 + 1.295 +=item I<base-dir>C</>I<source-rpm-package-file> 1.296 + 1.297 +=item I<$TMPDIR>C</openpkg/>I<temporary-file> 1.298 + 1.299 +=back 1.300 + 1.301 +This is the simple filesystem layout of an unpacked 1.302 +OpenPKG package. All files are simply put into a sub-directory with the 1.303 +I<name> of the package. 1.304 + 1.305 +This is the filesystem layout used for the quick patching of a single 1.306 +OpenPKG package in a stand-alone environment. 1.307 + 1.308 +=item B<structured> 1.309 + 1.310 +=over 4 1.311 + 1.312 +=item I<base-dir>C</>I<name>C</.openpkg/rpmmacros> 1.313 + 1.314 +=item I<base-dir>C</>I<name>C</src/>I<name>C<.spec> 1.315 + 1.316 +=item I<base-dir>C</>I<name>C</src/>I<packaging-source-file> 1.317 + 1.318 +=item I<base-dir>C</>I<name>C</dst/>I<thirdparty-distribution-file> 1.319 + 1.320 +=item I<base-dir>C</>I<name>C</pkg/>[C<bin/>]I<binary-rpm-package-file> 1.321 + 1.322 +=item I<base-dir>C</>I<name>C</pkg/>[C<src/>]I<source-rpm-package-file> 1.323 + 1.324 +=item I<base-dir>C</>I<name>C</tmp/>I<temporary-file> 1.325 + 1.326 +=back 1.327 + 1.328 +This is the structured (and default) filesystem layout of an unpacked 1.329 +OpenPKG package. A top-level sub-directory with the I<name> of the 1.330 +package is created. There the package specification and all packaging 1.331 +source files are put into the sub-directory I<src> and all the 1.332 +third-party distribution files are put into the sub-directory I<dst>. 1.333 + 1.334 +This is the filesystem layout used for the development of a single 1.335 +OpenPKG package in a stand-alone environment. 1.336 + 1.337 +=item B<distributed> 1.338 + 1.339 +=over 4 1.340 + 1.341 +=item I<base-dir>C</>C<.openpkg/rpmmacros> 1.342 + 1.343 +=item I<base-dir>C</>C<src/>I<name>C</>I<name>C<.spec> 1.344 + 1.345 +=item I<base-dir>C</>C<src/>I<name>C</>I<packaging-source-file> 1.346 + 1.347 +=item I<base-dir>C</>C<dst/>I<name>C</>I<thirdparty-distribution-file> 1.348 + 1.349 +=item I<base-dir>C</>C<pkg/>[C<bin/>]I<binary-rpm-package-file> 1.350 + 1.351 +=item I<base-dir>C</>C<pkg/>[C<src/>]I<source-rpm-package-file> 1.352 + 1.353 +=item I<base-dir>C</>C<tmp/>I<temporary-file> 1.354 + 1.355 +=back 1.356 + 1.357 +This is the distributed filesystem layout of an unpacked OpenPKG 1.358 +package. It is similar to the structured filesystem layout but the 1.359 +C<src> and C<dst> directories and the I<name> directory are swapped, 1.360 +mainly with the intention of bundling together all third-party 1.361 +distribution files of a large number of packages. 1.362 + 1.363 +This is the filesystem layout used for regular OpenPKG package 1.364 +development. 1.365 + 1.366 +=back 1.367 + 1.368 + 1.369 +=head1 LOCAL RPM MACROS FILE (.openpkg/rpmmacros) 1.370 + 1.371 +OpenPKG supports local RPM macros files F<.openpkg/rpmmacros> which 1.372 +can be used to configure RPM in a local scope. This is especially 1.373 +interesting to configure a local (even per-package) build environment 1.374 +with the help of the C<%openpkg_layout> macro. 1.375 + 1.376 +C<%openpkg_layout> 1.377 +[C<macrosfile=>I<filename>] 1.378 +[C<basedir=>I<directory>] 1.379 +[C<specdir=>I<directory>] 1.380 +[C<sourcedir=>I<directory>] 1.381 +[C<builddir=>I<directory>] 1.382 +[C<tmpdir=>I<directory>] 1.383 +[C<binrpmdir=>I<directory>] 1.384 +[C<srcrpmdir=>I<directory>] 1.385 +[C<shared=>I<yes-or-no>] 1.386 +[C<debug=>I<yes-or-no>] 1.387 + 1.388 +=over 4 1.389 + 1.390 +=item C<macrosfile=>I<filename> 1.391 + 1.392 +Absolute file path of the C<.openpkg/rpmmacros> file where this 1.393 +C<%openpkg_layout> macro is defined. Usually, the intended usage is to 1.394 +leverage from OpenPKG RPM's special C<%{macrosfile}> macro by simply 1.395 +using C<macrosfile=%{macrosfile}>. This parameter is important as 1.396 +the default C<basename> is derived from it. 1.397 + 1.398 +=item C<basedir=>I<directory> 1.399 + 1.400 +Absolute directory path where the C<.openpkg/rpmmacros> file is 1.401 +located under. Usually, the intended usage is to not explicitly 1.402 +set this parameter but let it be determined indirectly via 1.403 +C<macrosfile>. The effective default value is equal to a value like 1.404 +C<%{realpath:%{dirname:%{realpath:%{macrosfile}}}/..}> This parameter is 1.405 +important as all standard filesystem layouts (see parameter C<layout>) 1.406 +are always at least partially based on this base directory in order 1.407 +to provide absolute-path-independent flexible filesystem layouts. 1.408 + 1.409 +=item C<layout=>I<layout> 1.410 + 1.411 +The name of the filesystem layout type to use. The following standard 1.412 +filesystem layout types are pre-defined: C<global>, C<local>, C<simple>, 1.413 +C<structured> (default) and C<distributed>. 1.414 + 1.415 + global macrosdir <openpkg_prefix>/etc/openpkg 1.416 + global macrosfile <openpkg_prefix>/etc/openpkg/rpmmacros 1.417 + global specdir <openpkg_prefix>/RPM/SRC/$name 1.418 + global sourcedir <openpkg_prefix>/RPM/SRC/$name 1.419 + global builddir <openpkg_prefix>/RPM/TMP 1.420 + global tmpdir <openpkg_prefix>/RPM/TMP 1.421 + global binrpmdir <openpkg_prefix>/RPM/PKG 1.422 + global srcrpmdir <openpkg_prefix>/RPM/PKG 1.423 + 1.424 + local macrosdir <basedir>/.openpkg 1.425 + local macrosfile <basedir>/.openpkg/rpmmacros 1.426 + local specdir <basedir> 1.427 + local sourcedir <basedir> 1.428 + local builddir <basedir> 1.429 + local tmpdir <basedir> 1.430 + local binrpmdir <basedir> 1.431 + local srcrpmdir <basedir> 1.432 + 1.433 + simple macrosdir <basedir>/.openpkg 1.434 + simple macrosfile <basedir>/.openpkg/rpmmacros 1.435 + simple specdir <basedir> 1.436 + simple sourcedir <basedir> 1.437 + simple builddir <tmpdir> 1.438 + simple tmpdir <tmpdir> 1.439 + simple binrpmdir <basedir>/.. 1.440 + simple srcrpmdir <basedir>/.. 1.441 + 1.442 + structured macrosdir <basedir>/.openpkg 1.443 + structured macrosfile <basedir>/.openpkg/rpmmacros 1.444 + structured specdir <basedir>/src 1.445 + structured sourcedir <basedir>/dst 1.446 + structured builddir <basedir>/tmp 1.447 + structured tmpdir <basedir>/tmp 1.448 + structured binrpmdir <basedir>/pkg/bin 1.449 + structured srcrpmdir <basedir>/pkg/src 1.450 + 1.451 + distributed macrosdir <basedir>/.openpkg 1.452 + distributed macrosfile <basedir>/.openpkg/rpmmacros 1.453 + distributed specdir <basedir>/src/<name> 1.454 + distributed sourcedir <basedir>/dst/<name> 1.455 + distributed builddir <basedir>/tmp 1.456 + distributed tmpdir <basedir>/tmp 1.457 + distributed binrpmdir <basedir>/pkg/bin 1.458 + distributed srcrpmdir <basedir>/pkg/src 1.459 + 1.460 + 1.461 +=item C<specdir=>I<directory-list> 1.462 + 1.463 +=item C<sourcedir=>I<directory-list> 1.464 + 1.465 +=item C<builddir=>I<directory-list> 1.466 + 1.467 +=item C<tmpdir=>I<directory-list> 1.468 + 1.469 +=item C<binrpmdir=>I<directory-list> 1.470 + 1.471 +=item C<srcrpmdir=>I<directory-list> 1.472 + 1.473 +These parameters correspond to the six individual directories provided 1.474 +by a standard layout and allow you to selectively adjust parts of a 1.475 +standard layout to local needs and without having to define a full 1.476 +standard layout yourself. 1.477 + 1.478 +The I<directory-list> is a whitespace-separated list of 1.479 +I<directory>[C<:>[C<+>]I<directory>] specifications which are 1.480 +"first-match" searched for existence. The last directory in the list 1.481 +is always taken as the fallback and if it is not existing it is 1.482 +even created on-the-fly. The I<directory-check>C<:>I<directory-use> 1.483 +syntax variant allows the existence test to use I<directory-check>, 1.484 +but expands to I<directory-use> (replace mode). The 1.485 +I<directory-check>C<:+>I<directory-use> syntax variant allows 1.486 +the existence test to use I<directory-check>, but expands to 1.487 +I<directory-check>I<directory-use> (append mode). For instance 1.488 +C<tmpdir="%{getenv:HOME)/tmp:+/openpkg %{getenv:TMPDIR}:+/openpkg 1.489 +/tmp/%(echo $LOGNAME)/openpkg"> will first check for ~/tmp (and then use 1.490 +~/tmp/openpkg), then for $TMPDIR (and use $TMPDIR/openpkg) and finally 1.491 +it will use /tmp/$LOGNAME/openpkg at last resort. 1.492 + 1.493 +Paths are usually assembled by using RPM macros like 1.494 +C<%{l_prefix}> (the instance prefix), C<%{__openpkg_basename}> (the 1.495 +I<basename> parameter), C<%{realpath:<path>} (path resolution), 1.496 +C<%{dirname:<path>} (directory name extraction), C<%{basename:<path>} 1.497 +(file name extraction), etc. 1.498 + 1.499 +=item C<shared=>I<yes-or-no> 1.500 + 1.501 +This enables the I<subdir> components in the standard filesystem 1.502 +layouts by setting it to an automatically generated sub-directory named 1.503 +I<host>C<->I<arch>-I<os>. This allows one to build the same OpenPKG 1.504 +package in parallel on multiple hosts in a shared environment (usually 1.505 +on an NFS based filesystem). 1.506 + 1.507 +=item C<debug=>I<yes-or-no> 1.508 + 1.509 +This enables debug outputs which shows the effectively used directory 1.510 +paths. 1.511 + 1.512 +=back 1.513 + 1.514 +The generated C<.openpkg/rpmmacros> file contains the generic filesystem 1.515 +layout glue configuration for the particular filesystem I<layout>. 1.516 + 1.517 +=over 1 1.518 + 1.519 +=item C<%openpkg_layout macrosfile=%{macrosfile} layout=>I<type> 1.520 + 1.521 +=back 1.522 + 1.523 +=head1 CONFIGURATION 1.524 + 1.525 +=over 4 1.526 + 1.527 + OPENPKG_NAME="Ralf S. Engelschall" 1.528 + OPENPKG_MAIL="rse@openpkg.net" 1.529 + OPENPKG_MODE="developer" 1.530 + 1.531 + OPENPKG_PREFIX="/openpkg" 1.532 + OPENPKG_TMPDIR="${TMPDIR-/tmp}/openpkg" 1.533 + 1.534 + OPENPKG_VCS="cvs ci -m '<msg>' ." 1.535 + OPENPKG_UPLD="scp <srpm> openpkg-ftp@ftp.openpkg.org:/current/SRC/00UPLOAD/" 1.536 + 1.537 +=back 1.538 + 1.539 +=head1 ABOUT 1.540 + 1.541 +OpenPKG B<dev> is Ralf S. Engelschall's Perl-based clean-room partial 1.542 +re-implementation of 2008 for OpenPKG 4.0 of Thomas Lotterer's original 1.543 +OpenPKG B<dev> Bash-based shell from 2002. 1.544 + 1.545 +=cut 1.546 +