]> scripts.mit.edu Git - wizard.git/blob - wizard/command/upgrade.py
Explicitly specify branch to pull and merge.
[wizard.git] / wizard / command / upgrade.py
1 import optparse
2 import sys
3 import os
4 import shutil
5 import logging.handlers
6 import errno
7 import tempfile
8
9 from wizard import deploy
10 from wizard import shell
11 from wizard import util
12 from wizard.command import _base
13
14 # XXX: WARNING EXPERIMENTAL DANGER DANGER WILL ROBINSON
15
16 # need errors for checking DAG integrity (if the user is on a completely
17 # different history tree, stuff is problems)
18
19 # we need an option that specifies the person making the update. Since n-b
20 # doesn't actually have a way to do this, username is probably what we want.
21 def main(argv, global_options):
22     options, args = parse_args(argv)
23     dir = args[0]
24     _base.chdir(dir)
25     if not os.path.isdir(".git"):
26         raise NotAutoinstallError()
27     try:
28         d = deploy.Deployment.fromDir(".")
29     except IOError as e:
30         if e.errno == errno.ENOENT:
31             raise NotAutoinstallError()
32         else: raise e
33     repo = d.getApplication().getRepository()
34     # begin the command line process
35     sh = shell.Shell(options.dry_run)
36     # setup environment
37     util.set_git_env()
38     # commit their changes
39     message = "Pre-upgrade commit.\n\n" + util.get_git_footer()
40     try:
41         message += "\nPre-commit-by: " + util.get_operator_git()
42     except util.NoOperatorInfo:
43         pass
44     try:
45         sh.call("git", "commit", "-a", "-m", "Pre-upgrade commit.")
46     except shell.CallError:
47         logging.info("No changes detected")
48         pass
49     # perform fetch to update repository state
50     sh.call("git", "fetch", repo)
51     # clone their website to a temporary directory
52     temp_dir = tempfile.mkdtemp()
53     temp_wc_dir = os.path.join(temp_dir, "repo")
54     logging.info("Using temporary directory: " + temp_wc_dir)
55     sh.call("git", "clone", "--shared", ".", temp_wc_dir)
56     with util.ChangeDirectory(temp_wc_dir):
57         # reconfigure the repository path
58         sh.call("git", "remote", "add", "scripts", repo)
59         sh.call("git", "fetch", "scripts")
60         # perform the merge
61         try:
62             message = "Upgraded deployment.\n\n" + util.get_git_footer()
63             try:
64                 message += "\nUpgraded-by: " + util.get_operator_git()
65             except util.NoOperatorInfo:
66                 pass
67             sh.call("git", "merge", "-m", message, "scripts/master")
68         except shell.CallError:
69             raise MergeFailed
70     # XXX: frob .htaccess to make site inaccessible
71     # git merge (which performs a fast forward)
72     #   - merge could fail (race)
73     sh.call("git", "pull", temp_wc_dir, "master")
74     # run update script
75     sh.call(".scripts/update")
76     # XXX: frob .htaccess to make site accessible
77     # XXX:  - check if .htaccess changed, first.  Upgrade
78     #       process might have frobbed it.  Don't be
79     #       particularly worried if the segment dissappeared
80
81 def parse_args(argv):
82     usage = """usage: %prog upgrade [ARGS] DIR
83
84 Upgrades an autoinstall ot the latest version.  This involves
85 updating files and running .scripts/update.
86
87 WARNING: This is still experimental."""
88     parser = _base.WizardOptionParser(usage)
89     parser.add_option("--dry-run", dest="dry_run", action="store_true",
90             default=False, help="Prints would would be run without changing anything")
91     options, args = parser.parse_all(argv)
92     if len(args) > 1:
93         parser.error("too many arguments")
94     elif not args:
95         parser.error("must specify directory")
96     return options, args
97
98 class Error(_base.Error):
99     """Base exception for all exceptions raised by upgrade"""
100     pass
101
102 class NotAutoinstallError(Error):
103     def __str__(self):
104         return """
105
106 ERROR: Could not find .git file. Are you sure
107 this is an autoinstalled application? Did you remember
108 to migrate it?
109 """
110
111 class MergeFailed(Error):
112     pass