app: add mach CLI and integrate wasmserve (#738)

This commit is contained in:
Ali Chraghi 2023-04-02 23:07:05 +03:30 committed by GitHub
parent ee2ee13541
commit 60597f78d8
Failed to generate hash of commit
20 changed files with 731 additions and 813 deletions

177
app/main.zig Normal file
View file

@ -0,0 +1,177 @@
const std = @import("std");
const builtin = @import("builtin");
const Builder = @import("Builder.zig");
const Target = @import("target.zig").Target;
const default_zig_path = "zig";
var args: []const [:0]u8 = undefined;
var arg_i: usize = 1;
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
pub const allocator = gpa.allocator();
pub fn main() !void {
defer _ = gpa.deinit();
args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
if (args.len == 1) return;
if (std.mem.eql(u8, args[arg_i], "build")) {
arg_i += 1;
var builder = Builder{};
var steps = std.ArrayList([]const u8).init(allocator);
var build_args = std.ArrayList([]const u8).init(allocator);
while (arg_i < args.len) : (arg_i += 1) {
if (argOption("-zig-path")) |value| {
builder.zig_path = value;
} else if (std.mem.eql(u8, args[arg_i], "--serve")) {
if (builder.target == null) builder.target = .wasm32;
if (builder.target.? != .wasm32) {
std.log.err("--serve requires -target=wasm32", .{});
try printHelp(.build);
std.os.exit(1);
}
builder.serve = true;
} else if (argOption("-target")) |value| {
builder.target = Target.parse(value) orelse {
std.log.err("invalid target '{s}'", .{args[arg_i]});
try printHelp(.build);
std.os.exit(1);
};
} else if (argOption("-listen-port")) |value| {
builder.listen_port = std.fmt.parseInt(u16, value, 10) catch {
std.log.err("invalid port '{s}'", .{args[arg_i]});
try printHelp(.build);
std.os.exit(1);
};
} else if (argOption("-watch-path")) |value| {
var paths = std.mem.split(u8, value, ",");
builder.watch_paths = try allocator.alloc([]const u8, std.mem.count(u8, value, ",") + 1);
for (0..255) |i| {
const path = paths.next() orelse break;
builder.watch_paths.?[i] = std.mem.trim(u8, path, &std.ascii.whitespace);
}
} else if (argOption("-optimize")) |value| {
builder.optimize = std.meta.stringToEnum(std.builtin.OptimizeMode, value) orelse {
std.log.err("invalid optimize mode '{s}'", .{args[arg_i]});
try printHelp(.build);
std.os.exit(1);
};
} else if (std.mem.eql(u8, args[arg_i], "--")) {
arg_i += 1;
while (arg_i < args.len) : (arg_i += 1) {
try build_args.append(args[arg_i]);
}
} else {
try steps.append(args[arg_i]);
}
}
builder.steps = try steps.toOwnedSlice();
builder.zig_build_args = try build_args.toOwnedSlice();
return builder.run();
} else if (std.mem.eql(u8, args[arg_i], "help")) {
arg_i += 1;
var subcommand = SubCommand.help;
if (arg_i < args.len) {
if (std.mem.eql(u8, args[arg_i], "build")) {
subcommand = .build;
} else {
std.log.err("unknown command name '{s}'", .{args[arg_i]});
try printHelp(.help);
std.os.exit(1);
}
}
return printHelp(subcommand);
} else {
std.log.err("invalid command '{s}'", .{args[arg_i]});
try printHelp(.help);
std.os.exit(1);
}
}
pub const SubCommand = enum {
build,
help,
};
fn printHelp(subcommand: SubCommand) !void {
const stdout = std.io.getStdOut();
switch (subcommand) {
.build => {
try stdout.writeAll(
\\Usage:
\\ mach build [steps] [options] [-- [zig-build-options]]
\\
\\General Options:
\\
\\ -zig-path [path] Override path to zig binary
\\
\\ -target [target] The CPU architecture and OS to build for
\\ Default is native target
\\ Supported targets:
\\ linux-x86_64, linux-aarch64,
\\ macos-x86_64, macos-aarch64,
\\ windows-x86_64, windows-aarch64,
\\ wasm32,
\\
\\ -optimize [optimize] Prioritize performance, safety, or binary size
\\ Default is Debug
\\ Supported values:
\\ Debug
\\ ReleaseSafe
\\ ReleaseFast
\\ ReleaseSmall
\\
\\Serve Options:
\\
\\ --serve Starts a development server
\\ for testing WASM applications/games
\\
\\ -listen-port [port] The development server port
\\
\\ -watch-path [paths] Watches for changes in specified directory
\\ and automatically builds and reloads
\\ development server
\\ Separate each path with comma (,)
\\
\\
);
},
.help => {
try stdout.writeAll(
\\Usage:
\\ mach [command]
\\
\\Commands:
\\ build Build current project
\\ help Print this mesage or the help of the given command
\\
\\
);
},
}
}
pub fn argOption(name: []const u8) ?[]const u8 {
const cmd_arg = args[arg_i];
if (std.mem.startsWith(u8, cmd_arg, name)) {
if (cmd_arg.len > name.len + 1 and cmd_arg[name.len] == '=') {
return cmd_arg[name.len + 1 ..];
} else if (cmd_arg.len == name.len) {
arg_i += 1;
if (arg_i < args.len) {
return args[arg_i];
} else {
std.log.err("expected value after '{s}' option", .{cmd_arg});
std.os.exit(1);
}
}
}
return null;
}