mirror of
https://github.com/jetzig-framework/jetzig.git
synced 2025-05-14 14:06:08 +00:00
WIP
This commit is contained in:
parent
fa5b3f240e
commit
dc11412587
52
build.zig
52
build.zig
@ -150,11 +150,9 @@ pub fn jetzigInit(b: *std.Build, exe: *std.Build.Step.Compile, options: JetzigIn
|
|||||||
const jetcommon_module = jetzig_dep.module("jetcommon");
|
const jetcommon_module = jetzig_dep.module("jetcommon");
|
||||||
const jetquery_migrate_module = jetzig_dep.module("jetquery_migrate");
|
const jetquery_migrate_module = jetzig_dep.module("jetquery_migrate");
|
||||||
|
|
||||||
{
|
|
||||||
const build_options = b.addOptions();
|
const build_options = b.addOptions();
|
||||||
build_options.addOption(Environment, "environment", environment);
|
build_options.addOption(Environment, "environment", environment);
|
||||||
jetzig_module.addOptions("build_config", build_options);
|
jetzig_module.addOptions("build_options", build_options);
|
||||||
}
|
|
||||||
|
|
||||||
exe.root_module.addImport("jetzig", jetzig_module);
|
exe.root_module.addImport("jetzig", jetzig_module);
|
||||||
exe.root_module.addImport("zmpl", zmpl_module);
|
exe.root_module.addImport("zmpl", zmpl_module);
|
||||||
@ -311,18 +309,48 @@ pub fn jetzigInit(b: *std.Build, exe: *std.Build.Step.Compile, options: JetzigIn
|
|||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
|
||||||
const migrate_step = b.step("jetzig:migrate", "Migrate your app's database");
|
const exe_database = b.addExecutable(.{
|
||||||
const exe_migrate = b.addExecutable(.{
|
.name = "database",
|
||||||
.name = "migrate",
|
.root_source_file = jetzig_dep.path("src/commands/database.zig"),
|
||||||
.root_source_file = jetzig_dep.path("src/commands/migrate.zig"),
|
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
exe_migrate.root_module.addImport("jetquery", jetquery_module);
|
exe_database.root_module.addImport("jetquery", jetquery_module);
|
||||||
exe_migrate.root_module.addImport("jetcommon", jetcommon_module);
|
exe_database.root_module.addImport("jetcommon", jetcommon_module);
|
||||||
exe_migrate.root_module.addImport("jetquery_migrate", jetquery_migrate_module);
|
exe_database.root_module.addImport("jetquery_migrate", jetquery_migrate_module);
|
||||||
const run_migrate_cmd = b.addRunArtifact(exe_migrate);
|
exe_database.root_module.addOptions("build_options", build_options);
|
||||||
migrate_step.dependOn(&run_migrate_cmd.step);
|
|
||||||
|
const database_migrate_step = b.step(
|
||||||
|
"jetzig:database:migrate",
|
||||||
|
"Migrate your Jetzig app's database.",
|
||||||
|
);
|
||||||
|
const run_database_migrate_cmd = b.addRunArtifact(exe_database);
|
||||||
|
run_database_migrate_cmd.addArg("migrate");
|
||||||
|
database_migrate_step.dependOn(&run_database_migrate_cmd.step);
|
||||||
|
|
||||||
|
const database_rollback_step = b.step(
|
||||||
|
"jetzig:database:rollback",
|
||||||
|
"Roll back a migration in your Jetzig app's database.",
|
||||||
|
);
|
||||||
|
const run_database_rollback_cmd = b.addRunArtifact(exe_database);
|
||||||
|
run_database_rollback_cmd.addArg("rollback");
|
||||||
|
database_rollback_step.dependOn(&run_database_rollback_cmd.step);
|
||||||
|
|
||||||
|
const database_create_step = b.step(
|
||||||
|
"jetzig:database:create",
|
||||||
|
"Create a database for your Jetzig app.",
|
||||||
|
);
|
||||||
|
const run_database_create_cmd = b.addRunArtifact(exe_database);
|
||||||
|
run_database_create_cmd.addArg("create");
|
||||||
|
database_create_step.dependOn(&run_database_create_cmd.step);
|
||||||
|
|
||||||
|
const database_drop_step = b.step(
|
||||||
|
"jetzig:database:drop",
|
||||||
|
"Drop your Jetzig app's database.",
|
||||||
|
);
|
||||||
|
const run_database_drop_cmd = b.addRunArtifact(exe_database);
|
||||||
|
run_database_drop_cmd.addArg("drop");
|
||||||
|
database_drop_step.dependOn(&run_database_drop_cmd.step);
|
||||||
|
|
||||||
exe_routes.root_module.addImport("jetzig", jetzig_module);
|
exe_routes.root_module.addImport("jetzig", jetzig_module);
|
||||||
exe_routes.root_module.addImport("routes", routes_module);
|
exe_routes.root_module.addImport("routes", routes_module);
|
||||||
|
58
cli/cli.zig
58
cli/cli.zig
@ -1,17 +1,20 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const args = @import("args");
|
const args = @import("args");
|
||||||
const init = @import("commands/init.zig");
|
|
||||||
const update = @import("commands/update.zig");
|
|
||||||
const generate = @import("commands/generate.zig");
|
|
||||||
const server = @import("commands/server.zig");
|
|
||||||
const routes = @import("commands/routes.zig");
|
|
||||||
const bundle = @import("commands/bundle.zig");
|
|
||||||
const tests = @import("commands/tests.zig");
|
|
||||||
const database = @import("commands/database.zig");
|
|
||||||
|
|
||||||
const Options = struct {
|
pub const init = @import("commands/init.zig");
|
||||||
|
pub const update = @import("commands/update.zig");
|
||||||
|
pub const generate = @import("commands/generate.zig");
|
||||||
|
pub const server = @import("commands/server.zig");
|
||||||
|
pub const routes = @import("commands/routes.zig");
|
||||||
|
pub const bundle = @import("commands/bundle.zig");
|
||||||
|
pub const tests = @import("commands/tests.zig");
|
||||||
|
pub const database = @import("commands/database.zig");
|
||||||
|
|
||||||
|
pub const Environment = enum { development, testing, production };
|
||||||
|
|
||||||
|
pub const Options = struct {
|
||||||
help: bool = false,
|
help: bool = false,
|
||||||
environment: enum { development, testing, production },
|
environment: Environment = .development,
|
||||||
|
|
||||||
pub const shorthands = .{
|
pub const shorthands = .{
|
||||||
.h = "help",
|
.h = "help",
|
||||||
@ -30,6 +33,7 @@ const Options = struct {
|
|||||||
.@"test" = "Run app tests",
|
.@"test" = "Run app tests",
|
||||||
.database = "Manage the application's database",
|
.database = "Manage the application's database",
|
||||||
.help = "Print help and exit",
|
.help = "Print help and exit",
|
||||||
|
.environment = "Jetzig environment.",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -92,63 +96,65 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run(allocator: std.mem.Allocator, options: args.ParseArgsResult(Options, Verb), writer: anytype) !void {
|
fn run(allocator: std.mem.Allocator, options: args.ParseArgsResult(Options, Verb), writer: anytype) !void {
|
||||||
|
const OptionsType = args.ParseArgsResult(Options, Verb);
|
||||||
|
|
||||||
if (options.verb) |verb| {
|
if (options.verb) |verb| {
|
||||||
return switch (verb) {
|
return switch (verb) {
|
||||||
.init => |opts| init.run(
|
.init => |opts| init.run(
|
||||||
allocator,
|
allocator,
|
||||||
opts,
|
opts,
|
||||||
writer,
|
writer,
|
||||||
options.positionals,
|
OptionsType,
|
||||||
.{ .help = options.options.help },
|
options,
|
||||||
),
|
),
|
||||||
.g, .generate => |opts| generate.run(
|
.g, .generate => |opts| generate.run(
|
||||||
allocator,
|
allocator,
|
||||||
opts,
|
opts,
|
||||||
writer,
|
writer,
|
||||||
options.positionals,
|
OptionsType,
|
||||||
.{ .help = options.options.help },
|
options,
|
||||||
),
|
),
|
||||||
.update => |opts| update.run(
|
.update => |opts| update.run(
|
||||||
allocator,
|
allocator,
|
||||||
opts,
|
opts,
|
||||||
writer,
|
writer,
|
||||||
options.positionals,
|
OptionsType,
|
||||||
.{ .help = options.options.help },
|
options,
|
||||||
),
|
),
|
||||||
.s, .server => |opts| server.run(
|
.s, .server => |opts| server.run(
|
||||||
allocator,
|
allocator,
|
||||||
opts,
|
opts,
|
||||||
writer,
|
writer,
|
||||||
options.positionals,
|
OptionsType,
|
||||||
.{ .help = options.options.help },
|
options,
|
||||||
),
|
),
|
||||||
.r, .routes => |opts| routes.run(
|
.r, .routes => |opts| routes.run(
|
||||||
allocator,
|
allocator,
|
||||||
opts,
|
opts,
|
||||||
writer,
|
writer,
|
||||||
options.positionals,
|
OptionsType,
|
||||||
.{ .help = options.options.help },
|
options,
|
||||||
),
|
),
|
||||||
.b, .bundle => |opts| bundle.run(
|
.b, .bundle => |opts| bundle.run(
|
||||||
allocator,
|
allocator,
|
||||||
opts,
|
opts,
|
||||||
writer,
|
writer,
|
||||||
options.positionals,
|
OptionsType,
|
||||||
.{ .help = options.options.help },
|
options,
|
||||||
),
|
),
|
||||||
.t, .@"test" => |opts| tests.run(
|
.t, .@"test" => |opts| tests.run(
|
||||||
allocator,
|
allocator,
|
||||||
opts,
|
opts,
|
||||||
writer,
|
writer,
|
||||||
options.positionals,
|
OptionsType,
|
||||||
.{ .help = options.options.help },
|
options,
|
||||||
),
|
),
|
||||||
.d, .database => |opts| database.run(
|
.d, .database => |opts| database.run(
|
||||||
allocator,
|
allocator,
|
||||||
opts,
|
opts,
|
||||||
writer,
|
writer,
|
||||||
options.positionals,
|
OptionsType,
|
||||||
.{ .help = options.options.help },
|
options,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -37,16 +37,15 @@ pub fn run(
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
options: Options,
|
options: Options,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
positionals: [][]const u8,
|
T: type,
|
||||||
other_options: struct { help: bool },
|
main_options: T,
|
||||||
) !void {
|
) !void {
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
std.debug.print("Bundling on Windows is currently not supported.\n", .{});
|
std.debug.print("Bundling on Windows is currently not supported.\n", .{});
|
||||||
std.process.exit(1);
|
std.process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = positionals;
|
if (main_options.options.help) {
|
||||||
if (other_options.help) {
|
|
||||||
try args.printHelp(Options, "jetzig bundle", writer);
|
try args.printHelp(Options, "jetzig bundle", writer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const args = @import("args");
|
const args = @import("args");
|
||||||
const util = @import("../util.zig");
|
|
||||||
const jetquery = @import("jetquery");
|
const jetquery = @import("jetquery");
|
||||||
const Migrate = @import("jetquery_migrate");
|
const Migrate = @import("jetquery_migrate");
|
||||||
|
|
||||||
|
const util = @import("../util.zig");
|
||||||
|
const cli = @import("../cli.zig");
|
||||||
|
const migrate = @import("database/migrate.zig");
|
||||||
|
const rollback = @import("database/rollback.zig");
|
||||||
|
const create = @import("database/create.zig");
|
||||||
|
const drop = @import("database/drop.zig");
|
||||||
|
|
||||||
/// Command line options for the `database` command.
|
/// Command line options for the `database` command.
|
||||||
pub const Options = struct {
|
pub const Options = struct {
|
||||||
pub const meta = .{
|
pub const meta = .{
|
||||||
@ -24,16 +31,46 @@ pub fn run(
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
options: Options,
|
options: Options,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
positionals: [][]const u8,
|
T: type,
|
||||||
other_options: struct { help: bool },
|
main_options: T,
|
||||||
) !void {
|
) !void {
|
||||||
_ = options;
|
var arena = std.heap.ArenaAllocator.init(allocator);
|
||||||
_ = writer;
|
defer arena.deinit();
|
||||||
_ = positionals;
|
const alloc = arena.allocator();
|
||||||
_ = other_options;
|
|
||||||
try util.execCommand(allocator, &.{
|
const Action = enum { migrate, rollback, create, drop };
|
||||||
"zig",
|
const map = std.StaticStringMap(Action).initComptime(.{
|
||||||
"build",
|
.{ "migrate", .migrate },
|
||||||
"jetzig:migrate",
|
.{ "rollback", .rollback },
|
||||||
|
.{ "create", .create },
|
||||||
|
.{ "drop", .drop },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const action = if (main_options.positionals.len > 0)
|
||||||
|
map.get(main_options.positionals[0])
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
const sub_args: []const []const u8 = if (main_options.positionals.len > 1)
|
||||||
|
main_options.positionals[1..]
|
||||||
|
else
|
||||||
|
&.{};
|
||||||
|
|
||||||
|
return if (main_options.options.help and action == null) blk: {
|
||||||
|
try args.printHelp(Options, "jetzig database", writer);
|
||||||
|
break :blk {};
|
||||||
|
} else if (action == null) blk: {
|
||||||
|
const available_help = try std.mem.join(alloc, "|", map.keys());
|
||||||
|
std.debug.print("Missing sub-command. Expected: [{s}]\n", .{available_help});
|
||||||
|
break :blk error.JetzigCommandError;
|
||||||
|
} else if (action) |capture| blk: {
|
||||||
|
var cwd = try util.detectJetzigProjectDir();
|
||||||
|
defer cwd.close();
|
||||||
|
|
||||||
|
break :blk switch (capture) {
|
||||||
|
.migrate => migrate.run(alloc, cwd, sub_args, options, T, main_options),
|
||||||
|
.rollback => rollback.run(alloc, cwd, sub_args, options, T, main_options),
|
||||||
|
.create => create.run(alloc, cwd, sub_args, options, T, main_options),
|
||||||
|
.drop => drop.run(alloc, cwd, sub_args, options, T, main_options),
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
36
cli/commands/database/create.zig
Normal file
36
cli/commands/database/create.zig
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const cli = @import("../../cli.zig");
|
||||||
|
const util = @import("../../util.zig");
|
||||||
|
|
||||||
|
pub fn run(
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
cwd: std.fs.Dir,
|
||||||
|
args: []const []const u8,
|
||||||
|
options: cli.database.Options,
|
||||||
|
T: type,
|
||||||
|
main_options: T,
|
||||||
|
) !void {
|
||||||
|
_ = cwd;
|
||||||
|
_ = options;
|
||||||
|
if (main_options.options.help or args.len != 0) {
|
||||||
|
std.debug.print(
|
||||||
|
\\Create a database.
|
||||||
|
\\
|
||||||
|
\\Example:
|
||||||
|
\\
|
||||||
|
\\ jetzig database create
|
||||||
|
\\ jetzig --environment testing database create
|
||||||
|
\\
|
||||||
|
, .{});
|
||||||
|
|
||||||
|
return if (main_options.options.help) {} else error.JetzigCommandError;
|
||||||
|
}
|
||||||
|
|
||||||
|
try util.execCommand(allocator, &.{
|
||||||
|
"zig",
|
||||||
|
"build",
|
||||||
|
util.environmentBuildOption(main_options.options.environment),
|
||||||
|
"jetzig:database:create",
|
||||||
|
});
|
||||||
|
}
|
36
cli/commands/database/drop.zig
Normal file
36
cli/commands/database/drop.zig
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const cli = @import("../../cli.zig");
|
||||||
|
const util = @import("../../util.zig");
|
||||||
|
|
||||||
|
pub fn run(
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
cwd: std.fs.Dir,
|
||||||
|
args: []const []const u8,
|
||||||
|
options: cli.database.Options,
|
||||||
|
T: type,
|
||||||
|
main_options: T,
|
||||||
|
) !void {
|
||||||
|
_ = cwd;
|
||||||
|
_ = options;
|
||||||
|
if (main_options.options.help or args.len != 0) {
|
||||||
|
std.debug.print(
|
||||||
|
\\Run database migrations.
|
||||||
|
\\
|
||||||
|
\\Example:
|
||||||
|
\\
|
||||||
|
\\ jetzig database migrate
|
||||||
|
\\ jetzig --environment testing database migrate
|
||||||
|
\\
|
||||||
|
, .{});
|
||||||
|
|
||||||
|
return if (main_options.options.help) {} else error.JetzigCommandError;
|
||||||
|
}
|
||||||
|
|
||||||
|
try util.execCommand(allocator, &.{
|
||||||
|
"zig",
|
||||||
|
"build",
|
||||||
|
util.environmentBuildOption(main_options.options.environment),
|
||||||
|
"jetzig:database:drop",
|
||||||
|
});
|
||||||
|
}
|
36
cli/commands/database/migrate.zig
Normal file
36
cli/commands/database/migrate.zig
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const cli = @import("../../cli.zig");
|
||||||
|
const util = @import("../../util.zig");
|
||||||
|
|
||||||
|
pub fn run(
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
cwd: std.fs.Dir,
|
||||||
|
args: []const []const u8,
|
||||||
|
options: cli.database.Options,
|
||||||
|
T: type,
|
||||||
|
main_options: T,
|
||||||
|
) !void {
|
||||||
|
_ = cwd;
|
||||||
|
_ = options;
|
||||||
|
if (main_options.options.help or args.len != 0) {
|
||||||
|
std.debug.print(
|
||||||
|
\\Run database migrations.
|
||||||
|
\\
|
||||||
|
\\Example:
|
||||||
|
\\
|
||||||
|
\\ jetzig database migrate
|
||||||
|
\\ jetzig --environment testing database migrate
|
||||||
|
\\
|
||||||
|
, .{});
|
||||||
|
|
||||||
|
return if (main_options.options.help) {} else error.JetzigCommandError;
|
||||||
|
}
|
||||||
|
|
||||||
|
try util.execCommand(allocator, &.{
|
||||||
|
"zig",
|
||||||
|
"build",
|
||||||
|
util.environmentBuildOption(main_options.options.environment),
|
||||||
|
"jetzig:database:migrate",
|
||||||
|
});
|
||||||
|
}
|
36
cli/commands/database/rollback.zig
Normal file
36
cli/commands/database/rollback.zig
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const cli = @import("../../cli.zig");
|
||||||
|
const util = @import("../../util.zig");
|
||||||
|
|
||||||
|
pub fn run(
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
cwd: std.fs.Dir,
|
||||||
|
args: []const []const u8,
|
||||||
|
options: cli.database.Options,
|
||||||
|
T: type,
|
||||||
|
main_options: T,
|
||||||
|
) !void {
|
||||||
|
_ = cwd;
|
||||||
|
_ = options;
|
||||||
|
if (main_options.options.help or args.len != 0) {
|
||||||
|
std.debug.print(
|
||||||
|
\\Run database migrations.
|
||||||
|
\\
|
||||||
|
\\Example:
|
||||||
|
\\
|
||||||
|
\\ jetzig database migrate
|
||||||
|
\\ jetzig --environment testing database migrate
|
||||||
|
\\
|
||||||
|
, .{});
|
||||||
|
|
||||||
|
return if (main_options.options.help) {} else error.JetzigCommandError;
|
||||||
|
}
|
||||||
|
|
||||||
|
try util.execCommand(allocator, &.{
|
||||||
|
"zig",
|
||||||
|
"build",
|
||||||
|
util.environmentBuildOption(main_options.options.environment),
|
||||||
|
"jetzig:database:rollback",
|
||||||
|
});
|
||||||
|
}
|
@ -31,8 +31,8 @@ pub fn run(
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
options: Options,
|
options: Options,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
positionals: [][]const u8,
|
T: type,
|
||||||
other_options: struct { help: bool },
|
main_options: T,
|
||||||
) !void {
|
) !void {
|
||||||
var cwd = try util.detectJetzigProjectDir();
|
var cwd = try util.detectJetzigProjectDir();
|
||||||
defer cwd.close();
|
defer cwd.close();
|
||||||
@ -65,13 +65,16 @@ pub fn run(
|
|||||||
defer arena_allocator.deinit();
|
defer arena_allocator.deinit();
|
||||||
const arena = arena_allocator.allocator();
|
const arena = arena_allocator.allocator();
|
||||||
|
|
||||||
const generate_type: ?Generator = if (positionals.len > 0) map.get(positionals[0]) else null;
|
const generate_type: ?Generator = if (main_options.positionals.len > 0)
|
||||||
|
map.get(main_options.positionals[0])
|
||||||
|
else
|
||||||
|
null;
|
||||||
|
|
||||||
if (positionals.len > 1) {
|
if (main_options.positionals.len > 1) {
|
||||||
for (positionals[1..]) |arg| try sub_args.append(arg);
|
for (main_options.positionals[1..]) |arg| try sub_args.append(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (other_options.help and generate_type == null) {
|
if (main_options.options.help and generate_type == null) {
|
||||||
try args.printHelp(Options, "jetzig generate", writer);
|
try args.printHelp(Options, "jetzig generate", writer);
|
||||||
return;
|
return;
|
||||||
} else if (generate_type == null) {
|
} else if (generate_type == null) {
|
||||||
@ -81,14 +84,14 @@ pub fn run(
|
|||||||
|
|
||||||
if (generate_type) |capture| {
|
if (generate_type) |capture| {
|
||||||
return switch (capture) {
|
return switch (capture) {
|
||||||
.view => view.run(arena, cwd, sub_args.items, other_options.help),
|
.view => view.run(arena, cwd, sub_args.items, main_options.options.help),
|
||||||
.partial => partial.run(arena, cwd, sub_args.items, other_options.help),
|
.partial => partial.run(arena, cwd, sub_args.items, main_options.options.help),
|
||||||
.layout => layout.run(arena, cwd, sub_args.items, other_options.help),
|
.layout => layout.run(arena, cwd, sub_args.items, main_options.options.help),
|
||||||
.mailer => mailer.run(arena, cwd, sub_args.items, other_options.help),
|
.mailer => mailer.run(arena, cwd, sub_args.items, main_options.options.help),
|
||||||
.job => job.run(arena, cwd, sub_args.items, other_options.help),
|
.job => job.run(arena, cwd, sub_args.items, main_options.options.help),
|
||||||
.middleware => middleware.run(arena, cwd, sub_args.items, other_options.help),
|
.middleware => middleware.run(arena, cwd, sub_args.items, main_options.options.help),
|
||||||
.secret => secret.run(arena, cwd, sub_args.items, other_options.help),
|
.secret => secret.run(arena, cwd, sub_args.items, main_options.options.help),
|
||||||
.migration => migration.run(arena, cwd, sub_args.items, other_options.help),
|
.migration => migration.run(arena, cwd, sub_args.items, main_options.options.help),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const args = @import("args");
|
const args = @import("args");
|
||||||
|
|
||||||
const util = @import("../util.zig");
|
const util = @import("../util.zig");
|
||||||
|
const cli = @import("../cli.zig");
|
||||||
|
|
||||||
const init_data = @import("init_data").init_data;
|
const init_data = @import("init_data").init_data;
|
||||||
|
|
||||||
@ -33,13 +35,13 @@ pub fn run(
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
options: Options,
|
options: Options,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
positionals: [][]const u8,
|
T: type,
|
||||||
other_options: struct { help: bool },
|
main_options: T,
|
||||||
) !void {
|
) !void {
|
||||||
_ = options;
|
_ = options;
|
||||||
var install_path: ?[]const u8 = null;
|
var install_path: ?[]const u8 = null;
|
||||||
|
|
||||||
for (positionals) |arg| {
|
for (main_options.positionals) |arg| {
|
||||||
if (install_path != null) {
|
if (install_path != null) {
|
||||||
std.debug.print("Unexpected positional argument: {s}\n", .{arg});
|
std.debug.print("Unexpected positional argument: {s}\n", .{arg});
|
||||||
return error.JetzigCommandError;
|
return error.JetzigCommandError;
|
||||||
@ -50,7 +52,7 @@ pub fn run(
|
|||||||
const github_url = try util.githubUrl(allocator);
|
const github_url = try util.githubUrl(allocator);
|
||||||
defer allocator.free(github_url);
|
defer allocator.free(github_url);
|
||||||
|
|
||||||
if (other_options.help) {
|
if (main_options.options.help) {
|
||||||
try args.printHelp(Options, "jetzig init", writer);
|
try args.printHelp(Options, "jetzig init", writer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,11 @@ pub fn run(
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
options: Options,
|
options: Options,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
positionals: [][]const u8,
|
T: type,
|
||||||
other_options: struct { help: bool },
|
main_options: T,
|
||||||
) !void {
|
) !void {
|
||||||
_ = positionals;
|
|
||||||
_ = options;
|
_ = options;
|
||||||
if (other_options.help) {
|
if (main_options.options.help) {
|
||||||
try args.printHelp(Options, "jetzig routes", writer);
|
try args.printHelp(Options, "jetzig routes", writer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -34,15 +34,15 @@ pub fn run(
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
options: Options,
|
options: Options,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
positionals: [][]const u8,
|
T: type,
|
||||||
other_options: struct { help: bool },
|
main_options: T,
|
||||||
) !void {
|
) !void {
|
||||||
if (other_options.help) {
|
if (main_options.options.help) {
|
||||||
try args.printHelp(Options, "jetzig server", writer);
|
try args.printHelp(Options, "jetzig server", writer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (positionals.len > 0) {
|
if (main_options.positionals.len > 0) {
|
||||||
std.debug.print("The `server` command does not accept positional arguments.", .{});
|
std.debug.print("The `server` command does not accept positional arguments.", .{});
|
||||||
return error.JetzigCommandError;
|
return error.JetzigCommandError;
|
||||||
}
|
}
|
||||||
@ -66,7 +66,15 @@ pub fn run(
|
|||||||
util.runCommand(
|
util.runCommand(
|
||||||
allocator,
|
allocator,
|
||||||
realpath,
|
realpath,
|
||||||
&[_][]const u8{ "zig", "build", "-Djetzig_runner=true", "install", "--color", "on" },
|
&.{
|
||||||
|
"zig",
|
||||||
|
"build",
|
||||||
|
util.environmentBuildOption(main_options.options.environment),
|
||||||
|
"-Djetzig_runner=true",
|
||||||
|
"install",
|
||||||
|
"--color",
|
||||||
|
"on",
|
||||||
|
},
|
||||||
) catch {
|
) catch {
|
||||||
std.debug.print("Build failed, waiting for file change...\n", .{});
|
std.debug.print("Build failed, waiting for file change...\n", .{});
|
||||||
try awaitFileChange(allocator, cwd, &mtime);
|
try awaitFileChange(allocator, cwd, &mtime);
|
||||||
|
@ -28,16 +28,17 @@ pub fn run(
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
options: Options,
|
options: Options,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
positionals: [][]const u8,
|
T: type,
|
||||||
other_options: struct { help: bool },
|
main_options: T,
|
||||||
) !void {
|
) !void {
|
||||||
_ = options;
|
_ = options;
|
||||||
_ = writer;
|
_ = writer;
|
||||||
_ = positionals;
|
_ = main_options;
|
||||||
_ = other_options;
|
|
||||||
try util.execCommand(allocator, &.{
|
try util.execCommand(allocator, &.{
|
||||||
"zig",
|
"zig",
|
||||||
"build",
|
"build",
|
||||||
|
"-e",
|
||||||
|
"testing",
|
||||||
"jetzig:test",
|
"jetzig:test",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -30,21 +30,24 @@ pub fn run(
|
|||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
options: Options,
|
options: Options,
|
||||||
writer: anytype,
|
writer: anytype,
|
||||||
positionals: [][]const u8,
|
T: type,
|
||||||
other_options: struct { help: bool },
|
main_options: T,
|
||||||
) !void {
|
) !void {
|
||||||
_ = options;
|
_ = options;
|
||||||
if (other_options.help) {
|
if (main_options.options.help) {
|
||||||
try args.printHelp(Options, "jetzig update", writer);
|
try args.printHelp(Options, "jetzig update", writer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (positionals.len > 1) {
|
if (main_options.positionals.len > 1) {
|
||||||
std.debug.print("Expected at most 1 positional argument, found {}\n", .{positionals.len});
|
std.debug.print(
|
||||||
|
"Expected at most 1 positional argument, found {}\n",
|
||||||
|
.{main_options.positionals.len},
|
||||||
|
);
|
||||||
return error.JetzigCommandError;
|
return error.JetzigCommandError;
|
||||||
}
|
}
|
||||||
|
|
||||||
const name = if (positionals.len > 0) positionals[0] else "jetzig";
|
const name = if (main_options.positionals.len > 0) main_options.positionals[0] else "jetzig";
|
||||||
|
|
||||||
const github_url = try util.githubUrl(allocator);
|
const github_url = try util.githubUrl(allocator);
|
||||||
defer allocator.free(github_url);
|
defer allocator.free(github_url);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
|
|
||||||
|
const cli = @import("cli.zig");
|
||||||
|
|
||||||
/// Decode a base64 string, used for parsing out build artifacts generated by the CLI program's
|
/// Decode a base64 string, used for parsing out build artifacts generated by the CLI program's
|
||||||
/// build.zig which are stored in the executable as a module.
|
/// build.zig which are stored in the executable as a module.
|
||||||
pub fn base64Decode(allocator: std.mem.Allocator, input: []const u8) ![]const u8 {
|
pub fn base64Decode(allocator: std.mem.Allocator, input: []const u8) ![]const u8 {
|
||||||
@ -235,3 +237,9 @@ pub fn locateExecutable(
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn environmentBuildOption(environment: cli.Environment) []const u8 {
|
||||||
|
return switch (environment) {
|
||||||
|
inline else => |tag| "-Denvironment=" ++ @tagName(tag),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
85
src/commands/database.zig
Normal file
85
src/commands/database.zig
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const build_options = @import("build_options");
|
||||||
|
|
||||||
|
const jetquery = @import("jetquery");
|
||||||
|
const Migrate = @import("jetquery_migrate").Migrate;
|
||||||
|
const MigrateSchema = @import("jetquery_migrate").MigrateSchema;
|
||||||
|
|
||||||
|
const confirm_drop_env = "JETZIG_DROP_PRODUCTION_DATABASE";
|
||||||
|
const production_drop_failure_message = "To drop a production database, " ++
|
||||||
|
"set `JETZIG_DROP_PRODUCTION_DATABASE={s}`. Exiting.";
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
defer std.debug.assert(gpa.deinit() == .ok);
|
||||||
|
|
||||||
|
const gpa_allocator = gpa.allocator();
|
||||||
|
var arena = std.heap.ArenaAllocator.init(gpa_allocator);
|
||||||
|
defer arena.deinit();
|
||||||
|
|
||||||
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
|
const args = try std.process.argsAlloc(allocator);
|
||||||
|
|
||||||
|
if (args.len < 2) return error.JetzigMissingDatabaseArgument;
|
||||||
|
|
||||||
|
const Action = enum { migrate, rollback, create, drop };
|
||||||
|
const map = std.StaticStringMap(Action).initComptime(.{
|
||||||
|
.{ "migrate", .migrate },
|
||||||
|
.{ "rollback", .rollback },
|
||||||
|
.{ "create", .create },
|
||||||
|
.{ "drop", .drop },
|
||||||
|
});
|
||||||
|
const action = map.get(args[1]) orelse return error.JetzigUnrecognizedDatabaseArgument;
|
||||||
|
|
||||||
|
const environment = build_options.environment;
|
||||||
|
const config = @field(jetquery.config.database, @tagName(environment));
|
||||||
|
|
||||||
|
const Repo = jetquery.Repo(config.adapter, MigrateSchema);
|
||||||
|
var repo = try Repo.loadConfig(
|
||||||
|
allocator,
|
||||||
|
std.enums.nameCast(jetquery.Environment, environment),
|
||||||
|
.{
|
||||||
|
.admin = switch (action) {
|
||||||
|
.migrate, .rollback => false,
|
||||||
|
.create, .drop => true,
|
||||||
|
},
|
||||||
|
.context = .migration,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
defer repo.deinit();
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
.migrate => {
|
||||||
|
try Migrate(config.adapter).init(&repo).migrate();
|
||||||
|
},
|
||||||
|
.rollback => {
|
||||||
|
try Migrate(config.adapter).init(&repo).rollback();
|
||||||
|
},
|
||||||
|
.create => {
|
||||||
|
try repo.createDatabase(config.database, .{});
|
||||||
|
},
|
||||||
|
.drop => {
|
||||||
|
if (environment == .production) {
|
||||||
|
const confirm = std.process.getEnvVarOwned(allocator, confirm_drop_env) catch |err| {
|
||||||
|
switch (err) {
|
||||||
|
error.EnvironmentVariableNotFound => {
|
||||||
|
std.log.err(production_drop_failure_message, .{config.database});
|
||||||
|
std.process.exit(1);
|
||||||
|
},
|
||||||
|
else => return err,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (std.mem.eql(u8, confirm, config.database)) {
|
||||||
|
try repo.dropDatabase(config.database, .{});
|
||||||
|
} else {
|
||||||
|
std.log.err(production_drop_failure_message, .{config.database});
|
||||||
|
std.process.exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try repo.dropDatabase(config.database, .{});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
@ -1,25 +0,0 @@
|
|||||||
const std = @import("std");
|
|
||||||
|
|
||||||
const jetquery = @import("jetquery");
|
|
||||||
const Migrate = @import("jetquery_migrate").Migrate;
|
|
||||||
const MigrateSchema = @import("jetquery_migrate").MigrateSchema;
|
|
||||||
|
|
||||||
pub fn main() !void {
|
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
|
||||||
defer std.debug.assert(gpa.deinit() == .ok);
|
|
||||||
|
|
||||||
const gpa_allocator = gpa.allocator();
|
|
||||||
var arena = std.heap.ArenaAllocator.init(gpa_allocator);
|
|
||||||
defer arena.deinit();
|
|
||||||
|
|
||||||
const allocator = arena.allocator();
|
|
||||||
|
|
||||||
var repo = try jetquery.Repo(
|
|
||||||
jetquery.config.database.adapter,
|
|
||||||
MigrateSchema,
|
|
||||||
).loadConfig(allocator, .{});
|
|
||||||
defer repo.deinit();
|
|
||||||
|
|
||||||
const migrate = Migrate(jetquery.config.database.adapter).init(&repo);
|
|
||||||
try migrate.run();
|
|
||||||
}
|
|
@ -26,7 +26,7 @@ pub const DateTime = jetcommon.types.DateTime;
|
|||||||
pub const Time = jetcommon.types.Time;
|
pub const Time = jetcommon.types.Time;
|
||||||
pub const Date = jetcommon.types.Date;
|
pub const Date = jetcommon.types.Date;
|
||||||
|
|
||||||
pub const environment = @import("build_config").environment;
|
pub const environment = @import("build_options").environment;
|
||||||
|
|
||||||
/// The primary interface for a Jetzig application. Create an `App` in your application's
|
/// The primary interface for a Jetzig application. Create an `App` in your application's
|
||||||
/// `src/main.zig` and call `start` to launch the application.
|
/// `src/main.zig` and call `start` to launch the application.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user