cli/project.bend
near-v-framework@0.1.0.0 · 109 lines · 0 definitions
1import Base
2import near-v-framework@0.1.0.0/lib/effs/io.bend as X
3import near-v-framework@0.1.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{})