Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions doc/pakku.conf.5.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ Options
Set the temporary directory in which pakku will perform all
building operations. The default value is +/tmp/pakku-$\{USER\}+.

*PackageOutputDir =* path/to/package/output/dir::
Built package archives (\fB*.pkg.tar*\fP) are written to this
directory, separating package output from the transient build
workspace in +TmpDir+. Supports the same variable expansion as
+TmpDir+ (+\fB${USER}\fP+, +\fB${HOME}\fP+, +\fB${UID}\fP+,
+\fB$$\fP+). Defaults to +TmpDir+ when unset or empty.

*AurRepo =* name::
Set the fake AUR repository name. This name should not conflict with
names of declared repositories. The default value is +aur+.
Expand Down Expand Up @@ -56,10 +63,32 @@ Options
content of PKGBUILD and other files. Pressing enter key will give the
positive answer unless this option is specified.

*PreserveBuilt =* Internal | User | Disabled::
If set to Internal, built packages will be copied to pacman cache dir.
If set to User, built packages will be copied to UserCacheDir.
If set to Disabled (the default), built packages will not be preserved.
*KeepBuildDirOnFailure*::
When enabled, pakku preserves the build workspace (cloned repositories
and build directories) when a build fails. By default the workspace is
removed on failure.

*KeepBuiltPackagesOnFailure*::
When enabled, pakku preserves built package archives in the staging
directory when a build fails. By default archives are removed on
build failure.

*PreserveBuilt =* Internal | User | Pkgdest | Disabled::
Where to copy built packages before invoking pacman. If set to
Internal, packages are copied to the pacman cache directory. If set
to User, packages are copied to +UserCacheDir+. If set to Pkgdest,
packages are copied to the PKGDEST configured in the user's
linkman:makepkg.conf[5]. If set to Disabled (the default), no copy
is performed.

*CleanupAfterInstall =* Full | Worktree | None::
Controls cleanup of build artifacts and workspace after a successful
install. Full (the default) removes both temporary build directories
and built package archives. Worktree removes build directories but
preserves package archives selected for installation in the output
directory for reuse on subsequent runs. None preserves the workspace and
selected package archives. Unselected split-package sibling archives are
removed in Worktree and None modes.

*PreBuildCommand =* command::
This command will be executed in package directory before building,
Expand Down
7 changes: 6 additions & 1 deletion pakku.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[options]
#UserCacheDir = ${HOME}/.cache/pakku
#TmpDir = /tmp/pakku-${USER}
#PackageOutputDir =
#AurRepo = aur

AurComments
Expand All @@ -13,7 +14,11 @@ PrintLocalIsNewer
#SudoExec
#ViewNoDefault

#PreserveBuilt = Disabled
#KeepBuildDirOnFailure
#KeepBuiltPackagesOnFailure

#PreserveBuilt = Disabled | Internal | User | Pkgdest
#CleanupAfterInstall = Full

#PreBuildCommand =
#PreferredSudoCommand =
18 changes: 18 additions & 0 deletions src/common.nim
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,24 @@ proc resolveMakepkgConf*(): tuple[path: Option[Path], error: string] =

(none(Path), tr"failed to find makepkg config file")

proc resolveEffectivePkgdest*(confFile: string): string =
## Sources the resolved makepkg.conf to read the effective PKGDEST value
## without pakku's override block. Returns "" if PKGDEST is unset (makepkg
## default: write alongside the PKGBUILD). Environment variable PKGDEST takes
## precedence over the conf file.
let envDest = getEnv("PKGDEST")
if envDest.len > 0:
return envDest

forkWaitRedirect(() => (block:
if dropPrivRedirect():
execRedirect(bashCmd, "-c",
"source \"$@\" && echo \"$PKGDEST\"",
"bash", confFile)
else:
quit(1)))
.output.optFirst.get("")

