Skip to content

Commit

Permalink
Adds --debug flag to conversion script (#41)
Browse files Browse the repository at this point in the history
* Adds debug mode to convert.py

* Adds post-convert parser instance to the debug mode logs

* Bumps unit testing coverage. Old metric was from when this project was a part of percy

* Update conda_recipe_manager/parser/recipe_parser_convert.py

Co-authored-by: Bianca Henderson <[email protected]>

---------

Co-authored-by: Bianca Henderson <[email protected]>
  • Loading branch information
schuylermartin45 and beeankha authored May 1, 2024
1 parent ae34991 commit e323fd7
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ test-debug: ## runs test cases with debugging info enabled

test-cov: ## checks test coverage requirements
$(PYTHON3) -m pytest -n auto --cov-config=.coveragerc --cov=$(SRC_DIR) \
$(TEST_DIR) --cov-fail-under=45 --cov-report term-missing
$(TEST_DIR) --cov-fail-under=80 --cov-report term-missing

lint: ## runs the linter against the project
pylint --rcfile=.pylintrc $(SRC_DIR) $(TEST_DIR)
Expand Down
31 changes: 24 additions & 7 deletions conda_recipe_manager/commands/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,14 @@ def _record_unrecoverable_failure(
return conversion_result


def convert_file(file_path: Path, output: Optional[Path], print_output: bool) -> ConversionResult:
def convert_file(file_path: Path, output: Optional[Path], print_output: bool, debug: bool) -> ConversionResult:
"""
Converts a single recipe file to the new format, tracking results.
:param file_path: Path to the recipe file to convert
:param output: If specified, the file contents are written to this file path. Otherwise, the file is dumped to
STDOUT IF `print_output` is set to `True`.
:param print_output: Prints the recipe to STDOUT/STDERR if the output file is not specified and this flag is `True`.
:param debug: Enables debug mode output. Prints to STDERR.
:returns: A struct containing the results of the conversion process, including debugging metadata.
"""
conversion_result = ConversionResult(
Expand Down Expand Up @@ -146,9 +147,16 @@ def convert_file(file_path: Path, output: Optional[Path], print_output: bool) ->
e,
)

# Print the initial parser, if requested
print_err("########## PARSED RECIPE FILE ##########", print_enabled=debug)
print_err(parser, print_enabled=debug)

# Convert the recipe
try:
conversion_result.content, conversion_result.msg_tbl = parser.render_to_new_recipe_format()
conversion_result.content, conversion_result.msg_tbl, debug_new_parser = parser.render_to_new_recipe_format()
# Print the new parser, if requested
print_err("########## CONVERTED RECIPE FILE ##########", print_enabled=debug)
print_err(debug_new_parser, print_enabled=debug)
except Exception as e: # pylint: disable=broad-exception-caught
return _record_unrecoverable_failure(
conversion_result,
Expand All @@ -172,16 +180,17 @@ def convert_file(file_path: Path, output: Optional[Path], print_output: bool) ->
return conversion_result


def process_recipe(file: Path, path: Path, output: Optional[Path]) -> tuple[str, ConversionResult]:
def process_recipe(file: Path, path: Path, output: Optional[Path], debug: bool) -> tuple[str, ConversionResult]:
"""
Helper function that performs the conversion operation for parallelizable execution.
:param file: Recipe file to convert
:param path: Path argument provided by the user
:param output: Output argument file provided by the user
:param debug: Enables debug mode output. Prints to STDERR.
:returns: Tuple containing the key/value pairing that tracks the result of the conversion operation
"""
out_file: Optional[Path] = None if output is None else file.parent / output
conversion_result = convert_file(file, out_file, False)
conversion_result = convert_file(file, out_file, False, debug)
conversion_result.project_name = file.relative_to(path).parts[0]
return str(file.relative_to(path)), conversion_result

Expand Down Expand Up @@ -251,8 +260,14 @@ def _collect_issue_stats(project_name: str, issues: list[str], hist: dict[str, i
is_flag=True,
help="Truncates logging. On large tests in a GitHub CI environment, this can eliminate log buffering issues.",
)
@click.option(
"--debug",
"-d",
is_flag=True,
help="Debug mode, prints debugging information to STDERR.",
)
def convert(
path: Path, output: Optional[Path], min_success_rate: float, truncate: bool
path: Path, output: Optional[Path], min_success_rate: float, truncate: bool, debug: bool
) -> None: # pylint: disable=redefined-outer-name
"""
Recipe conversion CLI utility. By default, recipes print to STDOUT. Messages always print to STDERR. Takes 1 file or
Expand All @@ -265,7 +280,7 @@ def convert(

## Single-file case ##
if len(files) == 1:
result: Final[ConversionResult] = convert_file(files[0], output, True)
result: Final[ConversionResult] = convert_file(files[0], output, True, debug)
print_messages(MessageCategory.WARNING, result.msg_tbl)
print_messages(MessageCategory.ERROR, result.msg_tbl)
print_err(result.msg_tbl.get_totals_message())
Expand All @@ -276,7 +291,9 @@ def convert(
# Process recipes in parallel
thread_pool_size: Final[int] = mp.cpu_count()
with mp.Pool(thread_pool_size) as pool:
results = dict(pool.starmap(process_recipe, [(file, path, output) for file in files])) # type: ignore[misc]
results = dict(
pool.starmap(process_recipe, [(file, path, output, debug) for file in files]) # type: ignore[misc]
)

# Tracking failures from bulk operation
recipes_with_except: list[str] = []
Expand Down
8 changes: 6 additions & 2 deletions conda_recipe_manager/parser/recipe_parser_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def pre_process_recipe_text(content: str) -> str:

return content

def render_to_new_recipe_format(self) -> tuple[str, MessageTable]:
def render_to_new_recipe_format(self) -> tuple[str, MessageTable, RecipeParser]:
"""
Takes the current recipe representation and renders it to the new format WITHOUT modifying the current recipe
state.
Expand All @@ -447,6 +447,10 @@ def render_to_new_recipe_format(self) -> tuple[str, MessageTable]:
- https://github.com/conda-incubator/ceps/blob/main/cep-14.md
(As of writing there is no official name other than "the new recipe format")
:returns: Returns a tuple containing:
- The converted recipe, as a string
- A `MessageTbl` instance that contains error logging
- The `RecipeParser` instance containing the converted recipe file. USE FOR DEBUGGING PURPOSES ONLY!
"""
# Approach: In the event that we want to expand support later, this function should be implemented in terms
# of a `RecipeParser` tree. This will make it easier to build an upgrade-path, if we so choose to pursue one.
Expand Down Expand Up @@ -496,4 +500,4 @@ def render_to_new_recipe_format(self) -> tuple[str, MessageTable]:
# "sensible" to a human reader.
self._sort_subtree_keys("/", TOP_LEVEL_KEY_SORT_ORDER)

return self._new_recipe.render(), self._msg_tbl
return self._new_recipe.render(), self._msg_tbl, self._new_recipe
2 changes: 1 addition & 1 deletion tests/parser/test_recipe_parser_convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def test_render_to_new_recipe_format(file_base: str, errors: list[str], warnings
:param file_base: Base file name for both the input and the expected out
"""
parser = load_recipe_convert(file_base)
result, tbl = parser.render_to_new_recipe_format()
result, tbl, _ = parser.render_to_new_recipe_format()
assert result == load_file(f"{TEST_FILES_PATH}/new_format_{file_base}")
assert tbl.get_messages(MessageCategory.ERROR) == errors
assert tbl.get_messages(MessageCategory.WARNING) == warnings
Expand Down

0 comments on commit e323fd7

Please sign in to comment.