]> scripts.mit.edu Git - wizard.git/commitdiff
Refactor to get rid of _package.py using __import__ magic.
authorEdward Z. Yang <ezyang@mit.edu>
Thu, 30 Jul 2009 04:46:53 +0000 (00:46 -0400)
committerEdward Z. Yang <ezyang@mit.edu>
Thu, 30 Jul 2009 04:46:53 +0000 (00:46 -0400)
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
19 files changed:
README
TODO
bin/wizard
wizard/command/__init__.py
wizard/command/_command.py [deleted file]
wizard/command/info.py
wizard/command/massmigrate.py
wizard/command/migrate.py
wizard/command/summary/__init__.py
wizard/command/summary/_summary.py [deleted file]
wizard/command/summary/count_exists.py
wizard/command/summary/list.py
wizard/command/summary/list_errors.py
wizard/command/summary/version.py
wizard/command/upgrade.py
wizard/deploy.py
wizard/shell.py
wizard/tests/deploy_test.py
wizard/tests/log_test.py [new file with mode: 0644]

diff --git a/README b/README
index 7382dfa9ab0ec3938875eb917c377c8be24b4440..505e8f595e0a3c483886801efed43534d90c283e 100644 (file)
--- a/README
+++ b/README
@@ -31,9 +31,6 @@ locations:
 - bin/wizard
     Add a line describing your command in the helpstring
 
-- wizard/command/__init__.py
-    Add the line "import commandname"
-
 - wizard/command/commandname.py
     Implement your command there as main(). Copy the function
     signature and scaffolding from another file; it's non-trivial
diff --git a/TODO b/TODO
index 387e8bb36786d27a746370656fcbfafc9829a10b..410e729c99e047f14766471bc53b5cc5fce3f36a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -14,6 +14,8 @@ TODO NOW:
   file, so will we; installer script needs to be able to run
   the installer to generate config files, so will this)
 
+- Fix parallel find to work with new style autoinstalls
+
 - The great initial deploy:
     - Turn on mediawiki new autoinstaller
     - Migrate all mediawiki installs
index 81599efced1b6e3c839acb0bead9cc0bf7f0f29c..795adad34e1ecf6d4d52e48f546797a90fa7a1e7 100755 (executable)
@@ -4,10 +4,10 @@ import os
 import optparse
 import sys
 
-# Add lib to path
 sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-import wizard.command
-from wizard.command import _command
+
+import wizard
+from wizard import command
 
 def main():
     usage = """usage: %prog COMMAND [ARGS]
@@ -27,31 +27,32 @@ See '%prog help COMMAND' for more information on a specific command."""
     parser.disable_interspersed_args()
     _, args = parser.parse_args() # no global options
     rest_argv = args[1:]
-    baton = _command.OptionBaton()
+    baton = command.OptionBaton()
     baton.add("--versions-path", dest="versions_path",
         default="/afs/athena.mit.edu/contrib/scripts/sec-tools/store/versions",
         help="Location of parallel-find output directory, or a file containing a newline separated list of 'all autoinstalls' (for testing).")
     try:
-        command = args[0]
+        command_name = args[0]
     except IndexError:
         parser.print_help()
         raise SystemExit(1)
-    if command == "help":
+    if command_name == "help":
         try:
             get_command(rest_argv[0]).main(['--help'], baton)
-        except AttributeError:
+        except (AttributeError, ImportError):
             parser.error("invalid action")
         except IndexError:
             parser.print_help()
             raise SystemExit(1)
     # Dispatch commands
     try:
-        command_module = get_command(command)
-    except AttributeError:
+        command_module = get_command(command_name)
+    except (AttributeError, ImportError):
         parser.error("invalid action")
     command_module.main(rest_argv, baton)
 
 def get_command(name):
+    __import__("wizard.command." + name)
     return getattr(wizard.command, name)
 
 if __name__ == "__main__":