template checkAndRefreshUpgrade*(sudoPrefix: seq[string], color: bool, args: seq[Argument]):
tuple[code: int, args: seq[Argument]] =
checkAndRefreshUpgradeInternal(sudoPrefix, color, true, args)
Expand Down
155 changes: 90 additions & 65 deletions src/config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,54 +12,61 @@ type
PreserveBuilt* {.pure.} = enum
internal = "Internal",
user = "User",
pkgdest = "Pkgdest",
disabled = "Disabled"

CommonConfig* = tuple[
dbs: seq[string],
arch: string,
debug: bool,
progressBar: bool,
chomp: bool,
verbosePkgLists: bool,
downloadTimeout: bool,
pgpKeyserver: Option[string],
defaultRoot: bool,
ignorePkgs: HashSet[string],
ignoreGroups: HashSet[string]
]

PacmanConfig* = tuple[
common: CommonConfig,
sysrootOption: Option[string],
rootRelOption: Option[string],
dbRelOption: Option[string],
cacheRelOption: Option[string],
gpgRelOption: Option[string],
colorMode: ColorMode
]

Config* = tuple[
common: CommonConfig,
root: string,
db: string,
cache: string,
userCacheInitial: string,
userCacheCurrent: string,
tmpRootInitial: string,
tmpRootCurrent: string,
color: bool,
aurRepo: string,
aurComments: bool,
checkIgnored: bool,
ignoreArch: bool,
printAurNotFound: bool,
printLocalIsNewer: bool,
sudoExec: bool,
viewNoDefault: bool,
preserveBuilt: PreserveBuilt,
preBuildCommand: Option[string],
sudoCommand: seq[string]
]
CleanupPolicy* {.pure.} = enum
full = "Full",
worktree = "Worktree",
none = "None"

CommonConfig* = object
dbs*: seq[string]
arch*: string
debug*: bool
progressBar*: bool = true
chomp*: bool
verbosePkgLists*: bool
downloadTimeout*: bool = true
pgpKeyserver*: Option[string]
defaultRoot*: bool
ignorePkgs*: HashSet[string]
ignoreGroups*: HashSet[string]

PacmanConfig* = object
common*: CommonConfig
sysrootOption*: Option[string]
rootRelOption*: Option[string]
dbRelOption*: Option[string]
cacheRelOption*: Option[string]
gpgRelOption*: Option[string]
colorMode*: ColorMode = colorNever

Config* = object
common*: CommonConfig
root*: string
db*: string
cache*: string
userCacheInitial*: string
userCacheCurrent*: string
tmpRootInitial*: string
tmpRootCurrent*: string
packageOutputDir*: string
color*: bool
aurRepo*: string = "aur"
aurComments*: bool
checkIgnored*: bool
ignoreArch*: bool
printAurNotFound*: bool
printLocalIsNewer*: bool
sudoExec*: bool
viewNoDefault*: bool
keepBuildDirOnFailure*: bool
keepBuiltPackagesOnFailure*: bool
cleanupAfterInstall*: CleanupPolicy = full
preserveBuilt*: PreserveBuilt = disabled
preBuildCommand*: Option[string]
sudoCommand*: seq[string]

proc readConfigFile*(configFile: string):
(OrderedTable[string, ref Table[string, string]], bool) =
Expand Down Expand Up @@ -141,6 +148,8 @@ proc extendRel*(pathRel: string, sysroot: Option[string]): string =
sysroot.map(s => (s & "/" & pathRel).simplifyConfigPath).get(pathRel)

proc obtainConfig*(config: PacmanConfig): Config =
## Builds the pakku runtime configuration by layering the pacman config with
## user-specified options from the pakku.conf options section.
let (configTable, _) = readConfigFile(SysConfDir & "/pakku.conf")
let options = configTable.opt("options").map(t => t[]).get(initTable[string, string]())

