MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 70 lines 2.8 kB view raw
1const std = @import("std"); 2const root = @import("root.zig"); 3 4const ListCallback = 5 *const fn ([*:0]const u8, [*:0]const u8, ?*anyopaque) callconv(.c) void; 6 7const PkgDeps = struct { 8 deps: ?std.json.ObjectMap, 9 dev_deps: ?std.json.ObjectMap, 10 nm_path: []const u8, 11 arena: std.mem.Allocator, 12 parsed: std.json.Parsed(std.json.Value), 13 14 pub fn deinit(self: *PkgDeps) void { 15 self.parsed.deinit(); 16 } 17 18 pub fn count(self: *const PkgDeps) u32 { 19 var c: u32 = 0; 20 if (self.deps) |d| c += @intCast(d.count()); 21 if (self.dev_deps) |d| c += @intCast(d.count()); 22 return c; 23 } 24}; 25 26fn emitPkg(pd: *PkgDeps, name: []const u8, cb: ListCallback, ud: ?*anyopaque) void { 27 const pkg_json = std.fmt.allocPrint(pd.arena, "{s}/{s}/package.json", .{pd.nm_path, name}) catch return; 28 const content = std.fs.cwd().readFileAlloc(pd.arena, pkg_json, 256 * 1024) catch return; 29 const parsed = std.json.parseFromSlice(std.json.Value, pd.arena, content, .{}) catch return; 30 defer parsed.deinit(); 31 32 const ver = if (parsed.value.object.get("version")) |v| if (v == .string) v.string else "?" else "?"; 33 cb(pd.arena.dupeZ(u8, name) catch return, pd.arena.dupeZ(u8, ver) catch return, ud); 34} 35 36pub fn get_dependencies(ctx: ?*root.PkgContext, base_path: ?[]const u8, include_dev: bool) ?PkgDeps { 37 const c = ctx orelse return null; 38 _ = c.arena_state.reset(.retain_capacity); 39 const arena = c.arena_state.allocator(); 40 41 const pkg_json_path = if (base_path) |bp| std.fmt.allocPrint(arena, "{s}/package.json", .{bp}) catch return null 42 else arena.dupe(u8, "package.json") catch return null; 43 44 const nm_path = if (base_path) |bp| std.fmt.allocPrint(arena, "{s}/node_modules", .{bp}) catch return null 45 else arena.dupe(u8, "node_modules") catch return null; 46 47 const content = std.fs.cwd().readFileAlloc(arena, pkg_json_path, 1024 * 1024) catch return null; 48 const parsed = std.json.parseFromSlice(std.json.Value, arena, content, .{}) catch return null; 49 50 const deps_val = parsed.value.object.get("dependencies"); 51 const deps = if (deps_val) |v| if (v == .object) v.object else null else null; 52 53 const dev_deps = if (include_dev) blk: { 54 const dev_val = parsed.value.object.get("devDependencies"); 55 break :blk if (dev_val) |v| if (v == .object) v.object else null else null; 56 } else null; 57 58 if (deps == null and dev_deps == null) { 59 var p = parsed; 60 p.deinit(); 61 return null; 62 } 63 64 return .{ .deps = deps, .dev_deps = dev_deps, .nm_path = nm_path, .arena = arena, .parsed = parsed }; 65} 66 67pub fn list_dependencies(pd: *PkgDeps, cb: ListCallback, ud: ?*anyopaque) void { 68 if (pd.deps) |d| for (d.keys()) |n| emitPkg(pd, n, cb, ud); 69 if (pd.dev_deps) |d| for (d.keys()) |n| emitPkg(pd, n, cb, ud); 70}