diff --git a/src/flake_writer.rs b/src/flake_writer.rs index 6ad3f46..e289614 100644 --- a/src/flake_writer.rs +++ b/src/flake_writer.rs @@ -577,6 +577,8 @@ fn copy_for_poetry( } } } + //I'd love to return these relative, but since we run ancient-poetry in a tmp dir, + //this will fail. Ok(target_path.canonicalize()?.to_string_lossy().to_string()) } diff --git a/src/main.rs b/src/main.rs index 79ad12b..23dc2f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -352,6 +352,10 @@ fn inner_main() -> Result<()> { &mut out_non_spec_but_cached_values, )?; + if flake_changed.flake_nix_changed && !use_generated_file_instead { + register_flake_inputs_as_gc_root(&flake_dir)?; + } + if out_non_spec_but_cached_values != in_non_spec_but_cached_values { save_cached_values(&flake_dir, &out_non_spec_but_cached_values)?; } @@ -1407,6 +1411,9 @@ fn nix_build_flake(url: &str) -> Result { }) } +////register the used tools and the flake itself as gcroots +///our own flake is automatically gc rooted. +///and teh flake-inputs are handled when/if the flake changed pub fn register_nix_gc_root(url: &str, flake_dir: impl AsRef) -> Result<()> { debug!("registering gc root for {}", url); //where we store this stuff @@ -1416,13 +1423,14 @@ pub fn register_nix_gc_root(url: &str, flake_dir: impl AsRef) -> Result<() let (without_hash, _) = url .rsplit_once('#') .context("GC_root url should contain #")?; - //first we store and hash the flake itself and record tha. + //first we store and hash the flake itself and record that. let flake_symlink_here = gc_roots.join(without_hash.replace('/', "_")); if !flake_symlink_here.exists() { let store_path = prefetch_flake(without_hash)?; register_gc_root(&store_path, &flake_symlink_here)?; } + //then we record it's output let build_symlink_here = gc_roots.join(url.replace('/', "_")); if !build_symlink_here.exists() { let store_path = nix_build_flake(url)?; @@ -1431,6 +1439,21 @@ pub fn register_nix_gc_root(url: &str, flake_dir: impl AsRef) -> Result<() Ok(()) } +fn register_flake_inputs_as_gc_root(flake_dir: impl AsRef) -> Result<()> { + //run nix build .#flake_inputs_for_gc_root wit han output dir + Command::new("nix") + .args([ + "build", + ".#flake_inputs_for_gc_root", + "-o", + ".gcroot_for_flake_inputs", + ]) + .current_dir(flake_dir) + .status() + .context("retrieving content for flake input gc root from nix failed")?; + Ok(()) +} + fn attach_to_previous_container(flake_dir: impl AsRef) -> Result<()> { let mut available: Vec<_> = fs::read_dir(flake_dir.as_ref().join("dtach")) .context("Could not find dtach socket directory")? diff --git a/src/nix/flake_template.nix b/src/nix/flake_template.nix index 2e839de..2feddaa 100644 --- a/src/nix/flake_template.nix +++ b/src/nix/flake_template.nix @@ -4,7 +4,7 @@ #%INPUT_DEFS% }; - outputs = { + outputs = flake_inputs @ { self, #%INPUTS% }: @@ -27,13 +27,30 @@ }; helpers = import ./functions.nix {inherit pkgs;}; in rec { - defaultPackage = (helpers.buildSymlinkImage _args).derivation; - oci_image = helpers.buildOCIimage _args; + packages = { + default = (helpers.buildSymlinkImage _args).derivation; + oci_image = helpers.buildOCIimage _args; + flake_inputs_for_gc_root = pkgs.stdenv.mkDerivation { + pname = "anysnake2-flake-inputs"; + version = "0.1"; + unpackPhase = ":"; + buildPhase = let + str_inputs = + builtins.concatStringsSep "\n" + (map (key: "ln -s ${flake_inputs.${key}} ${key}") (builtins.attrNames flake_inputs)); + in + '' + mkdir $out -p + cd $out/ + '' + + str_inputs; + }; + }; devShell = pkgs.stdenv.mkDerivation { name = "anysnake2-devshell"; shellHook = '' - export PATH=${defaultPackage}/rootfs/bin:$PATH; + export PATH=${packages.default}/rootfs/bin:$PATH; if test -f "develop_python_path.bash"; then source "develop_python_path.bash" fi