Expand Down Expand Up @@ -169,18 +178,6 @@ proc obtainConfig*(config: PacmanConfig): Config =
tmpRootInitial = obtainTmpDir(initialOrCurrentUser)
tmpRootCurrent = obtainTmpDir(currentUser)
aurRepo = options.opt("AurRepo").get("aur")
aurComments = options.hasKey("AurComments")
checkIgnored = options.hasKey("CheckIgnored")
ignoreArch = options.hasKey("IgnoreArch")
printAurNotFound = options.hasKey("PrintAurNotFound")
printLocalIsNewer = options.hasKey("PrintLocalIsNewer")
sudoExec = options.hasKey("SudoExec")
viewNoDefault = options.hasKey("ViewNoDefault")
preserveBuilt = toSeq(enumerate[PreserveBuilt]())
.filter(o => some($o) == options.opt("PreserveBuilt"))
.optLast.get(PreserveBuilt.disabled)
preBuildCommand = options.opt("PreBuildCommand")
sudoCommand = options.opt("PreferredSudoCommand").getSudoPrefix()

if config.common.dbs.find(aurRepo) >= 0:
raise commandError(tr"repo '$#' can not be used as fake AUR repository" % [aurRepo],
Expand All @@ -190,13 +187,41 @@ proc obtainConfig*(config: PacmanConfig): Config =
raise commandError(trp("could not register '%s' database (%s)\n") %
[aurRepo, tra"wrong or NULL argument passed"], colorNeeded = some(color))

((config.common.dbs, config.common.arch, config.common.debug, config.common.progressBar,
config.common.chomp, config.common.verbosePkgLists, config.common.downloadTimeout,
config.common.pgpKeyserver, config.common.defaultRoot and config.sysrootOption.isNone,
config.common.ignorePkgs, config.common.ignoreGroups),
root, db, cache, userCacheInitial, userCacheCurrent, tmpRootInitial, tmpRootCurrent,
color, aurRepo, aurComments, checkIgnored, ignoreArch, printAurNotFound, printLocalIsNewer,
sudoExec, viewNoDefault, preserveBuilt, preBuildCommand, sudoCommand)
let common = block:
var c = config.common
c.defaultRoot = c.defaultRoot and config.sysrootOption.isNone
c

Config(
common: common,
root: root,
db: db,
cache: cache,
userCacheInitial: userCacheInitial,
userCacheCurrent: userCacheCurrent,
tmpRootInitial: tmpRootInitial,
tmpRootCurrent: tmpRootCurrent,
packageOutputDir: options.opt("PackageOutputDir").get("").handleDirPattern(initialOrCurrentUser),
color: color,
aurRepo: aurRepo,
aurComments: options.hasKey("AurComments"),
checkIgnored: options.hasKey("CheckIgnored"),
ignoreArch: options.hasKey("IgnoreArch"),
printAurNotFound: options.hasKey("PrintAurNotFound"),
printLocalIsNewer: options.hasKey("PrintLocalIsNewer"),
sudoExec: options.hasKey("SudoExec"),
viewNoDefault: options.hasKey("ViewNoDefault"),
keepBuildDirOnFailure: options.hasKey("KeepBuildDirOnFailure"),
keepBuiltPackagesOnFailure: options.hasKey("KeepBuiltPackagesOnFailure"),
cleanupAfterInstall: toSeq(enumerate[CleanupPolicy]())
.filterIt(some($it) == options.opt("CleanupAfterInstall"))
.optLast.get(CleanupPolicy.full),
preserveBuilt: toSeq(enumerate[PreserveBuilt]())
.filterIt(some($it) == options.opt("PreserveBuilt"))
.optLast.get(PreserveBuilt.disabled),
preBuildCommand: options.opt("PreBuildCommand"),
sudoCommand: options.opt("PreferredSudoCommand").getSudoPrefix(),
)

template withAlpmConfig*(config: Config, passDbs: bool,
handle: untyped, alpmDbs: untyped, errors: untyped, body: untyped): untyped =
Expand Down
Loading