diff --git a/CHANGELOG.md b/CHANGELOG.md index bdf1f29..cdb5f29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,10 +37,12 @@ and this project attempts to adhere to [Semantic Versioning](https://semver.org/ - Now using `nox` for testing. - Build script has been moved from inside the package to the root of the repository. +- Added link to MIT license in all SVG files and split the license and Refactoring UI Inc. copyright information into separate lines. ### Removed - Dropped support for Python 3.7. +- Removed all build scripts and related methods from package. ## [0.1.3] diff --git a/build.py b/build.py index d91f871..87678c3 100644 --- a/build.py +++ b/build.py @@ -5,62 +5,74 @@ import shutil from collections.abc import Sequence from pathlib import Path +from tempfile import TemporaryDirectory -from nodejs import npm - -from wagtail_heroicons.icons import Heroicon +import httpx +from bs4 import BeautifulSoup +from bs4 import Comment HEROICONS_LATEST_VERSION = "1.0.6" -NODE_SRC_DIR = Path(__file__).parent / "node_modules" / "heroicons" DEST_DIR = ( Path(__file__).parent / "src" / "wagtail_heroicons" / "templates" / "heroicons" ) -def build(argv: Sequence[str] | None = None) -> int: - args = parse_args(argv) - - install_heroicons(args.version, args.dest) - - for icon in Heroicon.get_icons(): - icon._add_id_and_license() - - return 0 - - -def parse_args(argv: Sequence[str] | None = None) -> argparse.Namespace: +def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser() - parser.add_argument( "-v", "--version", help="choose the version of heroicons to use", default=HEROICONS_LATEST_VERSION, ) - parser.add_argument( "--dest", help="choose the destination directory", type=Path, default=DEST_DIR, ) + args = parser.parse_args(argv) + + version = args.version + dest = args.dest + + response = httpx.get( + f"https://github.com/tailwindlabs/heroicons/archive/v{version}.zip", + follow_redirects=True, + ).raise_for_status() + + with TemporaryDirectory() as tmpdir: + with open(Path(tmpdir) / "heroicons.zip", "wb") as f: + f.write(response.content) - return parser.parse_args(argv) + shutil.unpack_archive(Path(tmpdir) / "heroicons.zip", tmpdir) + for icon_type_path in ( + Path(tmpdir) / f"heroicons-{version}" / "optimized" + ).iterdir(): + icon_type_folder = Path(dest) / icon_type_path.name -def install_heroicons(version: str, dest: Path) -> None: - npm.run(["install", f"heroicons@{version}", "--silent", "--no-save"]) + shutil.rmtree(icon_type_folder, ignore_errors=True) + shutil.copytree(icon_type_path, icon_type_folder) - for icon_type in ["outline", "solid"]: - shutil.rmtree(dest / icon_type, ignore_errors=True) - shutil.copytree( - NODE_SRC_DIR / icon_type, - dest / icon_type, - ) + for icon_path in dest.rglob("*.svg"): + with open(icon_path) as f: + soup = BeautifulSoup(f.read(), "html.parser") + for icon in soup.find_all("svg"): + icon_name = icon_path.stem + icon_type = icon_path.parent.name - shutil.rmtree("node_modules") + icon.attrs["id"] = f"icon-heroicons-{icon_name}-{icon_type}" + + icon.insert(0, Comment(" MIT License https://mit-license.org/ ")) + icon.insert(1, Comment(" Copyright (c) 2020 Refactoring UI Inc. ")) + + with open(icon_path, "wb") as f: + f.write(soup.prettify("utf-8")) + + return 0 if __name__ == "__main__": - raise SystemExit(build()) + raise SystemExit(main()) diff --git a/heroicons.zip b/heroicons.zip new file mode 100644 index 0000000..a943cd3 Binary files /dev/null and b/heroicons.zip differ diff --git a/pyproject.toml b/pyproject.toml index 1256418..8984786 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,8 +37,10 @@ dev = [ "beautifulsoup4", "bumpver", "coverage[toml]", + "django-stubs", "environs", "hatch", + "httpx", "mypy", "nodejs-bin", "nox[uv]", @@ -46,7 +48,8 @@ dev = [ "pytest-cov", "pytest-randomly", "pytest-xdist", - "ruff" + "ruff", + "types-beautifulsoup4" ] lint = ["pre-commit"] @@ -76,13 +79,17 @@ exclude_lines = [ "if TYPE_CHECKING:", 'def __str__\(self\)\s?\-?\>?\s?\w*\:' ] -fail_under = 75 +fail_under = 60 [tool.coverage.run] branch = true omit = ["tests/*"] parallel = true +[tool.django-stubs] +django_settings_module = "tests.settings" +strict_settings = false + [tool.hatch.build] exclude = [".*", "Justfile"] @@ -97,10 +104,16 @@ check_untyped_defs = true exclude = "docs/.*\\.py$" mypy_path = "src/" no_implicit_optional = true +plugins = ["mypy_django_plugin.main"] warn_redundant_casts = true warn_unused_configs = true warn_unused_ignores = true +[[tool.mypy.overrides]] +ignore_errors = true +ignore_missing_imports = true +module = ["tests.*", "wagtail.*"] + [tool.pytest.ini_options] addopts = "-n auto --dist loadfile --doctest-modules" norecursedirs = ".* bin build dist *.egg htmlcov logs node_modules templates venv" diff --git a/src/wagtail_heroicons/icons.py b/src/wagtail_heroicons/icons.py index 24e3289..32767e8 100644 --- a/src/wagtail_heroicons/icons.py +++ b/src/wagtail_heroicons/icons.py @@ -39,31 +39,3 @@ def get_icons(cls) -> HeroiconList: ) return icons - - def _add_id_and_license(self) -> None: - try: - from bs4 import BeautifulSoup - from bs4 import Comment - except ImportError as e: # pragma: no cover - raise ImportError( - "bs4 is required to add the id attribute to the tag." - ) from e - - with self.path.open("r") as f: - soup = BeautifulSoup(f.read(), "html.parser") - - for icon in soup.find_all("svg"): - # Wagtail uses the id attribute to identify icons. The name used in Wagtail - # is the id attribute of the tag, minus the "icon-" prefix. - icon.attrs[ - "id" - ] = f"icon-heroicons-{self.path.stem}-{self.path.parent.name}" - icon.insert( - 0, - Comment( - " This work is licensed under the MIT License and is Copyright (c) 2020 Refactoring UI Inc. " - ), - ) - - with self.path.open("wb") as f: - f.write(soup.prettify("utf-8")) diff --git a/src/wagtail_heroicons/templates/heroicons/outline/academic-cap.svg b/src/wagtail_heroicons/templates/heroicons/outline/academic-cap.svg index 3a99cc3..c4efa05 100644 --- a/src/wagtail_heroicons/templates/heroicons/outline/academic-cap.svg +++ b/src/wagtail_heroicons/templates/heroicons/outline/academic-cap.svg @@ -1,5 +1,6 @@