]> scripts.mit.edu Git - wizard.git/commitdiff
Libify wizard.
authorEdward Z. Yang <edwardzyang@thewritingpot.com>
Sun, 14 Jun 2009 03:44:19 +0000 (23:44 -0400)
committerEdward Z. Yang <edwardzyang@thewritingpot.com>
Sun, 14 Jun 2009 03:44:29 +0000 (23:44 -0400)
Signed-off-by: Edward Z. Yang <edwardzyang@thewritingpot.com>
.gitignore [new file with mode: 0644]
bin/wizard
lib/wizard/__init__.py [new file with mode: 0644]
lib/wizard/command/__init__.py [new file with mode: 0644]
lib/wizard/command/stat.py [new file with mode: 0644]
lib/wizard/deploy.py [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..0d20b64
--- /dev/null
@@ -0,0 +1 @@
+*.pyc
index 5615047330e49e6966187676ddfced658f01fe58..ac69d8ece66a42ea16dc1947dd1488755aa47567 100755 (executable)
@@ -10,150 +10,11 @@ Specifically, it:
 
 import os
 import optparse
-import fileinput
-import math
 import sys
-from distutils.version import LooseVersion as Version
 
-class NoSuchApplication(Exception):
-    pass
-
-class DeploymentParseError(Exception):
-    pass
-
-class Deployment(object):
-    def __init__(self, location, version):
-        self.location = location
-        self.version = version
-        self.application = version.application
-    @staticmethod
-    def parse(line):
-        """Parses a line from the results of parallel-find.pl.
-        This will work out of the box with fileinput"""
-        try:
-            location, deploydir = line.rstrip().split(":")
-        except ValueError:
-            raise DeploymentParseError
-        name = deploydir.split("/")[-1]
-        if name.find("-") != -1:
-            app, version = name.split("-")
-        elif name == "deploy":
-            # Assume that it's django, since those were botched
-            app = "django"
-            version = "0.1-scripts"
-        else:
-            raise DeploymentParseError
-        try:
-            return Deployment(location, applications[app].getVersion(version))
-        except KeyError:
-            raise NoSuchApplication
-    def count(self):
-        """Simple method which registers the deployment as a +1 on the
-        appropriate version. No further inspection is done."""
-        self.version.count(self)
-        return True
-    def count_exists(self, file):
-        """Checks if the codebase has a certain file/directory in it."""
-        if os.path.exists(self.location + "/" + file):
-            self.version.count_exists(self, file)
-            return True
-        return False
-
-class Application(object):
-    HISTOGRAM_WIDTH = 30
-    def __init__(self, name):
-        self.name = name
-        self.versions = {}
-        # Some cache variables for fast access of calculated data
-        self._total = 0
-        self._max   = 0
-        self._c_exists = {}
-    def getVersion(self, version):
-        if version not in self.versions:
-            self.versions[version] = ApplicationVersion(Version(version), self)
-        return self.versions[version]
-    def _graph(self, v):
-        return '+' * int(math.ceil(float(v)/self._max * self.HISTOGRAM_WIDTH))
-    def __str__(self):
-        if not self.versions: return "%-11s   no installs" % self.name
-        ret = \
-            ["%-16s %3d installs" % (self.name, self._total)] + \
-            [str(v) for v in sorted(self.versions.values())]
-        for f,c in self._c_exists.items():
-            ret.append("%d users have %s" % (c,f))
-        return "\n".join(ret)
-
-class ApplicationVersion(object):
-    def __init__(self, version, application):
-        self.version = version
-        self.application = application
-        self.c = 0
-        self.c_exists = {}
-    def __cmp__(x, y):
-        return cmp(x.version, y.version)
-    def count(self, deployment):
-        self.c += 1
-        self.application._total += 1
-        if self.c > self.application._max:
-            self.application._max = self.c
-    def count_exists(self, deployment, n):
-        if n in self.c_exists: self.c_exists[n] += 1
-        else: self.c_exists[n] = 1
-        if n in self.application._c_exists: self.application._c_exists[n] += 1
-        else: self.application._c_exists[n] = 1
-    def __str__(self):
-        return "    %-12s %3d  %s" \
-            % (self.version, self.c, self.application._graph(self.c))
-
-class Printer(object):
-    def __init__(self, quiet, verbose):
-        self.i = 0
-        self.quiet = quiet
-        self.verbose = verbose
-        self.hanging = False
-    def tick(self):
-        self.i += 1
-        if not self.quiet and self.i % 10 == 0:
-            sys.stdout.write(".")
-            sys.stdout.flush()
-            self.hanging = True
-    def _hang(self):
-        if self.hanging:
-            self.hanging = False
-            print
-    def write(self, str = ""):
-        self._hang()
-        print str
-    def qwrite(self, str = ""):
-        if not self.quiet:
-            self._hang
-            print str
-    def tweet(self, str = ""):
-        if not self.quiet:
-            self._hang()
-            print str, # note comma
-    def chat(self, str = ""):
-        if self.verbose:
-            self._hang()
-            print str
-
-application_list = [
-    "mediawiki", "wordpress", "joomla", "e107", "gallery2",
-    "phpBB", "advancedbook", "phpical", "trac", "turbogears", "django",
-    # these are technically deprecated
-    "advancedpoll", "gallery",
-]
-
-"""Hash table for looking up string application name to instance"""
-applications = dict([(n,Application(n)) for n in application_list ])
-
-def getInstallLines(global_options):
-    vd = global_options.version_dir
-    try:
-        return fileinput.input([vd + "/" + f for f in os.listdir(vd)])
-    except OSError:
-        print "No permissions; check if AFS is mounted"
-        raise SystemExit(-1)
+# Add lib to path
+sys.path.insert(0,os.path.abspath(os.path.join(__file__,'../../lib')))
+import wizard.command
 
 def main():
     usage = """usage: %prog [-d|--version-dir] COMMAND [ARGS]
@@ -184,80 +45,19 @@ See '%prog help COMMAND' for more information on a specific command.
     options, args = parser.parse_args(sys.argv[1:i+1])
     rest_argv = sys.argv[i+1:]
     command = args[0] # shouldn't fail
-    commands = {
-        "stat": stat
-    }
     if command == "help":
         try:
-            commands[rest_argv[0]](['-h'], options)
+            getattr(wizard.command, rest_argv[0])(['-h'], options)
         except KeyError:
             parser.error("invalid action")
         except IndexError:
             parser.print_usage()
             raise SystemExit(-1)
     # Dispatch commands
-    if command not in commands:
+    try:
+        getattr(wizard.command, command).main(rest_argv, options)
+    except AttributeError:
         parser.error("invalid action")
-    return commands[command](rest_argv, options)
-
-def stat(argv, global_options):
-    usage = """usage: %prog stat [ARGS] APPS
-
-Scans all of the collected data from parallel-find.pl, and
-determines version histograms for our applications.  You may
-optionally pass application parameters to filter the installs.
-
-Examples:
-    %prog stat
-        Basic usage
-    %prog stat mediawiki
-        Displays only MediaWiki statistics
-    %prog stat -v -q mediawiki-1.2.3
-        Displays all deployments of this version"""
-    parser = optparse.OptionParser(usage)
-    parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
-            default=False, help="Print interesting directories")
-    parser.add_option("-q", "--quiet", dest="quiet", action="store_true",
-            default=False, help="Suppresses progress output")
-    parser.add_option("--count-exists", dest="count_exists",
-            default=False, help="Count deployments that contain a file")
-    options, show = parser.parse_args(argv)
-    fi = getInstallLines(global_options)
-    if not show: show = applications.keys()
-    show = frozenset(show)
-    errors = 0
-    unrecognized = 0
-    processed = 0
-    printer = Printer(options.quiet, options.verbose)
-    printer.tweet("Processing")
-    for line in fi:
-        printer.tick()
-        try:
-            deploy = Deployment.parse(line)
-        except DeploymentParseError:
-            errors += 1
-            continue
-        except NoSuchApplication:
-            unrecognized += 1
-            continue
-        if deploy.application.name + "-" + str(deploy.version.version) in show:
-            printer.write("%s-%s deployment at %s" \
-                % (deploy.application.name, deploy.version.version, deploy.location))
-        elif deploy.application.name in show:
-            pass
-        else:
-            continue
-        deploy.count()
-        if options.count_exists:
-            r = deploy.count_exists(options.count_exists)
-            if r:
-                printer.chat("Found " + options.count_exists + " in " + deploy.location)
-    printer.write()
-    for app in applications.values():
-        if app.name not in show: continue
-        printer.write(app)
-        printer.write()
-    printer.write("With %d errors and %d unrecognized applications" % (errors, unrecognized))
 
 if __name__ == "__main__":
     main()
diff --git a/lib/wizard/__init__.py b/lib/wizard/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/lib/wizard/command/__init__.py b/lib/wizard/command/__init__.py
new file mode 100644 (file)
index 0000000..82bae4c
--- /dev/null
@@ -0,0 +1 @@
+import stat
diff --git a/lib/wizard/command/stat.py b/lib/wizard/command/stat.py
new file mode 100644 (file)
index 0000000..f291a30
--- /dev/null
@@ -0,0 +1,95 @@
+import optparse
+import wizard.deploy as wd
+import sys
+
+class Printer(object):
+    def __init__(self, quiet, verbose):
+        self.i = 0
+        self.quiet = quiet
+        self.verbose = verbose
+        self.hanging = False
+    def tick(self):
+        self.i += 1
+        if not self.quiet and self.i % 10 == 0:
+            sys.stdout.write(".")
+            sys.stdout.flush()
+            self.hanging = True
+    def _hang(self):
+        if self.hanging:
+            self.hanging = False
+            print
+    def write(self, str = ""):
+        self._hang()
+        print str
+    def qwrite(self, str = ""):
+        if not self.quiet:
+            self._hang
+            print str
+    def tweet(self, str = ""):
+        if not self.quiet:
+            self._hang()
+            print str, # note comma
+    def chat(self, str = ""):
+        if self.verbose:
+            self._hang()
+            print str
+
+def main(argv, global_options):
+    usage = """usage: %prog stat [ARGS] APPS
+
+Scans all of the collected data from parallel-find.pl, and
+determines version histograms for our applications.  You may
+optionally pass application parameters to filter the installs.
+
+Examples:
+    %prog stat
+        Basic usage
+    %prog stat mediawiki
+        Displays only MediaWiki statistics
+    %prog stat -v -q mediawiki-1.2.3
+        Displays all deployments of this version"""
+    parser = optparse.OptionParser(usage)
+    parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
+            default=False, help="Print interesting directories")
+    parser.add_option("-q", "--quiet", dest="quiet", action="store_true",
+            default=False, help="Suppresses progress output")
+    parser.add_option("--count-exists", dest="count_exists",
+            default=False, help="Count deployments that contain a file")
+    options, show = parser.parse_args(argv)
+    fi = wd.getInstallLines(global_options)
+    if not show: show = wd.applications.keys()
+    show = frozenset(show)
+    errors = 0
+    unrecognized = 0
+    processed = 0
+    printer = Printer(options.quiet, options.verbose)
+    printer.tweet("Processing")
+    for line in fi:
+        printer.tick()
+        try:
+            deploy = wd.Deployment.parse(line)
+        except wd.DeploymentParseError:
+            errors += 1
+            continue
+        except wd.NoSuchApplication:
+            unrecognized += 1
+            continue
+        if deploy.application.name + "-" + str(deploy.version.version) in show:
+            printer.write("%s-%s deployment at %s" \
+                % (deploy.application.name, deploy.version.version, deploy.location))
+        elif deploy.application.name in show:
+            pass
+        else:
+            continue
+        deploy.count()
+        if options.count_exists:
+            r = deploy.count_exists(options.count_exists)
+            if r:
+                printer.chat("Found " + options.count_exists + " in " + deploy.location)
+    printer.write()
+    for app in wd.applications.values():
+        if app.name not in show: continue
+        printer.write(app)
+        printer.write()
+    printer.write("With %d errors and %d unrecognized applications" % (errors, unrecognized))
+
diff --git a/lib/wizard/deploy.py b/lib/wizard/deploy.py
new file mode 100644 (file)
index 0000000..a552437
--- /dev/null
@@ -0,0 +1,113 @@
+import os.path
+import math
+import fileinput
+from distutils.version import LooseVersion as Version
+
+def getInstallLines(global_options):
+    vd = global_options.version_dir
+    try:
+        return fileinput.input([vd + "/" + f for f in os.listdir(vd)])
+    except OSError:
+        print "No permissions; check if AFS is mounted"
+        raise SystemExit(-1)
+
+class NoSuchApplication(Exception):
+    pass
+
+class DeploymentParseError(Exception):
+    pass
+
+class Deployment(object):
+    def __init__(self, location, version):
+        self.location = location
+        self.version = version
+        self.application = version.application
+    @staticmethod
+    def parse(line):
+        """Parses a line from the results of parallel-find.pl.
+        This will work out of the box with fileinput"""
+        try:
+            location, deploydir = line.rstrip().split(":")
+        except ValueError:
+            raise DeploymentParseError
+        name = deploydir.split("/")[-1]
+        if name.find("-") != -1:
+            app, version = name.split("-")
+        elif name == "deploy":
+            # Assume that it's django, since those were botched
+            app = "django"
+            version = "0.1-scripts"
+        else:
+            raise DeploymentParseError
+        try:
+            return Deployment(location, applications[app].getVersion(version))
+        except KeyError:
+            raise NoSuchApplication
+    def count(self):
+        """Simple method which registers the deployment as a +1 on the
+        appropriate version. No further inspection is done."""
+        self.version.count(self)
+        return True
+    def count_exists(self, file):
+        """Checks if the codebase has a certain file/directory in it."""
+        if os.path.exists(self.location + "/" + file):
+            self.version.count_exists(self, file)
+            return True
+        return False
+
+class Application(object):
+    HISTOGRAM_WIDTH = 30
+    def __init__(self, name):
+        self.name = name
+        self.versions = {}
+        # Some cache variables for fast access of calculated data
+        self._total = 0
+        self._max   = 0
+        self._c_exists = {}
+    def getVersion(self, version):
+        if version not in self.versions:
+            self.versions[version] = ApplicationVersion(Version(version), self)
+        return self.versions[version]
+    def _graph(self, v):
+        return '+' * int(math.ceil(float(v)/self._max * self.HISTOGRAM_WIDTH))
+    def __str__(self):
+        if not self.versions: return "%-11s   no installs" % self.name
+        ret = \
+            ["%-16s %3d installs" % (self.name, self._total)] + \
+            [str(v) for v in sorted(self.versions.values())]
+        for f,c in self._c_exists.items():
+            ret.append("%d users have %s" % (c,f))
+        return "\n".join(ret)
+
+class ApplicationVersion(object):
+    def __init__(self, version, application):
+        self.version = version
+        self.application = application
+        self.c = 0
+        self.c_exists = {}
+    def __cmp__(x, y):
+        return cmp(x.version, y.version)
+    def count(self, deployment):
+        self.c += 1
+        self.application._total += 1
+        if self.c > self.application._max:
+            self.application._max = self.c
+    def count_exists(self, deployment, n):
+        if n in self.c_exists: self.c_exists[n] += 1
+        else: self.c_exists[n] = 1
+        if n in self.application._c_exists: self.application._c_exists[n] += 1
+        else: self.application._c_exists[n] = 1
+    def __str__(self):
+        return "    %-12s %3d  %s" \
+            % (self.version, self.c, self.application._graph(self.c))
+
+application_list = [
+    "mediawiki", "wordpress", "joomla", "e107", "gallery2",
+    "phpBB", "advancedbook", "phpical", "trac", "turbogears", "django",
+    # these are technically deprecated
+    "advancedpoll", "gallery",
+]
+
+"""Hash table for looking up string application name to instance"""
+applications = dict([(n,Application(n)) for n in application_list ])
+