| ... | @@ -1255,7 +1255,7 @@ fn buildOutputType( | ... | @@ -1255,7 +1255,7 @@ fn buildOutputType( |
| 1255 | override_lib_dir = args_iter.nextOrFatal(); | 1255 | override_lib_dir = args_iter.nextOrFatal(); |
| 1256 | } else if (mem.eql(u8, arg, "--debug-log")) { | 1256 | } else if (mem.eql(u8, arg, "--debug-log")) { |
| 1257 | if (!build_options.enable_logging) { | 1257 | if (!build_options.enable_logging) { |
| 1258 | std.log.warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{}); | 1258 | warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{}); |
| 1259 | _ = args_iter.nextOrFatal(); | 1259 | _ = args_iter.nextOrFatal(); |
| 1260 | } else { | 1260 | } else { |
| 1261 | try log_scopes.append(gpa, args_iter.nextOrFatal()); | 1261 | try log_scopes.append(gpa, args_iter.nextOrFatal()); |
| ... | @@ -1279,7 +1279,7 @@ fn buildOutputType( | ... | @@ -1279,7 +1279,7 @@ fn buildOutputType( |
| 1279 | listen = .stdio; | 1279 | listen = .stdio; |
| 1280 | } else if (mem.eql(u8, arg, "--debug-link-snapshot")) { | 1280 | } else if (mem.eql(u8, arg, "--debug-link-snapshot")) { |
| 1281 | if (!build_options.enable_link_snapshots) { | 1281 | if (!build_options.enable_link_snapshots) { |
| 1282 | std.log.warn("Zig was compiled without linker snapshots enabled (-Dlink-snapshot). --debug-link-snapshot has no effect.", .{}); | 1282 | warn("Zig was compiled without linker snapshots enabled (-Dlink-snapshot). --debug-link-snapshot has no effect.", .{}); |
| 1283 | } else { | 1283 | } else { |
| 1284 | enable_link_snapshots = true; | 1284 | enable_link_snapshots = true; |
| 1285 | } | 1285 | } |
| ... | @@ -1558,7 +1558,7 @@ fn buildOutputType( | ... | @@ -1558,7 +1558,7 @@ fn buildOutputType( |
| 1558 | }; | 1558 | }; |
| 1559 | } else if (mem.eql(u8, arg, "--debug-compile-errors")) { | 1559 | } else if (mem.eql(u8, arg, "--debug-compile-errors")) { |
| 1560 | if (!crash_report.is_enabled) { | 1560 | if (!crash_report.is_enabled) { |
| 1561 | std.log.warn("Zig was compiled in a release mode. --debug-compile-errors has no effect.", .{}); | 1561 | warn("Zig was compiled in a release mode. --debug-compile-errors has no effect.", .{}); |
| 1562 | } else { | 1562 | } else { |
| 1563 | debug_compile_errors = true; | 1563 | debug_compile_errors = true; |
| 1564 | } | 1564 | } |
| ... | @@ -1662,7 +1662,7 @@ fn buildOutputType( | ... | @@ -1662,7 +1662,7 @@ fn buildOutputType( |
| 1662 | }, | 1662 | }, |
| 1663 | .def, .unknown => { | 1663 | .def, .unknown => { |
| 1664 | if (std.ascii.eqlIgnoreCase(".xml", std.fs.path.extension(arg))) { | 1664 | if (std.ascii.eqlIgnoreCase(".xml", std.fs.path.extension(arg))) { |
| 1665 | std.log.warn("embedded manifest files must have the extension '.manifest'", .{}); | 1665 | warn("embedded manifest files must have the extension '.manifest'", .{}); |
| 1666 | } | 1666 | } |
| 1667 | fatal("unrecognized file extension of parameter '{s}'", .{arg}); | 1667 | fatal("unrecognized file extension of parameter '{s}'", .{arg}); |
| 1668 | }, | 1668 | }, |
| ... | @@ -2793,7 +2793,7 @@ fn buildOutputType( | ... | @@ -2793,7 +2793,7 @@ fn buildOutputType( |
| 2793 | continue; | 2793 | continue; |
| 2794 | }, | 2794 | }, |
| 2795 | .only_compiler_rt => { | 2795 | .only_compiler_rt => { |
| 2796 | std.log.warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name}); | 2796 | warn("ignoring superfluous library '{s}': this dependency is fulfilled instead by compiler-rt which zig unconditionally provides", .{lib_name}); |
| 2797 | continue; | 2797 | continue; |
| 2798 | }, | 2798 | }, |
| 2799 | } | 2799 | } |
| ... | @@ -4851,7 +4851,6 @@ pub const usage_init = | ... | @@ -4851,7 +4851,6 @@ pub const usage_init = |
| 4851 | ; | 4851 | ; |
| 4852 | | 4852 | |
| 4853 | pub fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | 4853 | pub fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4854 | _ = gpa; | | |
| 4855 | { | 4854 | { |
| 4856 | var i: usize = 0; | 4855 | var i: usize = 0; |
| 4857 | while (i < args.len) : (i += 1) { | 4856 | while (i < args.len) : (i += 1) { |
| ... | @@ -4868,58 +4867,24 @@ pub fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void | ... | @@ -4868,58 +4867,24 @@ pub fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void |
| 4868 | } | 4867 | } |
| 4869 | } | 4868 | } |
| 4870 | } | 4869 | } |
| 4871 | const self_exe_path = try introspect.findZigExePath(arena); | | |
| 4872 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { | | |
| 4873 | fatal("unable to find zig installation directory: {s}\n", .{@errorName(err)}); | | |
| 4874 | }; | | |
| 4875 | defer zig_lib_directory.handle.close(); | | |
| 4876 | | 4870 | |
| 4877 | const s = fs.path.sep_str; | 4871 | var templates = findTemplates(gpa, arena); |
| 4878 | const template_sub_path = "init"; | 4872 | defer templates.deinit(); |
| 4879 | var template_dir = zig_lib_directory.handle.openDir(template_sub_path, .{}) catch |err| { | | |
| 4880 | const path = zig_lib_directory.path orelse "."; | | |
| 4881 | fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{ | | |
| 4882 | path, s, template_sub_path, @errorName(err), | | |
| 4883 | }); | | |
| 4884 | }; | | |
| 4885 | defer template_dir.close(); | | |
| 4886 | | 4873 | |
| 4887 | const cwd_path = try process.getCwdAlloc(arena); | 4874 | const cwd_path = try process.getCwdAlloc(arena); |
| 4888 | const cwd_basename = fs.path.basename(cwd_path); | 4875 | const cwd_basename = fs.path.basename(cwd_path); |
| 4889 | | 4876 | |
| 4890 | const max_bytes = 10 * 1024 * 1024; | 4877 | const s = fs.path.sep_str; |
| 4891 | const template_paths = [_][]const u8{ | 4878 | const template_paths = [_][]const u8{ |
| 4892 | "build.zig", | 4879 | Package.build_zig_basename, |
| 4893 | "build.zig.zon", | 4880 | Package.Manifest.basename, |
| 4894 | "src" ++ s ++ "main.zig", | 4881 | "src" ++ s ++ "main.zig", |
| 4895 | "src" ++ s ++ "root.zig", | 4882 | "src" ++ s ++ "root.zig", |
| 4896 | }; | 4883 | }; |
| 4897 | var ok_count: usize = 0; | 4884 | var ok_count: usize = 0; |
| 4898 | | 4885 | |
| 4899 | for (template_paths) |template_path| { | 4886 | for (template_paths) |template_path| { |
| 4900 | if (fs.path.dirname(template_path)) |dirname| { | 4887 | if (templates.write(arena, fs.cwd(), cwd_basename, template_path)) |_| { |
| 4901 | fs.cwd().makePath(dirname) catch |err| { | | |
| 4902 | fatal("unable to make path '{s}': {s}", .{ dirname, @errorName(err) }); | | |
| 4903 | }; | | |
| 4904 | } | | |
| 4905 | | | |
| 4906 | const contents = template_dir.readFileAlloc(arena, template_path, max_bytes) catch |err| { | | |
| 4907 | fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) }); | | |
| 4908 | }; | | |
| 4909 | var modified_contents = try std.ArrayList(u8).initCapacity(arena, contents.len); | | |
| 4910 | for (contents) |c| { | | |
| 4911 | if (c == '$') { | | |
| 4912 | try modified_contents.appendSlice(cwd_basename); | | |
| 4913 | } else { | | |
| 4914 | try modified_contents.append(c); | | |
| 4915 | } | | |
| 4916 | } | | |
| 4917 | | | |
| 4918 | if (fs.cwd().writeFile2(.{ | | |
| 4919 | .sub_path = template_path, | | |
| 4920 | .data = modified_contents.items, | | |
| 4921 | .flags = .{ .exclusive = true }, | | |
| 4922 | })) |_| { | | |
| 4923 | std.log.info("created {s}", .{template_path}); | 4888 | std.log.info("created {s}", .{template_path}); |
| 4924 | ok_count += 1; | 4889 | ok_count += 1; |
| 4925 | } else |err| switch (err) { | 4890 | } else |err| switch (err) { |
| ... | @@ -5057,14 +5022,14 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi | ... | @@ -5057,14 +5022,14 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5057 | try child_argv.appendSlice(args[i .. i + 2]); | 5022 | try child_argv.appendSlice(args[i .. i + 2]); |
| 5058 | i += 1; | 5023 | i += 1; |
| 5059 | if (!build_options.enable_logging) { | 5024 | if (!build_options.enable_logging) { |
| 5060 | std.log.warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{}); | 5025 | warn("Zig was compiled without logging enabled (-Dlog). --debug-log has no effect.", .{}); |
| 5061 | } else { | 5026 | } else { |
| 5062 | try log_scopes.append(gpa, args[i]); | 5027 | try log_scopes.append(gpa, args[i]); |
| 5063 | } | 5028 | } |
| 5064 | continue; | 5029 | continue; |
| 5065 | } else if (mem.eql(u8, arg, "--debug-compile-errors")) { | 5030 | } else if (mem.eql(u8, arg, "--debug-compile-errors")) { |
| 5066 | if (!crash_report.is_enabled) { | 5031 | if (!crash_report.is_enabled) { |
| 5067 | std.log.warn("Zig was compiled in a release mode. --debug-compile-errors has no effect.", .{}); | 5032 | warn("Zig was compiled in a release mode. --debug-compile-errors has no effect.", .{}); |
| 5068 | } else { | 5033 | } else { |
| 5069 | debug_compile_errors = true; | 5034 | debug_compile_errors = true; |
| 5070 | } | 5035 | } |
| ... | @@ -5113,44 +5078,11 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi | ... | @@ -5113,44 +5078,11 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5113 | defer if (cleanup_build_dir) |*dir| dir.close(); | 5078 | defer if (cleanup_build_dir) |*dir| dir.close(); |
| 5114 | | 5079 | |
| 5115 | const cwd_path = try process.getCwdAlloc(arena); | 5080 | const cwd_path = try process.getCwdAlloc(arena); |
| 5116 | const build_zig_basename = if (build_file) |bf| fs.path.basename(bf) else Package.build_zig_basename; | 5081 | const build_root = try findBuildRoot(arena, .{ |
| 5117 | const build_root: Compilation.Directory = blk: { | 5082 | .cwd_path = cwd_path, |
| 5118 | if (build_file) |bf| { | 5083 | .build_file = build_file, |
| 5119 | if (fs.path.dirname(bf)) |dirname| { | 5084 | }); |
| 5120 | const dir = fs.cwd().openDir(dirname, .{}) catch |err| { | 5085 | child_argv.items[argv_index_build_file] = build_root.directory.path orelse cwd_path; |
| 5121 | fatal("unable to open directory to build file from argument 'build-file', '{s}': {s}", .{ dirname, @errorName(err) }); | | |
| 5122 | }; | | |
| 5123 | cleanup_build_dir = dir; | | |
| 5124 | break :blk .{ .path = dirname, .handle = dir }; | | |
| 5125 | } | | |
| 5126 | | | |
| 5127 | break :blk .{ .path = null, .handle = fs.cwd() }; | | |
| 5128 | } | | |
| 5129 | // Search up parent directories until we find build.zig. | | |
| 5130 | var dirname: []const u8 = cwd_path; | | |
| 5131 | while (true) { | | |
| 5132 | const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename }); | | |
| 5133 | if (fs.cwd().access(joined_path, .{})) |_| { | | |
| 5134 | const dir = fs.cwd().openDir(dirname, .{}) catch |err| { | | |
| 5135 | fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) }); | | |
| 5136 | }; | | |
| 5137 | break :blk .{ .path = dirname, .handle = dir }; | | |
| 5138 | } else |err| switch (err) { | | |
| 5139 | error.FileNotFound => { | | |
| 5140 | dirname = fs.path.dirname(dirname) orelse { | | |
| 5141 | std.log.info("{s}", .{ | | |
| 5142 | \\Initialize a 'build.zig' template file with `zig init-lib` or `zig init-exe`, | | |
| 5143 | \\or see `zig --help` for more options. | | |
| 5144 | }); | | |
| 5145 | fatal("No 'build.zig' file found, in the current directory or any parent directories.", .{}); | | |
| 5146 | }; | | |
| 5147 | continue; | | |
| 5148 | }, | | |
| 5149 | else => |e| return e, | | |
| 5150 | } | | |
| 5151 | } | | |
| 5152 | }; | | |
| 5153 | child_argv.items[argv_index_build_file] = build_root.path orelse cwd_path; | | |
| 5154 | | 5086 | |
| 5155 | var global_cache_directory: Compilation.Directory = l: { | 5087 | var global_cache_directory: Compilation.Directory = l: { |
| 5156 | const p = override_global_cache_dir orelse try introspect.resolveGlobalCacheDir(arena); | 5088 | 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 | ... | @@ -5170,9 +5102,9 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5170 | .path = local_cache_dir_path, | 5102 | .path = local_cache_dir_path, |
| 5171 | }; | 5103 | }; |
| 5172 | } | 5104 | } |
| 5173 | const cache_dir_path = try build_root.join(arena, &[_][]const u8{"zig-cache"}); | 5105 | const cache_dir_path = try build_root.directory.join(arena, &[_][]const u8{"zig-cache"}); |
| 5174 | break :l .{ | 5106 | break :l .{ |
| 5175 | .handle = try build_root.handle.makeOpenPath("zig-cache", .{}), | 5107 | .handle = try build_root.directory.handle.makeOpenPath("zig-cache", .{}), |
| 5176 | .path = cache_dir_path, | 5108 | .path = cache_dir_path, |
| 5177 | }; | 5109 | }; |
| 5178 | }; | 5110 | }; |
| ... | @@ -5215,8 +5147,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi | ... | @@ -5215,8 +5147,8 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi |
| 5215 | }; | 5147 | }; |
| 5216 | | 5148 | |
| 5217 | var build_mod: Package.Module = .{ | 5149 | var build_mod: Package.Module = .{ |
| 5218 | .root = .{ .root_dir = build_root }, | 5150 | .root = .{ .root_dir = build_root.directory }, |
| 5219 | .root_src_path = build_zig_basename, | 5151 | .root_src_path = build_root.build_zig_basename, |
| 5220 | .fully_qualified_name = "root.@build", | 5152 | .fully_qualified_name = "root.@build", |
| 5221 | }; | 5153 | }; |
| 5222 | if (build_options.only_core_functionality) { | 5154 | if (build_options.only_core_functionality) { |
| ... | @@ -6904,40 +6836,40 @@ const ClangSearchSanitizer = struct { | ... | @@ -6904,40 +6836,40 @@ const ClangSearchSanitizer = struct { |
| 6904 | .I => { | 6836 | .I => { |
| 6905 | if (m.I) return; | 6837 | if (m.I) return; |
| 6906 | m.I = true; | 6838 | m.I = true; |
| 6907 | if (m.isystem) std.log.warn(wtxt, .{ dir, "I", "isystem" }); | 6839 | if (m.isystem) warn(wtxt, .{ dir, "I", "isystem" }); |
| 6908 | if (m.idirafter) std.log.warn(wtxt, .{ dir, "I", "idirafter" }); | 6840 | if (m.idirafter) warn(wtxt, .{ dir, "I", "idirafter" }); |
| 6909 | if (m.iframework) std.log.warn(wtxt, .{ dir, "I", "iframework" }); | 6841 | if (m.iframework) warn(wtxt, .{ dir, "I", "iframework" }); |
| 6910 | }, | 6842 | }, |
| 6911 | .isystem => { | 6843 | .isystem => { |
| 6912 | if (m.isystem) return; | 6844 | if (m.isystem) return; |
| 6913 | m.isystem = true; | 6845 | m.isystem = true; |
| 6914 | if (m.I) std.log.warn(wtxt, .{ dir, "isystem", "I" }); | 6846 | if (m.I) warn(wtxt, .{ dir, "isystem", "I" }); |
| 6915 | if (m.idirafter) std.log.warn(wtxt, .{ dir, "isystem", "idirafter" }); | 6847 | if (m.idirafter) warn(wtxt, .{ dir, "isystem", "idirafter" }); |
| 6916 | if (m.iframework) std.log.warn(wtxt, .{ dir, "isystem", "iframework" }); | 6848 | if (m.iframework) warn(wtxt, .{ dir, "isystem", "iframework" }); |
| 6917 | }, | 6849 | }, |
| 6918 | .iwithsysroot => { | 6850 | .iwithsysroot => { |
| 6919 | if (m.iwithsysroot) return; | 6851 | if (m.iwithsysroot) return; |
| 6920 | m.iwithsysroot = true; | 6852 | m.iwithsysroot = true; |
| 6921 | if (m.iframeworkwithsysroot) std.log.warn(wtxt, .{ dir, "iwithsysroot", "iframeworkwithsysroot" }); | 6853 | if (m.iframeworkwithsysroot) warn(wtxt, .{ dir, "iwithsysroot", "iframeworkwithsysroot" }); |
| 6922 | }, | 6854 | }, |
| 6923 | .idirafter => { | 6855 | .idirafter => { |
| 6924 | if (m.idirafter) return; | 6856 | if (m.idirafter) return; |
| 6925 | m.idirafter = true; | 6857 | m.idirafter = true; |
| 6926 | if (m.I) std.log.warn(wtxt, .{ dir, "idirafter", "I" }); | 6858 | if (m.I) warn(wtxt, .{ dir, "idirafter", "I" }); |
| 6927 | if (m.isystem) std.log.warn(wtxt, .{ dir, "idirafter", "isystem" }); | 6859 | if (m.isystem) warn(wtxt, .{ dir, "idirafter", "isystem" }); |
| 6928 | if (m.iframework) std.log.warn(wtxt, .{ dir, "idirafter", "iframework" }); | 6860 | if (m.iframework) warn(wtxt, .{ dir, "idirafter", "iframework" }); |
| 6929 | }, | 6861 | }, |
| 6930 | .iframework => { | 6862 | .iframework => { |
| 6931 | if (m.iframework) return; | 6863 | if (m.iframework) return; |
| 6932 | m.iframework = true; | 6864 | m.iframework = true; |
| 6933 | if (m.I) std.log.warn(wtxt, .{ dir, "iframework", "I" }); | 6865 | if (m.I) warn(wtxt, .{ dir, "iframework", "I" }); |
| 6934 | if (m.isystem) std.log.warn(wtxt, .{ dir, "iframework", "isystem" }); | 6866 | if (m.isystem) warn(wtxt, .{ dir, "iframework", "isystem" }); |
| 6935 | if (m.idirafter) std.log.warn(wtxt, .{ dir, "iframework", "idirafter" }); | 6867 | if (m.idirafter) warn(wtxt, .{ dir, "iframework", "idirafter" }); |
| 6936 | }, | 6868 | }, |
| 6937 | .iframeworkwithsysroot => { | 6869 | .iframeworkwithsysroot => { |
| 6938 | if (m.iframeworkwithsysroot) return; | 6870 | if (m.iframeworkwithsysroot) return; |
| 6939 | m.iframeworkwithsysroot = true; | 6871 | m.iframeworkwithsysroot = true; |
| 6940 | if (m.iwithsysroot) std.log.warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" }); | 6872 | if (m.iwithsysroot) warn(wtxt, .{ dir, "iframeworkwithsysroot", "iwithsysroot" }); |
| 6941 | }, | 6873 | }, |
| 6942 | } | 6874 | } |
| 6943 | try self.argv.append(arg); | 6875 | try self.argv.append(arg); |
| ... | @@ -7097,6 +7029,8 @@ pub const usage_fetch = | ... | @@ -7097,6 +7029,8 @@ pub const usage_fetch = |
| 7097 | \\ -h, --help Print this help and exit | 7029 | \\ -h, --help Print this help and exit |
| 7098 | \\ --global-cache-dir [path] Override path to global Zig cache directory | 7030 | \\ --global-cache-dir [path] Override path to global Zig cache directory |
| 7099 | \\ --debug-hash Print verbose hash information to stdout | 7031 | \\ --debug-hash Print verbose hash information to stdout |
| | 7032 | \\ --save Add the fetched package to build.zig.zon |
| | 7033 | \\ --save=[name] Add the fetched package to build.zig.zon as name |
| 7100 | \\ | 7034 | \\ |
| 7101 | ; | 7035 | ; |
| 7102 | | 7036 | |
| ... | @@ -7111,6 +7045,7 @@ fn cmdFetch( | ... | @@ -7111,6 +7045,7 @@ fn cmdFetch( |
| 7111 | var opt_path_or_url: ?[]const u8 = null; | 7045 | var opt_path_or_url: ?[]const u8 = null; |
| 7112 | var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena); | 7046 | var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena); |
| 7113 | var debug_hash: bool = false; | 7047 | var debug_hash: bool = false; |
| | 7048 | var save: union(enum) { no, yes, name: []const u8 } = .no; |
| 7114 | | 7049 | |
| 7115 | { | 7050 | { |
| 7116 | var i: usize = 0; | 7051 | var i: usize = 0; |
| ... | @@ -7125,10 +7060,12 @@ fn cmdFetch( | ... | @@ -7125,10 +7060,12 @@ fn cmdFetch( |
| 7125 | if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg}); | 7060 | if (i + 1 >= args.len) fatal("expected argument after '{s}'", .{arg}); |
| 7126 | i += 1; | 7061 | i += 1; |
| 7127 | override_global_cache_dir = args[i]; | 7062 | override_global_cache_dir = args[i]; |
| 7128 | continue; | | |
| 7129 | } else if (mem.eql(u8, arg, "--debug-hash")) { | 7063 | } else if (mem.eql(u8, arg, "--debug-hash")) { |
| 7130 | debug_hash = true; | 7064 | debug_hash = true; |
| 7131 | continue; | 7065 | } else if (mem.eql(u8, arg, "--save")) { |
| | 7066 | save = .yes; |
| | 7067 | } else if (mem.startsWith(u8, arg, "--save=")) { |
| | 7068 | save = .{ .name = arg["--save=".len..] }; |
| 7132 | } else { | 7069 | } else { |
| 7133 | fatal("unrecognized parameter: '{s}'", .{arg}); | 7070 | fatal("unrecognized parameter: '{s}'", .{arg}); |
| 7134 | } | 7071 | } |
| ... | @@ -7214,7 +7151,97 @@ fn cmdFetch( | ... | @@ -7214,7 +7151,97 @@ fn cmdFetch( |
| 7214 | progress.done = true; | 7151 | progress.done = true; |
| 7215 | progress.refresh(); | 7152 | progress.refresh(); |
| 7216 | | 7153 | |
| 7217 | try io.getStdOut().writeAll(hex_digest ++ "\n"); | 7154 | const name = switch (save) { |
| | 7155 | .no => { |
| | 7156 | try io.getStdOut().writeAll(hex_digest ++ "\n"); |
| | 7157 | return cleanExit(); |
| | 7158 | }, |
| | 7159 | .yes => n: { |
| | 7160 | const fetched_manifest = fetch.manifest orelse |
| | 7161 | fatal("unable to determine name; fetched package has no build.zig.zon file", .{}); |
| | 7162 | break :n fetched_manifest.name; |
| | 7163 | }, |
| | 7164 | .name => |n| n, |
| | 7165 | }; |
| | 7166 | |
| | 7167 | const cwd_path = try process.getCwdAlloc(arena); |
| | 7168 | |
| | 7169 | var build_root = try findBuildRoot(arena, .{ |
| | 7170 | .cwd_path = cwd_path, |
| | 7171 | }); |
| | 7172 | defer build_root.deinit(); |
| | 7173 | |
| | 7174 | // The name to use in case the manifest file needs to be created now. |
| | 7175 | const init_root_name = fs.path.basename(build_root.directory.path orelse cwd_path); |
| | 7176 | var manifest, var ast = try loadManifest(gpa, arena, .{ |
| | 7177 | .root_name = init_root_name, |
| | 7178 | .dir = build_root.directory.handle, |
| | 7179 | .color = color, |
| | 7180 | }); |
| | 7181 | defer { |
| | 7182 | manifest.deinit(gpa); |
| | 7183 | ast.deinit(gpa); |
| | 7184 | } |
| | 7185 | |
| | 7186 | var fixups: Ast.Fixups = .{}; |
| | 7187 | defer fixups.deinit(gpa); |
| | 7188 | |
| | 7189 | const new_node_init = try std.fmt.allocPrint(arena, |
| | 7190 | \\.{{ |
| | 7191 | \\ .url = "{}", |
| | 7192 | \\ .hash = "{}", |
| | 7193 | \\ }} |
| | 7194 | , .{ |
| | 7195 | std.zig.fmtEscapes(path_or_url), |
| | 7196 | std.zig.fmtEscapes(&hex_digest), |
| | 7197 | }); |
| | 7198 | |
| | 7199 | const new_node_text = try std.fmt.allocPrint(arena, ".{} = {s},\n", .{ |
| | 7200 | std.zig.fmtId(name), new_node_init, |
| | 7201 | }); |
| | 7202 | |
| | 7203 | const dependencies_init = try std.fmt.allocPrint(arena, ".{{\n {s} }}", .{ |
| | 7204 | new_node_text, |
| | 7205 | }); |
| | 7206 | |
| | 7207 | const dependencies_text = try std.fmt.allocPrint(arena, ".dependencies = {s},\n", .{ |
| | 7208 | dependencies_init, |
| | 7209 | }); |
| | 7210 | |
| | 7211 | if (manifest.dependencies.get(name)) |dep| { |
| | 7212 | if (dep.hash) |h| { |
| | 7213 | switch (dep.location) { |
| | 7214 | .url => |u| { |
| | 7215 | if (mem.eql(u8, h, &hex_digest) and mem.eql(u8, u, path_or_url)) { |
| | 7216 | std.log.info("existing dependency named '{s}' is up-to-date", .{name}); |
| | 7217 | process.exit(0); |
| | 7218 | } |
| | 7219 | }, |
| | 7220 | .path => {}, |
| | 7221 | } |
| | 7222 | } |
| | 7223 | warn("overwriting existing dependency named '{s}'", .{name}); |
| | 7224 | try fixups.replace_nodes_with_string.put(gpa, dep.node, new_node_init); |
| | 7225 | } else if (manifest.dependencies.count() > 0) { |
| | 7226 | // Add fixup for adding another dependency. |
| | 7227 | const deps = manifest.dependencies.values(); |
| | 7228 | const last_dep_node = deps[deps.len - 1].node; |
| | 7229 | try fixups.append_string_after_node.put(gpa, last_dep_node, new_node_text); |
| | 7230 | } else if (manifest.dependencies_node != 0) { |
| | 7231 | // Add fixup for replacing the entire dependencies struct. |
| | 7232 | try fixups.replace_nodes_with_string.put(gpa, manifest.dependencies_node, dependencies_init); |
| | 7233 | } else { |
| | 7234 | // Add fixup for adding dependencies struct. |
| | 7235 | try fixups.append_string_after_node.put(gpa, manifest.version_node, dependencies_text); |
| | 7236 | } |
| | 7237 | |
| | 7238 | var rendered = std.ArrayList(u8).init(gpa); |
| | 7239 | defer rendered.deinit(); |
| | 7240 | try ast.renderToArrayList(&rendered, fixups); |
| | 7241 | |
| | 7242 | build_root.directory.handle.writeFile(Package.Manifest.basename, rendered.items) catch |err| { |
| | 7243 | fatal("unable to write {s} file: {s}", .{ Package.Manifest.basename, @errorName(err) }); |
| | 7244 | }; |
| 7218 | | 7245 | |
| 7219 | return cleanExit(); | 7246 | return cleanExit(); |
| 7220 | } | 7247 | } |
| ... | @@ -7279,3 +7306,211 @@ fn defaultWasmEntryName(exec_model: ?std.builtin.WasiExecModel) []const u8 { | ... | @@ -7279,3 +7306,211 @@ fn defaultWasmEntryName(exec_model: ?std.builtin.WasiExecModel) []const u8 { |
| 7279 | } | 7306 | } |
| 7280 | return "_start"; | 7307 | return "_start"; |
| 7281 | } | 7308 | } |
| | 7309 | |
| | 7310 | const BuildRoot = struct { |
| | 7311 | directory: Cache.Directory, |
| | 7312 | build_zig_basename: []const u8, |
| | 7313 | cleanup_build_dir: ?fs.Dir, |
| | 7314 | |
| | 7315 | fn deinit(br: *BuildRoot) void { |
| | 7316 | if (br.cleanup_build_dir) |*dir| dir.close(); |
| | 7317 | br.* = undefined; |
| | 7318 | } |
| | 7319 | }; |
| | 7320 | |
| | 7321 | const FindBuildRootOptions = struct { |
| | 7322 | build_file: ?[]const u8 = null, |
| | 7323 | cwd_path: ?[]const u8 = null, |
| | 7324 | }; |
| | 7325 | |
| | 7326 | fn findBuildRoot(arena: Allocator, options: FindBuildRootOptions) !BuildRoot { |
| | 7327 | const cwd_path = options.cwd_path orelse try process.getCwdAlloc(arena); |
| | 7328 | const build_zig_basename = if (options.build_file) |bf| |
| | 7329 | fs.path.basename(bf) |
| | 7330 | else |
| | 7331 | Package.build_zig_basename; |
| | 7332 | |
| | 7333 | if (options.build_file) |bf| { |
| | 7334 | if (fs.path.dirname(bf)) |dirname| { |
| | 7335 | const dir = fs.cwd().openDir(dirname, .{}) catch |err| { |
| | 7336 | fatal("unable to open directory to build file from argument 'build-file', '{s}': {s}", .{ dirname, @errorName(err) }); |
| | 7337 | }; |
| | 7338 | return .{ |
| | 7339 | .build_zig_basename = build_zig_basename, |
| | 7340 | .directory = .{ .path = dirname, .handle = dir }, |
| | 7341 | .cleanup_build_dir = dir, |
| | 7342 | }; |
| | 7343 | } |
| | 7344 | |
| | 7345 | return .{ |
| | 7346 | .build_zig_basename = build_zig_basename, |
| | 7347 | .directory = .{ .path = null, .handle = fs.cwd() }, |
| | 7348 | .cleanup_build_dir = null, |
| | 7349 | }; |
| | 7350 | } |
| | 7351 | // Search up parent directories until we find build.zig. |
| | 7352 | var dirname: []const u8 = cwd_path; |
| | 7353 | while (true) { |
| | 7354 | const joined_path = try fs.path.join(arena, &[_][]const u8{ dirname, build_zig_basename }); |
| | 7355 | if (fs.cwd().access(joined_path, .{})) |_| { |
| | 7356 | const dir = fs.cwd().openDir(dirname, .{}) catch |err| { |
| | 7357 | fatal("unable to open directory while searching for build.zig file, '{s}': {s}", .{ dirname, @errorName(err) }); |
| | 7358 | }; |
| | 7359 | return .{ |
| | 7360 | .build_zig_basename = build_zig_basename, |
| | 7361 | .directory = .{ |
| | 7362 | .path = dirname, |
| | 7363 | .handle = dir, |
| | 7364 | }, |
| | 7365 | .cleanup_build_dir = dir, |
| | 7366 | }; |
| | 7367 | } else |err| switch (err) { |
| | 7368 | error.FileNotFound => { |
| | 7369 | dirname = fs.path.dirname(dirname) orelse { |
| | 7370 | std.log.info("initialize {s} template file with 'zig init'", .{ |
| | 7371 | Package.build_zig_basename, |
| | 7372 | }); |
| | 7373 | std.log.info("see 'zig --help' for more options", .{}); |
| | 7374 | fatal("no build.zig file found, in the current directory or any parent directories", .{}); |
| | 7375 | }; |
| | 7376 | continue; |
| | 7377 | }, |
| | 7378 | else => |e| return e, |
| | 7379 | } |
| | 7380 | } |
| | 7381 | } |
| | 7382 | |
| | 7383 | const LoadManifestOptions = struct { |
| | 7384 | root_name: []const u8, |
| | 7385 | dir: fs.Dir, |
| | 7386 | color: Color, |
| | 7387 | }; |
| | 7388 | |
| | 7389 | fn loadManifest( |
| | 7390 | gpa: Allocator, |
| | 7391 | arena: Allocator, |
| | 7392 | options: LoadManifestOptions, |
| | 7393 | ) !struct { Package.Manifest, Ast } { |
| | 7394 | const manifest_bytes = while (true) { |
| | 7395 | break options.dir.readFileAllocOptions( |
| | 7396 | arena, |
| | 7397 | Package.Manifest.basename, |
| | 7398 | Package.Manifest.max_bytes, |
| | 7399 | null, |
| | 7400 | 1, |
| | 7401 | 0, |
| | 7402 | ) catch |err| switch (err) { |
| | 7403 | error.FileNotFound => { |
| | 7404 | var templates = findTemplates(gpa, arena); |
| | 7405 | defer templates.deinit(); |
| | 7406 | |
| | 7407 | templates.write(arena, options.dir, options.root_name, Package.Manifest.basename) catch |e| { |
| | 7408 | fatal("unable to write {s}: {s}", .{ |
| | 7409 | Package.Manifest.basename, @errorName(e), |
| | 7410 | }); |
| | 7411 | }; |
| | 7412 | continue; |
| | 7413 | }, |
| | 7414 | else => |e| fatal("unable to load {s}: {s}", .{ |
| | 7415 | Package.Manifest.basename, @errorName(e), |
| | 7416 | }), |
| | 7417 | }; |
| | 7418 | }; |
| | 7419 | var ast = try Ast.parse(gpa, manifest_bytes, .zon); |
| | 7420 | errdefer ast.deinit(gpa); |
| | 7421 | |
| | 7422 | if (ast.errors.len > 0) { |
| | 7423 | try printAstErrorsToStderr(gpa, ast, Package.Manifest.basename, options.color); |
| | 7424 | process.exit(2); |
| | 7425 | } |
| | 7426 | |
| | 7427 | var manifest = try Package.Manifest.parse(gpa, ast, .{}); |
| | 7428 | errdefer manifest.deinit(gpa); |
| | 7429 | |
| | 7430 | if (manifest.errors.len > 0) { |
| | 7431 | var wip_errors: std.zig.ErrorBundle.Wip = undefined; |
| | 7432 | try wip_errors.init(gpa); |
| | 7433 | defer wip_errors.deinit(); |
| | 7434 | |
| | 7435 | const src_path = try wip_errors.addString(Package.Manifest.basename); |
| | 7436 | try manifest.copyErrorsIntoBundle(ast, src_path, &wip_errors); |
| | 7437 | |
| | 7438 | var error_bundle = try wip_errors.toOwnedBundle(""); |
| | 7439 | defer error_bundle.deinit(gpa); |
| | 7440 | error_bundle.renderToStdErr(renderOptions(options.color)); |
| | 7441 | |
| | 7442 | process.exit(2); |
| | 7443 | } |
| | 7444 | return .{ manifest, ast }; |
| | 7445 | } |
| | 7446 | |
| | 7447 | const Templates = struct { |
| | 7448 | zig_lib_directory: Cache.Directory, |
| | 7449 | dir: fs.Dir, |
| | 7450 | buffer: std.ArrayList(u8), |
| | 7451 | |
| | 7452 | fn deinit(templates: *Templates) void { |
| | 7453 | templates.zig_lib_directory.handle.close(); |
| | 7454 | templates.dir.close(); |
| | 7455 | templates.buffer.deinit(); |
| | 7456 | templates.* = undefined; |
| | 7457 | } |
| | 7458 | |
| | 7459 | fn write( |
| | 7460 | templates: *Templates, |
| | 7461 | arena: Allocator, |
| | 7462 | out_dir: fs.Dir, |
| | 7463 | root_name: []const u8, |
| | 7464 | template_path: []const u8, |
| | 7465 | ) !void { |
| | 7466 | if (fs.path.dirname(template_path)) |dirname| { |
| | 7467 | out_dir.makePath(dirname) catch |err| { |
| | 7468 | fatal("unable to make path '{s}': {s}", .{ dirname, @errorName(err) }); |
| | 7469 | }; |
| | 7470 | } |
| | 7471 | |
| | 7472 | const max_bytes = 10 * 1024 * 1024; |
| | 7473 | const contents = templates.dir.readFileAlloc(arena, template_path, max_bytes) catch |err| { |
| | 7474 | fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) }); |
| | 7475 | }; |
| | 7476 | templates.buffer.clearRetainingCapacity(); |
| | 7477 | try templates.buffer.ensureUnusedCapacity(contents.len); |
| | 7478 | for (contents) |c| { |
| | 7479 | if (c == '$') { |
| | 7480 | try templates.buffer.appendSlice(root_name); |
| | 7481 | } else { |
| | 7482 | try templates.buffer.append(c); |
| | 7483 | } |
| | 7484 | } |
| | 7485 | |
| | 7486 | return out_dir.writeFile2(.{ |
| | 7487 | .sub_path = template_path, |
| | 7488 | .data = templates.buffer.items, |
| | 7489 | .flags = .{ .exclusive = true }, |
| | 7490 | }); |
| | 7491 | } |
| | 7492 | }; |
| | 7493 | |
| | 7494 | fn findTemplates(gpa: Allocator, arena: Allocator) Templates { |
| | 7495 | const self_exe_path = introspect.findZigExePath(arena) catch |err| { |
| | 7496 | fatal("unable to find self exe path: {s}", .{@errorName(err)}); |
| | 7497 | }; |
| | 7498 | var zig_lib_directory = introspect.findZigLibDirFromSelfExe(arena, self_exe_path) catch |err| { |
| | 7499 | fatal("unable to find zig installation directory: {s}", .{@errorName(err)}); |
| | 7500 | }; |
| | 7501 | |
| | 7502 | const s = fs.path.sep_str; |
| | 7503 | const template_sub_path = "init"; |
| | 7504 | const template_dir = zig_lib_directory.handle.openDir(template_sub_path, .{}) catch |err| { |
| | 7505 | const path = zig_lib_directory.path orelse "."; |
| | 7506 | fatal("unable to open zig project template directory '{s}{s}{s}': {s}", .{ |
| | 7507 | path, s, template_sub_path, @errorName(err), |
| | 7508 | }); |
| | 7509 | }; |
| | 7510 | |
| | 7511 | return .{ |
| | 7512 | .zig_lib_directory = zig_lib_directory, |
| | 7513 | .dir = template_dir, |
| | 7514 | .buffer = std.ArrayList(u8).init(gpa), |
| | 7515 | }; |
| | 7516 | } |