index bbf389bc565df6b707cdc6c535595069f5cb86e1..e5cb0b4354f06b3d3c85b2ab9d43c92aa8e16ab8 100644 (file)
@@ -1,5 +1,147 @@
-import migrate
-import massmigrate
-import info
-import summary
-import upgrade
+import logging
+import os
+import sys
+import optparse
+import errno
+
+import wizard
+
+logging_setup = False
+
+class Error(wizard.Error):
+    """Base error class for all command errors"""
+    pass
+
+class PermissionsError(Error):
+    def __init__(self, dir):
+        self.dir = dir
+    def __str__(self):
+        return """
+
+ERROR: You don't have permissions to access this directory.
+Do you have tokens for AFS with your root instance, and
+is your root instance on scripts-security-upd?
+
+You can check by running the commands 'klist' and
+'blanche scripts-security-upd'.
+"""
+
+class NoSuchDirectoryError(Error):
+    def __init__(self, dir):
+        self.dir = dir
+    def __str__(self):
+        return """
+
+ERROR: No such directory... check your typing
+"""
+
+def chdir(dir):
+    try:
+        os.chdir(dir)
+    except OSError as e:
+        if e.errno == errno.EACCES:
+            raise PermissionsError(dir)
+        elif e.errno == errno.ENOENT:
+            raise NoSuchDirectoryError(dir)
+        else: raise e
+
+def makeLogger(options, numeric_args):
+    global logging_setup
+    if logging_setup: return logging.getLogger()
+    context = " ".join(numeric_args)
+    logger = logging.getLogger()
+    logger.setLevel(logging.INFO)
+    stderr = logging.StreamHandler(sys.stderr)
+    stderr.setFormatter(logging.Formatter(" " * int(options.indent) + '%(levelname)s: %(message)s'))
+    dateFormat = "%H:%M:%S"
+    if options.context:
+        logformatter = logging.Formatter("%(asctime)s %(levelname)s -- " + context + ": %(message)s", dateFormat)
+    else:
+        logformatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s", dateFormat)
+    if not options.quiet: logger.addHandler(stderr)
+    else: logger.addHandler(NullLogHandler()) # prevent default
+    if options.log_file:
+        file = logging.FileHandler(options.log_file)
+        file.setFormatter(logformatter)
+        logger.addHandler(file)
+        if options.log_file_chmod:
+            os.chmod(options.log_file, int(options.log_file_chmod, 8))
+    if options.debug:
+        logger.setLevel(logging.DEBUG)
+    else:
+        stderr.setLevel(logging.WARNING)
+        if options.verbose or hasattr(options, "dry_run"):
+            stderr.setLevel(logging.INFO)
+        if options.log_file:
+            file.setLevel(logging.INFO)
+    logging_setup = True
+    return logger
+
+def makeBaseArgs(options, **grab):
+    """Takes parsed options, and breaks them back into a command
+    line string that we can pass into a subcommand"""
+    args = []
+    grab["log_file"]= "--log-file"
+    grab["debug"]   = "--debug"
+    grab["verbose"] = "--verbose"
+    grab["indent"]  = "--indent"
+    grab["quiet"]   = "--quiet"
+    #grab["log_db"] = "--log-db"
+    for k,flag in grab.items():
+        value = getattr(options, k)
+        if not value and k != "indent": continue
+        args.append(flag)
+        if type(value) is not bool:
+            if k == "indent":
+                value += 4
+            args.append(str(value))
+    args.append("--context") # always have context for a subcommand
+    return args
+
+class NullLogHandler(logging.Handler):
+    """Log handler that doesn't do anything"""
+    def emit(self, record):
+        pass
+
+class WizardOptionParser(optparse.OptionParser):
+    """Configures some default user-level options"""
+    def __init__(self, *args, **kwargs):
+        kwargs["add_help_option"] = False
+        optparse.OptionParser.__init__(self, *args, **kwargs)
+    def parse_all(self, argv):
+        self.add_option("-h", "--help", action="help", help=optparse.SUPPRESS_HELP)
+        group = optparse.OptionGroup(self, "Common Options")
+        group.add_option("-v", "--verbose", dest="verbose", action="store_true",
+                default=False, help="Turns on verbose output")
+        group.add_option("--debug", dest="debug", action="store_true",
+                default=False, help="Turns on debugging output")
+        group.add_option("-q", "--quiet", dest="quiet", action="store_true",
+                default=False, help="Turns off output to stdout")
+        group.add_option("--log-file", dest="log_file",
+                default=None, help="Logs verbose output to file")
+        group.add_option("--log-file-chmod", dest="log_file_chmod",
+                default=None, help="Chmod the log file after opening.  Number is octal. You must chmod the log file 666 and place the file in /tmp if subprocesses are running as different users.")
+        group.add_option("--indent", dest="indent",
+                default=0, help="Indents stdout, useful for nested calls")
+        group.add_option("--context", dest="context", action="store_true",
+                default=False, help="Adds context to logs, useful for parallel processing")
+        self.add_option_group(group)
+        options, numeric_args = self.parse_args(argv)
+        makeLogger(options, numeric_args)
+        return options, numeric_args
+
+class OptionBaton(object):
+    """Command classes may define options that they sub-commands may
+    use.  Since wizard --global-command subcommand is not a supported
+    mode of operation, these options have to be passed down the command
+    chain until a option parser is ready to take it; this baton is
+    what is passed down."""
+    def __init__(self):
+        self.store = {}
+    def add(self, *args, **kwargs):
+        key = kwargs["dest"] # require this to be set
+        self.store[key] = optparse.make_option(*args, **kwargs)
+    def push(self, option_parser, *args):
+        """Hands off parameters to option parser"""
+        for key in args:
+            option_parser.add_option(self.store[key])
diff --git a/wizard/command/_command.py b/wizard/command/_command.py
deleted file mode 100644 (file)
index e5cb0b4..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-import logging
-import os
-import sys
-import optparse
-import errno
-
-import wizard
-
-logging_setup = False
-
-class Error(wizard.Error):
-    """Base error class for all command errors"""
-    pass
-
-class PermissionsError(Error):
-    def __init__(self, dir):
-        self.dir = dir
-    def __str__(self):
-        return """
-
-ERROR: You don't have permissions to access this directory.
-Do you have tokens for AFS with your root instance, and
-is your root instance on scripts-security-upd?
-
-You can check by running the commands 'klist' and
-'blanche scripts-security-upd'.
-"""
-
-class NoSuchDirectoryError(Error):
-    def __init__(self, dir):
-        self.dir = dir
-    def __str__(self):
-        return """
-
-ERROR: No such directory... check your typing
-"""
-
-def chdir(dir):
-    try:
-        os.chdir(dir)
-    except OSError as e:
-        if e.errno == errno.EACCES:
-            raise PermissionsError(dir)
-        elif e.errno == errno.ENOENT:
-            raise NoSuchDirectoryError(dir)
-        else: raise e
-
-def makeLogger(options, numeric_args):
-    global logging_setup
-    if logging_setup: return logging.getLogger()
-    context = " ".join(numeric_args)
-    logger = logging.getLogger()
-    logger.setLevel(logging.INFO)
-    stderr = logging.StreamHandler(sys.stderr)
-    stderr.setFormatter(logging.Formatter(" " * int(options.indent) + '%(levelname)s: %(message)s'))
-    dateFormat = "%H:%M:%S"
-    if options.context:
-        logformatter = logging.Formatter("%(asctime)s %(levelname)s -- " + context + ": %(message)s", dateFormat)
-    else:
-        logformatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)s", dateFormat)
-    if not options.quiet: logger.addHandler(stderr)
-    else: logger.addHandler(NullLogHandler()) # prevent default
-    if options.log_file:
-        file = logging.FileHandler(options.log_file)
-        file.setFormatter(logformatter)
-        logger.addHandler(file)
-        if options.log_file_chmod:
-            os.chmod(options.log_file, int(options.log_file_chmod, 8))
-    if options.debug:
-        logger.setLevel(logging.DEBUG)
-    else:
-        stderr.setLevel(logging.WARNING)
-        if options.verbose or hasattr(options, "dry_run"):
-            stderr.setLevel(logging.INFO)
-        if options.log_file:
-            file.setLevel(logging.INFO)
-    logging_setup = True
-    return logger
-
-def makeBaseArgs(options, **grab):
-    """Takes parsed options, and breaks them back into a command
-    line string that we can pass into a subcommand"""
-    args = []
-    grab["log_file"]= "--log-file"
-    grab["debug"]   = "--debug"
-    grab["verbose"] = "--verbose"
-    grab["indent"]  = "--indent"
-    grab["quiet"]   = "--quiet"
-    #grab["log_db"] = "--log-db"
-    for k,flag in grab.items():
-        value = getattr(options, k)
-        if not value and k != "indent": continue
-        args.append(flag)
-        if type(value) is not bool:
-            if k == "indent":
-                value += 4
-            args.append(str(value))
-    args.append("--context") # always have context for a subcommand
-    return args
-
-class NullLogHandler(logging.Handler):
-    """Log handler that doesn't do anything"""
-    def emit(self, record):
-        pass
-
-class WizardOptionParser(optparse.OptionParser):
-    """Configures some default user-level options"""
-    def __init__(self, *args, **kwargs):
-        kwargs["add_help_option"] = False
-        optparse.OptionParser.__init__(self, *args, **kwargs)
-    def parse_all(self, argv):
-        self.add_option("-h", "--help", action="help", help=optparse.SUPPRESS_HELP)
-        group = optparse.OptionGroup(self, "Common Options")
-        group.add_option("-v", "--verbose", dest="verbose", action="store_true",
-                default=False, help="Turns on verbose output")
-        group.add_option("--debug", dest="debug", action="store_true",
-                default=False, help="Turns on debugging output")
-        group.add_option("-q", "--quiet", dest="quiet", action="store_true",
-                default=False, help="Turns off output to stdout")
-        group.add_option("--log-file", dest="log_file",
-                default=None, help="Logs verbose output to file")
-        group.add_option("--log-file-chmod", dest="log_file_chmod",
-                default=None, help="Chmod the log file after opening.  Number is octal. You must chmod the log file 666 and place the file in /tmp if subprocesses are running as different users.")
-        group.add_option("--indent", dest="indent",
-                default=0, help="Indents stdout, useful for nested calls")
-        group.add_option("--context", dest="context", action="store_true",
-                default=False, help="Adds context to logs, useful for parallel processing")
-        self.add_option_group(group)
-        options, numeric_args = self.parse_args(argv)
-        makeLogger(options, numeric_args)
-        return options, numeric_args
-
-class OptionBaton(object):
-    """Command classes may define options that they sub-commands may
-    use.  Since wizard --global-command subcommand is not a supported
-    mode of operation, these options have to be passed down the command
-    chain until a option parser is ready to take it; this baton is
-    what is passed down."""
-    def __init__(self):
-        self.store = {}
-    def add(self, *args, **kwargs):
-        key = kwargs["dest"] # require this to be set
-        self.store[key] = optparse.make_option(*args, **kwargs)
-    def push(self, option_parser, *args):
-        """Hands off parameters to option parser"""
-        for key in args:
-            option_parser.add_option(self.store[key])
index 04ed70d7a9d389265d65eeec917afc3d04f43462..2fd47d267a79b3a803c01c4133842c551caae6be 100644 (file)
@@ -2,8 +2,7 @@ import optparse
 import sys
 import subprocess
 
