]> scripts.mit.edu Git - wizard.git/commitdiff
Add list-errors, fix exceptions, and fix logging bug.
authorEdward Z. Yang <ezyang@mit.edu>
Tue, 28 Jul 2009 03:09:34 +0000 (23:09 -0400)
committerEdward Z. Yang <ezyang@mit.edu>
Tue, 28 Jul 2009 03:09:34 +0000 (23:09 -0400)
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
TODO
wizard/command/_command.py
wizard/command/migrate.py
wizard/command/summary/__init__.py
wizard/command/summary/list.py
wizard/command/summary/list_errors.py [new file with mode: 0644]
wizard/deploy.py

diff --git a/TODO b/TODO
index b726963f7d5cb12946cb97ed405d284477cbe33f..bc6550b314c89a25220640a0fe29dafc35b33542 100644 (file)
--- a/TODO
+++ b/TODO
@@ -2,6 +2,9 @@ The Git Autoinstaller
 
 TODO NOW:
 
 
 TODO NOW:
 
+- Better error message if daemon/scripts-security-upd
+  is not on scripts-security-upd list
+
 - Consider adding user config to repository
 - Put php.ini links in repos (probably will need another
   script in .scripts)
 - Consider adding user config to repository
 - Put php.ini links in repos (probably will need another
   script in .scripts)
index 9c1b6fb2f94128d57d59cb519d49bc5485960bd6..e5cb0b4354f06b3d3c85b2ab9d43c92aa8e16ab8 100644 (file)
@@ -6,6 +6,8 @@ import errno
 
 import wizard
 
 
 import wizard
 
+logging_setup = False
+
 class Error(wizard.Error):
     """Base error class for all command errors"""
     pass
 class Error(wizard.Error):
     """Base error class for all command errors"""
     pass
@@ -44,6 +46,8 @@ def chdir(dir):
         else: raise e
 
 def makeLogger(options, numeric_args):
         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)
     context = " ".join(numeric_args)
     logger = logging.getLogger()
     logger.setLevel(logging.INFO)
@@ -70,6 +74,7 @@ def makeLogger(options, numeric_args):
             stderr.setLevel(logging.INFO)
         if options.log_file:
             file.setLevel(logging.INFO)
             stderr.setLevel(logging.INFO)
         if options.log_file:
             file.setLevel(logging.INFO)
+    logging_setup = True
     return logger
 
 def makeBaseArgs(options, **grab):
     return logger
 
 def makeBaseArgs(options, **grab):
index e289b720c7360af99676bb93216bcd6b17c4c83d..18d0c0870f0c2fe7951e42eccc34d97ed51ebc34 100644 (file)
@@ -152,17 +152,6 @@ ERROR: Could not find .scripts-version file. Are you sure
 this is an autoinstalled application?
 """
 
 this is an autoinstalled application?
 """
 
-class NoRepositoryError(Error):
-    def __init__(self, app):
-        self.app = app
-    def __str__(self):
-        return """
-
-ERROR: Could not find repository for this application. Have
-you converted the repository over? Is the name %s
-the same as the name of the .git folder?
-""" % self.app
-
 class NoTagError(Error):
     def __init__(self, version):
         self.version = version
 class NoTagError(Error):
     def __init__(self, version):
         self.version = version
index 72b5f3f0b3daeec4dc33e8fbdd4de9cefe5af055..b2f7ccc909487d76e721a2fb480163aef5093cfc 100644 (file)
@@ -5,14 +5,10 @@ from wizard.command import _command
 
 # submodules
 import list
 
 # submodules
 import list
+import list_errors
 import version
 import count_exists
 
 import version
 import count_exists
 
-def summary_count_exists(deploys, options, args):
-    for d in deploys:
-        if os.path.exists(d.location + "/" + value):
-            print d.location
-
 def main(argv, baton):
     usage = """usage: %prog summary [ARGS] APPS
 
 def main(argv, baton):
     usage = """usage: %prog summary [ARGS] APPS
 
@@ -22,6 +18,7 @@ calculates interesting information about them.
 Its subcommands are:
     count-exists    Counts how many autoinstalls contain a file
     list            Prints the locations of all autoinstalls
 Its subcommands are:
     count-exists    Counts how many autoinstalls contain a file
     list            Prints the locations of all autoinstalls
