| author | |
| committer | |
| log | b6168b6da8718f32e416c5256ad4839603a71b37 |
| tree | ef803825468673adc134bb94a2d14e5dec3db063 |
| parent | 1d66aac054ac54f39ead1cd87903744bee3b4b33 |
9 files changed, 63 insertions(+), 23 deletions(-)
docs/zig.mod.md+5| ... | @@ -58,6 +58,11 @@ Similar to `dependencies` but will only get added to the project if the current | ... | @@ -58,6 +58,11 @@ Similar to `dependencies` but will only get added to the project if the current |
| 58 | - Type: `string` | 58 | - Type: `string` |
| 59 | Parsed as a `std.SemanticVersion`, this attribute refers to the minimum compatible Zig version for this package/application and will cause `zig build` to panic if violated. | 59 | Parsed as a `std.SemanticVersion`, this attribute refers to the minimum compatible Zig version for this package/application and will cause `zig build` to panic if violated. |
| 60 | 60 | ||
| 61 | ### `min_zigmod_version` | ||
| 62 | - Type: `string` | ||
| 63 | This attribute refers to the minimum compatible Zigmod version for this package/application and will cause `zigmod fetch`, `zigmod ci`, and others to exit with an error. | ||
| 64 | While rare, this is most useful to provide a nice error message to the user when your `zigmod.yml` uses a new feature that may not be available in previous versions of Zigmod. | ||
| 65 | |||
| 61 | ---- | 66 | ---- |
| 62 | 67 | ||
| 63 | ### Dep Object | 68 | ### Dep Object |
src/cmd/aquila/add.zig+4-4| ... | @@ -12,11 +12,11 @@ pub fn execute(self_name: []const u8, args: [][:0]u8) !void { | ... | @@ -12,11 +12,11 @@ pub fn execute(self_name: []const u8, args: [][:0]u8) !void { |
| 12 | _ = self_name; | 12 | _ = self_name; |
| 13 | 13 | ||
| 14 | const pkg_id = args[0]; | 14 | const pkg_id = args[0]; |
| 15 | _ = try do(std.fs.cwd(), pkg_id); | 15 | _ = try do(std.fs.cwd(), ".", pkg_id); |
| 16 | std.log.info("Successfully added package {s}", .{pkg_id}); | 16 | std.log.info("Successfully added package {s}", .{pkg_id}); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | pub fn do(dir: std.fs.Dir, pkg_id: string) !string { | 19 | pub fn do(dir: std.fs.Dir, dir_path: string, pkg_id: string) !string { |
| 20 | const url = try std.mem.join(gpa, "/", &.{ aq.server_root, pkg_id }); | 20 | const url = try std.mem.join(gpa, "/", &.{ aq.server_root, pkg_id }); |
| 21 | const doc = try aq.server_fetch(url); | 21 | const doc = try aq.server_fetch(url); |
| 22 | doc.acquire(); | 22 | doc.acquire(); |
| ... | @@ -27,7 +27,7 @@ pub fn do(dir: std.fs.Dir, pkg_id: string) !string { | ... | @@ -27,7 +27,7 @@ pub fn do(dir: std.fs.Dir, pkg_id: string) !string { |
| 27 | doc.root.object().getO("package").?.getS("remote_name").?, | 27 | doc.root.object().getO("package").?.getS("remote_name").?, |
| 28 | }); | 28 | }); |
| 29 | 29 | ||
| 30 | const m = try zigmod.ModFile.from_dir(gpa, dir); | 30 | const m = try zigmod.ModFile.from_dir(gpa, dir, dir_path); |
| 31 | for (m.rootdeps) |d| { | 31 | for (m.rootdeps) |d| { |
| 32 | if (std.mem.eql(u8, d.path, pkg_url)) { | 32 | if (std.mem.eql(u8, d.path, pkg_url)) { |
| 33 | return pkg_url; | 33 | return pkg_url; |
| ... | @@ -39,7 +39,7 @@ pub fn do(dir: std.fs.Dir, pkg_id: string) !string { | ... | @@ -39,7 +39,7 @@ pub fn do(dir: std.fs.Dir, pkg_id: string) !string { |
| 39 | } | 39 | } |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | var file = try zigmod.ModFile.openFile(dir, .{ .mode = .read_write }); | 42 | _, var file = try zigmod.ModFile.openFile(dir, .{ .mode = .read_write }); |
| 43 | defer file.close(); | 43 | defer file.close(); |
| 44 | try file.seekTo(try file.getEndPos()); | 44 | try file.seekTo(try file.getEndPos()); |
| 45 | 45 |
src/cmd/aquila/install.zig+2-2| ... | @@ -25,13 +25,13 @@ pub fn execute(self_name: []const u8, args: [][:0]u8) !void { | ... | @@ -25,13 +25,13 @@ pub fn execute(self_name: []const u8, args: [][:0]u8) !void { |
| 25 | 25 | ||
| 26 | // add to ~/zigmod.yml for later | 26 | // add to ~/zigmod.yml for later |
| 27 | const aqadd = @import("./add.zig"); | 27 | const aqadd = @import("./add.zig"); |
| 28 | const pkgurl = aqadd.do(homedir, args[0]) catch |err| switch (err) { | 28 | const pkgurl = aqadd.do(homedir, homepath, args[0]) catch |err| switch (err) { |
| 29 | error.AquilaBadResponse => return, | 29 | error.AquilaBadResponse => return, |
| 30 | else => |ee| return ee, | 30 | else => |ee| return ee, |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | // get modfile and dep | 33 | // get modfile and dep |
| 34 | const m = try zigmod.ModFile.from_dir(gpa, homedir); | 34 | const m = try zigmod.ModFile.from_dir(gpa, homedir, homepath); |
| 35 | var dep: zigmod.Dep = undefined; | 35 | var dep: zigmod.Dep = undefined; |
| 36 | for (m.rootdeps) |d| { | 36 | for (m.rootdeps) |d| { |
| 37 | if (std.mem.eql(u8, d.path, pkgurl)) { | 37 | if (std.mem.eql(u8, d.path, pkgurl)) { |
src/cmd/aquila/update.zig+1-1| ... | @@ -25,7 +25,7 @@ pub fn execute(self_name: []const u8, args: [][:0]u8) !void { | ... | @@ -25,7 +25,7 @@ pub fn execute(self_name: []const u8, args: [][:0]u8) !void { |
| 25 | u.assert(args.len == 0, "zigmod aq update accepts no parameters", .{}); | 25 | u.assert(args.len == 0, "zigmod aq update accepts no parameters", .{}); |
| 26 | 26 | ||
| 27 | // get modfile and dep | 27 | // get modfile and dep |
| 28 | const m = try zigmod.ModFile.from_dir(gpa, homedir); | 28 | const m = try zigmod.ModFile.from_dir(gpa, homedir, homepath); |
| 29 | for (m.rootdeps) |dep| { | 29 | for (m.rootdeps) |dep| { |
| 30 | // | 30 | // |
| 31 | const cache = try knownfolders.getPath(gpa, .cache); | 31 | const cache = try knownfolders.getPath(gpa, .cache); |
src/cmd/zpm/add.zig+1-1| ... | @@ -57,7 +57,7 @@ pub fn execute(self_name: []const u8, args: [][:0]u8) !void { | ... | @@ -57,7 +57,7 @@ pub fn execute(self_name: []const u8, args: [][:0]u8) !void { |
| 57 | break :blk @intFromEnum(_req.status) == 200; | 57 | break :blk @intFromEnum(_req.status) == 200; |
| 58 | }; | 58 | }; |
| 59 | 59 | ||
| 60 | const file = try zigmod.ModFile.openFile(std.fs.cwd(), .{ .mode = .read_write }); | 60 | _, const file = try zigmod.ModFile.openFile(std.fs.cwd(), .{ .mode = .read_write }); |
| 61 | defer file.close(); | 61 | defer file.close(); |
| 62 | try file.seekTo(try file.getEndPos()); | 62 | try file.seekTo(try file.getEndPos()); |
| 63 | 63 |
src/common.zig+5-5| ... | @@ -26,14 +26,14 @@ pub const CollectOptions = struct { | ... | @@ -26,14 +26,14 @@ pub const CollectOptions = struct { |
| 26 | pub fn collect_deps_deep(cachepath: string, mdir: std.fs.Dir, options: *CollectOptions) !zigmod.Module { | 26 | pub fn collect_deps_deep(cachepath: string, mdir: std.fs.Dir, options: *CollectOptions) !zigmod.Module { |
| 27 | try std.fs.cwd().makePath(cachepath); | 27 | try std.fs.cwd().makePath(cachepath); |
| 28 | 28 | ||
| 29 | const m = try zigmod.ModFile.from_dir(options.alloc, mdir); | 29 | const m = try zigmod.ModFile.from_dir(options.alloc, mdir, "."); |
| 30 | try options.init(); | 30 | try options.init(); |
| 31 | var moduledeps = std.ArrayList(zigmod.Module).init(options.alloc); | 31 | var moduledeps = std.ArrayList(zigmod.Module).init(options.alloc); |
| 32 | errdefer moduledeps.deinit(); | 32 | errdefer moduledeps.deinit(); |
| 33 | if (m.root_files.len > 0) { | 33 | if (m.root_files.len > 0) { |
| 34 | try gen_files_package(options.alloc, cachepath, mdir, m.root_files); | 34 | try gen_files_package(options.alloc, cachepath, mdir, m.root_files); |
| 35 | } | 35 | } |
| 36 | try moduledeps.append(try collect_deps(cachepath, mdir, .local, options)); | 36 | try moduledeps.append(try collect_deps(cachepath, mdir, ".", .local, options)); |
| 37 | for (m.rootdeps) |*d| { | 37 | for (m.rootdeps) |*d| { |
| 38 | if (try get_module_from_dep(d, cachepath, options)) |founddep| { | 38 | if (try get_module_from_dep(d, cachepath, options)) |founddep| { |
| 39 | try moduledeps.append(founddep); | 39 | try moduledeps.append(founddep); |
| ... | @@ -57,10 +57,10 @@ pub fn collect_deps_deep(cachepath: string, mdir: std.fs.Dir, options: *CollectO | ... | @@ -57,10 +57,10 @@ pub fn collect_deps_deep(cachepath: string, mdir: std.fs.Dir, options: *CollectO |
| 57 | }; | 57 | }; |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | pub fn collect_deps(cachepath: string, mdir: std.fs.Dir, dtype: zigmod.Dep.Type, options: *CollectOptions) anyerror!zigmod.Module { | 60 | pub fn collect_deps(cachepath: string, mdir: std.fs.Dir, mdir_path: string, dtype: zigmod.Dep.Type, options: *CollectOptions) anyerror!zigmod.Module { |
| 61 | try std.fs.cwd().makePath(cachepath); | 61 | try std.fs.cwd().makePath(cachepath); |
| 62 | 62 | ||
| 63 | const m = try zigmod.ModFile.from_dir(options.alloc, mdir); | 63 | const m = try zigmod.ModFile.from_dir(options.alloc, mdir, mdir_path); |
| 64 | var moduledeps = std.ArrayList(zigmod.Module).init(options.alloc); | 64 | var moduledeps = std.ArrayList(zigmod.Module).init(options.alloc); |
| 65 | errdefer moduledeps.deinit(); | 65 | errdefer moduledeps.deinit(); |
| 66 | if (m.files.len > 0) { | 66 | if (m.files.len > 0) { |
| ... | @@ -244,7 +244,7 @@ pub fn get_module_from_dep(d: *zigmod.Dep, cachepath: string, options: *CollectO | ... | @@ -244,7 +244,7 @@ pub fn get_module_from_dep(d: *zigmod.Dep, cachepath: string, options: *CollectO |
| 244 | }; | 244 | }; |
| 245 | }, | 245 | }, |
| 246 | else => { | 246 | else => { |
| 247 | var dd = collect_deps(cachepath, moddir, d.type, options) catch |e| switch (e) { | 247 | var dd = collect_deps(cachepath, moddir, modpath, d.type, options) catch |e| switch (e) { |
| 248 | error.ManifestNotFound => { | 248 | error.ManifestNotFound => { |
| 249 | if (d.main.len > 0 or d.c_include_dirs.len > 0 or d.c_source_files.len > 0 or d.keep) { | 249 | if (d.main.len > 0 or d.c_include_dirs.len > 0 or d.c_source_files.len > 0 or d.keep) { |
| 250 | var mod_from = try zigmod.Module.from(options.alloc, d.*, cachepath, options); | 250 | var mod_from = try zigmod.Module.from(options.alloc, d.*, cachepath, options); |
src/lib.zig+21| ... | @@ -1,4 +1,8 @@ | ... | @@ -1,4 +1,8 @@ |
| 1 | const std = @import("std"); | ||
| 1 | const zfetch = @import("zfetch"); | 2 | const zfetch = @import("zfetch"); |
| 3 | const extras = @import("extras"); | ||
| 4 | const root = @import("root"); | ||
| 5 | const build_options = root.build_options; | ||
| 2 | 6 | ||
| 3 | pub const commands = struct { | 7 | pub const commands = struct { |
| 4 | pub const version = @import("./cmd/version.zig"); | 8 | pub const version = @import("./cmd/version.zig"); |
| ... | @@ -23,3 +27,20 @@ pub fn deinit() void { | ... | @@ -23,3 +27,20 @@ pub fn deinit() void { |
| 23 | pub const Dep = @import("./util/dep.zig").Dep; | 27 | pub const Dep = @import("./util/dep.zig").Dep; |
| 24 | pub const ModFile = @import("./util/modfile.zig").ModFile; | 28 | pub const ModFile = @import("./util/modfile.zig").ModFile; |
| 25 | pub const Module = @import("./util/module.zig").Module; | 29 | pub const Module = @import("./util/module.zig").Module; |
| 30 | |||
| 31 | pub const version: u16 = blk: { | ||
| 32 | var version_s = build_options.version; | ||
| 33 | version_s = extras.trimPrefixEnsure(version_s, "r").?; | ||
| 34 | version_s = version_s[0 .. std.mem.indexOfScalar(u8, version_s, '-') orelse version_s.len]; | ||
| 35 | var version_i = std.fmt.parseInt(u16, version_s, 10) catch unreachable; | ||
| 36 | if (std.mem.indexOfScalar(u8, version_s, '-')) |_| version_i += 1; | ||
| 37 | break :blk version_i; | ||
| 38 | }; | ||
| 39 | |||
| 40 | pub fn meetsMinimumVersion(min_zigmod_version_raw: []const u8) ?bool { | ||
| 41 | var min_zigmod_version_s = min_zigmod_version_raw; | ||
| 42 | min_zigmod_version_s = extras.trimPrefixEnsure(min_zigmod_version_s, "r") orelse return null; | ||
| 43 | min_zigmod_version_s = min_zigmod_version_s[0 .. std.mem.indexOfScalar(u8, min_zigmod_version_s, '-') orelse min_zigmod_version_s.len]; | ||
| 44 | const min_zigmod_version = std.fmt.parseInt(u16, min_zigmod_version_s, 10) catch return null; | ||
| 45 | return min_zigmod_version <= version; | ||
| 46 | } |
src/util/modfile.zig+23-10| ... | @@ -1,6 +1,9 @@ | ... | @@ -1,6 +1,9 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | const string = []const u8; | 2 | const string = []const u8; |
| 3 | const yaml = @import("yaml"); | 3 | const yaml = @import("yaml"); |
| 4 | const extras = @import("extras"); | ||
| 5 | const root = @import("root"); | ||
| 6 | const build_options = root.build_options; | ||
| 4 | 7 | ||
| 5 | const zigmod = @import("../lib.zig"); | 8 | const zigmod = @import("../lib.zig"); |
| 6 | const u = @import("funcs.zig"); | 9 | const u = @import("funcs.zig"); |
| ... | @@ -29,29 +32,29 @@ pub const ModFile = struct { | ... | @@ -29,29 +32,29 @@ pub const ModFile = struct { |
| 29 | builddeps: []zigmod.Dep, | 32 | builddeps: []zigmod.Dep, |
| 30 | min_zig_version: ?std.SemanticVersion, | 33 | min_zig_version: ?std.SemanticVersion, |
| 31 | 34 | ||
| 32 | pub fn openFile(dir: std.fs.Dir, ops: std.fs.File.OpenFlags) !std.fs.File { | 35 | pub fn openFile(dir: std.fs.Dir, ops: std.fs.File.OpenFlags) !struct { string, std.fs.File } { |
| 33 | return dir.openFile("zig.mod", ops) catch |err| switch (err) { | 36 | return .{ "zig.mod", dir.openFile("zig.mod", ops) catch |err| switch (err) { |
| 34 | error.FileNotFound => dir.openFile("zigmod.yml", ops) catch |err2| switch (err2) { | 37 | error.FileNotFound => return .{ "zigmod.yml", dir.openFile("zigmod.yml", ops) catch |err2| switch (err2) { |
| 35 | error.FileNotFound => return error.ManifestNotFound, | 38 | error.FileNotFound => return error.ManifestNotFound, |
| 36 | else => |e2| return e2, | 39 | else => |e2| return e2, |
| 37 | }, | 40 | } }, |
| 38 | else => |e| return e, | 41 | else => |e| return e, |
| 39 | }; | 42 | } }; |
| 40 | } | 43 | } |
| 41 | 44 | ||
| 42 | pub fn init(alloc: std.mem.Allocator) !Self { | 45 | pub fn init(alloc: std.mem.Allocator) !Self { |
| 43 | return try from_dir(alloc, std.fs.cwd()); | 46 | return try from_dir(alloc, std.fs.cwd(), "."); |
| 44 | } | 47 | } |
| 45 | 48 | ||
| 46 | pub fn from_dir(alloc: std.mem.Allocator, dir: std.fs.Dir) !Self { | 49 | pub fn from_dir(alloc: std.mem.Allocator, dir: std.fs.Dir, dir_path: string) !Self { |
| 47 | const file = try openFile(dir, .{}); | 50 | const file_path, const file = try openFile(dir, .{}); |
| 48 | defer file.close(); | 51 | defer file.close(); |
| 49 | const input = try file.reader().readAllAlloc(alloc, mb); | 52 | const input = try file.reader().readAllAlloc(alloc, mb); |
| 50 | const doc = try yaml.parse(alloc, input); | 53 | const doc = try yaml.parse(alloc, input); |
| 51 | return from_mapping(alloc, doc.mapping); | 54 | return from_mapping(alloc, doc.mapping, dir_path, file_path); |
| 52 | } | 55 | } |
| 53 | 56 | ||
| 54 | pub fn from_mapping(alloc: std.mem.Allocator, mapping: yaml.Mapping) !Self { | 57 | pub fn from_mapping(alloc: std.mem.Allocator, mapping: yaml.Mapping, dir_path: string, file_path: string) !Self { |
| 55 | var id = zigmod.Dep.EMPTY; | 58 | var id = zigmod.Dep.EMPTY; |
| 56 | std.mem.copyForwards(u8, &id, mapping.get_string("id") orelse &u.random_string(48)); | 59 | std.mem.copyForwards(u8, &id, mapping.get_string("id") orelse &u.random_string(48)); |
| 57 | 60 | ||
| ... | @@ -62,6 +65,16 @@ pub const ModFile = struct { | ... | @@ -62,6 +65,16 @@ pub const ModFile = struct { |
| 62 | u.fail("name may not contain any '/'", .{}); | 65 | u.fail("name may not contain any '/'", .{}); |
| 63 | } | 66 | } |
| 64 | 67 | ||
| 68 | if (mapping.get_string("min_zigmod_version")) |min_zigmod_version_raw| { | ||
| 69 | const meets = zigmod.meetsMinimumVersion(min_zigmod_version_raw); | ||
| 70 | if (meets == null) { | ||
| 71 | u.fail("invalid min_zigmod_version: {s}", .{min_zigmod_version_raw}); | ||
| 72 | } | ||
| 73 | if (meets.? == false) { | ||
| 74 | u.fail("Your Zigmod version {s} does not meet the minimum of {s} required by {s}{s}{s}", .{ build_options.version, min_zigmod_version_raw, dir_path, std.fs.path.sep_str, file_path }); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 65 | return Self{ | 78 | return Self{ |
| 66 | .id = id, | 79 | .id = id, |
| 67 | .name = name, | 80 | .name = name, |
zig.mod+1| ... | @@ -4,6 +4,7 @@ main: src/lib.zig | ... | @@ -4,6 +4,7 @@ main: src/lib.zig |
| 4 | license: MIT | 4 | license: MIT |
| 5 | description: A package manager for the Zig programming language. | 5 | description: A package manager for the Zig programming language. |
| 6 | min_zig_version: 0.14.0 | 6 | min_zig_version: 0.14.0 |
| 7 | min_zigmod_version: r96 | ||
| 7 | dependencies: | 8 | dependencies: |
| 8 | - src: git https://github.com/nektro/zig-yaml | 9 | - src: git https://github.com/nektro/zig-yaml |
| 9 | - src: git https://github.com/nektro/zig-ansi | 10 | - src: git https://github.com/nektro/zig-ansi |