nimbus/src/nimbs/options.nim

205 lines
5.8 KiB
Nim
Raw Normal View History

2022-06-26 00:22:04 +00:00
# SPDX-FileCopyrightText: Copyright (C) Dominik Picheta. All rights reserved.
2023-04-25 13:04:52 +00:00
# SPDX-FileCopyrightText: 2023 Anna <cyber@sysrq.in>
2022-06-26 00:22:04 +00:00
# SPDX-License-Identifier: BSD-3-Clause
2023-04-25 15:21:27 +00:00
import std/[logging, os, parseopt, strformat, strutils]
2022-06-26 00:22:04 +00:00
2022-06-26 20:21:23 +00:00
import common
2022-06-26 00:22:04 +00:00
type
Options* = object
showHelp*: bool
2022-07-04 09:45:59 +00:00
debug*: bool
2022-06-26 20:21:23 +00:00
nimbleDir*: string
2022-06-29 02:52:56 +00:00
binDir*: string
2022-06-26 00:22:04 +00:00
nim*: string # Nim compiler location
2023-04-25 13:04:52 +00:00
url*: string
2022-06-26 00:22:04 +00:00
sourceDir*: string
2022-06-29 04:28:26 +00:00
buildDir*: string
2022-06-26 19:36:35 +00:00
logger*: ConsoleLogger
nimCacheBaseDir*: string
2022-06-29 03:07:18 +00:00
passNimFlags*: seq[string]
cmdLine*: seq[string] # only flags, not arguments
2022-06-26 00:22:04 +00:00
const
2023-04-25 15:21:27 +00:00
help* = fmt"""
Usage: nimbus [-h] [--debug] [--nimbleDir:path] [--binDir:path] [--nim:path]
[--nimcache:path] [--url:url] [nim opts...] sourceDir [buildDir]
2022-06-26 00:22:04 +00:00
positional arguments:
sourceDir
2022-06-29 04:28:26 +00:00
buildDir
2022-06-26 00:22:04 +00:00
optional arguments:
2023-04-25 15:21:27 +00:00
-h, --help Show this help message and exit.
2022-07-04 09:45:59 +00:00
--debug Show debugging information.
2023-04-25 15:21:27 +00:00
--nimbleDir:path Nimble directory (default: {defaultNimbleDir}).
--binDir:path Executable directory (default: {defaultBinDir}).
2022-06-26 20:21:23 +00:00
--nim:path Nim compiler (default: nim).
--nimcache:path Base directory for Nim cache (default: {nimCacheDirName}).
2022-06-29 05:49:38 +00:00
--url:url Package URL.
2022-06-29 03:07:18 +00:00
Unrecognized flags are passed to the Nim compiler.
2023-04-25 15:21:27 +00:00
""".strip()
2022-06-26 00:22:04 +00:00
proc writeHelp*() =
echo(help)
quit(QuitSuccess)
2022-07-04 09:45:59 +00:00
proc initLogger*(options: Options) =
if getHandlers().len != 0:
return
addHandler(options.logger)
if options.debug:
setLogFilter(lvlDebug)
else:
setLogFilter(lvlNotice)
2022-07-04 09:45:59 +00:00
2022-06-26 19:36:35 +00:00
proc setLogger*(options: var Options) =
options.logger = newConsoleLogger()
2022-07-04 09:45:59 +00:00
options.initLogger()
2022-06-26 19:36:35 +00:00
func getBuildDir*(options: Options): string =
2022-06-29 04:28:26 +00:00
return options.buildDir
func getNimCacheBaseDir*(options: Options): string =
if options.nimCacheBaseDir.len == 0:
return options.getBuildDir() / nimCacheDirName
else:
return options.nimCacheBaseDir
2022-07-02 14:29:28 +00:00
2022-06-29 04:28:26 +00:00
proc setBuildDir*(options: var Options) =
if options.buildDir.len != 0:
options.buildDir = expandTilde(options.buildDir).absolutePath()
createDir(options.buildDir)
else:
options.buildDir = getCurrentDir()
func getSourceDir*(options: Options): string =
2022-06-26 00:22:04 +00:00
return options.sourceDir
proc setSourceDir*(options: var Options) =
options.sourceDir = expandTilde(options.sourceDir).absolutePath()
if not dirExists(options.sourceDir):
quit("Source directory $1 does not exist" % options.sourceDir)
func getNimbleDir*(options: Options): string =
## Get the Nimble directory.
2022-06-26 20:21:23 +00:00
return options.nimbleDir
func getPkgsDir*(options: Options): string =
## Get the packages directory inside the Nimble directory.
2022-06-26 20:21:23 +00:00
options.getNimbleDir() / nimblePackagesDirName
proc setNimbleDir*(options: var Options) =
## Set the Nimble directory.
2022-06-26 20:21:23 +00:00
if options.nimbleDir.len != 0:
options.nimbleDir = expandTilde(options.nimbleDir).absolutePath()
else:
options.nimbleDir = defaultNimbleDir
func getBinDir*(options: Options): string =
## Get the executable directory.
2022-06-29 02:52:56 +00:00
return options.binDir
proc setBinDir*(options: var Options) =
## Set the executable directory.
2022-06-29 02:52:56 +00:00
if options.binDir.len != 0:
options.binDir = expandTilde(options.binDir).absolutePath()
else:
options.binDir = defaultBinDir
2022-06-26 00:22:04 +00:00
proc setNimBin*(options: var Options) =
# Find nim binary and set into options
if options.nim.len != 0:
# --nim:<path> takes priority...
if options.nim.splitPath().head.len == 0:
# Just filename, search in PATH - nim_temp shortcut
let pnim = findExe(options.nim)
if pnim.len != 0:
options.nim = pnim
else:
quit("Unable to find `$1` in $PATH" % options.nim)
elif not options.nim.isAbsolute():
# Relative path
options.nim = expandTilde(options.nim).absolutePath()
if not fileExists(options.nim):
quit("Unable to find `$1`" % options.nim)
else:
# Search PATH
let pnim = findExe("nim")
if pnim.len != 0:
options.nim = pnim
if options.nim.len == 0:
# Nim not found in PATH
quit("Unable to find `nim` binary - add to $PATH or use `--nim`")
func getNimBin*(options: Options): string =
2022-06-26 00:22:04 +00:00
return options.nim
func getNimFlags*(options: Options): string =
2022-06-29 03:07:18 +00:00
return options.passNimFlags.join(" ")
func getFlagString(kind: CmdLineKind, flag, val: string): string =
## Make a flag string from components. The result is quoted.
2022-06-26 00:22:04 +00:00
let prefix =
case kind
of cmdShortOption: "-"
of cmdLongOption: "--"
else: ""
if val == "":
result = prefix & flag
2022-06-26 00:22:04 +00:00
else:
result = prefix & flag & ":" & val
return result.quoteShell
2022-06-26 00:22:04 +00:00
func parseFlag(flag, val: string, result: var Options, kind = cmdLongOption) =
2022-06-26 00:22:04 +00:00
let f = flag.normalize()
let flagString = getFlagString(kind, flag, val)
2022-06-26 00:22:04 +00:00
case f
of "help", "h": result.showHelp = true
2022-07-04 09:45:59 +00:00
of "debug": result.debug = true
of "usedepfile": discard
2022-06-26 20:21:23 +00:00
of "nimbledir": result.nimbleDir = val
2022-06-29 02:52:56 +00:00
of "bindir": result.binDir = val
2022-06-26 00:22:04 +00:00
of "nim": result.nim = val
2022-06-29 05:49:38 +00:00
of "url": result.url = val
of "nimcache": result.nimCacheBaseDir = val
else: result.passNimFlags.add(flagString)
2022-06-26 00:22:04 +00:00
result.cmdline.add(flagString)
func parseArgument(key: string, argc: var int, result: var Options) =
inc argc
case argc
of 1: result.sourceDir = key
of 2: result.buildDir = key
else: discard
2022-06-26 00:22:04 +00:00
proc parseCmdLine*(): Options =
# set default values here
result.debug = false
result.showHelp = false
2022-06-26 00:22:04 +00:00
var argc = 0
for kind, key, val in getOpt():
case kind
of cmdArgument:
parseArgument(key, argc, result)
2022-06-26 00:22:04 +00:00
of cmdLongOption, cmdShortOption:
parseFlag(key, val, result, kind)
of cmdEnd: assert(false) # cannot happen
2022-06-29 04:28:26 +00:00
if argc notin {1..2}:
2022-06-26 00:22:04 +00:00
result.showHelp = true
func getCmdLine*(options: Options): string =
var cmdLine = options.cmdLine
cmdLine.add(options.getSourceDir().quoteShell)
cmdLine.add(options.getBuildDir().quoteShell)
return cmdLine.join(" ")