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 "os"
result &= @[
"--cc:clang",
&"--clang.exe='forgecc'",
&"--clang.linkerexe='forgecc'",
# &"--passC:\"-target {target} -fno-sanitize=undefined\"",
&"--passC:'-target {triplet}'",
# &"--passL:\"-target {target} -fno-sanitize=undefined\"",
&"--passL:'-target {triplet}'",
]
result &=
@[
"--cc:clang",
&"--clang.exe='forgecc'",
&"--clang.linkerexe='forgecc'",
# &"--passC:\"-target {target} -fno-sanitize=undefined\"",
&"--passC:'-target {triplet}'",
# &"--passL:\"-target {target} -fno-sanitize=undefined\"",
&"--passL:'-target {triplet}'",
]
proc targets() =
## show available targets
@ -43,19 +44,19 @@ proc cc(target: string, dryrun: bool = false, nimble: bool = false, args: seq[st
quit(execCmd cmd)
proc release(
target: seq[string] = @[],
bin: seq[string] = @[],
args: seq[string],
outdir: string = "dist",
format: string = "",
name: string = "",
version: string = "",
dryrun: bool = false,
nimble: bool = false,
configFile: string = ".forge.cfg",
noConfig: bool = false,
verbose: bool = false,
) =
target: seq[string] = @[],
bin: seq[string] = @[],
args: seq[string],
outdir: string = "dist",
format: string = "",
name: string = "",
version: string = "",
dryrun: bool = false,
nimble: bool = false,
configFile: string = ".forge.cfg",
noConfig: bool = false,
verbose: bool = false,
) =
## generate release assets for n>=1 targets
##
## format argument:
@ -66,17 +67,8 @@ proc release(
## if name or version are not specified they will be inferred from the local .nimble file
zigExists()
let cfg = newConfig(
target,
bin,
outdir,
format,
name,
version,
nimble,
configFile,
noConfig
)
let cfg =
newConfig(target, bin, outdir, format, name, version, nimble, configFile, noConfig)
if cfg.targets.len == 0:
termErrQuit "expected at least 1 target"
@ -100,9 +92,9 @@ proc release(
for t, tArgs in cfg.targets:
for b, bArgs in cfg.bins:
var cmdParts: seq[string] = @[]
let outFlag = &"--outdir:'" & (
cfg.outdir / formatDirName(cfg.format, cfg.name, cfg.version, t)
) & "'"
let outFlag =
&"--outdir:'" &
(cfg.outdir / formatDirName(cfg.format, cfg.name, cfg.version, t)) & "'"
cmdParts &= @[baseCmd, "c"]
cmdParts.add genFlags(t, rest)
@ -110,7 +102,8 @@ proc release(
cmdParts.add rest
cmdParts.add outFlag
for a in @[targs, bargs]:
if a != "": cmdParts.add a
if a != "":
cmdParts.add a
cmdParts.add b
let cmd = cmdParts.join(" ")
@ -137,20 +130,27 @@ when isMainModule:
dispatchMulti(
["multi", cf = vsnCfg],
[cc, usage = clUse, help = {
[
cc,
usage = clUse,
help = {
"dryrun": "show command instead of executing",
"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"
"nimble": "use nimble as base command for compiling",
},
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 term
type
ForgeConfig* = object
targets*: OrderedTableRef[string, string]
bins*: OrderedTableRef[string, string]
outdir*: string
format*: string
name*: string
version*: string
nimble*: bool
type ForgeConfig* = object
targets*: OrderedTableRef[string, string]
bins*: OrderedTableRef[string, string]
outdir*: string
format*: string
name*: string
version*: string
nimble*: bool
proc showConfig*(c: ForgeConfig) =
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 =
result.add fmt"| {name}"
if args != "":
@ -26,7 +27,6 @@ config =
| [blue]format[/] {c.format}
| [blue]version[/] {c.version}"""
addLine $bb"| [green]targets[/]:"
for target, args in c.targets:
addLine addNameArgs(target, args)
@ -37,11 +37,7 @@ config =
termEcho lines
proc loadConfigFile*(
f: string,
load_targets: bool,
load_bins: bool
): ForgeConfig =
proc loadConfigFile*(f: string, load_targets: bool, load_bins: bool): ForgeConfig =
let dict = loadConfig(f)
# get the top level flags
@ -70,11 +66,12 @@ proc inferName(s: string, nimbleFile: string): string =
proc findNimbleFile(): string =
var candidates: seq[string]
for kind, path in walkDir(getCurrentDir(), relative = true):
case kind:
of pcFile, pcLinkToFile:
if path.endsWith(".nimble"):
candidates.add path
else: discard
case kind
of pcFile, pcLinkToFile:
if path.endsWith(".nimble"):
candidates.add path
else:
discard
# nimble will probably prevent this,
# but not sure about atlas or bespoke builds
@ -85,7 +82,8 @@ proc findNimbleFile(): string =
return candidates[0]
proc inferVersion(s: string, nimbleFile: string): string =
if s != "": return s
if s != "":
return s
if nimbleFile.fileExists:
let nimbleCfg = loadConfig(nimbleFile)
@ -97,22 +95,22 @@ proc inferBin(nimbleFile: string): string =
default = "src" / &"{pkgName}.nim"
backup = &"{pkgName}.nim"
if default.fileExists(): return default
if backup.fileExists(): return backup
if default.fileExists():
return default
if backup.fileExists():
return backup
proc newConfig*(
targets: seq[string],
bins: seq[string],
outdir: string,
format: string,
name: string,
version: string,
nimble: bool,
configFile: string,
noConfig: bool
targets: seq[string],
bins: seq[string],
outdir: string,
format: string,
name: string,
version: string,
nimble: bool,
configFile: string,
noConfig: bool,
): ForgeConfig =
let nimbleFile = findNimbleFile()
if configFile.fileExists and not noConfig:
@ -132,8 +130,10 @@ proc newConfig*(
if result.version == "":
result.version = inferVersion(version, nimbleFile)
if result.format == "":
if format != "": result.format = format
else: result.format = "${name}-v${version}-${target}"
if format != "":
result.format = format
else:
result.format = "${name}-v${version}-${target}"
for t in targets:
result.targets[t] = ""

View file

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

View file

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