+    list-errors     Prints all errors that occurred during parsing
     versions        Breakdown of autoinstalls by version
 
 Use %prog summary SUBCOMMAND --help for more information."""
     versions        Breakdown of autoinstalls by version
 
 Use %prog summary SUBCOMMAND --help for more information."""
index 70f137302227d9ae85481283bb271f77bb329345..1a1cefaf6118ba507de8bd8d04114cdb26572980 100644 (file)
@@ -1,10 +1,18 @@
+import logging
+import traceback
+
 from wizard.command import _command
 from wizard.command.summary import _summary
 
 def main(argv, baton):
     options, show = parse_args(argv, baton)
 from wizard.command import _command
 from wizard.command.summary import _summary
 
 def main(argv, baton):
     options, show = parse_args(argv, baton)
-    for d in _summary.parse_install_lines(show, options):
+    errors = 0
+    for d in _summary.parse_install_lines(show, options, True):
+        if isinstance(d, Exception):
+            errors += 1
         print d.location
         print d.location
+    if errors:
+        logging.warning("%d errors, see wizard summary list-errors for details" % errors)
 
 def parse_args(argv, baton):
     usage = """usage: %prog summary list [ARGS] [APP[-VERSION]]
 
 def parse_args(argv, baton):
     usage = """usage: %prog summary list [ARGS] [APP[-VERSION]]
diff --git a/wizard/command/summary/list_errors.py b/wizard/command/summary/list_errors.py
new file mode 100644 (file)
index 0000000..ce974dd
--- /dev/null
@@ -0,0 +1,30 @@
+import logging
+
+from wizard import deploy
+from wizard.command import _command
+from wizard.command.summary import _summary
+
+def main(argv, baton):
+    options, show = parse_args(argv, baton)
+    for e in _summary.parse_install_lines(show, options, True):
+        if not isinstance(e, deploy.Error):
+            if isinstance(e, Exception):
+                raise e
+            continue
+        if options.verbose:
+            print e
+        else:
+            print e.location
+
+def parse_args(argv, baton):
+    usage = """usage: %prog summary list-errors [ARGS]
+
+Lists all errors that occurred while parsing the versions
+directory."""
+    parser = _command.WizardOptionParser(usage)
+    baton.push(parser, "versions_path")
+    options, args = parser.parse_all(argv)
+    if len(args) > 1:
+        parser.error("too many arguments")
+    return options, args
+
index 3b3f80fb00b17bb53ea26b013fb2223d25a171e5..fce0c3a2fed678c67e77d777f472613f9cb6c3f1 100644 (file)
@@ -32,7 +32,7 @@ class Deployment(object):
             location, deploydir = line.split(":")
         except ValueError:
             return Deployment(line) # lazy loaded version
             location, deploydir = line.split(":")
         except ValueError:
             return Deployment(line) # lazy loaded version
-        return Deployment(location, version=ApplicationVersion.parse(deploydir))
+        return Deployment(location, version=ApplicationVersion.parse(deploydir, location))
     @staticmethod
     def fromDir(dir):
         """Lazily creates a deployment from a directory"""
     @staticmethod
     def fromDir(dir):
         """Lazily creates a deployment from a directory"""
@@ -92,7 +92,7 @@ class DeployLog(list):
         def append(rev):
             if i:
                 if i != 4:
         def append(rev):
             if i:
                 if i != 4:
-                    raise ScriptsVersionNotEnoughFieldsError()
+                    raise ScriptsVersionNotEnoughFieldsError(file)
                 revs.append(rev)
         try:
             fh = open(file)
                 revs.append(rev)
         try:
             fh = open(file)
@@ -116,10 +116,10 @@ class DeployLog(list):
             elif i == 2:
                 rev.source = DeploySource.parse(line)
             elif i == 3:
             elif i == 2:
                 rev.source = DeploySource.parse(line)
             elif i == 3:
-                rev.version = ApplicationVersion.parse(line)
+                rev.version = ApplicationVersion.parse(line, rev.source)
             else:
                 # ruh oh
             else:
                 # ruh oh
-                raise ScriptsVersionTooManyFieldsError()
+                raise ScriptsVersionTooManyFieldsError(file)
             i += 1
         append(rev)
         return DeployLog(revs)
             i += 1
         append(rev)
         return DeployLog(revs)
@@ -206,7 +206,7 @@ class ApplicationVersion(object):
     def __cmp__(x, y):
         return cmp(x.version, y.version)
     @staticmethod
     def __cmp__(x, y):
         return cmp(x.version, y.version)
     @staticmethod
