diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..b1cf4d1 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,53 @@ +name: Release + +on: + workflow_dispatch: + +jobs: + # Build Python package + build: + uses: ewoks-kit/.github/.github/workflows/python-build.yml@main + + # Run tests + tests: + needs: build + uses: ewoks-kit/.github/.github/workflows/python-tests.yml@main + + + # Publish package to TestPyPI + publish-testpypi: + needs: tests + runs-on: ubuntu-latest + environment: + name: release + permissions: + id-token: write + steps: + - uses: ewoks-kit/.github/.github/actions/setup-python-package@main + - uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + + # Publish package to PyPI + publish-pypi: + needs: tests + runs-on: ubuntu-latest + environment: + name: release + permissions: + id-token: write + steps: + - uses: ewoks-kit/.github/.github/actions/setup-python-package@main + - uses: pypa/gh-action-pypi-publish@release/v1 + + # Tag + tag-release: + needs: publish-pypi + runs-on: ubuntu-latest + permissions: + contents: write + steps: + - uses: ewoks-kit/.github/.github/actions/setup-python-package@main + - uses: ewoks-kit/.github/.github/actions/tag-release@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..0bc8c97 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,53 @@ +name: Test + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + workflow_call: + +jobs: + # Build Python package + build: + uses: ewoks-kit/.github/.github/workflows/python-build.yml@main + + # Run tests + tests: + needs: build + uses: ewoks-kit/.github/.github/workflows/python-tests.yml@main + secrets: + codecov_token: ${{ secrets.CODECOV_TOKEN }} + with: + os: ${{ matrix.os }} + python-version: ${{ matrix.python-version }} + enable-coverage: ${{ matrix.enable-coverage }} + jupyter-platform-dirs: "1" + codecov-flags: "unit" + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + python-version: "3.9" + enable-coverage: "false" + # https://github.com/networkx/networkx/issues/7372 + extra-pytest-warnings: "-W ignore::RuntimeWarning:networkx.utils.backends" + + - os: ubuntu-latest + python-version: "3.12" + enable-coverage: "true" + extra-pytest-warnings: "" + + + - os: windows-latest + python-version: "3.12" + enable-coverage: "false" + extra-pytest-warnings: "" + + # Run linter / checks + checks: + uses: ewoks-kit/.github/.github/workflows/python-check.yml@main + with: + enable-isort: "false" diff --git a/.gitignore b/.gitignore index 2bba7ec..7973ac4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ !.readthedocs.yaml !.flake8 !.flake8_nb +!.github # Byte / compiled / optimized *.py[cod] diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29..210bbb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- CLI entry point `ewoksdraw` that generates an SVG file from a single output path argument. +- Automatic mock workflow generation with a background and randomly positioned task blocks. +- SVG task rendering with: + - task title text + - task box and title separator line + - input/output labels + - circular anchor links for IO ports +- Adaptive task layout logic that scales/truncates text and adjusts font sizes to keep content within box width constraints. +- SVG canvas export helpers: + - pretty-printed SVG file output + - in-memory XML representation + - dictionary representation via `xmltodict` +- Basic CLI smoke test ensuring `ewoksdraw` writes an SVG output file. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0bbc69a..e139321 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1 +1 @@ -CONTRIBUTING.md \ No newline at end of file +CONTRIBUTING.md \ No newline at end of file diff --git a/README.md b/README.md index 74efbf0..d7f3c76 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # ewoksdraw +[![Pipeline](https://github.com/ewoks-kit/ewoksdraw/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/ewoks-kit/ewoksdraw/actions/workflows/test.yml) +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![License](https://img.shields.io/github/license/ewoks-kit/ewoksdraw)](https://github.com/ewoks-kit/ewoksdraw/blob/main/LICENSE.md) +[![Coverage](https://codecov.io/gh/ewoks-kit/ewoksdraw/branch/main/graph/badge.svg)](https://codecov.io/gh/ewoks-kit/ewoksdraw) + A project to generate SVG mock-ups out of Ewoks workflows. ## Quick start diff --git a/pyproject.toml b/pyproject.toml index 7085113..f6b552d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,8 @@ test = [ ] dev = [ "pytest >=7", - "ruff", + "ruff", + "black", "mypy", ] doc = [ @@ -76,7 +77,4 @@ ignore_missing_imports = true [[tool.mypy.overrides]] module = "setuptools.*" -ignore_missing_imports = true - -[tool.pytest.ini_options] -addopts = "--cov=ewoksdraw --cov-report=term" \ No newline at end of file +ignore_missing_imports = true \ No newline at end of file diff --git a/src/ewoksdraw/main.py b/src/ewoksdraw/main.py index 11956bc..6b4c0f8 100644 --- a/src/ewoksdraw/main.py +++ b/src/ewoksdraw/main.py @@ -3,9 +3,7 @@ from faker import Faker -from .svg import SvgBackground -from .svg import SvgCanvas -from .svg import SvgTask +from .svg import SvgBackground, SvgCanvas, SvgTask def generate_random_names() -> list: diff --git a/src/ewoksdraw/svg/svg_canvas.py b/src/ewoksdraw/svg/svg_canvas.py index 6a79b9f..7aa4080 100644 --- a/src/ewoksdraw/svg/svg_canvas.py +++ b/src/ewoksdraw/svg/svg_canvas.py @@ -1,10 +1,7 @@ from pathlib import Path -from typing import Iterator -from typing import List -from typing import Union +from typing import Iterator, List, Union from xml.dom import minidom -from xml.etree.ElementTree import Element -from xml.etree.ElementTree import tostring +from xml.etree.ElementTree import Element, tostring import xmltodict diff --git a/src/ewoksdraw/svg/svg_element.py b/src/ewoksdraw/svg/svg_element.py index 0ca1c50..dc25aee 100644 --- a/src/ewoksdraw/svg/svg_element.py +++ b/src/ewoksdraw/svg/svg_element.py @@ -1,6 +1,5 @@ from pathlib import Path -from typing import Literal -from typing import Optional +from typing import Literal, Optional from xml.etree.ElementTree import Element diff --git a/src/ewoksdraw/svg/svg_group.py b/src/ewoksdraw/svg/svg_group.py index df937d3..533fed0 100644 --- a/src/ewoksdraw/svg/svg_group.py +++ b/src/ewoksdraw/svg/svg_group.py @@ -1,6 +1,5 @@ import re -from typing import Iterable -from typing import Union +from typing import Iterable, Union from xml.etree.ElementTree import Element from .svg_element import SvgElement diff --git a/src/ewoksdraw/svg/svg_task.py b/src/ewoksdraw/svg/svg_task.py index da077ce..4ee5e28 100644 --- a/src/ewoksdraw/svg/svg_task.py +++ b/src/ewoksdraw/svg/svg_task.py @@ -1,5 +1,4 @@ -from ..config.constants import IO_INTER_IO_MARGIN -from ..config.constants import IO_TOP_MARGIN +from ..config.constants import IO_INTER_IO_MARGIN, IO_TOP_MARGIN from .svg_group import SvgGroup from .svg_task_box import SvgTaskBox from .svg_task_io import SvgTaskIOGroup diff --git a/src/ewoksdraw/svg/svg_task_box.py b/src/ewoksdraw/svg/svg_task_box.py index bca00df..e735f3a 100644 --- a/src/ewoksdraw/svg/svg_task_box.py +++ b/src/ewoksdraw/svg/svg_task_box.py @@ -1,5 +1,4 @@ -from ..config.constants import BOX_MAX_WIDTH -from ..config.constants import BOX_MIN_WIDTH +from ..config.constants import BOX_MAX_WIDTH, BOX_MIN_WIDTH from .svg_element import SvgElement diff --git a/src/ewoksdraw/svg/svg_task_io.py b/src/ewoksdraw/svg/svg_task_io.py index 0ea43d3..7763a52 100644 --- a/src/ewoksdraw/svg/svg_task_io.py +++ b/src/ewoksdraw/svg/svg_task_io.py @@ -1,9 +1,11 @@ from typing import Literal -from ..config.constants import ANCHOR_LINKS_RADIUS -from ..config.constants import IO_ANCHOR_TEXT_MARGIN -from ..config.constants import IO_MIN_FONT_SIZE -from ..config.constants import IO_TARGET_FONT_SIZE +from ..config.constants import ( + ANCHOR_LINKS_RADIUS, + IO_ANCHOR_TEXT_MARGIN, + IO_MIN_FONT_SIZE, + IO_TARGET_FONT_SIZE, +) from .svg_group import SvgGroup from .svg_task_anchor_link import SvgTaskAnchorLink from .svg_text import SvgText diff --git a/src/ewoksdraw/svg/svg_task_title.py b/src/ewoksdraw/svg/svg_task_title.py index fc5888a..60c6e93 100644 --- a/src/ewoksdraw/svg/svg_task_title.py +++ b/src/ewoksdraw/svg/svg_task_title.py @@ -1,9 +1,11 @@ from typing import Optional -from ..config.constants import TITLE_HORIZONTAL_MARGIN -from ..config.constants import TITLE_MIN_FONT_SIZE -from ..config.constants import TITLE_TARGET_FONT_SIZE -from ..config.constants import TITLE_VERTICAL_MARGIN +from ..config.constants import ( + TITLE_HORIZONTAL_MARGIN, + TITLE_MIN_FONT_SIZE, + TITLE_TARGET_FONT_SIZE, + TITLE_VERTICAL_MARGIN, +) from .svg_text import SvgText diff --git a/tests/test_main.py b/src/ewoksdraw/tests/test_main.py similarity index 100% rename from tests/test_main.py rename to src/ewoksdraw/tests/test_main.py