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