Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
root = true
[*.toml]
indent_style = space
indent_size = 8

10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.PHONY: test

test:
poetry run coverage run --source=entangled -m pytest
poetry run coverage xml
poetry run coverage report
poetry run mypy
uv run coverage run --source=entangled -m pytest
uv run coverage xml
uv run coverage report
uv run mypy

docs:
poetry run mkdocs build
uv run mkdocs build
2 changes: 2 additions & 0 deletions README.md

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's rename the hook to spdx_license; I don't like arbitrary verbs in variable names

Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ Entangled has a system of *hooks*: these add actions to the tangling process:
- `brei` trigger actions (or tasks) using [Brei](https://entangled.github.io/brei), which is automatically installed along with Entangled. This is now prefered over the `build` hook.
- `quarto_attributes` add attributes to the code block in Quatro style with `#|` comments at the top of the code block.
- `shebang` takes the first line if it starts with `#!` and puts it at the top of the file.
- `spdx_license` takes the first line if it contains `SPDX-License-Identifier`
and puts it at the top of the file.

### `build` hook

Expand Down
11 changes: 6 additions & 5 deletions entangled/hooks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,28 @@
from importlib.metadata import entry_points

from .base import HookBase, PrerequisitesFailed
from . import build, task, quarto_attributes, shebang
from . import build, task, quarto_attributes, shebang, spdx_license
from ..config import config
from ..construct import construct
from typing import TypeVar


AbstractHook = TypeVar('AbstractHook', bound=HookBase)
AbstractHook = TypeVar("AbstractHook", bound=HookBase)

discovered_hooks = entry_points(group="entangled.hooks")


external_hooks = {
name: discovered_hooks[name].load().Hook
for name in discovered_hooks.names
name: discovered_hooks[name].load().Hook for name in discovered_hooks.names
}

hooks: dict[str, type[HookBase]] = {
"build": build.Hook,
"brei": task.Hook,
"shebang": shebang.Hook,
"quarto_attributes": quarto_attributes.Hook }
"spdx_license": spdx_license.Hook,
"quarto_attributes": quarto_attributes.Hook,
}


def get_hooks() -> list[HookBase]:
Expand Down
10 changes: 10 additions & 0 deletions entangled/hooks/spdx_license.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from ..document import CodeBlock
from .base import HookBase


class Hook(HookBase):
def on_read(self, code: CodeBlock):
lines = code.source.splitlines()
if lines and "SPDX-License-Identifier" in lines[0]:
code.header = lines[0]
code.source = "\n".join(lines[1:])
47 changes: 24 additions & 23 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ requires-python = "~=3.11"
readme = "README.md"
license = "Apache-2.0"
dependencies = [
"mawk>=0.1.4,<0.2",
"watchdog>=3.0.0,<4",
"filelock>=3.12.0,<4",
"argh>=0.30,<0.31",
"rich>=13.3.5,<14",
"tomlkit>=0.12.1,<0.13",
"copier>=9,<10",
"brei>=0.2.3,<0.3",
"rich-argparse>=1.4.0,<2",
"pexpect>=4.9.0,<5",
"pyyaml>=6.0.1,<7",
"mawk>=0.1.4,<0.2",
"watchdog>=3.0.0,<4",
"filelock>=3.12.0,<4",
"argh>=0.30,<0.31",
"rich>=13.3.5,<14",
"tomlkit>=0.12.1,<0.13",
"copier>=9,<10",
"brei>=0.2.3,<0.3",
"rich-argparse>=1.4.0,<2",
"pexpect>=4.9.0,<5",
"pyyaml>=6.0.1,<7",
"types-PyYAML>=6.0.1,<7",
]

[project.urls]
Expand All @@ -29,18 +30,18 @@ entangled = "entangled.main:cli"

[dependency-groups]
dev = [
"pytest>=7.3.1,<8",
"mypy>=1.3.0,<2",
"black>=23.3.0,<24",
"pytest-cov>=4.0.0,<5",
"mkdocs>=1.4.3,<2",
"mkdocs-material>=9.1.13,<10",
"mkdocstrings[python]>=0.21.2,<0.22",
"pytest-asyncio>=0.21.1,<0.22",
"ruff>=0.4.4,<0.5",
"types-pyyaml>=6.0.12.20240311,<7",
"types-pygments>=2.18.0.20240506,<3",
"types-colorama>=0.4.15.20240311,<0.5",
"pytest>=7.3.1,<8",
"mypy>=1.3.0,<2",
"black>=23.3.0,<24",
"pytest-cov>=4.0.0,<5",
"mkdocs>=1.4.3,<2",
"mkdocs-material>=9.1.13,<10",
"mkdocstrings[python]>=0.21.2,<0.22",
"pytest-asyncio>=0.21.1,<0.22",
"ruff>=0.4.4,<0.5",
"types-pyyaml>=6.0.12.20240311,<7",
"types-pygments>=2.18.0.20240506,<3",
"types-colorama>=0.4.15.20240311,<0.5",
]

[tool.hatch.build.targets.sdist]
Expand Down
70 changes: 70 additions & 0 deletions test/test_spdx_license.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from entangled.markdown_reader import read_markdown_string
from entangled.hooks.spdx_license import Hook as SPDXLicense
from entangled.tangle import tangle_ref, AnnotationMethod
from entangled.code_reader import CodeReader
from entangled.commands.stitch import stitch_markdown

input_md = """
A C file with a license!

``` {.c file=test.c}
// SPDX-License-Identifier: MIT
#include <stdio.h>

int main() {
printf("Hello, World!\n");
return 0;
}
```
"""

output_test_c = """// SPDX-License-Identifier: MIT
/* ~/~ begin <<-#test.c>>[init] */
#include <stdio.h>

int main() {
printf("Hello, World!\n");
return 0;
}
/* ~/~ end */
"""

output_test_c_modified = """// SPDX-License-Identifier: MIT
# ~/~ begin <<-#test.c>>[init]

int main() {
printf("Hello, World!\n");
return 0;
}
# ~/~ end
"""

input_md_modified = """
A C file with a license!

``` {.c file=test.c}
// SPDX-License-Identifier: MIT

int main() {
printf("Hello, World!\n");
return 0;
}
```
"""


def test_spdx_license():
hooks = [SPDXLicense(SPDXLicense.Config())]
refs, content = read_markdown_string(input_md, hooks=hooks)
assert "test.c" in refs
print(next(refs["test.c"]))
assert next(refs["test.c"]).header == "// SPDX-License-Identifier: MIT"
code_content, _ = tangle_ref(refs, "test.c", AnnotationMethod.STANDARD)
print(code_content.strip())
print(output_test_c.strip())
assert code_content.strip() == output_test_c.strip()

cr = CodeReader("test.c", refs)
cr.run(output_test_c_modified)
md_content = stitch_markdown(refs, content)
assert md_content.strip() == input_md_modified.strip()
Loading