-from wizard import deploy
-from wizard import log
+from wizard import deploy, log
 
 def main(argv, baton):
     options, args = parse_args(argv)
index 6c107e0fd75ce53aae68b1df0aa6297914e9cd21..3d034c934e238b2973ae15c12c10b00c2922f958 100644 (file)
@@ -5,11 +5,7 @@ import os.path
 import pwd
 
 import wizard
-from wizard import deploy
-from wizard import util
-from wizard import shell
-from wizard import sset
-from wizard.command import _command
+from wizard import deploy, util, shell, sset, command
 from wizard.command import migrate
 
 def main(argv, baton):
@@ -77,7 +73,7 @@ This command is intended to be run as root on a server with
 the scripts AFS patch.  You may run it as an unpriviledged
 user for testing purposes, but then you MUST NOT run this on
 untrusted repositories."""
-    parser = _command.WizardOptionParser(usage)
+    parser = command.WizardOptionParser(usage)
     parser.add_option("--no-parallelize", dest="no_parallelize", action="store_true",
             default=False, help="Turn off parallelization")
     parser.add_option("--dry-run", dest="dry_run", action="store_true",
@@ -97,7 +93,7 @@ untrusted repositories."""
     return options, args
 
 def calculate_base_args(options):
-    base_args = _command.makeBaseArgs(options, dry_run="--dry-run")
+    base_args = command.makeBaseArgs(options, dry_run="--dry-run")
     if not options.debug:
         base_args.append("--quiet")
     return base_args
