Skip to content

Commit

Permalink
feat: add promote command (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheCrab13 committed Mar 17, 2024
1 parent 3b6dfda commit c66fe2e
Show file tree
Hide file tree
Showing 45 changed files with 924 additions and 406 deletions.
4 changes: 2 additions & 2 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,10 @@ Commit Message Header
│ │
│ └─⫸ Commit Scope: cli|io|report|store|packaging|changelog
└─⫸ Commit Type: build|ci|chore|doc|feat|fix|perf|refactor|test
└─⫸ Commit Type: ci|chore|docs|feat|fix|perf|refactor|style|test
The `<type>` and `<summary>` fields are mandatory, the `(<scope>)` field is optional.


Type
""""

Expand All @@ -91,6 +90,7 @@ Must be one of the following:
* **fix**: A bug fix
* **perf**: A code change that improves performance
* **refactor**: A code change that neither fixes a bug nor adds a feature
* **style**: Code modification which does add a new feature nor fix a bug
* **test**: Adding missing tests or correcting existing tests


Expand Down
12 changes: 7 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,11 @@ $(PRECOMMIT_EXE): | $(VENV_BIN_DIR)
$(VENV_BIN_DIR):
$(NOISE)$(PYTHON) -m venv .venv

## -- Syntax checkers ---------------------------------------------------------
## -- Tox ---------------------------------------------------------------------

tox: | $(TOX_EXE) ## Execute specific tox environment using e parameter (ex. make tox e=py311)
$(NOISE)$(eval e ?= ALL)
$(NOISE)$(TOX_CMD) -e $(e) $(TOX_ARG)

syntax: e=syntax ## Perform all formatting, styling and coding checks
syntax: tox
Expand All @@ -87,11 +91,9 @@ pylint: tox

cover: e=cover ## Generate coverate report
cover: tox
$(NOISE)$(TOX_CMD) -e cover

tox: | $(TOX_EXE) ## Execute specific tox environment using e parameter (ex. make tox e=py311)
$(NOISE)$(eval e ?= ALL)
$(NOISE)$(TOX_CMD) -e $(e) $(TOX_ARG)
doc: e=doc ## Generate documentation
doc: tox

## -- Testing -----------------------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion docs/source/cli-usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Files

``pdbstore`` looks up 3 configuration files by default:

``PYTHON_PDB_CFG`` environment variable
``PDBSTORE_CFG`` environment variable
An environment variable that contains the path to a configuration file

``/etc/pdbstore.cfg``
Expand Down
31 changes: 24 additions & 7 deletions pdbstore/cli/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@


def add_global_arguments(
parser: argparse.ArgumentParser, add_help: bool = True
parser: argparse.ArgumentParser, add_help: bool = True, single: bool = True
) -> None:
"""Add global parsers command-line options."""
BaseCommand.init_config(parser)
BaseCommand.init_config(parser, single)
BaseCommand.init_log_file(parser)
BaseCommand.init_log_levels(parser)

Expand All @@ -27,23 +27,40 @@ def add_global_arguments(
)


def add_storage_arguments(parser: argparse.ArgumentParser) -> None:
def add_storage_arguments(parser: argparse.ArgumentParser, single: bool = True) -> None:
"""Add storage command-line options"""
if single:
help_msg = (
"Local root directory for the symbol store. " f"[env var: {ENV_PDBSTORE_STORAGE_DIR}]"
)
else:
help_msg = "Local root directory for the output symbol store."

parser.add_argument(
"-s",
"--store-dir",
metavar="DIRECTORY",
dest="store_dir",
type=str,
help=(
"Local root directory for the symbol store. "
f"[env var: {ENV_PDBSTORE_STORAGE_DIR}]"
),
help=help_msg,
required=False,
default=os.getenv(ENV_PDBSTORE_STORAGE_DIR),
action=OnceArgument,
)

if not single:
parser.add_argument(
"-i",
"--input-store-dir",
metavar="DIRECTORY",
dest="input_store_dir",
type=str,
help="Local root directory for the input symbol store.",
required=False,
default=None,
action=OnceArgument,
)


def add_product_arguments(parser: argparse.ArgumentParser) -> None:
"""Add product information command-line options"""
Expand Down
11 changes: 3 additions & 8 deletions pdbstore/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,7 @@ def _output_help_cli(self) -> None:
continue
data.append(line)

txt = textwrap.fill(
" ".join(data), 80, subsequent_indent=" " * (max_len + 2)
)
txt = textwrap.fill(" ".join(data), 80, subsequent_indent=" " * (max_len + 2))
cli_out_write(txt)

cli_out_write("")
Expand All @@ -146,9 +144,7 @@ def run(self, *args: Any) -> ExitCode:
command_argument = args[0][0]
except IndexError: # No parameters
self._output_help_cli()
raise PDBInvalidCommandNameException( # pylint: disable=raise-missing-from
None
)
raise PDBInvalidCommandNameException(None) # pylint: disable=raise-missing-from

try:
command = self._commands[command_argument]
Expand All @@ -165,8 +161,7 @@ def run(self, *args: Any) -> ExitCode:
raise PDBAbortExecution(0) # pylint: disable=raise-missing-from

output.info(
f"'{command_argument}' is not a PDBStore command. "
"See 'pdbstore --help'."
f"'{command_argument}' is not a PDBStore command. " "See 'pdbstore --help'."
)
output.info("")
self._print_similar(command_argument)
Expand Down
34 changes: 22 additions & 12 deletions pdbstore/cli/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ def parse_args( # type: ignore[override] # pylint: disable=arguments-differ
if value is not None:
args_dict[key] = value

if "input_store_id" in args_dict:
input_store_name = args_dict.get("input_store_id")
if input_store_name:
args_dict["input_store_dir"] = config.get_store_directory(input_store_name)

return argparse.Namespace(**args_dict)


Expand All @@ -94,9 +99,7 @@ def parse_args( # type: ignore[override] # pylint: disable=arguments-differ
:return: Depend on each command.
"""

SubCommandCallback = Callable[
[PDBStoreArgumentParser, argparse.ArgumentParser, Any], Any
]
SubCommandCallback = Callable[[PDBStoreArgumentParser, argparse.ArgumentParser, Any], Any]
"""Sub-command callback function.
:param PDBStoreArgumentParser: Current parser object
:param argparse.ArgumentParser: The command sub-parser object
Expand Down Expand Up @@ -128,8 +131,7 @@ def __init__(
self.formatters[kind] = action
else:
raise PDBStoreException(
f"Invalid formatter for {kind}. The formatter must be"
"a valid function"
f"Invalid formatter for {kind}. The formatter must be" "a valid function"
)
if callback.__doc__:
self.callback_doc = callback.__doc__
Expand Down Expand Up @@ -168,7 +170,7 @@ def init_log_file(parser: argparse.ArgumentParser) -> None:
)

@staticmethod
def init_config(parser: argparse.ArgumentParser) -> None:
def init_config(parser: argparse.ArgumentParser, single: bool = True) -> None:
"""Add configuration file command-line option"""
parser.add_argument(
"-C",
Expand Down Expand Up @@ -196,6 +198,18 @@ def init_config(parser: argparse.ArgumentParser) -> None:
action=OnceArgument,
)

if not single:
parser.add_argument(
"-I",
"--input-store",
metavar="NAME",
dest="input_store_id",
type=str,
help=("Which configuration section should be used as input store. "),
required=False,
action=OnceArgument,
)

@property
def _help_formatters(self) -> List[str]:
"""
Expand Down Expand Up @@ -231,9 +245,7 @@ def doc(self) -> str:
"""Get action help message"""
return self.callback_doc

def _format(
self, parser: argparse.ArgumentParser, info: Dict[str, Any], *args: Any
) -> None:
def _format(self, parser: argparse.ArgumentParser, info: Dict[str, Any], *args: Any) -> None:
parser_args, _ = parser.parse_known_args(*args)

default_format = "text"
Expand Down Expand Up @@ -358,9 +370,7 @@ def pdbstore_command(
name: Optional[str] = None,
) -> Callable[[CommandCallback], PDBStoreCommand]:
"""Register a PDBStore command"""
return lambda f: PDBStoreCommand(
f, group, formatters=formatters, callback_name=name
)
return lambda f: PDBStoreCommand(f, group, formatters=formatters, callback_name=name)


def pdbstore_subcommand(
Expand Down
11 changes: 4 additions & 7 deletions pdbstore/cli/commands/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,10 @@ def add(parser: PDBStoreArgumentParser, *args: Any) -> Any:
except PDBStoreException as exp:
output.error(str(exp))
errors_list.append([file, str(exp)])
except Exception as exg: # pylint: disable=broad-except
except Exception as exg: # pylint: disable=broad-except # pragma: no cover
errors_list.append([file, str(exg)])
output.error(
f"unexpected error when adding {file} with the following error:"
)
output.error(f"unexpected error when adding {file} with the following error:")
output.error(exg)

if success > 0:
# Commit modifications to the disk
Expand All @@ -172,9 +171,7 @@ def add(parser: PDBStoreArgumentParser, *args: Any) -> Any:
keep_count = opts.keep_count or 0
head = summary
if keep_count > 0:
summary_clean = store.remove_old_versions(
product_name, product_version, keep_count
)
summary_clean = store.remove_old_versions(product_name, product_version, keep_count)
head.linked = summary_clean
head = summary_clean

Expand Down
4 changes: 1 addition & 3 deletions pdbstore/cli/commands/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,6 @@ def clean(parser: PDBStoreArgumentParser, *args: Any) -> Any:
store = Store(store_dir)

# Delete the transaction from the store
summary = store.remove_old_versions(
product_name, product_version, keep_count, comment, dry_run
)
summary = store.remove_old_versions(product_name, product_version, keep_count, comment, dry_run)

return summary
18 changes: 5 additions & 13 deletions pdbstore/cli/commands/del.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,27 +61,19 @@ def delete(parser: PDBStoreArgumentParser, *args: Any) -> Any:
summary: Summary
summary_head: Optional[Summary] = None

for trans_id in (
transaction_id if isinstance(transaction_id, list) else [transaction_id]
):
for trans_id in transaction_id if isinstance(transaction_id, list) else [transaction_id]:
try:
summary_del: Summary = store.delete_transaction(trans_id)
except PDBStoreException as exp:
output.error(str(exp))
summary_del = Summary(
trans_id, OpStatus.FAILED, TransactionType.DEL, str(exp)
)
except BaseException as exg: # pylint: disable=broad-exception-caught
summary_del = Summary(
trans_id, OpStatus.FAILED, TransactionType.DEL, str(exg)
)
summary_del = Summary(trans_id, OpStatus.FAILED, TransactionType.DEL, str(exp))
except BaseException as exg: # pylint: disable=broad-exception-caught # pragma: no cover
summary_del = Summary(trans_id, OpStatus.FAILED, TransactionType.DEL, str(exg))
output.error(
f"unexpected error when deleting {trans_id} transaction",
)
if summary_head:
summary.linked = ( # noqa: F821 # pylint: disable=used-before-assignment
summary_del
)
summary.linked = summary_del # noqa: F821 # pylint: disable=used-before-assignment
else:
summary_head = summary_del
summary = summary_del
Expand Down
30 changes: 8 additions & 22 deletions pdbstore/cli/commands/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,9 @@ def fetch_text_formatter(summary: Summary) -> None:

if status == OpStatus.SUCCESS:
compressed = "Yes" if queryd.get("compressed", False) else "No"
cli_out_write(
f"{str(file_path):<{input_len}s}{compressed:^10s} {symbol_path}"
)
cli_out_write(f"{str(file_path):<{input_len}s}{compressed:^10s} {symbol_path}")
elif status == OpStatus.SKIPPED:
cli_out_write(
f"{str(file_path):<{input_len}s}{'':^10s} {error_msg or 'Not found'}"
)
cli_out_write(f"{str(file_path):<{input_len}s}{'':^10s} {error_msg or 'Not found'}")
else:
cli_out_write(
f"{str(file_path):<{input_len}s}{'':^10s} {error_msg or 'File not found'}"
Expand All @@ -81,9 +77,7 @@ def fetch_json_formatter(summary: Summary) -> None:
while head:
dct = {
"id": head.transaction_id,
"type": head.transaction_type.value
if head.transaction_type
else "undefined",
"type": head.transaction_type.value if head.transaction_type else "undefined",
"status": head.status.value,
"success": head.success(False),
"failure": head.failed(True),
Expand Down Expand Up @@ -178,9 +172,7 @@ def fetch(parser: PDBStoreArgumentParser, *args: Any) -> Any:

for file_path in input_files:
try:
entry: Optional[Tuple[Transaction, TransactionEntry]] = store.fetch_symbol(
file_path
)
entry: Optional[Tuple[Transaction, TransactionEntry]] = store.fetch_symbol(file_path)
if not entry:
summary.add_file(file_path, OpStatus.SKIPPED, "Not found")
continue
Expand All @@ -198,19 +190,13 @@ def fetch(parser: PDBStoreArgumentParser, *args: Any) -> Any:
f"Failed to extract from transaction {entry[0].transaction_id}",
)
except InvalidPEFile:
summary.add_file(
util.path_to_str(file_path), OpStatus.SKIPPED, "Not a valid pe file"
)
summary.add_file(util.path_to_str(file_path), OpStatus.SKIPPED, "Not a valid pe file")
except FileNotExistsError:
summary.add_file(
util.path_to_str(file_path), OpStatus.FAILED, "File not found"
)
summary.add_file(util.path_to_str(file_path), OpStatus.FAILED, "File not found")
except PDBStoreException as exp: # pragma: no cover
summary.add_file(
util.path_to_str(file_path), OpStatus.FAILED, "ex:" + str(exp)
)
summary.add_file(util.path_to_str(file_path), OpStatus.FAILED, "ex:" + str(exp))
except Exception as exc: # pylint: disable=broad-except # pragma: no cover
summary.add_file(util.path_to_str(file_path), OpStatus.FAILED, str(exc))
output.error(exc)
output.error("unexpected error when querying information for {file_path}")
output.error(f"unexpected error when fetching information for {file_path}")
return summary

0 comments on commit c66fe2e

Please sign in to comment.