Skip to content

Commit

Permalink
rebase
Browse files Browse the repository at this point in the history
  • Loading branch information
ToyVo committed Feb 13, 2025
1 parent 8ef70b6 commit 7d8977d
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 3 deletions.
101 changes: 101 additions & 0 deletions darwin-module.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
self:{ config
, lib
, pkgs
, ...
}:
let
cfg = config.programs.nh;
in
{
meta.maintainers = [ lib.maintainers.ToyVo ];

options.programs.nh = {
enable = lib.mkEnableOption "nh, yet another Nix CLI helper";

package = lib.mkPackageOption pkgs "nh" { } // {
default = self.packages.${pkgs.stdenv.hostPlatform.system}.default;
};

flake = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
The path that will be used for the `NH_FLAKE` environment variable.
`NH_FLAKE` is used by nh as the default flake for performing actions, like `nh os switch`.
'';
};

clean = {
enable = lib.mkEnableOption "periodic garbage collection with nh clean all";

# Not in NixOS module
user = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "User that runs the garbage collector.";
};

interval = lib.mkOption {
type = lib.types.attrs;
default = { Weekday = 0; };
description = ''
How often cleanup is performed. Passed to launchd.StartCalendarInterval
The format is described in
{manpage}`crontab(5)`.
'';
};

extraArgs = lib.mkOption {
type = lib.types.singleLineStr;
default = "";
example = "--keep 5 --keep-since 3d";
description = ''
Options given to nh clean when the service is run automatically.
See `nh clean all --help` for more information.
'';
};
};
};

config = {
warnings =
if (!(cfg.clean.enable -> !config.nix.gc.automatic)) then [
"programs.nh.clean.enable and nix.gc.automatic are both enabled. Please use one or the other to avoid conflict."
] else [ ];

assertions = [
# Not strictly required but probably a good assertion to have
{
assertion = cfg.clean.enable -> cfg.enable;
message = "programs.nh.clean.enable requires programs.nh.enable";
}

{
assertion = (cfg.flake != null) -> !(lib.hasSuffix ".nix" cfg.flake);
message = "nh.flake must be a directory, not a nix file";
}
];

nixpkgs.overlays = [ self.overlays.default ];

environment = lib.mkIf cfg.enable {
systemPackages = [ cfg.package ];
variables = lib.mkIf (cfg.flake != null) {
NH_FLAKE = cfg.flake;
};
};

launchd = lib.mkIf cfg.clean.enable {
daemons.nh-clean = {
command = "exec ${lib.getExe cfg.package} clean all ${cfg.clean.extraArgs}";
environment.NIX_REMOTE = lib.optionalString config.nix.useDaemon "daemon";
serviceConfig.RunAtLoad = false;
serviceConfig.StartCalendarInterval = [ cfg.clean.interval ];
serviceConfig.UserName = cfg.clean.user;
};
};
};
}
9 changes: 9 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,14 @@
});

formatter = forAllSystems (pkgs: pkgs.nixfmt-rfc-style);
nixosModules.default = import ./module.nix self;
# use this module before this pr is merged https://github.com/LnL7/nix-darwin/pull/942
nixDarwinModules.prebuiltin = import ./darwin-module.nix self;
# use this module after that pr is merged
nixDarwinModules.default = import ./module.nix self;
# use this module before this pr is merged https://github.com/nix-community/home-manager/pull/5304
homeManagerModules.prebuiltin = import ./home-manager-module.nix self;
# use this module after that pr is merged
homeManagerModules.default = import ./module.nix self;
};
}
39 changes: 39 additions & 0 deletions home-manager-module.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Notice: this file will only exist until this pr is merged https://github.com/nix-community/home-manager/pull/5304
self: { config, lib, pkgs, ... }:

let
cfg = config.programs.nh;
in
{
meta.maintainers = with lib.maintainers; [ johnrtitor ];

options.programs.nh = {
enable = lib.mkEnableOption "nh, yet another Nix CLI helper";

package = lib.mkPackageOption pkgs "nh" { } // {
default = self.packages.${pkgs.stdenv.hostPlatform.system}.default;
};

flake = lib.mkOption {
type = lib.types.nullOr lib.types.path;
default = null;
description = ''
The path that will be used for the `NH_FLAKE` environment variable.
`NH_FLAKE` is used by nh as the default flake for performing actions, like `nh os switch`.
'';
};
};

