Contributing Guidelines¶
First off, thanks for considering to contribute to this project!
These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request.
Versioning and changelog¶
This project adheres to Semantic Versioning.
The CHANGELOG format tries to complies with Keep a Changelog but it’s mainly a concatenation of autogenerated release notes by GitHub Release.
Git hooks¶
We use git hooks through pre-commit to enforce and automatically check some “rules”. Please install it before any commit: pre-commit install.
See the relevant configuration file: .pre-commit-config.yaml.
Code Style¶
Make sure your code roughly follows PEP-8 and keeps things consistent with the rest of the code:
docstrings: google-style is used to write technical documentation right into the code.
formatting, imports and static analisis: ruff is used to automatically format the code without debate, sort imports and run a bunch of flake8 lint checks. The rules are set in
pyproject.toml([tool.ruff]) and enforced: the pre-commit hook applies safe fixes, then fails on any violation left, locally and on pull requests. When a rule must be bypassed on purpose, add a# noqa: <rule>comment on the line with the reason; rules that only make noise in tests are exempted there throughper-file-ignores.file system paths: use
pathlib, notos.path(noropen(),os.chmod(), etc. where pathlib has a method). Ruff’sPTHrules enforce it. The rare deliberate exceptions carry a# noqa: PTHxxxcomment saying why:dicogis.utils.paths.absolute_path(), since pathlib has no exactos.path.abspath()equivalent, and the per-file loop of the folder listing, where pathlib was measured about 6 times slower.
Graphical interface¶
The GUI is designed to run both standalone and as a QGIS plugin (QGIS >= 4.4, so Qt >= 6.8: don’t use newer Qt APIs).
Qt binding: never import
PyQt6(or any other binding) indicogis/ui. Import fromdicogis.ui.qt_compatinstead, which mirrors theqgis.PyQtlayout and resolves toqgis.PyQtinside QGIS and to PyQt6 otherwise:from dicogis.ui.qt_compat.QtWidgets import QWidget,from dicogis.ui.qt_compat import uic. If you need a Qt module it doesn’t provide yet, add the matching submodule there. TheDICOGIS_QT_APIenvironment variable (auto,qgis,pyqt6) forces the binding for troubleshooting. A test fails on any direct binding import.Interfaces: widgets and dialogs are designed in Qt Designer
.uifiles, loaded at runtime withuic.loadUi()from the Python module of the same name (wdg_tab_files.pyloadswdg_tab_files.ui). Don’t compile them withpyuic, and don’t build widgets or layouts in Python: the project’s own widgets (tab pages, tables…) go in the.uifile too, by promotion (header: the Python module path, e.g.dicogis.ui.wdg_scrollable_table). Python only fills in what’s known at runtime (values, table rows, translated texts) and wires the signals. A test fails on any widget instantiated indicogis/ui, dialogs opened at runtime aside.Widget names: a widget’s
objectNamebecomes the Python attribute holding it, so it must be PEP 8 compliant (lowercase, words separated by_) and start with the prefix of its class, which groups widgets by type and keeps names consistent across the project. Python attributes holding widgets follow the same rule, custom widgets (tab pages, collapsible frames…) takingwdg_. A test checks every.uifile against this table; extend both when using a new widget class.
Widget class |
Prefix |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Object names: give every
QActionand toolbar anobjectName, so QGIS can save the interface state and offer them in its interface customization.
Commit messages¶
We follow Conventional Commits: <type>(<scope>): <description>, e.g. feat(gui): add Publish tab for uData catalog publication. The scope is optional.
Common types used in this project:
feat: new feature or enhancementfix: bug fixdocs: documentation onlytest: adding or fixing testsrefactor: code change that neither fixes a bug nor adds a featurechore: maintenance (dependency bumps, housekeeping, etc.)ci: CI/CD configurationbuild: build system or packaging
AI Policy¶
Contributors can use whatever tools they would like to craft their contributions, but there must be a human in the loop.
Contributors must read and review all LLM-generated code before marking a pull request as ready for review. The contributor is always the author and is fully accountable for their contributions, which includes ensuring their contributions are aligned with guidelines.
Contributors should be sufficiently confident that their contribution is high enough quality that asking for a review is a good use of scarce maintainer time, and they should be able to answer questions about their work during review.
Disclosure¶
Community members are expected to be transparent and disclose AI usage in contributions submitted for review that contain substantial amounts of LLM-generated content.
“Substantial” means different things depending on the type of contribution:
Code: any generation beyond single-line autocomplete, such as whole functions, tests, or algorithms.
Documentation: anything more than a few words.
Disclosure is not penalized during PR review.
Contributors should note details on tool usage (such as models and prompts used) in PR descriptions.
Copyright and licensing¶
Using AI tools to regenerate copyrighted material does not remove the copyright. As per the GitHub TOS, contributors are responsible for ensuring they have the right to contribute code under the terms of the repository license. This responsibility applies equally to code written by hand, code generated by an AI tool, and code adapted from elsewhere.
AI level¶
If you used an AI/LLM (Claude, ChatGPT, Copilot, etc.) to help produce a contribution, please disclose it, following the transparency levels described in VisiData’s “Using AI to Contribute to Open Source”. In your PR description (or as commit message trailers), indicate:
the disclosure level, per the scale from the article above;
the model used (name/version);
a link to the session (chat/agent conversation) that produced the change, when available.
Whatever the level, a human must still vouch for the PR: you should have reviewed and tested the change yourself.
The scale, summarized:
Level |
Name |
|---|---|
0 |
Human did not use AI at all |
1 |
Human asked chatbot for ideas |
2 |
Human coded with minor assists |
3 |
Human coded, bots assisted non-trivially |
4 |
Human coded, bots helped significantly |
5 |
Bots coded, human understands completely |
6 |
Bots coded, human understands mostly |
7 |
Human specced, bots coded |
8 |
Bots planned, human approved |
9 |
Human fired-and-forgot |
10 |
Rogue bots, zero human attention |
Levels 0-8 are welcome here with proper disclosure. Levels 9-10 (autonomous bots acting without a human reviewing this specific change) are out of scope for this project unless explicitly authorized by a maintainer — see the article for the full description of each level.
Pull requests¶
Please fill out the pull request template - it’s pre-filled when you open a PR on GitHub.
Labels are applied automatically based on your branch name and changed files (see .github/labeler.yml), which also drives the release notes categorization (.github/release.yml). Prefixing your branch name accordingly helps:
fix/...orhotfix/...: bug fixfeature/...orimprove/...: new feature or enhancementdocs/...: documentationpackaging/...: build/packagingtooling/...: toolingcli/...: CLI-specific change
IDE¶
Feel free to use the IDE you love. Here come configurations for some popular IDEs to fit those guidelines.
Visual Studio Code¶
It’s the IDE used by the main developer, so the configuration is tracked on this repository until new contributors with other IDEs are joining the project.
Configuration is under: .vscode/settings.json