Skip to content

Commit

Permalink
Created classes and functions to be used for slices and convert command.
Browse files Browse the repository at this point in the history
  • Loading branch information
cerrussell committed Jan 10, 2024
1 parent 80e034a commit bc8dd43
Show file tree
Hide file tree
Showing 17 changed files with 106,820 additions and 0 deletions.
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include atom_tools/atom_data/openapi_slices_schemas.json
4 changes: 4 additions & 0 deletions atom_tools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"""
A cli, classes and functions for converting an atom slice to a different format
"""
__version__ = '0.0.1'
Empty file.
464 changes: 464 additions & 0 deletions atom_tools/atom_data/openapi_slices_schemas.json

Large diffs are not rendered by default.

Empty file added atom_tools/cli/__init__.py
Empty file.
81 changes: 81 additions & 0 deletions atom_tools/cli/application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
"""
Base console application.
"""

from importlib import import_module
from typing import Callable

from cleo.application import Application as BaseApplication
from cleo.commands.command import Command

from atom_tools import __version__
from atom_tools.cli.command_loader import CommandLoader


def load_command(name: str) -> Callable[[], Command]:
"""
Load a command dynamically based on the given name.
This function dynamically imports the module and retrieves the command
class based on the name. It returns a callable that can be used to
instantiate the command.
Args:
name (str): The name of the command.
Returns:
Callable[[], Command]: A callable that of an instance of the command.
"""

def _load() -> Command:
words = name.split(' ')
module = import_module('atom-tools.cli.commands.' + '.'.join(words))
command_class = getattr(
module, ''.join(c.title() for c in words) + 'Command'
)
command: Command = command_class()
return command

return _load


COMMANDS = [
'convert',
]


class Application(BaseApplication):
"""
Represents the main application.
This class initializes the application with the appropriate command loader
and command names.
"""

def __init__(self) -> None:
super().__init__('atom-tools', __version__)

command_loader = CommandLoader(
{name: load_command(name) for name in COMMANDS}
)
self.set_command_loader(command_loader)


def main() -> int:
"""
The entry point of the application.
This function initializes and runs the application.
Returns:
int: The exit code of the application.
"""
exit_code: int = Application().run()
return exit_code


if __name__ == '__main__':
main()
46 changes: 46 additions & 0 deletions atom_tools/cli/command_loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""
Command Loader for the atom-tools CLI.
"""

from typing import Callable

from cleo.commands.command import Command
from cleo.exceptions import CleoLogicError
from cleo.loaders.factory_command_loader import FactoryCommandLoader


class CommandLoader(FactoryCommandLoader):
"""
Register a command factory for a command name.
Args:
command_name (str): The name of the command.
factory (Callable[[], Command]): The command factory function.
Raises:
CleoLogicError: If the command name already exists.
"""

def register_factory(
self, command_name: str, factory: Callable[[], Command]
) -> None:
"""
Register a command factory.
Args:
command_name (str): The name of the command.
factory (Callable[[], Command]): A callable that returns a Command.
Raises:
CleoLogicError: If the command with the given name already exists.
Returns:
None
"""
if command_name in self._factories:
raise CleoLogicError(
f'The command "{command_name}" already exists.'
)

self._factories[command_name] = factory
Empty file.
74 changes: 74 additions & 0 deletions atom_tools/cli/commands/convert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""
Convert Command for the atom-tools CLI.
"""

from cleo.commands.command import Command
from cleo.helpers import option

from atom_tools.lib.converter import OpenAPI


class ConvertCommand(Command):
"""
Represents a command to convert an atom slice to a different format.
This command handles the conversion of an atom slice to a specified
destination format. It requires a slice generated by atom and a Bill of
Materials (BOM) generated by cdxgen.
Attributes:
name (str): The name of the command.
description (str): The description of the command.
options (list): The list of options for the command.
help (str): The help message for the command.
Methods:
handle: Executes the command and performs the conversion.
"""

name = 'convert'
description = 'Convert an atom slice to a different format'
options = [
option(
'format',
'f',
'Destination format',
flag=False,
default='openapi3.1.0',
),
option(
'bom-file',
'b',
'Path to bom generated by cdxgen',
),
option('usages-slice', 'u', 'Usages slice file'),
option(
'reachables-slice',
'r',
'Reachables slice file',
),
]
help = """The convert command converts an atom slice to a different format.
This operation requires a slice generated by atom and a bom generated by
cdxgen using the --evidence option."""
# TODO: add logger
# loggers = []

def handle(self):
"""
Executes the convert command and performs the conversion.
"""
match self.option('format'):
case 'openapi3.0.1', 'openapi3.1.0':
converter_instance = OpenAPI(
self.option('format'),
self.option('bom-file'),
self.option('language'),
self.option('usages-slice'),
self.option('reachables-slice'),
)
converter_instance.convert_slices()
case _:
raise ValueError(
f'Unknown destination format: {self.option("format")}'
)
Empty file added atom_tools/lib/__init__.py
Empty file.
Loading

0 comments on commit bc8dd43

Please sign in to comment.