authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-06-05 16:56:00 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2021-06-05 16:56:00 -07:00
log23e8c736cbf63396c3250a3ec1b1959d801f6417
tree6b9aa3ec999625c9a6996809a019485a6c736d54
parent5daf2123318a7b6eb499d96383bc2c804270c19d

zig.mod- add `files` and `root_files` attrs for static asset embedding


3 files changed, 85 insertions(+), 0 deletions(-)

docs/zig.mod.md+8
......@@ -30,6 +30,14 @@ This is a list of [`clang`](https://clang.llvm.org/docs/UsersManual.html#command
3030- Type: `[]string`
3131This is a list of relative paths to C source files to compile along with this project. This will be required if you use Zig's [`@cImport`](https://ziglang.org/documentation/master/#cImport), `extern`, etc.
3232
33### `files`
34- Type: `[]string`
35This accepts a list of local directories to embed static assets. These files will be provided through a `self/files` package to `@import(main)`.
36
37### `root_files`
38- Type: `[]string`
39This accepts a list of local directories to embed static assets. These files will be provided through a `self/files` package to `@import("root")`.
40
3341### `dependencies`
3442- Type: `[]Dep`
3543This is a list of `Dep` objects. `Dep` objects are how you include the other people's code in your project. See the `Dep` documentation below to learn more about the attributes available here.
src/common.zig+71
......@@ -2,6 +2,7 @@ const std = @import("std");
22const gpa = std.heap.c_allocator;
33
44const u = @import("./util/index.zig");
5const yaml = @import("./util/yaml.zig");
56
67//
78//
......@@ -15,6 +16,10 @@ pub fn collect_deps_deep(dir: []const u8, mpath: []const u8, options: CollectOpt
1516 const m = try u.ModFile.init(gpa, mpath);
1617 const moduledeps = &std.ArrayList(u.Module).init(gpa);
1718 defer moduledeps.deinit();
19 try std.fs.cwd().makePath(".zigmod/deps/files");
20 if (m.root_files.len > 0) {
21 try add_files_package("root", m.root_files, moduledeps, m.name);
22 }
1823 try moduledeps.append(try collect_deps(dir, mpath, options));
1924 for (m.devdeps) |d| {
2025 if (!d.is_for_this()) {
......@@ -42,6 +47,9 @@ pub fn collect_deps(dir: []const u8, mpath: []const u8, options: CollectOptions)
4247 const m = try u.ModFile.init(gpa, mpath);
4348 const moduledeps = &std.ArrayList(u.Module).init(gpa);
4449 defer moduledeps.deinit();
50 if (m.files.len > 0) {
51 try add_files_package(m.id, m.files, moduledeps, m.name);
52 }
4553 for (m.deps) |d| {
4654 if (!d.is_for_this()) {
4755 continue;
......@@ -219,3 +227,66 @@ fn get_module_from_dep(list: *std.ArrayList(u.Module), d: u.Dep, dir: []const u8
219227 },
220228 }
221229}
230
231fn add_files_package(pkg_name: []const u8, dirs: []const []const u8, list: *std.ArrayList(u.Module), parent_name: []const u8) !void {
232 const destination = ".zigmod/deps/files";
233 const fname = try std.mem.join(gpa, "", &.{ pkg_name, ".zig" });
234
235 const map = &std.StringHashMap([]const u8).init(gpa);
236 defer map.deinit();
237
238 for (dirs) |dir_path| {
239 var walker = try std.fs.walkPath(gpa, dir_path);
240 while (try walker.next()) |p| {
241 if (p.kind == .Directory) {
242 continue;
243 }
244 const path = try std.mem.dupe(gpa, u8, p.path);
245 try map.put(path[dir_path.len..], path);
246 }
247 }
248
249 const rff = try (try std.fs.cwd().openDir(destination, .{})).createFile(fname, .{});
250 defer rff.close();
251 const w = rff.writer();
252 try w.writeAll(
253 \\const std = @import("std");
254 \\
255 \\const files = std.ComptimeStringMap([]const u8, .{
256 \\
257 );
258 var iter = map.iterator();
259 while (iter.next()) |item| {
260 try w.print(" .{{ .@\"0\" = \"{}\", .@\"1\" = @embedFile(\"./../../../{}\") }},\n", .{ std.zig.fmtEscapes(item.key_ptr.*), std.zig.fmtEscapes(item.value_ptr.*) });
261 }
262 try w.writeAll("\n");
263 try w.writeAll(
264 \\});
265 \\
266 \\pub fn open(comptime path: []const u8) ?[]const u8 {
267 \\ if (path.len == 0) return null;
268 \\ if (path[0] != '/') return null;
269 \\ return files.get(path);
270 \\}
271 \\
272 );
273
274 const d: u.Dep = .{
275 .type = .local,
276 .path = "files",
277 .id = "",
278 .name = "self/files",
279 .main = fname,
280 .version = "absolute",
281 .c_include_dirs = &.{},
282 .c_source_flags = &.{},
283 .c_source_files = &.{},
284 .only_os = &.{},
285 .except_os = &.{},
286 .yaml = null,
287 };
288 try get_module_from_dep(list, d, destination, parent_name, .{
289 .log = false,
290 .update = false,
291 });
292}
src/util/modfile.zig+6
......@@ -23,6 +23,8 @@ pub const ModFile = struct {
2323 deps: []u.Dep,
2424 yaml: yaml.Mapping,
2525 devdeps: []u.Dep,
26 root_files: [][]const u8,
27 files: [][]const u8,
2628
2729 pub fn init(alloc: *std.mem.Allocator, fpath: []const u8) !Self {
2830 //
......@@ -42,6 +44,7 @@ pub const ModFile = struct {
4244 if (std.mem.indexOf(u8, name, "/")) |_| {
4345 u.assert(false, "name may not contain any '/'", .{});
4446 }
47
4548 const dep_list = try dep_list_by_name(alloc, mapping, "dependencies");
4649 defer dep_list.deinit();
4750 const devdep_list = try dep_list_by_name(alloc, mapping, "dev_dependencies");
......@@ -58,6 +61,8 @@ pub const ModFile = struct {
5861 .deps = dep_list.toOwnedSlice(),
5962 .yaml = mapping,
6063 .devdeps = devdep_list.toOwnedSlice(),
64 .root_files = try mapping.get_string_array(alloc, "root_files"),
65 .files = try mapping.get_string_array(alloc, "files"),
6166 };
6267 }
6368
......@@ -72,6 +77,7 @@ pub const ModFile = struct {
7277 var version: ?[]const u8 = null;
7378 var name = item.mapping.get_string("name");
7479 var main = item.mapping.get_string("main");
80
7581 if (item.mapping.get("src")) |val| {
7682 var src_iter = std.mem.tokenize(val.string, " ");
7783 dtype = src_iter.next().?;