コード例 #1
0
def _run_dispatcher(dispatcher: craft_cli.Dispatcher) -> None:
    global_args = dispatcher.pre_parse_args(sys.argv[1:])
    if global_args.get("version"):
        emit.message(f"snapcraft {__version__}")
    else:
        if global_args.get("trace"):
            emit.message(
                "Options -t and --trace are deprecated, use --verbosity=debug instead."
            )
            emit.set_mode(EmitterMode.DEBUG)

        dispatcher.load_command(None)
        dispatcher.run()
    emit.ended_ok()
コード例 #2
0
def run():
    """Run the CLI."""
    dispatcher = get_dispatcher()
    try:
        _run_dispatcher(dispatcher)
        retcode = 0
    except ArgumentParsingError as err:
        # TODO https://github.com/canonical/craft-cli/issues/78
        with contextlib.suppress(KeyError, IndexError):
            if (
                err.__context__ is not None
                and err.__context__.args[0]  # pylint: disable=no-member
                not in dispatcher.commands
            ):
                run_legacy(err)
        print(err, file=sys.stderr)  # to stderr, as argparse normally does
        emit.ended_ok()
        retcode = 1
    except ProvideHelpException as err:
        print(err, file=sys.stderr)  # to stderr, as argparse normally does
        emit.ended_ok()
        retcode = 0
    except errors.LegacyFallback as err:
        run_legacy(err)
    except craft_store.errors.NoKeyringError as err:
        emit.error(
            craft_cli.errors.CraftError(
                f"craft-store error: {err}",
                resolution=(
                    "Ensure the keyring is working or "
                    f"{store.constants.ENVIRONMENT_STORE_CREDENTIALS} "
                    "is correctly exported into the environment"
                ),
                docs_url="https://snapcraft.io/docs/snapcraft-authentication",
            )
        )
        retcode = 1
    except craft_store.errors.CraftStoreError as err:
        emit.error(craft_cli.errors.CraftError(f"craft-store error: {err}"))
        retcode = 1
    except errors.LinterError as err:
        emit.error(craft_cli.errors.CraftError(f"linter error: {err}"))
        retcode = err.exit_code
    except errors.SnapcraftError as err:
        emit.error(err)
        retcode = 1

    return retcode
コード例 #3
0
ファイル: legacy_cli.py プロジェクト: snapcore/snapcraft
def run_legacy(err: Optional[Exception] = None):
    """Run legacy implementation."""
    # Reset the libraries to their original log level
    for lib_name in _LIB_NAMES:
        logger = logging.getLogger(lib_name)
        logger.setLevel(_ORIGINAL_LIB_NAME_LOG_LEVEL[lib_name])

    snapcraft.BasePlugin = snapcraft_legacy.BasePlugin  # type: ignore
    snapcraft.ProjectOptions = snapcraft_legacy.ProjectOptions  # type: ignore

    # Legacy does not use craft-cli
    if err is not None:
        emit.trace(f"run legacy implementation: {err!s}")
    emit.ended_ok()

    legacy.legacy_run()
コード例 #4
0
ファイル: main.py プロジェクト: canonical/charmcraft
def main(argv=None):
    """Provide the main entry point."""
    if env.is_charmcraft_running_in_managed_mode():
        logpath = env.get_managed_environment_log_path()
    else:
        logpath = None

    emit.init(
        EmitterMode.NORMAL,
        "charmcraft",
        f"Starting charmcraft version {__version__}",
        log_filepath=logpath,
    )

    if argv is None:
        argv = sys.argv

    extra_global_options = [
        GlobalArgument(
            "project_dir",
            "option",
            "-p",
            "--project-dir",
            "Specify the project's directory (defaults to current)",
        ),
    ]

    # process
    try:
        setup_parts()

        # load the dispatcher and put everything in motion
        dispatcher = Dispatcher(
            "charmcraft",
            COMMAND_GROUPS,
            summary=GENERAL_SUMMARY,
            extra_global_args=extra_global_options,
        )
        global_args = dispatcher.pre_parse_args(argv[1:])
        loaded_config = config.load(global_args["project_dir"])
        command = dispatcher.load_command(loaded_config)
        if command.needs_config and not loaded_config.project.config_provided:
            raise ArgumentParsingError(
                "The specified command needs a valid 'charmcraft.yaml' configuration file (in "
                "the current directory or where specified with --project-dir option); see "
                "the reference: https://discourse.charmhub.io/t/charmcraft-configuration/4138"
            )
        emit.trace(_get_system_details())
        retcode = dispatcher.run()

    except ArgumentParsingError as err:
        print(err, file=sys.stderr)  # to stderr, as argparse normally does
        emit.ended_ok()
        retcode = 1
    except ProvideHelpException as err:
        print(err, file=sys.stderr)  # to stderr, as argparse normally does
        emit.ended_ok()
        retcode = 0
    except CraftError as err:
        emit.error(err)
        retcode = err.retcode
    except errors.CraftStoreError as err:
        error = CraftError(f"craft-store error: {err}")
        emit.error(error)
        retcode = 1
    except KeyboardInterrupt as exc:
        error = CraftError("Interrupted.")
        error.__cause__ = exc
        emit.error(error)
        retcode = 1
    except Exception as err:
        error = CraftError(f"charmcraft internal error: {err!r}")
        error.__cause__ = err
        emit.error(error)
        retcode = 1
    else:
        emit.ended_ok()
        if retcode is None:
            retcode = 0

    return retcode