plinth-cli 0.2.0__py3-none-any.whl

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 (49) hide show
  1. plinth/__init__.py +1 -0
  2. plinth/__main__.py +5 -0
  3. plinth/add.py +97 -0
  4. plinth/blueprints/ci/github/dot-github/workflows/ci.yaml.j2 +38 -0
  5. plinth/blueprints/ci/gitlab/dot-gitlab-ci.yml.j2 +36 -0
  6. plinth/blueprints/gitops/applicationset.yaml.j2 +46 -0
  7. plinth/blueprints/gitops/values.yaml.j2 +2 -0
  8. plinth/blueprints/repo/app/README.md.j2 +63 -0
  9. plinth/blueprints/repo/app/dagger.json.j2 +8 -0
  10. plinth/blueprints/repo/app/dot-dagger/dot-gitignore +3 -0
  11. plinth/blueprints/repo/app/dot-dagger/pyproject.toml +12 -0
  12. plinth/blueprints/repo/app/dot-dagger/src/ci/__init__.py +3 -0
  13. plinth/blueprints/repo/app/dot-dagger/src/ci/main.py.j2 +133 -0
  14. plinth/blueprints/repo/app/dot-gitignore +4 -0
  15. plinth/blueprints/repo/gitops/README.md.j2 +53 -0
  16. plinth/blueprints/repo/gitops/apps/project.yaml.j2 +15 -0
  17. plinth/blueprints/repo/gitops/bootstrap/root.yaml.j2 +20 -0
  18. plinth/blueprints/repo/gitops/charts/workload/Chart.yaml +5 -0
  19. plinth/blueprints/repo/gitops/charts/workload/templates/_helpers.tpl +13 -0
  20. plinth/blueprints/repo/gitops/charts/workload/templates/deployment.yaml +61 -0
  21. plinth/blueprints/repo/gitops/charts/workload/templates/service.yaml +20 -0
  22. plinth/blueprints/repo/gitops/charts/workload/values.yaml +9 -0
  23. plinth/blueprints/repo/gitops/scripts/bootstrap-local.sh.j2 +23 -0
  24. plinth/blueprints/workload/common/Dockerfile.j2 +14 -0
  25. plinth/blueprints/workload/common/app/__init__.py +0 -0
  26. plinth/blueprints/workload/common/dot-dockerignore +4 -0
  27. plinth/blueprints/workload/common/score.yaml.j2 +33 -0
  28. plinth/blueprints/workload/common/tests/__init__.py +0 -0
  29. plinth/blueprints/workload/modular-monolith/app/main.py.j2 +63 -0
  30. plinth/blueprints/workload/modular-monolith/app/modules/__init__.py +5 -0
  31. plinth/blueprints/workload/modular-monolith/app/modules/example.py +12 -0
  32. plinth/blueprints/workload/modular-monolith/tests/test_main.py.j2 +42 -0
  33. plinth/blueprints/workload/service/app/main.py.j2 +54 -0
  34. plinth/blueprints/workload/service/tests/test_main.py.j2 +41 -0
  35. plinth/blueprints/workload/worker/app/main.py.j2 +44 -0
  36. plinth/blueprints/workload/worker/tests/test_main.py.j2 +26 -0
  37. plinth/cli.py +185 -0
  38. plinth/config.py +51 -0
  39. plinth/loader.py +49 -0
  40. plinth/plan.py +70 -0
  41. plinth/render.py +119 -0
  42. plinth/schema.py +158 -0
  43. plinth/wizard.py +129 -0
  44. plinth/write.py +72 -0
  45. plinth_cli-0.2.0.dist-info/METADATA +174 -0
  46. plinth_cli-0.2.0.dist-info/RECORD +49 -0
  47. plinth_cli-0.2.0.dist-info/WHEEL +4 -0
  48. plinth_cli-0.2.0.dist-info/entry_points.txt +2 -0
  49. plinth_cli-0.2.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,174 @@
