From adf868872873a423deeb01defd17b0275c08f741 Mon Sep 17 00:00:00 2001 From: Alexandre Gauthier Date: Fri, 23 Oct 2026 00:17:38 -0400 Subject: [PATCH 1/2] Split readme dev docs into CONTRIBUTING.md The README was getting obnoxiously large, so the information relevant to contributors and would-be developers has been moved into CONTRIBUTING, in order to have a cleaner read for casual browsers of the repository and/or PyPI package site. --- CONTRIBUTING.md | 248 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 175 +--------------------------------- pyproject.toml | 4 +- 3 files changed, 253 insertions(+), 174 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5cd8eec --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,248 @@ +# Contributing to Exosphere + +Thank you for considering a contribution to Exosphere! + +We absolutely welcome contributions. If you are making something cool with Exosphere, +please let us know in the [GitHub Discussions](https://github.com/mrdaemon/exosphere/discussions)! + +If what you'd like to implement is a fundamental change with ramifications that touch +on the core functionality of Providers, Objects or the way Exosphere is designed, please +[open an issue](https://github.com/mrdaemon/exosphere/issues/new?template=feature_request.md) to discuss it first, +mainly to avoid clashing with projected features and the general design philosophy of the program. + +Bugfixes are always welcome. + +Documentation fixes are also welcome! If anything is unclear, we'd consider that +a bug, and [filing an issue](https://github.com/mrdaemon/exosphere/issues/new?template=documentation_suggestion.md) +would be correct, and desirable. + +## Guidelines + +### Code Style + +Code style should try to mimic the existing form where possible. +We use type annotations everywhere, and run a typechecker as standard. +The code should pass the 'check' poe task (see below), which generally should +encompass the basic stuff. + +### Test Suites + +Exosphere has an exhaustive test suite, comprised of unit tests, smoke tests, +and integration tests for all of the core functionality and most of the UI. + +If you add a feature, we would ask for minimum test coverage to ensure the +feature does not regress across supported versions and dependencies. + +Submitting a PR will run the test suite across all supported Python versions +as well as the minimum dependencies specified in `pyproject.toml`. + +We standardize on pytest and pytest-mock, essentially. The tests directory +in the project loosely mirrors the source tree and should be self-explanatory. + +When possible, favor `create_autospec` and/or `Mock(spec=...)` for fixtures, +or (preferably) reuse the existing ones. + +### Targeted Python versions + +We currently target a minimum version of **Python 3.13**, with no hard upper +boundary. New Python releases may take a moment to be added to CI, but this +is generally handled swiftly. + +Your code should always be compatible with the lowest common denominator, +which is Python 3.13, at the time of writing. CI matrices will ensure this +through the test suites. + +### Packaging Exosphere for Operating System Distributions + +Our official means of distribution is through PyPI, but we do welcome, +and will absolutely support packaging efforts for various operating systems +for inclusion in their repositories, and will subsequently integrate them in +the installation documentation. + +If the platform you are packaging for has specific needs, we are likely to +try to accommodate them through code changes, if possible! + +### LLM/"AI" Contributions Policy + +We do not endorse, recommend, or want contributions from Large Language Models +(LLMs) or "AI" code generation tools. We like our bugs human made and ethically +sourced, with a verifiable license. + +Anything you wish to contribute should be something you can explain and defend in +code review, assert the licensing of, and take responsibility for as the human who +owns the change. If you cannot explain it, or would defer to asking an LLM, please +don't bother, and save everyone the time. + +If you want the author to bother reviewing your pull request, take the time to +write it yourself. Automated PRs, or code generated by Claude, ChatGPT, Copilot +or by any Large Language Model or similar will be summarily rejected. + +### Licensing + +Content submitted to the project should be compatible with its licenses. +The short version is: MIT for code, CC BY 4.0 for documentation prose, per LICENSE +and COPYRIGHT. See those files for details. + +## Development Guide + +### Using Exosphere as a Library + +This use case is not currently well supported, but it is possible to use Exosphere as a library. +The documentation for this (alongside actual examples) is still a WIP, but you can +refer to the [Online API Documentation](https://docs.exosphere.tools/en/stable/api/index.html) +for the core functionality and objects that are considered public. + +### Development Quick Start + +The project uses [uv](https://docs.astral.sh/uv/getting-started/installation/) to +manage dependencies, and run tasks (through [poe](https://poethepoet.natn.io/)). + +It will fetch and manage its own Python if you don't have a compatible runtime available, and maintain its own venv automatically. + +```bash +uv sync --dev +uv run exosphere +``` + +Linting, formatting and testing can be done with poe tasks. + +**This should be done systematically before submitting a PR**. + +```bash +uv run poe format +uv run poe check +uv run poe test +``` + +For more details, and available tasks, run: + +```bash +uv run poe --help +``` + +### UI Development Quick Start + +The UI is built with [Textual](https://textual.textualize.io/). + +A quick start for running the UI with live editing and reloading, plus debug +console, is as follows: + +```bash +# Ensure you have the dev dependencies +uv sync --dev +# Run the console +uv run textual console +# In another terminal, run the UI +uv run textual run --dev -c exosphere ui +``` + +Congratulations! Editing any of the `.tcss` files in the `ui/` directory will +reflect changes immediately. + +### Documentation Editing Quick Start + +To edit the documentation, you can use the following commands: + +```bash +uv sync --dev +uv run poe docs-serve +``` + +This will start a local server at `http://localhost:8000` where you can view the +documentation. You can edit the files in the `docs/source` directory, and the changes +will be reflected in real-time. + +To check the documentation for spelling errors, you can run: + +```bash +uv run poe docs-spellcheck +``` + +Linting is performed as part of the `poe docs` task, which also builds the +documentation, but can also be invoked separately: + +```bash +uv run poe docs-lint +``` + +### Project Structure + +The project is managed via uv and `pyproject.toml`, which contains all dependencies, +scripts, and metadata for the application. + +Exosphere uses [Poe the Poet](https://poethepoet.natn.io/) as a task runner, and all +tasks are defined in the `pyproject.toml` file under the `[tool.poe.tasks]` table. + +#### Root Directory + +| path | description | +| ---- | ----------- | +| `LICENSES/` | Full text of every license used by the project and its assets | +| `docs/` | Sphinx documentation source tree | +| `docs/source/_ext/` | Custom Sphinx extensions for the project | +| `docs/source/changelog/` | Per-release changelog entries (markdown) and their assets | +| `examples/` | Example configuration files and reports | +| `scripts/` | Utilitarian scripts for dev and maintenance | +| `src/` | Main source code for the application | +| `tests/` | Test suite for the application | + +#### Source Tree + +| path | description | +| ---- | ----------- | +| `src/exosphere/` | Main application source code | +| `src/exosphere/commands/` | CLI command implementations | +| `src/exosphere/providers/` | Package Manager Provider implementations (e.g. debian, freebsd, redhat, etc) | +| `src/exosphere/schema/` | Reporting JSON schema definitions | +| `src/exosphere/setup/` | Discovery and platform detection module | +| `src/exosphere/templates/` | Jinja2 templates for reporting | +| `src/exosphere/ui/` | Textual UI source code | +| `src/exosphere/ui/style.tcss` | Textual CSS for styling the UI | + +The rest of the source tree should be fairly self-explanatory. + +#### Core Modules + +Paths below are relative to `src/exosphere/` unless otherwise noted. + +| module | description | +| ------ | ----------- | +| `main.py` | Main entry point for the application | +| `providers/api.py` | Package manager provider API and base classes | +| `providers/factory.py` | Concrete provider factory for creation of Package Managers | +| `cli.py` | CLI interface entry point | +| `config.py` | Configuration subsystem, including defaults | +| `context.py` | Context management for shared state across commands and UI | +| `data.py` | Data models and structures for serialization and exchange | +| `database.py` | Cache system for serialization | +| `editing.py` | External editor helper module, shared between CLI and UI | +| `errors.py` | Exception classes and general error messages | +| `fspaths.py` | Platform-appropriate filesystem paths module, for state | +| `inventory.py` | Inventory management subsystem | +| `migrations.py` | Cache format migration processes | +| `objects.py` | Main objects for representing Hosts, and most of the relevant logic | +| `pipelining.py` | SSH pipelining implementation, including reaper thread | +| `repl.py` | REPL module for interactive CLI usage | +| `reporting.py` | Reporting subsystem, including templates and formatters | +| `runners.py` | SSH runners module, handles setting up remote POSIX environment | +| `security.py` | Sudo management subsystem, including policy and utilities | + +Generally, most of the things Exosphere does to hosts (including connection management +and operations) are going to be found in `objects.py`. + +#### UI Modules + +Paths below are relative to `src/exosphere/` unless otherwise noted. + +| module | description | +| ------ | ----------- | +| `ui/app.py` | Main Textual application class and entry point for the UI | +| `ui/context.py` | UI Context management for shared state across UI components | +| `ui/elements.py` | Shared UI elements, including task runners | +| `ui/dashboard.py` | Dashboard screen implementation | +| `ui/inventory.py` | Inventory screen implementation | +| `ui/logs.py` | Logs screen implementation | +| `ui/messages.py` | Screen refresh and message passing system | +| `ui/palette.py` | Command palette providers and implementations | + +The TCSS for all of it is in a single file under `ui/style.tcss`. diff --git a/README.md b/README.md index 4b7ca50..086ae90 100644 --- a/README.md +++ b/README.md @@ -64,179 +64,10 @@ This includes network equipment with proprietary operating systems, etc. For installation instructions, configuration and usage examples, [full documentation](https://docs.exosphere.tools/) is available. -## Development +## Contributing Guidelines and Project Policies -### Development Quick Start - -TL;DR, use [uv](https://docs.astral.sh/uv/getting-started/installation/) - -```bash -uv sync --dev -uv run exosphere -``` - -Linting, formatting and testing can be done with poe tasks: - -```bash -uv run poe format -uv run poe check -uv run poe test -``` - -For more details, and available tasks, run: - -```bash -uv run poe --help -``` - -### UI Development Quick Start - -The UI is built with [Textual](https://textual.textualize.io/). - -A quick start for running the UI with live editing and reloading, plus debug -console, is as follows: - -```bash -# Ensure you have the dev dependencies -uv sync --dev -# In a separate terminal, run the console -uv run textual console -# In another terminal, run the UI -uv run textual run --dev -c exosphere ui -``` - -Congratulations! Editing any of the `.tcss` files in the `ui/` directory will -reflect changes immediately. - -### Documentation Editing Quick Start - -To edit the documentation, you can use the following commands: - -```bash -uv sync --dev -uv run poe docs-serve -``` - -This will start a local server at `http://localhost:8000` where you can view the -documentation. You can edit the files in the `docs/source` directory, and the changes -will be reflected in real-time. - -To check the documentation for spelling errors, you can run: - -```bash -uv run poe docs-spellcheck -``` - -Linting is performed as part of the `poe docs` task, which also builds the -documentation, but can also be invoked separately: - -```bash -uv run poe docs-lint -``` - -### Project Structure - -The project is managed via uv and `pyproject.toml`, which contains all dependencies, -scripts, and metadata for the application. - -Exosphere uses [Poe the Poet](https://poethepoet.natn.io/) as a task runner, and all -tasks are defined in the `pyproject.toml` file under the `[tool.poe.tasks]` table. - -#### Root Directory - -| path | description | -| ---- | ----------- | -| `LICENSES/` | Full text of every license used by the project and its assets | -| `docs/` | Sphinx documentation source tree | -| `docs/source/_ext/` | Custom Sphinx extensions for the project | -| `docs/source/changelog/` | Per-release changelog entries (markdown) and their assets | -| `examples/` | Example configuration files and reports | -| `scripts/` | Utilitarian scripts for dev and maintenance | -| `src/` | Main source code for the application | -| `tests/` | Test suite for the application | - -#### Source Tree - -| path | description | -| ---- | ----------- | -| `src/exosphere/` | Main application source code | -| `src/exosphere/commands/` | CLI command implementations | -| `src/exosphere/providers/` | Package Manager Provider implementations (e.g. debian, freebsd, redhat, etc) | -| `src/exosphere/schema/` | Reporting JSON schema definitions | -| `src/exosphere/setup/` | Discovery and platform detection module | -| `src/exosphere/templates/` | Jinja2 templates for reporting | -| `src/exosphere/ui/` | Textual UI source code | -| `src/exosphere/ui/style.tcss` | Textual CSS for styling the UI | - -The rest of the source tree should be fairly self-explanatory. - -#### Core Modules - -Paths below are relative to `src/exosphere/` unless otherwise noted. - -| module | description | -| ------ | ----------- | -| `main.py` | Main entry point for the application | -| `providers/api.py` | Package manager provider API and base classes | -| `providers/factory.py` | Concrete provider factory for creation of Package Managers | -| `cli.py` | CLI interface entry point | -| `config.py` | Configuration subsystem, including defaults | -| `context.py` | Context management for shared state across commands and UI | -| `data.py` | Data models and structures for serialization and exchange | -| `database.py` | Cache system for serialization | -| `editing.py` | External editor helper module, shared between CLI and UI | -| `errors.py` | Exception classes and general error messages | -| `fspaths.py` | Platform-appropriate filesystem paths module, for state | -| `inventory.py` | Inventory management subsystem | -| `migrations.py` | Cache format migration processes | -| `objects.py` | Main objects for representing Hosts, and most of the relevant logic | -| `pipelining.py` | SSH pipelining implementation, including reaper thread | -| `repl.py` | REPL module for interactive CLI usage | -| `reporting.py` | Reporting subsystem, including templates and formatters | -| `runners.py` | SSH runners module, handles setting up remote POSIX environment | -| `security.py` | Sudo management subsystem, including policy and utilities | - -Generally, most of the things Exosphere does to hosts (including connection management -and operations) are going to be found in `objects.py`. - -#### UI Modules - -Paths below are relative to `src/exosphere/` unless otherwise noted. - -| module | description | -| ------ | ----------- | -| `ui/app.py` | Main Textual application class and entry point for the UI | -| `ui/context.py` | UI Context management for shared state across UI components | -| `ui/elements.py` | Shared UI elements, including task runners | -| `ui/dashboard.py` | Dashboard screen implementation | -| `ui/inventory.py` | Inventory screen implementation | -| `ui/logs.py` | Logs screen implementation | -| `ui/messages.py` | Screen refresh and message passing system | -| `ui/palette.py` | Command palette providers and implementations | - -The TCSS for all of it is in a single file under `ui/style.tcss`. - -### Using Exosphere as a Library - -This use case is not currently well supported, but it is possible to use Exosphere as a library. -The documentation for this (alongside actual examples) is still a WIP, but you can -refer to the [Online API Documentation](https://docs.exosphere.tools/en/stable/api/index.html) -for the core functionality and objects that are considered public. - -## LLM/"AI" Contributions Policy - -We do not endorse, recommend, or want contributions from Large Language Models -(LLMs) or "AI" code generation tools. We like our bugs human made and ethically -sourced. - -If you want the author to bother reviewing your pull request, take the time to -write it yourself. Automated PRs from Claude, ChatGPT, Copilot or similar will -be summarily rejected. - -Similarly, anything you wish to contribute should be something you can explain -and defend in code review, as the human who owns the change. If you cannot -explain it, or would defer to asking an LLM, please don't bother, and save -everyone the time. +See the [CONTRIBUTING.md](https://github.com/mrdaemon/exosphere/blob/main/CONTRIBUTING.md) +file in the code repository for details. ## License diff --git a/pyproject.toml b/pyproject.toml index d81300c..9bc050e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -98,8 +98,8 @@ isort-check = "ruff check --select I src tests scripts --diff" typecheck = "pyright src tests scripts" ruff-format = "ruff format src tests scripts" ruff-format-check = "ruff format --check src tests scripts --diff" -spellcheck = "codespell src tests scripts docs/source README.md" -spellcheck-fix = "codespell --write-changes src tests scripts docs/source README.md" +spellcheck = "codespell src tests scripts docs/source README.md CONTRIBUTING.md" +spellcheck-fix = "codespell --write-changes src tests scripts docs/source README.md CONTRIBUTING.md" format = ['ruff-format', 'isort'] format-check = ['ruff-format-check', 'isort-check'] check = ['format-check', 'lint', 'typecheck', 'spellcheck'] From 4b9e4583c1f961f6a5e5b2845e357f4070740390 Mon Sep 17 00:00:00 2001 From: Alexandre Gauthier Date: Fri, 23 Oct 2026 22:05:55 -0400 Subject: [PATCH 2/2] Move convenience DEP5 file to proper home GitHub is suddenly starting to parse this weird out of nowhere, so we move it to .reuse/dep5, from COPYRIGHT. --- COPYRIGHT => .reuse/dep5 | 0 CONTRIBUTING.md | 2 +- README.md | 2 +- docs/source/_static/css/exosphere-overrides.css | 2 +- pyproject.toml | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename COPYRIGHT => .reuse/dep5 (100%) diff --git a/COPYRIGHT b/.reuse/dep5 similarity index 100% rename from COPYRIGHT rename to .reuse/dep5 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5cd8eec..49cb215 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -81,7 +81,7 @@ or by any Large Language Model or similar will be summarily rejected. Content submitted to the project should be compatible with its licenses. The short version is: MIT for code, CC BY 4.0 for documentation prose, per LICENSE -and COPYRIGHT. See those files for details. +and .reuse/dep5. See those files for details. ## Development Guide diff --git a/README.md b/README.md index 086ae90..e43f0ad 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file The documentation prose is licensed under CC BY 4.0, and the docs bundle a few third-party assets (fonts under the SIL OFL 1.1, a CSS file derived from the Renku Sphinx Theme under Apache-2.0). The exact per-path licensing is recorded -in machine-readable form in the [COPYRIGHT](COPYRIGHT) file, with full license +in machine-readable form in the [dep5](.reuse/dep5) file, with full license texts under [LICENSES/](LICENSES/). The bundled fonts under `docs/source/_static/fonts/` are cosmetic and safe to diff --git a/docs/source/_static/css/exosphere-overrides.css b/docs/source/_static/css/exosphere-overrides.css index 1d12913..effdbd5 100644 --- a/docs/source/_static/css/exosphere-overrides.css +++ b/docs/source/_static/css/exosphere-overrides.css @@ -18,7 +18,7 @@ * directory. The non-bundled DejaVu Sans / DejaVu Sans Mono are specified * only as a convenience fallback and are not distributed with this project. * - * See the top-level COPYRIGHT file for the full machine-readable summary. + * See the top-level .reuse/dep5 file for the full machine-readable summary. */ /* Font definitions, no Google Fonts please */ diff --git a/pyproject.toml b/pyproject.toml index 9bc050e..4bce2b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ license = "MIT" license-files = [ "LICENSE", "LICENSES/*", - "COPYRIGHT", + ".reuse/dep5", ] dependencies = [