-    def parse(deploydir,applookup=None):
+    def parse(deploydir,location,applookup=None):
         # The version of the deployment, will be:
         #   /afs/athena.mit.edu/contrib/scripts/deploy/APP-x.y.z for old style installs
         #   /afs/athena.mit.edu/contrib/scripts/wizard/srv/APP.git vx.y.z-scripts for new style installs
         # The version of the deployment, will be:
         #   /afs/athena.mit.edu/contrib/scripts/deploy/APP-x.y.z for old style installs
         #   /afs/athena.mit.edu/contrib/scripts/wizard/srv/APP.git vx.y.z-scripts for new style installs
@@ -219,38 +219,58 @@ class ApplicationVersion(object):
                 app, _ = raw_app.split(".") # remove trailing .git
             elif name.find("-") != -1:
                 app, _, version = name.partition("-")
                 app, _ = raw_app.split(".") # remove trailing .git
             elif name.find("-") != -1:
                 app, _, version = name.partition("-")
-            # XXX: this should be removed after the next parallel-find run
-            elif name == "deploy":
-                raise NoSuchApplication()
             else:
             else:
-                raise DeploymentParseError(deploydir)
+                app = name
+                version = "trunk"
         except ValueError: # mostly from the a, b = foo.split(' ')
         except ValueError: # mostly from the a, b = foo.split(' ')
-            raise DeploymentParseError(deploydir)
+            raise DeploymentParseError(deploydir, location)
         if not applookup: applookup = applications
         try:
             # defer to the application for version creation
             return applookup[app].getVersion(version)
         except KeyError:
         if not applookup: applookup = applications
         try:
             # defer to the application for version creation
             return applookup[app].getVersion(version)
         except KeyError:
-            raise NoSuchApplication()
+            raise NoSuchApplication(app, location)
 
 class Error(wizard.Error):
     """Base error class for deploy errors"""
 
 class Error(wizard.Error):
     """Base error class for deploy errors"""
-    pass
+    def __init__(self, location):
+        self.location = location
+    def __str__(self):
+        return "ERROR: Generic error at %s" % self.location
+
+class NoRepositoryError(Error):
+    def __init__(self, app):
+        self.app = app
+        self.location = "unknown"
+    def __str__(self):
+        return """
+
+ERROR: Could not find repository for this application. Have
+you converted the repository over? Is the name %s
+the same as the name of the .git folder?
+""" % self.app
 
 class NoSuchApplication(Error):
 
 class NoSuchApplication(Error):
-    pass
+    def __init__(self, name, location):
+        self.name = name
+        self.location = location
+    def __str__(self):
+        return "ERROR: Unrecognized app '%s' at %s" % (self.name, self.location)
 
 class DeploymentParseError(Error):
 
 class DeploymentParseError(Error):
-    def __init__(self, malformed):
+    def __init__(self, malformed, location):
         self.malformed = malformed
         self.malformed = malformed
+        self.location = location
     def __str__(self):
     def __str__(self):
-        return """
+        return """ERROR: Unparseable '%s' at %s""" % (self.malformed, self.location)
 
 
-ERROR: Could not parse deployment string:
-%s
-""" % self.malformed
+class ScriptsVersionError(Error):
+    """Errors specific to the parsing of a full .scripts-version file
+    (errors that could also be triggered while parsing a parallel-find
+    output should not be this subclass.)"""
+    pass
 
 
-class ScriptsVersionTooManyFieldsError(Error):
+class ScriptsVersionTooManyFieldsError(ScriptsVersionError):
     def __str__(self):
         return """
 
     def __str__(self):
         return """
 
@@ -258,7 +278,7 @@ ERROR: Could not parse .scripts-version file.  It
 contained too many fields.
 """
 
 contained too many fields.
 """
 
-class ScriptsVersionNotEnoughFieldsError(Error):
+class ScriptsVersionNotEnoughFieldsError(ScriptsVersionError):
     def __str__(self):
         return """
 
     def __str__(self):
         return """
 
@@ -266,7 +286,7 @@ ERROR: Could not parse .scripts-version file. It
 didn't contain enough fields.
 """
 
 didn't contain enough fields.
 """
 
-class ScriptsVersionNoSuchFile(Error):
+class ScriptsVersionNoSuchFile(ScriptsVersionError):
     def __init__(self, file):
         self.file = file
     def __str__(self):
     def __init__(self, file):
         self.file = file
     def __str__(self):