]> scripts.mit.edu Git - wizard.git/blob - wizard/old_log.py
Set admin e-mail address properly on MediaWiki >= 1.18.0
[wizard.git] / wizard / old_log.py
1 import os.path
2 import sys
3 import dateutil.parser
4
5 import wizard
6 from wizard import app
7 import wizard.deploy # to break circular loop
8
9 # This code operates off of the assumption of .scripts-version, which
10 # is not true.
11
12 class DeployLog(list):
13     # As per #python; if you decide to start overloading magic methods,
14     # we should remove this subclass
15     """Equivalent to .scripts-version: a series of DeployRevisions."""
16     def __init__(self, revs = []):
17         """`revs`  List of DeployRevision objects"""
18         list.__init__(self, revs) # pass to list
19     def __repr__(self):
20         return '<DeployLog %s>' % list.__repr__(self)
21     @staticmethod
22     def load(deployment):
23         """Loads a scripts version file and parses it into
24         DeployLog and DeployRevision objects"""
25         # XXX: DIRTY DIRTY HACK
26         # What we should actually do is parse the git logs
27         file = deployment.old_version_file
28         i = 0
29         rev = DeployRevision()
30         revs = []
31         def append(rev):
32             if i:
33                 if i != 4:
34                     raise ScriptsVersionNotEnoughFieldsError(file)
35                 revs.append(rev)
36         try:
37             fh = open(file)
38         except IOError:
39             raise ScriptsVersionNoSuchFile(file)
40         for line in fh:
41             line = line.rstrip()
42             if not line:
43                 append(rev)
44                 i = 0
45                 rev = DeployRevision()
46                 continue
47             if i == 0:
48                 # we need the dateutil parser in order to
49                 # be able to parse time offsets
50                 rev.datetime = dateutil.parser.parse(line)
51             elif i == 1:
52                 rev.user = line
53             elif i == 2:
54                 rev.source = DeploySource.parse(line)
55             elif i == 3:
56                 try:
57                     rev.version = app.ApplicationVersion.parse(line)
58                 except (wizard.deploy.Error, app.Error) as e:
59                     e.location = deployment.location
60                     raise e, None, sys.exc_info()[2]
61             else:
62                 # ruh oh
63                 raise ScriptsVersionTooManyFieldsError(file)
64             i += 1
65         append(rev)
66         return DeployLog(revs)
67
68 class DeployRevision(object):
69     """A single entry in the .scripts-version file. Contains who deployed
70     this revision, what application version this is, etc."""
71     def __init__(self, datetime=None, user=None, source=None, version=None):
72         """ `datetime`  Time this revision was deployed
73             `user`      Person who deployed this revision, in ``user@host`` format.
74             `source`    Instance of :class:`DeploySource`
75             `version`   Instance of :class:`app.ApplicationVersion`
76         Note: This object is typically built incrementally."""
77         self.datetime = datetime
78         self.user = user
79         self.source = source
80         self.version = version
81
82 class DeploySource(object):
83     """Source of the deployment; see subclasses for examples"""
84     def __init__(self):
85         raise NotImplementedError # abstract class
86     @staticmethod
87     def parse(line):
88         # munge out common prefix
89         rel = os.path.relpath(line, "/afs/athena.mit.edu/contrib/scripts/")
90         parts = rel.split("/")
91         if parts[0] == "wizard":
92             return WizardUpdate()
93         elif parts[0] == "deploy" or parts[0] == "deploydev":
94             isDev = ( parts[0] == "deploydev" )
95             try:
96                 if parts[1] == "updates":
97                     return OldUpdate(isDev)
98                 else:
99                     return TarballInstall(line, isDev)
100             except IndexError:
101                 pass
102         return UnknownDeploySource(line)
103
104 class TarballInstall(DeploySource):
105     """Original installation from tarball, characterized by
106     /afs/athena.mit.edu/contrib/scripts/deploy/APP-x.y.z.tar.gz
107     """
108     def __init__(self, location, isDev):
109         self.location = location
110         self.isDev = isDev
111
112 class OldUpdate(DeploySource):
113     """Upgrade using old upgrade infrastructure, characterized by
114     /afs/athena.mit.edu/contrib/scripts/deploydev/updates/update-scripts-version.pl
115     """
116     def __init__(self, isDev):
117         self.isDev = isDev
118
119 class WizardUpdate(DeploySource):
120     """Upgrade using wizard infrastructure, characterized by
121     /afs/athena.mit.edu/contrib/scripts/wizard/bin/wizard HASHGOBBLEDYGOOK
122     """
123     def __init__(self):
124         pass
125
126 class UnknownDeploySource(DeploySource):
127     """Deployment that we don't know the meaning of. Wot!"""
128     def __init__(self, line):
129         self.line = line
130
131 ## -- Exceptions --
132
133 class Error(wizard.Error):
134     """Base error class for log errors."""
135     pass
136
137 class ScriptsVersionError(Error):
138     """Errors specific to the parsing of a full .scripts-version file
139     (errors that could also be triggered while parsing a parallel-find
140     output should not be this subclass.)"""
141     pass
142
143 class ScriptsVersionTooManyFieldsError(ScriptsVersionError):
144     def __str__(self):
145         return """
146
147 ERROR: Could not parse .scripts-version file.  It
148 contained too many fields.
149 """
150
151 class ScriptsVersionNotEnoughFieldsError(ScriptsVersionError):
152     def __str__(self):
153         return """
154
155 ERROR: Could not parse .scripts-version file. It
156 didn't contain enough fields.
157 """
158
159 class ScriptsVersionNoSuchFile(ScriptsVersionError):
160     def __init__(self, file):
161         self.file = file
162     def __str__(self):
163         return """
164
165 ERROR: File %s didn't exist.
166 """ % self.file
167