| author | |
| committer | |
| log | 7468b49d771010ac9ed02fcf6ca03069651342d5 |
| tree | f88e00cac084107f510def0fdf25035b2d6352c2 |
| parent | 3d228ccdc54576621743e4a74f274b97210073ff |
11 files changed, 467 insertions(+), 467 deletions(-)
src/cmd/fetch.zig created+239| ... | @@ -0,0 +1,239 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const gpa = std.heap.c_allocator; | ||
| 3 | const fs = std.fs; | ||
| 4 | |||
| 5 | const known_folders = @import("known-folders"); | ||
| 6 | const u = @import("./../util/index.zig"); | ||
| 7 | const common = @import("./../common.zig"); | ||
| 8 | |||
| 9 | // | ||
| 10 | // | ||
| 11 | |||
| 12 | pub fn execute(args: [][]u8) !void { | ||
| 13 | // | ||
| 14 | const dir = try fs.path.join(gpa, &.{".zigmod", "deps"}); | ||
| 15 | |||
| 16 | const top_module = try common.collect_deps(dir, "zig.mod", .{ | ||
| 17 | .log = true, | ||
| 18 | .update = true, | ||
| 19 | }); | ||
| 20 | |||
| 21 | // | ||
| 22 | const f = try fs.cwd().createFile("deps.zig", .{}); | ||
| 23 | defer f.close(); | ||
| 24 | |||
| 25 | const w = f.writer(); | ||
| 26 | try w.writeAll("const std = @import(\"std\");\n"); | ||
| 27 | try w.writeAll("const build = std.build;\n"); | ||
| 28 | try w.writeAll("\n"); | ||
| 29 | try w.print("pub const cache = \"{s}\";\n", .{std.zig.fmtEscapes(dir)}); | ||
| 30 | try w.writeAll("\n"); | ||
| 31 | try w.print("{s}\n", .{ | ||
| 32 | \\pub fn addAllTo(exe: *build.LibExeObjStep) void { | ||
| 33 | \\ @setEvalBranchQuota(1_000_000); | ||
| 34 | \\ for (packages) |pkg| { | ||
| 35 | \\ exe.addPackage(pkg); | ||
| 36 | \\ } | ||
| 37 | \\ if (c_include_dirs.len > 0 or c_source_files.len > 0) { | ||
| 38 | \\ exe.linkLibC(); | ||
| 39 | \\ } | ||
| 40 | \\ for (c_include_dirs) |dir| { | ||
| 41 | \\ exe.addIncludeDir(dir); | ||
| 42 | \\ } | ||
| 43 | \\ inline for (c_source_files) |fpath| { | ||
| 44 | \\ exe.addCSourceFile(fpath[1], @field(c_source_flags, fpath[0])); | ||
| 45 | \\ } | ||
| 46 | \\ for (system_libs) |lib| { | ||
| 47 | \\ exe.linkSystemLibrary(lib); | ||
| 48 | \\ } | ||
| 49 | \\} | ||
| 50 | \\ | ||
| 51 | \\fn get_flags(comptime index: usize) []const u8 { | ||
| 52 | \\ return @field(c_source_flags, _paths[index]); | ||
| 53 | \\} | ||
| 54 | \\ | ||
| 55 | }); | ||
| 56 | |||
| 57 | const list = &std.ArrayList(u.Module).init(gpa); | ||
| 58 | try common.collect_pkgs(top_module, list); | ||
| 59 | |||
| 60 | try w.writeAll("pub const _ids = .{\n"); | ||
| 61 | try print_ids(w, list.items); | ||
| 62 | try w.writeAll("};\n\n"); | ||
| 63 | |||
| 64 | try w.print("pub const _paths = {s}\n", .{".{"}); | ||
| 65 | try print_paths(w, list.items); | ||
| 66 | try w.writeAll("};\n\n"); | ||
| 67 | |||
| 68 | try w.writeAll("pub const package_data = struct {\n"); | ||
| 69 | const duped = &std.ArrayList(u.Module).init(gpa); | ||
| 70 | for (list.items) |mod| { | ||
| 71 | if (mod.main.len > 0 and mod.clean_path.len > 0) { | ||
| 72 | try duped.append(mod); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | try print_pkg_data_to(w, duped, &std.ArrayList(u.Module).init(gpa)); | ||
| 76 | try w.writeAll("};\n\n"); | ||
| 77 | |||
| 78 | try w.writeAll("pub const packages = "); | ||
| 79 | try print_deps(w, dir, top_module, 0, true); | ||
| 80 | try w.writeAll(";\n\n"); | ||
| 81 | |||
| 82 | try w.writeAll("pub const pkgs = "); | ||
| 83 | try print_deps(w, dir, top_module, 0, false); | ||
| 84 | try w.writeAll(";\n\n"); | ||
| 85 | |||
| 86 | try w.writeAll("pub const c_include_dirs = &[_][]const u8{\n"); | ||
| 87 | try print_incl_dirs_to(w, list.items); | ||
| 88 | try w.writeAll("};\n\n"); | ||
| 89 | |||
| 90 | try w.writeAll("pub const c_source_flags = struct {\n"); | ||
| 91 | try print_csrc_flags_to(w, list.items); | ||
| 92 | try w.writeAll("};\n\n"); | ||
| 93 | |||
| 94 | try w.writeAll("pub const c_source_files = &[_][2][]const u8{\n"); | ||
| 95 | try print_csrc_dirs_to(w, list.items); | ||
| 96 | try w.writeAll("};\n\n"); | ||
| 97 | |||
| 98 | try w.writeAll("pub const system_libs = &[_][]const u8{\n"); | ||
| 99 | try print_sys_libs_to(w, list.items, &std.ArrayList([]const u8).init(gpa)); | ||
| 100 | try w.writeAll("};\n\n"); | ||
| 101 | } | ||
| 102 | |||
| 103 | fn print_ids(w: fs.File.Writer, list: []u.Module) !void { | ||
| 104 | for (list) |mod| { | ||
| 105 | if (mod.is_sys_lib) { | ||
| 106 | continue; | ||
| 107 | } | ||
| 108 | try w.print(" \"{s}\",\n", .{mod.id}); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | fn print_paths(w: fs.File.Writer, list: []u.Module) !void { | ||
| 113 | for (list) |mod| { | ||
| 114 | if (mod.is_sys_lib) { | ||
| 115 | continue; | ||
| 116 | } | ||
| 117 | if (mod.clean_path.len == 0) { | ||
| 118 | try w.print(" \"\",\n", .{}); | ||
| 119 | } else { | ||
| 120 | const s = std.fs.path.sep_str; | ||
| 121 | try w.print(" \"{s}{s}{s}\",\n", .{std.zig.fmtEscapes(s), std.zig.fmtEscapes(mod.clean_path), std.zig.fmtEscapes(s)}); | ||
| 122 | } | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | fn print_deps(w: fs.File.Writer, dir: []const u8, m: u.Module, tabs: i32, array: bool) anyerror!void { | ||
| 127 | if (m.has_no_zig_deps() and tabs > 0) { | ||
| 128 | try w.print("null", .{}); | ||
| 129 | return; | ||
| 130 | } | ||
| 131 | if (array) { | ||
| 132 | try u.print_all(w, .{"&[_]build.Pkg{"}, true); | ||
| 133 | } else { | ||
| 134 | try u.print_all(w, .{"struct {"}, true); | ||
| 135 | } | ||
| 136 | const t = " "; | ||
| 137 | const r = try u.repeat(t, tabs); | ||
| 138 | for (m.deps) |d, i| { | ||
| 139 | if (d.main.len == 0) { | ||
| 140 | continue; | ||
| 141 | } | ||
| 142 | if (!array) { | ||
| 143 | try w.print(" pub const {s} = packages[{}];\n", .{std.mem.replaceOwned(u8, gpa, d.name, "-", "_"), i}); | ||
| 144 | } | ||
| 145 | else { | ||
| 146 | try w.print(" package_data._{s},\n", .{d.id}); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | try w.print("{s}", .{try u.concat(&.{r,"}"})}); | ||
| 150 | } | ||
| 151 | |||
| 152 | fn print_incl_dirs_to(w: fs.File.Writer, list: []u.Module) !void { | ||
| 153 | for (list) |mod, i| { | ||
| 154 | if (mod.is_sys_lib) { | ||
| 155 | continue; | ||
| 156 | } | ||
| 157 | for (mod.c_include_dirs) |it| { | ||
| 158 | if (i > 0) { | ||
| 159 | try w.print(" cache ++ _paths[{}] ++ \"{s}\",\n", .{i, std.zig.fmtEscapes(it)}); | ||
| 160 | } else { | ||
| 161 | try w.print(" \"{s}\",\n", .{std.zig.fmtEscapes(it)}); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | fn print_csrc_dirs_to(w: fs.File.Writer, list: []u.Module) !void { | ||
| 168 | for (list) |mod, i| { | ||
| 169 | if (mod.is_sys_lib) { | ||
| 170 | continue; | ||
| 171 | } | ||
| 172 | for (mod.c_source_files) |it| { | ||
| 173 | if (i > 0) { | ||
| 174 | try w.print(" {s}_ids[{}], cache ++ _paths[{}] ++ \"{s}\"{s},\n", .{"[_][]const u8{", i, i, it, "}"}); | ||
| 175 | } else { | ||
| 176 | try w.print(" {s}_ids[{}], \".{s}/{s}\"{s},\n", .{"[_][]const u8{", i, std.zig.fmtEscapes(mod.clean_path), it, "}"}); | ||
| 177 | } | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | fn print_csrc_flags_to(w: fs.File.Writer, list: []u.Module) !void { | ||
| 183 | for (list) |mod, i| { | ||
| 184 | if (mod.is_sys_lib) { | ||
| 185 | continue; | ||
| 186 | } | ||
| 187 | if (mod.c_source_flags.len == 0 and mod.c_source_files.len == 0) { | ||
| 188 | continue; | ||
| 189 | } | ||
| 190 | try w.print(" pub const @\"{s}\" = {s}", .{mod.id, "&.{"}); | ||
| 191 | for (mod.c_source_flags) |it| { | ||
| 192 | try w.print("\"{s}\",", .{std.zig.fmtEscapes(it)}); | ||
| 193 | } | ||
| 194 | try w.print("{s};\n", .{"}"}); | ||
| 195 | |||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | fn print_sys_libs_to(w: fs.File.Writer, list: []u.Module, list2: *std.ArrayList([]const u8)) !void { | ||
| 200 | for (list) |mod| { | ||
| 201 | if (!mod.is_sys_lib) { | ||
| 202 | continue; | ||
| 203 | } | ||
| 204 | try w.print(" \"{s}\",\n", .{mod.name}); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | fn print_pkg_data_to(w: fs.File.Writer, list: *std.ArrayList(u.Module), list2: *std.ArrayList(u.Module)) anyerror!void { | ||
| 209 | var i: usize = 0; | ||
| 210 | while (i < list.items.len) : (i += 1) { | ||
| 211 | const mod = list.items[i]; | ||
| 212 | if (contains_all(mod.deps, list2)) { | ||
| 213 | try w.print(" pub const _{s} = build.Pkg{{ .name = \"{s}\", .path = cache ++ \"/{s}/{s}\", .dependencies = &[_]build.Pkg{{", .{mod.id, mod.name, std.zig.fmtEscapes(mod.clean_path), mod.main}); | ||
| 214 | for (mod.deps) |d| { | ||
| 215 | if (d.main.len > 0) { | ||
| 216 | try w.print(" _{s},", .{d.id}); | ||
| 217 | } | ||
| 218 | } | ||
| 219 | try w.print(" }} }};\n", .{}); | ||
| 220 | |||
| 221 | try list2.append(mod); | ||
| 222 | _ = list.orderedRemove(i); | ||
| 223 | break; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | if (list.items.len > 0) { | ||
| 227 | try print_pkg_data_to(w, list, list2); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | /// returns if all of the zig modules in needles are in haystack | ||
| 232 | fn contains_all(needles: []u.Module, haystack: *std.ArrayList(u.Module)) bool { | ||
| 233 | for (needles) |item| { | ||
| 234 | if (item.main.len > 0 and !u.list_contains_gen(u.Module, haystack, item)) { | ||
| 235 | return false; | ||
| 236 | } | ||
| 237 | } | ||
| 238 | return true; | ||
| 239 | } | ||
src/cmd/init.zig created+53| ... | @@ -0,0 +1,53 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const gpa = std.heap.c_allocator; | ||
| 3 | |||
| 4 | const u = @import("./../util/index.zig"); | ||
| 5 | |||
| 6 | // | ||
| 7 | // | ||
| 8 | |||
| 9 | pub fn execute(args: [][]u8) !void { | ||
| 10 | const name = try detect_pkgname(u.try_index([]const u8, args, 0, "")); | ||
| 11 | const mainf = try detct_mainfile(u.try_index([]const u8, args, 1, "")); | ||
| 12 | |||
| 13 | const file = try std.fs.cwd().createFile("zig.mod", .{}); | ||
| 14 | defer file.close(); | ||
| 15 | |||
| 16 | const fwriter = file.writer(); | ||
| 17 | try fwriter.print("id: {s}\n", .{u.random_string(48)}); | ||
| 18 | try fwriter.print("name: {s}\n", .{name}); | ||
| 19 | try fwriter.print("main: {s}\n", .{mainf}); | ||
| 20 | try fwriter.print("dependencies:\n", .{}); | ||
| 21 | |||
| 22 | u.print("Initialized a new package named {s} with entry point {s}", .{name, mainf}); | ||
| 23 | } | ||
| 24 | |||
| 25 | fn detect_pkgname(def: []const u8) ![]const u8 { | ||
| 26 | if (def.len > 0) { | ||
| 27 | return def; | ||
| 28 | } | ||
| 29 | const dpath = try std.fs.cwd().realpathAlloc(gpa, "build.zig"); | ||
| 30 | const split = try u.split(dpath, std.fs.path.sep_str); | ||
| 31 | var name = split[split.len-2]; | ||
| 32 | name = u.trim_prefix(name, "zig-"); | ||
| 33 | u.assert(name.len > 0, "package name must not be an empty string", .{}); | ||
| 34 | return name; | ||
| 35 | } | ||
| 36 | |||
| 37 | fn detct_mainfile(def: []const u8) ![]const u8 { | ||
| 38 | if (def.len > 0) { | ||
| 39 | if (try u.does_file_exist(def)) { | ||
| 40 | if (std.mem.endsWith(u8, def, ".zig")) { | ||
| 41 | return def; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | if (try u.does_file_exist(try std.fs.path.join(gpa, &.{"src", "lib.zig"}))) { | ||
| 46 | return "src/lib.zig"; | ||
| 47 | } | ||
| 48 | if (try u.does_file_exist(try std.fs.path.join(gpa, &.{"src", "main.zig"}))) { | ||
| 49 | return "src/main.zig"; | ||
| 50 | } | ||
| 51 | u.assert(false, "unable to detect package entry point", .{}); | ||
| 52 | unreachable; | ||
| 53 | } | ||
src/cmd/sum.zig created+46| ... | @@ -0,0 +1,46 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const gpa = std.heap.c_allocator; | ||
| 3 | |||
| 4 | const known_folders = @import("known-folders"); | ||
| 5 | const u = @import("./../util/index.zig"); | ||
| 6 | const common = @import("./../common.zig"); | ||
| 7 | |||
| 8 | // | ||
| 9 | // | ||
| 10 | |||
| 11 | pub fn execute(args: [][]u8) !void { | ||
| 12 | // | ||
| 13 | const dir = try std.fs.path.join(gpa, &.{".zigmod", "deps"}); | ||
| 14 | |||
| 15 | const top_module = try common.collect_deps(dir, "zig.mod", .{ | ||
| 16 | .log = false, | ||
| 17 | .update = false, | ||
| 18 | }); | ||
| 19 | |||
| 20 | // | ||
| 21 | const f = try std.fs.cwd().createFile("zig.sum", .{}); | ||
| 22 | defer f.close(); | ||
| 23 | const w = f.writer(); | ||
| 24 | |||
| 25 | // | ||
| 26 | const module_list = &std.ArrayList(u.Module).init(gpa); | ||
| 27 | try dedupe_mod_list(module_list, top_module); | ||
| 28 | |||
| 29 | for (module_list.items) |m| { | ||
| 30 | if (m.clean_path.len == 0) { continue; } | ||
| 31 | const hash = try m.get_hash(dir); | ||
| 32 | try w.print("{s} {s}\n", .{hash, m.clean_path}); | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | fn dedupe_mod_list(list: *std.ArrayList(u.Module), module: u.Module) anyerror!void { | ||
| 37 | if (u.list_contains_gen(u.Module, list, module)) { | ||
| 38 | return; | ||
| 39 | } | ||
| 40 | if (module.clean_path.len > 0) { | ||
| 41 | try list.append(module); | ||
| 42 | } | ||
| 43 | for (module.deps) |m| { | ||
| 44 | try dedupe_mod_list(list, m); | ||
| 45 | } | ||
| 46 | } | ||
src/cmd/zpm.zig created+34| ... | @@ -0,0 +1,34 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const gpa = std.heap.c_allocator; | ||
| 3 | |||
| 4 | const u = @import("./../util/index.zig"); | ||
| 5 | |||
| 6 | // | ||
| 7 | // | ||
| 8 | |||
| 9 | pub const commands = struct { | ||
| 10 | pub const add = @import("./zpm_add.zig"); | ||
| 11 | }; | ||
| 12 | |||
| 13 | pub fn execute(args: [][]u8) !void { | ||
| 14 | if (args.len == 0) { | ||
| 15 | std.debug.warn("{s}\n", .{ | ||
| 16 | \\This is a subcommand for use with https://github.com/zigtools/zpm-server instances but has no default behavior on its own aside from showing you this nice help text. | ||
| 17 | \\ | ||
| 18 | \\The default remote is https://zpm.random-projects.net/. | ||
| 19 | \\ | ||
| 20 | \\The subcommands available are: | ||
| 21 | \\ - add Append this package to your dependencies | ||
| 22 | }); | ||
| 23 | return; | ||
| 24 | } | ||
| 25 | |||
| 26 | inline for (std.meta.declarations(commands)) |decl| { | ||
| 27 | if (std.mem.eql(u8, args[0], decl.name)) { | ||
| 28 | const cmd = @field(commands, decl.name); | ||
| 29 | try cmd.execute(args[1..]); | ||
| 30 | return; | ||
| 31 | } | ||
| 32 | } | ||
| 33 | std.debug.panic("error: unknown command \"{s}\" for \"zigmod zpm\"", .{args[0]}); | ||
| 34 | } | ||
src/cmd/zpm_add.zig created+90| ... | @@ -0,0 +1,90 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const gpa = std.heap.c_allocator; | ||
| 3 | |||
| 4 | const zuri = @import("zuri"); | ||
| 5 | const iguanatls = @import("iguanatls"); | ||
| 6 | const u = @import("./../util/index.zig"); | ||
| 7 | |||
| 8 | // | ||
| 9 | // | ||
| 10 | |||
| 11 | pub const Zpm = struct { | ||
| 12 | pub const Package = struct { | ||
| 13 | author: []const u8, | ||
| 14 | name: []const u8, | ||
| 15 | tags: [][]const u8, | ||
| 16 | git: []const u8, | ||
| 17 | root_file: ?[]const u8, | ||
| 18 | description: []const u8, | ||
| 19 | }; | ||
| 20 | }; | ||
| 21 | |||
| 22 | pub fn execute(args: [][]u8) !void { | ||
| 23 | const url = try zuri.Uri.parse("https://zpm.random-projects.net:443/api/packages", true); | ||
| 24 | |||
| 25 | const sock = try std.net.tcpConnectToHost(gpa, url.host.name, url.port.?); | ||
| 26 | defer sock.close(); | ||
| 27 | |||
| 28 | var client = try iguanatls.client_connect(.{ | ||
| 29 | .reader = sock.reader(), | ||
| 30 | .writer = sock.writer(), | ||
| 31 | .cert_verifier = .none, | ||
| 32 | .temp_allocator = gpa, | ||
| 33 | .ciphersuites = iguanatls.ciphersuites.all, | ||
| 34 | }, url.host.name); | ||
| 35 | defer client.close_notify() catch {}; | ||
| 36 | |||
| 37 | const w = client.writer(); | ||
| 38 | try w.print("GET {s} HTTP/1.1\r\n", .{url.path}); | ||
| 39 | try w.print("Host: {s}:{}\r\n", .{url.host.name, url.port.?}); | ||
| 40 | try w.writeAll("Accept: application/json; charset=UTF-8\r\n"); | ||
| 41 | try w.writeAll("Connection: close\r\n"); | ||
| 42 | try w.writeAll("\r\n"); | ||
| 43 | |||
| 44 | const r = client.reader(); | ||
| 45 | var buf: [1]u8 = undefined; | ||
| 46 | const data = &std.ArrayList(u8).init(gpa); | ||
| 47 | while (true) { | ||
| 48 | const len = try r.read(&buf); | ||
| 49 | if (len == 0) { | ||
| 50 | break; | ||
| 51 | } | ||
| 52 | try data.appendSlice(buf[0..len]); | ||
| 53 | } | ||
| 54 | |||
| 55 | const index = std.mem.indexOf(u8, data.items, "\r\n\r\n").?; | ||
| 56 | const html_contents = data.items[index..]; | ||
| 57 | |||
| 58 | var stream = std.json.TokenStream.init(html_contents[4..]); | ||
| 59 | const res = try std.json.parse([]Zpm.Package, &stream, .{ .allocator = gpa, }); | ||
| 60 | |||
| 61 | const found = blk: { | ||
| 62 | for (res) |pkg| { | ||
| 63 | if (std.mem.eql(u8, pkg.name, args[0])) { | ||
| 64 | break :blk pkg; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | u.assert(false, "no package with name '{s}' found", .{args[0]}); | ||
| 68 | unreachable; | ||
| 69 | }; | ||
| 70 | |||
| 71 | u.assert(found.root_file != null, "package must have an entry point to be able to be added to your dependencies", .{}); | ||
| 72 | |||
| 73 | const self_module = try u.ModFile.init(gpa, "zig.mod"); | ||
| 74 | for (self_module.deps) |dep| { | ||
| 75 | if (std.mem.eql(u8, dep.name, found.name)) { | ||
| 76 | u.assert(false, "dependency with name '{s}' already exists in your dependencies", .{found.name}); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | const file = try std.fs.cwd().openFile("zig.mod", .{ .read=true, .write=true }); | ||
| 81 | try file.seekTo(try file.getEndPos()); | ||
| 82 | |||
| 83 | const file_w = file.writer(); | ||
| 84 | try file_w.print("\n", .{}); | ||
| 85 | try file_w.print(" - src: git {s}\n", .{found.git}); | ||
| 86 | try file_w.print(" name: {s}\n", .{found.name}); | ||
| 87 | try file_w.print(" main: {s}\n", .{found.root_file.?[1..]}); | ||
| 88 | |||
| 89 | std.log.info("Successfully added package {s} by {s}", .{found.name, found.author}); | ||
| 90 | } | ||
src/cmd_fetch.zig deleted-239| ... | @@ -1,239 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const gpa = std.heap.c_allocator; | ||
| 3 | const fs = std.fs; | ||
| 4 | |||
| 5 | const known_folders = @import("known-folders"); | ||
| 6 | const u = @import("./util/index.zig"); | ||
| 7 | const common = @import("./common.zig"); | ||
| 8 | |||
| 9 | // | ||
| 10 | // | ||
| 11 | |||
| 12 | pub fn execute(args: [][]u8) !void { | ||
| 13 | // | ||
| 14 | const dir = try fs.path.join(gpa, &.{".zigmod", "deps"}); | ||
| 15 | |||
| 16 | const top_module = try common.collect_deps(dir, "zig.mod", .{ | ||
| 17 | .log = true, | ||
| 18 | .update = true, | ||
| 19 | }); | ||
| 20 | |||
| 21 | // | ||
| 22 | const f = try fs.cwd().createFile("deps.zig", .{}); | ||
| 23 | defer f.close(); | ||
| 24 | |||
| 25 | const w = f.writer(); | ||
| 26 | try w.writeAll("const std = @import(\"std\");\n"); | ||
| 27 | try w.writeAll("const build = std.build;\n"); | ||
| 28 | try w.writeAll("\n"); | ||
| 29 | try w.print("pub const cache = \"{s}\";\n", .{std.zig.fmtEscapes(dir)}); | ||
| 30 | try w.writeAll("\n"); | ||
| 31 | try w.print("{s}\n", .{ | ||
| 32 | \\pub fn addAllTo(exe: *build.LibExeObjStep) void { | ||
| 33 | \\ @setEvalBranchQuota(1_000_000); | ||
| 34 | \\ for (packages) |pkg| { | ||
| 35 | \\ exe.addPackage(pkg); | ||
| 36 | \\ } | ||
| 37 | \\ if (c_include_dirs.len > 0 or c_source_files.len > 0) { | ||
| 38 | \\ exe.linkLibC(); | ||
| 39 | \\ } | ||
| 40 | \\ for (c_include_dirs) |dir| { | ||
| 41 | \\ exe.addIncludeDir(dir); | ||
| 42 | \\ } | ||
| 43 | \\ inline for (c_source_files) |fpath| { | ||
| 44 | \\ exe.addCSourceFile(fpath[1], @field(c_source_flags, fpath[0])); | ||
| 45 | \\ } | ||
| 46 | \\ for (system_libs) |lib| { | ||
| 47 | \\ exe.linkSystemLibrary(lib); | ||
| 48 | \\ } | ||
| 49 | \\} | ||
| 50 | \\ | ||
| 51 | \\fn get_flags(comptime index: usize) []const u8 { | ||
| 52 | \\ return @field(c_source_flags, _paths[index]); | ||
| 53 | \\} | ||
| 54 | \\ | ||
| 55 | }); | ||
| 56 | |||
| 57 | const list = &std.ArrayList(u.Module).init(gpa); | ||
| 58 | try common.collect_pkgs(top_module, list); | ||
| 59 | |||
| 60 | try w.writeAll("pub const _ids = .{\n"); | ||
| 61 | try print_ids(w, list.items); | ||
| 62 | try w.writeAll("};\n\n"); | ||
| 63 | |||
| 64 | try w.print("pub const _paths = {s}\n", .{".{"}); | ||
| 65 | try print_paths(w, list.items); | ||
| 66 | try w.writeAll("};\n\n"); | ||
| 67 | |||
| 68 | try w.writeAll("pub const package_data = struct {\n"); | ||
| 69 | const duped = &std.ArrayList(u.Module).init(gpa); | ||
| 70 | for (list.items) |mod| { | ||
| 71 | if (mod.main.len > 0 and mod.clean_path.len > 0) { | ||
| 72 | try duped.append(mod); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | try print_pkg_data_to(w, duped, &std.ArrayList(u.Module).init(gpa)); | ||
| 76 | try w.writeAll("};\n\n"); | ||
| 77 | |||
| 78 | try w.writeAll("pub const packages = "); | ||
| 79 | try print_deps(w, dir, top_module, 0, true); | ||
| 80 | try w.writeAll(";\n\n"); | ||
| 81 | |||
| 82 | try w.writeAll("pub const pkgs = "); | ||
| 83 | try print_deps(w, dir, top_module, 0, false); | ||
| 84 | try w.writeAll(";\n\n"); | ||
| 85 | |||
| 86 | try w.writeAll("pub const c_include_dirs = &[_][]const u8{\n"); | ||
| 87 | try print_incl_dirs_to(w, list.items); | ||
| 88 | try w.writeAll("};\n\n"); | ||
| 89 | |||
| 90 | try w.writeAll("pub const c_source_flags = struct {\n"); | ||
| 91 | try print_csrc_flags_to(w, list.items); | ||
| 92 | try w.writeAll("};\n\n"); | ||
| 93 | |||
| 94 | try w.writeAll("pub const c_source_files = &[_][2][]const u8{\n"); | ||
| 95 | try print_csrc_dirs_to(w, list.items); | ||
| 96 | try w.writeAll("};\n\n"); | ||
| 97 | |||
| 98 | try w.writeAll("pub const system_libs = &[_][]const u8{\n"); | ||
| 99 | try print_sys_libs_to(w, list.items, &std.ArrayList([]const u8).init(gpa)); | ||
| 100 | try w.writeAll("};\n\n"); | ||
| 101 | } | ||
| 102 | |||
| 103 | fn print_ids(w: fs.File.Writer, list: []u.Module) !void { | ||
| 104 | for (list) |mod| { | ||
| 105 | if (mod.is_sys_lib) { | ||
| 106 | continue; | ||
| 107 | } | ||
| 108 | try w.print(" \"{s}\",\n", .{mod.id}); | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | fn print_paths(w: fs.File.Writer, list: []u.Module) !void { | ||
| 113 | for (list) |mod| { | ||
| 114 | if (mod.is_sys_lib) { | ||
| 115 | continue; | ||
| 116 | } | ||
| 117 | if (mod.clean_path.len == 0) { | ||
| 118 | try w.print(" \"\",\n", .{}); | ||
| 119 | } else { | ||
| 120 | const s = std.fs.path.sep_str; | ||
| 121 | try w.print(" \"{s}{s}{s}\",\n", .{std.zig.fmtEscapes(s), std.zig.fmtEscapes(mod.clean_path), std.zig.fmtEscapes(s)}); | ||
| 122 | } | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | fn print_deps(w: fs.File.Writer, dir: []const u8, m: u.Module, tabs: i32, array: bool) anyerror!void { | ||
| 127 | if (m.has_no_zig_deps() and tabs > 0) { | ||
| 128 | try w.print("null", .{}); | ||
| 129 | return; | ||
| 130 | } | ||
| 131 | if (array) { | ||
| 132 | try u.print_all(w, .{"&[_]build.Pkg{"}, true); | ||
| 133 | } else { | ||
| 134 | try u.print_all(w, .{"struct {"}, true); | ||
| 135 | } | ||
| 136 | const t = " "; | ||
| 137 | const r = try u.repeat(t, tabs); | ||
| 138 | for (m.deps) |d, i| { | ||
| 139 | if (d.main.len == 0) { | ||
| 140 | continue; | ||
| 141 | } | ||
| 142 | if (!array) { | ||
| 143 | try w.print(" pub const {s} = packages[{}];\n", .{std.mem.replaceOwned(u8, gpa, d.name, "-", "_"), i}); | ||
| 144 | } | ||
| 145 | else { | ||
| 146 | try w.print(" package_data._{s},\n", .{d.id}); | ||
| 147 | } | ||
| 148 | } | ||
| 149 | try w.print("{s}", .{try u.concat(&.{r,"}"})}); | ||
| 150 | } | ||
| 151 | |||
| 152 | fn print_incl_dirs_to(w: fs.File.Writer, list: []u.Module) !void { | ||
| 153 | for (list) |mod, i| { | ||
| 154 | if (mod.is_sys_lib) { | ||
| 155 | continue; | ||
| 156 | } | ||
| 157 | for (mod.c_include_dirs) |it| { | ||
| 158 | if (i > 0) { | ||
| 159 | try w.print(" cache ++ _paths[{}] ++ \"{s}\",\n", .{i, std.zig.fmtEscapes(it)}); | ||
| 160 | } else { | ||
| 161 | try w.print(" \"{s}\",\n", .{std.zig.fmtEscapes(it)}); | ||
| 162 | } | ||
| 163 | } | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | fn print_csrc_dirs_to(w: fs.File.Writer, list: []u.Module) !void { | ||
| 168 | for (list) |mod, i| { | ||
| 169 | if (mod.is_sys_lib) { | ||
| 170 | continue; | ||
| 171 | } | ||
| 172 | for (mod.c_source_files) |it| { | ||
| 173 | if (i > 0) { | ||
| 174 | try w.print(" {s}_ids[{}], cache ++ _paths[{}] ++ \"{s}\"{s},\n", .{"[_][]const u8{", i, i, it, "}"}); | ||
| 175 | } else { | ||
| 176 | try w.print(" {s}_ids[{}], \".{s}/{s}\"{s},\n", .{"[_][]const u8{", i, std.zig.fmtEscapes(mod.clean_path), it, "}"}); | ||
| 177 | } | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | |||
| 182 | fn print_csrc_flags_to(w: fs.File.Writer, list: []u.Module) !void { | ||
| 183 | for (list) |mod, i| { | ||
| 184 | if (mod.is_sys_lib) { | ||
| 185 | continue; | ||
| 186 | } | ||
| 187 | if (mod.c_source_flags.len == 0 and mod.c_source_files.len == 0) { | ||
| 188 | continue; | ||
| 189 | } | ||
| 190 | try w.print(" pub const @\"{s}\" = {s}", .{mod.id, "&.{"}); | ||
| 191 | for (mod.c_source_flags) |it| { | ||
| 192 | try w.print("\"{s}\",", .{std.zig.fmtEscapes(it)}); | ||
| 193 | } | ||
| 194 | try w.print("{s};\n", .{"}"}); | ||
| 195 | |||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 199 | fn print_sys_libs_to(w: fs.File.Writer, list: []u.Module, list2: *std.ArrayList([]const u8)) !void { | ||
| 200 | for (list) |mod| { | ||
| 201 | if (!mod.is_sys_lib) { | ||
| 202 | continue; | ||
| 203 | } | ||
| 204 | try w.print(" \"{s}\",\n", .{mod.name}); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | fn print_pkg_data_to(w: fs.File.Writer, list: *std.ArrayList(u.Module), list2: *std.ArrayList(u.Module)) anyerror!void { | ||
| 209 | var i: usize = 0; | ||
| 210 | while (i < list.items.len) : (i += 1) { | ||
| 211 | const mod = list.items[i]; | ||
| 212 | if (contains_all(mod.deps, list2)) { | ||
| 213 | try w.print(" pub const _{s} = build.Pkg{{ .name = \"{s}\", .path = cache ++ \"/{s}/{s}\", .dependencies = &[_]build.Pkg{{", .{mod.id, mod.name, std.zig.fmtEscapes(mod.clean_path), mod.main}); | ||
| 214 | for (mod.deps) |d| { | ||
| 215 | if (d.main.len > 0) { | ||
| 216 | try w.print(" _{s},", .{d.id}); | ||
| 217 | } | ||
| 218 | } | ||
| 219 | try w.print(" }} }};\n", .{}); | ||
| 220 | |||
| 221 | try list2.append(mod); | ||
| 222 | _ = list.orderedRemove(i); | ||
| 223 | break; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | if (list.items.len > 0) { | ||
| 227 | try print_pkg_data_to(w, list, list2); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | /// returns if all of the zig modules in needles are in haystack | ||
| 232 | fn contains_all(needles: []u.Module, haystack: *std.ArrayList(u.Module)) bool { | ||
| 233 | for (needles) |item| { | ||
| 234 | if (item.main.len > 0 and !u.list_contains_gen(u.Module, haystack, item)) { | ||
| 235 | return false; | ||
| 236 | } | ||
| 237 | } | ||
| 238 | return true; | ||
| 239 | } | ||
src/cmd_init.zig deleted-53| ... | @@ -1,53 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const gpa = std.heap.c_allocator; | ||
| 3 | |||
| 4 | const u = @import("./util/index.zig"); | ||
| 5 | |||
| 6 | // | ||
| 7 | // | ||
| 8 | |||
| 9 | pub fn execute(args: [][]u8) !void { | ||
| 10 | const name = try detect_pkgname(u.try_index([]const u8, args, 0, "")); | ||
| 11 | const mainf = try detct_mainfile(u.try_index([]const u8, args, 1, "")); | ||
| 12 | |||
| 13 | const file = try std.fs.cwd().createFile("zig.mod", .{}); | ||
| 14 | defer file.close(); | ||
| 15 | |||
| 16 | const fwriter = file.writer(); | ||
| 17 | try fwriter.print("id: {s}\n", .{u.random_string(48)}); | ||
| 18 | try fwriter.print("name: {s}\n", .{name}); | ||
| 19 | try fwriter.print("main: {s}\n", .{mainf}); | ||
| 20 | try fwriter.print("dependencies:\n", .{}); | ||
| 21 | |||
| 22 | u.print("Initialized a new package named {s} with entry point {s}", .{name, mainf}); | ||
| 23 | } | ||
| 24 | |||
| 25 | fn detect_pkgname(def: []const u8) ![]const u8 { | ||
| 26 | if (def.len > 0) { | ||
| 27 | return def; | ||
| 28 | } | ||
| 29 | const dpath = try std.fs.cwd().realpathAlloc(gpa, "build.zig"); | ||
| 30 | const split = try u.split(dpath, std.fs.path.sep_str); | ||
| 31 | var name = split[split.len-2]; | ||
| 32 | name = u.trim_prefix(name, "zig-"); | ||
| 33 | u.assert(name.len > 0, "package name must not be an empty string", .{}); | ||
| 34 | return name; | ||
| 35 | } | ||
| 36 | |||
| 37 | fn detct_mainfile(def: []const u8) ![]const u8 { | ||
| 38 | if (def.len > 0) { | ||
| 39 | if (try u.does_file_exist(def)) { | ||
| 40 | if (std.mem.endsWith(u8, def, ".zig")) { | ||
| 41 | return def; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | if (try u.does_file_exist(try std.fs.path.join(gpa, &.{"src", "lib.zig"}))) { | ||
| 46 | return "src/lib.zig"; | ||
| 47 | } | ||
| 48 | if (try u.does_file_exist(try std.fs.path.join(gpa, &.{"src", "main.zig"}))) { | ||
| 49 | return "src/main.zig"; | ||
| 50 | } | ||
| 51 | u.assert(false, "unable to detect package entry point", .{}); | ||
| 52 | unreachable; | ||
| 53 | } | ||
src/cmd_sum.zig deleted-46| ... | @@ -1,46 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const gpa = std.heap.c_allocator; | ||
| 3 | |||
| 4 | const known_folders = @import("known-folders"); | ||
| 5 | const u = @import("./util/index.zig"); | ||
| 6 | const common = @import("./common.zig"); | ||
| 7 | |||
| 8 | // | ||
| 9 | // | ||
| 10 | |||
| 11 | pub fn execute(args: [][]u8) !void { | ||
| 12 | // | ||
| 13 | const dir = try std.fs.path.join(gpa, &.{".zigmod", "deps"}); | ||
| 14 | |||
| 15 | const top_module = try common.collect_deps(dir, "zig.mod", .{ | ||
| 16 | .log = false, | ||
| 17 | .update = false, | ||
| 18 | }); | ||
| 19 | |||
| 20 | // | ||
| 21 | const f = try std.fs.cwd().createFile("zig.sum", .{}); | ||
| 22 | defer f.close(); | ||
| 23 | const w = f.writer(); | ||
| 24 | |||
| 25 | // | ||
| 26 | const module_list = &std.ArrayList(u.Module).init(gpa); | ||
| 27 | try dedupe_mod_list(module_list, top_module); | ||
| 28 | |||
| 29 | for (module_list.items) |m| { | ||
| 30 | if (m.clean_path.len == 0) { continue; } | ||
| 31 | const hash = try m.get_hash(dir); | ||
| 32 | try w.print("{s} {s}\n", .{hash, m.clean_path}); | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | fn dedupe_mod_list(list: *std.ArrayList(u.Module), module: u.Module) anyerror!void { | ||
| 37 | if (u.list_contains_gen(u.Module, list, module)) { | ||
| 38 | return; | ||
| 39 | } | ||
| 40 | if (module.clean_path.len > 0) { | ||
| 41 | try list.append(module); | ||
| 42 | } | ||
| 43 | for (module.deps) |m| { | ||
| 44 | try dedupe_mod_list(list, m); | ||
| 45 | } | ||
| 46 | } | ||
src/cmd_zpm.zig deleted-34| ... | @@ -1,34 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const gpa = std.heap.c_allocator; | ||
| 3 | |||
| 4 | const u = @import("./util/index.zig"); | ||
| 5 | |||
| 6 | // | ||
| 7 | // | ||
| 8 | |||
| 9 | pub const commands = struct { | ||
| 10 | pub const add = @import("./cmd_zpm_add.zig"); | ||
| 11 | }; | ||
| 12 | |||
| 13 | pub fn execute(args: [][]u8) !void { | ||
| 14 | if (args.len == 0) { | ||
| 15 | std.debug.warn("{s}\n", .{ | ||
| 16 | \\This is a subcommand for use with https://github.com/zigtools/zpm-server instances but has no default behavior on its own aside from showing you this nice help text. | ||
| 17 | \\ | ||
| 18 | \\The default remote is https://zpm.random-projects.net/. | ||
| 19 | \\ | ||
| 20 | \\The subcommands available are: | ||
| 21 | \\ - add Append this package to your dependencies | ||
| 22 | }); | ||
| 23 | return; | ||
| 24 | } | ||
| 25 | |||
| 26 | inline for (std.meta.declarations(commands)) |decl| { | ||
| 27 | if (std.mem.eql(u8, args[0], decl.name)) { | ||
| 28 | const cmd = @field(commands, decl.name); | ||
| 29 | try cmd.execute(args[1..]); | ||
| 30 | return; | ||
| 31 | } | ||
| 32 | } | ||
| 33 | std.debug.panic("error: unknown command \"{s}\" for \"zigmod zpm\"", .{args[0]}); | ||
| 34 | } | ||
src/cmd_zpm_add.zig deleted-90| ... | @@ -1,90 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const gpa = std.heap.c_allocator; | ||
| 3 | |||
| 4 | const zuri = @import("zuri"); | ||
| 5 | const iguanatls = @import("iguanatls"); | ||
| 6 | const u = @import("./util/index.zig"); | ||
| 7 | |||
| 8 | // | ||
| 9 | // | ||
| 10 | |||
| 11 | pub const Zpm = struct { | ||
| 12 | pub const Package = struct { | ||
| 13 | author: []const u8, | ||
| 14 | name: []const u8, | ||
| 15 | tags: [][]const u8, | ||
| 16 | git: []const u8, | ||
| 17 | root_file: ?[]const u8, | ||
| 18 | description: []const u8, | ||
| 19 | }; | ||
| 20 | }; | ||
| 21 | |||
| 22 | pub fn execute(args: [][]u8) !void { | ||
| 23 | const url = try zuri.Uri.parse("https://zpm.random-projects.net:443/api/packages", true); | ||
| 24 | |||
| 25 | const sock = try std.net.tcpConnectToHost(gpa, url.host.name, url.port.?); | ||
| 26 | defer sock.close(); | ||
| 27 | |||
| 28 | var client = try iguanatls.client_connect(.{ | ||
| 29 | .reader = sock.reader(), | ||
| 30 | .writer = sock.writer(), | ||
| 31 | .cert_verifier = .none, | ||
| 32 | .temp_allocator = gpa, | ||
| 33 | .ciphersuites = iguanatls.ciphersuites.all, | ||
| 34 | }, url.host.name); | ||
| 35 | defer client.close_notify() catch {}; | ||
| 36 | |||
| 37 | const w = client.writer(); | ||
| 38 | try w.print("GET {s} HTTP/1.1\r\n", .{url.path}); | ||
| 39 | try w.print("Host: {s}:{}\r\n", .{url.host.name, url.port.?}); | ||
| 40 | try w.writeAll("Accept: application/json; charset=UTF-8\r\n"); | ||
| 41 | try w.writeAll("Connection: close\r\n"); | ||
| 42 | try w.writeAll("\r\n"); | ||
| 43 | |||
| 44 | const r = client.reader(); | ||
| 45 | var buf: [1]u8 = undefined; | ||
| 46 | const data = &std.ArrayList(u8).init(gpa); | ||
| 47 | while (true) { | ||
| 48 | const len = try r.read(&buf); | ||
| 49 | if (len == 0) { | ||
| 50 | break; | ||
| 51 | } | ||
| 52 | try data.appendSlice(buf[0..len]); | ||
| 53 | } | ||
| 54 | |||
| 55 | const index = std.mem.indexOf(u8, data.items, "\r\n\r\n").?; | ||
| 56 | const html_contents = data.items[index..]; | ||
| 57 | |||
| 58 | var stream = std.json.TokenStream.init(html_contents[4..]); | ||
| 59 | const res = try std.json.parse([]Zpm.Package, &stream, .{ .allocator = gpa, }); | ||
| 60 | |||
| 61 | const found = blk: { | ||
| 62 | for (res) |pkg| { | ||
| 63 | if (std.mem.eql(u8, pkg.name, args[0])) { | ||
| 64 | break :blk pkg; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | u.assert(false, "no package with name '{s}' found", .{args[0]}); | ||
| 68 | unreachable; | ||
| 69 | }; | ||
| 70 | |||
| 71 | u.assert(found.root_file != null, "package must have an entry point to be able to be added to your dependencies", .{}); | ||
| 72 | |||
| 73 | const self_module = try u.ModFile.init(gpa, "zig.mod"); | ||
| 74 | for (self_module.deps) |dep| { | ||
| 75 | if (std.mem.eql(u8, dep.name, found.name)) { | ||
| 76 | u.assert(false, "dependency with name '{s}' already exists in your dependencies", .{found.name}); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | const file = try std.fs.cwd().openFile("zig.mod", .{ .read=true, .write=true }); | ||
| 81 | try file.seekTo(try file.getEndPos()); | ||
| 82 | |||
| 83 | const file_w = file.writer(); | ||
| 84 | try file_w.print("\n", .{}); | ||
| 85 | try file_w.print(" - src: git {s}\n", .{found.git}); | ||
| 86 | try file_w.print(" name: {s}\n", .{found.name}); | ||
| 87 | try file_w.print(" main: {s}\n", .{found.root_file.?[1..]}); | ||
| 88 | |||
| 89 | std.log.info("Successfully added package {s} by {s}", .{found.name, found.author}); | ||
| 90 | } | ||
src/main.zig+5-5| ... | @@ -9,14 +9,14 @@ pub const common = @import("./common.zig"); | ... | @@ -9,14 +9,14 @@ pub const common = @import("./common.zig"); |
| 9 | // | 9 | // |
| 10 | 10 | ||
| 11 | pub const commands_to_bootstrap = struct { | 11 | pub const commands_to_bootstrap = struct { |
| 12 | pub const fetch = @import("./cmd_fetch.zig"); | 12 | pub const fetch = @import("./cmd/fetch.zig"); |
| 13 | }; | 13 | }; |
| 14 | 14 | ||
| 15 | pub const commands = struct { | 15 | pub const commands = struct { |
| 16 | pub const init = @import("./cmd_init.zig"); | 16 | pub const init = @import("./cmd/init.zig"); |
| 17 | pub const fetch = @import("./cmd_fetch.zig"); | 17 | pub const fetch = @import("./cmd/fetch.zig"); |
| 18 | pub const sum = @import("./cmd_sum.zig"); | 18 | pub const sum = @import("./cmd/sum.zig"); |
| 19 | pub const zpm = @import("./cmd_zpm.zig"); | 19 | pub const zpm = @import("./cmd/zpm.zig"); |
| 20 | pub const license = @import("./cmd/license.zig"); | 20 | pub const license = @import("./cmd/license.zig"); |
| 21 | }; | 21 | }; |
| 22 | 22 |