1
+ Metadata-Version: 2.5
2
+ Name: plinth-cli
3
+ Version: 0.2.0
4
+ Summary: Generates local, ready-to-push application and GitOps repositories from one config.
5
+ Project-URL: Homepage, https://github.com/dfoshidero/plinth
6
+ Project-URL: Issues, https://github.com/dfoshidero/plinth/issues
7
+ Author: dfoshidero
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ Keywords: argo-cd,dagger,generator,gitops,monorepo,scaffolding,score
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Code Generators
18
+ Requires-Python: >=3.12
19
+ Requires-Dist: jinja2<4,>=3.1
20
+ Requires-Dist: pydantic<3,>=2.11
21
+ Requires-Dist: pyyaml<7,>=6.0
22
+ Requires-Dist: questionary<3,>=2.1
23
+ Description-Content-Type: text/markdown
24
+
25
+ # plinth
26
+
27
+ Generate ready-to-push application and GitOps repositories from one config file.
28
+
29
+ plinth turns a short `plinth.yaml` into git repositories with working application code, a
30
+ [Dagger](https://dagger.io) CI pipeline, [Score](https://score.dev) workload specs, and an
31
+ [Argo CD](https://argo-cd.readthedocs.io) GitOps repository that deploys them. Start as a
32
+ modular monolith, a set of microservices or a hybrid of both, in one repo or one repo per app,
33
+ and grow later with `plinth add`.
34
+
35
+ ## Install
36
+
37
+ ```sh
38
+ uv tool install plinth-cli # or: pipx install plinth-cli
39
+ plinth --version
40
+ ```
41
+
42
+ The PyPI package is `plinth-cli`; the command is `plinth`. Requires Python 3.12+.
43
+
44
+ ## Quick start
45
+
46
+ Answer a few questions:
47
+
48
+ ```sh
49
+ plinth project
50
+ ```
51
+
52
+ or write a config and generate from it:
53
+
54
+ ```yaml
55
+ # plinth.yaml
56
+ project:
57
+ name: atlas
58
+ architecture: hybrid # modular-monolith | microservices | hybrid
59
+ layout: monorepo # monorepo | split-repo
60
+ gitProvider: github # github | gitlab | generic
61
+ gitBaseUrl: https://github.com/acme
62
+ registry: ghcr.io/acme
63
+ applications:
64
+ - {name: api, kind: modular-monolith}
65
+ - {name: worker, kind: worker}
66
+ - {name: notifier, kind: service, port: 8081}
67
+ environments: [dev, production]
68
+ ```
69
+
70
+ ```sh
71
+ plinth validate --config plinth.yaml
72
+ plinth generate --config plinth.yaml --output .
73
+ ```
74
+
75
+ This writes `./atlas/` containing one folder per repository, each initialised with git, an
76
+ initial commit and an `origin` remote under `gitBaseUrl`. Create the empty repositories on your
77
+ git host and push.
78
+
79
+ More configs live in [`examples/`](examples/): every architecture with both layouts.
80
+
81
+ ## What you get
82
+
83
+ **Application repositories** (one for a monorepo, one per app for split-repo):
84
+
85
+ - a small, dependency-free Python app per workload with a `/health` endpoint (services and the
86
+ monolith) or a run loop (workers), plus tests; replace it with your own code
87
+ - a `Dockerfile` and a `score.yaml` describing how the workload runs
88
+ - a Dagger module (`.dagger/`) with `test`, `build` and `ship` functions that run identically on
89
+ your laptop and in CI
90
+ - a CI file for your provider (`.github/workflows/ci.yaml` or `.gitlab-ci.yml`) that tests pull
91
+ requests and ships `main`
92
+
93
+ **A GitOps repository:**
94
+
95
+ - an Argo CD app-of-apps (`bootstrap/root.yaml`) and one ApplicationSet per environment
96
+ - a Helm chart that deploys any workload straight from its `score.yaml`
97
+ - per-environment values, and `release.yaml` files written by CI on every ship
98
+ - `scripts/bootstrap-local.sh` to run everything on a local [k3d](https://k3d.io) cluster
99
+
100
+ The flow: push to `main` → CI tests, builds and pushes images tagged with the commit → CI writes
101
+ `environments/dev/<workload>/release.yaml` → Argo CD deploys it. Promote by copying a
102
+ `release.yaml` to another environment.
103
+
104
+ ## Grow a project
105
+
106
+ Add a service or worker to a generated project:
107
+
108
+ ```sh
109
+ cd atlas
110
+ plinth add service billing --port 8090
111
+ plinth add worker mailer
112
+ ```
113
+
114
+ plinth creates the new workload's files (and a new repository for split-repo layouts) and
115
+ updates `plinth.yaml`. Adding to a modular monolith turns it into a hybrid. Existing files are
116
+ never overwritten; any that plinth would now generate differently are listed for you to review.
117
+
118
+ ## Commands
119
+
120
+ | Command | What it does |
121
+ |---|---|
122
+ | `plinth project [--output DIR]` | interactive questions, then generate |
123
+ | `plinth validate --config FILE` | check a config and show the repositories it produces |
124
+ | `plinth generate --config FILE --output DIR [--dry-run]` | write the repositories |
125
+ | `plinth add {service,worker} NAME [--port N]` | add a workload to an existing project |
126
+
127
+ `--no-git` skips `git init` and the initial commit.
128
+
129
+ ## Configuration
130
+
131
+ | Key | Notes |
132
+ |---|---|
133
+ | `project.name` | kebab-case, 2-30 chars; prefixes every repository name |
134
+ | `project.architecture` | `modular-monolith` (one monolith), `microservices` (services/workers only), `hybrid` (one monolith plus services/workers) |
135
+ | `project.layout` | `monorepo` (`<name>-app` holds every workload) or `split-repo` (`<name>-<app>` each) |
136
+ | `project.gitProvider` | picks the CI file; `generic` generates none |
137
+ | `project.gitBaseUrl` | `https://host/org` the repositories live under |
138
+ | `project.registry` | `host/path` images are pushed to |
139
+ | `applications[]` | `name`, `kind` (`modular-monolith`, `service`, `worker`), optional `port` for HTTP kinds |
140
+ | `environments` | must include `dev`, which CI releases to |
141
+
142
+ Defaults and pinned tool versions are in [`plinth/config.py`](plinth/config.py).
143
+
144
+ ## When not to use plinth
145
+
146
+ - You only need a single repository from a template: [Copier](https://copier.readthedocs.io)
147
+ or [Cookiecutter](https://cookiecutter.readthedocs.io) are simpler, and Copier can update
148
+ projects later.
149
+ - You already run [Backstage](https://backstage.io): its software templates fit better there.
150
+ - You don't deploy to Kubernetes: the GitOps half won't help you.
151
+
152
+ plinth generates once. It does not keep generated repositories in sync with newer templates;
153
+ after generation the code is yours.
154
+
155
+ ## Development
156
+
157
+ ```sh
158
+ uv sync
159
+ uv run pytest
160
+ uv run ruff check . && uv run ruff format --check .
161
+ ```
162
+
163
+ Templates live in [`plinth/blueprints/`](plinth/blueprints/). Files ending in `.j2` are rendered
164
+ with Jinja; path segments starting with `dot-` are written with a leading `.`.
165
+
166
+ ## Contributing
167
+
168
+ Contributions are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md) first; in short, open an
169
+ issue before large changes, and every contribution must be written by a human (no AI-generated
170
+ code or text).
171
+
172
+ ## License
173
+
174
+ [MIT](LICENSE)
@@ -0,0 +1,49 @@
1
+ plinth/__init__.py,sha256=iiHE7PbslX3kD7ibzZV-v1aezICaREHHEAAjHGJ3hbU,90
2
+ plinth/__main__.py,sha256=D7dIGZPVzn2TH_VoNBsy3b56IRUatGw-7PtfjeIPUp4,58
3
+ plinth/add.py,sha256=duBHMBM_VhTeRZrY5PQwFGXP0szNzxknqoPjr66S-iU,3545
4
+ plinth/cli.py,sha256=zi5Ql8RcQm_Hj4waMv4extXIzuj-v2pwmp9RcufOsR8,6925
5
+ plinth/config.py,sha256=-t04CW6EQ5JtgzONnOOwZ6bh0Sv8GNO5HYMKs61iG1I,1491
6
+ plinth/loader.py,sha256=UyKn7AMHO1GaRx9fqCutQrNVze9464tT1vVCjkWGnco,1559
7
+ plinth/plan.py,sha256=lIE0kICx0N49ZhU0G8XG2nUW0AIt200pTvcssqSsPVI,2027
8
+ plinth/render.py,sha256=iopOLw2VyBMOw1UNkdg8P_hoIDN7utqBFCKHaO0rNvQ,4204
9
+ plinth/schema.py,sha256=EtMpvMn4nX2lU_jLdgYa25aHnRrOYe-oVso9P0FSwXU,5224
10
+ plinth/wizard.py,sha256=Jpf4hRNxRqNBOEDinF0aGOjiJ7Go5Lgtr85L181CviY,4448
11
+ plinth/write.py,sha256=_7r91v2SYKEBEACbOozARHe5LuQyoDEud7DkdfDO8N0,2491
12
+ plinth/blueprints/ci/github/dot-github/workflows/ci.yaml.j2,sha256=DQBQ2IAHaiKEm_FUXFyCYlBUQgg1aobrhBYphQdLwQQ,1018
13
+ plinth/blueprints/ci/gitlab/dot-gitlab-ci.yml.j2,sha256=Yws8cLG53g7zzklJQwqrrGivUChcXg0TUm43aQqpylI,884
14
+ plinth/blueprints/gitops/applicationset.yaml.j2,sha256=9PN6iVhmmvoKEJnlXcKaUKsKzPQRYjhvGpl2x4BT4bc,1499
15
+ plinth/blueprints/gitops/values.yaml.j2,sha256=aDjDjBxvmVqYHCqJ24aPGWIY8mVs654cvpl_nOzkSEo,161
16
+ plinth/blueprints/repo/app/README.md.j2,sha256=wzGqIFHkooKpOssl05jHTkjUJ27oGGa752cqJRE0RZs,2486
17
+ plinth/blueprints/repo/app/dagger.json.j2,sha256=YCZ3d0TFAXUjVaWM_H3JZP1hr0n-7dGs01vnn6KYbC0,134
18
+ plinth/blueprints/repo/app/dot-gitignore,sha256=H6qnYh1ykCi1BwwMd-IDyj-JmOO1JfSIaOJc5XppJUo,31
19
+ plinth/blueprints/repo/app/dot-dagger/dot-gitignore,sha256=wXhhUha0HQGaPV3m1nXQm4wzYGDEKn6YOQp9232M82o,25
20
+ plinth/blueprints/repo/app/dot-dagger/pyproject.toml,sha256=bEGusglaeV6zaCtzOYZTw7avWQMgys5CDJNV4D8KZns,252
21
+ plinth/blueprints/repo/app/dot-dagger/src/ci/__init__.py,sha256=MjyrYvJYRimlNAA8yi_M80i52upZhKoIou48lfyDa9s,112
22
+ plinth/blueprints/repo/app/dot-dagger/src/ci/main.py.j2,sha256=uiREhlY452UC_Ks0ICr3WH7A3KHsvIqTATLx-ow2wDc,4963
23
+ plinth/blueprints/repo/gitops/README.md.j2,sha256=TJfjKeMX2FbzFGNkp8lLXV5ffYkboQl8IoIQMgnqwrc,2172
24
+ plinth/blueprints/repo/gitops/apps/project.yaml.j2,sha256=eskRk938bPTm6PobzLCtR79kidu3_8nbuAIaAfHlCcs,399
25
+ plinth/blueprints/repo/gitops/bootstrap/root.yaml.j2,sha256=orYQYnfO14hT6evrSKsxvY3f2nmDknjYiJ-gup_DFHE,473
26
+ plinth/blueprints/repo/gitops/charts/workload/Chart.yaml,sha256=23nVJBheVJrV03WWJochhtXFSmRoOsULlktsMZtU3Tw,141
27
+ plinth/blueprints/repo/gitops/charts/workload/values.yaml,sha256=D8vBb12jVIFnO37QE57GSpBc2bLrmylGPVSWtxdFfho,453
28
+ plinth/blueprints/repo/gitops/charts/workload/templates/_helpers.tpl,sha256=MsLlo5FE4xZMfl4NQ8VP84zdjtOrvWj27Qo2jQsxsJ0,456
29
+ plinth/blueprints/repo/gitops/charts/workload/templates/deployment.yaml,sha256=5nDO-mYW28-sbUc6i5n_O5eLLtbyVHBswTKcXTnUmRw,1917
30
+ plinth/blueprints/repo/gitops/charts/workload/templates/service.yaml,sha256=_zfW1c0gIJs9dkJW4o0MGmDTZA08RIUwQ_-rrRmsf8U,507
31
+ plinth/blueprints/repo/gitops/scripts/bootstrap-local.sh.j2,sha256=VV7YLjk37u4crpAqMlpoFBE459unfKZy1D29-wUXJFE,1060
32
+ plinth/blueprints/workload/common/Dockerfile.j2,sha256=BuPwFdA0-cnZSOoX8tKjllssZph-OKllk3R1WFhe5FE,341
33
+ plinth/blueprints/workload/common/dot-dockerignore,sha256=2UIakcAtmPm6h0UnkT3YQs-b0wmKD_t26JLS4nAgUb4,37
34
+ plinth/blueprints/workload/common/score.yaml.j2,sha256=qzyQj-pBABUlbflz--lmv3tYqo_R9bAB0h4M449FJQE,843
35
+ plinth/blueprints/workload/common/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
+ plinth/blueprints/workload/common/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
+ plinth/blueprints/workload/modular-monolith/app/main.py.j2,sha256=fYl6jTL-GSvU6ecIZw_BUbPPrQHVLmKi1sxVfIMdXD4,2010
38
+ plinth/blueprints/workload/modular-monolith/app/modules/__init__.py,sha256=gZ9cK3rfa0IxxKgbW34PPmXt3cQvPdkTN2Vs797DF7g,132
39
+ plinth/blueprints/workload/modular-monolith/app/modules/example.py,sha256=_sEOQsGEJytAzqDm39RhgqcQy0GV23AkXMZVF_hFaxs,384
40
+ plinth/blueprints/workload/modular-monolith/tests/test_main.py.j2,sha256=Oc6sQkmXVPCV6XTYJA4S846zmcz-UZvFduK3z-HyVJ4,1252
41
+ plinth/blueprints/workload/service/app/main.py.j2,sha256=ccnnzku84w2YS-4LmCwNJkitCeZHckIHLFx4yLESdxA,1716
42
+ plinth/blueprints/workload/service/tests/test_main.py.j2,sha256=uBB813XETVMXxwHTuyy8_RKYKGlND10jMRqb0vsySbQ,1254
43
+ plinth/blueprints/workload/worker/app/main.py.j2,sha256=TlpxZj85uQMeKM2dgs59eLPyu2tI4taKij0TOgDzJMw,1220
44
+ plinth/blueprints/workload/worker/tests/test_main.py.j2,sha256=Rya7k0e8_GC37SeR29RDGjJs-2RFp2fXr2Aq7CfUznc,645
45
+ plinth_cli-0.2.0.dist-info/METADATA,sha256=dhAQVhtLnK2jF6LSAS01vFxMQlisMQ0g2GDzcC7cMt4,6517
46
+ plinth_cli-0.2.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
47
+ plinth_cli-0.2.0.dist-info/entry_points.txt,sha256=swe0Vm7verOMY4Y6X5npNfUE24IKeIn4IQoGWbYGsNw,43
48
+ plinth_cli-0.2.0.dist-info/licenses/LICENSE,sha256=TcNxerWiq9IH4n-FDxwo4GpbpZQE8eW9k4A-nj0fDnQ,1067
49
+ plinth_cli-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.32.4
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ plinth = plinth.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dfoshidero
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.