opengate-gate-macro-fold 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. opengate_gate_macro_fold-0.1.2/.github/PULL_REQUEST_TEMPLATE.md +27 -0
  2. opengate_gate_macro_fold-0.1.2/.github/get_review.sh +119 -0
  3. opengate_gate_macro_fold-0.1.2/.github/workflows/ci.yaml +48 -0
  4. opengate_gate_macro_fold-0.1.2/.github/workflows/publish.yml +32 -0
  5. opengate_gate_macro_fold-0.1.2/.gitignore +16 -0
  6. opengate_gate_macro_fold-0.1.2/.pre-commit-config.yaml +10 -0
  7. opengate_gate_macro_fold-0.1.2/LICENSE +23 -0
  8. opengate_gate_macro_fold-0.1.2/Makefile +108 -0
  9. opengate_gate_macro_fold-0.1.2/PKG-INFO +158 -0
  10. opengate_gate_macro_fold-0.1.2/README.md +138 -0
  11. opengate_gate_macro_fold-0.1.2/docs/CODING_CONVENTIONS.md +498 -0
  12. opengate_gate_macro_fold-0.1.2/docs/COMMIT_CONVENTIONS.md +79 -0
  13. opengate_gate_macro_fold-0.1.2/docs/CONTRIBUTION.md +100 -0
  14. opengate_gate_macro_fold-0.1.2/docs/TESTING_CONVENTIONS.md +487 -0
  15. opengate_gate_macro_fold-0.1.2/docs/VERSION_UPGRADE_CONVENTIONS.md +155 -0
  16. opengate_gate_macro_fold-0.1.2/pyproject.toml +74 -0
  17. opengate_gate_macro_fold-0.1.2/script/update_version_in_files.sh +71 -0
  18. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/__init__.py +13 -0
  19. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/__main__.py +11 -0
  20. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/cli.py +140 -0
  21. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/config.py +41 -0
  22. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/io/__init__.py +0 -0
  23. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/io/readers.py +0 -0
  24. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/io/writers.py +0 -0
  25. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/logging_setup.py +56 -0
  26. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/macro_processing/__init__.py +0 -0
  27. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/macro_processing/folding.py +0 -0
  28. opengate_gate_macro_fold-0.1.2/src/opengate_gate_macro_fold/macro_processing/unfolding.py +0 -0
  29. opengate_gate_macro_fold-0.1.2/tests/__init__.py +0 -0
  30. opengate_gate_macro_fold-0.1.2/tests/unit/test_cli.py +142 -0
  31. opengate_gate_macro_fold-0.1.2/tests/unit/test_config.py +60 -0
  32. opengate_gate_macro_fold-0.1.2/tests/unit/test_logging_setup.py +51 -0
