| ... | @@ -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 { |
| 4741 | | 4741 | |
| 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); |
| 4744 | | 4745 | |
| 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(); |
| 4755 | | 4756 | |
| 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 | } |
| 4773 | | 4774 | |
| | 4775 | fn 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 | |
| 4774 | fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | 4792 | fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 4775 | dev.check(.build_command); | 4793 | dev.check(.build_command); |
| 4776 | | 4794 | |
| ... | @@ -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 | }); |