domain/architecture/system/plan/ops.bend

near-v-framework@0.3.0.2 · 104 lines · 0 definitions

1import Base
2import near-v-framework@0.3.0.2/domain/architecture/system/release/type.bend as Rl
3import near-v-framework@0.3.0.2/domain/architecture/system/release/ops.bend as RlO
4import near-v-framework@0.3.0.2/domain/architecture/system/plan/type.bend as P
5
6def visibility(p: Bool) -> String:
7  match p:
8    case True{}:
9      "public"
10    case False{}:
11      "private"
12
13# Bend hub rules apply to Bend packages, not to an application's whole repository.
14def repo_steps(+fs: List<&2, String>, +reached: List<&2, String>, +package_reached: List<&2, String>, ps: List<&2, Rl.Package>) -> List<&2, P.Step>:
15  match ps:
16    case []:
17      []
18    case _ <> _:
19      List.append(&2, P.Step,
20        Bool.pick(List<&2, P.Step>, String.is_empty(RlO.not_bend(package_reached)), [],
21          [P.Blocked{"package", RlO.not_bend(package_reached) ++ " is not Bend or a C/JavaScript effector"}]),
22        List.append(&2, P.Step,
23          Bool.pick(List<&2, P.Step>, Bool.not(RlO.bend_only(fs)) || String.is_empty(RlO.dead(fs, reached)), [],
24            [P.Blocked{"repository", RlO.dead(fs, reached) ++ " is dead code: no entry reaches it"}]),
25          Bool.pick(List<&2, P.Step>, String.is_empty(RlO.hub_refused(package_reached)), [],
26            [P.Blocked{"package", RlO.hub_refused(package_reached) ++ ": the Bend hub refuses this path (segments of letters, digits and _)"}])))
27
28def remote_step(+repo: Rl.Repository, rm: P.Remote) -> P.Step:
29  match repo rm:
30    case Rl.Repository{+name, +public} P.Remote{+origin, +vis, clean, pushed}:
31      Bool.pick(P.Step, String.contains(origin, name),
32        Bool.pick(P.Step, String.eq(vis, visibility(public)),
33          Bool.pick(P.Step, clean,
34            Bool.pick(P.Step, pushed, P.Current{"github " ++ name}, P.Push{name}),
35            P.Blocked{"github " ++ name, "uncommitted changes"}),
36          P.Blocked{"github " ++ name, "GitHub says " ++ Bool.pick(String, String.is_empty(vis), "nothing (unreachable)", vis) ++ ", declared " ++ visibility(public)}),
37        P.Blocked{"github " ++ name, "origin is " ++ origin})
38
39# ---- each package: already published as it is, new, or changed without a new version ----
40def package_step(p: Rl.Package, h: P.Hub) -> P.Step:
41  match p:
42    case Rl.Package{+n, +v, e, _}:
43      match h:
44        case P.Same{}:
45          P.Current{"package " ++ n ++ "@" ++ v}
46        case P.Unpublished{}:
47          P.Publish{n, v, e}
48        case P.Differs{f}:
49          P.Blocked{"package " ++ n ++ "@" ++ v, f ++ " changed since it was published; give it a new version"}
50
51def package_steps(ps: List<&2, Rl.Package>, hs: List<&2, P.Hub>) -> List<&2, P.Step>:
52  match ps:
53    case []:
54      []
55    case p <> prest:
56      match hs:
57        case []:
58          []
59        case h <> hrest:
60          package_step(p, h) <> package_steps(prest, hrest)
61
62# The plan: what a deploy would do, from the release and what was observed.
63def plan(r: Rl.Release, o: P.Observed) -> List<&2, P.Step>:
64  match r o:
65    case Rl.Release{repo, +ps} P.Observed{+fs, +reached, +package_reached, hs, rm}:
66      List.append(&2, P.Step, repo_steps(fs, reached, package_reached, ps), List.append(&2, P.Step, package_steps(ps, hs), [remote_step(repo, rm)]))
67
68def blocked(s: P.Step) -> Bool:
69  match s:
70    case P.Blocked{_, _}:
71      True{}
72    case _:
73      False{}
74
75def any_blocked(ss: List<&2, P.Step>) -> Bool:
76  match ss:
77    case []:
78      False{}
79    case s <> rest:
80      blocked(s) || any_blocked(rest)
81
82def show(s: P.Step) -> String:
83  match s:
84    case P.Current{w}:
85      "current  " ++ w
86    case P.Publish{n, v, _}:
87      "publish  " ++ n ++ "@" ++ v
88    case P.Push{r}:
89      "push     github " ++ r
90    case P.Rebuild{h, _, _}:
91      "rebuild  nix-darwin " ++ h
92    case P.ServePort{p, t, _}:
93      "serve    :" ++ U32.show(p) ++ " -> " ++ t
94    case P.Change{w, now, want}:
95      "change   " ++ w ++ ": " ++ now ++ " -> " ++ want
96    case P.Blocked{w, why}:
97      "blocked  " ++ w ++ ": " ++ why
98
99def show_all(ss: List<&2, P.Step>) -> String:
100  match ss:
101    case []:
102      ""
103    case s <> rest:
104      show(s) ++ "\n" ++ show_all(rest)