tlaplus-cli 0.1.7__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.
- tlaplus_cli-0.1.7/LICENSE +21 -0
- tlaplus_cli-0.1.7/MANIFEST.in +4 -0
- tlaplus_cli-0.1.7/PKG-INFO +142 -0
- tlaplus_cli-0.1.7/README.md +114 -0
- tlaplus_cli-0.1.7/pyproject.toml +137 -0
- tlaplus_cli-0.1.7/setup.cfg +4 -0
- tlaplus_cli-0.1.7/tests/test_build_tlc_module.py +81 -0
- tlaplus_cli-0.1.7/tests/test_check_java.py +59 -0
- tlaplus_cli-0.1.7/tests/test_cli.py +43 -0
- tlaplus_cli-0.1.7/tests/test_download_tla2tools.py +147 -0
- tlaplus_cli-0.1.7/tests/test_run_tlc.py +78 -0
- tlaplus_cli-0.1.7/tla/__init__.py +0 -0
- tlaplus_cli-0.1.7/tla/build_tlc_module.py +70 -0
- tlaplus_cli-0.1.7/tla/check_java.py +82 -0
- tlaplus_cli-0.1.7/tla/cli.py +70 -0
- tlaplus_cli-0.1.7/tla/config.py +63 -0
- tlaplus_cli-0.1.7/tla/download_tla2tools.py +109 -0
- tlaplus_cli-0.1.7/tla/py.typed +0 -0
- tlaplus_cli-0.1.7/tla/resources/default_config.yaml +23 -0
- tlaplus_cli-0.1.7/tla/run_tlc.py +45 -0
- tlaplus_cli-0.1.7/tla/settings.py +48 -0
- tlaplus_cli-0.1.7/tlaplus_cli.egg-info/PKG-INFO +142 -0
- tlaplus_cli-0.1.7/tlaplus_cli.egg-info/SOURCES.txt +25 -0
- tlaplus_cli-0.1.7/tlaplus_cli.egg-info/dependency_links.txt +1 -0
- tlaplus_cli-0.1.7/tlaplus_cli.egg-info/entry_points.txt +2 -0
- tlaplus_cli-0.1.7/tlaplus_cli.egg-info/requires.txt +5 -0
- tlaplus_cli-0.1.7/tlaplus_cli.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Denis Nikolskiy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tlaplus-cli
|
|
3
|
+
Version: 0.1.7
|
|
4
|
+
Summary: TLA+ tools: download TLC, compile custom modules, run model checker
|
|
5
|
+
Author-email: Denis Nikolskiy <codeomatics@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/nikolskiy/tlaplus-cli
|
|
8
|
+
Project-URL: Repository, https://github.com/nikolskiy/tlaplus-cli
|
|
9
|
+
Project-URL: Issues, https://github.com/nikolskiy/tlaplus-cli/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/nikolskiy/tlaplus-cli/blob/main/CHANGELOG.md
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: typer<1.0.0,>=0.22.0
|
|
23
|
+
Requires-Dist: requests<3.0.0,>=2.31.0
|
|
24
|
+
Requires-Dist: pyyaml<7.0,>=6.0
|
|
25
|
+
Requires-Dist: platformdirs<5.0,>=4.0
|
|
26
|
+
Requires-Dist: pydantic<3.0.0,>=2.12.5
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# TLA+ CLI
|
|
30
|
+
|
|
31
|
+
Command-line tool for working with TLA+ specifications and the TLC model checker.
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
Install system-wide via uv tool
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
uv tool install git+https://github.com/nikolskiy/tlaplus-cli
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Upgrade:
|
|
42
|
+
```bash
|
|
43
|
+
uv tool upgrade tlaplus-cli
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Uninstall
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
uv tool uninstall tlaplus-cli
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
### Download TLC
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Download stable release
|
|
58
|
+
tla download
|
|
59
|
+
|
|
60
|
+
# Download nightly build
|
|
61
|
+
tla download --nightly
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Check Java Version
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
tla check-java
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Compile Custom Java Modules
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
tla build
|
|
74
|
+
|
|
75
|
+
# Verbose output
|
|
76
|
+
tla build --verbose
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Compiles `.java` files from `workspace/modules/` into `workspace/classes/`.
|
|
80
|
+
|
|
81
|
+
### Run TLC
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
tla tlc <spec_name>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
For example:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
tla tlc queue
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Configuration
|
|
94
|
+
|
|
95
|
+
On first run, a default config is created at:
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
~/.config/tla/config.yaml
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Edit this file to set your workspace path and TLC options:
|
|
102
|
+
|
|
103
|
+
```yaml
|
|
104
|
+
tla:
|
|
105
|
+
jar_name: tla2tools.jar
|
|
106
|
+
urls:
|
|
107
|
+
stable: https://github.com/tlaplus/tlaplus/releases/latest/download/tla2tools.jar
|
|
108
|
+
nightly: https://tla.msr-inria.inria.fr/tlatoolbox/ci/dist/tla2tools.jar
|
|
109
|
+
|
|
110
|
+
workspace:
|
|
111
|
+
root: . # Project root (relative to CWD)
|
|
112
|
+
spec_dir: spec # Directory containing .tla files
|
|
113
|
+
modules_dir: modules # Directory containing .java files
|
|
114
|
+
classes_dir: classes # Directory for compiled .class files
|
|
115
|
+
|
|
116
|
+
tlc:
|
|
117
|
+
java_class: tlc2.TLC
|
|
118
|
+
overrides_class: tlc2.overrides.TLCOverrides
|
|
119
|
+
|
|
120
|
+
java:
|
|
121
|
+
min_version: 11
|
|
122
|
+
opts:
|
|
123
|
+
- "-XX:+IgnoreUnrecognizedVMOptions"
|
|
124
|
+
- "-XX:+UseParallelGC"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Directory Layout
|
|
128
|
+
|
|
129
|
+
| Directory | Purpose | Location |
|
|
130
|
+
|---|---|---|
|
|
131
|
+
| Config | `config.yaml` | `~/.config/tla/` |
|
|
132
|
+
| Cache | `tla2tools.jar` | `~/.cache/tla/` |
|
|
133
|
+
| Workspace | specs + modules + classes | Set via `workspace.root` in config |
|
|
134
|
+
|
|
135
|
+
## Note on Package Name
|
|
136
|
+
|
|
137
|
+
This package is distributed on PyPI as **`tlaplus-cli`** but imports as **`tla`**. There is a separate, unrelated [`tla`](https://pypi.org/project/tla/) package on PyPI (a TLA+ parser). If you have both installed, they will conflict. In practice this is unlikely since they serve different purposes, but be aware of it.
|
|
138
|
+
|
|
139
|
+
## Dependencies
|
|
140
|
+
|
|
141
|
+
* **Java >= 11**: Required for TLC.
|
|
142
|
+
* [**uv**](https://docs.astral.sh/uv/getting-started/installation/): For installing the tool.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# TLA+ CLI
|
|
2
|
+
|
|
3
|
+
Command-line tool for working with TLA+ specifications and the TLC model checker.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Install system-wide via uv tool
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
uv tool install git+https://github.com/nikolskiy/tlaplus-cli
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Upgrade:
|
|
14
|
+
```bash
|
|
15
|
+
uv tool upgrade tlaplus-cli
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Uninstall
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv tool uninstall tlaplus-cli
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
### Download TLC
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Download stable release
|
|
30
|
+
tla download
|
|
31
|
+
|
|
32
|
+
# Download nightly build
|
|
33
|
+
tla download --nightly
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Check Java Version
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
tla check-java
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Compile Custom Java Modules
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
tla build
|
|
46
|
+
|
|
47
|
+
# Verbose output
|
|
48
|
+
tla build --verbose
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Compiles `.java` files from `workspace/modules/` into `workspace/classes/`.
|
|
52
|
+
|
|
53
|
+
### Run TLC
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
tla tlc <spec_name>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
For example:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
tla tlc queue
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
On first run, a default config is created at:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
~/.config/tla/config.yaml
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Edit this file to set your workspace path and TLC options:
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
tla:
|
|
77
|
+
jar_name: tla2tools.jar
|
|
78
|
+
urls:
|
|
79
|
+
stable: https://github.com/tlaplus/tlaplus/releases/latest/download/tla2tools.jar
|
|
80
|
+
nightly: https://tla.msr-inria.inria.fr/tlatoolbox/ci/dist/tla2tools.jar
|
|
81
|
+
|
|
82
|
+
workspace:
|
|
83
|
+
root: . # Project root (relative to CWD)
|
|
84
|
+
spec_dir: spec # Directory containing .tla files
|
|
85
|
+
modules_dir: modules # Directory containing .java files
|
|
86
|
+
classes_dir: classes # Directory for compiled .class files
|
|
87
|
+
|
|
88
|
+
tlc:
|
|
89
|
+
java_class: tlc2.TLC
|
|
90
|
+
overrides_class: tlc2.overrides.TLCOverrides
|
|
91
|
+
|
|
92
|
+
java:
|
|
93
|
+
min_version: 11
|
|
94
|
+
opts:
|
|
95
|
+
- "-XX:+IgnoreUnrecognizedVMOptions"
|
|
96
|
+
- "-XX:+UseParallelGC"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Directory Layout
|
|
100
|
+
|
|
101
|
+
| Directory | Purpose | Location |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| Config | `config.yaml` | `~/.config/tla/` |
|
|
104
|
+
| Cache | `tla2tools.jar` | `~/.cache/tla/` |
|
|
105
|
+
| Workspace | specs + modules + classes | Set via `workspace.root` in config |
|
|
106
|
+
|
|
107
|
+
## Note on Package Name
|
|
108
|
+
|
|
109
|
+
This package is distributed on PyPI as **`tlaplus-cli`** but imports as **`tla`**. There is a separate, unrelated [`tla`](https://pypi.org/project/tla/) package on PyPI (a TLA+ parser). If you have both installed, they will conflict. In practice this is unlikely since they serve different purposes, but be aware of it.
|
|
110
|
+
|
|
111
|
+
## Dependencies
|
|
112
|
+
|
|
113
|
+
* **Java >= 11**: Required for TLC.
|
|
114
|
+
* [**uv**](https://docs.astral.sh/uv/getting-started/installation/): For installing the tool.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tlaplus-cli"
|
|
7
|
+
version = "0.1.7"
|
|
8
|
+
description = "TLA+ tools: download TLC, compile custom modules, run model checker"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"typer>=0.22.0,<1.0.0",
|
|
13
|
+
"requests>=2.31.0,<3.0.0",
|
|
14
|
+
"pyyaml>=6.0,<7.0",
|
|
15
|
+
"platformdirs>=4.0,<5.0",
|
|
16
|
+
"pydantic>=2.12.5,<3.0.0",
|
|
17
|
+
]
|
|
18
|
+
authors = [
|
|
19
|
+
{name = "Denis Nikolskiy", email = "codeomatics@gmail.com"}
|
|
20
|
+
]
|
|
21
|
+
license = "MIT"
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Development Status :: 3 - Alpha",
|
|
24
|
+
"Programming Language :: Python :: 3",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"Operating System :: OS Independent",
|
|
29
|
+
"Topic :: Software Development :: Build Tools",
|
|
30
|
+
"Topic :: Utilities",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/nikolskiy/tlaplus-cli"
|
|
35
|
+
Repository = "https://github.com/nikolskiy/tlaplus-cli"
|
|
36
|
+
Issues = "https://github.com/nikolskiy/tlaplus-cli/issues"
|
|
37
|
+
Changelog = "https://github.com/nikolskiy/tlaplus-cli/blob/main/CHANGELOG.md"
|
|
38
|
+
|
|
39
|
+
[project.scripts]
|
|
40
|
+
tla = "tla.cli:main"
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
include = ["tla*"]
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.package-data]
|
|
46
|
+
tla = ["resources/default_config.yaml", "py.typed"]
|
|
47
|
+
|
|
48
|
+
[dependency-groups]
|
|
49
|
+
dev = [
|
|
50
|
+
"pytest>=9.0.2,<10.0.0",
|
|
51
|
+
"pytest-cov>=7.0.0,<8.0.0",
|
|
52
|
+
"pytest-mock>=3.15.1,<4.0.0",
|
|
53
|
+
"ruff>=0.9.0,<1.0.0",
|
|
54
|
+
"mypy>=1.0.0,<2.0.0",
|
|
55
|
+
"types-PyYAML>=6.0.12.12,<7.0.0.0",
|
|
56
|
+
"types-requests>=2.31.0.2,<3.0.0.0",
|
|
57
|
+
"poethepoet>=0.24.0,<1.0.0",
|
|
58
|
+
"detect-secrets>=1.5.0,<2.0.0",
|
|
59
|
+
"pre-commit>=3.5.0,<4.0.0",
|
|
60
|
+
"pre-commit-hooks>=6.0.0,<7.0.0",
|
|
61
|
+
"twine>=6.0.0,<7.0.0",
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
[tool.pytest.ini_options]
|
|
65
|
+
addopts = "--cov=tla --cov-report=term-missing"
|
|
66
|
+
testpaths = ["tests"]
|
|
67
|
+
|
|
68
|
+
[tool.ruff]
|
|
69
|
+
line-length = 120
|
|
70
|
+
target-version = "py311"
|
|
71
|
+
|
|
72
|
+
[tool.ruff.lint]
|
|
73
|
+
select = [
|
|
74
|
+
"F", # Pyflakes: logic errors
|
|
75
|
+
"E", # pycodestyle errors
|
|
76
|
+
"W", # pycodestyle warnings
|
|
77
|
+
"I", # isort: import sorting
|
|
78
|
+
"N", # pep8-naming: naming conventions
|
|
79
|
+
"UP", # pyupgrade: upgrade syntax for newer python versions
|
|
80
|
+
"PL", # Pylint: various checks (convention, refactor, warning, etc.)
|
|
81
|
+
"B", # flake8-bugbear: finds likely bugs and design problems
|
|
82
|
+
"SIM", # flake8-simplify: suggests simpler python constructs
|
|
83
|
+
"C4", # flake8-comprehensions: better list/set/dict comprehensions
|
|
84
|
+
"PIE", # flake8-pie: miscellaneous lints
|
|
85
|
+
"TCH", # flake8-type-checking: move imports to type-checking blocks
|
|
86
|
+
"PGH", # pygrep-hooks: regex based checks
|
|
87
|
+
"G", # flake8-logging-format: validate logging format strings
|
|
88
|
+
"RUF", # Ruff-specific rules
|
|
89
|
+
"PTH", # flake8-use-pathlib: replace os.path with pathlib
|
|
90
|
+
"ARG", # flake8-unused-arguments: find unused function arguments
|
|
91
|
+
"RET", # flake8-return: cleaner return logic
|
|
92
|
+
"TRY", # tryceratops: prevent exception handling anti-patterns
|
|
93
|
+
]
|
|
94
|
+
ignore = [
|
|
95
|
+
"PLR2004", # Magic value used in comparison
|
|
96
|
+
"PLW1510", # subprocess.run without explicit check
|
|
97
|
+
]
|
|
98
|
+
|
|
99
|
+
[tool.ruff.lint.per-file-ignores]
|
|
100
|
+
"tests/*" = [
|
|
101
|
+
"ARG001", # Unused arguments are common in tests (fixtures)
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
[tool.poe.tasks]
|
|
105
|
+
check = "pre-commit run --all-files"
|
|
106
|
+
lint = ["lint-ruff", "type-check"]
|
|
107
|
+
lint-ruff = "ruff check ."
|
|
108
|
+
type-check = "mypy ."
|
|
109
|
+
fix = ["format", "lint-fix"]
|
|
110
|
+
format = "ruff format ."
|
|
111
|
+
lint-fix = "ruff check --fix ."
|
|
112
|
+
test = "pytest"
|
|
113
|
+
install-hooks = "pre-commit install --install-hooks"
|
|
114
|
+
audit = "detect-secrets audit .secrets.baseline"
|
|
115
|
+
build = "uv build"
|
|
116
|
+
clean = "rm -rf dist"
|
|
117
|
+
|
|
118
|
+
twine-check = "twine check dist/*.whl dist/*.tar.gz"
|
|
119
|
+
|
|
120
|
+
[tool.poe.tasks.check-release]
|
|
121
|
+
sequence = [
|
|
122
|
+
"check",
|
|
123
|
+
"clean",
|
|
124
|
+
"build",
|
|
125
|
+
"twine-check",
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
[tool.mypy]
|
|
129
|
+
python_version = "3.11"
|
|
130
|
+
strict = true
|
|
131
|
+
ignore_missing_imports = false
|
|
132
|
+
exclude = ["build", "tests/"]
|
|
133
|
+
|
|
134
|
+
# Per-module overrides for libraries without strict types
|
|
135
|
+
[[tool.mypy.overrides]]
|
|
136
|
+
module = "platformdirs.*"
|
|
137
|
+
ignore_missing_imports = true
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from tla import build_tlc_module
|
|
6
|
+
|
|
7
|
+
# Define paths relative to the test file
|
|
8
|
+
# Check if javac is available
|
|
9
|
+
JAVAC_AVAILABLE = shutil.which("javac") is not None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.mark.skipif(not JAVAC_AVAILABLE, reason="javac not found")
|
|
13
|
+
def test_build_integration(mocker, tmp_path, queue_dir, base_settings):
|
|
14
|
+
"""
|
|
15
|
+
Integration test for build_tlc_module.build().
|
|
16
|
+
Uses the actual files in tla-example and the real tla2tools.jar (if available).
|
|
17
|
+
Verified output classes are generated in a temporary directory.
|
|
18
|
+
"""
|
|
19
|
+
# Create a temporary classes directory
|
|
20
|
+
classes_dir = tmp_path / "classes"
|
|
21
|
+
|
|
22
|
+
# Configure base_settings for this test
|
|
23
|
+
base_settings.workspace.root = queue_dir
|
|
24
|
+
base_settings.workspace.classes_dir = classes_dir
|
|
25
|
+
|
|
26
|
+
# Patch load_config to return our mock config
|
|
27
|
+
mocker.patch("tla.build_tlc_module.load_config", return_value=base_settings)
|
|
28
|
+
|
|
29
|
+
# Patch workspace_root to return the example directory
|
|
30
|
+
mocker.patch("tla.build_tlc_module.workspace_root", return_value=queue_dir)
|
|
31
|
+
|
|
32
|
+
# Run build
|
|
33
|
+
# We catch typer.Exit just in case, though it shouldn't be raised on success
|
|
34
|
+
try:
|
|
35
|
+
build_tlc_module.build(verbose=True)
|
|
36
|
+
except SystemExit as e:
|
|
37
|
+
# build() raises typer.Exit(1) on failure
|
|
38
|
+
# If it raises, we fail the test
|
|
39
|
+
assert e.code == 0, "Build failed with SystemExit"
|
|
40
|
+
|
|
41
|
+
# Verify outputs
|
|
42
|
+
assert classes_dir.exists(), "Classes directory not created"
|
|
43
|
+
|
|
44
|
+
# Verify TLCOverrides.class exists
|
|
45
|
+
# The source is modules/tlc2/overrides/TLCOverrides.java
|
|
46
|
+
# Package is tlc2.overrides, so output should be in tlc2/overrides/
|
|
47
|
+
output_class = classes_dir / "tlc2/overrides/TLCOverrides.class"
|
|
48
|
+
assert output_class.exists(), f"Class file not found at {output_class}"
|
|
49
|
+
|
|
50
|
+
# Verify META-INF service file
|
|
51
|
+
service_file = classes_dir / "META-INF/services/tlc2.overrides.ITLCOverrides"
|
|
52
|
+
assert service_file.exists(), "Service file not found"
|
|
53
|
+
|
|
54
|
+
content = service_file.read_text().strip()
|
|
55
|
+
assert content == "tlc2.overrides.TLCOverrides", f"Unexpected service file content: {content}"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.mark.skipif(not JAVAC_AVAILABLE, reason="javac not found")
|
|
59
|
+
def test_build_custom_overrides(mocker, tmp_path, queue_dir, base_settings):
|
|
60
|
+
"""
|
|
61
|
+
Test build with custom overrides class configuration.
|
|
62
|
+
"""
|
|
63
|
+
classes_dir = tmp_path / "classes"
|
|
64
|
+
|
|
65
|
+
# Configure custom override
|
|
66
|
+
custom_override = "com.example.MyOverrides"
|
|
67
|
+
base_settings.tlc.overrides_class = custom_override
|
|
68
|
+
base_settings.workspace.root = queue_dir
|
|
69
|
+
base_settings.workspace.classes_dir = classes_dir
|
|
70
|
+
|
|
71
|
+
mocker.patch("tla.build_tlc_module.load_config", return_value=base_settings)
|
|
72
|
+
mocker.patch("tla.build_tlc_module.workspace_root", return_value=queue_dir)
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
build_tlc_module.build(verbose=False)
|
|
76
|
+
except SystemExit as e:
|
|
77
|
+
assert e.code == 0
|
|
78
|
+
|
|
79
|
+
service_file = classes_dir / "META-INF/services/tlc2.overrides.ITLCOverrides"
|
|
80
|
+
assert service_file.exists()
|
|
81
|
+
assert service_file.read_text().strip() == custom_override
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from unittest.mock import MagicMock
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
import typer
|
|
5
|
+
|
|
6
|
+
from tla import check_java
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_parse_java_version():
|
|
10
|
+
"""Test parsing of Java version strings."""
|
|
11
|
+
assert check_java.parse_java_version("1.8.0_202") == 8
|
|
12
|
+
assert check_java.parse_java_version("9.0.4") == 9
|
|
13
|
+
assert check_java.parse_java_version("11.0.2") == 11
|
|
14
|
+
assert check_java.parse_java_version("17") == 17
|
|
15
|
+
assert check_java.parse_java_version("21.0.1") == 21
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_get_java_version_success(mocker):
|
|
19
|
+
"""Test successful retrieval of Java version."""
|
|
20
|
+
mock_run = mocker.patch("subprocess.run")
|
|
21
|
+
# Simulate java -version output (it usually goes to stderr)
|
|
22
|
+
mock_run.return_value = MagicMock(
|
|
23
|
+
stdout="", stderr='openjdk version "11.0.2" 2019-01-15\nOpenJDK Runtime Environment 18.9...'
|
|
24
|
+
)
|
|
25
|
+
mocker.patch("shutil.which", return_value="/usr/bin/java")
|
|
26
|
+
|
|
27
|
+
assert check_java.get_java_version() == "11.0.2"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_get_java_version_not_found(mocker):
|
|
31
|
+
"""Test when java is not found in PATH."""
|
|
32
|
+
mocker.patch("shutil.which", return_value=None)
|
|
33
|
+
assert check_java.get_java_version() is None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_check_java_version_ok(mocker):
|
|
37
|
+
"""Test check passes when version is sufficient."""
|
|
38
|
+
mocker.patch("tla.check_java.get_java_version", return_value="11.0.2")
|
|
39
|
+
# Should not raise
|
|
40
|
+
check_java.check_java_version(11)
|
|
41
|
+
check_java.check_java_version(8)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_check_java_version_too_low(mocker):
|
|
45
|
+
"""Test check fails when version is too low."""
|
|
46
|
+
mocker.patch("tla.check_java.get_java_version", return_value="1.8.0_202")
|
|
47
|
+
|
|
48
|
+
with pytest.raises(typer.Exit) as e:
|
|
49
|
+
check_java.check_java_version(11)
|
|
50
|
+
assert e.value.exit_code == 1
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_check_java_version_missing(mocker):
|
|
54
|
+
"""Test check fails when java is missing."""
|
|
55
|
+
mocker.patch("tla.check_java.get_java_version", return_value=None)
|
|
56
|
+
|
|
57
|
+
with pytest.raises(typer.Exit) as e:
|
|
58
|
+
check_java.check_java_version(11)
|
|
59
|
+
assert e.value.exit_code == 1
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
|
|
2
|
+
import pytest
|
|
3
|
+
import typer
|
|
4
|
+
from typer.testing import CliRunner
|
|
5
|
+
|
|
6
|
+
from tla.cli import app, version_callback
|
|
7
|
+
|
|
8
|
+
runner = CliRunner()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_version_callback_exits(mocker):
|
|
12
|
+
"""Test version callback exits after printing."""
|
|
13
|
+
mock_metadata = mocker.patch("importlib.metadata.metadata")
|
|
14
|
+
mock_metadata.return_value = {
|
|
15
|
+
"Name": "tlaplus-cli",
|
|
16
|
+
"Version": "1.2.3",
|
|
17
|
+
"Summary": "Test summary",
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
with pytest.raises(typer.Exit):
|
|
21
|
+
version_callback(True)
|
|
22
|
+
|
|
23
|
+
mock_metadata.assert_called_once_with("tlaplus-cli")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_cli_version_flag(mocker):
|
|
27
|
+
"""Test 'tla --version' command."""
|
|
28
|
+
mock_metadata = mocker.patch("importlib.metadata.metadata")
|
|
29
|
+
mock_metadata.return_value = {
|
|
30
|
+
"Name": "tlaplus-cli",
|
|
31
|
+
"Version": "1.2.3",
|
|
32
|
+
"Summary": "Test summary",
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Running the CLI with --version
|
|
36
|
+
result = runner.invoke(app, ["--version"])
|
|
37
|
+
|
|
38
|
+
# It should exit with 0
|
|
39
|
+
assert result.exit_code == 0
|
|
40
|
+
assert "tlaplus-cli v1.2.3" in result.stdout
|
|
41
|
+
assert "Test summary" in result.stdout
|
|
42
|
+
|
|
43
|
+
mock_metadata.assert_called_once_with("tlaplus-cli")
|