From 7bc0b74b6d57ff1a350a4f430f7d9e799a90edd0 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 21 Mar 2024 16:16:47 -0700 Subject: [PATCH] move Package.Path to std.Build.Cache.Path --- lib/std/Build/Cache.zig | 1 + lib/std/Build/Cache/Path.zig | 154 +++++++++++++++++++++++++++++++++ src/Package.zig | 159 ----------------------------------- src/Package/Fetch.zig | 12 +-- src/Package/Module.zig | 6 +- src/main.zig | 4 +- 6 files changed, 166 insertions(+), 170 deletions(-) create mode 100644 lib/std/Build/Cache/Path.zig diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index a33e574871..d846917fd3 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -17,6 +17,7 @@ mutex: std.Thread.Mutex = .{}, prefixes_buffer: [4]Directory = undefined, prefixes_len: usize = 0, +pub const Path = @import("Cache/Path.zig"); pub const Directory = @import("Cache/Directory.zig"); pub const DepTokenizer = @import("Cache/DepTokenizer.zig"); diff --git a/lib/std/Build/Cache/Path.zig b/lib/std/Build/Cache/Path.zig new file mode 100644 index 0000000000..99ce2e12ee --- /dev/null +++ b/lib/std/Build/Cache/Path.zig @@ -0,0 +1,154 @@ +root_dir: Cache.Directory, +/// The path, relative to the root dir, that this `Path` represents. +/// Empty string means the root_dir is the path. +sub_path: []const u8 = "", + +pub fn clone(p: Path, arena: Allocator) Allocator.Error!Path { + return .{ + .root_dir = try p.root_dir.clone(arena), + .sub_path = try arena.dupe(u8, p.sub_path), + }; +} + +pub fn cwd() Path { + return .{ .root_dir = Cache.Directory.cwd() }; +} + +pub fn join(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path { + if (sub_path.len == 0) return p; + const parts: []const []const u8 = + if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path }; + return .{ + .root_dir = p.root_dir, + .sub_path = try fs.path.join(arena, parts), + }; +} + +pub fn resolvePosix(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path { + if (sub_path.len == 0) return p; + return .{ + .root_dir = p.root_dir, + .sub_path = try fs.path.resolvePosix(arena, &.{ p.sub_path, sub_path }), + }; +} + +pub fn joinString(p: Path, allocator: Allocator, sub_path: []const u8) Allocator.Error![]u8 { + const parts: []const []const u8 = + if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path }; + return p.root_dir.join(allocator, parts); +} + +pub fn joinStringZ(p: Path, allocator: Allocator, sub_path: []const u8) Allocator.Error![:0]u8 { + const parts: []const []const u8 = + if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path }; + return p.root_dir.joinZ(allocator, parts); +} + +pub fn openFile( + p: Path, + sub_path: []const u8, + flags: fs.File.OpenFlags, +) !fs.File { + var buf: [fs.MAX_PATH_BYTES]u8 = undefined; + const joined_path = if (p.sub_path.len == 0) sub_path else p: { + break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ + p.sub_path, sub_path, + }) catch return error.NameTooLong; + }; + return p.root_dir.handle.openFile(joined_path, flags); +} + +pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: fs.OpenDirOptions) !fs.Dir { + var buf: [fs.MAX_PATH_BYTES]u8 = undefined; + const joined_path = if (p.sub_path.len == 0) sub_path else p: { + break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ + p.sub_path, sub_path, + }) catch return error.NameTooLong; + }; + return p.root_dir.handle.makeOpenPath(joined_path, opts); +} + +pub fn statFile(p: Path, sub_path: []const u8) !fs.Dir.Stat { + var buf: [fs.MAX_PATH_BYTES]u8 = undefined; + const joined_path = if (p.sub_path.len == 0) sub_path else p: { + break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ + p.sub_path, sub_path, + }) catch return error.NameTooLong; + }; + return p.root_dir.handle.statFile(joined_path); +} + +pub fn atomicFile( + p: Path, + sub_path: []const u8, + options: fs.Dir.AtomicFileOptions, + buf: *[fs.MAX_PATH_BYTES]u8, +) !fs.AtomicFile { + const joined_path = if (p.sub_path.len == 0) sub_path else p: { + break :p std.fmt.bufPrint(buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ + p.sub_path, sub_path, + }) catch return error.NameTooLong; + }; + return p.root_dir.handle.atomicFile(joined_path, options); +} + +pub fn access(p: Path, sub_path: []const u8, flags: fs.File.OpenFlags) !void { + var buf: [fs.MAX_PATH_BYTES]u8 = undefined; + const joined_path = if (p.sub_path.len == 0) sub_path else p: { + break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ + p.sub_path, sub_path, + }) catch return error.NameTooLong; + }; + return p.root_dir.handle.access(joined_path, flags); +} + +pub fn makePath(p: Path, sub_path: []const u8) !void { + var buf: [fs.MAX_PATH_BYTES]u8 = undefined; + const joined_path = if (p.sub_path.len == 0) sub_path else p: { + break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ + p.sub_path, sub_path, + }) catch return error.NameTooLong; + }; + return p.root_dir.handle.makePath(joined_path); +} + +pub fn format( + self: Path, + comptime fmt_string: []const u8, + options: std.fmt.FormatOptions, + writer: anytype, +) !void { + if (fmt_string.len == 1) { + // Quote-escape the string. + const stringEscape = std.zig.stringEscape; + const f = switch (fmt_string[0]) { + 'q' => "", + '\'' => '\'', + else => @compileError("unsupported format string: " ++ fmt_string), + }; + if (self.root_dir.path) |p| { + try stringEscape(p, f, options, writer); + if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, f, options, writer); + } + if (self.sub_path.len > 0) { + try stringEscape(self.sub_path, f, options, writer); + } + return; + } + if (fmt_string.len > 0) + std.fmt.invalidFmtError(fmt_string, self); + if (self.root_dir.path) |p| { + try writer.writeAll(p); + try writer.writeAll(fs.path.sep_str); + } + if (self.sub_path.len > 0) { + try writer.writeAll(self.sub_path); + try writer.writeAll(fs.path.sep_str); + } +} + +const Path = @This(); +const std = @import("../../std.zig"); +const fs = std.fs; +const Allocator = std.mem.Allocator; +const Cache = std.Build.Cache; diff --git a/src/Package.zig b/src/Package.zig index 1bb02c5a5a..e173665e11 100644 --- a/src/Package.zig +++ b/src/Package.zig @@ -2,162 +2,3 @@ pub const Module = @import("Package/Module.zig"); pub const Fetch = @import("Package/Fetch.zig"); pub const build_zig_basename = "build.zig"; pub const Manifest = @import("Package/Manifest.zig"); - -pub const Path = struct { - root_dir: Cache.Directory, - /// The path, relative to the root dir, that this `Path` represents. - /// Empty string means the root_dir is the path. - sub_path: []const u8 = "", - - pub fn clone(p: Path, arena: Allocator) Allocator.Error!Path { - return .{ - .root_dir = try p.root_dir.clone(arena), - .sub_path = try arena.dupe(u8, p.sub_path), - }; - } - - pub fn cwd() Path { - return .{ .root_dir = Cache.Directory.cwd() }; - } - - pub fn join(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path { - if (sub_path.len == 0) return p; - const parts: []const []const u8 = - if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path }; - return .{ - .root_dir = p.root_dir, - .sub_path = try fs.path.join(arena, parts), - }; - } - - pub fn resolvePosix(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path { - if (sub_path.len == 0) return p; - return .{ - .root_dir = p.root_dir, - .sub_path = try fs.path.resolvePosix(arena, &.{ p.sub_path, sub_path }), - }; - } - - pub fn joinString(p: Path, allocator: Allocator, sub_path: []const u8) Allocator.Error![]u8 { - const parts: []const []const u8 = - if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path }; - return p.root_dir.join(allocator, parts); - } - - pub fn joinStringZ(p: Path, allocator: Allocator, sub_path: []const u8) Allocator.Error![:0]u8 { - const parts: []const []const u8 = - if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path }; - return p.root_dir.joinZ(allocator, parts); - } - - pub fn openFile( - p: Path, - sub_path: []const u8, - flags: fs.File.OpenFlags, - ) !fs.File { - var buf: [fs.MAX_PATH_BYTES]u8 = undefined; - const joined_path = if (p.sub_path.len == 0) sub_path else p: { - break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ - p.sub_path, sub_path, - }) catch return error.NameTooLong; - }; - return p.root_dir.handle.openFile(joined_path, flags); - } - - pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: fs.OpenDirOptions) !fs.Dir { - var buf: [fs.MAX_PATH_BYTES]u8 = undefined; - const joined_path = if (p.sub_path.len == 0) sub_path else p: { - break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ - p.sub_path, sub_path, - }) catch return error.NameTooLong; - }; - return p.root_dir.handle.makeOpenPath(joined_path, opts); - } - - pub fn statFile(p: Path, sub_path: []const u8) !fs.Dir.Stat { - var buf: [fs.MAX_PATH_BYTES]u8 = undefined; - const joined_path = if (p.sub_path.len == 0) sub_path else p: { - break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ - p.sub_path, sub_path, - }) catch return error.NameTooLong; - }; - return p.root_dir.handle.statFile(joined_path); - } - - pub fn atomicFile( - p: Path, - sub_path: []const u8, - options: fs.Dir.AtomicFileOptions, - buf: *[fs.MAX_PATH_BYTES]u8, - ) !fs.AtomicFile { - const joined_path = if (p.sub_path.len == 0) sub_path else p: { - break :p std.fmt.bufPrint(buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ - p.sub_path, sub_path, - }) catch return error.NameTooLong; - }; - return p.root_dir.handle.atomicFile(joined_path, options); - } - - pub fn access(p: Path, sub_path: []const u8, flags: fs.File.OpenFlags) !void { - var buf: [fs.MAX_PATH_BYTES]u8 = undefined; - const joined_path = if (p.sub_path.len == 0) sub_path else p: { - break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ - p.sub_path, sub_path, - }) catch return error.NameTooLong; - }; - return p.root_dir.handle.access(joined_path, flags); - } - - pub fn makePath(p: Path, sub_path: []const u8) !void { - var buf: [fs.MAX_PATH_BYTES]u8 = undefined; - const joined_path = if (p.sub_path.len == 0) sub_path else p: { - break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{ - p.sub_path, sub_path, - }) catch return error.NameTooLong; - }; - return p.root_dir.handle.makePath(joined_path); - } - - pub fn format( - self: Path, - comptime fmt_string: []const u8, - options: std.fmt.FormatOptions, - writer: anytype, - ) !void { - if (fmt_string.len == 1) { - // Quote-escape the string. - const stringEscape = std.zig.stringEscape; - const f = switch (fmt_string[0]) { - 'q' => "", - '\'' => '\'', - else => @compileError("unsupported format string: " ++ fmt_string), - }; - if (self.root_dir.path) |p| { - try stringEscape(p, f, options, writer); - if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, f, options, writer); - } - if (self.sub_path.len > 0) { - try stringEscape(self.sub_path, f, options, writer); - } - return; - } - if (fmt_string.len > 0) - std.fmt.invalidFmtError(fmt_string, self); - if (self.root_dir.path) |p| { - try writer.writeAll(p); - try writer.writeAll(fs.path.sep_str); - } - if (self.sub_path.len > 0) { - try writer.writeAll(self.sub_path); - try writer.writeAll(fs.path.sep_str); - } - } -}; - -const Package = @This(); -const builtin = @import("builtin"); -const std = @import("std"); -const fs = std.fs; -const Allocator = std.mem.Allocator; -const assert = std.debug.assert; -const Cache = std.Build.Cache; diff --git a/src/Package/Fetch.zig b/src/Package/Fetch.zig index a40bb539f7..d0cfd5ab94 100644 --- a/src/Package/Fetch.zig +++ b/src/Package/Fetch.zig @@ -33,7 +33,7 @@ location_tok: std.zig.Ast.TokenIndex, hash_tok: std.zig.Ast.TokenIndex, name_tok: std.zig.Ast.TokenIndex, lazy_status: LazyStatus, -parent_package_root: Package.Path, +parent_package_root: Cache.Path, parent_manifest_ast: ?*const std.zig.Ast, prog_node: *std.Progress.Node, job_queue: *JobQueue, @@ -50,7 +50,7 @@ allow_missing_paths_field: bool, /// This will either be relative to `global_cache`, or to the build root of /// the root package. -package_root: Package.Path, +package_root: Cache.Path, error_bundle: ErrorBundle.Wip, manifest: ?Manifest, manifest_ast: std.zig.Ast, @@ -263,7 +263,7 @@ pub const JobQueue = struct { pub const Location = union(enum) { remote: Remote, /// A directory found inside the parent package. - relative_path: Package.Path, + relative_path: Cache.Path, /// Recursive Fetch tasks will never use this Location, but it may be /// passed in by the CLI. Indicates the file contents here should be copied /// 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 { } /// This function populates `f.manifest` or leaves it `null`. -fn loadManifest(f: *Fetch, pkg_root: Package.Path) RunError!void { +fn loadManifest(f: *Fetch, pkg_root: Cache.Path) RunError!void { const eb = &f.error_bundle; const arena = f.arena.allocator(); const manifest_bytes = pkg_root.root_dir.handle.readFileAllocOptions( @@ -722,7 +722,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void { } pub fn relativePathDigest( - pkg_root: Package.Path, + pkg_root: Cache.Path, cache_root: Cache.Directory, ) Manifest.MultiHashHexDigest { var hasher = Manifest.Hash.init(.{}); @@ -1658,7 +1658,7 @@ const Filter = struct { }; pub fn depDigest( - pkg_root: Package.Path, + pkg_root: Cache.Path, cache_root: Cache.Directory, dep: Manifest.Dependency, ) ?Manifest.MultiHashHexDigest { diff --git a/src/Package/Module.zig b/src/Package/Module.zig index d6b89efb41..f9cb4475ad 100644 --- a/src/Package/Module.zig +++ b/src/Package/Module.zig @@ -3,7 +3,7 @@ //! to Zcu. https://github.com/ziglang/zig/issues/14307 /// Only files inside this directory can be imported. -root: Package.Path, +root: Cache.Path, /// Relative to `root`. May contain path separators. root_src_path: []const u8, /// Name used in compile errors. Looks like "root.foo.bar". @@ -69,7 +69,7 @@ pub const CreateOptions = struct { builtin_modules: ?*std.StringHashMapUnmanaged(*Module), pub const Paths = struct { - root: Package.Path, + root: Cache.Path, /// Relative to `root`. May contain path separators. root_src_path: []const u8, }; @@ -463,7 +463,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { /// All fields correspond to `CreateOptions`. pub const LimitedOptions = struct { - root: Package.Path, + root: Cache.Path, root_src_path: []const u8, fully_qualified_name: []const u8, }; diff --git a/src/main.zig b/src/main.zig index be2083a0f8..9629d2bf18 100644 --- a/src/main.zig +++ b/src/main.zig @@ -6133,7 +6133,7 @@ fn cmdAstCheck( } file.mod = try Package.Module.createLimited(arena, .{ - .root = Package.Path.cwd(), + .root = Cache.Path.cwd(), .root_src_path = file.sub_file_path, .fully_qualified_name = "root", }); @@ -6306,7 +6306,7 @@ fn cmdChangelist( }; file.mod = try Package.Module.createLimited(arena, .{ - .root = Package.Path.cwd(), + .root = Cache.Path.cwd(), .root_src_path = file.sub_file_path, .fully_qualified_name = "root", });