index b1459e33b6e0fcff7faaaf3306bc10cd988681d6..cfe461929779b022c452119c14aceecbc40844d3 100644 (file)
@@ -4,10 +4,7 @@ import logging
 import errno
 import sys
 
-from wizard import deploy
-from wizard import shell
-from wizard import util
-from wizard.command import _command
+from wizard import command, deploy, shell, util
 
 def main(argv, baton):
     options, args = parse_args(argv)
@@ -15,7 +12,7 @@ def main(argv, baton):
 
     logging.debug("uid is %d" % os.getuid())
 
-    _command.chdir(dir)
+    command.chdir(dir)
     check_if_already_migrated(options)
 
     version = calculate_version()
@@ -40,7 +37,7 @@ what repository and tag to use.
 This command is meant to be run as the owner of the install
 it is upgrading (see the scripts AFS kernel patch).  Do
 NOT run this command as root."""
-    parser = _command.WizardOptionParser(usage)
+    parser = command.WizardOptionParser(usage)
     parser.add_option("--dry-run", dest="dry_run", action="store_true",
             default=False, help="Prints would would be run without changing anything")
     parser.add_option("--force", "-f", dest="force", action="store_true",
@@ -128,7 +125,7 @@ def make_repository(sh, options, repo, tag):
         except shell.CallError:
             pass
 
-class Error(_command.Error):
+class Error(command.Error):
     """Base exception for all exceptions raised by migrate"""
     pass
 
index 1df876f13501a02f350ed22940c10ff80b94f6bd..d59492c5595775a88ed84d5211dc83fa13ed4256 100644 (file)
@@ -1,13 +1,9 @@
 import optparse
 import os
+import logging
 
-from wizard.command import _command
-
-# submodules
-import list
-import list_errors
-import version
-import count_exists
+import wizard
+from wizard import command, deploy
 
 def main(argv, baton):
     usage = """usage: %prog summary [ARGS] APPS
