mirror of
https://github.com/sbrow/envr.git
synced 2026-06-27 10:38:33 -04:00
feat(comma): Added help method.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
//! By convention, root.zig is the root source file when making a package.
|
||||
const std = @import("std");
|
||||
// const Io = std.Io;
|
||||
const Io = std.Io;
|
||||
|
||||
pub const Command = struct {
|
||||
name: []const u8,
|
||||
@@ -8,7 +8,10 @@ pub const Command = struct {
|
||||
long: ?[]const u8 = null,
|
||||
subcommands: []const Command = &.{},
|
||||
examples: [][]const u8 = &.{},
|
||||
/// The enum type of the command
|
||||
Type: type,
|
||||
/// The type of struct that holds the Commands's flags and arguments
|
||||
// Params: type,
|
||||
|
||||
pub fn new(cmd: CommandOptions) Command {
|
||||
const subcommands: [cmd.subcommands.len]Command = blk: {
|
||||
@@ -43,6 +46,65 @@ pub const Command = struct {
|
||||
|
||||
return @enumFromInt(self.subcommands.len + 1);
|
||||
}
|
||||
|
||||
/// Used for indentation when printing command help
|
||||
const tab = " ";
|
||||
|
||||
/// Print usage information to the console.
|
||||
pub fn help(self: @This(), w: *Io.Writer) !void {
|
||||
defer w.flush() catch {};
|
||||
|
||||
if (self.long) |long| {
|
||||
try w.print("{s}\n\n", .{long});
|
||||
}
|
||||
|
||||
try w.print("Usage:\n{s}{s}\n", .{ tab, self.name });
|
||||
|
||||
if (self.subcommands.len > 0) {
|
||||
try w.print("\nAvailable Commands:\n", .{});
|
||||
|
||||
var max_width: u8 = 0;
|
||||
|
||||
inline for (self.subcommands) |cmd| {
|
||||
max_width = @max(max_width, cmd.name.len);
|
||||
}
|
||||
|
||||
// Print short command description
|
||||
inline for (self.subcommands) |cmd| {
|
||||
try w.print(
|
||||
"{s}{s}",
|
||||
.{
|
||||
tab,
|
||||
cmd.name,
|
||||
},
|
||||
);
|
||||
|
||||
for (0..(max_width - cmd.name.len)) |_| {
|
||||
try w.print(" ", .{});
|
||||
}
|
||||
|
||||
try w.print(
|
||||
" {s}\n",
|
||||
.{
|
||||
cmd.short orelse "",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
try w.print("\n", .{});
|
||||
}
|
||||
|
||||
// TODO: Print flags
|
||||
|
||||
// TODO: Print arguments
|
||||
|
||||
if (self.subcommands.len > 0) {
|
||||
try w.print(
|
||||
"Use \"{s} [command] --help\" for more information about a command.",
|
||||
.{self.name},
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const ParseError = error{
|
||||
@@ -78,3 +140,7 @@ const CommandOptions = struct {
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// /// parses the args into params
|
||||
// pub fn params(cmd: Command, args: [][]const u8) cmd.Params {
|
||||
// }
|
||||
|
||||
11
src/main.zig
11
src/main.zig
@@ -26,8 +26,12 @@ fn run(
|
||||
) !void {
|
||||
const cmd = envr.root.parse(args[1..]);
|
||||
switch (cmd) {
|
||||
.envr, .unknown => {
|
||||
return fallback_to_go(io, arena, args);
|
||||
.envr => {
|
||||
var stdout_buffer: [4096]u8 = undefined;
|
||||
var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer);
|
||||
const stdout_writer = &stdout_file_writer.interface;
|
||||
|
||||
return envr.root.help(stdout_writer);
|
||||
},
|
||||
.version => {
|
||||
var stdout_buffer: [1024]u8 = undefined;
|
||||
@@ -47,6 +51,9 @@ fn run(
|
||||
environ_map.get("PATH").?,
|
||||
);
|
||||
},
|
||||
.unknown => {
|
||||
return fallback_to_go(io, arena, args);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
39
src/root.zig
39
src/root.zig
@@ -7,6 +7,38 @@ const Command = comma.Command;
|
||||
|
||||
pub const root: Command = .new(.{
|
||||
.name = "envr",
|
||||
.short = "Manage your .env files.",
|
||||
.long =
|
||||
\\envr keeps your .env synced to a local, age encrypted database.
|
||||
\\It is a safe and eay way to gather all your .env files in one place where they can
|
||||
\\easily be backed by another tool such as restic or git.
|
||||
\\All your data is stored in ~/data.age
|
||||
\\
|
||||
\\Getting started is easy:
|
||||
\\
|
||||
\\1. Create your configuration file and set up encrypted storage:
|
||||
\\
|
||||
\\> envr init
|
||||
\\
|
||||
\\2. Scan for existing .env files:
|
||||
\\
|
||||
\\> envr scan
|
||||
\\
|
||||
\\Select the files you want to back up from the interactive list.
|
||||
\\
|
||||
\\3. Verify that it worked:
|
||||
\\
|
||||
\\> envr list
|
||||
\\
|
||||
\\4. After changing any of your .env files, update the backup with:
|
||||
\\
|
||||
\\> envr sync
|
||||
\\
|
||||
\\5. If you lose a repository, after re-cloning the repo into the same path it was
|
||||
\\at before, restore your backup with:
|
||||
\\
|
||||
\\> envr restore <path to repository> .env
|
||||
,
|
||||
.subcommands = &.{
|
||||
.{
|
||||
.name = "deps",
|
||||
@@ -17,7 +49,10 @@ pub const root: Command = .new(.{
|
||||
\\ The deps command reports which binaries are available and which are not."
|
||||
,
|
||||
},
|
||||
.{ .name = "version" },
|
||||
.{
|
||||
.name = "version",
|
||||
.short = "Show envr's version",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -35,7 +70,7 @@ test "parse version" {
|
||||
}
|
||||
|
||||
test "parse unknown" {
|
||||
const args = &[_][]const u8{"bad", "value"};
|
||||
const args = &[_][]const u8{ "bad", "value" };
|
||||
const cmd = root.parse(args);
|
||||
|
||||
try std.testing.expectEqual(.unknown, cmd);
|
||||
|
||||
Reference in New Issue
Block a user