Example #1
0
def _ask_command(command):
    if not console_utils.stdin_is_interactive():
        return None

    if platform.system() == 'Windows':
        other = 'windows'
    else:
        other = 'unix'
    choices = {'b': 'bokeh_app', 'c': other, 'n': 'notebook'}

    while True:
        data = console_utils.console_input(
            "Is `{}` a (B)okeh app, (N)otebook, or (C)ommand line? ".format(
                command))
        data = data.lower().strip()

        if len(data) == 0 or data[0] not in choices:
            print("Please enter 'b', 'n', or 'c'.")
            print(
                "    A Bokeh app is the project-relative path to a Bokeh script or app directory."
            )
            print(
                "    A notebook file is the project-relative path to a .ipynb file."
            )
            print(
                "    A command line is any command you might type at the command prompt."
            )
            continue

        return choices[data]
Example #2
0
def load_project(dirname):
    """Load a Project, fixing it if needed and possible."""
    project = Project(dirname, frontend=CliFrontend(), must_exist=True)

    # No sense in engaging the user if we cannot achieve a fixed state.
    if project.unfixable_problems:
        return project

    if console_utils.stdin_is_interactive():
        regressions = 0
        problems = project.fixable_problems
        while problems and regressions < 3:
            # Instead of looping through the problems in the list, we
            # fix only the first one and refresh the list. This allows
            # us to detect when fixing one problem impacts another,
            # positively or negatively.
            problem = problems[0]
            print(problem.text)
            should_fix = console_utils.console_ask_yes_or_no(problem.fix_prompt, default=False)
            if not should_fix:
                break
            problem.fix(project)
            project.use_changes_without_saving()
            o_problems, problems = problems, project.fixable_problems
            # If the number of problems doesn't decrease as a result of
            # fixing a problem, it suggests some sort of negative cycle.
            # We can't reliably detect a cycle, so instead we simply let
            # this happen 3 times before we give up.
            regressions += (len(problems) >= len(o_problems))
        if not problems:
            project.save()

    return project
Example #3
0
def _interactively_fix_missing_variables(project, result):
    """Return True if we need to re-prepare."""
    if project.problems:
        return False

    if not console_utils.stdin_is_interactive():
        return False

    # We don't ask the user to manually enter CONDA_PREFIX
    # (CondaEnvRequirement) because it's a bizarre/confusing
    # thing to ask.
    can_ask_about = [
        status for status in result.statuses
        if (not status and isinstance(status.requirement, EnvVarRequirement)
            and not isinstance(status.requirement, CondaEnvRequirement))
    ]

    if can_ask_about:
        print("(Use Ctrl+C to quit.)")

    start_over = False
    values = dict()
    for status in can_ask_about:
        reply = console_utils.console_input(
            "Value for " + status.requirement.env_var + ": ",
            encrypted=status.requirement.encrypted)
        if reply is None:
            return False  # EOF
        reply = reply.strip()
        if reply == '':
            start_over = True
            break
        values[status.requirement.env_var] = reply

    if len(values) > 0:
        status = project_ops.set_variables(project, result.env_spec_name,
                                           values.items(), result)
        if status:
            return True
        else:
            console_utils.print_status_errors(status)
            return False
    else:
        return start_over
def load_project(dirname):
    """Load a Project, fixing it if needed and possible."""
    project = Project(dirname, frontend=CliFrontend())

    if console_utils.stdin_is_interactive():
        had_fixable = len(project.fixable_problems) > 0
        for problem in project.fixable_problems:
            print(problem.text)
            should_fix = console_utils.console_ask_yes_or_no(problem.fix_prompt, default=False)
            if should_fix:
                problem.fix(project)
            else:
                problem.no_fix(project)

        # both fix() and no_fix() can modify project_file, if no changes
        # were made this is a no-op.
        if had_fixable:
            project.save()

    return project
Example #5
0
def test_stdin_is_interactive(monkeypatch):
    result = console_utils.stdin_is_interactive()
    assert result is True or result is False
def handle_bugs(main_func, program_name, details_dict):
    """Invoke main entry point, handling uncaught exceptions.

    Args:
        main_func (function): a main()-style function returning an exit status
        program_name (str): name of the app
        details_dict (dict): dictionary of stuff to include in the bug report file

    Returns:
        an exit status code from main_func or 1 on uncaught exception
    """
    slugified_program_name = slugify(program_name)

    try:
        return main_func()
    except KeyboardInterrupt:
        # KeyboardInterrupt doesn't derive from Exception, but the default handler
        # prints a stack trace which is sort of ugly, so we replace the default
        # with this.
        print("%s was interrupted." % program_name, file=sys.stderr)
        return 1
    except Exception:
        (exception_type, exception_value, exception_trace) = sys.exc_info()

        try:
            import datetime
            import pprint
            import tempfile
            import traceback

            print("An unexpected error occurred, most likely a bug in %s." %
                  program_name,
                  file=sys.stderr)
            print("    (The error was: %s: %s)" %
                  (exception_type.__name__, str(exception_value)),
                  file=sys.stderr)

            # so batch jobs have the details in their logs
            output_to_console = not console_utils.stdin_is_interactive()

            when = datetime.date.today().isoformat()
            prefix = "bug_details_%s_%s_" % (slugified_program_name, when)
            with tempfile.NamedTemporaryFile(prefix=prefix,
                                             suffix=".txt",
                                             delete=False) as bugfile:
                report_name = bugfile.name

                def output(s):
                    bugfile.write(s.encode('utf-8'))
                    bugfile.write("\n".encode('utf-8'))
                    if output_to_console:
                        print(s, file=sys.stderr)

                output("Bug details for %s error on %s" % (program_name, when))
                output("")
                output("sys.argv: %r" % sys.argv)
                output("")
                output(pprint.pformat(details_dict))
                output("")
                output("\n".join(
                    traceback.format_exception(exception_type, exception_value,
                                               exception_trace)))

            if output_to_console:
                print("Above details were also saved to %s" % report_name,
                      file=sys.stderr)
            else:
                print("Details about the error were saved to %s" % report_name,
                      file=sys.stderr)
        except Exception:
            # re-raise the original exception, which is probably more useful
            # than reporting whatever was broken about our bug handling code
            # above.
            raise exception_value

        # exit code
        return 1