authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-21 16:16:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-03-21 16:16:47-07:00
log7bc0b74b6d57ff1a350a4f430f7d9e799a90edd0
tree5e251595d497f7eacd44673ecf61370f28d0c3cc
parent8778dc4bb2bb20779bee3fc964f79437ff3ef9fe

move Package.Path to std.Build.Cache.Path


6 files changed, 166 insertions(+), 170 deletions(-)

lib/std/Build/Cache.zig+1
......@@ -17,6 +17,7 @@ mutex: std.Thread.Mutex = .{},
1717prefixes_buffer: [4]Directory = undefined,
1818prefixes_len: usize = 0,
1919
20pub const Path = @import("Cache/Path.zig");
2021pub const Directory = @import("Cache/Directory.zig");
2122pub const DepTokenizer = @import("Cache/DepTokenizer.zig");
2223
lib/std/Build/Cache/Path.zig created+154
......@@ -0,0 +1,154 @@
1root_dir: Cache.Directory,
2/// The path, relative to the root dir, that this `Path` represents.
3/// Empty string means the root_dir is the path.
4sub_path: []const u8 = "",
5
6pub fn clone(p: Path, arena: Allocator) Allocator.Error!Path {
7 return .{
8 .root_dir = try p.root_dir.clone(arena),
9 .sub_path = try arena.dupe(u8, p.sub_path),
10 };
11}
12
13pub fn cwd() Path {
14 return .{ .root_dir = Cache.Directory.cwd() };
15}
16
17pub fn join(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path {
18 if (sub_path.len == 0) return p;
19 const parts: []const []const u8 =
20 if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
21 return .{
22 .root_dir = p.root_dir,
23 .sub_path = try fs.path.join(arena, parts),
24 };
25}
26
27pub fn resolvePosix(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path {
28 if (sub_path.len == 0) return p;
29 return .{
30 .root_dir = p.root_dir,
31 .sub_path = try fs.path.resolvePosix(arena, &.{ p.sub_path, sub_path }),
32 };
33}
34
35pub fn joinString(p: Path, allocator: Allocator, sub_path: []const u8) Allocator.Error![]u8 {
36 const parts: []const []const u8 =
37 if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
38 return p.root_dir.join(allocator, parts);
39}
40
41pub fn joinStringZ(p: Path, allocator: Allocator, sub_path: []const u8) Allocator.Error![:0]u8 {
42 const parts: []const []const u8 =
43 if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
44 return p.root_dir.joinZ(allocator, parts);
45}
46
47pub fn openFile(
48 p: Path,
49 sub_path: []const u8,
50 flags: fs.File.OpenFlags,
51) !fs.File {
52 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
53 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
54 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
55 p.sub_path, sub_path,
56 }) catch return error.NameTooLong;
57 };
58 return p.root_dir.handle.openFile(joined_path, flags);
59}
60
61pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: fs.OpenDirOptions) !fs.Dir {
62 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
63 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
64 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
65 p.sub_path, sub_path,
66 }) catch return error.NameTooLong;
67 };
68 return p.root_dir.handle.makeOpenPath(joined_path, opts);
69}
70
71pub fn statFile(p: Path, sub_path: []const u8) !fs.Dir.Stat {
72 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
73 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
74 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
75 p.sub_path, sub_path,
76 }) catch return error.NameTooLong;
77 };
78 return p.root_dir.handle.statFile(joined_path);
79}
80
81pub fn atomicFile(
82 p: Path,
83 sub_path: []const u8,
84 options: fs.Dir.AtomicFileOptions,
85 buf: *[fs.MAX_PATH_BYTES]u8,
86) !fs.AtomicFile {
87 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
88 break :p std.fmt.bufPrint(buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
89 p.sub_path, sub_path,
90 }) catch return error.NameTooLong;
91 };
92 return p.root_dir.handle.atomicFile(joined_path, options);
93}
94
95pub fn access(p: Path, sub_path: []const u8, flags: fs.File.OpenFlags) !void {
96 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
97 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
98 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
99 p.sub_path, sub_path,
100 }) catch return error.NameTooLong;
101 };
102 return p.root_dir.handle.access(joined_path, flags);
103}
104
105pub fn makePath(p: Path, sub_path: []const u8) !void {
106 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
107 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
108 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
109 p.sub_path, sub_path,
110 }) catch return error.NameTooLong;
111 };
112 return p.root_dir.handle.makePath(joined_path);
113}
114
115pub fn format(
116 self: Path,
117 comptime fmt_string: []const u8,
118 options: std.fmt.FormatOptions,
119 writer: anytype,
120) !void {
121 if (fmt_string.len == 1) {
122 // Quote-escape the string.
123 const stringEscape = std.zig.stringEscape;
124 const f = switch (fmt_string[0]) {
125 'q' => "",
126 '\'' => '\'',
127 else => @compileError("unsupported format string: " ++ fmt_string),
128 };
129 if (self.root_dir.path) |p| {
130 try stringEscape(p, f, options, writer);
131 if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, f, options, writer);
132 }
133 if (self.sub_path.len > 0) {
134 try stringEscape(self.sub_path, f, options, writer);
135 }
136 return;
137 }
138 if (fmt_string.len > 0)
139 std.fmt.invalidFmtError(fmt_string, self);
140 if (self.root_dir.path) |p| {
141 try writer.writeAll(p);
142 try writer.writeAll(fs.path.sep_str);
143 }
144 if (self.sub_path.len > 0) {
145 try writer.writeAll(self.sub_path);
146 try writer.writeAll(fs.path.sep_str);
147 }
148}
149
150const Path = @This();
151const std = @import("../../std.zig");
152const fs = std.fs;
153const Allocator = std.mem.Allocator;
154const Cache = std.Build.Cache;
src/Package.zig-159
......@@ -2,162 +2,3 @@ pub const Module = @import("Package/Module.zig");
22pub const Fetch = @import("Package/Fetch.zig");
33pub const build_zig_basename = "build.zig";
44pub const Manifest = @import("Package/Manifest.zig");
5
6pub const Path = struct {
7 root_dir: Cache.Directory,
8 /// The path, relative to the root dir, that this `Path` represents.
9 /// Empty string means the root_dir is the path.
10 sub_path: []const u8 = "",
11
12 pub fn clone(p: Path, arena: Allocator) Allocator.Error!Path {
13 return .{
14 .root_dir = try p.root_dir.clone(arena),
15 .sub_path = try arena.dupe(u8, p.sub_path),
16 };
17 }
18
19 pub fn cwd() Path {
20 return .{ .root_dir = Cache.Directory.cwd() };
21 }
22
23 pub fn join(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path {
24 if (sub_path.len == 0) return p;
25 const parts: []const []const u8 =
26 if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
27 return .{
28 .root_dir = p.root_dir,
29 .sub_path = try fs.path.join(arena, parts),
30 };
31 }
32
33 pub fn resolvePosix(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path {
34 if (sub_path.len == 0) return p;
35 return .{
36 .root_dir = p.root_dir,
37 .sub_path = try fs.path.resolvePosix(arena, &.{ p.sub_path, sub_path }),
38 };
39 }
40
41 pub fn joinString(p: Path, allocator: Allocator, sub_path: []const u8) Allocator.Error![]u8 {
42 const parts: []const []const u8 =
43 if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
44 return p.root_dir.join(allocator, parts);
45 }
46
47 pub fn joinStringZ(p: Path, allocator: Allocator, sub_path: []const u8) Allocator.Error![:0]u8 {
48 const parts: []const []const u8 =
49 if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
50 return p.root_dir.joinZ(allocator, parts);
51 }
52
53 pub fn openFile(
54 p: Path,
55 sub_path: []const u8,
56 flags: fs.File.OpenFlags,
57 ) !fs.File {
58 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
59 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
60 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
61 p.sub_path, sub_path,
62 }) catch return error.NameTooLong;
63 };
64 return p.root_dir.handle.openFile(joined_path, flags);
65 }
66
67 pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: fs.OpenDirOptions) !fs.Dir {
68 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
69 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
70 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
71 p.sub_path, sub_path,
72 }) catch return error.NameTooLong;
73 };
74 return p.root_dir.handle.makeOpenPath(joined_path, opts);
75 }
76
77 pub fn statFile(p: Path, sub_path: []const u8) !fs.Dir.Stat {
78 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
79 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
80 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
81 p.sub_path, sub_path,
82 }) catch return error.NameTooLong;
83 };
84 return p.root_dir.handle.statFile(joined_path);
85 }
86
87 pub fn atomicFile(
88 p: Path,
89 sub_path: []const u8,
90 options: fs.Dir.AtomicFileOptions,
91 buf: *[fs.MAX_PATH_BYTES]u8,
92 ) !fs.AtomicFile {
93 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
94 break :p std.fmt.bufPrint(buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
95 p.sub_path, sub_path,
96 }) catch return error.NameTooLong;
97 };
98 return p.root_dir.handle.atomicFile(joined_path, options);
99 }
100
101 pub fn access(p: Path, sub_path: []const u8, flags: fs.File.OpenFlags) !void {
102 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
103 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
104 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
105 p.sub_path, sub_path,
106 }) catch return error.NameTooLong;
107 };
108 return p.root_dir.handle.access(joined_path, flags);
109 }
110
111 pub fn makePath(p: Path, sub_path: []const u8) !void {
112 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
113 const joined_path = if (p.sub_path.len == 0) sub_path else p: {
114 break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
115 p.sub_path, sub_path,
116 }) catch return error.NameTooLong;
117 };
118 return p.root_dir.handle.makePath(joined_path);
119 }
120
121 pub fn format(
122 self: Path,
123 comptime fmt_string: []const u8,
124 options: std.fmt.FormatOptions,
125 writer: anytype,
126 ) !void {
127 if (fmt_string.len == 1) {
128 // Quote-escape the string.
129 const stringEscape = std.zig.stringEscape;
130 const f = switch (fmt_string[0]) {
131 'q' => "",
132 '\'' => '\'',
133 else => @compileError("unsupported format string: " ++ fmt_string),
134 };
135 if (self.root_dir.path) |p| {
136 try stringEscape(p, f, options, writer);
137 if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, f, options, writer);
138 }
139 if (self.sub_path.len > 0) {
140 try stringEscape(self.sub_path, f, options, writer);
141 }
142 return;
143 }
144 if (fmt_string.len > 0)
145 std.fmt.invalidFmtError(fmt_string, self);
146 if (self.root_dir.path) |p| {
147 try writer.writeAll(p);
148 try writer.writeAll(fs.path.sep_str);
149 }
150 if (self.sub_path.len > 0) {
151 try writer.writeAll(self.sub_path);
152 try writer.writeAll(fs.path.sep_str);
153 }
154 }
155};
156
157const Package = @This();
158const builtin = @import("builtin");
159const std = @import("std");
160const fs = std.fs;
161const Allocator = std.mem.Allocator;
162const assert = std.debug.assert;
163const Cache = std.Build.Cache;
src/Package/Fetch.zig+6-6
......@@ -33,7 +33,7 @@ location_tok: std.zig.Ast.TokenIndex,
3333hash_tok: std.zig.Ast.TokenIndex,
3434name_tok: std.zig.Ast.TokenIndex,
3535lazy_status: LazyStatus,
36parent_package_root: Package.Path,
36parent_package_root: Cache.Path,
3737parent_manifest_ast: ?*const std.zig.Ast,
3838prog_node: *std.Progress.Node,
3939job_queue: *JobQueue,
......@@ -50,7 +50,7 @@ allow_missing_paths_field: bool,
5050
5151/// This will either be relative to `global_cache`, or to the build root of
5252/// the root package.
53package_root: Package.Path,
53package_root: Cache.Path,
5454error_bundle: ErrorBundle.Wip,
5555manifest: ?Manifest,
5656manifest_ast: std.zig.Ast,
......@@ -263,7 +263,7 @@ pub const JobQueue = struct {
263263pub const Location = union(enum) {
264264 remote: Remote,
265265 /// A directory found inside the parent package.
266 relative_path: Package.Path,
266 relative_path: Cache.Path,
267267 /// Recursive Fetch tasks will never use this Location, but it may be
268268 /// passed in by the CLI. Indicates the file contents here should be copied
269269 /// into the global package cache. It may be a file relative to the cwd or
......@@ -564,7 +564,7 @@ fn checkBuildFileExistence(f: *Fetch) RunError!void {
564564}
565565
566566/// This function populates `f.manifest` or leaves it `null`.
567fn loadManifest(f: *Fetch, pkg_root: Package.Path) RunError!void {
567fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void {
568568 const eb = &f.error_bundle;
569569 const arena = f.arena.allocator();
570570 const manifest_bytes = pkg_root.root_dir.handle.readFileAllocOptions(
......@@ -722,7 +722,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
722722}
723723
724724pub fn relativePathDigest(
725 pkg_root: Package.Path,
725 pkg_root: Cache.Path,
726726 cache_root: Cache.Directory,
727727) Manifest.MultiHashHexDigest {
728728 var hasher = Manifest.Hash.init(.{});
......@@ -1658,7 +1658,7 @@ const Filter = struct {
16581658};
16591659
16601660pub fn depDigest(
1661 pkg_root: Package.Path,
1661 pkg_root: Cache.Path,
16621662 cache_root: Cache.Directory,
16631663 dep: Manifest.Dependency,
16641664) ?Manifest.MultiHashHexDigest {
src/Package/Module.zig+3-3
......@@ -3,7 +3,7 @@
33//! to Zcu. https://github.com/ziglang/zig/issues/14307
44
55/// Only files inside this directory can be imported.
6root: Package.Path,
6root: Cache.Path,
77/// Relative to `root`. May contain path separators.
88root_src_path: []const u8,
99/// Name used in compile errors. Looks like "root.foo.bar".
......@@ -69,7 +69,7 @@ pub const CreateOptions = struct {
6969 builtin_modules: ?*std.StringHashMapUnmanaged(*Module),
7070
7171 pub const Paths = struct {
72 root: Package.Path,
72 root: Cache.Path,
7373 /// Relative to `root`. May contain path separators.
7474 root_src_path: []const u8,
7575 };
......@@ -463,7 +463,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
463463
464464/// All fields correspond to `CreateOptions`.
465465pub const LimitedOptions = struct {
466 root: Package.Path,
466 root: Cache.Path,
467467 root_src_path: []const u8,
468468 fully_qualified_name: []const u8,
469469};
src/main.zig+2-2
......@@ -6133,7 +6133,7 @@ fn cmdAstCheck(
61336133 }
61346134
61356135 file.mod = try Package.Module.createLimited(arena, .{
6136 .root = Package.Path.cwd(),
6136 .root = Cache.Path.cwd(),
61376137 .root_src_path = file.sub_file_path,
61386138 .fully_qualified_name = "root",
61396139 });
......@@ -6306,7 +6306,7 @@ fn cmdChangelist(
63066306 };
63076307
63086308 file.mod = try Package.Module.createLimited(arena, .{
6309 .root = Package.Path.cwd(),
6309 .root = Cache.Path.cwd(),
63106310 .root_src_path = file.sub_file_path,
63116311 .fully_qualified_name = "root",
63126312 });