mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
zig fetch: add --save flag
``` --save Add the fetched package to build.zig.zon --save=[name] Add the fetched package to build.zig.zon as name ```
This commit is contained in:
parent
a0c8d54823
commit
0c0b69891a
@ -61,7 +61,7 @@ String.
|
|||||||
|
|
||||||
When this is provided, the package is found in a directory relative to the
|
When this is provided, the package is found in a directory relative to the
|
||||||
build root. In this case the package's hash is irrelevant and therefore not
|
build root. In this case the package's hash is irrelevant and therefore not
|
||||||
computed.
|
computed. This field and `url` are mutually exclusive.
|
||||||
|
|
||||||
### `paths`
|
### `paths`
|
||||||
|
|
||||||
|
|||||||
@ -15,8 +15,7 @@
|
|||||||
// Once all dependencies are fetched, `zig build` no longer requires
|
// Once all dependencies are fetched, `zig build` no longer requires
|
||||||
// Internet connectivity.
|
// Internet connectivity.
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
// A future version of Zig will provide a `zig add <url>` subcommand
|
// See `zig fetch --save <url>` for a command-line interface for adding dependencies.
|
||||||
// for easily adding dependencies.
|
|
||||||
//.example = .{
|
//.example = .{
|
||||||
// // When updating this field to a new URL, be sure to delete the corresponding
|
// // When updating this field to a new URL, be sure to delete the corresponding
|
||||||
// // `hash`, otherwise you are communicating that you expect to find the old hash at
|
// // `hash`, otherwise you are communicating that you expect to find the old hash at
|
||||||
@ -36,7 +35,7 @@
|
|||||||
//
|
//
|
||||||
// // When this is provided, the package is found in a directory relative to the
|
// // When this is provided, the package is found in a directory relative to the
|
||||||
// // build root. In this case the package's hash is irrelevant and therefore not
|
// // build root. In this case the package's hash is irrelevant and therefore not
|
||||||
// // computed.
|
// // computed. This field and `url` are mutually exclusive.
|
||||||
// .path = "foo",
|
// .path = "foo",
|
||||||
//},
|
//},
|
||||||
},
|
},
|
||||||
@ -57,5 +56,7 @@
|
|||||||
//"build.zig",
|
//"build.zig",
|
||||||
//"build.zig.zon",
|
//"build.zig.zon",
|
||||||
//"src",
|
//"src",
|
||||||
|
//"LICENSE",
|
||||||
|
//"README.md",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
445
src/main.zig
445
src/main.zig
@ -1255,7 +1255,7 @@ fn buildOutputType(
|
|||||||
override_lib_dir = args_iter.nextOrFatal();
|
override_lib_dir = args_iter.nextOrFatal();
|
||||||
} else if (mem.eql(u8, arg, "--debug-log")) {
|
} else if (mem.eql(u8, arg, "--debug-log")) {
|
||||||
if (!build_options.enable_logging) {
|
if (!build_options.enable_logging) {
|
||||||
std.log.warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{});
|
warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{});
|
||||||
_ = args_iter.nextOrFatal();
|
_ = args_iter.nextOrFatal();
|
||||||
} else {
|
} else {
|
||||||
try log_scopes.append(gpa, args_iter.nextOrFatal());
|
try log_scopes.append(gpa, args_iter.nextOrFatal());
|
||||||
@ -1279,7 +1279,7 @@ fn buildOutputType(
|
|||||||
listen = .stdio;
|
listen = .stdio;
|
||||||
} else if (mem.eql(u8, arg, "--debug-link-snapshot")) {
|
} else if (mem.eql(u8, arg, "--debug-link-snapshot")) {
|
||||||
if (!build_options.enable_link_snapshots) {
|
if (!build_options.enable_link_snapshots) {
|
||||||
std.log.warn("Zig was compiled without linker snapshots enabled (-Dlink-snapshot). --debug-link-snapshot has no effect.", .{});
|
warn("Zig was compiled without linker snapshots enabled (-Dlink-snapshot). --debug-link-snapshot has no effect.", .{});
|
||||||
} else {
|
} else {
|
||||||
enable_link_snapshots = true;
|
enable_link_snapshots = true;
|
||||||
}
|
}
|
||||||
@ -1558,7 +1558,7 @@ fn buildOutputType(
|
|||||||
};
|
};
|
||||||
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
|
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
|
||||||
if (!crash_report.is_enabled) {
|
if (!crash_report.is_enabled) {
|
||||||
std.log.warn("Zig was compiled in a release mode. --debug-compile-errors has no effect.", .{});
|
warn("Zig was compiled in a release mode. --debug-compile-errors has no effect.", .{});
|
||||||
} else {
|
} else {
|
||||||
debug_compile_errors = true;
|
debug_compile_errors = true;
|
||||||
}
|
}
|
||||||
@ -1662,7 +1662,7 @@ fn buildOutputType(
|
|||||||
},
|
},
|
||||||
.def, .unknown => {
|
.def, .unknown => {
|
||||||
if (std.ascii.eqlIgnoreCase(".xml", std.fs.path.extension(arg))) {
|
if (std.ascii.eqlIgnoreCase(".xml", std.fs.path.extension(arg))) {
|
||||||
std.log.warn("embedded manifest files must have the extension '.manifest'", .{});
|
warn("embedded manifest files must have the extension '.manifest'", .{});
|
||||||
}
|
}
|
||||||
fatal("unrecognized file extension of parameter '{s}'", .{arg});
|
fatal("unrecognized file extension of parameter '{s}'", .{arg});
|
||||||
},
|
},
|
||||||
@ -2793,7 +2793,7 @@ fn buildOutputType(
|
|||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
.only_compiler_rt => {
|
.only_compiler_rt => {
|
||||||
std.log.warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name});
|
warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name});
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -4851,7 +4851,6 @@ pub const usage_init =
|
|||||||
;
|
;
|
||||||
|
|
||||||
pub fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
pub fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
|
||||||
_ = gpa;
|
|
||||||
{
|
{
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < args.len) : (i += 1) {
|
while (i < args.len) : (i += 1) {
|
||||||
@ -4868,58 +4867,24 @@ pub fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const self_exe_path = try introspect.findZigExePath(arena);
|
|
||||||
var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| {
|
|
||||||
fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)});
|
|
||||||
};
|
|
||||||
defer zig_lib_directory.handle.close();
|
|
||||||
|
|
||||||
const s = fs.path.sep_str;
|
var templates = findTemplates(gpa, arena);
|
||||||
const template_sub_path = "init";
|
defer templates.deinit();
|
||||||
var template_dir = zig_lib_directory.handle.openDir(template_sub_path, .{}) catch |err| {
|
|
||||||
const path = zig_lib_directory.path orelse ".";
|
|
||||||
fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{
|
|
||||||
path, s, template_sub_path, @errorName(err),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
defer template_dir.close();
|
|
||||||
|
|
||||||
const cwd_path = try process.getCwdAlloc(arena);
|
const cwd_path = try process.getCwdAlloc(arena);
|
||||||
const cwd_basename = fs.path.basename(cwd_path);
|
const cwd_basename = fs.path.basename(cwd_path);
|
||||||
|
|
||||||
const max_bytes = 10 * 1024 * 1024;
|
const s = fs.path.sep_str;
|
||||||
const template_paths = [_][]const u8{
|
const template_paths = [_][]const u8{
|
||||||
"build.zig",
|
Package.build_zig_basename,
|
||||||
"build.zig.zon",
|
Package.Manifest.basename,
|
||||||
"src" ++ s ++ "main.zig",
|
"src" ++ s ++ "main.zig",
|
||||||
"src" ++ s ++ "root.zig",
|
"src" ++ s ++ "root.zig",
|
||||||
};
|
};
|
||||||
var ok_count: usize = 0;
|
var ok_count: usize = 0;
|
||||||
|
|
||||||
for (template_paths) |template_path| {
|
for (template_paths) |template_path| {
|
||||||
if (fs.path.dirname(template_path)) |dirname| {
|
if (templates.write(arena, fs.cwd(), cwd_basename, template_path)) |_| {
|
||||||
fs.cwd().makePath(dirname) catch |err| {
|
|
||||||
fatal("unable to make path '{s}': {s}", .{ dirname, @errorName(err) });
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const contents = template_dir.readFileAlloc(arena, template_path, max_bytes) catch |err| {
|
|
||||||
fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) });
|
|
||||||
};
|
|
||||||
var modified_contents = try std.ArrayList(u8).initCapacity(arena, contents.len);
|
|
||||||
for (contents) |c| {
|
|
||||||
if (c == '$') {
|
|
||||||
try modified_contents.appendSlice(cwd_basename);
|
|
||||||
} else {
|
|
||||||
try modified_contents.append(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fs.cwd().writeFile2(.{
|
|
||||||
.sub_path = template_path,
|
|
||||||
.data = modified_contents.items,
|
|
||||||
.flags = .{ .exclusive = true },
|
|
||||||
})) |_| {
|
|
||||||
std.log.info("created {s}", .{template_path});
|
std.log.info("created {s}", .{template_path});
|
||||||
ok_count += 1;
|
ok_count += 1;
|
||||||
} else |err| switch (err) {
|
} else |err| switch (err) {
|
||||||
@ -5057,14 +5022,14 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
|
|||||||
try child_argv.appendSlice(args[i .. i + 2]);
|
try child_argv.appendSlice(args[i .. i + 2]);
|
||||||
i += 1;
|
i += 1;
|
||||||
if (!build_options.enable_logging) {
|
if (!build_options.enable_logging) {
|
||||||
std.log.warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{});
|
warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{});
|
||||||
} else {
|
} else {
|
||||||
try log_scopes.append(gpa, args[i]);
|
try log_scopes.append(gpa, args[i]);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
|
} else if (mem.eql(u8, arg, "--debug-compile-errors")) {
|
||||||
if (!crash_report.is_enabled) {
|
if (!crash_report.is_enabled) {
|
||||||
std.log.warn("Zig was compiled in a release mode. --debug-compile-errors has no effect.", .{});
|
warn("Zig was compiled in a release mode. --debug-compile-errors has no effect.", .{});
|
||||||
} else {
|
} else {
|
||||||
debug_compile_errors = true;
|
debug_compile_errors = true;
|
||||||
}
|
}
|
||||||
@ -5113,44 +5078,11 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
|
|||||||
defer if (cleanup_build_dir) |*dir| dir.close();
|
defer if (cleanup_build_dir) |*dir| dir.close();
|
||||||
|
|
||||||
const cwd_path = try process.getCwdAlloc(arena);
|
const cwd_path = try process.getCwdAlloc(arena);
|
||||||
const build_zig_basename = if (build_file) |bf| fs.path.basename(bf) else Package.build_zig_basename;
|
const build_root = try findBuildRoot(arena, .{
|
||||||
const build_root: Compilation.Directory = blk: {
|
.cwd_path = cwd_path,
|
||||||
if (build_file) |bf| {
|
.build_file = build_file,
|
||||||
if (fs.path.dirname(bf)) |dirname| {
|
|
||||||
const dir = fs.cwd().openDir(dirname, .{}) catch |err| {
|
|
||||||
fatal("unable to open directory to build file from argument 'build-file', '{s}': {s}", .{ dirname, @errorName(err) });
|
|
||||||
};
|
|
||||||
cleanup_build_dir = dir;
|
|
||||||
break :blk .{ .path = dirname, .handle = dir };
|
|
||||||
}
|
|
||||||
|
|
||||||
break :blk .{ .path = null, .handle = fs.cwd() };
|
|
||||||
}
|
|
||||||
// Search up parent directories until we find build.zig.
|
|
||||||
var dirname: []const u8 = cwd_path;
|
|
||||||
while (true) {
|
|
||||||
const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename });
|
|
||||||
if (fs.cwd().access(joined_path, .{})) |_| {
|
|
||||||
const dir = fs.cwd().openDir(dirname, .{}) catch |err| {
|
|
||||||
fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) });
|
|
||||||
};
|
|
||||||
break :blk .{ .path = dirname, .handle = dir };
|
|
||||||
} else |err| switch (err) {
|
|
||||||
error.FileNotFound => {
|
|
||||||
dirname = fs.path.dirname(dirname) orelse {
|
|
||||||
std.log.info("{s}", .{
|
|
||||||
\\Initialize a 'build.zig' template file with `zig init-lib` or `zig init-exe`,
|
|
||||||
\\or see `zig --help` for more options.
|
|
||||||
});
|
});
|
||||||
fatal("No 'build.zig' file found, in the current directory or any parent directories.", .{});
|
child_argv.items[argv_index_build_file] = build_root.directory.path orelse cwd_path;
|
||||||
};
|
|
||||||
continue;
|
|
||||||
},
|
|
||||||
else => |e| return e,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
child_argv.items[argv_index_build_file] = build_root.path orelse cwd_path;
|
|
||||||
|
|
||||||
var global_cache_directory: Compilation.Directory = l: {
|
var global_cache_directory: Compilation.Directory = l: {
|
||||||
const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena);
|
const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena);
|
||||||
@ -5170,9 +5102,9 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
|
|||||||
.path = local_cache_dir_path,
|
.path = local_cache_dir_path,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const cache_dir_path = try build_root.join(arena, &[_][]const u8{"zig-cache"});
|
const cache_dir_path = try build_root.directory.join(arena, &[_][]const u8{"zig-cache"});
|
||||||
break :l .{
|
break :l .{
|
||||||
.handle = try build_root.handle.makeOpenPath("zig-cache", .{}),
|
.handle = try build_root.directory.handle.makeOpenPath("zig-cache", .{}),
|
||||||
.path = cache_dir_path,
|
.path = cache_dir_path,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -5215,8 +5147,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
|
|||||||
};
|
};
|
||||||
|
|
||||||
var build_mod: Package.Module = .{
|
var build_mod: Package.Module = .{
|
||||||
.root = .{ .root_dir = build_root },
|
.root = .{ .root_dir = build_root.directory },
|
||||||
.root_src_path = build_zig_basename,
|
.root_src_path = build_root.build_zig_basename,
|
||||||
.fully_qualified_name = "root.@build",
|
.fully_qualified_name = "root.@build",
|
||||||
};
|
};
|
||||||
if (build_options.only_core_functionality) {
|
if (build_options.only_core_functionality) {
|
||||||
@ -6904,40 +6836,40 @@ const ClangSearchSanitizer = struct {
|
|||||||
.I => {
|
.I => {
|
||||||
if (m.I) return;
|
if (m.I) return;
|
||||||
m.I = true;
|
m.I = true;
|
||||||
if (m.isystem) std.log.warn(wtxt, .{ dir, "I", "isystem" });
|
if (m.isystem) warn(wtxt, .{ dir, "I", "isystem" });
|
||||||
if (m.idirafter) std.log.warn(wtxt, .{ dir, "I", "idirafter" });
|
if (m.idirafter) warn(wtxt, .{ dir, "I", "idirafter" });
|
||||||
if (m.iframework) std.log.warn(wtxt, .{ dir, "I", "iframework" });
|
if (m.iframework) warn(wtxt, .{ dir, "I", "iframework" });
|
||||||
},
|
},
|
||||||
.isystem => {
|
.isystem => {
|
||||||
if (m.isystem) return;
|
if (m.isystem) return;
|
||||||
m.isystem = true;
|
m.isystem = true;
|
||||||
if (m.I) std.log.warn(wtxt, .{ dir, "isystem", "I" });
|
if (m.I) warn(wtxt, .{ dir, "isystem", "I" });
|
||||||
if (m.idirafter) std.log.warn(wtxt, .{ dir, "isystem", "idirafter" });
|
if (m.idirafter) warn(wtxt, .{ dir, "isystem", "idirafter" });
|
||||||
if (m.iframework) std.log.warn(wtxt, .{ dir, "isystem", "iframework" });
|
if (m.iframework) warn(wtxt, .{ dir, "isystem", "iframework" });
|
||||||
},
|
},
|
||||||
.iwithsysroot => {
|
.iwithsysroot => {
|
||||||
if (m.iwithsysroot) return;
|
if (m.iwithsysroot) return;
|
||||||
m.iwithsysroot = true;
|
m.iwithsysroot = true;
|
||||||
if (m.iframeworkwithsysroot) std.log.warn(wtxt, .{ dir, "iwithsysroot", "iframeworkwithsysroot" });
|
if (m.iframeworkwithsysroot) warn(wtxt, .{ dir, "iwithsysroot", "iframeworkwithsysroot" });
|
||||||
},
|
},
|
||||||
.idirafter => {
|
.idirafter => {
|
||||||
if (m.idirafter) return;
|
if (m.idirafter) return;
|
||||||
m.idirafter = true;
|
m.idirafter = true;
|
||||||
if (m.I) std.log.warn(wtxt, .{ dir, "idirafter", "I" });
|
if (m.I) warn(wtxt, .{ dir, "idirafter", "I" });
|
||||||
if (m.isystem) std.log.warn(wtxt, .{ dir, "idirafter", "isystem" });
|
if (m.isystem) warn(wtxt, .{ dir, "idirafter", "isystem" });
|
||||||
if (m.iframework) std.log.warn(wtxt, .{ dir, "idirafter", "iframework" });
|
if (m.iframework) warn(wtxt, .{ dir, "idirafter", "iframework" });
|
||||||
},
|
},
|
||||||
.iframework => {
|
.iframework => {
|
||||||
if (m.iframework) return;
|
if (m.iframework) return;
|
||||||
m.iframework = true;
|
m.iframework = true;
|
||||||
if (m.I) std.log.warn(wtxt, .{ dir, "iframework", "I" });
|
if (m.I) warn(wtxt, .{ dir, "iframework", "I" });
|
||||||
if (m.isystem) std.log.warn(wtxt, .{ dir, "iframework", "isystem" });
|
if (m.isystem) warn(wtxt, .{ dir, "iframework", "isystem" });
|
||||||
if (m.idirafter) std.log.warn(wtxt, .{ dir, "iframework", "idirafter" });
|
if (m.idirafter) warn(wtxt, .{ dir, "iframework", "idirafter" });
|
||||||
},
|
},
|
||||||
.iframeworkwithsysroot => {
|
.iframeworkwithsysroot => {
|
||||||
if (m.iframeworkwithsysroot) return;
|
if (m.iframeworkwithsysroot) return;
|
||||||
m.iframeworkwithsysroot = true;
|
m.iframeworkwithsysroot = true;
|
||||||
if (m.iwithsysroot) std.log.warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" });
|
if (m.iwithsysroot) warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" });
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
try self.argv.append(arg);
|
try self.argv.append(arg);
|
||||||
@ -7097,6 +7029,8 @@ pub const usage_fetch =
|
|||||||
\\ -h, --help Print this help and exit
|
\\ -h, --help Print this help and exit
|
||||||
\\ --global-cache-dir [path] Override path to global Zig cache directory
|
\\ --global-cache-dir [path] Override path to global Zig cache directory
|
||||||
\\ --debug-hash Print verbose hash information to stdout
|
\\ --debug-hash Print verbose hash information to stdout
|
||||||
|
\\ --save Add the fetched package to build.zig.zon
|
||||||
|
\\ --save=[name] Add the fetched package to build.zig.zon as name
|
||||||
\\
|
\\
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -7111,6 +7045,7 @@ fn cmdFetch(
|
|||||||
var opt_path_or_url: ?[]const u8 = null;
|
var opt_path_or_url: ?[]const u8 = null;
|
||||||
var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
|
var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
|
||||||
var debug_hash: bool = false;
|
var debug_hash: bool = false;
|
||||||
|
var save: union(enum) { no, yes, name: []const u8 } = .no;
|
||||||
|
|
||||||
{
|
{
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
@ -7125,10 +7060,12 @@ fn cmdFetch(
|
|||||||
if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg});
|
if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg});
|
||||||
i += 1;
|
i += 1;
|
||||||
override_global_cache_dir = args[i];
|
override_global_cache_dir = args[i];
|
||||||
continue;
|
|
||||||
} else if (mem.eql(u8, arg, "--debug-hash")) {
|
} else if (mem.eql(u8, arg, "--debug-hash")) {
|
||||||
debug_hash = true;
|
debug_hash = true;
|
||||||
continue;
|
} else if (mem.eql(u8, arg, "--save")) {
|
||||||
|
save = .yes;
|
||||||
|
} else if (mem.startsWith(u8, arg, "--save=")) {
|
||||||
|
save = .{ .name = arg["--save=".len..] };
|
||||||
} else {
|
} else {
|
||||||
fatal("unrecognized parameter: '{s}'", .{arg});
|
fatal("unrecognized parameter: '{s}'", .{arg});
|
||||||
}
|
}
|
||||||
@ -7214,7 +7151,97 @@ fn cmdFetch(
|
|||||||
progress.done = true;
|
progress.done = true;
|
||||||
progress.refresh();
|
progress.refresh();
|
||||||
|
|
||||||
|
const name = switch (save) {
|
||||||
|
.no => {
|
||||||
try io.getStdOut().writeAll(hex_digest ++ "\n");
|
try io.getStdOut().writeAll(hex_digest ++ "\n");
|
||||||
|
return cleanExit();
|
||||||
|
},
|
||||||
|
.yes => n: {
|
||||||
|
const fetched_manifest = fetch.manifest orelse
|
||||||
|
fatal("unable to determine name; fetched package has no build.zig.zon file", .{});
|
||||||
|
break :n fetched_manifest.name;
|
||||||
|
},
|
||||||
|
.name => |n| n,
|
||||||
|
};
|
||||||
|
|
||||||
|
const cwd_path = try process.getCwdAlloc(arena);
|
||||||
|
|
||||||
|
var build_root = try findBuildRoot(arena, .{
|
||||||
|
.cwd_path = cwd_path,
|
||||||
|
});
|
||||||
|
defer build_root.deinit();
|
||||||
|
|
||||||
|
// The name to use in case the manifest file needs to be created now.
|
||||||
|
const init_root_name = fs.path.basename(build_root.directory.path orelse cwd_path);
|
||||||
|
var manifest, var ast = try loadManifest(gpa, arena, .{
|
||||||
|
.root_name = init_root_name,
|
||||||
|
.dir = build_root.directory.handle,
|
||||||
|
.color = color,
|
||||||
|
});
|
||||||
|
defer {
|
||||||
|
manifest.deinit(gpa);
|
||||||
|
ast.deinit(gpa);
|
||||||
|
}
|
||||||
|
|
||||||
|
var fixups: Ast.Fixups = .{};
|
||||||
|
defer fixups.deinit(gpa);
|
||||||
|
|
||||||
|
const new_node_init = try std.fmt.allocPrint(arena,
|
||||||
|
\\.{{
|
||||||
|
\\ .url = "{}",
|
||||||
|
\\ .hash = "{}",
|
||||||
|
\\ }}
|
||||||
|
, .{
|
||||||
|
std.zig.fmtEscapes(path_or_url),
|
||||||
|
std.zig.fmtEscapes(&hex_digest),
|
||||||
|
});
|
||||||
|
|
||||||
|
const new_node_text = try std.fmt.allocPrint(arena, ".{} = {s},\n", .{
|
||||||
|
std.zig.fmtId(name), new_node_init,
|
||||||
|
});
|
||||||
|
|
||||||
|
const dependencies_init = try std.fmt.allocPrint(arena, ".{{\n {s} }}", .{
|
||||||
|
new_node_text,
|
||||||
|
});
|
||||||
|
|
||||||
|
const dependencies_text = try std.fmt.allocPrint(arena, ".dependencies = {s},\n", .{
|
||||||
|
dependencies_init,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (manifest.dependencies.get(name)) |dep| {
|
||||||
|
if (dep.hash) |h| {
|
||||||
|
switch (dep.location) {
|
||||||
|
.url => |u| {
|
||||||
|
if (mem.eql(u8, h, &hex_digest) and mem.eql(u8, u, path_or_url)) {
|
||||||
|
std.log.info("existing dependency named '{s}' is up-to-date", .{name});
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
.path => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
warn("overwriting existing dependency named '{s}'", .{name});
|
||||||
|
try fixups.replace_nodes_with_string.put(gpa, dep.node, new_node_init);
|
||||||
|
} else if (manifest.dependencies.count() > 0) {
|
||||||
|
// Add fixup for adding another dependency.
|
||||||
|
const deps = manifest.dependencies.values();
|
||||||
|
const last_dep_node = deps[deps.len - 1].node;
|
||||||
|
try fixups.append_string_after_node.put(gpa, last_dep_node, new_node_text);
|
||||||
|
} else if (manifest.dependencies_node != 0) {
|
||||||
|
// Add fixup for replacing the entire dependencies struct.
|
||||||
|
try fixups.replace_nodes_with_string.put(gpa, manifest.dependencies_node, dependencies_init);
|
||||||
|
} else {
|
||||||
|
// Add fixup for adding dependencies struct.
|
||||||
|
try fixups.append_string_after_node.put(gpa, manifest.version_node, dependencies_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
var rendered = std.ArrayList(u8).init(gpa);
|
||||||
|
defer rendered.deinit();
|
||||||
|
try ast.renderToArrayList(&rendered, fixups);
|
||||||
|
|
||||||
|
build_root.directory.handle.writeFile(Package.Manifest.basename, rendered.items) catch |err| {
|
||||||
|
fatal("unable to write {s} file: {s}", .{ Package.Manifest.basename, @errorName(err) });
|
||||||
|
};
|
||||||
|
|
||||||
return cleanExit();
|
return cleanExit();
|
||||||
}
|
}
|
||||||
@ -7279,3 +7306,211 @@ fn defaultWasmEntryName(exec_model: ?std.builtin.WasiExecModel) []const u8 {
|
|||||||
}
|
}
|
||||||
return "_start";
|
return "_start";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BuildRoot = struct {
|
||||||
|
directory: Cache.Directory,
|
||||||
|
build_zig_basename: []const u8,
|
||||||
|
cleanup_build_dir: ?fs.Dir,
|
||||||
|
|
||||||
|
fn deinit(br: *BuildRoot) void {
|
||||||
|
if (br.cleanup_build_dir) |*dir| dir.close();
|
||||||
|
br.* = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const FindBuildRootOptions = struct {
|
||||||
|
build_file: ?[]const u8 = null,
|
||||||
|
cwd_path: ?[]const u8 = null,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot {
|
||||||
|
const cwd_path = options.cwd_path orelse try process.getCwdAlloc(arena);
|
||||||
|
const build_zig_basename = if (options.build_file) |bf|
|
||||||
|
fs.path.basename(bf)
|
||||||
|
else
|
||||||
|
Package.build_zig_basename;
|
||||||
|
|
||||||
|
if (options.build_file) |bf| {
|
||||||
|
if (fs.path.dirname(bf)) |dirname| {
|
||||||
|
const dir = fs.cwd().openDir(dirname, .{}) catch |err| {
|
||||||
|
fatal("unable to open directory to build file from argument 'build-file', '{s}': {s}", .{ dirname, @errorName(err) });
|
||||||
|
};
|
||||||
|
return .{
|
||||||
|
.build_zig_basename = build_zig_basename,
|
||||||
|
.directory = .{ .path = dirname, .handle = dir },
|
||||||
|
.cleanup_build_dir = dir,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.build_zig_basename = build_zig_basename,
|
||||||
|
.directory = .{ .path = null, .handle = fs.cwd() },
|
||||||
|
.cleanup_build_dir = null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// Search up parent directories until we find build.zig.
|
||||||
|
var dirname: []const u8 = cwd_path;
|
||||||
|
while (true) {
|
||||||
|
const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename });
|
||||||
|
if (fs.cwd().access(joined_path, .{})) |_| {
|
||||||
|
const dir = fs.cwd().openDir(dirname, .{}) catch |err| {
|
||||||
|
fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) });
|
||||||
|
};
|
||||||
|
return .{
|
||||||
|
.build_zig_basename = build_zig_basename,
|
||||||
|
.directory = .{
|
||||||
|
.path = dirname,
|
||||||
|
.handle = dir,
|
||||||
|
},
|
||||||
|
.cleanup_build_dir = dir,
|
||||||
|
};
|
||||||
|
} else |err| switch (err) {
|
||||||
|
error.FileNotFound => {
|
||||||
|
dirname = fs.path.dirname(dirname) orelse {
|
||||||
|
std.log.info("initialize {s} template file with 'zig init'", .{
|
||||||
|
Package.build_zig_basename,
|
||||||
|
});
|
||||||
|
std.log.info("see 'zig --help' for more options", .{});
|
||||||
|
fatal("no build.zig file found, in the current directory or any parent directories", .{});
|
||||||
|
};
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
else => |e| return e,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const LoadManifestOptions = struct {
|
||||||
|
root_name: []const u8,
|
||||||
|
dir: fs.Dir,
|
||||||
|
color: Color,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn loadManifest(
|
||||||
|
gpa: Allocator,
|
||||||
|
arena: Allocator,
|
||||||
|
options: LoadManifestOptions,
|
||||||
|
) !struct { Package.Manifest, Ast } {
|
||||||
|
const manifest_bytes = while (true) {
|
||||||
|
break options.dir.readFileAllocOptions(
|
||||||
|
arena,
|
||||||
|
Package.Manifest.basename,
|
||||||
|
Package.Manifest.max_bytes,
|
||||||
|
null,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
) catch |err| switch (err) {
|
||||||
|
error.FileNotFound => {
|
||||||
|
var templates = findTemplates(gpa, arena);
|
||||||
|
defer templates.deinit();
|
||||||
|
|
||||||
|
templates.write(arena, options.dir, options.root_name, Package.Manifest.basename) catch |e| {
|
||||||
|
fatal("unable to write {s}: {s}", .{
|
||||||
|
Package.Manifest.basename, @errorName(e),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
else => |e| fatal("unable to load {s}: {s}", .{
|
||||||
|
Package.Manifest.basename, @errorName(e),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
var ast = try Ast.parse(gpa, manifest_bytes, .zon);
|
||||||
|
errdefer ast.deinit(gpa);
|
||||||
|
|
||||||
|
if (ast.errors.len > 0) {
|
||||||
|
try printAstErrorsToStderr(gpa, ast, Package.Manifest.basename, options.color);
|
||||||
|
process.exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
var manifest = try Package.Manifest.parse(gpa, ast, .{});
|
||||||
|
errdefer manifest.deinit(gpa);
|
||||||
|
|
||||||
|
if (manifest.errors.len > 0) {
|
||||||
|
var wip_errors: std.zig.ErrorBundle.Wip = undefined;
|
||||||
|
try wip_errors.init(gpa);
|
||||||
|
defer wip_errors.deinit();
|
||||||
|
|
||||||
|
const src_path = try wip_errors.addString(Package.Manifest.basename);
|
||||||
|
try manifest.copyErrorsIntoBundle(ast, src_path, &wip_errors);
|
||||||
|
|
||||||
|
var error_bundle = try wip_errors.toOwnedBundle("");
|
||||||
|
defer error_bundle.deinit(gpa);
|
||||||
|
error_bundle.renderToStdErr(renderOptions(options.color));
|
||||||
|
|
||||||
|
process.exit(2);
|
||||||
|
}
|
||||||
|
return .{ manifest, ast };
|
||||||
|
}
|
||||||
|
|
||||||
|
const Templates = struct {
|
||||||
|
zig_lib_directory: Cache.Directory,
|
||||||
|
dir: fs.Dir,
|
||||||
|
buffer: std.ArrayList(u8),
|
||||||
|
|
||||||
|
fn deinit(templates: *Templates) void {
|
||||||
|
templates.zig_lib_directory.handle.close();
|
||||||
|
templates.dir.close();
|
||||||
|
templates.buffer.deinit();
|
||||||
|
templates.* = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn write(
|
||||||
|
templates: *Templates,
|
||||||
|
arena: Allocator,
|
||||||
|
out_dir: fs.Dir,
|
||||||
|
root_name: []const u8,
|
||||||
|
template_path: []const u8,
|
||||||
|
) !void {
|
||||||
|
if (fs.path.dirname(template_path)) |dirname| {
|
||||||
|
out_dir.makePath(dirname) catch |err| {
|
||||||
|
fatal("unable to make path '{s}': {s}", .{ dirname, @errorName(err) });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const max_bytes = 10 * 1024 * 1024;
|
||||||
|
const contents = templates.dir.readFileAlloc(arena, template_path, max_bytes) catch |err| {
|
||||||
|
fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) });
|
||||||
|
};
|
||||||
|
templates.buffer.clearRetainingCapacity();
|
||||||
|
try templates.buffer.ensureUnusedCapacity(contents.len);
|
||||||
|
for (contents) |c| {
|
||||||
|
if (c == '$') {
|
||||||
|
try templates.buffer.appendSlice(root_name);
|
||||||
|
} else {
|
||||||
|
try templates.buffer.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out_dir.writeFile2(.{
|
||||||
|
.sub_path = template_path,
|
||||||
|
.data = templates.buffer.items,
|
||||||
|
.flags = .{ .exclusive = true },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fn findTemplates(gpa: Allocator, arena: Allocator) Templates {
|
||||||
|
const self_exe_path = introspect.findZigExePath(arena) catch |err| {
|
||||||
|
fatal("unable to find self exe path: {s}", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| {
|
||||||
|
fatal("unable to find zig installation directory: {s}", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
|
||||||
|
const s = fs.path.sep_str;
|
||||||
|
const template_sub_path = "init";
|
||||||
|
const template_dir = zig_lib_directory.handle.openDir(template_sub_path, .{}) catch |err| {
|
||||||
|
const path = zig_lib_directory.path orelse ".";
|
||||||
|
fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{
|
||||||
|
path, s, template_sub_path, @errorName(err),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.zig_lib_directory = zig_lib_directory,
|
||||||
|
.dir = template_dir,
|
||||||
|
.buffer = std.ArrayList(u8).init(gpa),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user