groundskeeping 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.
- groundskeeping-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +66 -0
- groundskeeping-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- groundskeeping-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +32 -0
- groundskeeping-0.1.0/.github/ISSUE_TEMPLATE/not_working.yml +65 -0
- groundskeeping-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +9 -0
- groundskeeping-0.1.0/.github/release-drafter.yml +31 -0
- groundskeeping-0.1.0/.github/workflows/ci.yml +10 -0
- groundskeeping-0.1.0/.github/workflows/docs.yml +10 -0
- groundskeeping-0.1.0/.github/workflows/merge.yml +13 -0
- groundskeeping-0.1.0/.github/workflows/publish.yml +21 -0
- groundskeeping-0.1.0/.gitignore +228 -0
- groundskeeping-0.1.0/CONTRIBUTING.md +27 -0
- groundskeeping-0.1.0/PKG-INFO +133 -0
- groundskeeping-0.1.0/README.md +116 -0
- groundskeeping-0.1.0/docs/actions.md +108 -0
- groundskeeping-0.1.0/docs/api/actions.md +3 -0
- groundskeeping-0.1.0/docs/api/app.md +3 -0
- groundskeeping-0.1.0/docs/api/configurator.md +5 -0
- groundskeeping-0.1.0/docs/api/jobs.md +3 -0
- groundskeeping-0.1.0/docs/api/pages.md +3 -0
- groundskeeping-0.1.0/docs/api/telemetry.md +7 -0
- groundskeeping-0.1.0/docs/api/views.md +3 -0
- groundskeeping-0.1.0/docs/api/widgets.md +7 -0
- groundskeeping-0.1.0/docs/configuration.md +56 -0
- groundskeeping-0.1.0/docs/contributing.md +47 -0
- groundskeeping-0.1.0/docs/index.md +55 -0
- groundskeeping-0.1.0/docs/ownership.md +55 -0
- groundskeeping-0.1.0/docs/pages.md +72 -0
- groundskeeping-0.1.0/docs/quickstart.md +77 -0
- groundskeeping-0.1.0/docs/telemetry.md +46 -0
- groundskeeping-0.1.0/examples/demo_app.py +6 -0
- groundskeeping-0.1.0/mkdocs.yml +79 -0
- groundskeeping-0.1.0/pyproject.toml +51 -0
- groundskeeping-0.1.0/src/groundskeeping/__init__.py +17 -0
- groundskeeping-0.1.0/src/groundskeeping/app.py +233 -0
- groundskeeping-0.1.0/src/groundskeeping/configurator/__init__.py +18 -0
- groundskeeping-0.1.0/src/groundskeeping/configurator/adapter.py +227 -0
- groundskeeping-0.1.0/src/groundskeeping/configurator/models.py +110 -0
- groundskeeping-0.1.0/src/groundskeeping/contracts/__init__.py +57 -0
- groundskeeping-0.1.0/src/groundskeeping/contracts/actions.py +360 -0
- groundskeeping-0.1.0/src/groundskeeping/contracts/jobs.py +245 -0
- groundskeeping-0.1.0/src/groundskeeping/contracts/pages.py +112 -0
- groundskeeping-0.1.0/src/groundskeeping/contracts/views.py +111 -0
- groundskeeping-0.1.0/src/groundskeeping/demo.py +255 -0
- groundskeeping-0.1.0/src/groundskeeping/navigation.py +21 -0
- groundskeeping-0.1.0/src/groundskeeping/telemetry/__init__.py +10 -0
- groundskeeping-0.1.0/src/groundskeeping/telemetry/contracts.py +17 -0
- groundskeeping-0.1.0/src/groundskeeping/telemetry/models.py +55 -0
- groundskeeping-0.1.0/src/groundskeeping/telemetry/providers/__init__.py +3 -0
- groundskeeping-0.1.0/src/groundskeeping/telemetry/providers/fake.py +80 -0
- groundskeeping-0.1.0/src/groundskeeping/telemetry/runtime.py +72 -0
- groundskeeping-0.1.0/src/groundskeeping/theme.py +67 -0
- groundskeeping-0.1.0/src/groundskeeping/themes/groundskeeping.tcss +148 -0
- groundskeeping-0.1.0/src/groundskeeping/widgets/__init__.py +4 -0
- groundskeeping-0.1.0/src/groundskeeping/widgets/configurator.py +39 -0
- groundskeeping-0.1.0/src/groundskeeping/widgets/primitives.py +50 -0
- groundskeeping-0.1.0/src/groundskeeping/widgets/telemetry.py +26 -0
- groundskeeping-0.1.0/src/groundskeeping/widgets/workbench.py +236 -0
- groundskeeping-0.1.0/tests/test_actions_and_jobs.py +102 -0
- groundskeeping-0.1.0/tests/test_app_smoke.py +18 -0
- groundskeeping-0.1.0/tests/test_configurator_adapter.py +93 -0
- groundskeeping-0.1.0/tests/test_dependency_boundaries.py +35 -0
- groundskeeping-0.1.0/tests/test_navigation_contracts.py +29 -0
- groundskeeping-0.1.0/tests/test_telemetry_core.py +43 -0
- groundskeeping-0.1.0/uv.lock +1029 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
name: "🐞 Bug Report"
|
|
2
|
+
description: Report a reproducible bug.
|
|
3
|
+
type: "Bug"
|
|
4
|
+
body:
|
|
5
|
+
- type: checkboxes
|
|
6
|
+
attributes:
|
|
7
|
+
label: Pre-flight
|
|
8
|
+
options:
|
|
9
|
+
- label: I searched existing issues and this is not a duplicate.
|
|
10
|
+
required: true
|
|
11
|
+
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: summary
|
|
14
|
+
attributes:
|
|
15
|
+
label: Summary
|
|
16
|
+
description: One or two sentences describing the bug.
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: reproduction
|
|
22
|
+
attributes:
|
|
23
|
+
label: Reproduction
|
|
24
|
+
description: Steps and/or a minimal code example that reproduces the issue. Wrap code in triple backticks.
|
|
25
|
+
placeholder: |
|
|
26
|
+
1. Import X and call Y with Z
|
|
27
|
+
2. Observe error
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
# minimal example
|
|
31
|
+
```
|
|
32
|
+
validations:
|
|
33
|
+
required: true
|
|
34
|
+
|
|
35
|
+
- type: textarea
|
|
36
|
+
id: actual
|
|
37
|
+
attributes:
|
|
38
|
+
label: Actual behaviour
|
|
39
|
+
validations:
|
|
40
|
+
required: true
|
|
41
|
+
|
|
42
|
+
- type: textarea
|
|
43
|
+
id: expected
|
|
44
|
+
attributes:
|
|
45
|
+
label: Expected behaviour
|
|
46
|
+
validations:
|
|
47
|
+
required: true
|
|
48
|
+
|
|
49
|
+
- type: textarea
|
|
50
|
+
id: logs
|
|
51
|
+
attributes:
|
|
52
|
+
label: Error output
|
|
53
|
+
description: Full traceback if applicable. Formatted automatically.
|
|
54
|
+
render: python-traceback
|
|
55
|
+
|
|
56
|
+
- type: textarea
|
|
57
|
+
id: system
|
|
58
|
+
attributes:
|
|
59
|
+
label: System info
|
|
60
|
+
description: |
|
|
61
|
+
Run this in your environment and paste the output:
|
|
62
|
+
|
|
63
|
+
```shell
|
|
64
|
+
python <(curl -s https://raw.githubusercontent.com/AustralianCancerDataNetwork/cava-devops/main/scripts/cava_system_info.py)
|
|
65
|
+
```
|
|
66
|
+
render: shell
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: "🚀 Feature Request"
|
|
2
|
+
description: Propose a new feature or enhancement.
|
|
3
|
+
type: "Feature"
|
|
4
|
+
body:
|
|
5
|
+
- type: checkboxes
|
|
6
|
+
attributes:
|
|
7
|
+
label: Pre-flight
|
|
8
|
+
options:
|
|
9
|
+
- label: I searched existing issues and this has not been requested before.
|
|
10
|
+
required: true
|
|
11
|
+
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: problem
|
|
14
|
+
attributes:
|
|
15
|
+
label: Problem or motivation
|
|
16
|
+
description: What are you trying to do that you currently cannot?
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: proposal
|
|
22
|
+
attributes:
|
|
23
|
+
label: Proposed solution
|
|
24
|
+
description: How would you like this to work?
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
|
|
28
|
+
- type: textarea
|
|
29
|
+
id: alternatives
|
|
30
|
+
attributes:
|
|
31
|
+
label: Alternatives considered
|
|
32
|
+
description: Other approaches you considered and why you ruled them out.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: "❗ Something is not working"
|
|
2
|
+
description: Something behaves unexpectedly but you are not sure if it is a bug.
|
|
3
|
+
body:
|
|
4
|
+
- type: checkboxes
|
|
5
|
+
attributes:
|
|
6
|
+
label: Pre-flight
|
|
7
|
+
options:
|
|
8
|
+
- label: I searched existing issues for this problem.
|
|
9
|
+
required: true
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: summary
|
|
13
|
+
attributes:
|
|
14
|
+
label: Problem summary
|
|
15
|
+
description: 1-2 sentences describing what is not working.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: reproduction
|
|
21
|
+
attributes:
|
|
22
|
+
label: Reproduction
|
|
23
|
+
description: Steps and/or a minimal code example. Wrap code in triple backticks.
|
|
24
|
+
placeholder: |
|
|
25
|
+
1. Import X and call Y with Z
|
|
26
|
+
2. Observe unexpected behaviour
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
# minimal example
|
|
30
|
+
```
|
|
31
|
+
validations:
|
|
32
|
+
required: true
|
|
33
|
+
|
|
34
|
+
- type: textarea
|
|
35
|
+
id: actual
|
|
36
|
+
attributes:
|
|
37
|
+
label: Actual outcome
|
|
38
|
+
validations:
|
|
39
|
+
required: true
|
|
40
|
+
|
|
41
|
+
- type: textarea
|
|
42
|
+
id: expected
|
|
43
|
+
attributes:
|
|
44
|
+
label: Expected outcome
|
|
45
|
+
validations:
|
|
46
|
+
required: true
|
|
47
|
+
|
|
48
|
+
- type: textarea
|
|
49
|
+
id: logs
|
|
50
|
+
attributes:
|
|
51
|
+
label: Error messages
|
|
52
|
+
description: Full traceback if applicable. Formatted automatically.
|
|
53
|
+
render: python-traceback
|
|
54
|
+
|
|
55
|
+
- type: textarea
|
|
56
|
+
id: system
|
|
57
|
+
attributes:
|
|
58
|
+
label: System info
|
|
59
|
+
description: |
|
|
60
|
+
Run this in your environment and paste the output:
|
|
61
|
+
|
|
62
|
+
```shell
|
|
63
|
+
python <(curl -s https://raw.githubusercontent.com/AustralianCancerDataNetwork/cava-devops/main/scripts/cava_system_info.py)
|
|
64
|
+
```
|
|
65
|
+
render: shell
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- What does this PR do? This text becomes the changelog entry — write it for a reader who will see it months from now, not for the reviewer reading the diff. Leave blank for chore PRs. -->
|
|
4
|
+
|
|
5
|
+
## Checklist
|
|
6
|
+
|
|
7
|
+
- [ ] Applied exactly one label (`breaking`, `feature`, `fix`, `dependencies`, or `chore`)
|
|
8
|
+
- [ ] Tests pass locally (`uv run pytest -q`)
|
|
9
|
+
- [ ] Lint passes (`uv run ruff check .`)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name-template: 'v$RESOLVED_VERSION'
|
|
2
|
+
tag-template: 'v$RESOLVED_VERSION'
|
|
3
|
+
commitish: main
|
|
4
|
+
|
|
5
|
+
categories:
|
|
6
|
+
- title: Breaking Changes
|
|
7
|
+
labels: ['breaking']
|
|
8
|
+
- title: Features
|
|
9
|
+
labels: ['feature']
|
|
10
|
+
- title: Fixes
|
|
11
|
+
labels: ['fix']
|
|
12
|
+
- title: Dependencies
|
|
13
|
+
labels: ['dependencies']
|
|
14
|
+
|
|
15
|
+
template: |
|
|
16
|
+
$CHANGES
|
|
17
|
+
|
|
18
|
+
change-template: '- **$TITLE** (#$NUMBER) @$AUTHOR'
|
|
19
|
+
|
|
20
|
+
version-resolver:
|
|
21
|
+
major:
|
|
22
|
+
labels: ['breaking']
|
|
23
|
+
minor:
|
|
24
|
+
labels: ['feature']
|
|
25
|
+
patch:
|
|
26
|
+
labels: ['fix', 'dependencies']
|
|
27
|
+
default: patch
|
|
28
|
+
|
|
29
|
+
exclude-labels: ['chore']
|
|
30
|
+
|
|
31
|
+
autolabeler: []
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
branches: [main]
|
|
5
|
+
types: [opened, synchronize, reopened, labeled, unlabeled]
|
|
6
|
+
jobs:
|
|
7
|
+
label-gate:
|
|
8
|
+
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/label-gate.yml@main
|
|
9
|
+
build-test:
|
|
10
|
+
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test.yml@main
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
name: Release Update
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
types: [closed]
|
|
5
|
+
branches: [main]
|
|
6
|
+
permissions:
|
|
7
|
+
contents: write
|
|
8
|
+
pull-requests: read
|
|
9
|
+
jobs:
|
|
10
|
+
draft:
|
|
11
|
+
if: github.event.pull_request.merged == true
|
|
12
|
+
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/release-drafter.yml@main
|
|
13
|
+
secrets: inherit
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
tags: ['v*']
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/publish.yml@main
|
|
8
|
+
publish:
|
|
9
|
+
# Inline: PyPI OIDC checks job_workflow_ref, which must point to this file.
|
|
10
|
+
# Moving pypa/gh-action-pypi-publish into cava-devops would break the trusted publisher.
|
|
11
|
+
needs: build
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write
|
|
15
|
+
environment:
|
|
16
|
+
name: pypi
|
|
17
|
+
url: https://pypi.org/p/groundskeeping
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/download-artifact@v4
|
|
20
|
+
with: { name: dist, path: dist/ }
|
|
21
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
*.lcov
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
cover/
|
|
54
|
+
|
|
55
|
+
# Translations
|
|
56
|
+
*.mo
|
|
57
|
+
*.pot
|
|
58
|
+
|
|
59
|
+
# Django stuff:
|
|
60
|
+
*.log
|
|
61
|
+
local_settings.py
|
|
62
|
+
db.sqlite3
|
|
63
|
+
db.sqlite3-journal
|
|
64
|
+
|
|
65
|
+
# Flask stuff:
|
|
66
|
+
instance/
|
|
67
|
+
.webassets-cache
|
|
68
|
+
|
|
69
|
+
# Scrapy stuff:
|
|
70
|
+
.scrapy
|
|
71
|
+
|
|
72
|
+
# Sphinx documentation
|
|
73
|
+
docs/_build/
|
|
74
|
+
|
|
75
|
+
# PyBuilder
|
|
76
|
+
.pybuilder/
|
|
77
|
+
target/
|
|
78
|
+
|
|
79
|
+
# Jupyter Notebook
|
|
80
|
+
.ipynb_checkpoints
|
|
81
|
+
|
|
82
|
+
# IPython
|
|
83
|
+
profile_default/
|
|
84
|
+
ipython_config.py
|
|
85
|
+
|
|
86
|
+
# pyenv
|
|
87
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
88
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
89
|
+
# .python-version
|
|
90
|
+
|
|
91
|
+
# pipenv
|
|
92
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
93
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
94
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
95
|
+
# install all needed dependencies.
|
|
96
|
+
# Pipfile.lock
|
|
97
|
+
|
|
98
|
+
# UV
|
|
99
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
100
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
101
|
+
# commonly ignored for libraries.
|
|
102
|
+
# uv.lock
|
|
103
|
+
|
|
104
|
+
# poetry
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
106
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
107
|
+
# commonly ignored for libraries.
|
|
108
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
109
|
+
# poetry.lock
|
|
110
|
+
# poetry.toml
|
|
111
|
+
|
|
112
|
+
# pdm
|
|
113
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
114
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
115
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
116
|
+
# pdm.lock
|
|
117
|
+
# pdm.toml
|
|
118
|
+
.pdm-python
|
|
119
|
+
.pdm-build/
|
|
120
|
+
|
|
121
|
+
# pixi
|
|
122
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
123
|
+
# pixi.lock
|
|
124
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
125
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
126
|
+
.pixi/*
|
|
127
|
+
!.pixi/config.toml
|
|
128
|
+
|
|
129
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
130
|
+
__pypackages__/
|
|
131
|
+
|
|
132
|
+
# Celery stuff
|
|
133
|
+
celerybeat-schedule*
|
|
134
|
+
celerybeat.pid
|
|
135
|
+
|
|
136
|
+
# Redis
|
|
137
|
+
*.rdb
|
|
138
|
+
*.aof
|
|
139
|
+
*.pid
|
|
140
|
+
|
|
141
|
+
# RabbitMQ
|
|
142
|
+
mnesia/
|
|
143
|
+
rabbitmq/
|
|
144
|
+
rabbitmq-data/
|
|
145
|
+
|
|
146
|
+
# ActiveMQ
|
|
147
|
+
activemq-data/
|
|
148
|
+
|
|
149
|
+
# SageMath parsed files
|
|
150
|
+
*.sage.py
|
|
151
|
+
|
|
152
|
+
# Environments
|
|
153
|
+
.env
|
|
154
|
+
.envrc
|
|
155
|
+
.venv
|
|
156
|
+
env/
|
|
157
|
+
venv/
|
|
158
|
+
ENV/
|
|
159
|
+
env.bak/
|
|
160
|
+
venv.bak/
|
|
161
|
+
|
|
162
|
+
# Spyder project settings
|
|
163
|
+
.spyderproject
|
|
164
|
+
.spyproject
|
|
165
|
+
|
|
166
|
+
# Rope project settings
|
|
167
|
+
.ropeproject
|
|
168
|
+
|
|
169
|
+
# mkdocs documentation
|
|
170
|
+
/site
|
|
171
|
+
|
|
172
|
+
# mypy
|
|
173
|
+
.mypy_cache/
|
|
174
|
+
.dmypy.json
|
|
175
|
+
dmypy.json
|
|
176
|
+
|
|
177
|
+
# Pyre type checker
|
|
178
|
+
.pyre/
|
|
179
|
+
|
|
180
|
+
# pytype static type analyzer
|
|
181
|
+
.pytype/
|
|
182
|
+
|
|
183
|
+
# Cython debug symbols
|
|
184
|
+
cython_debug/
|
|
185
|
+
|
|
186
|
+
# PyCharm
|
|
187
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
188
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
189
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
190
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
191
|
+
# .idea/
|
|
192
|
+
|
|
193
|
+
# Abstra
|
|
194
|
+
# Abstra is an AI-powered process automation framework.
|
|
195
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
196
|
+
# Learn more at https://abstra.io/docs
|
|
197
|
+
.abstra/
|
|
198
|
+
|
|
199
|
+
# Visual Studio Code
|
|
200
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
|
201
|
+
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
202
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
|
203
|
+
# you could uncomment the following to ignore the entire vscode folder
|
|
204
|
+
.vscode/
|
|
205
|
+
# Temporary file for partial code execution
|
|
206
|
+
tempCodeRunnerFile.py
|
|
207
|
+
|
|
208
|
+
# Ruff stuff:
|
|
209
|
+
.ruff_cache/
|
|
210
|
+
|
|
211
|
+
# PyPI configuration file
|
|
212
|
+
.pypirc
|
|
213
|
+
|
|
214
|
+
# Marimo
|
|
215
|
+
marimo/_static/
|
|
216
|
+
marimo/_lsp/
|
|
217
|
+
__marimo__/
|
|
218
|
+
|
|
219
|
+
# Streamlit
|
|
220
|
+
.streamlit/secrets.toml
|
|
221
|
+
__pycache__/
|
|
222
|
+
*.py[cod]
|
|
223
|
+
.pytest_cache/
|
|
224
|
+
.mypy_cache/
|
|
225
|
+
.ruff_cache/
|
|
226
|
+
.venv/
|
|
227
|
+
*.ipynb
|
|
228
|
+
_temp/
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
## Development setup
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
uv sync --all-extras --dev
|
|
7
|
+
uv run pytest -q
|
|
8
|
+
uv run ruff check .
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Opening a pull request
|
|
12
|
+
|
|
13
|
+
1. Apply **exactly one** label before merging:
|
|
14
|
+
|
|
15
|
+
| Label | When to use |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `breaking` | Public API change, backward-incompatible |
|
|
18
|
+
| `feature` | New functionality, backward-compatible |
|
|
19
|
+
| `fix` | Bug fix |
|
|
20
|
+
| `dependencies` | Dependency version update |
|
|
21
|
+
| `chore` | CI changes, refactoring, test additions, docs — anything that does not affect the public-facing package. Bypasses the label gate; excluded from the changelog and does not bump the version. |
|
|
22
|
+
|
|
23
|
+
2. When merging (squash), write a clear extended description in the merge dialog. That text — not the PR's opening description — becomes the changelog entry for this change. Leave it blank for `chore` PRs.
|
|
24
|
+
|
|
25
|
+
## Versioning and releases
|
|
26
|
+
|
|
27
|
+
Versions are derived from git tags; there is no version string in any source file. Releases are triggered by a maintainer publishing the standing draft release on the repository's Releases page. There is no automated commit-back to `main`.
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: groundskeeping
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Reusable Textual operator shell, workbench, configuration browser, and telemetry primitives.
|
|
5
|
+
Author: UNSW CAVA platform tooling
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: oa-configurator<0.3,>=0.1.2
|
|
8
|
+
Requires-Dist: textual<9,>=8.2
|
|
9
|
+
Provides-Extra: dev
|
|
10
|
+
Requires-Dist: mkdocs-material>=9.7.1; extra == 'dev'
|
|
11
|
+
Requires-Dist: mkdocs>=1.6.1; extra == 'dev'
|
|
12
|
+
Requires-Dist: mkdocstrings-python>=2.0.1; extra == 'dev'
|
|
13
|
+
Requires-Dist: pytest>=9.0; extra == 'dev'
|
|
14
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
15
|
+
Requires-Dist: ty>=0.0.59; extra == 'dev'
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# groundskeeping
|
|
19
|
+
|
|
20
|
+
`groundskeeping` is a reusable Textual shell for operator tools that help people care for a working environment: setup checks, configuration, queues, telemetry, tuning, and long-running operations.
|
|
21
|
+
|
|
22
|
+
The package provides the shared operating frame. A consumer application provides the domain. Keep that distinction close and most design decisions become simpler.
|
|
23
|
+
|
|
24
|
+
## The Shape Of An App
|
|
25
|
+
|
|
26
|
+
A `groundskeeping` app starts with one `OperatorAppSpec`.
|
|
27
|
+
|
|
28
|
+
The spec names the app, orders the pages, registers the actions, and supplies the policies that decide whether work may run. It is the composition root: everything application-specific should arrive there from the consumer, not through global lookup inside the shared package.
|
|
29
|
+
|
|
30
|
+
Pages are owned by the consumer and are ordinary Textual widgets. The shell mounts them once, activates and deactivates them as the operator moves between tabs, and preserves page-local state. A page receives a narrow `PageContext`; it does not receive the whole app.
|
|
31
|
+
|
|
32
|
+
The default page surface is the workbench:
|
|
33
|
+
|
|
34
|
+
- catalogue on the left;
|
|
35
|
+
- rows or tree content on the upper right; and
|
|
36
|
+
- selected detail on the lower right.
|
|
37
|
+
|
|
38
|
+
Pages render package-owned view models such as `CatalogueItem`, `TableView`, `TreeView`, `EmptyView`, `TextView`, and `KeyValueView`. Domain objects should be translated before they reach the workbench. That keeps the shared shell reusable and keeps consumer language in the consumer.
|
|
39
|
+
|
|
40
|
+
## Setup Pages
|
|
41
|
+
|
|
42
|
+
A setup page should answer a concrete operator question: "can this environment do the work I am about to ask of it?"
|
|
43
|
+
|
|
44
|
+
The page should normally live in the consumer package and use consumer services to inspect the environment. `groundskeeping` supplies the rendering and action contracts; it should not know what "ready" means for Groundworkers, CAVA, or any future application.
|
|
45
|
+
|
|
46
|
+
A good setup page usually has:
|
|
47
|
+
|
|
48
|
+
- a catalogue of setup areas, such as config, database, runtime, model server, paths, or credentials;
|
|
49
|
+
- a landing `TreeView` summarising overall readiness;
|
|
50
|
+
- a `TableView` for repeated checks where scanning matters;
|
|
51
|
+
- `KeyValueView` detail for the selected check;
|
|
52
|
+
- one or two safe verification actions; and
|
|
53
|
+
- an operation policy that describes effects in the consumer's own vocabulary.
|
|
54
|
+
|
|
55
|
+
Start read-only. Verification actions are a good first step because they exercise the shell, action contracts, progress reporting, and failure presentation without taking ownership of durable setup changes too early.
|
|
56
|
+
|
|
57
|
+
## Actions And Jobs
|
|
58
|
+
|
|
59
|
+
Actions are declarations plus runners.
|
|
60
|
+
|
|
61
|
+
An `ActionSpec` describes the operator-facing command: label, summary, fields, resources, effects, cancellation mode, and runner. `FieldSpec` parses and redacts input before it reaches the runner. The runner receives an `ActionContext` with progress and cancellation, so long-running work can report what it is doing without importing widgets.
|
|
62
|
+
|
|
63
|
+
A shell job is work launched by this TUI process. It is not a durable processing queue. Use `JobManager` and `JobPolicy` to gate in-process work and show progress; keep queue state, retries, leases, and durable records inside the consumer.
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
`groundskeeping.configurator` understands the public shape of `oa-configurator` stack configuration well enough to inspect and present it safely. It can build snapshots, section views, drafts, redacted diffs, and apply intents.
|
|
68
|
+
|
|
69
|
+
It does not write TOML. Persistence belongs to the public `oa-configurator` mutation API and to the consumer's operation policy. That separation protects comments, secrets, external edits, and tenant-specific safety rules.
|
|
70
|
+
|
|
71
|
+
Consumer applications can add `ConfigResourceAdapter` implementations for resource types that need better labels, choices, validation, verification, or post-apply effects.
|
|
72
|
+
|
|
73
|
+
## Telemetry
|
|
74
|
+
|
|
75
|
+
Telemetry has a headless core and Textual widgets layered above it.
|
|
76
|
+
|
|
77
|
+
`groundskeeping.telemetry` contains source protocols, availability, normalized metrics, snapshots, and sampling runtime. It must remain free of Textual imports so collectors can be tested and reused outside a running app.
|
|
78
|
+
|
|
79
|
+
`groundskeeping.widgets.telemetry` renders snapshots. Widgets should bind to metric keys and capabilities, not concrete provider classes. A GPU card, for example, should care about accelerator utilisation and memory metrics; it should not need to know whether the source is NVIDIA, Apple Silicon, or something added later.
|
|
80
|
+
|
|
81
|
+
Consumers own domain telemetry: queue depth, pipeline progress, database state, workload throughput, and tuning interpretation.
|
|
82
|
+
|
|
83
|
+
## Ownership Boundary
|
|
84
|
+
|
|
85
|
+
`groundskeeping` owns:
|
|
86
|
+
|
|
87
|
+
- route validation and page activation;
|
|
88
|
+
- mounted-page state preservation;
|
|
89
|
+
- the shared workbench surface;
|
|
90
|
+
- generic view models;
|
|
91
|
+
- action, field, progress, cancellation, and job contracts;
|
|
92
|
+
- in-process job gating;
|
|
93
|
+
- read-only configuration inspection and draft/diff models;
|
|
94
|
+
- Textual-free infrastructure telemetry contracts; and
|
|
95
|
+
- reusable widgets that render normalized models.
|
|
96
|
+
|
|
97
|
+
Consumers own:
|
|
98
|
+
|
|
99
|
+
- every production page;
|
|
100
|
+
- domain presenters, controllers, and services;
|
|
101
|
+
- queue semantics and durable records;
|
|
102
|
+
- YAML or other consumer configuration formats;
|
|
103
|
+
- resource-specific `oa-configurator` adapters;
|
|
104
|
+
- model calls, database access, and runtime execution;
|
|
105
|
+
- domain telemetry and tuning algorithms;
|
|
106
|
+
- operation safety policy; and
|
|
107
|
+
- application branding and help text.
|
|
108
|
+
|
|
109
|
+
## Commenting Style
|
|
110
|
+
|
|
111
|
+
Write comments for the next person adapting the tool.
|
|
112
|
+
|
|
113
|
+
Good comments explain why a boundary exists, what operator-facing behaviour depends on it, and where domain logic should stay. They are especially useful around Textual lifecycle methods, event routing, worker handoffs, cancellation, secret redaction, and extension points.
|
|
114
|
+
|
|
115
|
+
Prefer comments that preserve intent over comments that narrate syntax. Explain why row events return to the active page through the workbench surface. Do not explain that a loop iterates over rows.
|
|
116
|
+
|
|
117
|
+
If a future maintainer is likely to wonder "why is this shaped this way?", leave them a small signpost.
|
|
118
|
+
|
|
119
|
+
## Running The Demo
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
uv run groundskeeping
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The demo composes overview, configuration, and telemetry pages. It also registers a small action so the app spec and action registry can be exercised without a consumer application.
|
|
126
|
+
|
|
127
|
+
## Running Tests
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
uv run --extra dev pytest -q
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The tests cover route validation, app startup, action and job contracts, configurator redaction, telemetry import boundaries, and consumer dependency boundaries.
|