X-Git-Url: https://scripts.mit.edu/gitweb/wizard.git/blobdiff_plain/927306192de34246cb2babe858262e8184a1b57d..30380c4b5b28df9670ea5952e14bc485d1d34133:/wizard/command/install.py diff --git a/wizard/command/install.py b/wizard/command/install.py index faf627b..4ae9058 100644 --- a/wizard/command/install.py +++ b/wizard/command/install.py @@ -1,45 +1,95 @@ import os -import shutil -import logging -import errno import sys +import distutils import wizard -from wizard import command, deploy, shell, util +from wizard import app, command, git, prompt, shell, util +from wizard.install import installopt, interactive def main(argv, baton): - options, args = parse_args(argv) - # XXX: do something smart if -scripts is not at the end - dir = args[0] - if os.path.exists(dir): + old_options, args = parse_args(argv, baton) + + input = prompt.make(old_options.prompt, old_options.non_interactive) + + appstr = args[0] + dir = os.path.abspath(args[1]) + + if not old_options.retry and not old_options.help and os.path.exists(dir) and os.listdir(dir): raise DirectoryExistsError - appname, _, version = options.app.partition('-') - app = deploy.applications()[appname] - sh = shell.Shell() - sh.call("git", "clone", "--shared", app.repository, dir) + + appname, _, version = appstr.partition('-') + application = app.applications()[appname] + + # get configuration + schema = application.install_schema + schema.commit(application, dir) + options = None + opthandler = installopt.Controller(dir, schema) + parser = command.WizardOptionParser("""usage: %%prog install %s DIR [ -- SETUPARGS ] + +Autoinstalls the application %s in the directory DIR.""" % (appname, appname)) + configure_parser(parser, baton) + opthandler.push(parser) + if old_options.help: + parser.print_help() + sys.exit(1) + ihandler = interactive.Controller(dir, schema, input) + options, _ = parser.parse_all(args[2:] + command.make_base_args(old_options)) + if old_options.non_interactive: + opthandler.handle(options) + else: + ihandler.ask(options) + + input.infobox("Copying files (this may take a while)...") + if not os.path.exists(dir): + shell.call("git", "clone", "-q", "--shared", application.repository(old_options.srv_path), dir) with util.ChangeDirectory(dir): - if version: - sh.call("git", "checkout", options.app) - # this command's stdin should be hooked up to ours - try: - sh.call("wizard", "configure", *args[1:], interactive=True) - except shell.PythonCallError: - sys.exit(1) + if not old_options.retry and version and version != "head-scripts": # for ease in testing + shell.call("git", "reset", "-q", "--hard", appstr) + input.infobox("Installing...") + application.install(distutils.version.LooseVersion(version), options) + if not old_options.no_commit: + git.commit_configure() + if not hasattr(options, "web_inferred"): + open(os.path.join(dir, ".scripts/url"), "w").write("http://%s%s" % (options.web_host, options.web_path)) # XXX: no support for https yet! + input.infobox("Congratulations, your new install is now accessible at:\n\nhttp://%s%s" % (options.web_host, options.web_path), width=80) + +def configure_parser(parser, baton): + parser.add_option("--prompt", dest="prompt", action="store_true", + default=False, help="Force to use non-ncurses interactive interface") + parser.add_option("--non-interactive", dest="non_interactive", action="store_true", + default=False, help="Force program to be non-interactive and use SETUPARGS. Use --help with APP to find argument names.") + parser.add_option("--no-commit", dest="no_commit", action="store_true", + default=command.boolish(os.getenv("WIZARD_NO_COMMIT")), help="Do not generate an 'installation commit' after configuring the application. Envvar is WIZARD_NO_COMMIT") + parser.add_option("--retry", dest="retry", action="store_true", + default=False, help="Do not complain if directory already exists and reinstall application.") + baton.push(parser, "srv_path") -def parse_args(argv): - usage = """usage: %prog install [--app APP] [DIR -- [SETUPARGS]] +def parse_args(argv, baton): + usage = """usage: %prog install APP DIR [ -- SETUPARGS ] -Autoinstalls an application.""" - parser = command.WizardOptionParser(usage) - parser.add_option("--app", dest="app", - help="Application to install, optionally specifying a version as APP-VERSION") +Autoinstalls the application APP in the directory DIR. +This command will interactively ask for information to +complete the autoinstall. + +You can also use --help with APP and DIR to find out what +are required SETUPARGS if you want to run this non-interactively +(the distribution of required and optional arguments may change +depending on what directory you are installing to.)""" + parser = command.WizardOptionParser(usage, store_help=True) + configure_parser(parser, baton) options, args = parser.parse_all(argv) - if not args: - # XXX: in the future, not specifying stuff is supported, since - # we'll prompt for it interactively - parser.error("must specify application") + if options.help: + if len(args) == 0: + parser.print_help() + sys.exit(1) + elif len(args) == 1: + args.append(os.getcwd()) + else: + if len(args) < 2: + parser.error("not enough arguments") return options, args class DirectoryExistsError(wizard.Error): def __str__(self): - return "Directory already exists" + return "Directory already exists and is not empty"