about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthew O'Gorman <mog@rldn.net>2016-01-07T01·15-0500
committerMatthew O'Gorman <mog@rldn.net>2018-03-02T02·47-0500
commit429154b74c7f4b4d679ae79bbc939049f537bfaf (patch)
tree8f393c37c7138cf16a23c2e364b9f5f0bcd765a1 /src
parent4a000cbb39766812fccebfa7cf8b76ecca8f6e63 (diff)
Implement --delete-generations + flag for keeping last N number of generations
Diffstat (limited to 'src')
-rw-r--r--src/libstore/profiles.cc23
-rw-r--r--src/libstore/profiles.hh2
-rw-r--r--src/nix-env/nix-env.cc2
3 files changed, 27 insertions, 0 deletions
diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc
index 4a607b584506..e6300cf05552 100644
--- a/src/libstore/profiles.cc
+++ b/src/libstore/profiles.cc
@@ -157,6 +157,29 @@ void deleteGenerations(const Path & profile, const std::set<unsigned int> & gens
     }
 }
 
+void deleteGenerationsGreaterThan(const Path & profile, const string & max, bool dryRun)
+{
+    int max_keep = 0;
+    PathLocks lock;
+    if(max.size() < 2)
+     throw Error(format("invalid number of generations ‘%1%’") % max);
+    string str_max = string(max, 1, max.size());
+    if (!string2Int(str_max, max_keep) || max_keep == 0)
+      throw Error(format("invalid number of generations to keep ‘%1%’") % max);
+
+    lockProfile(lock, profile);
+
+    int curGen;
+    Generations gens = findGenerations(profile, curGen);
+
+    for (auto i = gens.rbegin(); i != gens.rend(); ++i) {
+      if (max_keep) {
+	max_keep--;
+	continue;
+      }
+      deleteGeneration2(profile, i->number, dryRun);
+    }
+}
 
 void deleteOldGenerations(const Path & profile, bool dryRun)
 {
diff --git a/src/libstore/profiles.hh b/src/libstore/profiles.hh
index 1d4e6d3037db..3cad08dc5265 100644
--- a/src/libstore/profiles.hh
+++ b/src/libstore/profiles.hh
@@ -39,6 +39,8 @@ void deleteGeneration(const Path & profile, unsigned int gen);
 
 void deleteGenerations(const Path & profile, const std::set<unsigned int> & gensToDelete, bool dryRun);
 
+void deleteGenerationsGreaterThan(const Path & profile, const string & max, bool dryRun);
+
 void deleteOldGenerations(const Path & profile, bool dryRun);
 
 void deleteGenerationsOlderThan(const Path & profile, time_t t, bool dryRun);
diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc
index 97e66cbd937e..1440b7744fd6 100644
--- a/src/nix-env/nix-env.cc
+++ b/src/nix-env/nix-env.cc
@@ -1284,6 +1284,8 @@ static void opDeleteGenerations(Globals & globals, Strings opFlags, Strings opAr
         deleteOldGenerations(globals.profile, globals.dryRun);
     } else if (opArgs.size() == 1 && opArgs.front().find('d') != string::npos) {
         deleteGenerationsOlderThan(globals.profile, opArgs.front(), globals.dryRun);
+    } else if (opArgs.size() == 1 && opArgs.front().find('+') != string::npos) {
+        deleteGenerationsGreaterThan(globals.profile, opArgs.front(), globals.dryRun);
     } else {
         std::set<unsigned int> gens;
         for (auto & i : opArgs) {