domain/architecture/system/release/ops.bend
near-v-framework@0.4.0.0 · 181 lines · 26 definitions
1import Base
2import near-v-framework@0.4.0.0/domain/architecture/system/release/type.bend as Rl
3
4
5def digits_only(cs: List<&2, Char>) -> Bool:
6 match cs:
7 case []:
8 True{}
9 case c <> rest:
10 Char.is_digit(c) && digits_only(rest)
11
12def all_numbers(xs: List<&2, String>) -> Bool:
13 match xs:
14 case []:
15 True{}
16 case +x <> rest:
17 Bool.not(String.is_empty(x)) && digits_only(String.to_list(x)) && all_numbers(rest)
18
19def name_chars(cs: List<&2, Char>) -> Bool:
20 match cs:
21 case []:
22 True{}
23 case +c <> rest:
24 (Char.is_lower(c) || Char.is_digit(c) || Char.is_eq(c, '-')) && name_chars(rest)
25
26def package_ok(p: Rl.Package) -> Bool:
27 match p:
28 case Rl.Package{+n, +v, _, _}:
29 Nat.is_ge(String.length(n), 12n) && Nat.is_le(String.length(n), 64n) && name_chars(String.to_list(n)) &&
30 Nat.is_eq(List.length(&2, String, String.split(v, '.')), 4n) && all_numbers(String.split(v, '.'))
31
32def packages_ok(ps: List<&2, Rl.Package>) -> Bool:
33 match ps:
34 case []:
35 True{}
36 case p <> rest:
37 package_ok(p) && packages_ok(rest)
38
39def packages(r: Rl.Release) -> List<&2, Rl.Package>:
40 match r:
41 case Rl.Release{_, ps, _}:
42 ps
43
44def plugins(r: Rl.Release) -> List<&2, Rl.Plugin>:
45 match r:
46 case Rl.Release{_, _, gs}:
47 gs
48
49def repository(r: Rl.Release) -> Rl.Repository:
50 match r:
51 case Rl.Release{repo, _, _}:
52 repo
53
54def is_public(r: Rl.Release) -> Bool:
55 match r:
56 case Rl.Release{repo, _, _}:
57 match repo:
58 case Rl.Repository{_, p}:
59 p
60
61
62def shipped_components(ps: List<&2, Rl.Package>) -> List<&2, String>:
63 match ps:
64 case []:
65 []
66 case p <> rest:
67 match p:
68 case Rl.Package{_, _, _, cs}:
69 List.append(&2, String, cs, shipped_components(rest))
70
71
72def entries(ps: List<&2, Rl.Package>) -> List<&2, String>:
73 match ps:
74 case []:
75 []
76 case p <> rest:
77 match p:
78 case Rl.Package{_, _, e, _}:
79 e <> entries(rest)
80
81
82def plugin_entries(gs: List<&2, Rl.Plugin>) -> List<&2, String>:
83 match gs:
84 case []:
85 []
86 case g <> rest:
87 match g:
88 case Rl.Plugin{_, _, e, _, _}:
89 e <> plugin_entries(rest)
90
91
92def plugin_components(gs: List<&2, Rl.Plugin>) -> List<&2, String>:
93 match gs:
94 case []:
95 []
96 case g <> rest:
97 match g:
98 case Rl.Plugin{_, _, _, cs, _}:
99 List.append(&2, String, cs, plugin_components(rest))
100
101
102
103def is_source(+f: String) -> Bool:
104 String.ends_with(f, ".bend") || String.ends_with(f, ".c") || String.ends_with(f, ".js")
105
106def base_name(f: String) -> String:
107 Maybe.default(&2, String, List.head(&2, String, List.reverse(&2, String, String.split(f, '/'))), "")
108
109
110def allowed(+f: String) -> Bool:
111 is_source(f) || String.eq(base_name(f), "LICENSE") || String.eq(f, "README.md") || String.eq(f, ".gitignore")
112
113def bend_only(fs: List<&2, String>) -> Bool:
114 match fs:
115 case []:
116 True{}
117 case +f <> rest:
118 allowed(f) && bend_only(rest)
119
120
121def no_dead_code(fs: List<&2, String>, +reached: List<&2, String>) -> Bool:
122 match fs:
123 case []:
124 True{}
125 case +f <> rest:
126 (Bool.not(is_source(f)) || List.contains(~String, ~String.eq, reached, f)) && no_dead_code(rest, reached)
127
128
129def dead(fs: List<&2, String>, +reached: List<&2, String>) -> String:
130 match fs:
131 case []:
132 ""
133 case +f <> rest:
134 Bool.pick(String, is_source(f) && Bool.not(List.contains(~String, ~String.eq, reached, f)), f, dead(rest, reached))
135
136
137def not_bend(fs: List<&2, String>) -> String:
138 match fs:
139 case []:
140 ""
141 case +f <> rest:
142 Bool.pick(String, allowed(f), not_bend(rest), f)
143
144
145
146def name_char(+c: Char, first: Bool) -> Bool:
147 Char.is_lower(c) || Char.is_upper(c) || Char.is_eq(c, '_') || (Bool.not(first) && Char.is_digit(c))
148
149def name_chars_ok(cs: List<&2, Char>, first: Bool) -> Bool:
150 match cs:
151 case []:
152 Bool.not(first)
153 case +c <> rest:
154 name_char(c, first) && name_chars_ok(rest, False{})
155
156def stem(+f: String) -> String:
157 Bool.pick(String, String.ends_with(f, ".bend"), String.take(f, Nat.sub(String.length(f), 5n)),
158 Bool.pick(String, String.ends_with(f, ".js"), String.take(f, Nat.sub(String.length(f), 3n)),
159 Bool.pick(String, String.ends_with(f, ".c"), String.take(f, Nat.sub(String.length(f), 2n)), f)))
160
161def segments_ok(ss: List<&2, String>) -> Bool:
162 match ss:
163 case []:
164 True{}
165 case +s <> rest:
166 match rest:
167 case []:
168 String.eq(s, "LICENSE") || (is_source(s) && name_chars_ok(String.to_list(stem(s)), True{}))
169 case _ <> _:
170 name_chars_ok(String.to_list(s), True{}) && segments_ok(rest)
171
172def hub_path_ok(+f: String) -> Bool:
173 Nat.is_lt(String.length(f), 256n) && segments_ok(String.split(f, '/'))
174
175
176def hub_refused(fs: List<&2, String>) -> String:
177 match fs:
178 case []:
179 ""
180 case +f <> rest:
181 Bool.pick(String, hub_path_ok(f), hub_refused(rest), f)