@@ -22,28 +18,68 @@ Its subcommands are:
     version         Breakdown of autoinstalls by version (default)
 
 Use %prog summary SUBCOMMAND --help for more information."""
-    parser = _command.WizardOptionParser(usage)
+    parser = command.WizardOptionParser(usage)
     parser.disable_interspersed_args()
     baton.push(parser, "versions_path")
     _, args = parser.parse_all(argv)
     rest_argv = args[1:]
     try:
-        command = args[0]
+        command_name = args[0]
     except IndexError:
-        command = "version"
+        command_name = "version"
     def get_command(name):
-        return globals()[name.replace("-", "_")]
+        member = name.replace("-", "_")
+        module = "wizard.command.summary." + member
+        __import__(module)
+        return getattr(wizard.command.summary, member)
     if command == "help":
         try:
             get_command(rest_argv[0]).main(['--help'], baton)
-        except KeyError:
+        except ImportError:
             parser.error("invalid action")
         except IndexError:
             parser.print_help()
             raise SystemExit(1)
     try:
-        command_module = get_command(command)
-    except KeyError:
+        command_module = get_command(command_name)
+    except ImportError:
         parser.error("invalid action")
     command_module.main(rest_argv, baton)
 
+## -- some generic helper stuff --
+
+def parse_install_lines(show, options, yield_errors = False):
+    if not show: show = deploy.applications
+    show = frozenset(show)
+    for line in deploy.getInstallLines(options.versions_path):
+        # construction
+        try:
+            d = deploy.Deployment.parse(line)
+            name = d.application.name
+        except deploy.NoSuchApplication as e:
+            if yield_errors:
+                yield e
+            continue
+        except deploy.Error:
+            # we consider this a worse error
+            logging.warning("Error with '%s'" % line.rstrip())
+            continue
+        # filter
+        if name + "-" + str(d.version) in show or name in show:
+            pass
+        else:
+            continue
+        # yield
+        yield d
+
+class Counter(object):
+    def __init__(self):
+        self.dict = {}
+    def count(self, value):
+        self.dict.setdefault(value, 0)
+        self.dict[value] += 1
+    def __getitem__(self, key):
+        return self.dict[key]
+    def __iter__(self):
+        return self.dict.__iter__()
+
diff --git a/wizard/command/summary/_summary.py b/wizard/command/summary/_summary.py
deleted file mode 100644 (file)
index c68f42a..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-import logging
-
-from wizard import deploy
-
-def parse_install_lines(show, options, yield_errors = False):
-    if not show: show = deploy.applications
-    show = frozenset(show)
-    for line in deploy.getInstallLines(options.versions_path):
-        # construction
-        try:
-            d = deploy.Deployment.parse(line)
-            name = d.application.name
-        except deploy.NoSuchApplication as e:
-            if yield_errors:
-                yield e
-            continue
-        except deploy.Error:
-            # we consider this a worse error
-            logging.warning("Error with '%s'" % line.rstrip())
-            continue
-        # filter
-        if name + "-" + str(d.version) in show or name in show:
-            pass
-        else:
-            continue
-        # yield
-        yield d
-
-class Counter(object):
-    def __init__(self):
-        self.dict = {}
-    def count(self, value):
-        self.dict.setdefault(value, 0)
-        self.dict[value] += 1
-    def __getitem__(self, key):
-        return self.dict[key]
-    def __iter__(self):
-        return self.dict.__iter__()
-
index d3d78ed3ecfa18b7684a2b6e495aba3e405dc394..e9f6eea492329c631f1b819f80d9ffe2e95c5017 100644 (file)
@@ -1,13 +1,13 @@
 import os
 
-from wizard.command import _command
-from wizard.command.summary import _summary
+from wizard import command
+from wizard.command import summary
 
 def main(argv, baton):
     options, args = parse_args(argv, baton)
     value = args[0]
     show = args[1:]
-    for d in _summary.parse_install_lines(show, options):
+    for d in summary.parse_install_lines(show, options):
         if os.path.exists(d.location + "/" + value):
             print d.location
 
@@ -20,7 +20,7 @@ working copy.
 Examples:
     %prog summary count-exists php.ini
         Finds all autoinstalls that contain php.ini files"""
-    parser = _command.WizardOptionParser(usage)
+    parser = command.WizardOptionParser(usage)
     baton.push(parser, "versions_path")
     options, args = parser.parse_all(argv)
     if len(args) > 1:
index 1a1cefaf6118ba507de8bd8d04114cdb26572980..7d3feb1e1c22401b977bdf23c92f20c55ff6cb28 100644 (file)
@@ -1,13 +1,13 @@
 import logging
 import traceback
 
-from wizard.command import _command
-from wizard.command.summary import _summary
+from wizard import command
+from wizard.command import summary
 
 def main(argv, baton):
     options, show = parse_args(argv, baton)
     errors = 0
-    for d in _summary.parse_install_lines(show, options, True):
+    for d in summary.parse_install_lines(show, options, True):
         if isinstance(d, Exception):
             errors += 1
         print d.location
@@ -27,7 +27,7 @@ Examples:
         List only MediaWiki autoinstalls
     %prog summary list mediawiki-1.11.0
         List only Mediawiki 1.11.0 autoinstalls"""
-    parser = _command.WizardOptionParser(usage)
+    parser = command.WizardOptionParser(usage)
     baton.push(parser, "versions_path")
     options, args = parser.parse_all(argv)
     if len(args) > 1:
index ce974dd1a290d837883e9946b9c879c33f40ba74..7a6702fc253a620f5709c342024e71bf3d3210a3 100644 (file)
@@ -1,12 +1,11 @@
 import logging
 
-from wizard import deploy
-from wizard.command import _command
-from wizard.command.summary import _summary
+from wizard import deploy, command
+from wizard.command import summary
 
 def main(argv, baton):
     options, show = parse_args(argv, baton)
-    for e in _summary.parse_install_lines(show, options, True):
+    for e in summary.parse_install_lines(show, options, True):
         if not isinstance(e, deploy.Error):
             if isinstance(e, Exception):
                 raise e
@@ -21,7 +20,7 @@ def parse_args(argv, baton):
 
 Lists all errors that occurred while parsing the versions
 directory."""
-    parser = _command.WizardOptionParser(usage)
+    parser = command.WizardOptionParser(usage)
     baton.push(parser, "versions_path")
     options, args = parser.parse_all(argv)
     if len(args) > 1:
index 5c73afcda64b4db1cf638ba549a8619b832a8be6..09d17ee92fa279d3cf654d17395947d2d33384d0 100644 (file)
@@ -1,15 +1,15 @@
 import math
 
-from wizard.command import _command
-from wizard.command.summary import _summary
+from wizard import command
+from wizard.command import summary
 
 def main(argv, baton):
     options, show = parse_args(argv, baton)
     HISTOGRAM_WIDTH = 30
     show = set()
-    c_version = _summary.Counter()
-    c_application = _summary.Counter()
-    for d in _summary.parse_install_lines(show, options):
+    c_version = summary.Counter()
+    c_application = summary.Counter()
+    for d in summary.parse_install_lines(show, options):
         version = d.app_version
         c_version.count(version)
         c_application.count(version.application)
@@ -35,7 +35,7 @@ Examples:
         Show graphs for all autoinstall versions
     %prog summary list mediawiki
         Show graph for MediaWiki autoinstall versions"""
-    parser = _command.WizardOptionParser(usage)
+    parser = command.WizardOptionParser(usage)
     baton.push(parser, "versions_path")
     options, args = parser.parse_all(argv)
     if len(args) > 1:
index 54f6d5bb19cab1afb4efcb5c12b7cc90f6df3552..eb6a5ac53a42615cd0dd395cf36199cb91294915 100644 (file)
@@ -6,10 +6,7 @@ import logging.handlers
 import errno
 import tempfile
 
-from wizard import deploy
-from wizard import shell
-from wizard import util
-from wizard.command import _command
+from wizard import command, deploy, shell, util
 
 # XXX: WARNING EXPERIMENTAL DANGER DANGER WILL ROBINSON
 
@@ -21,7 +18,7 @@ from wizard.command import _command
 def main(argv, baton):
     options, args = parse_args(argv)
     dir = args[0]
-    _command.chdir(dir)
+    command.chdir(dir)
     if not os.path.isdir(".git"):
         raise NotAutoinstallError()
     try:
@@ -86,7 +83,7 @@ Upgrades an autoinstall to the latest version.  This involves
 updating files and running .scripts/update.
 
 WARNING: This is still experimental."""
-    parser = _command.WizardOptionParser(usage)
+    parser = command.WizardOptionParser(usage)
     parser.add_option("--dry-run", dest="dry_run", action="store_true",
             default=False, help="Prints would would be run without changing anything")
     options, args = parser.parse_all(argv)
@@ -96,7 +93,7 @@ WARNING: This is still experimental."""
         parser.error("must specify directory")
     return options, args
 
-class Error(_command.Error):
+class Error(command.Error):
     """Base exception for all exceptions raised by upgrade"""
     pass
 
index a5a5ee181074e79022beb9e80e1939392976f130..39d15034af567237c9dd957f975f02c077c3706f 100644 (file)
@@ -76,6 +76,9 @@ class Application(object):
         if version not in self.versions:
             self.versions[version] = ApplicationVersion(distutils.version.LooseVersion(version), self)
         return self.versions[version]
+    @staticmethod
+    def make(self, name):
+        pass
 
 class ApplicationVersion(object):
     """Represents an abstract notion of a version for an application"""
index 94fe3cdc6242c58b6045e647189465b70510a076..bf7e172fb1132711ea675156c5da18a4065e73ca 100644 (file)
@@ -3,7 +3,7 @@ import logging
 import sys
 import os
 
-import wizard as _wizard
+import wizard
 from wizard import util
 
 """This is the path to the wizard executable as specified
@@ -110,7 +110,7 @@ class DummyParallelShell(ParallelShell):
     def __init__(self, dry = False):
         super(DummyParallelShell, self).__init__(dry=dry, max=1)
 
-class CallError(_wizard.Error):
+class CallError(wizard.Error):
     def __init__(self, code, args, stdout, stderr):
         self.code = code
         self.args = args
index a1e4a37c2edd517220ba50119e1b58b8f9641de4..95e7bb80c54736cbc7f1f4531757897aa8d27dc8 100644 (file)
@@ -1,46 +1,22 @@
-from wizard.deploy import *
-from distutils.version import LooseVersion as Version
-from datetime import datetime
-from dateutil.tz import tzoffset
-import os.path
+import distutils.version
+import datetime
+import dateutil.tz
 
-def getTestFile(file):
-    return os.path.realpath(os.path.join(__file__, "..", file))
+from wizard import deploy
 
 def test_deployment_parse():
-    result = Deployment.parse("/afs/athena.mit.edu/user/e/z/ezyang/web_scripts/test-wiki:/afs/athena.mit.edu/contrib/scripts/deploy/mediawiki-1.11.0\n")
+    result = deploy.Deployment.parse("/afs/athena.mit.edu/user/e/z/ezyang/web_scripts/test-wiki:/afs/athena.mit.edu/contrib/scripts/deploy/mediawiki-1.11.0\n")
     assert result.location == "/afs/athena.mit.edu/user/e/z/ezyang/web_scripts/test-wiki"
-    assert result.getVersion() == Version("1.11.0")
-    assert result.getApplication().name == "mediawiki"
+    assert result.version == distutils.version.LooseVersion("1.11.0")
+    assert result.application.name == "mediawiki"
 
 def test_deployment_parse_nosuchapplication():
     try:
-        Deployment.parse("a:/foo/obviouslybogus-1.11.0\n")
+        deploy.Deployment.parse("a:/foo/obviouslybogus-1.11.0\n")
         assert False
-    except NoSuchApplication:
+    except deploy.NoSuchApplication:
         pass
 
 def test_deployment_from_dir():
     pass # XXX
 
-def test_deploy_log_load():
-    # this also is test_deploy_source_parse() and test_application_version_parse()
-    log = DeployLog.load(getTestFile("deploy-log"))
-
-    assert log[0].datetime == datetime(2006, 3, 23, 10, 7, 40, tzinfo=tzoffset(None, -5 * 60 * 60))
-    assert log[0].user == "unknown"
-    assert isinstance(log[0].source, TarballInstall)
-    assert log[0].source.location == "/afs/athena.mit.edu/contrib/scripts/deploy/mediawiki.tar.gz"
-    assert log[0].source.isDev == False
-    assert log[0].version == applications["mediawiki"].getVersion('1.5.6')
-
-    assert log[1].datetime == datetime(2007, 10, 17, 3, 38, 2, tzinfo=tzoffset(None, -4 * 60 * 60))
-    assert log[1].user == "quentin@QUICHE-LORRAINE.MIT.EDU"
-    assert isinstance(log[1].source, OldUpdate)
-    assert log[1].source.isDev == True
-    assert log[1].version == applications["mediawiki"].getVersion('1.5.6')
-
-    assert log[2].datetime == datetime(2009, 6, 13, 21, 33, 0, tzinfo=tzoffset(None, -4 * 60 * 60))
-    assert log[2].user == "ezyang@mit.edu"
-    assert isinstance(log[2].source, WizardUpdate)
-    assert log[2].version == applications["mediawiki"].getVersion('1.14.0-scripts')
diff --git a/wizard/tests/log_test.py b/wizard/tests/log_test.py
new file mode 100644 (file)
index 0000000..c075601
--- /dev/null
@@ -0,0 +1,31 @@
+import os.path
+from dateutil.tz import tzoffset
+from datetime import datetime
+
+from wizard import deploy, log
+
+def getTestFile(file):
+    return os.path.realpath(os.path.join(__file__, "..", file))
+
+def test_deploy_log_load():
+    # this also is test_deploy_source_parse() and test_application_version_parse()
+    dlog = log.DeployLog.load(getTestFile("deploy-log"))
+
+    assert dlog[0].datetime == datetime(2006, 3, 23, 10, 7, 40, tzinfo=tzoffset(None, -5 * 60 * 60))
+    assert dlog[0].user == "unknown"
+    assert isinstance(dlog[0].source, log.TarballInstall)
+    assert dlog[0].source.location == "/afs/athena.mit.edu/contrib/scripts/deploy/mediawiki.tar.gz"
+    assert dlog[0].source.isDev == False
+    assert dlog[0].version == deploy.applications["mediawiki"].makeVersion('1.5.6')
+
+    assert dlog[1].datetime == datetime(2007, 10, 17, 3, 38, 2, tzinfo=tzoffset(None, -4 * 60 * 60))
+    assert dlog[1].user == "quentin@QUICHE-LORRAINE.MIT.EDU"
+    assert isinstance(dlog[1].source, log.OldUpdate)
+    assert dlog[1].source.isDev == True
+    assert dlog[1].version == deploy.applications["mediawiki"].makeVersion('1.5.6')
+
+    assert dlog[2].datetime == datetime(2009, 6, 13, 21, 33, 0, tzinfo=tzoffset(None, -4 * 60 * 60))
+    assert dlog[2].user == "ezyang@mit.edu"
+    assert isinstance(dlog[2].source, log.WizardUpdate)
+    assert dlog[2].version == deploy.applications["mediawiki"].makeVersion('1.14.0-scripts')
+