Skip to content

zig init template: add compiler version to build.zig.zon by default #22698

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/init/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ pub fn build(b: *std.Build) void {
// Modules can depend on one another using the `std.Build.Module.addImport` function.
// This is what allows Zig source code to use `@import("foo")` where 'foo' is not a
// file path. In this case, we set up `exe_mod` to import `lib_mod`.
exe_mod.addImport("$_lib", lib_mod);
exe_mod.addImport("$root_lib", lib_mod);

// Now, we will create a static library based on the module we created above.
// This creates a `std.Build.Step.Compile`, which is the build step responsible
// for actually invoking the compiler.
const lib = b.addLibrary(.{
.linkage = .static,
.name = "$",
.name = "$root",
.root_module = lib_mod,
});

Expand All @@ -61,7 +61,7 @@ pub fn build(b: *std.Build) void {
// This creates another `std.Build.Step.Compile`, but this one builds an executable
// rather than a static library.
const exe = b.addExecutable(.{
.name = "$",
.name = "$root",
.root_module = exe_mod,
});

Expand Down
4 changes: 2 additions & 2 deletions lib/init/build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
// It is redundant to include "zig" in this name because it is already
// within the Zig package namespace.
.name = "$",
.name = "$root",

// This is a [Semantic Version](https://semver.org/).
// In a future version of Zig it will be used for package deduplication.
Expand All @@ -15,7 +15,7 @@
// This field is optional.
// This is currently advisory only; Zig does not yet do anything
// with this value.
//.minimum_zig_version = "0.11.0",
.minimum_zig_version = "$version",

// This field is optional.
// Each dependency must either provide a `url` and `hash`, or a `path`.
Expand Down
8 changes: 3 additions & 5 deletions lib/init/src/main.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! By convention, main.zig is where your main function lives in the case that
//! you are building an executable. If you are making a library, the convention
//! is to delete this file and start with root.zig instead.
const std = @import("std");
/// This imports the separate module containing `root.zig`. Take a look in `build.zig` for details.
const lib = @import("$root_lib");

pub fn main() !void {
// Prints to stderr (it's a shortcut based on `std.io.getStdErr()`)
Expand Down Expand Up @@ -38,8 +41,3 @@ test "fuzz example" {
};
try std.testing.fuzz(global.testOne, .{});
}

const std = @import("std");

/// This imports the separate module containing `root.zig`. Take a look in `build.zig` for details.
const lib = @import("$_lib");
72 changes: 64 additions & 8 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4739,8 +4739,14 @@ fn cmdInit(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
};
var ok_count: usize = 0;

// default replacements for templates
const replacements = &[_]Replacement{
.{ .variable = "$root", .replacement = cwd_basename },
.{ .variable = "$version", .replacement = build_options.version },
};

for (template_paths) |template_path| {
if (templates.write(arena, fs.cwd(), cwd_basename, template_path)) |_| {
if (templates.write(arena, fs.cwd(), template_path, replacements)) |_| {
std.log.info("created {s}", .{template_path});
ok_count += 1;
} else |err| switch (err) {
Expand Down Expand Up @@ -7410,7 +7416,12 @@ fn loadManifest(
var templates = findTemplates(gpa, arena);
defer templates.deinit();

templates.write(arena, options.dir, options.root_name, Package.Manifest.basename) catch |e| {
const replacements = &[_]Replacement{
.{ .variable = "$root", .replacement = options.root_name },
.{ .variable = "$version", .replacement = build_options.version },
};

templates.write(arena, options.dir, Package.Manifest.basename, replacements) catch |e| {
fatal("unable to write {s}: {s}", .{
Package.Manifest.basename, @errorName(e),
});
Expand Down Expand Up @@ -7450,6 +7461,13 @@ fn loadManifest(
return .{ manifest, ast };
}

/// replace variables for Zig templates
/// $root -> "project_name"
const Replacement = struct {
variable: []const u8,
replacement: []const u8,
};

const Templates = struct {
zig_lib_directory: Cache.Directory,
dir: fs.Dir,
Expand All @@ -7466,8 +7484,8 @@ const Templates = struct {
templates: *Templates,
arena: Allocator,
out_dir: fs.Dir,
root_name: []const u8,
template_path: []const u8,
replacements: ?[]const Replacement,
) !void {
if (fs.path.dirname(template_path)) |dirname| {
out_dir.makePath(dirname) catch |err| {
Expand All @@ -7479,14 +7497,52 @@ const Templates = struct {
const contents = templates.dir.readFileAlloc(arena, template_path, max_bytes) catch |err| {
fatal("unable to read template file '{s}': {s}", .{ template_path, @errorName(err) });
};

templates.buffer.clearRetainingCapacity();
try templates.buffer.ensureUnusedCapacity(contents.len);
for (contents) |c| {
if (c == '$') {
try templates.buffer.appendSlice(root_name);
} else {
try templates.buffer.append(c);

var iterator = mem.splitScalar(u8, contents, '\n');

// replace variables like $root and $version with the project name
// and zig compiler version respectively
while (iterator.next()) |line| {
var i: usize = 0;
while (i < line.len) : (i += 1) {
const c = line[i];

if (replacements) |replace_items| {
if (c == '$') {
var found: bool = false;

for (replace_items) |replacement| {
if (replacement.variable.len < 2) {
return error.InvalidVariable;
}

if (line.len - i < replacement.variable.len) {
continue;
}

// found a match, break out
if (mem.eql(u8, replacement.variable, line[i .. i + replacement.variable.len])) {
try templates.buffer.appendSlice(replacement.replacement);
i += replacement.variable.len - 1;
found = true;
break;
}
}

if (!found) try templates.buffer.append(c);
} else {
// if we make it out here, no replacement was found, and we write out the literal '$'
try templates.buffer.append(c);
}
} else {
try templates.buffer.append(c);
}
}

try templates.buffer.append('\n');
}

return out_dir.writeFile(.{
Expand Down
Loading