config = {
assertions = [{
assertion = (cfg.flake != null) -> !(lib.hasSuffix ".nix" cfg.flake);
message = "nh.flake must be a directory, not a nix file";
}];

home = lib.mkIf cfg.enable {
packages = [ cfg.package ];
sessionVariables = lib.mkIf (cfg.flake != null) { NH_FLAKE = cfg.flake; };
};
};
}
7 changes: 7 additions & 0 deletions module.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
self: { config, pkgs, lib, ... }:
{
config = {
nixpkgs.overlays = [ self.overlays.default ];
programs.nh.package = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.default;
};
}
20 changes: 19 additions & 1 deletion src/darwin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::commands::Command;
use crate::installable::Installable;
use crate::interface::{DarwinArgs, DarwinRebuildArgs, DarwinReplArgs, DarwinSubcommand};
use crate::nixos::toplevel_for;
use crate::update::update;
use crate::update::{pull, update};
use crate::Result;

const SYSTEM_PROFILE: &str = "/nix/var/nix/profiles/system";
Expand Down Expand Up @@ -72,6 +72,14 @@ impl DarwinRebuildArgs {
bail!("Don't run nh os as root. I will call sudo internally as needed");
}

if self.common.pull {
pull(
&self.common.installable,
self.update_args.update,
self.common.dry,
)?;
}

if self.update_args.update {
update(&self.common.installable, self.update_args.update_input)?;
}
Expand Down Expand Up @@ -102,6 +110,16 @@ impl DarwinRebuildArgs {

let toplevel = toplevel_for(hostname, installable);

if self.common.pull {
if let Installable::Flake { reference, .. } = &self.common.installable {
commands::Command::new("git")
.args(["-C", reference, "pull"])
.dry(self.common.dry)
.message("Pulling Flake")
.run()?;
}
}

commands::Build::new(toplevel)
.extra_arg("--out-link")
.extra_arg(out_path.get_path())
Expand Down
10 changes: 9 additions & 1 deletion src/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::commands;
use crate::commands::Command;
use crate::installable::Installable;
use crate::interface::{self, HomeRebuildArgs, HomeReplArgs, HomeSubcommand};
use crate::update::update;
use crate::update::{pull, update};

impl interface::HomeArgs {
pub fn run(self) -> Result<()> {
Expand Down Expand Up @@ -37,6 +37,14 @@ impl HomeRebuildArgs {
fn rebuild(self, variant: HomeRebuildVariant) -> Result<()> {
use HomeRebuildVariant::*;

if self.common.pull {
pull(
&self.common.installable,
self.update_args.update,
self.common.dry,
)?;
}

if self.update_args.update {
update(&self.common.installable, self.update_args.update_input)?;
}
Expand Down
4 changes: 4 additions & 0 deletions src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ pub struct CommonRebuildArgs {
#[command(flatten)]
pub installable: Installable,

/// Run git pull on the flake before building specified configuration
#[arg(long, short = 'p')]
pub pull: bool,

/// Don't use nix-output-monitor for the build process
#[arg(long)]
pub no_nom: bool,
Expand Down
10 changes: 9 additions & 1 deletion src/nixos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::generations;
use crate::installable::Installable;
use crate::interface::OsSubcommand::{self};
use crate::interface::{self, OsGenerationsArgs, OsRebuildArgs, OsReplArgs};
use crate::update::update;
use crate::update::{pull, update};

const SYSTEM_PROFILE: &str = "/nix/var/nix/profiles/system";
const CURRENT_PROFILE: &str = "/run/current-system";
Expand Down Expand Up @@ -59,6 +59,14 @@ impl OsRebuildArgs {
true
};

if self.common.pull {
pull(
&self.common.installable,
self.update_args.update,
self.common.dry,
)?;
}

if self.update_args.update {
update(&self.common.installable, self.update_args.update_input)?;
}
Expand Down
42 changes: 42 additions & 0 deletions src/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,45 @@ pub fn update(installable: &Installable, input: Option<String>) -> Result<()> {

Ok(())
}

pub fn pull(installable: &Installable, update: bool, dry: bool) -> Result<()> {
match installable {
Installable::Flake { reference, .. } => {
Command::new("git")
.args(["-C", reference, "pull"])
.dry(dry)
.message("Pulling git repository")
.run()?;

if update {
let status = Command::new("git")
.args(["-C", reference, "diff", "--name-only", "--diff-filter=U"])
.message("Checking for conflicts")
.run_capture()?;

if let Some(conflict) = status {
if conflict == "flake.lock\n".to_string() {
Command::new("git")
.args(["-C", reference, "reset", "flake.lock"])
.message("Resetting flake.lock")
.run()?;
Command::new("git")
.args(["-C", reference, "checkout", "flake.lock"])
.message("Checking out flake.lock")
.run()?;
} else {
panic!("Conflicts dectected that were more than just flake.lock");
}
}
}
}
_ => {
warn!(
"Only flake installables can be pulled, {} is not supported",
installable.str_kind()
);
}
}

Ok(())
}

0 comments on commit 7d8977d

Please sign in to comment.