Repository: railwayapp/nixpacks
Pull request #270 (2022-07-08 02:34:16)

Configurable cache dirs
Allow the user to add additional directories to cache during the install and build phases with the variables `NIXPACKS_BUILD_CACHE_DIRS` and `NIXPACKS_INSTALL_CACHE_DIRS` respectively.



Patch:
diff --git a/docs/pages/docs/config.md b/docs/pages/docs/config.md
index abc17bd..eaee9ec 100644
--- a/docs/pages/docs/config.md
+++ b/docs/pages/docs/config.md
@@ -8,14 +8,16 @@ title: Configuration
 
 Nixpacks can be configured via environment variables. Most of these variables are prefixed with `NIXPACKS_`.
 
-| Variable               | Description                                                                                  |
-| :--------------------- | :------------------------------------------------------------------------------------------- |
-| `NIXPACKS_INSTALL_CMD` | Override the install command to use                                                          |
-| `NIXPACKS_BUILD_CMD`   | Override the build command to use                                                            |
-| `NIXPACKS_START_CMD`   | Override command to run when starting the container                                          |
-| `NIXPACKS_PKGS_CMD`    | Add additional [Nix packages](https://search.nixos.org/packages?channel=unstable) to install |
-| `NIXPACKS_APT_CMD`     | Add additional Apt packages to install                                                       |
-| `NIXPACKS_LIBS_CMD`    | Add additional Nix libraries to make available                                               |
+| Variable                      | Description                                                                                  |
+| :---------------------------- | :------------------------------------------------------------------------------------------- |
+| `NIXPACKS_INSTALL_CMD`        | Override the install command to use                                                          |
+| `NIXPACKS_BUILD_CMD`          | Override the build command to use                                                            |
+| `NIXPACKS_START_CMD`          | Override command to run when starting the container                                          |
+| `NIXPACKS_PKGS_CMD`           | Add additional [Nix packages](https://search.nixos.org/packages?channel=unstable) to install |
+| `NIXPACKS_APT_CMD`            | Add additional Apt packages to install                                                       |
+| `NIXPACKS_LIBS_CMD`           | Add additional Nix libraries to make available                                               |
+| `NIXPACKS_INSTALL_CACHE_DIRS` | Add additional directories to cache during the install phase                                 |
+| `NIXPACKS_BUILD_CACHE_DIRS`   | Add additional directories to cache during the build phase                                   |
 
 ## Procfiles
 
diff --git a/src/main.rs b/src/main.rs
index cc39c2a..0982672 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -157,6 +157,7 @@ fn main() -> Result<()> {
         Some(values) => values.map(String::from).collect::<Vec<String>>(),
         None => Vec::new(),
     };
+
     let pin_pkgs = matches.is_present("pin");
 
     let envs: Vec<_> = match matches.values_of("env") {
diff --git a/src/nixpacks/plan/generator.rs b/src/nixpacks/plan/generator.rs
index dfc4d41..5389c76 100644
--- a/src/nixpacks/plan/generator.rs
+++ b/src/nixpacks/plan/generator.rs
@@ -164,6 +164,18 @@ impl<'a> NixpacksBuildPlanGenerator<'a> {
             env_install_cmd = Some(vec![install_cmd]);
         }
 
+        if let Some(install_cache_dirs) = environment.get_config_variable("INSTALL_CACHE_DIRS") {
+            let custom_install_cache_dirs = install_cache_dirs
+                .split(',')
+                .map(|s| s.to_string())
+                .collect::<Vec<_>>();
+
+            install_phase.cache_directories = match install_phase.cache_directories {
+                Some(dirs) => Some([dirs, custom_install_cache_dirs].concat()),
+                None => Some(custom_install_cache_dirs),
+            }
+        }
+
         // Start command priority
         // - custom install command
         // - environment variable
@@ -190,6 +202,18 @@ impl<'a> NixpacksBuildPlanGenerator<'a> {
             env_build_cmd = Some(vec![build_cmd]);
         }
 
+        if let Some(build_cache_dirs) = environment.get_config_variable("BUILD_CACHE_DIRS") {
+            let custom_build_cache_dirs = build_cache_dirs
+                .split(',')
+                .map(|s| s.to_string())
+                .collect::<Vec<_>>();
+
+            build_phase.cache_directories = match build_phase.cache_directories {
+                Some(dirs) => Some([dirs, custom_build_cache_dirs].concat()),
+                None => Some(custom_build_cache_dirs),
+            }
+        }
+
         // Build command priority
         // - custom build command
         // - environment variable


Test patch:
diff --git a/tests/generate_plan_tests.rs b/tests/generate_plan_tests.rs
index 2127cb8..09e05ed 100644
--- a/tests/generate_plan_tests.rs
+++ b/tests/generate_plan_tests.rs
@@ -558,19 +558,36 @@ fn test_config_from_environment_variables() -> Result<()> {
             "NIXPACKS_BUILD_CMD=build",
             "NIXPACKS_START_CMD=start",
             "NIXPACKS_RUN_IMAGE=alpine",
+            "NIXPACKS_INSTALL_CACHE_DIRS=/tmp,foobar",
+            "NIXPACKS_BUILD_CACHE_DIRS=/build,barbaz",
         ],
         &GeneratePlanOptions::default(),
     )?;
+
     assert_eq!(
-        plan.install.unwrap().cmds,
+        plan.setup.unwrap().pkgs,
+        vec![Pkg::new("cowsay"), Pkg::new("ripgrep")]
+    );
+
+    assert_eq!(
+        plan.install.clone().unwrap().cmds,
         Some(vec!["install".to_string()])
     );
-    assert_eq!(plan.build.unwrap().cmds, Some(vec!["build".to_string()]));
-    assert_eq!(plan.start.clone().unwrap().cmd, Some("start".to_string()));
     assert_eq!(
-        plan.setup.unwrap().pkgs,
-        vec![Pkg::new("cowsay"), Pkg::new("ripgrep")]
+        plan.install.unwrap().cache_directories,
+        Some(vec!["/tmp".to_string(), "foobar".to_string()])
+    );
+
+    assert_eq!(
+        plan.build.clone().unwrap().cmds,
+        Some(vec!["build".to_string()])
     );
+    assert_eq!(
+        plan.build.unwrap().cache_directories,
+        Some(vec!["/build".to_string(), "barbaz".to_string()])
+    );
+
+    assert_eq!(plan.start.clone().unwrap().cmd, Some("start".to_string()));
     assert_eq!(plan.start.unwrap().run_image, Some("alpine".to_string()));
 
     Ok(())