<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch master
in repository macports-infrastructure.

</pre>
<p><a href="https://github.com/macports/macports-infrastructure/commit/36f6f348e3fd7e1fc3ce2e119b762946d958e812">https://github.com/macports/macports-infrastructure/commit/36f6f348e3fd7e1fc3ce2e119b762946d958e812</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'>     new 36f6f34  Add scripts for deleting old archives.
</span>36f6f34 is described below

<span style='display:block; white-space:pre;color:#808000;'>commit 36f6f348e3fd7e1fc3ce2e119b762946d958e812
</span>Author: Joshua Root <jmr@macports.org>
AuthorDate: Fri Nov 4 00:03:06 2016 +1100

<span style='display:block; white-space:pre;color:#404040;'>    Add scripts for deleting old archives.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    These previously lived at
</span><span style='display:block; white-space:pre;color:#404040;'>    <https://svn.macports.org/repository/macports/users/jmr/delete_old_archives/>
</span>---
 jobs/current_versions.tcl   | 17 +++++++++
 jobs/delete_old_archives.py | 84 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 101 insertions(+)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/jobs/current_versions.tcl b/jobs/current_versions.tcl
</span>new file mode 100755
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..6d58a8e
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/jobs/current_versions.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,17 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#!/usr/bin/env port-tclsh
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+package require macports
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+mportinit
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {[catch {set res [mportlistall]} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    puts stderr "$::errorInfo"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    error "listing all ports failed: $result"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+foreach {name dictionary} $res {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    array unset portinfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    array set portinfo $dictionary
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    puts "${name} $portinfo(version)_$portinfo(revision)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+mportshutdown
</span><span style='display:block; white-space:pre;color:#808080;'>diff --git a/jobs/delete_old_archives.py b/jobs/delete_old_archives.py
</span>new file mode 100755
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..b69046f
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/jobs/delete_old_archives.py
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,84 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#!/usr/bin/env python
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+greatestAge = 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+greatestSize = 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+totalSize = 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+class archiveFile(object):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    """An archive file being considered for deletion"""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    def __init__(self, path, age, size):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        self.path = path
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        self.age = age
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        self.size = size
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+def weightedValue(age, size):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    """Combine an age and a size into a value out of 100"""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    weightedAge = (float(age) / float(greatestAge)) * 50.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    weightedSize = (float(size) / float(greatestSize)) * 50.0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return weightedAge + weightedSize
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+def weightedKey(archive):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    """Key extraction function for sorting using weightedValue"""
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return weightedValue(archive.age, archive.size)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+import sys
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+versionFile = 'current_versions.txt'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+rootDir = '.'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if len(sys.argv) > 1:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    rootDir = sys.argv[1]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if len(sys.argv) > 2:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        versionFile = sys.argv[2]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+import re
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# patterns to match against for archives that are the current version
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+currentVersions = {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fd = open(versionFile, 'r')
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+for line in fd:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    name, version = line.split()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    currentVersions[name] = re.compile(name+'-'+version+'[.+]')
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fd.close()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+import time
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+now = time.time()
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fileList = []
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+import os
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+for portdir in os.listdir(rootDir):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    portDirPath = os.path.join(rootDir, portdir)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if os.path.isdir(portDirPath):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        for archiveFilename in os.listdir(portDirPath):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            try:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if archiveFilename.endswith('.rmd160') or currentVersions[portdir].match(archiveFilename):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    continue
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            except KeyError:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                pass
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            archivePath = os.path.join(portDirPath, archiveFilename)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if os.path.isfile(archivePath):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                thisAge = now - os.path.getmtime(archivePath)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                thisSize = os.path.getsize(archivePath)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                thisArchiveFile = archiveFile(archivePath, thisAge, thisSize)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                fileList.append(thisArchiveFile)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if thisArchiveFile.age > greatestAge:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    greatestAge = thisArchiveFile.age
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                if thisArchiveFile.size > greatestSize:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    greatestSize = thisArchiveFile.size
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                totalSize += thisSize
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+fileList.sort(key=weightedKey, reverse=True)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+for f in fileList:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    sys.stderr.write(f.path+' '+str(f.age)+' '+str(f.size)+': weighted value = '+str(weightedValue(f.age, f.size))+'\n')
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+# trim files until the total size of non-current archives remaining is this or less
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+targetSize = 200 * 10**9
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+for f in fileList:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if totalSize <= targetSize:
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        break
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    print (f.path)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    sigpath = f.path+'.rmd160'
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if os.path.isfile(sigpath):
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        print (sigpath)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    totalSize -= f.size
</span></pre><pre style='margin:0'>

</pre>