Compare commits
2 Commits
dd32db056e
...
b4f82ebfda
| Author | SHA1 | Date | |
|---|---|---|---|
| b4f82ebfda | |||
| 21a4c231a3 |
56
build.zig
56
build.zig
@@ -1,11 +1,16 @@
|
||||
const std = @import("std");
|
||||
|
||||
// TODO TODO
|
||||
// Must match the version in build.zig.zon
|
||||
const totp_version: std.SemanticVersion = .{ .major = 0, .minor = 1, .patch = 0, .pre = "dev" };
|
||||
|
||||
// Although this function looks imperative, note that its job is to
|
||||
// declaratively construct a build graph that will be executed by an external
|
||||
// runner.
|
||||
pub fn build(b: *std.Build) void {
|
||||
const version = getVersion(b);
|
||||
const options = b.addOptions();
|
||||
options.addOption(std.SemanticVersion, "version", version);
|
||||
|
||||
// Standard target options allows the person running `zig build` to choose
|
||||
// what target to build for. Here we do not override the defaults, which
|
||||
// means any target is allowed, and the default is native. Other options
|
||||
@@ -37,6 +42,7 @@ pub fn build(b: *std.Build) void {
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe.root_module.addOptions("config", options);
|
||||
|
||||
// This declares intent for the executable to be installed into the
|
||||
// standard location when the user invokes the "install" step (the default
|
||||
@@ -91,3 +97,51 @@ pub fn build(b: *std.Build) void {
|
||||
test_step.dependOn(&run_lib_unit_tests.step);
|
||||
test_step.dependOn(&run_exe_unit_tests.step);
|
||||
}
|
||||
|
||||
fn getVersion(b: *std.Build) std.SemanticVersion {
|
||||
// if this is a release version , aka this is not a pre-release or build version,
|
||||
// then use the specified version
|
||||
if (totp_version.pre == null and totp_version.build == null) return totp_version;
|
||||
|
||||
// for pre-release version we use the git version
|
||||
const args: []const []const u8 = &.{ "git", "-C", b.pathFromRoot("."), "describe", "--match", "*.*.*", "--tags" };
|
||||
var out_code: u8 = undefined;
|
||||
const output_untrimmed = b.runAllowFail(args, &out_code, .Ignore) catch |err| {
|
||||
std.log.warn(
|
||||
\\ failed to run git describe: {}
|
||||
, .{err});
|
||||
return totp_version;
|
||||
};
|
||||
|
||||
const output_trimmed = std.mem.trim(u8, output_untrimmed, " \r\n");
|
||||
switch (std.mem.count(u8, output_trimmed, "-")) {
|
||||
0 => {
|
||||
// release version, e.g. 1.0.0
|
||||
if (!std.mem.eql(u8, output_trimmed, b.fmt("{}", .{totp_version}))) {
|
||||
std.debug.panic("the version in build.zig and build.zig.zon must match the tag in git", .{});
|
||||
}
|
||||
return totp_version;
|
||||
},
|
||||
2 => {
|
||||
// development version, e.g. 1.0.0-7-64es356
|
||||
var iter = std.mem.splitScalar(u8, output_trimmed, '-');
|
||||
const tag = iter.first();
|
||||
const commits_since_tag = iter.next().?;
|
||||
const commit_hash = iter.next().?;
|
||||
|
||||
const v: std.SemanticVersion = std.SemanticVersion.parse(tag) catch unreachable;
|
||||
|
||||
return .{
|
||||
.major = v.major,
|
||||
.minor = v.minor,
|
||||
.patch = v.patch,
|
||||
.pre = b.fmt("dev.{s}", .{commits_since_tag}),
|
||||
.build = commit_hash[1..],
|
||||
};
|
||||
},
|
||||
else => {
|
||||
std.debug.print("unexpected output of git describe: '{s}'\n", .{output_untrimmed});
|
||||
std.process.exit(1);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
.name = "zig-totp",
|
||||
// This is a [Semantic Version](https://semver.org/).
|
||||
// In a future version of Zig it will be used for package deduplication.
|
||||
.version = "0.0.0",
|
||||
.version = "0.1.0-dev",
|
||||
|
||||
// This field is optional.
|
||||
// This is currently advisory only; Zig does not yet do anything
|
||||
|
||||
15
src/main.zig
15
src/main.zig
@@ -10,6 +10,7 @@ const expect = testing.expect;
|
||||
const ArrayList = std.ArrayList;
|
||||
const Base32 = @import("base32.zig").Base32;
|
||||
const Base32Error = @import("base32.zig").Base32Error;
|
||||
const options = @import("config");
|
||||
|
||||
// otpauth://totp/AWS+Dev?secret=47STA47VFCMMLLWOLHWO3KY7MYNC36MLCDTHOLIYKJCTTSSAMKVM7YA3VWT2AJEP&digits=6&icon=Amazon
|
||||
// otpauth://totp/Gitea%20%28git.lucares.de%29:andi?algorithm=SHA1&digits=6&issuer=Gitea&period=30&secret=MSP53Q672UJMSCLQVRCJKMMZKK7MWSMYFL77OQ24JBM65RZWY7F2Y45FMTNLYM36
|
||||
@@ -49,7 +50,9 @@ fn mainInternal() !void {
|
||||
|
||||
const arg: Args = try parseArgs(allocator, args);
|
||||
//print("parsed Args: {?any}\n", arg);
|
||||
if (arg.list) {
|
||||
if (arg.print_version) {
|
||||
try std.io.getStdOut().writer().print("{}", .{options.version});
|
||||
} else if (arg.list) {
|
||||
const names = try executeGetList(allocator, arg.config_location);
|
||||
|
||||
for (0..names.items.len) |i| {
|
||||
@@ -85,12 +88,14 @@ fn printHelp() void {
|
||||
\\ eval "$(zig-totp --bash)"
|
||||
\\ to your ~/.bashrc
|
||||
\\ --config [path] The path to a config file (default is $XDG_CONFIG_HOME/zig-totp or $HOME/.zig-totp).
|
||||
\\ --help Show this help
|
||||
\\ --version Print the version number
|
||||
\\
|
||||
;
|
||||
std.debug.print("{s}", .{msg});
|
||||
}
|
||||
|
||||
const Args = struct { list: bool, show: ?[]const u8, config_location: []const u8, validateAuthenticator: ?[]const u8, validateCode: ?[]const u8 };
|
||||
const Args = struct { list: bool, show: ?[]const u8, config_location: []const u8, validateAuthenticator: ?[]const u8, validateCode: ?[]const u8, print_version: bool, show_help: bool };
|
||||
|
||||
const OtpAuthUrl = struct { name: []const u8, secretEncoded: []const u8, url: []const u8, period: u32, digits: u4, algorithm: []const u8 };
|
||||
|
||||
@@ -186,7 +191,7 @@ fn zeroPad(allocator: Allocator, digits: u4, x: anytype) ![]u8 {
|
||||
const ArgumentError = error{ InvalidOtpAuthUrl, UnknownParameter, MissingConfigLocation, AuthenticatorNotFound, MissingAuthenticatorParam, FailedToOpenConfigFile, TooManyParsinErrors };
|
||||
|
||||
fn parseArgs(allocator: Allocator, args: []const []const u8) !Args {
|
||||
var result = Args{ .list = false, .show = null, .config_location = try configLocation(allocator), .validateAuthenticator = null, .validateCode = null };
|
||||
var result = Args{ .list = false, .show = null, .config_location = try configLocation(allocator), .validateAuthenticator = null, .validateCode = null, .print_version = false, .show_help = false };
|
||||
var i: u17 = 1;
|
||||
while (i < args.len) : (i += 1) {
|
||||
const arg = args[i];
|
||||
@@ -220,6 +225,10 @@ fn parseArgs(allocator: Allocator, args: []const []const u8) !Args {
|
||||
return error.MissingConfigLocation;
|
||||
}
|
||||
result.config_location = args[i];
|
||||
} else if (eql(u8, "--help", arg) or eql(u8, "help", arg)) {
|
||||
result.show_help = true;
|
||||
} else if (eql(u8, "--version", arg)) {
|
||||
result.print_version = true;
|
||||
} else if (eql(u8, "list", arg)) {
|
||||
result.list = true;
|
||||
} else if (eql(u8, "show", arg)) {
|
||||
|
||||
Reference in New Issue
Block a user