cola-cli 0.1.0__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 (53) hide show
  1. cola_cli-0.1.0/LICENSE +21 -0
  2. cola_cli-0.1.0/PKG-INFO +272 -0
  3. cola_cli-0.1.0/README.md +244 -0
  4. cola_cli-0.1.0/pyproject.toml +48 -0
  5. cola_cli-0.1.0/setup.cfg +4 -0
  6. cola_cli-0.1.0/src/cola_cli/__init__.py +3 -0
  7. cola_cli-0.1.0/src/cola_cli/__main__.py +3 -0
  8. cola_cli-0.1.0/src/cola_cli/builders.py +347 -0
  9. cola_cli-0.1.0/src/cola_cli/cli.py +177 -0
  10. cola_cli-0.1.0/src/cola_cli/common.py +98 -0
  11. cola_cli-0.1.0/src/cola_cli/environment.py +245 -0
  12. cola_cli-0.1.0/src/cola_cli/runtime.py +25 -0
  13. cola_cli-0.1.0/src/cola_cli/scripts/install.jl +10 -0
  14. cola_cli-0.1.0/src/cola_cli/scripts/locking.gradle +9 -0
  15. cola_cli-0.1.0/src/cola_cli/setup.py +163 -0
  16. cola_cli-0.1.0/src/cola_cli/sources.py +256 -0
  17. cola_cli-0.1.0/src/cola_cli/templates/common/.editorconfig.j2 +15 -0
  18. cola_cli-0.1.0/src/cola_cli/templates/common/.gitignore.j2 +20 -0
  19. cola_cli-0.1.0/src/cola_cli/templates/common/cola.toml.j2 +8 -0
  20. cola_cli-0.1.0/src/cola_cli/templates/cpp/.clang-format.j2 +6 -0
  21. cola_cli-0.1.0/src/cola_cli/templates/cpp/.clang-tidy.j2 +4 -0
  22. cola_cli-0.1.0/src/cola_cli/templates/cpp/CMakeLists.txt.j2 +51 -0
  23. cola_cli-0.1.0/src/cola_cli/templates/cpp/include/{{ name }}.hh.j2 +23 -0
  24. cola_cli-0.1.0/src/cola_cli/templates/cpp/src/{{ name }}.cc.j2 +3 -0
  25. cola_cli-0.1.0/src/cola_cli/templates/fortran/.fprettify.rc.j2 +2 -0
  26. cola_cli-0.1.0/src/cola_cli/templates/fortran/CMakeLists.txt.j2 +63 -0
  27. cola_cli-0.1.0/src/cola_cli/templates/fortran/src/{{ name }}.f90.j2 +73 -0
  28. cola_cli-0.1.0/src/cola_cli/templates/java/CMakeLists.txt.j2 +33 -0
  29. cola_cli-0.1.0/src/cola_cli/templates/java/build.gradle.kts.j2 +35 -0
  30. cola_cli-0.1.0/src/cola_cli/templates/java/config/checkstyle/checkstyle.xml.j2 +19 -0
  31. cola_cli-0.1.0/src/cola_cli/templates/java/settings.gradle.kts.j2 +1 -0
  32. cola_cli-0.1.0/src/cola_cli/templates/java/src/main/java/org/cola/generated/{{ package }}/{{ name }}Converter.java.j2 +9 -0
  33. cola_cli-0.1.0/src/cola_cli/templates/java/src/main/java/org/cola/generated/{{ package }}/{{ name }}Generator.java.j2 +9 -0
  34. cola_cli-0.1.0/src/cola_cli/templates/java/src/main/java/org/cola/generated/{{ package }}/{{ name }}Writer.java.j2 +9 -0
  35. cola_cli-0.1.0/src/cola_cli/templates/julia/.JuliaFormatter.toml.j2 +2 -0
  36. cola_cli-0.1.0/src/cola_cli/templates/julia/Project.toml.j2 +10 -0
  37. cola_cli-0.1.0/src/cola_cli/templates/julia/src/{{ name }}.jl.j2 +17 -0
  38. cola_cli-0.1.0/src/cola_cli/templates/python/pyproject.toml.j2 +23 -0
  39. cola_cli-0.1.0/src/cola_cli/templates/python/src/{{ package }}/__init__.py.j2 +1 -0
  40. cola_cli-0.1.0/src/cola_cli/templates/python/src/{{ package }}/filters.py.j2 +18 -0
  41. cola_cli-0.1.0/src/cola_cli/templates/quality/.cmake-format.yaml.j2 +13 -0
  42. cola_cli-0.1.0/src/cola_cli/templates/quality/CMakePresets.json.j2 +22 -0
  43. cola_cli-0.1.0/src/cola_cli.egg-info/PKG-INFO +272 -0
  44. cola_cli-0.1.0/src/cola_cli.egg-info/SOURCES.txt +51 -0
  45. cola_cli-0.1.0/src/cola_cli.egg-info/dependency_links.txt +1 -0
  46. cola_cli-0.1.0/src/cola_cli.egg-info/entry_points.txt +2 -0
  47. cola_cli-0.1.0/src/cola_cli.egg-info/requires.txt +12 -0
  48. cola_cli-0.1.0/src/cola_cli.egg-info/top_level.txt +1 -0
  49. cola_cli-0.1.0/tests/test_builders.py +57 -0
  50. cola_cli-0.1.0/tests/test_environment.py +118 -0
  51. cola_cli-0.1.0/tests/test_integration.py +145 -0
  52. cola_cli-0.1.0/tests/test_setup.py +234 -0
  53. cola_cli-0.1.0/tests/test_sources.py +116 -0
