Fork of daniellemaywood.uk/gleam — Wasm codegen work
3.3 kB
138 lines
1import gleam/io
2import gleam/list
3import gleam/set.{type Set}
4import gleam/string
5import shellout
6import simplifile
7import tom
8
9pub fn main() -> Nil {
10 let gleam_crates = determine_gleam_crates()
11 let active_licences = determine_licences()
12
13 let assert Ok(output) =
14 shellout.command(
15 run: "cargo",
16 with: [
17 "tree",
18 "--format",
19 "{p} {l}",
20 "--edges",
21 "no-dev,no-build,no-proc-macro",
22 ],
23 in: "..",
24 opt: [],
25 )
26
27 let lines =
28 output
29 |> string.split("\n")
30 |> list.filter(fn(line) { line != "" })
31 |> list.map(trim_line_prefix)
32 |> list.map(crate_information(_, active_licences))
33 |> list.filter(is_dependency(_, gleam_crates))
34 |> set.from_list
35 |> set.to_list
36 |> list.map(string.inspect)
37
38 io.println(string.join(lines, "\n"))
39 Nil
40}
41
42fn determine_licences() -> Set(String) {
43 let assert Ok(files) = simplifile.read_directory("../licences")
44 files
45 |> list.map(string.remove_suffix(_, ".txt"))
46 |> set.from_list
47}
48
49fn is_dependency(crate: Crate, gleam_crates: Set(String)) -> Bool {
50 !set.contains(gleam_crates, crate.name)
51}
52
53fn determine_gleam_crates() -> Set(String) {
54 let assert Ok(toml) = simplifile.read("../Cargo.toml")
55 let assert Ok(config) = tom.parse(toml)
56 let assert Ok(crates) = tom.get_array(config, ["workspace", "members"])
57 let assert Ok(paths) = list.try_map(crates, tom.as_string)
58 let crates =
59 list.map(paths, fn(path) {
60 let assert Ok(toml) = simplifile.read("../" <> path <> "/Cargo.toml")
61 let assert Ok(config) = tom.parse(toml)
62 let assert Ok(name) = tom.get_string(config, ["package", "name"])
63 name
64 })
65 set.from_list(crates)
66}
67
68type Crate {
69 Crate(
70 name: String,
71 version: String,
72 licence_identifier: String,
73 used_licences: List(String),
74 )
75}
76
77fn crate_information(line: String, active_licences: Set(String)) -> Crate {
78 let line = string.remove_suffix(line, " (*)")
79 let assert [name, version, ..licence_parts] = string.split(line, " ")
80 let licence_identifier = string.join(licence_parts, " ")
81 let used_licences =
82 licence_identifier
83 |> string.split(" OR ")
84 |> list.flat_map(string.split(_, " AND "))
85 |> list.flat_map(string.split(_, "/"))
86 |> list.map(string.remove_prefix(_, "("))
87 |> list.map(string.remove_suffix(_, ")"))
88 |> list.filter(set.contains(active_licences, _))
89 Crate(name:, version:, licence_identifier:, used_licences:)
90}
91
92/// Convert lines like these:
93///
94/// ```txt
95/// │ └── wasm-bindgen v0.2.106 MIT OR Apache-2.0
96/// ```
97///
98/// into lines like these
99///
100/// ```txt
101/// wasm-bindgen v0.2.106 MIT OR Apache-2.0
102/// ```
103///
104fn trim_line_prefix(line: String) -> String {
105 case line {
106 " " <> line | "│" <> line | "─" <> line | "├" <> line | "└" <> line ->
107 trim_line_prefix(line)
108
109 ""
110 | "a" <> _
111 | "b" <> _
112 | "c" <> _
113 | "d" <> _
114 | "e" <> _
115 | "f" <> _
116 | "g" <> _
117 | "h" <> _
118 | "i" <> _
119 | "j" <> _
120 | "k" <> _
121 | "l" <> _
122 | "m" <> _
123 | "n" <> _
124 | "o" <> _
125 | "p" <> _
126 | "q" <> _
127 | "r" <> _
128 | "s" <> _
129 | "t" <> _
130 | "u" <> _
131 | "v" <> _
132 | "w" <> _
133 | "x" <> _
134 | "y" <> _
135 | "z" <> _ -> line
136 _ -> panic as { "Unexpected line prefix: " <> string.inspect(line) }
137 }
138}