zig init: sanitize generated name

Adhere to the new rules: 32 byte limit + must be a valid bare zig
identifier
This commit is contained in:
Andrew Kelley 2025-02-24 21:00:30 -08:00
parent d6a88ed74d
commit 7cedc01b7e

View File

@ -4741,6 +4741,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
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 sanitized_root_name = try sanitizeExampleName(arena, cwd_basename);
const s = fs.path.sep_str; const s = fs.path.sep_str;
const template_paths = [_][]const u8{ const template_paths = [_][]const u8{
@ -4754,7 +4755,7 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
const id = Package.randomId(); const id = Package.randomId();
for (template_paths) |template_path| { for (template_paths) |template_path| {
if (templates.write(arena, fs.cwd(), cwd_basename, template_path, id)) |_| { if (templates.write(arena, fs.cwd(), sanitized_root_name, template_path, id)) |_| {
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) {
@ -4771,6 +4772,23 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
return cleanExit(); return cleanExit();
} }
fn sanitizeExampleName(arena: Allocator, bytes: []const u8) error{OutOfMemory}![]const u8 {
if (bytes.len == 0) return "foo";
var result: std.ArrayListUnmanaged(u8) = .empty;
try result.append(arena, switch (bytes[0]) {
'_', 'a'...'z', 'A'...'Z' => |c| c,
else => '_',
});
for (bytes[1..]) |byte| switch (byte) {
'_', 'a'...'z', 'A'...'Z', '0'...'9' => try result.append(arena, byte),
else => continue,
};
if (result.items.len > Package.Manifest.max_name_len)
result.shrinkRetainingCapacity(Package.Manifest.max_name_len);
return result.toOwnedSlice(arena);
}
fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
dev.check(.build_command); dev.check(.build_command);
@ -7148,7 +7166,7 @@ fn cmdFetch(
// The name to use in case the manifest file needs to be created now. // 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); const init_root_name = fs.path.basename(build_root.directory.path orelse cwd_path);
var manifest, var ast = try loadManifest(gpa, arena, .{ var manifest, var ast = try loadManifest(gpa, arena, .{
.root_name = init_root_name, .root_name = try sanitizeExampleName(arena, init_root_name),
.dir = build_root.directory.handle, .dir = build_root.directory.handle,
.color = color, .color = color,
}); });