mirror of
https://github.com/daylinmorgan/oizys.git
synced 2024-12-23 15:10:44 -06:00
Compare commits
6 commits
59aca58dae
...
aa62080857
Author | SHA1 | Date | |
---|---|---|---|
aa62080857 | |||
908ab5189a | |||
8347ad4a55 | |||
ee0b137279 | |||
9736bb3bcd | |||
6e31339e3c |
12 changed files with 71 additions and 104 deletions
22
flake.lock
22
flake.lock
|
@ -323,11 +323,11 @@
|
||||||
"xdph": "xdph"
|
"xdph": "xdph"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1725873008,
|
"lastModified": 1725895184,
|
||||||
"narHash": "sha256-hVPjlB0EPbf98tm4LcwOmS80tO/qfAoXqXKWZjDUG50=",
|
"narHash": "sha256-VtrRnnmRaL/7ovFKYe5hXyYc3ZV6IQ8JVCxcnCT3iEs=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "04421063af2941c6e27e6dca2bdc2c387778a3a5",
|
"rev": "85da1a17d831e2b5db9c1c1e4ce6427d63563562",
|
||||||
"revCount": 5203,
|
"revCount": 5205,
|
||||||
"submodules": true,
|
"submodules": true,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/hyprwm/Hyprland/"
|
"url": "https://github.com/hyprwm/Hyprland/"
|
||||||
|
@ -504,11 +504,11 @@
|
||||||
"lix": {
|
"lix": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1725846500,
|
"lastModified": 1725898463,
|
||||||
"narHash": "sha256-8tzJO3PllVPc0RYE0OfXVWlgTiJxKH1nzXsQLGyFRJ4=",
|
"narHash": "sha256-/Q99Vj3w/8BDrlCA3Ncen2FXqjMPyGaWTkKoex2HxSk=",
|
||||||
"rev": "c14486ae8d3bbc862c625d948a6b2f4dc0927d5b",
|
"rev": "8f7ab26f96ec025db3f922fc50f5184167662596",
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/c14486ae8d3bbc862c625d948a6b2f4dc0927d5b.tar.gz?rev=c14486ae8d3bbc862c625d948a6b2f4dc0927d5b"
|
"url": "https://git.lix.systems/api/v1/repos/lix-project/lix/archive/8f7ab26f96ec025db3f922fc50f5184167662596.tar.gz?rev=8f7ab26f96ec025db3f922fc50f5184167662596"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
|
@ -744,11 +744,11 @@
|
||||||
"nixpkgs": "nixpkgs_6"
|
"nixpkgs": "nixpkgs_6"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1725885379,
|
"lastModified": 1725891647,
|
||||||
"narHash": "sha256-gw+CYMQRqzErAIp4WOTTeX6YXOhgk9YWyTM1Sa2cACA=",
|
"narHash": "sha256-0PPiL9SbX9LuY3icYE6amlc5jCqme9QYi/d/r1FSaIU=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "nixpkgs-wayland",
|
"repo": "nixpkgs-wayland",
|
||||||
"rev": "dc951da2b8fdaabc09a1bc72dd5744438976be47",
|
"rev": "386a8eb790f34ee62eb475815fffe99613d74d1f",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
@ -8,5 +8,5 @@ buildNimblePackage {
|
||||||
verions = "unstable";
|
verions = "unstable";
|
||||||
src = lib.cleanSource ./.;
|
src = lib.cleanSource ./.;
|
||||||
nativeBuildInputs = [ openssl ];
|
nativeBuildInputs = [ openssl ];
|
||||||
nimbleDepsHash = "sha256-KErXGNNU5VVBHcvBmBhbagxZabHzajY5dF2OLHPmWf8=";
|
nimbleDepsHash = "sha256-WeTbNoF+TuzWriqoHWk5DBVgBXtNBIBHMkwy8/+a2JA=";
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,16 @@
|
||||||
"checksums": {
|
"checksums": {
|
||||||
"sha1": "6aeb83e7481ca8686396a568096054bc668294df"
|
"sha1": "6aeb83e7481ca8686396a568096054bc668294df"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"zippy": {
|
||||||
|
"version": "0.10.16",
|
||||||
|
"vcsRevision": "a99f6a7d8a8e3e0213b3cad0daf0ea974bf58e3f",
|
||||||
|
"url": "https://github.com/guzba/zippy",
|
||||||
|
"downloadMethod": "git",
|
||||||
|
"dependencies": [],
|
||||||
|
"checksums": {
|
||||||
|
"sha1": "da3bb5ea388f980babcc29760348e2899d29a639"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tasks": {}
|
"tasks": {}
|
||||||
|
|
|
@ -13,4 +13,5 @@ bin = @["oizys"]
|
||||||
requires "nim >= 2.0.8"
|
requires "nim >= 2.0.8"
|
||||||
requires "cligen"
|
requires "cligen"
|
||||||
requires "jsony"
|
requires "jsony"
|
||||||
|
requires "zippy"
|
||||||
requires "https://github.com/daylinmorgan/bbansi#9a85d9e"
|
requires "https://github.com/daylinmorgan/bbansi#9a85d9e"
|
||||||
|
|
|
@ -46,24 +46,23 @@ overlay:
|
||||||
|
|
||||||
proc osCmd() =
|
proc osCmd() =
|
||||||
## nixos-rebuild
|
## nixos-rebuild
|
||||||
if len(rest) == 0: quit "please provide subcmd"
|
if len(rest) == 0: fatalQuit "please provide subcmd"
|
||||||
let subcmd = rest[0]
|
let subcmd = rest[0]
|
||||||
if subcmd notin nixosSubcmds:
|
if subcmd notin nixosSubcmds:
|
||||||
error (
|
fatalQuit(
|
||||||
&"unknown nixos-rebuild subcmd: {subcmd}\nexpected one of: \n" &
|
&"unknown nixos-rebuild subcmd: {subcmd}\nexpected one of: \n" &
|
||||||
nixosSubcmds.mapIt(" " & it).join("\n")
|
nixosSubcmds.mapIt(" " & it).join("\n")
|
||||||
); quit QuitFailure
|
)
|
||||||
nixosRebuild(subcmd, rest[1..^1])
|
nixosRebuild(subcmd, rest[1..^1])
|
||||||
|
|
||||||
proc ci(`ref`: string = "main") =
|
proc ci(`ref`: string = "main") =
|
||||||
## trigger GHA update flow
|
## trigger GHA update flow
|
||||||
if rest.len == 0:
|
if rest.len == 0: fatalQuit "expected workflow file name"
|
||||||
fatal "expected workflow file name"; quit QuitFailure
|
|
||||||
createDispatch(rest[0], `ref`)
|
createDispatch(rest[0], `ref`)
|
||||||
|
|
||||||
proc checkExes() =
|
proc checkExes() =
|
||||||
if findExe("nix") == "":
|
if findExe("nix") == "":
|
||||||
quit("oizys requires nix", QuitFailure)
|
fatalQuit "oizys requires nix"
|
||||||
|
|
||||||
proc `//`(t1: Table[string, string], t2: Table[string, string]): Table[string, string] =
|
proc `//`(t1: Table[string, string], t2: Table[string, string]): Table[string, string] =
|
||||||
# nix style shallow table merge
|
# nix style shallow table merge
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import std/[logging, os, strformat, strutils]
|
import std/[logging, os, strformat, strutils]
|
||||||
from std/nativesockets import getHostname
|
from std/nativesockets import getHostname
|
||||||
|
|
||||||
|
import ./logging
|
||||||
|
|
||||||
type
|
type
|
||||||
OizysContext* = object
|
OizysContext* = object
|
||||||
flake, host: string
|
flake, host: string
|
||||||
|
@ -24,8 +26,7 @@ var oc = initContext()
|
||||||
proc checkPath(s: string): string =
|
proc checkPath(s: string): string =
|
||||||
## fail if path doesn't exist
|
## fail if path doesn't exist
|
||||||
if not s.dirExists:
|
if not s.dirExists:
|
||||||
error fmt"flake path: {s} does not exist"
|
errorQuit fmt"flake path: {s} does not exist"
|
||||||
quit()
|
|
||||||
s
|
s
|
||||||
|
|
||||||
# public api -------------------------------------
|
# public api -------------------------------------
|
||||||
|
@ -44,6 +45,7 @@ proc updateContext*(
|
||||||
oc.flake =
|
oc.flake =
|
||||||
if flake.startsWith("github") or flake.startsWith("git+"): flake
|
if flake.startsWith("github") or flake.startsWith("git+"): flake
|
||||||
else: checkPath(flake.normalizedPath().absolutePath())
|
else: checkPath(flake.normalizedPath().absolutePath())
|
||||||
|
debug oc
|
||||||
|
|
||||||
proc getHosts*(): seq[string] = return oc.hosts
|
proc getHosts*(): seq[string] = return oc.hosts
|
||||||
proc getFlake*(): string = return oc.flake
|
proc getFlake*(): string = return oc.flake
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import std/[httpclient,logging, os, strformat, strutils, json]
|
import std/[httpclient,logging, os, strformat, strutils, json]
|
||||||
|
import ./logging
|
||||||
|
|
||||||
var ghToken = getEnv("GITHUB_TOKEN")
|
var ghToken = getEnv("GITHUB_TOKEN")
|
||||||
|
|
||||||
|
proc checkToken() {.inline.} =
|
||||||
|
if ghToken == "": fatalQuit "GITHUB_TOKEN not set"
|
||||||
|
|
||||||
#[curl -L \
|
#[curl -L \
|
||||||
-X POST \
|
-X POST \
|
||||||
-H "Accept: application/vnd.github+json" \
|
-H "Accept: application/vnd.github+json" \
|
||||||
|
@ -11,16 +15,17 @@ var ghToken = getEnv("GITHUB_TOKEN")
|
||||||
-d '{"ref":"topic-branch","inputs":{"name":"Mona the Octocat","home":"San Francisco, CA"}}'
|
-d '{"ref":"topic-branch","inputs":{"name":"Mona the Octocat","home":"San Francisco, CA"}}'
|
||||||
]#
|
]#
|
||||||
|
|
||||||
|
|
||||||
proc postGhApi(url: string, body: JsonNode) =
|
proc postGhApi(url: string, body: JsonNode) =
|
||||||
if ghToken == "": fatal "GITHUB_TOKEN not set"; quit QuitFailure
|
checkToken()
|
||||||
let client = newHttpClient()
|
let client = newHttpClient()
|
||||||
client.headers = newHttpHeaders({
|
client.headers = newHttpHeaders({
|
||||||
"Accept" : "application/vnd.github+json",
|
"Accept" : "application/vnd.github+json",
|
||||||
"Authorization" : fmt"Bearer {ghToken}",
|
"Authorization" : fmt"Bearer {ghToken}",
|
||||||
"X-GitHub-Api-Version": "2022-11-28",
|
"X-GitHub-Api-Version": "2022-11-28",
|
||||||
})
|
})
|
||||||
let response = client.post(url, body = $body)
|
|
||||||
try:
|
try:
|
||||||
|
let response = client.post(url, body = $body)
|
||||||
info fmt"Status: {response.code}"
|
info fmt"Status: {response.code}"
|
||||||
except:
|
except:
|
||||||
error "failed to get response code"
|
error "failed to get response code"
|
||||||
|
|
|
@ -19,3 +19,4 @@ restic-gdrive
|
||||||
gitea
|
gitea
|
||||||
lock
|
lock
|
||||||
code
|
code
|
||||||
|
comma-with-db
|
||||||
|
|
|
@ -106,3 +106,12 @@ method log*(logger: FancyConsoleLogger, level: Level, args: varargs[string, `$`]
|
||||||
|
|
||||||
proc addHandlers*(handler: Logger) =
|
proc addHandlers*(handler: Logger) =
|
||||||
handlers.add(handler)
|
handlers.add(handler)
|
||||||
|
|
||||||
|
template errorQuit*(args: varargs[string, `$`]) =
|
||||||
|
error args
|
||||||
|
quit QuitFailure
|
||||||
|
|
||||||
|
template fatalQuit*(args: varargs[string, `$`]) =
|
||||||
|
error args
|
||||||
|
quit QuitFailure
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import std/[
|
||||||
strutils, sugar, logging, tables
|
strutils, sugar, logging, tables
|
||||||
]
|
]
|
||||||
import bbansi, jsony
|
import bbansi, jsony
|
||||||
import ./[context, exec]
|
import ./[context, exec, logging]
|
||||||
|
|
||||||
|
|
||||||
proc nixCommand(cmd: string): string =
|
proc nixCommand(cmd: string): string =
|
||||||
|
@ -23,10 +23,9 @@ const nixosSubcmds* =
|
||||||
repl build-vm build-vm-with-bootloader list-generations""".splitWhitespace()
|
repl build-vm build-vm-with-bootloader list-generations""".splitWhitespace()
|
||||||
|
|
||||||
proc nixosRebuild*(subcmd: string, rest: seq[string] = @[]) =
|
proc nixosRebuild*(subcmd: string, rest: seq[string] = @[]) =
|
||||||
var cmd = fmt"sudo nixos-rebuild {subcmd} --flake {getFlake()} --log-format multiline"
|
|
||||||
if getHosts().len > 1:
|
if getHosts().len > 1:
|
||||||
error "nixos-rebuild only supports one host"
|
fatalQuit "nixos-rebuild only supports one host"
|
||||||
quit QuitFailure
|
var cmd = fmt"sudo nixos-rebuild {subcmd} --flake {getFlake()} --log-format multiline"
|
||||||
cmd.addArgs rest
|
cmd.addArgs rest
|
||||||
quitWithCmd cmd
|
quitWithCmd cmd
|
||||||
|
|
||||||
|
@ -77,8 +76,8 @@ proc parseDryRunOutput(err: string): DryRunOutput =
|
||||||
stderr.writeLine err
|
stderr.writeLine err
|
||||||
quit()
|
quit()
|
||||||
of 0:
|
of 0:
|
||||||
info "nothing to do";
|
info "nothing to do"
|
||||||
quit(QuitSuccess)
|
quit QuitSuccess
|
||||||
else:
|
else:
|
||||||
fatal "unexpected output from nix"
|
fatal "unexpected output from nix"
|
||||||
stderr.writeLine err
|
stderr.writeLine err
|
||||||
|
@ -88,7 +87,7 @@ proc parseDryRunOutput(err: string): DryRunOutput =
|
||||||
result.toFetch.sort(cmpDrv)
|
result.toFetch.sort(cmpDrv)
|
||||||
|
|
||||||
proc trunc(s: string, limit: int): string =
|
proc trunc(s: string, limit: int): string =
|
||||||
if s.len <= limit:
|
if s.len <= limit:
|
||||||
s
|
s
|
||||||
else:
|
else:
|
||||||
s[0..(limit-4)] & "..."
|
s[0..(limit-4)] & "..."
|
||||||
|
@ -175,9 +174,7 @@ proc writeDervationsToStepSummary(drvs: seq[string]) =
|
||||||
fmt"| {name} | {hash} |"
|
fmt"| {name} | {hash} |"
|
||||||
)
|
)
|
||||||
let summaryFilePath = getEnv("GITHUB_STEP_SUMMARY")
|
let summaryFilePath = getEnv("GITHUB_STEP_SUMMARY")
|
||||||
if summaryFilePath == "":
|
if summaryFilePath == "": fatalQuit "no github step summary found"
|
||||||
fatal "no github step summary found"
|
|
||||||
quit QuitFailure
|
|
||||||
let output = open(summaryFilePath,fmAppend)
|
let output = open(summaryFilePath,fmAppend)
|
||||||
output.writeLine("| derivation | hash |\n|---|---|")
|
output.writeLine("| derivation | hash |\n|---|---|")
|
||||||
output.writeLine(rows.join("\n"))
|
output.writeLine(rows.join("\n"))
|
||||||
|
@ -217,7 +214,7 @@ proc nixBuildHostDry*(minimal: bool, rest: seq[string]) =
|
||||||
cmd.addArg "--dry-run"
|
cmd.addArg "--dry-run"
|
||||||
cmd.addArgs rest
|
cmd.addArgs rest
|
||||||
let (_, err) =
|
let (_, err) =
|
||||||
runCmdCaptWithSpinner(cmd, "evaluating derivation for: " & getHosts().join(" "))
|
runCmdCaptWithSpinner(cmd, "evaluating derivation for: " & getHosts().join(" "), {CaptStderr})
|
||||||
let output = parseDryRunOutput err
|
let output = parseDryRunOutput err
|
||||||
display output
|
display output
|
||||||
|
|
||||||
|
@ -226,8 +223,7 @@ template `bbfmt`(pattern: static string): untyped =
|
||||||
bb(fmt(pattern))
|
bb(fmt(pattern))
|
||||||
|
|
||||||
proc nixBuildWithCache*(minimal: bool, name: string, rest:seq[string]) =
|
proc nixBuildWithCache*(minimal: bool, name: string, rest:seq[string]) =
|
||||||
if findExe("cachix") == "":
|
if findExe("cachix") == "": fatalQuit "is cachix installed?"
|
||||||
fatal "is cachix installed?"; quit QuitFailure
|
|
||||||
info bbfmt"building and pushing to cache: [b]{name}"
|
info bbfmt"building and pushing to cache: [b]{name}"
|
||||||
var cmd = "cachix"
|
var cmd = "cachix"
|
||||||
cmd.addArgs ["watch-exec","--"]
|
cmd.addArgs ["watch-exec","--"]
|
||||||
|
|
|
@ -1,49 +1,6 @@
|
||||||
import std/[os, locks, sequtils, terminal]
|
import std/[os, locks, sequtils, terminal]
|
||||||
|
|
||||||
# https://github.com/molnarmark/colorize
|
import bbansi
|
||||||
proc reset(): string = "\e[0m"
|
|
||||||
|
|
||||||
# foreground colors
|
|
||||||
proc fgRed*(s: string): string = "\e[31m" & s & reset()
|
|
||||||
proc fgBlack*(s: string): string = "\e[30m" & s & reset()
|
|
||||||
proc fgGreen*(s: string): string = "\e[32m" & s & reset()
|
|
||||||
proc fgYellow*(s: string): string = "\e[33m" & s & reset()
|
|
||||||
proc fgBlue*(s: string): string = "\e[34m" & s & reset()
|
|
||||||
proc fgMagenta*(s: string): string = "\e[35m" & s & reset()
|
|
||||||
proc fgCyan*(s: string): string = "\e[36m" & s & reset()
|
|
||||||
proc fgLightGray*(s: string): string = "\e[37m" & s & reset()
|
|
||||||
proc fgDarkGray*(s: string): string = "\e[90m" & s & reset()
|
|
||||||
proc fgLightRed*(s: string): string = "\e[91m" & s & reset()
|
|
||||||
proc fgLightGreen*(s: string): string = "\e[92m" & s & reset()
|
|
||||||
proc fgLightYellow*(s: string): string = "\e[93m" & s & reset()
|
|
||||||
proc fgLightBlue*(s: string): string = "\e[94m" & s & reset()
|
|
||||||
proc fgLightMagenta*(s: string): string = "\e[95m" & s & reset()
|
|
||||||
proc fgLightCyan*(s: string): string = "\e[96m" & s & reset()
|
|
||||||
proc fgWhite*(s: string): string = "\e[97m" & s & reset()
|
|
||||||
|
|
||||||
# background colors
|
|
||||||
proc bgBlack*(s: string): string = "\e[40m" & s & reset()
|
|
||||||
proc bgRed*(s: string): string = "\e[41m" & s & reset()
|
|
||||||
proc bgGreen*(s: string): string = "\e[42m" & s & reset()
|
|
||||||
proc bgYellow*(s: string): string = "\e[43m" & s & reset()
|
|
||||||
proc bgBlue*(s: string): string = "\e[44m" & s & reset()
|
|
||||||
proc bgMagenta*(s: string): string = "\e[45m" & s & reset()
|
|
||||||
proc bgCyan*(s: string): string = "\e[46m" & s & reset()
|
|
||||||
proc bgLightGray*(s: string): string = "\e[47m" & s & reset()
|
|
||||||
proc bgDarkGray*(s: string): string = "\e[100m" & s & reset()
|
|
||||||
proc bgLightRed*(s: string): string = "\e[101m" & s & reset()
|
|
||||||
proc bgLightGreen*(s: string): string = "\e[102m" & s & reset()
|
|
||||||
proc bgLightYellow*(s: string): string = "\e[103m" & s & reset()
|
|
||||||
proc bgLightBlue*(s: string): string = "\e[104m" & s & reset()
|
|
||||||
proc bgLightMagenta*(s: string): string = "\e[105m" & s & reset()
|
|
||||||
proc bgLightCyan*(s: string): string = "\e[106m" & s & reset()
|
|
||||||
proc bgWhite*(s: string): string = "\e[107m" & s & reset()
|
|
||||||
|
|
||||||
# formatting functions
|
|
||||||
proc bold*(s: string): string = "\e[1m" & s & reset()
|
|
||||||
proc underline*(s: string): string = "\e[4m" & s & reset()
|
|
||||||
proc hidden*(s: string): string = "\e[8m" & s & reset()
|
|
||||||
proc invert*(s: string): string = "\e[7m" & s & reset()
|
|
||||||
|
|
||||||
type
|
type
|
||||||
SpinnerKind* = enum
|
SpinnerKind* = enum
|
||||||
|
@ -71,10 +28,10 @@ type
|
||||||
frame: string
|
frame: string
|
||||||
interval: int
|
interval: int
|
||||||
customSymbol: bool
|
customSymbol: bool
|
||||||
|
style: string
|
||||||
|
|
||||||
EventKind = enum
|
EventKind = enum
|
||||||
Stop, StopSuccess, StopError,
|
Stop, SymbolChange, TextChange,
|
||||||
SymbolChange, TextChange,
|
|
||||||
|
|
||||||
SpinnyEvent = object
|
SpinnyEvent = object
|
||||||
kind: EventKind
|
kind: EventKind
|
||||||
|
@ -83,19 +40,21 @@ type
|
||||||
var spinnyChannel: Channel[SpinnyEvent]
|
var spinnyChannel: Channel[SpinnyEvent]
|
||||||
|
|
||||||
proc newSpinny*(text: string, s: Spinner): Spinny =
|
proc newSpinny*(text: string, s: Spinner): Spinny =
|
||||||
|
let style = "bold blue"
|
||||||
Spinny(
|
Spinny(
|
||||||
text: text,
|
text: text,
|
||||||
running: true,
|
running: true,
|
||||||
frames: s.frames,
|
frames: mapIt(s.frames, $bb(it, style)),
|
||||||
customSymbol: false,
|
customSymbol: false,
|
||||||
interval: s.interval
|
interval: s.interval,
|
||||||
|
style: "bold blue"
|
||||||
)
|
)
|
||||||
|
|
||||||
proc newSpinny*(text: string, spinType: SpinnerKind): Spinny =
|
proc newSpinny*(text: string, spinType: SpinnerKind): Spinny =
|
||||||
newSpinny(text, Spinners[spinType])
|
newSpinny(text, Spinners[spinType])
|
||||||
|
|
||||||
proc setSymbolColor*(spinny: Spinny, color: proc(x: string): string) =
|
proc setSymbolColor*(spinny: Spinny, style: string) =
|
||||||
spinny.frames = mapIt(spinny.frames, color(it))
|
spinny.frames = mapIt(spinny.frames, $bb(it, style))
|
||||||
|
|
||||||
proc setSymbol*(spinny: Spinny, symbol: string) =
|
proc setSymbol*(spinny: Spinny, symbol: string) =
|
||||||
spinnyChannel.send(SpinnyEvent(kind: SymbolChange, payload: symbol))
|
spinnyChannel.send(SpinnyEvent(kind: SymbolChange, payload: symbol))
|
||||||
|
@ -113,14 +72,6 @@ proc handleEvent(spinny: Spinny, eventData: SpinnyEvent): bool =
|
||||||
spinny.frame = eventData.payload
|
spinny.frame = eventData.payload
|
||||||
of TextChange:
|
of TextChange:
|
||||||
spinny.text = eventData.payload
|
spinny.text = eventData.payload
|
||||||
of StopSuccess:
|
|
||||||
spinny.customSymbol = true
|
|
||||||
spinny.frame = "✔".bold.fgGreen
|
|
||||||
spinny.text = eventData.payload.bold.fgGreen
|
|
||||||
of StopError:
|
|
||||||
spinny.customSymbol = true
|
|
||||||
spinny.frame = "✖".bold.fgRed
|
|
||||||
spinny.text = eventData.payload.bold.fgRed
|
|
||||||
|
|
||||||
proc spinnyLoop(spinny: Spinny) {.thread.} =
|
proc spinnyLoop(spinny: Spinny) {.thread.} =
|
||||||
var frameCounter = 0
|
var frameCounter = 0
|
||||||
|
@ -147,7 +98,7 @@ proc spinnyLoop(spinny: Spinny) {.thread.} =
|
||||||
stdout.write(spinny.frame & " " & spinny.text)
|
stdout.write(spinny.frame & " " & spinny.text)
|
||||||
stdout.flushFile()
|
stdout.flushFile()
|
||||||
|
|
||||||
sleep(spinny.interval)
|
sleep spinny.interval
|
||||||
|
|
||||||
if frameCounter >= spinny.frames.len - 1:
|
if frameCounter >= spinny.frames.len - 1:
|
||||||
frameCounter = 0
|
frameCounter = 0
|
||||||
|
@ -155,14 +106,14 @@ proc spinnyLoop(spinny: Spinny) {.thread.} =
|
||||||
frameCounter += 1
|
frameCounter += 1
|
||||||
|
|
||||||
proc start*(spinny: Spinny) =
|
proc start*(spinny: Spinny) =
|
||||||
initLock(spinny.lock)
|
initLock spinny.lock
|
||||||
spinnyChannel.open()
|
spinnyChannel.open()
|
||||||
createThread(spinny.t, spinnyLoop, spinny)
|
createThread(spinny.t, spinnyLoop, spinny)
|
||||||
|
|
||||||
proc stop(spinny: Spinny, kind: EventKind, payload = "") =
|
proc stop(spinny: Spinny, kind: EventKind, payload = "") =
|
||||||
spinnyChannel.send(SpinnyEvent(kind: kind, payload: payload))
|
spinnyChannel.send(SpinnyEvent(kind: kind, payload: payload))
|
||||||
spinnyChannel.send(SpinnyEvent(kind: Stop))
|
spinnyChannel.send(SpinnyEvent(kind: Stop))
|
||||||
joinThread(spinny.t)
|
joinThread spinny.t
|
||||||
eraseLine stdout
|
eraseLine stdout
|
||||||
flushFile stdout
|
flushFile stdout
|
||||||
|
|
||||||
|
@ -170,15 +121,8 @@ proc stop(spinny: Spinny, kind: EventKind, payload = "") =
|
||||||
proc stop*(spinny: Spinny) =
|
proc stop*(spinny: Spinny) =
|
||||||
spinny.stop(Stop)
|
spinny.stop(Stop)
|
||||||
|
|
||||||
proc success*(spinny: Spinny, msg: string) =
|
|
||||||
spinny.stop(StopSuccess, msg)
|
|
||||||
|
|
||||||
proc error*(spinny: Spinny, msg: string) =
|
|
||||||
spinny.stop(StopError, msg)
|
|
||||||
|
|
||||||
template withSpinner*(msg: string = "", body: untyped): untyped =
|
template withSpinner*(msg: string = "", body: untyped): untyped =
|
||||||
var spinner {.inject.} = newSpinny(msg, Dots)
|
var spinner {.inject.} = newSpinny(msg, Dots)
|
||||||
spinner.setSymbolColor(fgBlue)
|
|
||||||
if isatty(stdout): # don't spin if it's not a tty
|
if isatty(stdout): # don't spin if it's not a tty
|
||||||
start spinner
|
start spinner
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
- [x] nix commands including dry runs
|
- [x] nix commands including dry runs
|
||||||
- [ ] gh api commands
|
- [ ] gh api commands
|
||||||
- [ ] ci <- start with the easier one
|
- [x] ci <- start with the easier one
|
||||||
- [ ] update
|
- [ ] update
|
||||||
|
|
||||||
<!-- generated with <3 by daylinmorgan/todo -->
|
<!-- generated with <3 by daylinmorgan/todo -->
|
||||||
|
|
Loading…
Reference in a new issue