cola_cli-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Novikov Artemii
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,272 @@
1
+ Metadata-Version: 2.4
2
+ Name: cola-cli
3
+ Version: 0.1.0
4
+ Summary: Global COLA environment and module manager for Linux and macOS
5
+ Author: Novikov Artemii
6
+ License-Expression: MIT
7
+ Keywords: cola,physics,cli,environment,package-manager
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Operating System :: POSIX :: Linux
12
+ Classifier: Operating System :: MacOS
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.11
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: click<9,>=8.1
18
+ Requires-Dist: jinja2<4,>=3.1
19
+ Requires-Dist: uv<1,>=0.9
20
+ Provides-Extra: test
21
+ Requires-Dist: pytest>=8; extra == "test"
22
+ Requires-Dist: ruff>=0.9; extra == "test"
23
+ Requires-Dist: build; extra == "test"
24
+ Provides-Extra: release
25
+ Requires-Dist: build; extra == "release"
26
+ Requires-Dist: twine>=6; extra == "release"
27
+ Dynamic: license-file
28
+
29
+ # cola-cli
30
+
31
+ Standalone Python CLI for building and running COLA modules on **Linux and macOS**.
32
+ Installing the CLI does not compile COLA or import `colapy`.
33
+
34
+ This MVP has **one global environment per user**. Commands never search the current
35
+ directory for an environment. There are no project environments, named environments
36
+ or `--env` options. Completed build generations are internal revisions of that one
37
+ environment; only one is active at a time.
38
+
39
+ ## Installation
40
+
41
+ Requires Python 3.11+:
42
+
43
+ ```sh
44
+ python3 -m pip install cola-cli
45
+ cola --version
46
+ cola doctor
47
+ ```
48
+
49
+ For an isolated CLI installation, use `pipx install cola-cli` or
50
+ `uv tool install cola-cli`. The managed COLA runtime is still the single global
51
+ environment described below.
52
+
53
+ From a local checkout:
54
+
55
+ ```sh
56
+ python3 -m pip install /path/to/COLA-CLI
57
+ cola --version
58
+ cola doctor
59
+ ```
60
+
61
+ The distribution is `cola-cli`, the import package is `cola_cli`, and the executable
62
+ is `cola`. `colapy` is installed separately inside the managed runtime. The updated
63
+ COLA-PY distribution uses `colapy` for its legacy executable to avoid overwriting
64
+ `cola`; `python -m colapy` remains available.
65
+
66
+ Install Git, CMake, Make and a C++17/20 compiler before building. Optional bridges
67
+ require a Fortran compiler, Julia 1.10+, or JDK 17+ respectively. Java filter projects
68
+ also need a Gradle Wrapper or Gradle. `uv` is a dependency of the CLI; Python packages
69
+ are resolved and installed by uv, Julia packages by Pkg, and Java dependencies by
70
+ Gradle. Native code uses the existing CMake projects.
71
+
72
+ The MVP uses explicitly selected native sources and existing external libraries.
73
+ It does **not** yet integrate Spack or automatically resolve/install external
74
+ scientific libraries such as Geant4 or ROOT. Provide existing native dependency
75
+ prefixes with `cola init --prefix /path/to/library` (repeatable).
76
+
77
+ ## First calculation
78
+
79
+ ```sh
80
+ # Local sources, including any uncommitted changes:
81
+ cola init --core /path/to/COLA --bindings /path/to/COLA-PY
82
+
83
+ # Or use upstream repositories. The first successful build records exact commits:
84
+ # cola init
85
+
86
+ cola add /path/to/MyPythonFilters
87
+ cola build
88
+ cola run --config calculation.xml --steps 10
89
+ ```
90
+
91
+ `cola run` automatically loads the native libraries exported by the active modules,
92
+ including the language bridges. Repeat `--library NAME` to override that list. Python
93
+ filters must be installed as packages; the caller's `PYTHONPATH` and user site are not
94
+ used. The working directory is preserved for calculation data/configuration paths.
95
+
96
+ ```sh
97
+ cola add github:org/MyPhysics --ref v1.2.0
98
+ cola add /path/to/MyRepository --subdirectory packages/MyPhysics
99
+ cola list
100
+ cola list --json
101
+ cola exec python -c 'import colapy; print(colapy.__version__)'
102
+ ```
103
+
104
+ CMake applications can be managed too: declare `libraries = []` in their
105
+ `cola.toml`, list the required modules in `depends`, and provide a normal CMake
106
+ `install(TARGETS ... RUNTIME DESTINATION bin)` rule. Run installed executables with
107
+ `cola exec MyApplication ...`; the active native prefix's `bin` directory is on PATH.
108
+ For an example, see the `cola.toml` and installation rules in AAMCC-COLA.
109
+
110
+ `add` records the desired composition but does not replace the running environment.
111
+ It resolves Git refs to commits and snapshots local inputs. Non-locked builds take a
112
+ fresh snapshot of local sources; run `cola build` after editing a local module.
113
+ Local sources are copied, not installed editable, and builds do not modify checkouts.
114
+ Build outputs, `.git`, virtual environments and common caches are excluded.
115
+ Untracked build inputs are included. External symlinks and directory symlinks are
116
+ rejected because they cannot be represented by this snapshot format.
117
+ Modules must build from a source archive without requiring a live `.git` directory.
118
+
119
+ ## Other languages
120
+
121
+ Add local bridges **before** their filter modules to use your checkouts:
122
+
123
+ ```sh
124
+ cola add /path/to/COLA_Fortran
125
+ cola add /path/to/MyFortranFilters
126
+
127
+ cola add /path/to/COLA_JVM
128
+ cola add /path/to/MyJavaFilters
129
+
130
+ cola add /path/to/COLA_Julia
131
+ cola add /path/to/MyJuliaFilters
132
+
133
+ cola build
134
+ ```
135
+
136
+ Missing standard bridges are added to the desired specification automatically using
137
+ their upstream Git repositories. To select a bridge version, explicitly add its Git
138
+ URL with `--ref`. Fortran and Java filter modules must expose their existing COLA
139
+ CMake integration. The Fortran port is currently CMake-based; fpm is not a backend in
140
+ this MVP. Julia packages use `Project.toml` and the COLA package UUID. Java projects
141
+ produce their runtime dependency JAR using their existing Gradle/CMake integration.
142
+
143
+ ## Module metadata
144
+
145
+ `pyproject.toml`, `Project.toml` and `CMakeLists.txt` are detected automatically.
146
+ For a CMake module, the default native module name is the CMake project name.
147
+ Use `--library` if the installed COLA module has a different name.
148
+
149
+ An optional `cola.toml` makes the integration explicit:
150
+
151
+ ```toml
152
+ [module]
153
+ name = "my-physics"
154
+ backend = "cmake" # cmake, python or julia
155
+ depends = ["fortran"] # module identifiers, not version expressions
156
+ libraries = ["MyPhysics"] # native directories under prefix/lib; [] for pure packages
157
+ cmake_args = ["-DENABLE_OPTION=ON"]
158
+ ```
159
+
160
+ Dependencies remain in their native manifests. `depends` only orders explicitly
161
+ selected COLA modules; it is not a second dependency/version solver. The reserved
162
+ module identifiers are `core`, `python`, `fortran`, `java` and `julia`.
163
+ The MVP builds the core, Java/Fortran bridges, Julia packages, native filters, then
164
+ Python packages. Dependencies requiring the reverse phase order are rejected with
165
+ an explicit error; arbitrary cross-language build dependency cycles are unsupported.
166
+
167
+ CLI overrides are available for existing projects:
168
+
169
+ ```sh
170
+ cola add /path/to/physics --name my-physics --backend cmake \
171
+ --requires fortran --library MyPhysics --cmake-arg=-DENABLE_OPTION=ON
172
+ ```
173
+
174
+ The scaffold generator is carried over from COLA-PY and adds `cola.toml`:
175
+
176
+ ```sh
177
+ cola setup project --name MyPhysics --language python --prefix ./modules
178
+ ```
179
+
180
+ Scaffolds contain declarations/stubs: implement them before adding and building.
181
+ C++ scaffolds must also define `LoadCOLAModule`, build a shared library and install
182
+ it under `lib/<module>`, as explained in their generated CMakeLists.
183
+
184
+ ## Locks and updates
185
+
186
+ ```sh
187
+ cola build # new local snapshots and language dependency resolution
188
+ cola sync --locked # restore the active lock into a fresh generation
189
+ cola update my-physics # follow that module's Git ref, resolve, build and activate
190
+ cola update # update all selected Git refs
191
+ cola remove my-physics # edit desired composition
192
+ cola build # activate removal
193
+ ```
194
+
195
+ Every successful build writes `current/cola.lock`. It records source SHA-256s,
196
+ Git commits, toolchain versions/flags, the uv project and lock, Julia's Project and
197
+ Manifest, Gradle dependency locks, and captured CMake FetchContent source trees.
198
+ Python build-system requirements are included in the uv environment; first-party
199
+ packages are then built with those backends using `--no-build-isolation`.
200
+ First-party Python packages therefore share one compatible set of build backends
201
+ in this MVP; mutually incompatible build-system requirements produce a uv error.
202
+
203
+ `sync --locked` requires unchanged desired composition and toolchain. It uses the
204
+ stored source snapshots even when the original local folder changed or was deleted.
205
+ It restores language locks and supplies captured FetchContent sources to CMake in
206
+ disconnected mode. Missing or modified snapshots cause an error. This is a
207
+ same-machine dependency/source lock, **not** a portable binary archive or a promise
208
+ of bit-identical output. System libraries, explicit external prefixes, arbitrary
209
+ downloads in custom build scripts, and Gradle plugin artifact contents are outside
210
+ the MVP's complete reproducibility guarantee. Do not use changing Maven SNAPSHOT
211
+ dependencies for locked builds.
212
+
213
+ ## State and isolation
214
+
215
+ Default storage on both platforms is `~/.local/share/cola`. Set `COLA_HOME` to an
216
+ absolute location to move the **single** global store (also useful in CI):
217
+
218
+ ```text
219
+ global.json desired composition
220
+ sources/<sha256>/ stored source inputs
221
+ cache/uv/ uv-managed dependency cache
222
+ generations/<id>/ prefix, Python venv, Julia project/depot, builds, build.log, cola.lock
223
+ current -> generations/id active completed build
224
+ ```
225
+
226
+ Each build uses a new native prefix, Python venv and Julia environment. It is checked
227
+ by importing `colapy` and loading its declared native modules before an atomic pointer
228
+ switch. A failed build leaves the previous runtime active and retains its log.
229
+ Concurrent mutating commands are rejected. Running calculations keep using their
230
+ original physical generation. Old generations are deliberately retained in this MVP;
231
+ do not delete one while a calculation is using it. Runtime isolation is dependency
232
+ isolation, not a sandbox for third-party source/build scripts.
233
+
234
+ ## Development and checks
235
+
236
+ ```sh
237
+ python3 -m pip install -e '.[test]'
238
+ pytest
239
+ ruff check .
240
+ python3 -m build
241
+ ```
242
+
243
+ Integration tests against real COLA repositories are opt-in:
244
+
245
+ ```sh
246
+ COLA_CLI_CORE=/path/to/COLA COLA_CLI_BINDINGS=/path/to/COLA-PY pytest -m integration -v
247
+ ```
248
+
249
+ The CI workflow runs the unit suite, wheel/resource checks and a real core/Python
250
+ build and locked restore on Linux and macOS. Optional bridge checks require their
251
+ corresponding compilers/runtimes and can be enabled with `COLA_CLI_PORTS` pointing to
252
+ the common parent directory of the four port checkouts.
253
+
254
+ ## Publishing a release
255
+
256
+ The PyPI distribution name is `cola-cli`; the command remains `cola`. Version 0.1.0
257
+ is an alpha MVP. Increment `project.version` in `pyproject.toml` before every new
258
+ release. From the package directory, in a development virtual environment:
259
+
260
+ ```sh
261
+ python -m pip install -e '.[test,release]'
262
+ ruff check src tests
263
+ pytest -m 'not integration'
264
+ # Use a fresh output directory to avoid uploading artifacts from older releases.
265
+ python -m build --outdir /tmp/cola-cli-release-0.1.0
266
+ python -m twine check --strict /tmp/cola-cli-release-0.1.0/*
267
+ python -m twine upload --repository pypi /tmp/cola-cli-release-0.1.0/*
268
+ ```
269
+
270
+ Authenticate with a PyPI API token configured through Twine or `~/.pypirc`; never
271
+ commit tokens to the repository. Once the package has its own GitHub repository,
272
+ PyPI Trusted Publishing can replace the local token-based upload.
@@ -0,0 +1,244 @@
1
+ # cola-cli
2
+
3
+ Standalone Python CLI for building and running COLA modules on **Linux and macOS**.
4
+ Installing the CLI does not compile COLA or import `colapy`.
5
+
6
+ This MVP has **one global environment per user**. Commands never search the current
7
+ directory for an environment. There are no project environments, named environments
8
+ or `--env` options. Completed build generations are internal revisions of that one
9
+ environment; only one is active at a time.
10
+
11
+ ## Installation
12
+
13
+ Requires Python 3.11+:
14
+
15
+ ```sh
16
+ python3 -m pip install cola-cli
17
+ cola --version
18
+ cola doctor
19
+ ```
20
+
21
+ For an isolated CLI installation, use `pipx install cola-cli` or
22
+ `uv tool install cola-cli`. The managed COLA runtime is still the single global
23
+ environment described below.
24
+
25
+ From a local checkout:
26
+
27
+ ```sh
28
+ python3 -m pip install /path/to/COLA-CLI
29
+ cola --version
30
+ cola doctor
31
+ ```
32
+
33
+ The distribution is `cola-cli`, the import package is `cola_cli`, and the executable
34
+ is `cola`. `colapy` is installed separately inside the managed runtime. The updated
35
+ COLA-PY distribution uses `colapy` for its legacy executable to avoid overwriting
36
+ `cola`; `python -m colapy` remains available.
37
+
38
+ Install Git, CMake, Make and a C++17/20 compiler before building. Optional bridges
39
+ require a Fortran compiler, Julia 1.10+, or JDK 17+ respectively. Java filter projects
40
+ also need a Gradle Wrapper or Gradle. `uv` is a dependency of the CLI; Python packages
41
+ are resolved and installed by uv, Julia packages by Pkg, and Java dependencies by
42
+ Gradle. Native code uses the existing CMake projects.
43
+
44
+ The MVP uses explicitly selected native sources and existing external libraries.
45
+ It does **not** yet integrate Spack or automatically resolve/install external
46
+ scientific libraries such as Geant4 or ROOT. Provide existing native dependency
47
+ prefixes with `cola init --prefix /path/to/library` (repeatable).
48
+
49
+ ## First calculation
50
+
51
+ ```sh
52
+ # Local sources, including any uncommitted changes:
53
+ cola init --core /path/to/COLA --bindings /path/to/COLA-PY
54
+
55
+ # Or use upstream repositories. The first successful build records exact commits:
56
+ # cola init
57
+
58
+ cola add /path/to/MyPythonFilters
59
+ cola build
60
+ cola run --config calculation.xml --steps 10
61
+ ```
62
+
63
+ `cola run` automatically loads the native libraries exported by the active modules,
64
+ including the language bridges. Repeat `--library NAME` to override that list. Python
65
+ filters must be installed as packages; the caller's `PYTHONPATH` and user site are not
66
+ used. The working directory is preserved for calculation data/configuration paths.
67
+
68
+ ```sh
69
+ cola add github:org/MyPhysics --ref v1.2.0
70
+ cola add /path/to/MyRepository --subdirectory packages/MyPhysics
71
+ cola list
72
+ cola list --json
73
+ cola exec python -c 'import colapy; print(colapy.__version__)'
74
+ ```
75
+
76
+ CMake applications can be managed too: declare `libraries = []` in their
77
+ `cola.toml`, list the required modules in `depends`, and provide a normal CMake
78
+ `install(TARGETS ... RUNTIME DESTINATION bin)` rule. Run installed executables with
79
+ `cola exec MyApplication ...`; the active native prefix's `bin` directory is on PATH.
80
+ For an example, see the `cola.toml` and installation rules in AAMCC-COLA.
81
+
82
+ `add` records the desired composition but does not replace the running environment.
83
+ It resolves Git refs to commits and snapshots local inputs. Non-locked builds take a
84
+ fresh snapshot of local sources; run `cola build` after editing a local module.
85
+ Local sources are copied, not installed editable, and builds do not modify checkouts.
86
+ Build outputs, `.git`, virtual environments and common caches are excluded.
87
+ Untracked build inputs are included. External symlinks and directory symlinks are
88
+ rejected because they cannot be represented by this snapshot format.
89
+ Modules must build from a source archive without requiring a live `.git` directory.
90
+
91
+ ## Other languages
92
+
93
+ Add local bridges **before** their filter modules to use your checkouts:
94
+
95
+ ```sh
96
+ cola add /path/to/COLA_Fortran
97
+ cola add /path/to/MyFortranFilters
98
+
99
+ cola add /path/to/COLA_JVM
100
+ cola add /path/to/MyJavaFilters
101
+
102
+ cola add /path/to/COLA_Julia
103
+ cola add /path/to/MyJuliaFilters
104
+
105
+ cola build
106
+ ```
107
+
108
+ Missing standard bridges are added to the desired specification automatically using
109
+ their upstream Git repositories. To select a bridge version, explicitly add its Git
110
+ URL with `--ref`. Fortran and Java filter modules must expose their existing COLA
111
+ CMake integration. The Fortran port is currently CMake-based; fpm is not a backend in
112
+ this MVP. Julia packages use `Project.toml` and the COLA package UUID. Java projects
113
+ produce their runtime dependency JAR using their existing Gradle/CMake integration.
114
+
115
+ ## Module metadata
116
+
117
+ `pyproject.toml`, `Project.toml` and `CMakeLists.txt` are detected automatically.
118
+ For a CMake module, the default native module name is the CMake project name.
119
+ Use `--library` if the installed COLA module has a different name.
120
+
121
+ An optional `cola.toml` makes the integration explicit:
122
+
123
+ ```toml
124
+ [module]
125
+ name = "my-physics"
126
+ backend = "cmake" # cmake, python or julia
127
+ depends = ["fortran"] # module identifiers, not version expressions
128
+ libraries = ["MyPhysics"] # native directories under prefix/lib; [] for pure packages
129
+ cmake_args = ["-DENABLE_OPTION=ON"]
130
+ ```
131
+
132
+ Dependencies remain in their native manifests. `depends` only orders explicitly
133
+ selected COLA modules; it is not a second dependency/version solver. The reserved
134
+ module identifiers are `core`, `python`, `fortran`, `java` and `julia`.
135
+ The MVP builds the core, Java/Fortran bridges, Julia packages, native filters, then
136
+ Python packages. Dependencies requiring the reverse phase order are rejected with
137
+ an explicit error; arbitrary cross-language build dependency cycles are unsupported.
138
+
139
+ CLI overrides are available for existing projects:
140
+
141
+ ```sh
142
+ cola add /path/to/physics --name my-physics --backend cmake \
143
+ --requires fortran --library MyPhysics --cmake-arg=-DENABLE_OPTION=ON
144
+ ```
145
+
146
+ The scaffold generator is carried over from COLA-PY and adds `cola.toml`:
147
+
148
+ ```sh
149
+ cola setup project --name MyPhysics --language python --prefix ./modules
150
+ ```
151
+
152
+ Scaffolds contain declarations/stubs: implement them before adding and building.
153
+ C++ scaffolds must also define `LoadCOLAModule`, build a shared library and install
154
+ it under `lib/<module>`, as explained in their generated CMakeLists.
155
+
156
+ ## Locks and updates
157
+
158
+ ```sh
159
+ cola build # new local snapshots and language dependency resolution
160
+ cola sync --locked # restore the active lock into a fresh generation
161
+ cola update my-physics # follow that module's Git ref, resolve, build and activate
162
+ cola update # update all selected Git refs
163
+ cola remove my-physics # edit desired composition
164
+ cola build # activate removal
165
+ ```
166
+
167
+ Every successful build writes `current/cola.lock`. It records source SHA-256s,
168
+ Git commits, toolchain versions/flags, the uv project and lock, Julia's Project and
169
+ Manifest, Gradle dependency locks, and captured CMake FetchContent source trees.
170
+ Python build-system requirements are included in the uv environment; first-party
171
+ packages are then built with those backends using `--no-build-isolation`.
172
+ First-party Python packages therefore share one compatible set of build backends
173
+ in this MVP; mutually incompatible build-system requirements produce a uv error.
174
+
175
+ `sync --locked` requires unchanged desired composition and toolchain. It uses the
176
+ stored source snapshots even when the original local folder changed or was deleted.
177
+ It restores language locks and supplies captured FetchContent sources to CMake in
178
+ disconnected mode. Missing or modified snapshots cause an error. This is a
179
+ same-machine dependency/source lock, **not** a portable binary archive or a promise
180
+ of bit-identical output. System libraries, explicit external prefixes, arbitrary
181
+ downloads in custom build scripts, and Gradle plugin artifact contents are outside
182
+ the MVP's complete reproducibility guarantee. Do not use changing Maven SNAPSHOT
183
+ dependencies for locked builds.
184
+
185
+ ## State and isolation
186
+
187
+ Default storage on both platforms is `~/.local/share/cola`. Set `COLA_HOME` to an
188
+ absolute location to move the **single** global store (also useful in CI):
189
+
190
+ ```text
191
+ global.json desired composition
192
+ sources/<sha256>/ stored source inputs
193
+ cache/uv/ uv-managed dependency cache
194
+ generations/<id>/ prefix, Python venv, Julia project/depot, builds, build.log, cola.lock
195
+ current -> generations/id active completed build
196
+ ```
197
+
198
+ Each build uses a new native prefix, Python venv and Julia environment. It is checked
199
+ by importing `colapy` and loading its declared native modules before an atomic pointer
200
+ switch. A failed build leaves the previous runtime active and retains its log.
201
+ Concurrent mutating commands are rejected. Running calculations keep using their
202
+ original physical generation. Old generations are deliberately retained in this MVP;
203
+ do not delete one while a calculation is using it. Runtime isolation is dependency
204
+ isolation, not a sandbox for third-party source/build scripts.
205
+
206
+ ## Development and checks
207
+
208
+ ```sh
209
+ python3 -m pip install -e '.[test]'
210
+ pytest
211
+ ruff check .
212
+ python3 -m build
213
+ ```
214
+
215
+ Integration tests against real COLA repositories are opt-in:
216
+
217
+ ```sh
218
+ COLA_CLI_CORE=/path/to/COLA COLA_CLI_BINDINGS=/path/to/COLA-PY pytest -m integration -v
219
+ ```
220
+
221
+ The CI workflow runs the unit suite, wheel/resource checks and a real core/Python
222
+ build and locked restore on Linux and macOS. Optional bridge checks require their
223
+ corresponding compilers/runtimes and can be enabled with `COLA_CLI_PORTS` pointing to
224
+ the common parent directory of the four port checkouts.
225
+
226
+ ## Publishing a release
227
+
228
+ The PyPI distribution name is `cola-cli`; the command remains `cola`. Version 0.1.0
229
+ is an alpha MVP. Increment `project.version` in `pyproject.toml` before every new
230
+ release. From the package directory, in a development virtual environment:
231
+
232
+ ```sh
233
+ python -m pip install -e '.[test,release]'
234
+ ruff check src tests
235
+ pytest -m 'not integration'
236
+ # Use a fresh output directory to avoid uploading artifacts from older releases.
237
+ python -m build --outdir /tmp/cola-cli-release-0.1.0
238
+ python -m twine check --strict /tmp/cola-cli-release-0.1.0/*
239
+ python -m twine upload --repository pypi /tmp/cola-cli-release-0.1.0/*
240
+ ```
241
+
242
+ Authenticate with a PyPI API token configured through Twine or `~/.pypirc`; never
243
+ commit tokens to the repository. Once the package has its own GitHub repository,
244
+ PyPI Trusted Publishing can replace the local token-based upload.
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "cola-cli"
7
+ version = "0.1.0"
8
+ description = "Global COLA environment and module manager for Linux and macOS"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{name = "Novikov Artemii"}]
14
+ keywords = ["cola", "physics", "cli", "environment", "package-manager"]
15
+ dependencies = ["click>=8.1,<9", "jinja2>=3.1,<4", "uv>=0.9,<1"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Science/Research",
20
+ "Operating System :: POSIX :: Linux",
21
+ "Operating System :: MacOS",
22
+ "Programming Language :: Python :: 3",
23
+ ]
24
+
25
+ [project.scripts]
26
+ cola = "cola_cli.cli:main"
27
+
28
+ [project.optional-dependencies]
29
+ test = ["pytest>=8", "ruff>=0.9", "build"]
30
+ release = ["build", "twine>=6"]
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["src"]
34
+
35
+ [tool.setuptools.package-data]
36
+ cola_cli = ["templates/**/*.j2", "templates/**/.*.j2", "scripts/*.jl", "scripts/*.gradle"]
37
+
38
+ [tool.pytest.ini_options]
39
+ testpaths = ["tests"]
40
+ pythonpath = ["src"]
41
+ markers = ["integration: builds actual COLA sources using external tools"]
42
+
43
+ [tool.ruff]
44
+ line-length = 120
45
+ target-version = "py311"
46
+
47
+ [tool.ruff.lint]
48
+ select = ["E", "F", "I", "B", "UP"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """The CLI never imports COLA's native Python bindings."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ main()