mirror of
https://github.com/daylinmorgan/oizys.git
synced 2024-12-27 14:10:45 -06:00
Compare commits
4 commits
8f51affe7c
...
887fe2f49d
Author | SHA1 | Date | |
---|---|---|---|
887fe2f49d | |||
5e4629c1e0 | |||
f930a245e3 | |||
689c594493 |
5 changed files with 136 additions and 43 deletions
|
@ -11,10 +11,19 @@ var dryCmd = &cobra.Command{
|
||||||
Short: "poor man's nix flake check",
|
Short: "poor man's nix flake check",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
oizys.CheckFlake(flake)
|
oizys.CheckFlake(flake)
|
||||||
oizys.NixDryRun(flake, host)
|
oizys.NixDryRun(flake, host, verbose)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var verbose bool
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(dryCmd)
|
rootCmd.AddCommand(dryCmd)
|
||||||
|
dryCmd.Flags().BoolVarP(
|
||||||
|
&verbose,
|
||||||
|
"verbose",
|
||||||
|
"v",
|
||||||
|
false,
|
||||||
|
"show verbose output",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,12 @@ func TerminalSize() (int, int) {
|
||||||
return w, h
|
return w, h
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseDryRunOutput(nixOutput string) {
|
func ParseDryRunOutput(nixOutput string, verbose bool) {
|
||||||
output := termenv.NewOutput(os.Stdout)
|
output := termenv.NewOutput(os.Stdout)
|
||||||
parts := strings.Split(nixOutput, "\nthese")
|
parts := strings.Split(nixOutput, "\nthese")
|
||||||
if len(parts) != 3 {
|
if len(parts) != 3 {
|
||||||
log.Println("no changes...")
|
log.Println("no changes...")
|
||||||
|
log.Println(output)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
built := strings.Split(strings.TrimSpace(parts[1]), "\n")[1:]
|
built := strings.Split(strings.TrimSpace(parts[1]), "\n")[1:]
|
||||||
|
@ -58,15 +59,18 @@ func ParseDryRunOutput(nixOutput string) {
|
||||||
rows = append(rows, table.Row{hash, name})
|
rows = append(rows, table.Row{hash, name})
|
||||||
}
|
}
|
||||||
|
|
||||||
w, _ := TerminalSize()
|
if verbose {
|
||||||
columns := []table.Column{
|
|
||||||
{Title: "hash", Width: 34},
|
w, _ := TerminalSize()
|
||||||
{Title: "pkg", Width: int(w / 4)},
|
columns := []table.Column{
|
||||||
|
{Title: "hash", Width: 34},
|
||||||
|
{Title: "pkg", Width: int(w / 4)},
|
||||||
|
}
|
||||||
|
ShowTable(columns, rows)
|
||||||
}
|
}
|
||||||
ShowTable(columns, rows)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NixDryRun(flake string, host string) {
|
func NixDryRun(flake string, host string, verbose bool) {
|
||||||
output := termenv.NewOutput(os.Stdout)
|
output := termenv.NewOutput(os.Stdout)
|
||||||
path := Output(flake, host)
|
path := Output(flake, host)
|
||||||
cmd := exec.Command("nix", "build", path, "--dry-run")
|
cmd := exec.Command("nix", "build", path, "--dry-run")
|
||||||
|
@ -85,7 +89,7 @@ func NixDryRun(flake string, host string) {
|
||||||
fmt.Println(string(result))
|
fmt.Println(string(result))
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
ParseDryRunOutput(string(result))
|
ParseDryRunOutput(string(result), verbose)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NixosRebuild(subcmd string, flake string, rest ...string) {
|
func NixosRebuild(subcmd string, flake string, rest ...string) {
|
||||||
|
|
|
@ -34,7 +34,6 @@ pub fn init(allocator: Allocator) !Cli {
|
||||||
try subcmd.addArg(Arg.positional("forward", null, null));
|
try subcmd.addArg(Arg.positional("forward", null, null));
|
||||||
try subcmd.addArg(Arg.singleValueOption("flake", 'f', "path to flake"));
|
try subcmd.addArg(Arg.singleValueOption("flake", 'f', "path to flake"));
|
||||||
try subcmd.addArg(Arg.singleValueOption("host", null, "hostname (default: current host)"));
|
try subcmd.addArg(Arg.singleValueOption("host", null, "hostname (default: current host)"));
|
||||||
try subcmd.addArg(Arg.booleanOption("no-pinix", null, "don't use pinix"));
|
|
||||||
try oizys.addSubcommand(subcmd.*);
|
try oizys.addSubcommand(subcmd.*);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ host: []const u8,
|
||||||
cache_name: []const u8,
|
cache_name: []const u8,
|
||||||
output: []const u8,
|
output: []const u8,
|
||||||
cmd: OizysCmd,
|
cmd: OizysCmd,
|
||||||
no_pinix: bool,
|
|
||||||
debug: bool = false,
|
debug: bool = false,
|
||||||
forward: ?[][]const u8,
|
forward: ?[][]const u8,
|
||||||
|
|
||||||
|
@ -25,39 +24,52 @@ pub const OizysCmd = enum {
|
||||||
pub fn init(allocator: std.mem.Allocator, matches: *const ArgMatches, forward: ?[][]const u8) !Oizys {
|
pub fn init(allocator: std.mem.Allocator, matches: *const ArgMatches, forward: ?[][]const u8) !Oizys {
|
||||||
const cmd = matches.subcommand.?.name;
|
const cmd = matches.subcommand.?.name;
|
||||||
const flags = matches.subcommandMatches(cmd).?;
|
const flags = matches.subcommandMatches(cmd).?;
|
||||||
const host = flags.getSingleValue("host") orelse
|
var oizys = Oizys{
|
||||||
try Oizys.getDefaultHostName(allocator);
|
|
||||||
const flake = flags.getSingleValue("flake") orelse
|
|
||||||
try Oizys.getDefaultFlake(allocator);
|
|
||||||
|
|
||||||
return Oizys{
|
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.host = host,
|
.host = undefined,
|
||||||
.flake = flake,
|
.flake = undefined,
|
||||||
.output = try std.fmt.allocPrint(
|
.output = undefined,
|
||||||
allocator,
|
|
||||||
"{s}#nixosConfigurations.{s}.config.system.build.toplevel",
|
|
||||||
.{ flake, host },
|
|
||||||
),
|
|
||||||
.cmd = std.meta.stringToEnum(OizysCmd, cmd).?,
|
.cmd = std.meta.stringToEnum(OizysCmd, cmd).?,
|
||||||
.cache_name = flags.getSingleValue("cache") orelse "daylin",
|
.cache_name = flags.getSingleValue("cache") orelse "daylin",
|
||||||
.no_pinix = flags.containsArg("no-pinix"),
|
|
||||||
.forward = forward,
|
.forward = forward,
|
||||||
};
|
};
|
||||||
|
if (flags.getSingleValue("host")) |host| {
|
||||||
|
oizys.host = try allocator.dupe(u8, host);
|
||||||
|
} else {
|
||||||
|
oizys.host = try Oizys.getDefaultHostName(allocator);
|
||||||
|
}
|
||||||
|
if (flags.getSingleValue("flake")) |flake| {
|
||||||
|
oizys.flake = try allocator.dupe(u8, flake);
|
||||||
|
} else {
|
||||||
|
oizys.flake = try Oizys.getDefaultFlake(allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
oizys.output = try std.fmt.allocPrint(
|
||||||
|
allocator,
|
||||||
|
"{s}#nixosConfigurations.{s}.config.system.build.toplevel",
|
||||||
|
.{ oizys.flake, oizys.host },
|
||||||
|
);
|
||||||
|
|
||||||
|
return oizys;
|
||||||
|
// return Oizys{
|
||||||
|
// .allocator = allocator,
|
||||||
|
// .host = host,
|
||||||
|
// .flake = flake,
|
||||||
|
// .output = try std.fmt.allocPrint(
|
||||||
|
// allocator,
|
||||||
|
// "{s}#nixosConfigurations.{s}.config.system.build.toplevel",
|
||||||
|
// .{ flake, host },
|
||||||
|
// ),
|
||||||
|
// .cmd = std.meta.stringToEnum(OizysCmd, cmd).?,
|
||||||
|
// .cache_name = flags.getSingleValue("cache") orelse "daylin",
|
||||||
|
// .forward = forward,
|
||||||
|
// };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Oizys) void {
|
pub fn deinit(self: *Oizys) void {
|
||||||
self.allocator.free(self.flake);
|
self.allocator.free(self.flake);
|
||||||
self.allocator.free(self.host);
|
|
||||||
self.allocator.free(self.output);
|
self.allocator.free(self.output);
|
||||||
}
|
self.allocator.free(self.host);
|
||||||
|
|
||||||
pub fn nix(self: *Oizys) []const u8 {
|
|
||||||
return if (self.no_pinix) "nix" else "pix";
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nixos_rebuild(self: *Oizys) []const u8 {
|
|
||||||
return if (self.no_pinix) "nixos-rebuild" else "pixos-rebuild";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getDefaultHostName(allocator: Allocator) ![]const u8 {
|
pub fn getDefaultHostName(allocator: Allocator) ![]const u8 {
|
||||||
|
@ -89,8 +101,8 @@ pub fn runNixCmd(self: *Oizys, cmd: NixCmd, argv: []const []const u8) !void {
|
||||||
defer args.deinit();
|
defer args.deinit();
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
NixCmd.Nix => try args.append(self.nix()),
|
NixCmd.Nix => try args.append("nix"),
|
||||||
NixCmd.NixosRebuild => try args.appendSlice(&.{ "sudo", self.nixos_rebuild() }),
|
NixCmd.NixosRebuild => try args.appendSlice(&.{ "sudo", "nixos-rebuild" }),
|
||||||
}
|
}
|
||||||
try args.appendSlice(argv);
|
try args.appendSlice(argv);
|
||||||
if (self.forward) |fwd| try args.appendSlice(fwd);
|
if (self.forward) |fwd| try args.appendSlice(fwd);
|
||||||
|
@ -117,12 +129,77 @@ pub fn cache(self: *Oizys) !void {
|
||||||
_ = try p.spawnAndWait();
|
_ = try p.spawnAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DryResult = struct {
|
||||||
|
allocator: Allocator,
|
||||||
|
fetch: [][]const u8,
|
||||||
|
build: [][]const u8,
|
||||||
|
|
||||||
|
pub fn parse(allocator: Allocator, output: []const u8) !DryResult {
|
||||||
|
var it = std.mem.splitSequence(u8, output, ":\n");
|
||||||
|
_ = it.next();
|
||||||
|
var fetch = std.ArrayList([]const u8).init(allocator);
|
||||||
|
var build = std.ArrayList([]const u8).init(allocator);
|
||||||
|
|
||||||
|
if (it.next()) |x| {
|
||||||
|
try parseLines(x, &fetch);
|
||||||
|
} else {
|
||||||
|
return error.DryParseError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (it.next()) |x| {
|
||||||
|
try parseLines(x, &build);
|
||||||
|
} else {
|
||||||
|
return error.DryParseError;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.fetch = try fetch.toOwnedSlice(),
|
||||||
|
.build = try build.toOwnedSlice(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *DryResult) void {
|
||||||
|
self.allocator.free(self.fetch);
|
||||||
|
self.allocator.free(self.build);
|
||||||
|
// for (self.fetch) |item| {
|
||||||
|
// self.allocator.free(item);
|
||||||
|
// }
|
||||||
|
// for (self.build) |item| {
|
||||||
|
// self.allocator.free(item);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
fn parseLines(buffer: []const u8, list: *std.ArrayList([]const u8)) !void {
|
||||||
|
var lines = std.mem.splitSequence(u8, buffer, "\n");
|
||||||
|
while (lines.next()) |line| {
|
||||||
|
try list.append(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn dry(self: *Oizys) !void {
|
||||||
|
const cmd_output = try std.ChildProcess.run(.{
|
||||||
|
.allocator = self.allocator,
|
||||||
|
.argv = &.{ "nix", "build", self.output, "--dry-run" },
|
||||||
|
});
|
||||||
|
defer self.allocator.free(cmd_output.stdout);
|
||||||
|
defer self.allocator.free(cmd_output.stderr);
|
||||||
|
var result = try DryResult.parse(self.allocator, cmd_output.stderr);
|
||||||
|
defer result.deinit();
|
||||||
|
|
||||||
|
std.debug.print(
|
||||||
|
"to fetch: {d}\nto build: {d}\n",
|
||||||
|
.{ result.fetch.len, result.build.len },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run(self: *Oizys) !void {
|
pub fn run(self: *Oizys) !void {
|
||||||
switch (self.cmd) {
|
switch (self.cmd) {
|
||||||
.@"switch" => try self.runNixCmd(NixCmd.NixosRebuild, &.{ "switch", "--flake", self.flake }),
|
.@"switch" => try self.runNixCmd(.NixosRebuild, &.{ "switch", "--flake", self.flake }),
|
||||||
.boot => try self.runNixCmd(NixCmd.NixosRebuild, &.{ "boot", "--flake", self.flake }),
|
|
||||||
.dry => try self.runNixCmd(NixCmd.Nix, &.{ "build", self.output, "--dry-run" }),
|
.boot => try self.runNixCmd(.NixosRebuild, &.{ "boot", "--flake", self.flake }),
|
||||||
.build => try self.runNixCmd(NixCmd.Nix, &.{ "build", self.output }),
|
.dry => try self.dry(),
|
||||||
|
.build => try self.runNixCmd(.Nix, &.{ "build", self.output }),
|
||||||
.output => {
|
.output => {
|
||||||
const stdout = std.io.getStdOut().writer();
|
const stdout = std.io.getStdOut().writer();
|
||||||
try stdout.print("{s}\n", .{self.output});
|
try stdout.print("{s}\n", .{self.output});
|
||||||
|
|
|
@ -4,9 +4,13 @@ const Cli = @import("Cli.zig");
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
// memory management isn't hard :P
|
// memory management isn't hard :P
|
||||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
// var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
defer arena.deinit();
|
// defer arena.deinit();
|
||||||
const allocator = arena.allocator();
|
// const allocator = arena.allocator();
|
||||||
|
//
|
||||||
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
|
const allocator = gpa.allocator();
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
|
||||||
var cli = try Cli.init(allocator);
|
var cli = try Cli.init(allocator);
|
||||||
try cli.parse();
|
try cli.parse();
|
||||||
|
|
Loading…
Reference in a new issue