authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-24 21:00:30-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-02-26 11:42:03-08:00
log7cedc01b7e8b0788bb707456bfc0a7b344a783a6
tree9402779572f38fa5e6c21d53f5b87474471dca02
parentd6a88ed74db270c14c669ab334f3ab715cfd2b76

zig init: sanitize generated name

Adhere to the new rules: 32 byte limit + must be a valid bare zig identifier

1 files changed, 20 insertions(+), 2 deletions(-)

src/main.zig+20-2
...@@ -4741,6 +4741,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4741,6 +4741,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
47414741
4742 const cwd_path = try process.getCwdAlloc(arena);4742 const cwd_path = try process.getCwdAlloc(arena);
4743 const cwd_basename = fs.path.basename(cwd_path);4743 const cwd_basename = fs.path.basename(cwd_path);
4744 const sanitized_root_name = try sanitizeExampleName(arena, cwd_basename);
47444745
4745 const s = fs.path.sep_str;4746 const s = fs.path.sep_str;
4746 const template_paths = [_][]const u8{4747 const template_paths = [_][]const u8{
...@@ -4754,7 +4755,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4754,7 +4755,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4754 const id = Package.randomId();4755 const id = Package.randomId();
47554756
4756 for (template_paths) |template_path| {4757 for (template_paths) |template_path| {
4757 if (templates.write(arena, fs.cwd(), cwd_basename, template_path, id)) |_| {4758 if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, id)) |_| {
4758 std.log.info("created {s}", .{template_path});4759 std.log.info("created {s}", .{template_path});
4759 ok_count += 1;4760 ok_count += 1;
4760 } else |err| switch (err) {4761 } else |err| switch (err) {
...@@ -4771,6 +4772,23 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -4771,6 +4772,23 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4771 return cleanExit();4772 return cleanExit();
4772}4773}
47734774
4775fn sanitizeExampleName(arena: Allocator, bytes: []const u8) error{OutOfMemory}![]const u8 {
4776 if (bytes.len == 0) return "foo";
4777 var result: std.ArrayListUnmanaged(u8) = .empty;
4778 try result.append(arena, switch (bytes[0]) {
4779 '_', 'a'...'z', 'A'...'Z' => |c| c,
4780 else => '_',
4781 });
4782 for (bytes[1..]) |byte| switch (byte) {
4783 '_', 'a'...'z', 'A'...'Z', '0'...'9' => try result.append(arena, byte),
4784 else => continue,
4785 };
4786 if (result.items.len > Package.Manifest.max_name_len)
4787 result.shrinkRetainingCapacity(Package.Manifest.max_name_len);
4788
4789 return result.toOwnedSlice(arena);
4790}
4791
4774fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {4792fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
4775 dev.check(.build_command);4793 dev.check(.build_command);
47764794
...@@ -7148,7 +7166,7 @@ fn cmdFetch(...@@ -7148,7 +7166,7 @@ fn cmdFetch(
7148 // The name to use in case the manifest file needs to be created now.7166 // The name to use in case the manifest file needs to be created now.
7149 const init_root_name = fs.path.basename(build_root.directory.path orelse cwd_path);7167 const init_root_name = fs.path.basename(build_root.directory.path orelse cwd_path);
7150 var manifest, var ast = try loadManifest(gpa, arena, .{7168 var manifest, var ast = try loadManifest(gpa, arena, .{
7151 .root_name = init_root_name,7169 .root_name = try sanitizeExampleName(arena, init_root_name),
7152 .dir = build_root.directory.handle,7170 .dir = build_root.directory.handle,
7153 .color = color,7171 .color = color,
7154 });7172 });