apply nph

This commit is contained in:
Daylin Morgan 2024-11-06 23:07:04 -06:00
parent e60415e9b0
commit 19df564645
Signed by: daylin
GPG key ID: 950D13E9719334AD
4 changed files with 120 additions and 123 deletions

View file

@ -7,15 +7,16 @@ proc genFlags(target: string, args: seq[string] = @[]): seq[string] =
addFlag "cpu" addFlag "cpu"
addFlag "os" addFlag "os"
result &= @[ result &=
"--cc:clang", @[
&"--clang.exe='forgecc'", "--cc:clang",
&"--clang.linkerexe='forgecc'", &"--clang.exe='forgecc'",
# &"--passC:\"-target {target} -fno-sanitize=undefined\"", &"--clang.linkerexe='forgecc'",
&"--passC:'-target {triplet}'", # &"--passC:\"-target {target} -fno-sanitize=undefined\"",
# &"--passL:\"-target {target} -fno-sanitize=undefined\"", &"--passC:'-target {triplet}'",
&"--passL:'-target {triplet}'", # &"--passL:\"-target {target} -fno-sanitize=undefined\"",
] &"--passL:'-target {triplet}'",
]
proc targets() = proc targets() =
## show available targets ## show available targets
@ -43,19 +44,19 @@ proc cc(target: string, dryrun: bool = false, nimble: bool = false, args: seq[st
quit(execCmd cmd) quit(execCmd cmd)
proc release( proc release(
target: seq[string] = @[], target: seq[string] = @[],
bin: seq[string] = @[], bin: seq[string] = @[],
args: seq[string], args: seq[string],
outdir: string = "dist", outdir: string = "dist",
format: string = "", format: string = "",
name: string = "", name: string = "",
version: string = "", version: string = "",
dryrun: bool = false, dryrun: bool = false,
nimble: bool = false, nimble: bool = false,
configFile: string = ".forge.cfg", configFile: string = ".forge.cfg",
noConfig: bool = false, noConfig: bool = false,
verbose: bool = false, verbose: bool = false,
) = ) =
## generate release assets for n>=1 targets ## generate release assets for n>=1 targets
## ##
## format argument: ## format argument:
@ -66,17 +67,8 @@ proc release(
## if name or version are not specified they will be inferred from the local .nimble file ## if name or version are not specified they will be inferred from the local .nimble file
zigExists() zigExists()
let cfg = newConfig( let cfg =
target, newConfig(target, bin, outdir, format, name, version, nimble, configFile, noConfig)
bin,
outdir,
format,
name,
version,
nimble,
configFile,
noConfig
)
if cfg.targets.len == 0: if cfg.targets.len == 0:
termErrQuit "expected at least 1 target" termErrQuit "expected at least 1 target"
@ -100,9 +92,9 @@ proc release(
for t, tArgs in cfg.targets: for t, tArgs in cfg.targets:
for b, bArgs in cfg.bins: for b, bArgs in cfg.bins:
var cmdParts: seq[string] = @[] var cmdParts: seq[string] = @[]
let outFlag = &"--outdir:'" & ( let outFlag =
cfg.outdir / formatDirName(cfg.format, cfg.name, cfg.version, t) &"--outdir:'" &
) & "'" (cfg.outdir / formatDirName(cfg.format, cfg.name, cfg.version, t)) & "'"
cmdParts &= @[baseCmd, "c"] cmdParts &= @[baseCmd, "c"]
cmdParts.add genFlags(t, rest) cmdParts.add genFlags(t, rest)
@ -110,7 +102,8 @@ proc release(
cmdParts.add rest cmdParts.add rest
cmdParts.add outFlag cmdParts.add outFlag
for a in @[targs, bargs]: for a in @[targs, bargs]:
if a != "": cmdParts.add a if a != "":
cmdParts.add a
cmdParts.add b cmdParts.add b
let cmd = cmdParts.join(" ") let cmd = cmdParts.join(" ")
@ -137,20 +130,27 @@ when isMainModule:
dispatchMulti( dispatchMulti(
["multi", cf = vsnCfg], ["multi", cf = vsnCfg],
[cc, usage = clUse, help = { [
cc,
usage = clUse,
help = {
"dryrun": "show command instead of executing", "dryrun": "show command instead of executing",
"nimble": "use nimble as base command for compiling" "nimble": "use nimble as base command for compiling",
}],
[targets, usage = clUse],
[release, usage = clUse, help = {
"target": "set target, may be repeated",
"bin": "set bin, may be repeated",
"dryrun": "show command instead of executing",
"format": "set format, see help above",
"nimble": "use nimble as base command for compiling",
"config-file": "path to config",
"no-config": "ignore config file"
}, },
short = {"verbose": 'V'} ],
] [targets, usage = clUse],
[
release,
usage = clUse,
help = {
"target": "set target, may be repeated",
"bin": "set bin, may be repeated",
"dryrun": "show command instead of executing",
"format": "set format, see help above",
"nimble": "use nimble as base command for compiling",
"config-file": "path to config",
"no-config": "ignore config file",
},
short = {"verbose": 'V'},
],
) )

View file

@ -1,19 +1,20 @@
import std/[parsecfg, tables, os, strutils, strformat] import std/[parsecfg, tables, os, strutils, strformat]
import term import term
type type ForgeConfig* = object
ForgeConfig* = object targets*: OrderedTableRef[string, string]
targets*: OrderedTableRef[string, string] bins*: OrderedTableRef[string, string]
bins*: OrderedTableRef[string, string] outdir*: string
outdir*: string format*: string
format*: string name*: string
name*: string version*: string
version*: string nimble*: bool
nimble*: bool
proc showConfig*(c: ForgeConfig) = proc showConfig*(c: ForgeConfig) =
var lines: string = "" var lines: string = ""
template addLine(l: string) = lines.add(l & "\n") template addLine(l: string) =
lines.add(l & "\n")
proc addNameArgs(name, args: string): string = proc addNameArgs(name, args: string): string =
result.add fmt"| {name}" result.add fmt"| {name}"
if args != "": if args != "":
@ -26,7 +27,6 @@ config =
| [blue]format[/] {c.format} | [blue]format[/] {c.format}
| [blue]version[/] {c.version}""" | [blue]version[/] {c.version}"""
addLine $bb"| [green]targets[/]:" addLine $bb"| [green]targets[/]:"
for target, args in c.targets: for target, args in c.targets:
addLine addNameArgs(target, args) addLine addNameArgs(target, args)
@ -37,11 +37,7 @@ config =
termEcho lines termEcho lines
proc loadConfigFile*( proc loadConfigFile*(f: string, load_targets: bool, load_bins: bool): ForgeConfig =
f: string,
load_targets: bool,
load_bins: bool
): ForgeConfig =
let dict = loadConfig(f) let dict = loadConfig(f)
# get the top level flags # get the top level flags
@ -64,17 +60,18 @@ proc loadConfigFile*(
proc inferName(s: string, nimbleFile: string): string = proc inferName(s: string, nimbleFile: string): string =
if s != "": if s != "":
return s return s
elif nimbleFile != "": elif nimbleFile != "":
return nimbleFile.rsplit(".", maxsplit = 1)[0] return nimbleFile.rsplit(".", maxsplit = 1)[0]
proc findNimbleFile(): string = proc findNimbleFile(): string =
var candidates: seq[string] var candidates: seq[string]
for kind, path in walkDir(getCurrentDir(), relative = true): for kind, path in walkDir(getCurrentDir(), relative = true):
case kind: case kind
of pcFile, pcLinkToFile: of pcFile, pcLinkToFile:
if path.endsWith(".nimble"): if path.endsWith(".nimble"):
candidates.add path candidates.add path
else: discard else:
discard
# nimble will probably prevent this, # nimble will probably prevent this,
# but not sure about atlas or bespoke builds # but not sure about atlas or bespoke builds
@ -85,7 +82,8 @@ proc findNimbleFile(): string =
return candidates[0] return candidates[0]
proc inferVersion(s: string, nimbleFile: string): string = proc inferVersion(s: string, nimbleFile: string): string =
if s != "": return s if s != "":
return s
if nimbleFile.fileExists: if nimbleFile.fileExists:
let nimbleCfg = loadConfig(nimbleFile) let nimbleCfg = loadConfig(nimbleFile)
@ -97,22 +95,22 @@ proc inferBin(nimbleFile: string): string =
default = "src" / &"{pkgName}.nim" default = "src" / &"{pkgName}.nim"
backup = &"{pkgName}.nim" backup = &"{pkgName}.nim"
if default.fileExists(): return default if default.fileExists():
if backup.fileExists(): return backup return default
if backup.fileExists():
return backup
proc newConfig*( proc newConfig*(
targets: seq[string], targets: seq[string],
bins: seq[string], bins: seq[string],
outdir: string, outdir: string,
format: string, format: string,
name: string, name: string,
version: string, version: string,
nimble: bool, nimble: bool,
configFile: string, configFile: string,
noConfig: bool noConfig: bool,
): ForgeConfig = ): ForgeConfig =
let nimbleFile = findNimbleFile() let nimbleFile = findNimbleFile()
if configFile.fileExists and not noConfig: if configFile.fileExists and not noConfig:
@ -132,8 +130,10 @@ proc newConfig*(
if result.version == "": if result.version == "":
result.version = inferVersion(version, nimbleFile) result.version = inferVersion(version, nimbleFile)
if result.format == "": if result.format == "":
if format != "": result.format = format if format != "":
else: result.format = "${name}-v${version}-${target}" result.format = format
else:
result.format = "${name}-v${version}-${target}"
for t in targets: for t in targets:
result.targets[t] = "" result.targets[t] = ""

View file

@ -8,27 +8,26 @@ proc columns*(items: seq[string]): string =
let let
maxWidth = max(items.mapIt(it.len)) maxWidth = max(items.mapIt(it.len))
nColumns = floor((terminalWidth() + 1) / (maxWidth + 1)).int nColumns = floor((terminalWidth() + 1) / (maxWidth + 1)).int
result = ( result = (items.mapIt(it.alignLeft(maxWidth + 1)))
items.mapIt(it.alignLeft(maxWidth + 1)) .distribute((items.len / nColumns).int + 1)
).distribute( .mapIt(it.join(""))
(items.len / nColumns).int + 1 .join("\n")
).mapIt(it.join("")).join("\n")
template parseArgs*(args: seq[string]): seq[string] = template parseArgs*(args: seq[string]): seq[string] =
if args.len == 0: if args.len == 0:
args args
elif args[0] == "c": elif args[0] == "c":
args[1..^1] args[1 ..^ 1]
else: else:
args args
type type Triplet* = object
Triplet* = object cpu: string
cpu: string os: string
os: string libc: string
libc: string
proc `$`*(t: Triplet): string = &"{t.cpu}-{t.os}-{t.libc}" proc `$`*(t: Triplet): string =
&"{t.cpu}-{t.os}-{t.libc}"
proc checkTargets*(targets: seq[string]) = proc checkTargets*(targets: seq[string]) =
let knownTargets = zigTargets() let knownTargets = zigTargets()
@ -54,19 +53,22 @@ macro addFlag*(arg: untyped): untyped =
flag = "--" & arg.strVal & ":" flag = "--" & arg.strVal & ":"
inferProc = newCall("infer" & arg.strVal, newIdentNode("triplet")) inferProc = newCall("infer" & arg.strVal, newIdentNode("triplet"))
quote do: quote:
if `flag` notin args: if `flag` notin args:
let selected = `inferProc` let selected = `inferProc`
if selected != "": if selected != "":
result.add `flag` & selected result.add `flag` & selected
proc inferOs*(t: Triplet): string = proc inferOs*(t: Triplet): string =
case t.os: case t.os
of "windows", "linux": t.os.capitalizeAscii() of "windows", "linux":
of "macos": "MacOSX" t.os.capitalizeAscii()
of "wasm": "Linux" of "macos":
else: "" "MacOSX"
of "wasm":
"Linux"
else:
""
proc inferCpu*(t: Triplet): string = proc inferCpu*(t: Triplet): string =
# Available options are: # Available options are:
@ -78,7 +80,7 @@ proc inferCpu*(t: Triplet): string =
# NOTE: I don't know what the _be eb means but if nim # NOTE: I don't know what the _be eb means but if nim
# can't handle them then maybe an error would be better # can't handle them then maybe an error would be better
result = result =
case t.cpu: case t.cpu
of "x86_64": of "x86_64":
"amd64" "amd64"
of "aarch64", "aarch64_be": of "aarch64", "aarch64_be":
@ -90,17 +92,18 @@ proc inferCpu*(t: Triplet): string =
of "powerpc64el": of "powerpc64el":
"powerpc64le" "powerpc64le"
# remain the same # remain the same
of "m68k", "mips64el", "mipsel", "mips", "powerpc", "powerpc64", "riscv64", of "m68k", "mips64el", "mipsel", "mips", "powerpc", "powerpc64", "riscv64", "sparc",
"sparc", "sparc64", "wasm32": t.cpu "sparc64", "wasm32":
t.cpu
else: else:
"" ""
proc formatDirName*(formatstr: string, name: string, version: string, proc formatDirName*(
target: string): string = formatstr: string, name: string, version: string, target: string
): string =
var vsn = version var vsn = version
if ("v$version" in formatstr or "v${version}" in formatstr) and if ("v$version" in formatstr or "v${version}" in formatstr) and vsn.startsWith("v"):
vsn.startsWith("v"): vsn = vsn[1 ..^ 1]
vsn = vsn[1..^1]
try: try:
result = formatstr % ["name", name, "version", vsn, "target", target] result = formatstr % ["name", name, "version", vsn, "target", target]
except ValueError as e: except ValueError as e:
@ -108,4 +111,3 @@ proc formatDirName*(formatstr: string, name: string, version: string,
if result == "": if result == "":
termErrQuit &"error processing formatstr: {formatstr}" termErrQuit &"error processing formatstr: {formatstr}"

View file

@ -12,9 +12,7 @@ template callZig*(zigCmd: string) =
args &= commandLineParams() args &= commandLineParams()
# Start process # Start process
let process = startProcess( let process = startProcess(
"zig", "zig", args = args, options = {poStdErrToStdOut, poUsePath, poParentStreams}
args = args,
options = {poStdErrToStdOut, poUsePath, poParentStreams}
) )
# Get the code so we can carry across the exit code # Get the code so we can carry across the exit code
let exitCode = process.waitForExit() let exitCode = process.waitForExit()
@ -22,12 +20,9 @@ template callZig*(zigCmd: string) =
close process close process
quit exitCode quit exitCode
proc zigExists*() = proc zigExists*() =
if (findExe "zig") == "": if (findExe "zig") == "":
termErr "[red]zig not found".bb termErr "[red]zig not found".bb
termErr " forge requires a working installation of zig" termErr " forge requires a working installation of zig"
termErr " see: https://ziglang.org/download/" termErr " see: https://ziglang.org/download/"
quit 1 quit 1