diff --git a/src/pytask_latex/collect.py b/src/pytask_latex/collect.py index 303658f..24c1fab 100644 --- a/src/pytask_latex/collect.py +++ b/src/pytask_latex/collect.py @@ -205,14 +205,28 @@ def pytask_collect_task( markers=markers, ) - if session.config["infer_latex_dependencies"]: - task = _add_latex_dependencies_retroactively(task, session) - return task return None -def _add_latex_dependencies_retroactively(task: PTask, session: Session) -> PTask: +@hookimpl +def pytask_collect_modify_tasks(session: Session, tasks: list[PTask]) -> None: + """Add dependencies from from LaTeX documents to tasks.""" + if session.config["infer_latex_dependencies"]: + all_products = { + product.path + for task in tasks + for product in tree_leaves(task.produces) + if isinstance(product, PPathNode) + } + latex_tasks = [task for task in tasks if has_mark(task, "latex")] + for task in latex_tasks: + _add_latex_dependencies_retroactively(task, session, all_products) + + +def _add_latex_dependencies_retroactively( + task: PTask, session: Session, all_products: set[Path] +) -> None: """Add dependencies from LaTeX document to task. Unfortunately, the dependencies have to be added retroactively, after the task has @@ -234,23 +248,22 @@ def _add_latex_dependencies_retroactively(task: PTask, session: Session) -> PTas """ # Scan the LaTeX document for included files. try: - latex_dependencies = set( + scanned_deps = set( lds.scan(task.depends_on["_path_to_tex"].path) # type: ignore[attr-defined] ) except Exception: # noqa: BLE001 warnings.warn( "pytask-latex failed to scan latex document for dependencies.", stacklevel=1 ) - latex_dependencies = set() + scanned_deps = set() # Remove duplicated dependencies which have already been added by the user and those # which do not exist. - existing_paths = { + task_deps = { i.path for i in tree_leaves(task.depends_on) if isinstance(i, PPathNode) } - new_deps = latex_dependencies - existing_paths - new_existing_deps = {i for i in new_deps if i.exists()} - new_numbered_deps = dict(enumerate(new_existing_deps)) + additional_deps = scanned_deps - task_deps + new_deps = [i for i in additional_deps if i in all_products or i.exists()] # Collect new dependencies and add them to the task. task_path = task.path if isinstance(task, PTaskWithPath) else None @@ -268,7 +281,7 @@ def _add_latex_dependencies_retroactively(task: PTask, session: Session) -> PTas task_name=task.name, ), ), - new_numbered_deps, + new_deps, ) task.depends_on[ "_scanned_dependencies" @@ -277,8 +290,6 @@ def _add_latex_dependencies_retroactively(task: PTask, session: Session) -> PTas # Mark the task as being delayed to avoid conflicts with unmatched dependencies. task.markers.append(Mark("try_last", (), {})) - return task - def _collect_node( session: Session, path: Path, node_info: NodeInfo diff --git a/tests/test_execute.py b/tests/test_execute.py index 1726429..1d25d2b 100644 --- a/tests/test_execute.py +++ b/tests/test_execute.py @@ -584,3 +584,43 @@ def test_use_task_without_path(tmp_path): tmp_path.joinpath("document.tex").write_text(textwrap.dedent(latex_source)) session = build(paths=tmp_path) assert session.exit_code == ExitCode.OK + + +@needs_latexmk +@skip_on_github_actions_with_win +@pytest.mark.end_to_end() +def test_collect_latex_document_with_product_from_another_task(runner, tmp_path): + """Test simple compilation.""" + task_source = """ + import pytask + from pathlib import Path + from pytask import Product + from typing_extensions import Annotated + + @pytask.mark.latex(script="document.tex", document="document.pdf") + def task_compile_document(): pass + + + def task_create_input_tex( + path: Annotated[Path, Product] = Path("duesterboys.tex") + ) -> None: + path.write_text("weil du meine Mitten extrahierst.") + """ + tmp_path.joinpath("task_dummy.py").write_text(textwrap.dedent(task_source)) + + latex_source = r""" + \documentclass{report} + \begin{document} + \input{duesseldorf} + \input{duesterboys} + \end{document} + """ + tmp_path.joinpath("document.tex").write_text(textwrap.dedent(latex_source)) + tmp_path.joinpath("duesseldorf.tex").write_text( + "Bin ich wieder nur so nett zu dir, " + ) + + result = runner.invoke(cli, ["collect", "--nodes", tmp_path.as_posix()]) + assert result.exit_code == ExitCode.OK + assert "duesseldorf.tex" in result.output + assert "duesterboys.tex" in result.output