Skip to content

Commit

Permalink
wip very hackily use upstream to all commands
Browse files Browse the repository at this point in the history
  • Loading branch information
tigarmo committed Oct 2, 2023
1 parent 9af92fe commit d7b8d5c
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 147 deletions.
3 changes: 2 additions & 1 deletion rockcraft/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Main module."""
import sys

from .cli import run

if __name__ == "__main__":
run()
sys.exit(run())
83 changes: 0 additions & 83 deletions rockcraft/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,96 +49,13 @@ class FallbackRunError(RuntimeError):
class Rockcraft(Application):
"""Rockcraft application definition."""

@property
@override
def command_groups(self) -> list[craft_cli.CommandGroup]:
"""Filter supported command from CraftApplication."""
all_lifecycle_commands = get_lifecycle_command_group().commands
migrated_commands = {"pack"}

return [
CommandGroup(
"Lifecycle",
[c for c in all_lifecycle_commands if c.name in migrated_commands],
)
]

@functools.cached_property
def project(self) -> models.Project:
"""Get this application's Project metadata."""
project_file = (pathlib.Path.cwd() / f"{self.app.name}.yaml").resolve()
craft_cli.emit.debug(f"Loading project file '{project_file!s}'")
return models.Project.from_yaml_file(project_file, work_dir=self._work_dir)

@override
def _get_dispatcher(self) -> _Dispatcher:
"""Overridden to raise a FallbackRunError() for unhandled commands.
Should be removed after we finish migrating all commands.
"""
craft_cli.emit.init(
mode=craft_cli.EmitterMode.BRIEF,
appname=self.app.name,
greeting=f"Starting {self.app.name}",
log_filepath=self.log_path,
streaming_brief=True,
)

dispatcher = _Dispatcher(
self.app.name,
self.command_groups,
summary=str(self.app.summary),
extra_global_args=self._global_arguments,
)

try:
craft_cli.emit.trace("pre-parsing arguments...")
# Workaround for the fact that craft_cli requires a command.
# https://github.com/canonical/craft-cli/issues/141
if "--version" in sys.argv or "-V" in sys.argv:
try:
global_args = dispatcher.pre_parse_args(["pull", *sys.argv[1:]])
except craft_cli.ArgumentParsingError:
global_args = dispatcher.pre_parse_args(sys.argv[1:])
else:
global_args = dispatcher.pre_parse_args(sys.argv[1:])

if global_args.get("version"):
craft_cli.emit.ended_ok()
print(f"{self.app.name} {self.app.version}")
sys.exit(0)
# Try loading the command to shake out possible ArgumentParsingErrors
# from commands with options that we can't handle yet (like
# --destructive-mode)
dispatcher.load_command(
{
"app": self.app,
"services": self.services,
}
)
except (craft_cli.ProvideHelpException, craft_cli.ArgumentParsingError) as err:
# Difference from base's behavior: fallback to the legacy run
# if we get an unknown command, or an invalid option, or a request
# for help.
raise FallbackRunError() from err
except KeyboardInterrupt as err:
self._emit_error(craft_cli.CraftError("Interrupted."), cause=err)
sys.exit(128 + signal.SIGINT)
except Exception as err: # pylint: disable=broad-except
self._emit_error(
craft_cli.CraftError(
f"Internal error while loading {self.app.name}: {err!r}"
)
)
if os.getenv("CRAFT_DEBUG") == "1":
raise
sys.exit(70) # EX_SOFTWARE from sysexits.h

craft_cli.emit.trace("Preparing application...")
self.configure(global_args)

return dispatcher

@override
def _configure_services(self, platform: str | None, build_for: str | None) -> None:
if build_for is None:
Expand Down
66 changes: 3 additions & 63 deletions rockcraft/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@
]


def run() -> None:
def run() -> int:
"""Command-line interface entrypoint."""
# pylint: disable=import-outside-toplevel
# Import these here so that the script that generates the docs for the
# commands doesn't need to know *too much* of the application.
from .application import APP_METADATA, FallbackRunError, Rockcraft
from .application import APP_METADATA, Rockcraft

# Register our own plugins
plugins.register()
Expand All @@ -89,64 +89,4 @@ def run() -> None:

app = Rockcraft(app=APP_METADATA, services=services)

try:
app.run()
except FallbackRunError:
legacy_run()


def _emit_error(error: craft_cli.CraftError, cause: Optional[Exception] = None) -> None:
"""Emit the error in a centralized way so we can alter it consistently."""
# set the cause, if any
if cause is not None:
error.__cause__ = cause

# if running inside a managed instance, do not report the internal logpath
if is_managed_mode():
error.logpath_report = False

# finally, emit
emit.error(error)


def legacy_run() -> None:
"""Run the CLI."""
dispatcher = craft_cli.Dispatcher(
"rockcraft",
COMMAND_GROUPS,
summary="A tool to create OCI images",
extra_global_args=GLOBAL_ARGS,
default_command=commands.PackCommand,
)

try:
global_args = dispatcher.pre_parse_args(sys.argv[1:])
if global_args.get("version"):
emit.message(f"rockcraft {__version__}")
else:
dispatcher.load_command(None)
dispatcher.run()
emit.ended_ok()
except ProvideHelpException as err:
print(err, file=sys.stderr) # to stderr, as argparse normally does
emit.ended_ok()
except ArgumentParsingError as err:
print(err, file=sys.stderr) # to stderr, as argparse normally does
emit.ended_ok()
sys.exit(1)
except errors.RockcraftError as err:
_emit_error(err)
sys.exit(1)
except PartsError as err:
_emit_error(
craft_cli.CraftError(
err.brief, details=err.details, resolution=err.resolution
)
)
sys.exit(1)
except ProviderError as err:
_emit_error(craft_cli.CraftError(f"craft-providers error: {err}"))
sys.exit(1)
except Exception as err: # pylint: disable=broad-except
_emit_error(craft_cli.CraftError(f"rockcraft internal error: {err!r}"))
sys.exit(1)
return app.run()

0 comments on commit d7b8d5c

Please sign in to comment.