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
3 changes: 2 additions & 1 deletion .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,8 @@ jobs:
cp ${{ github.workspace }}/examples/examples.zip release-files/examples.zip
cp ${{ github.workspace }}/pattern-lens/* release-files/
cp ${{ github.workspace }}/pattern-syntax-parser/* release-files/
cp ${{ github.workspace }}/pattern-syntax-plugin/* release-files/
cp ${{ github.workspace }}/pattern-syntax-plugin/*-lite.jar release-files/
cp ${{ github.workspace }}/pattern-syntax-plugin/*-standalone.jar release-files/
cp ${{ github.workspace }}/vs-code-extension/* release-files/

- name: Create release
Expand Down
18 changes: 15 additions & 3 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ jobs:
run: gradle -Dmaven.repo.local=${{ github.workspace }}/repo -Pdeps.pattern-syntax-parser.version=debug build
working-directory: pattern-syntax-plugin

- name: Publish jar file
- name: Publish jar files
uses: actions/upload-artifact@v4
with:
name: pattern-syntax-plugin
Expand Down Expand Up @@ -335,12 +335,24 @@ jobs:
name: examples
path: ${{ github.workspace }}/.samples

- name: Download syntax plugin
- name: Download syntax plugin distributive
uses: actions/download-artifact@v4
with:
name: pattern-syntax-plugin
path: ${{ github.workspace }}/.pattern-syntax-plugin

- name: Prepare jar archive of lite version
run: |
mv \
${{ github.workspace }}/.pattern-syntax-plugin/pattern-syntax-plugin-1.0-lite.jar \
${{ github.workspace }}/.pattern-syntax-plugin/lite.jar

- name: Prepare jar archive of standalone version
run: |
mv \
${{ github.workspace }}/.pattern-syntax-plugin/pattern-syntax-plugin-1.0-standalone.jar \
${{ github.workspace }}/.pattern-syntax-plugin/standalone.jar

- name: Setup java
uses: actions/setup-java@v5
with:
Expand All @@ -350,7 +362,7 @@ jobs:
- name: Run integration tests
run: |
uv run cli.py integration-tests \
--plugin-path ${{ github.workspace }}/.pattern-syntax-plugin/pattern-syntax-plugin-1.0.jar \
--plugin-dist ${{ github.workspace }}/.pattern-syntax-plugin/ \
--java-path $JAVA_HOME/bin \
--samples-dir ${{ github.workspace }}/.samples
working-directory: dev-tools
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- Removed typo in project docs ([#55](https://github.com/Nifacy/c4-patterns/issues/55))
- Added change log support ([#62](https://github.com/Nifacy/c4-patterns/issues/62))
- Added lite & standalone versions of syntax plugin based on AspectJ ([#56](https://github.com/Nifacy/c4-patterns/issues/56))

### Internal

Expand Down
211 changes: 189 additions & 22 deletions dev-tools/_exporter_factory.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import dataclasses
import shutil
import stat
import sys
from typing import Final, Protocol
Expand All @@ -15,14 +17,39 @@
_STRUCTURIZR_CLI_ARCHIVE_NAME: Final = "structurizr-cli.zip"
_STRUCTURIZR_CLI_DIR: Final = "structurizr-cli"
_STRUCTURIZR_CLI_SHELL_FILE: Final = "structurizr.sh"
_JWEAVER_NAME: Final = "aspectjweaver.jar"


class ExporterFactory(Protocol):
def __call__(self, java_path: Path, syntax_plugin_path: Path) -> _exporters.StructurizrWorkspaceExporter:
...


def _get_structurizr_cli_exporter_factory(downloader: CachedDownloader, release: _exporter_release.StructurizrCliRelease, temp_dir_path: Path, log: logging.Logger) -> ExporterFactory:
@dataclasses.dataclass(frozen=True, slots=True)
class JWeaverRelease:
url: str
version: str


@dataclasses.dataclass(frozen=True, slots=True)
class _ExporterConfigBase:
exporter_release: _exporter_release.ExporterRelease


@dataclasses.dataclass(frozen=True, slots=True)
class LiteVersionExporterConfig(_ExporterConfigBase):
jweaver_release: JWeaverRelease


@dataclasses.dataclass(frozen=True, slots=True)
class StandaloneVersionExporterConfig(_ExporterConfigBase):
pass


type ExporterConfig = LiteVersionExporterConfig | StandaloneVersionExporterConfig


def _prepare_structurizr_cli_environment(downloader: CachedDownloader, release: _exporter_release.StructurizrCliRelease, temp_dir_path: Path, log: logging.Logger) -> Path:
structurizr_archive_path = temp_dir_path / _STRUCTURIZR_CLI_ARCHIVE_NAME
structurizr_cli_dir = temp_dir_path / _STRUCTURIZR_CLI_DIR

Expand All @@ -41,44 +68,184 @@ def _get_structurizr_cli_exporter_factory(downloader: CachedDownloader, release:
current_permissions = script_path.stat().st_mode
script_path.chmod(current_permissions | stat.S_IXUSR)

def _create_structurizr_cli_exporter(java_path: Path, syntax_plugin_path: Path) -> _exporters.StructurizrCli:
return _exporters.StructurizrCli(
structurizr_cli_dir=structurizr_cli_dir,
java_path=java_path,
syntax_plugin_path=syntax_plugin_path,
)

return _create_structurizr_cli_exporter
return structurizr_cli_dir


def _get_structurizr_lite_exporter_factory(downloader: CachedDownloader, release: _exporter_release.StructurizrLiteRelease, temp_dir_path: Path, log: logging.Logger) -> ExporterFactory:
def _prepare_structurizr_lite_environment(
downloader: CachedDownloader,
release: _exporter_release.StructurizrLiteRelease,
temp_dir_path: Path,
log: logging.Logger,
) -> Path:
structurizr_lite_dir = temp_dir_path / "structurizr-lite"
structurizr_lite_dir.mkdir()

structurizr_lite_war_file = structurizr_lite_dir / "structurizr-lite.war"

structurizr_lite_dir.mkdir()

with _logging_tools.log_action(log, "Install structurizr lite"):
downloader.install_file(
url=release.url,
output_path=structurizr_lite_war_file,
)

def _create_structurizr_lite_exporter(java_path: Path, syntax_plugin_path: Path) -> _exporters.StructurizrLite:
return _exporters.StructurizrLite(
return structurizr_lite_dir


def _install_jweaver(downloader: CachedDownloader, temp_dir_path: Path, release: JWeaverRelease, log: logging.Logger) -> Path:
aspect_jweaver_path = temp_dir_path / _JWEAVER_NAME

with _logging_tools.log_action(log, "Install jweaver"):
downloader.install_file(
url=release.url,
output_path=aspect_jweaver_path,
)

return aspect_jweaver_path


def _get_structurizr_cli_lite_exporter_factory(
downloader: CachedDownloader,
jweaver_release: JWeaverRelease,
release: _exporter_release.StructurizrCliRelease,
temp_dir_path: Path,
log: logging.Logger,
) -> ExporterFactory:
structurizr_cli_dir = _prepare_structurizr_cli_environment(
downloader=downloader,
release=release,
temp_dir_path=temp_dir_path,
log=log,
)

jweaver_path = _install_jweaver(
downloader=downloader,
temp_dir_path=temp_dir_path,
release=jweaver_release,
log=log,
)

def _create_structurizr_cli_exporter(java_path: Path, syntax_plugin_path: Path) -> _exporters.StructurizrCliForLiteVersion:
return _exporters.StructurizrCliForLiteVersion(
structurizr_cli_dir=structurizr_cli_dir,
java_path=java_path,
syntax_plugin_path=syntax_plugin_path,
jweaver_path=jweaver_path,
)

return _create_structurizr_cli_exporter


def _get_structurizr_cli_standalone_exporter_factory(
downloader: CachedDownloader,
release: _exporter_release.StructurizrCliRelease,
temp_dir_path: Path,
log: logging.Logger,
) -> ExporterFactory:
structurizr_cli_dir = _prepare_structurizr_cli_environment(
downloader=downloader,
release=release,
temp_dir_path=temp_dir_path,
log=log,
)

def _create_structurizr_cli_exporter(java_path: Path, syntax_plugin_path: Path) -> _exporters.StructurizrCliForStandaloneVersion:
return _exporters.StructurizrCliForStandaloneVersion(
structurizr_cli_dir=structurizr_cli_dir,
java_path=java_path,
syntax_plugin_path=syntax_plugin_path,
)

return _create_structurizr_cli_exporter


def _get_structurizr_lite_lite_exporter_factory(
downloader: CachedDownloader,
jweaver_release: JWeaverRelease,
release: _exporter_release.StructurizrLiteRelease,
temp_dir_path: Path,
log: logging.Logger,
) -> ExporterFactory:
structurizr_lite_dir = _prepare_structurizr_lite_environment(
downloader=downloader,
release=release,
temp_dir_path=temp_dir_path,
log=log,
)

jweaver_path = _install_jweaver(
downloader=downloader,
temp_dir_path=temp_dir_path,
release=jweaver_release,
log=log,
)

def _create_exporter(java_path: Path, syntax_plugin_path: Path) -> _exporters.StructurizrLiteForLiteVersion:
return _exporters.StructurizrLiteForLiteVersion(
structurizr_lite_dir=structurizr_lite_dir,
java_path=java_path,
syntax_plugin_path=syntax_plugin_path,
stdout_path=temp_dir_path / "stdout.txt",
stderr_path=temp_dir_path / "stderr.txt",
log=log,
jweaver_path=jweaver_path,
)

return _create_structurizr_lite_exporter

return _create_exporter

def _get_structurizr_lite_standalone_exporter_factory(
downloader: CachedDownloader,
release: _exporter_release.StructurizrLiteRelease,
temp_dir_path: Path,
log: logging.Logger,
) -> ExporterFactory:
structurizr_lite_dir = _prepare_structurizr_lite_environment(
downloader=downloader,
release=release,
temp_dir_path=temp_dir_path,
log=log,
)

def _create_exporter(java_path: Path, syntax_plugin_path: Path) -> _exporters.StructurizrLiteForStandaloneVersion:
return _exporters.StructurizrLiteForStandaloneVersion(
structurizr_lite_dir=structurizr_lite_dir,
java_path=java_path,
syntax_plugin_path=syntax_plugin_path,
stdout_path=temp_dir_path / "stdout.txt",
stderr_path=temp_dir_path / "stderr.txt",
log=log,
)

def get_exporter_factory(downloader: CachedDownloader, release: _exporter_release.ExporterRelease, temp_dir_path: Path, log: logging.Logger) -> ExporterFactory:
match release:
case _exporter_release.StructurizrCliRelease() as cli_release:
return _get_structurizr_cli_exporter_factory(downloader, cli_release, temp_dir_path, log)
case _exporter_release.StructurizrLiteRelease() as lite_release:
return _get_structurizr_lite_exporter_factory(downloader, lite_release, temp_dir_path, log)
return _create_exporter

def get_exporter_factory(downloader: CachedDownloader, config: ExporterConfig, temp_dir_path: Path, log: logging.Logger) -> ExporterFactory:
match config:
case LiteVersionExporterConfig(exporter_release=_exporter_release.StructurizrCliRelease()):
return _get_structurizr_cli_lite_exporter_factory(
downloader=downloader,
jweaver_release=config.jweaver_release,
release=config.exporter_release,
temp_dir_path=temp_dir_path,
log=log,
)
case LiteVersionExporterConfig(exporter_release=_exporter_release.StructurizrLiteRelease()):
return _get_structurizr_lite_lite_exporter_factory(
downloader=downloader,
jweaver_release=config.jweaver_release,
release=config.exporter_release,
temp_dir_path=temp_dir_path,
log=log,
)
case StandaloneVersionExporterConfig(exporter_release=_exporter_release.StructurizrCliRelease()):
return _get_structurizr_cli_standalone_exporter_factory(
downloader=downloader,
release=config.exporter_release,
temp_dir_path=temp_dir_path,
log=log,
)
case StandaloneVersionExporterConfig(exporter_release=_exporter_release.StructurizrLiteRelease()):
return _get_structurizr_lite_standalone_exporter_factory(
downloader=downloader,
release=config.exporter_release,
temp_dir_path=temp_dir_path,
log=log,
)
12 changes: 8 additions & 4 deletions dev-tools/_exporters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@
from ._interface import ExportedWorkspace
from ._interface import ExportResult
from ._interface import ExportFailure
from ._structurizr_cli import StructurizrCli
from ._structurizr_lite import StructurizrLite
from ._structurizr_cli import StructurizrCliForLiteVersion
from ._structurizr_cli import StructurizrCliForStandaloneVersion
from ._structurizr_lite import StructurizrLiteForLiteVersion
from ._structurizr_lite import StructurizrLiteForStandaloneVersion


__all__ = [
"ExportedWorkspace",
"ExportFailure",
"ExportResult",
"StructurizrCli",
"StructurizrCliForLiteVersion",
"StructurizrCliForStandaloneVersion",
"StructurizrWorkspaceExporter",
"StructurizrLite",
"StructurizrLiteForLiteVersion",
"StructurizrLiteForStandaloneVersion",
]
Loading