mirror of
https://github.com/daylinmorgan/forge.git
synced 2024-12-22 02:50:44 -06:00
apply nph
This commit is contained in:
parent
e60415e9b0
commit
19df564645
4 changed files with 120 additions and 123 deletions
102
src/forge.nim
102
src/forge.nim
|
@ -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'},
|
||||
],
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
@ -64,17 +60,18 @@ proc loadConfigFile*(
|
|||
proc inferName(s: string, nimbleFile: string): string =
|
||||
if s != "":
|
||||
return s
|
||||
elif nimbleFile != "":
|
||||
elif nimbleFile != "":
|
||||
return nimbleFile.rsplit(".", maxsplit = 1)[0]
|
||||
|
||||
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] = ""
|
||||
|
|
|
@ -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}"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue