From 2a40f8ef842a45a0277bd3b425bbf66888708d00 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Fri, 26 Jun 2009 00:29:53 -0400 Subject: [PATCH] Major refactoring of modules and packages to enforce Google style guide. Signed-off-by: Edward Z. Yang --- TODO | 2 ++ lib/wizard/__init__.py | 36 ++----------------- lib/wizard/command/__init__.py | 1 + lib/wizard/command/_base.py | 38 ++++++++++++++++++++ lib/wizard/command/info.py | 10 +++--- lib/wizard/command/massmigrate.py | 29 +++++++--------- lib/wizard/command/migrate.py | 58 +++++++++++++++++-------------- lib/wizard/command/summary.py | 27 +++++++------- 8 files changed, 107 insertions(+), 94 deletions(-) create mode 100644 lib/wizard/command/_base.py diff --git a/TODO b/TODO index 09eb63e..91520c4 100644 --- a/TODO +++ b/TODO @@ -2,6 +2,8 @@ The Git Autoinstaller TODO NOW: +- Check how many autoinstalls are missing w bits for + daemon.scripts - Whiteboard the flow for performing an upgrade on a single install. How assisted does it need to be? - Conduct migration tool testing (check andersk, geofft for diff --git a/lib/wizard/__init__.py b/lib/wizard/__init__.py index f9fbb9f..9a7d216 100644 --- a/lib/wizard/__init__.py +++ b/lib/wizard/__init__.py @@ -1,36 +1,4 @@ -import logging -import sys -import optparse - -def makeLogger(options): - logger = logging.getLogger("main") - logger.setLevel(logging.INFO) - stdout = logging.StreamHandler(sys.stdout) - logger.addHandler(stdout) - if options.verbose: - logger.verbose = True - else: - if not options.debug: stdout.setLevel(logging.ERROR) - if options.debug: logger.setLevel(logging.DEBUG) - return logger - -class UserException(Exception): - """User friendly exceptions inherit from here""" +class Error(Exception): + """Base exception for all Wizard exceptions""" pass -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): - optparse.OptionParser.__init__(self, *args, **kwargs) - self.add_option("-v", "--verbose", dest="verbose", action="store_true", - default=False, help="Turns on verbose output") - self.add_option("--debug", dest="debug", action="store_true", - default=False, help="Turns on debugging output") - def parse_all(self, argv, logger): - options, numeric_args = self.parse_args(argv) - return options, numeric_args, logger and logger or makeLogger(options) diff --git a/lib/wizard/command/__init__.py b/lib/wizard/command/__init__.py index 7b5f36b..f675b96 100644 --- a/lib/wizard/command/__init__.py +++ b/lib/wizard/command/__init__.py @@ -2,3 +2,4 @@ from info import info from migrate import migrate from summary import summary from massmigrate import massmigrate + diff --git a/lib/wizard/command/_base.py b/lib/wizard/command/_base.py new file mode 100644 index 0000000..2ba6e2f --- /dev/null +++ b/lib/wizard/command/_base.py @@ -0,0 +1,38 @@ +import logging +import sys +import optparse + +import wizard + +class Error(wizard.Error): + """Base error class for all command errors""" + pass + +def makeLogger(options): + logger = logging.getLogger("main") + logger.setLevel(logging.INFO) + stdout = logging.StreamHandler(sys.stdout) + logger.addHandler(stdout) + if options.verbose: + logger.verbose = True + else: + if not options.debug: stdout.setLevel(logging.ERROR) + if options.debug: logger.setLevel(logging.DEBUG) + return logger + +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): + optparse.OptionParser.__init__(self, *args, **kwargs) + self.add_option("-v", "--verbose", dest="verbose", action="store_true", + default=False, help="Turns on verbose output") + self.add_option("--debug", dest="debug", action="store_true", + default=False, help="Turns on debugging output") + def parse_all(self, argv, logger): + options, numeric_args = self.parse_args(argv) + return options, numeric_args, logger and logger or makeLogger(options) diff --git a/lib/wizard/command/info.py b/lib/wizard/command/info.py index ec4331e..14c04c2 100644 --- a/lib/wizard/command/info.py +++ b/lib/wizard/command/info.py @@ -2,7 +2,7 @@ import optparse import sys import subprocess -import wizard.deploy as wd +from wizard import deploy def prettify(loc): return loc.replace("/afs/athena.mit.edu/contrib/scripts", "~scripts") @@ -24,8 +24,8 @@ including its history and current version.""" parser.error("too many arguments") elif not args: parser.error("must specify directory") - deploy = wd.Deployment.fromDir(args[0]) - deploy.getLog() # force the log to be loaded, to pre-empt errors + d = deploy.Deployment.fromDir(args[0]) + d.getLog() # force the log to be loaded, to pre-empt errors proc = False # This is prime candidate for refactoring. This code pipes # stdout to less, so that you get scrolling and stuff. @@ -35,13 +35,13 @@ including its history and current version.""" try: if options.reverse: munge = lambda x: x else: munge = reversed - for entry in munge(deploy.getLog()): + for entry in munge(d.getLog()): print "%s %s" % (entry.version.application.name, entry.version.version) print "User: %s" % entry.user print "Date: %s" % entry.datetime.strftime("%a %b %0d %H:%M:%S %Y %z") print info = "Unknown" - if isinstance(entry.source, wd.TarballInstall): + if isinstance(entry.source, deploy.TarballInstall): info = "Installed with tarball at:\n%s" % \ prettify(entry.source.location) print indent(info, 4) diff --git a/lib/wizard/command/massmigrate.py b/lib/wizard/command/massmigrate.py index b751194..9b5de9a 100644 --- a/lib/wizard/command/massmigrate.py +++ b/lib/wizard/command/massmigrate.py @@ -1,12 +1,9 @@ import optparse -import sys -import os -import shutil +from wizard import deploy + +import _base import migrate -import wizard.deploy as wd -import wizard.shell as sh -from wizard import * def massmigrate(argv, global_options, logger = None): usage = """usage: %prog massmigrate [ARGS] APPLICATION @@ -18,7 +15,7 @@ but with advanced reporting. NOTE: --verbose implies --no-parallelize, as it results in output going to stdout/stderr.""" - parser = WizardOptionParser(usage) + parser = _base.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", @@ -35,27 +32,27 @@ output going to stdout/stderr.""" if options.verbose: base_args.append("--verbose") if options.dry_run: base_args.append("--dry-run") deploys = [] - for line in wd.getInstallLines(global_options): + for line in deploy.getInstallLines(global_options): try: - deploy = wd.Deployment.parse(line) - except wd.DeploymentParseError, wd.NoSuchApplication: + d = deploy.Deployment.parse(line) + except deploy.DeploymentParseError, deploy.NoSuchApplication: continue - name = deploy.getApplication().name + name = d.getApplication().name if name != app: continue - deploys.append(deploy) + deploys.append(d) # parallelization code would go here errors = {} - for deploy in deploys: - sub_argv = base_args + [deploy.location] + for d in deploys: + sub_argv = base_args + [d.location] logger.info("$ wizard migrate " + " ".join(sub_argv)) try: migrate.migrate(sub_argv, global_options, logger) except migrate.AlreadyMigratedError as e: logger.info("Skipped already migrated %s" % d.location) - except UserException as e: + except migrate.Error as e: name = e.__class__.__name__ if name not in errors: errors[name] = [] - errors[name].append(deploy) + errors[name].append(d) logger.error("ERROR [%s] in %s" % (name, d.location)) for name, deploys in errors.items(): logger.warning("ERROR [%s] from %d installs" % (name, len(deploys))) diff --git a/lib/wizard/command/migrate.py b/lib/wizard/command/migrate.py index 056d448..9b5bcd5 100644 --- a/lib/wizard/command/migrate.py +++ b/lib/wizard/command/migrate.py @@ -4,11 +4,17 @@ import os import shutil import logging.handlers -from wizard import * -import wizard.deploy as wd -import wizard.shell as sh +from wizard import deploy +from wizard import shell -class PermissionsError(UserException): +import _base +import wizard + +class Error(_base.Error): + """Base exception for all exceptions raised by migrate""" + pass + +class PermissionsError(Error): def __init__(self, dir): self.dir = dir def __str__(self): @@ -25,7 +31,7 @@ at /mit/nelhage/Public/krbroot (for which you run 'krbroot shell' and then 'aklog'). """ -class NoSuchDirectoryError(UserException): +class NoSuchDirectoryError(Error): def __init__(self, dir): self.dir = dir def __str__(self): @@ -34,7 +40,7 @@ class NoSuchDirectoryError(UserException): ERROR: No such directory... check your typing """ -class AlreadyMigratedError(UserException): +class AlreadyMigratedError(Error): def __init__(self, dir): self.dir = dir def __str__(self): @@ -44,7 +50,7 @@ ERROR: Directory already contains a .git directory. Did you already migrate it? """ -class NotAutoinstallError(UserException): +class NotAutoinstallError(Error): def __init__(self, dir): self.dir = dir def __str__(self): @@ -54,7 +60,7 @@ ERROR: Could not find .scripts-version file. Are you sure this is an autoinstalled application? """ -class NoRepositoryError(UserException): +class NoRepositoryError(Error): def __init__(self, app): self.app = app def __str__(self): @@ -65,7 +71,7 @@ you converted the repository over? Is the name %s the same as the name of the .git folder? """ % self.app -class NoTagError(UserException): +class NoTagError(Error): def __init__(self, version): self.version = version def __str__(self): @@ -82,7 +88,7 @@ def migrate(argv, global_options, logger = None): Migrates a directory to our Git-based autoinstall format. Performs basic sanity checking and intelligently determines what repository and tag to use.""" - parser = WizardOptionParser(usage) + parser = _base.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", @@ -112,8 +118,8 @@ what repository and tag to use.""" logger.warning("Force removing .scripts directory") if not options.dry_run: shutil.rmtree(".scripts") try: - deploy = wd.Deployment.fromDir(".") - version = deploy.getAppVersion() + d = deploy.Deployment.fromDir(".") + version = d.getAppVersion() except IOError as e: if e.errno == 2: raise NotAutoinstallError(dir) @@ -125,43 +131,43 @@ what repository and tag to use.""" if not os.path.isdir(repo): raise NoRepositoryError(app) # begin the command line process - shell = sh.Shell(logger, options.dry_run) + sh = shell.Shell(logger, options.dry_run) # check if the version we're trying to convert exists. We assume # a convention here, namely, v1.2.3-scripts is what we want. If # you broke the convention... shame on you. try: tag = "v%s-scripts" % version.version - shell.call("git", "--git-dir", repo, "rev-parse", tag) - except sh.CalledProcessError: + sh.call("git", "--git-dir", repo, "rev-parse", tag) + except shell.CalledProcessError: raise NoTagError(version) did_git_init = False did_git_checkout_scripts = False try: # create repository - shell.call("git", "--git-dir=.git", "init") + sh.call("git", "--git-dir=.git", "init") did_git_init = True # configure our remote - shell.call("git", "remote", "add", "origin", repo) + sh.call("git", "remote", "add", "origin", repo) # configure what would normally be set up on a 'git clone' for consistency - shell.call("git", "config", "branch.master.remote", "origin") - shell.call("git", "config", "branch.master.merge", "refs/heads/master") + sh.call("git", "config", "branch.master.remote", "origin") + sh.call("git", "config", "branch.master.merge", "refs/heads/master") # perform the initial fetch - shell.call("git", "fetch", "origin") + sh.call("git", "fetch", "origin") # soft reset to our tag - shell.call("git", "reset", tag, "--") + sh.call("git", "reset", tag, "--") # checkout the .scripts directory - shell.call("git", "checkout", ".scripts") + sh.call("git", "checkout", ".scripts") did_git_checkout_scripts = True # XXX: setup .scripts/version??? # for verbose purposes, give us a git status and git diff if options.verbose: - shell.call("git", "status") - shell.call("git", "diff") + sh.call("git", "status") + sh.call("git", "diff") except: # this... is pretty bad logger.critical("ERROR: Exception detected! Rolling back...") if did_git_init: - shell.call("rm", "-Rf", ".git") + sh.call("rm", "-Rf", ".git") if did_git_checkout_scripts: - shell.call("rm", "-Rf", ".scripts") + sh.call("rm", "-Rf", ".scripts") raise diff --git a/lib/wizard/command/summary.py b/lib/wizard/command/summary.py index 2672403..6f25401 100644 --- a/lib/wizard/command/summary.py +++ b/lib/wizard/command/summary.py @@ -1,7 +1,8 @@ import optparse -import wizard.deploy as wd import sys +from wizard import deploy + # XXX: Migrate this to use logger class Printer(object): def __init__(self, quiet, verbose): @@ -57,8 +58,8 @@ Examples: 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() + fi = deploy.getInstallLines(global_options) + if not show: show = deploy.applications.keys() show = frozenset(show) errors = 0 unrecognized = 0 @@ -68,28 +69,28 @@ Examples: for line in fi: printer.tick() try: - deploy = wd.Deployment.parse(line) - except wd.DeploymentParseError: + d = deploy.Deployment.parse(line) + except deploy.DeploymentParseError: errors += 1 continue - except wd.NoSuchApplication: + except deploy.NoSuchApplication: unrecognized += 1 continue - name = deploy.getApplication().name - if name + "-" + str(deploy.getVersion()) in show: + name = d.getApplication().name + if name + "-" + str(d.getVersion()) in show: printer.write("%s-%s deployment at %s" \ - % (name, deploy.getVersion(), deploy.location)) + % (name, d.getVersion(), d.location)) elif name in show: pass else: continue - deploy.count() + d.count() if options.count_exists: - r = deploy.count_exists(options.count_exists) + r = d.count_exists(options.count_exists) if r: - printer.chat("Found " + options.count_exists + " in " + deploy.location) + printer.chat("Found " + options.count_exists + " in " + d.location) printer.write() - for app in wd.applications.values(): + for app in deploy.applications.values(): if app.name not in show: continue printer.write(app.report()) printer.write() -- 2.45.2