]> scripts.mit.edu Git - wizard.git/blob - wizard/command/install.py
Revamp tests, fix minor usability problems with installer.
[wizard.git] / wizard / command / install.py
1 import os
2 import sys
3 import distutils
4
5 import wizard
6 from wizard import app, command, git, prompt, shell, util
7 from wizard.install import installopt, interactive
8
9 def main(argv, baton):
10     old_options, args = parse_args(argv, baton)
11
12     input = prompt.make(old_options.prompt, old_options.non_interactive)
13
14     appstr = args[0]
15     dir = args[1]
16
17     if not old_options.help and os.path.exists(dir) and os.listdir(dir):
18         raise DirectoryExistsError
19
20     appname, _, version = appstr.partition('-')
21     application = app.applications()[appname]
22
23     # get configuration
24     schema = application.install_schema
25     schema.commit(dir)
26     options = None
27     opthandler = installopt.Controller(dir, schema)
28     ihandler = interactive.Controller(dir, schema, input)
29     parser = command.WizardOptionParser("""usage: %%prog install %s DIR [ -- SETUPARGS ]
30
31 Autoinstalls the application %s in the directory DIR.""" % (appname, appname))
32     configure_parser(parser, baton)
33     opthandler.push(parser)
34     if old_options.help:
35         parser.print_help()
36         sys.exit(1)
37     options, _ = parser.parse_all(args[2:] + command.make_base_args(old_options)) # accumulate
38     if old_options.non_interactive:
39         opthandler.handle(options)
40     else:
41         ihandler.ask(options)
42
43     sh = shell.Shell()
44     input.infobox("Copying files (this may take a while)...")
45     sh.call("git", "clone", "-q", "--shared", application.repository(old_options.srv_path), dir)
46     with util.ChangeDirectory(dir):
47         if version and version != "head-scripts": # for ease in testing
48             sh.call("git", "reset", "-q", "--hard", appstr)
49         input.infobox("Installing...")
50         application.install(distutils.version.LooseVersion(version), options)
51         git.commit_configure()
52     input.infobox("Congratulations, your new install is now accessible at:\n\nhttp://%s%s" % (options.web_host, options.web_path), width=80)
53
54 def configure_parser(parser, baton):
55     parser.add_option("--prompt", dest="prompt", action="store_true",
56             default=False, help="Force to use non-ncurses interactive interface")
57     parser.add_option("--non-interactive", dest="non_interactive", action="store_true",
58             default=False, help="Force program to be non-interactive and use SETUPARGS.  Use --help with APP to find argument names.")
59     baton.push(parser, "srv_path")
60
61 def parse_args(argv, baton):
62     usage = """usage: %prog install APP DIR [ -- SETUPARGS ]
63
64 Autoinstalls the application APP in the directory DIR.
65 This command will interactively ask for information to
66 complete the autoinstall.
67
68 You can also use --help with APP and DIR to find out what
69 are required SETUPARGS if you want to run this non-interactively
70 (the distribution of required and optional arguments may change
71 depending on what directory you are installing to.)"""
72     parser = command.WizardOptionParser(usage, store_help=True)
73     configure_parser(parser, baton)
74     options, args = parser.parse_all(argv)
75     if options.help:
76         if len(args) == 0:
77             parser.print_help()
78             sys.exit(1)
79         elif len(args) == 1:
80             args.append(os.getcwd())
81     else:
82         if len(args) < 2:
83             parser.error("not enough arguments")
84     return options, args
85
86 class DirectoryExistsError(wizard.Error):
87     def __str__(self):
88         return "Directory already exists and is not empty"