cli/project.bend

near-v-framework@0.2.0.0 · 109 lines · 0 definitions

1import Base
2import near-v-framework@0.2.0.0/lib/effs/io.bend as X
3import near-v-framework@0.2.0.0/lib/vstr.bend as S
4
5# The project `v` runs in: the current folder. Its own Bend programs (facts, plan, flake, laws...)
6# are compiled and run from there.
7
8# Compile one of the project's Bend programs to a native binary, then run it; answers its output.
9def run_bend(+file: String) -> IO(String):
10  X.sh("$HOME/.bend/bin/bend " ++ file ++ " -o /tmp/v-" ++ file ++ ".bin >/dev/null 2>&1 && /tmp/v-" ++ file ++ ".bin")
11
12# Type-check a Bend file (the laws); nothing is run.
13def check_bend(file: String) -> IO(String):
14  X.sh("$HOME/.bend/bin/bend " ++ file ++ " 2>&1 || true")
15
16# ---- the project's facts (facts.bend): where V's library is, its targets, services and packages ----
17type Facts is Data:
18  Facts{vlib: String, targets: List<&2, String>, labels: List<&2, String>, ports: List<&2, String>, packages: List<&2, String>, sources: List<&2, String>}
19
20def fact_values(+k: String, ls: List<&2, String>) -> List<&2, String>:
21  match ls:
22    case []:
23      []
24    case +l <> rest:
25      S.append(S.line_if(String.starts_with(l, k ++ " "), String.drop(l, Nat.add(String.length(k), 1n))), fact_values(k, rest))
26
27def read_facts() -> IO(Facts):
28  do IO<Facts>:
29    out : String <- run_bend("facts.bend")
30    +ls : List<&2, String> = String.lines(out)
31    return Facts{S.nth(fact_values("vlib", ls), 0n), fact_values("target", ls), fact_values("label", ls), fact_values("port", ls), fact_values("package", ls), fact_values("source", ls)}
32
33def vlib_of(f: Facts) -> String:
34  match f:
35    case Facts{v, _, _, _, _, _}:
36      v
37
38def targets_of(f: Facts) -> List<&2, String>:
39  match f:
40    case Facts{_, t, _, _, _, _}:
41      t
42
43def labels_of(f: Facts) -> List<&2, String>:
44  match f:
45    case Facts{_, _, l, _, _, _}:
46      l
47
48def ports_of(f: Facts) -> List<&2, String>:
49  match f:
50    case Facts{_, _, _, p, _, _}:
51      p
52
53def packages_of(f: Facts) -> List<&2, String>:
54  match f:
55    case Facts{_, _, _, _, p, _}:
56      p
57
58def sources_of(f: Facts) -> List<&2, String>:
59  match f:
60    case Facts{_, _, _, _, _, sources}:
61      sources
62
63def target_hit(+name: String, ts: List<&2, String>) -> Bool:
64  match ts:
65    case []:
66      False{}
67    case +t <> rest:
68      String.eq(S.nth(S.words(t), 0n), name) || target_hit(name, rest)
69
70# Whether the project declares a target ("nix-darwin", "tailscale-serve", "bend-hub").
71def has_target(+f: Facts, +name: String) -> Bool:
72  target_hit(name, targets_of(f))
73
74def host_in(+name: String, ts: List<&2, String>) -> String:
75  match ts:
76    case []:
77      ""
78    case +t <> rest:
79      S.pick(String.eq(S.nth(S.words(t), 0n), name), S.nth(S.words(t), 1n), host_in(name, rest))
80
81# The nix-darwin flake host ("" without a nix-darwin target).
82def flake_host(+f: Facts) -> String:
83  host_in("nix-darwin", targets_of(f))
84
85def github_repo(+f: Facts) -> String:
86  host_in("github", targets_of(f))
87
88def target_arg(+name: String, +index: Nat, ts: List<&2, String>) -> String:
89  match ts:
90    case []:
91      ""
92    case +t <> rest:
93      S.pick(String.eq(S.nth(S.words(t), 0n), name), S.nth(S.words(t), index), target_arg(name, index, rest))
94
95def github_visibility(+f: Facts) -> String:
96  target_arg("github", 2n, targets_of(f))
97
98def azure_organization(+f: Facts) -> String:
99  target_arg("azure", 1n, targets_of(f))
100
101def azure_project(+f: Facts) -> String:
102  target_arg("azure", 2n, targets_of(f))
103
104def when(c: Bool, act: IO(Unit)) -> IO(Unit):
105  match c:
106    case True{}:
107      act
108    case False{}:
109      IO.pure(Unit, Unit{})