@@ -0,0 +1,27 @@
1
+ ## Description
2
+ Brief description of what this PR does.
3
+
4
+ ## Related Issues
5
+ Closes #123
6
+ Related to #456
7
+
8
+ ## Changes
9
+ - Change 1
10
+ - Change 2
11
+ - Change 3
12
+
13
+ ## Type of Change
14
+ - [ ] Bug fix (non-breaking)
15
+ - [ ] New feature (non-breaking)
16
+ - [ ] Breaking change
17
+ - [ ] Documentation update
18
+
19
+ ## Testing
20
+ Describe tests added or how changes were tested.
21
+
22
+ ## Checklist
23
+ - [ ] Code follows style guidelines
24
+ - [ ] Tests added and passing
25
+ - [ ] Documentation updated
26
+ - [ ] Commit messages are clear
27
+ - [ ] No merge conflicts
@@ -0,0 +1,119 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -euo pipefail
4
+
5
+ if ! command -v gh >/dev/null 2>&1; then
6
+ echo "Error: required tool 'gh' is not installed." >&2
7
+ exit 1
8
+ fi
9
+
10
+ if ! command -v jq >/dev/null 2>&1; then
11
+ echo "Error: required tool 'jq' is not installed." >&2
12
+ exit 1
13
+ fi
14
+
15
+ if ! gh auth status >/dev/null 2>&1; then
16
+ echo "Error: you are not signed in to gh. Run: gh auth login" >&2
17
+ exit 1
18
+ fi
19
+
20
+ BRANCH="$(git rev-parse --abbrev-ref HEAD)"
21
+ REPO_FULL="$(gh repo view --json nameWithOwner -q .nameWithOwner)"
22
+ OWNER="${REPO_FULL%/*}"
23
+ REPO="${REPO_FULL#*/}"
24
+
25
+ OUTPUT_DIR=".tmp/code-reviews"
26
+ mkdir -p "$OUTPUT_DIR"
27
+
28
+ BRANCH_SAFE="$(echo "$BRANCH" | sed -E 's/[^A-Za-z0-9._-]+/-/g')"
29
+ if [[ -z "$BRANCH_SAFE" ]]; then
30
+ BRANCH_SAFE="unknown-branch"
31
+ fi
32
+
33
+ FETCH_DATE="$(date '+%Y%m%d-%H%M%S')"
34
+ FETCH_DAY="${FETCH_DATE%%-*}"
35
+ EXISTING_COUNT="$({
36
+ find "$OUTPUT_DIR" -maxdepth 1 -type f \
37
+ -name "pr-code-review-${BRANCH_SAFE}-${FETCH_DAY}-*.md"
38
+ } | wc -l | tr -d '[:space:]')"
39
+ ORDER_NUMBER="$(printf '%02d' "$((EXISTING_COUNT + 1))")"
40
+ OUTPUT_FILE="${OUTPUT_DIR}/pr-code-review-${BRANCH_SAFE}-${FETCH_DATE}-${ORDER_NUMBER}.md"
41
+
42
+ PRS_JSON="$(gh pr list --state open --head "$BRANCH" --json number,title,url,headRefName,author 2>/dev/null || true)"
43
+
44
+ if [[ -z "$PRS_JSON" || "$PRS_JSON" == "[]" ]]; then
45
+ {
46
+ echo "# Review tasks"
47
+ echo
48
+ echo "No open PR found for branch: $BRANCH."
49
+ } >"$OUTPUT_FILE"
50
+ echo "Saved: $OUTPUT_FILE"
51
+ exit 0
52
+ fi
53
+
54
+ PR_NUMBERS="$(echo "$PRS_JSON" | jq -r '.[].number')"
55
+ FIRST_PR_NUMBER="$(echo "$PR_NUMBERS" | head -n1)"
56
+
57
+ GRAPHQL_QUERY='query($owner:String!, $repo:String!, $number:Int!) {
58
+ repository(owner:$owner, name:$repo) {
59
+ pullRequest(number:$number) {
60
+ number
61
+ title
62
+ url
63
+ headRefName
64
+ reviewThreads(first: 100) {
65
+ nodes {
66
+ isResolved
67
+ isOutdated
68
+ path
69
+ line
70
+ startLine
71
+ comments(first: 100) {
72
+ nodes {
73
+ author { login }
74
+ body
75
+ url
76
+ createdAt
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ }
83
+ }'
84
+
85
+ PR_JSON="$(gh api graphql -f query="$GRAPHQL_QUERY" -F owner="$OWNER" -F repo="$REPO" -F number="$FIRST_PR_NUMBER")"
86
+
87
+ UNRESOLVED_COUNT="$(echo "$PR_JSON" | jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length')"
88
+
89
+ {
90
+ echo "# Review tasks"
91
+ echo
92
+ echo "Repository: \`$REPO_FULL\` "
93
+ echo "Branch: \`$BRANCH\` "
94
+ echo "PR: [#${FIRST_PR_NUMBER}]($(echo "$PR_JSON" | jq -r '.data.repository.pullRequest.url')) - $(echo "$PR_JSON" | jq -r '.data.repository.pullRequest.title')"
95
+ echo
96
+ echo "## Unresolved threads"
97
+ echo
98
+
99
+ if [[ "$UNRESOLVED_COUNT" -eq 0 ]]; then
100
+ echo "No unresolved threads ✅"
101
+ else
102
+ echo "$PR_JSON" | jq -r '
103
+ .data.repository.pullRequest.reviewThreads.nodes
104
+ | map(select(.isResolved == false))
105
+ | to_entries[]
106
+ | .value as $t
107
+ | $t.comments.nodes[0] as $c
108
+ | "- [ ] "
109
+ + "[" + ($t.path // "(brak pliku)")
110
+ + (if ($t.line // $t.startLine) then ":L" + (($t.line // $t.startLine)|tostring) else "" end)
111
+ + "](" + ($c.url // "") + ")"
112
+ + " — @" + ($c.author.login // "unknown")
113
+ + (if $t.isOutdated then " *(outdated)*" else "" end)
114
+ + "\n > " + (($c.body // "") | gsub("\n"; " ") | gsub("\r"; " ") | .[0:50000])
115
+ '
116
+ fi
117
+ } >"$OUTPUT_FILE"
118
+
119
+ echo "Saved: $OUTPUT_FILE"
@@ -0,0 +1,48 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - develop
8
+ pull_request:
9
+ branches:
10
+ - main
11
+ - develop
12
+ workflow_dispatch:
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ concurrency:
18
+ group: ci-${{ github.workflow }}-${{ github.ref }}
19
+ cancel-in-progress: true
20
+
21
+ jobs:
22
+ check:
23
+ name: check (Python ${{ matrix.python-version }})
24
+ runs-on: ubuntu-latest
25
+ strategy:
26
+ fail-fast: false
27
+ matrix:
28
+ python-version: ["3.11", "3.12", "3.13", "3.14"]
29
+
30
+ steps:
31
+ - name: Checkout repository
32
+ uses: actions/checkout@v4
33
+
34
+ - name: Set up Python
35
+ uses: actions/setup-python@v5
36
+ with:
37
+ python-version: ${{ matrix.python-version }}
38
+
39
+ - name: Set up uv
40
+ uses: astral-sh/setup-uv@v5
41
+ with:
42
+ enable-cache: true
43
+
44
+ - name: Install dependencies
45
+ run: make init
46
+
47
+ - name: Run full validation
48
+ run: make check
@@ -0,0 +1,32 @@
1
+ name: publish
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - name: Install uv
13
+ uses: astral-sh/setup-uv@v5
14
+ - name: Build sdist and wheel
15
+ run: uv build
16
+ - uses: actions/upload-artifact@v4
17
+ with:
18
+ name: dist
19
+ path: dist/
20
+
21
+ publish:
22
+ needs: build
23
+ runs-on: ubuntu-latest
24
+ environment: pypi
25
+ permissions:
26
+ id-token: write
27
+ steps:
28
+ - uses: actions/download-artifact@v4
29
+ with:
30
+ name: dist
31
+ path: dist/
32
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,16 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .ruff_cache/
7
+ .coverage
8
+ .coverage.*
9
+ htmlcov/
10
+ .venv/
11
+ venv/
12
+ .env
13
+ .tmp/
14
+ examples/output/
15
+ uv.lock
16
+ .claude/
@@ -0,0 +1,10 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: make-check
5
+ name: Run make check
6
+ entry: make check
7
+ language: system
8
+ pass_filenames: false
9
+ always_run: true
10
+ stages: [pre-commit]
@@ -0,0 +1,23 @@
1
+ # MIT License
2
+
3
+ **Project:** opengate-gate-macro-fold
4
+
5
+ Copyright (c) 2026 Mateusz Jakub Bała
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
@@ -0,0 +1,108 @@
1
+ # FILE: Makefile
2
+ # ABOUT: Project helper tasks: installation, validation, and worktree
3
+ # management for feature branches created from develop.
4
+ # USAGE:
5
+ # make init | install | install-user | test | lint | format | typecheck | check
6
+ # make worktree BRANCH_NAME=feature/description
7
+ # make switch-to-worktree BRANCH_NAME=feature/description
8
+
9
+ SHELL := /bin/bash
10
+
11
+ # Parent directory for worktrees and directory for lock files.
12
+ WORKTREE_ROOT ?= ../worktrees
13
+ WORKTREE_LOCKS_DIR ?= .tmp/worktree-locks
14
+
15
+ .PHONY: init install install-user test lint format typecheck check worktree switch-to-worktree
16
+
17
+ # Install dependencies and create the virtual environment (uv).
18
+ init:
19
+ uv sync
20
+
21
+ # Install project dependencies and package into the local .venv.
22
+ install: init
23
+ @echo "Installed in local virtual environment: .venv"
24
+ @echo "Run via uv: uv run opengate-gate-macro-fold --help"
25
+ @echo "Or activate the environment: source .venv/bin/activate"
26
+
27
+ # Install the package for the current user (outside project .venv).
28
+ install-user:
29
+ python3 -m pip install --user -e .
30
+ @echo "Installed in user site-packages (--user)."
31
+ @echo "If needed, add ~/.local/bin to PATH."
32
+
33
+ # Run the full test suite.
34
+ test:
35
+ uv run pytest
36
+
37
+ # Check code style (lint).
38
+ lint:
39
+ uv run ruff check
40
+
41
+ # Format code.
42
+ format:
43
+ uv run ruff format
44
+
45
+ # Static type checking.
46
+ typecheck:
47
+ uv run mypy src/
48
+
49
+ # Full local validation: lint, formatting check, types, tests.
50
+ check:
51
+ uv run ruff check
52
+ uv run ruff format --check
53
+ uv run mypy src/
54
+ uv run pytest
55
+
56
+ # Create a worktree for the given branch if it does not already exist.
57
+ worktree:
58
+ @if [[ -z "$(BRANCH_NAME)" ]]; then \
59
+ echo "Error: set BRANCH_NAME, e.g. make worktree BRANCH_NAME=worktree/branch/name." >&2; \
60
+ exit 1; \
61
+ fi
62
+ @WORKTREE_DIR="$(WORKTREE_ROOT)/$$(echo "$(BRANCH_NAME)" | tr '/' '-')"; \
63
+ mkdir -p "$(WORKTREE_ROOT)"; \
64
+ if git worktree list --porcelain | grep -Fxq "branch refs/heads/$(BRANCH_NAME)"; then \
65
+ echo "Worktree for branch $(BRANCH_NAME) already exists."; \
66
+ exit 0; \
67
+ fi; \
68
+ if git show-ref --verify --quiet "refs/heads/$(BRANCH_NAME)"; then \
69
+ git worktree add "$$WORKTREE_DIR" "$(BRANCH_NAME)"; \
70
+ else \
71
+ git worktree add -b "$(BRANCH_NAME)" "$$WORKTREE_DIR" develop; \
72
+ fi; \
73
+ echo "Created worktree: $$WORKTREE_DIR (branch: $(BRANCH_NAME))."
74
+
75
+ # Switch to an existing worktree if it is not locked by another instance.
76
+ switch-to-worktree:
77
+ @if [[ -z "$(BRANCH_NAME)" ]]; then \
78
+ echo "Error: set BRANCH_NAME, e.g. make switch-to-worktree BRANCH_NAME=worktree/branch/name." >&2; \
79
+ exit 1; \
80
+ fi
81
+ @if ! git show-ref --verify --quiet "refs/heads/$(BRANCH_NAME)"; then \
82
+ echo "Error: the specified branch does not exist: $(BRANCH_NAME)." >&2; \
83
+ exit 1; \
84
+ fi
85
+ @WORKTREE_DIR="$$(git worktree list --porcelain | awk -v target="refs/heads/$(BRANCH_NAME)" '\
86
+ $$1=="worktree" { path=$$2 } \
87
+ $$1=="branch" && $$2==target { print path; exit }')"; \
88
+ if [[ -z "$$WORKTREE_DIR" ]]; then \
89
+ echo "Error: no worktree exists for branch $(BRANCH_NAME). First run make worktree BRANCH_NAME=$(BRANCH_NAME)." >&2; \
90
+ exit 1; \
91
+ fi; \
92
+ LOCK_FILE="$(WORKTREE_LOCKS_DIR)/$$(echo "$(BRANCH_NAME)" | tr '/' '-').lock"; \
93
+ mkdir -p "$(WORKTREE_LOCKS_DIR)"; \
94
+ if [[ -f "$$LOCK_FILE" ]]; then \
95
+ LOCK_PID="$$(cat "$$LOCK_FILE")"; \
96
+ if [[ -n "$$LOCK_PID" ]] && kill -0 "$$LOCK_PID" 2>/dev/null; then \
97
+ echo "Error: the worktree is already locked by another instance (PID: $$LOCK_PID)." >&2; \
98
+ echo "How to release it: stop the process with PID $$LOCK_PID (for example, close the shell holding the lock)." >&2; \
99
+ exit 1; \
100
+ fi; \
101
+ rm -f "$$LOCK_FILE"; \
102
+ fi; \
103
+ echo "$$BASHPID" > "$$LOCK_FILE"; \
104
+ cleanup() { rm -f "$$LOCK_FILE"; }; \
105
+ trap cleanup EXIT INT TERM; \
106
+ echo "Switched to $$WORKTREE_DIR. To release the lock, close this shell."; \
107
+ cd "$$WORKTREE_DIR"; \
108
+ "$${SHELL:-/bin/bash}" -i
@@ -0,0 +1,158 @@
1
+ Metadata-Version: 2.4
2
+ Name: opengate-gate-macro-fold
3
+ Version: 0.1.2
4
+ Summary: Folding and unfolding GATE 9 macros - from mono macro to set of macros and vice versa
5
+ Project-URL: Homepage, https://github.com/MateuszBala/opengate-gate-macro-fold
6
+ Project-URL: Repository, https://github.com/MateuszBala/opengate-gate-macro-fold
7
+ Author: Mateusz Jakub Bała
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: gate,macro,monte-carlo,opengate,simulation
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+
21
+ # opengate-gate-macro-fold
22
+
23
+ [![CI](https://github.com/MateuszBala/opengate-gate-macro-fold/actions/workflows/ci.yaml/badge.svg)](https://github.com/MateuszBala/opengate-gate-macro-fold/actions/workflows/ci.yaml)
24
+ [![Version](https://img.shields.io/badge/version-0.1.2-informational)](https://github.com/MateuszBala/opengate-gate-macro-fold/releases)
25
+ [![Standard Python](https://img.shields.io/badge/Python-3.11-blue?logo=python&logoColor=white)]()
26
+ [![Standard Python](https://img.shields.io/badge/Python-3.12-blue?logo=python&logoColor=white)]()
27
+ [![Standard Python](https://img.shields.io/badge/Python-3.13-blue?logo=python&logoColor=white)]()
28
+ [![Standard Python](https://img.shields.io/badge/Python-3.14-blue?logo=python&logoColor=white)]()
29
+ [![license](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE)
30
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
31
+ [![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/)
32
+ [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
33
+
34
+ `opengate-gate-macro-fold` is a utility for managing [GATE 9](https://github.com/OpenGATE/Gate) simulation macro files. It supports:
35
+
36
+ - **Folding**: combining a directory of macro files into a single mono macro file.
37
+ - **Unfolding**: splitting a mono macro file into a directory of macro files.
38
+
39
+ This workflow is practical when switching between batch execution environments (for example, clusters) and local or interactive simulation workflows.
40
+
41
+ ## Quick Start
42
+
43
+ ### Install From PyPI
44
+
45
+ ```bash
46
+ pip3 install opengate-gate-macro-fold
47
+ ```
48
+
49
+ ### Install From Source
50
+
51
+ ```bash
52
+ make init
53
+ make install
54
+ ```
55
+
56
+ ### Fold A Macro Set Into A Mono Macro
57
+
58
+ ```bash
59
+ opengate-gate-macro-fold \
60
+ --fold \
61
+ --input-macros-dir=path/to/macros/directory \
62
+ --output-dir=path/to/output/directory \
63
+ [--title="my-mono-macro.mac"]
64
+ ```
65
+
66
+ ### Unfold A Mono Macro Into A Macro Set
67
+
68
+ ```bash
69
+ opengate-gate-macro-fold \
70
+ --unfold \
71
+ --input-mono-macro-file=path/to/mono/macro.mac \
72
+ --output-dir=path/to/output/directory
73
+ ```
74
+
75
+ ## Command-Line Options
76
+
77
+ - `--fold`: enable fold mode (macro set -> mono macro).
78
+ - `--unfold`: enable unfold mode (mono macro -> macro set).
79
+ - `--input-macros-dir`: source directory used in fold mode.
80
+ - `--input-mono-macro-file`: source mono macro file used in unfold mode.
81
+ - `--output-dir`: destination directory for generated output.
82
+ - `--title`: optional title metadata for mono macro output.
83
+
84
+ ## Development
85
+
86
+ Common development commands:
87
+
88
+ ```bash
89
+ make lint
90
+ make format
91
+ make typecheck
92
+ make test
93
+ make check
94
+ ```
95
+
96
+ ### Pre-commit setup
97
+
98
+ You can install and activate `pre-commit` in two supported ways.
99
+
100
+ #### Option A (recommended): use `uv` in this repository
101
+
102
+ ```bash
103
+ uv add --dev pre-commit
104
+ uv sync
105
+ uv run pre-commit install --hook-type pre-commit
106
+ ```
107
+
108
+ Optional one-time verification on all files:
109
+
110
+ ```bash
111
+ uv run pre-commit run --all-files
112
+ ```
113
+
114
+ #### Option B: install `pre-commit` from Debian packages
115
+
116
+ ```bash
117
+ sudo apt update
118
+ sudo apt install -y pre-commit
119
+ pre-commit --version
120
+ pre-commit install --hook-type pre-commit
121
+ ```
122
+
123
+ Optional one-time verification on all files:
124
+
125
+ ```bash
126
+ pre-commit run --all-files
127
+ ```
128
+
129
+ The configured hook runs `make check` before each commit and blocks the commit if validation fails.
130
+
131
+ Project conventions and contribution standards:
132
+
133
+ - [Coding conventions](docs/CODING_CONVENTIONS.md)
134
+ - [Testing conventions](docs/TESTING_CONVENTIONS.md)
135
+ - [Commit conventions](docs/COMMIT_CONVENTIONS.md)
136
+ - [Contribution guide](docs/CONTRIBUTION.md)
137
+
138
+ ## License
139
+
140
+ MIT License
141
+
142
+ Contact: [GitHub](https://github.com/MateuszBala)
143
+
144
+ ## Author
145
+
146
+ The project was designed and implemented by Mateusz Jakub Bała.
147
+
148
+ Contact: [GitHub](https://github.com/MateuszBala)
149
+
150
+
151
+ ## Contribution
152
+
153
+ To contribute new functionality:
154
+
155
+ - create a branch from `develop`
156
+ - follow the [commit conventions](docs/COMMIT_CONVENTIONS.md)
157
+ - open a PR using the [PR template](.github/PULL_REQUEST_TEMPLATE.md)
158
+ - follow the [contribution guide](docs/CONTRIBUTION.md)
@@ -0,0 +1,138 @@
1
+ # opengate-gate-macro-fold
2
+
3
+ [![CI](https://github.com/MateuszBala/opengate-gate-macro-fold/actions/workflows/ci.yaml/badge.svg)](https://github.com/MateuszBala/opengate-gate-macro-fold/actions/workflows/ci.yaml)
4
+ [![Version](https://img.shields.io/badge/version-0.1.2-informational)](https://github.com/MateuszBala/opengate-gate-macro-fold/releases)
5
+ [![Standard Python](https://img.shields.io/badge/Python-3.11-blue?logo=python&logoColor=white)]()
6
+ [![Standard Python](https://img.shields.io/badge/Python-3.12-blue?logo=python&logoColor=white)]()
7
+ [![Standard Python](https://img.shields.io/badge/Python-3.13-blue?logo=python&logoColor=white)]()
8
+ [![Standard Python](https://img.shields.io/badge/Python-3.14-blue?logo=python&logoColor=white)]()
9
+ [![license](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE)
10
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
11
+ [![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/)
12
+ [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
13
+
14
+ `opengate-gate-macro-fold` is a utility for managing [GATE 9](https://github.com/OpenGATE/Gate) simulation macro files. It supports:
15
+
16
+ - **Folding**: combining a directory of macro files into a single mono macro file.
17
+ - **Unfolding**: splitting a mono macro file into a directory of macro files.
18
+
19
+ This workflow is practical when switching between batch execution environments (for example, clusters) and local or interactive simulation workflows.
20
+
21
+ ## Quick Start
22
+
23
+ ### Install From PyPI
24
+
25
+ ```bash
26
+ pip3 install opengate-gate-macro-fold
27
+ ```
28
+
29
+ ### Install From Source
30
+
31
+ ```bash
32
+ make init
33
+ make install
34
+ ```
35
+
36
+ ### Fold A Macro Set Into A Mono Macro
37
+
38
+ ```bash
39
+ opengate-gate-macro-fold \
40
+ --fold \
41
+ --input-macros-dir=path/to/macros/directory \
42
+ --output-dir=path/to/output/directory \
43
+ [--title="my-mono-macro.mac"]
44
+ ```
45
+
46
+ ### Unfold A Mono Macro Into A Macro Set
47
+
48
+ ```bash
49
+ opengate-gate-macro-fold \
50
+ --unfold \
51
+ --input-mono-macro-file=path/to/mono/macro.mac \
52
+ --output-dir=path/to/output/directory
53
+ ```
54
+
55
+ ## Command-Line Options
56
+
57
+ - `--fold`: enable fold mode (macro set -> mono macro).
58
+ - `--unfold`: enable unfold mode (mono macro -> macro set).
59
+ - `--input-macros-dir`: source directory used in fold mode.
60
+ - `--input-mono-macro-file`: source mono macro file used in unfold mode.
61
+ - `--output-dir`: destination directory for generated output.
62
+ - `--title`: optional title metadata for mono macro output.
63
+
64
+ ## Development
65
+
66
+ Common development commands:
67
+
68
+ ```bash
69
+ make lint
70
+ make format
71
+ make typecheck
72
+ make test
73
+ make check
74
+ ```
75
+
76
+ ### Pre-commit setup
77
+
78
+ You can install and activate `pre-commit` in two supported ways.
79
+
80
+ #### Option A (recommended): use `uv` in this repository
81
+
82
+ ```bash
83
+ uv add --dev pre-commit
84
+ uv sync
85
+ uv run pre-commit install --hook-type pre-commit
86
+ ```
87
+
88
+ Optional one-time verification on all files:
89
+
90
+ ```bash
91
+ uv run pre-commit run --all-files
92
+ ```
93
+
94
+ #### Option B: install `pre-commit` from Debian packages
95
+
96
+ ```bash
97
+ sudo apt update
98
+ sudo apt install -y pre-commit
99
+ pre-commit --version
100
+ pre-commit install --hook-type pre-commit
101
+ ```
102
+
103
+ Optional one-time verification on all files:
104
+
105
+ ```bash
106
+ pre-commit run --all-files
107
+ ```
108
+
109
+ The configured hook runs `make check` before each commit and blocks the commit if validation fails.
110
+
111
+ Project conventions and contribution standards:
112
+
113
+ - [Coding conventions](docs/CODING_CONVENTIONS.md)
114
+ - [Testing conventions](docs/TESTING_CONVENTIONS.md)
115
+ - [Commit conventions](docs/COMMIT_CONVENTIONS.md)
116
+ - [Contribution guide](docs/CONTRIBUTION.md)
117
+
118
+ ## License
119
+
120
+ MIT License
121
+
122
+ Contact: [GitHub](https://github.com/MateuszBala)
123
+
124
+ ## Author
125
+
126
+ The project was designed and implemented by Mateusz Jakub Bała.
127
+
128
+ Contact: [GitHub](https://github.com/MateuszBala)
129
+
130
+
131
+ ## Contribution
132
+
133
+ To contribute new functionality:
134
+
135
+ - create a branch from `develop`
136
+ - follow the [commit conventions](docs/COMMIT_CONVENTIONS.md)
137
+ - open a PR using the [PR template](.github/PULL_REQUEST_TEMPLATE.md)
138
+ - follow the [contribution guide](docs/CONTRIBUTION.md)