User:Eduralph/Sandbox/Gramps 6.0 Wiki Manual - Addon Development - Packaging
← Previous · Index · Next →
Contents
Overview
From "works on my machine" to "users can install it from the addon manager." This chapter is the source-to-distribution pipeline: how addons-source becomes a .addon.tgz in addons, how the in-app addon manager picks it up, and what to send upstream.
The normative rules a submission must satisfy (branch targeting, version-field discipline, PR body shape, Mantis trailers) live in [15-guidelinesN-guidelines.md). This page covers the workflow — what to run, what files appear, where they end up.
The three repositories
Gramps addons live across three repositories. You'll have all three cloned side-by-side under one base directory:
base/ ├── gramps/ # gramps-project/gramps — Gramps itself; source of truth for the API ├── addons-source/ # gramps-project/addons-source — addon source code, one folder per addon └── addons/ # gramps-project/addons — built distribution, one folder per Gramps version
| Repo | What's there | You edit? |
|---|---|---|
gramps
|
The Gramps source tree; provides GRAMPSPATH for the build
|
No (unless writing a core change) |
addons-source
|
The addon source: <Addon>/<Addon>.gpr.py, <Addon>/<Addon>.py, po/, tests/
|
Yes — author addons here |
addons
|
Built .addon.tgz packages and listing JSON, organised by Gramps minor
|
No — make.py writes to it
|
addons is the output. The in-app addon manager hits its HTTPS mirror to fetch listings and downloads. Editing files in addons directly does nothing — the next make.py run overwrites them.
Branch directory split inside addons/
Inside addons/, each Gramps minor gets its own subdirectory:
addons/
├── gramps42/
├── gramps50/
├── gramps51/
├── gramps52/
├── gramps60/
│ ├── download/ # <Addon>.addon.tgz files
│ └── listings/ # JSON catalogues fetched by the addon manager
└── gramps61/
├── download/
└── listings/
The same addon can ship to multiple minors, each with its own .addon.tgz — that's why the addon manager reads only the listing for the running Gramps version.
Initial clone
mkdir gramps-addons && cd gramps-addons git clone https://github.com/gramps-project/gramps.git git clone https://github.com/gramps-project/addons-source.git git clone https://github.com/gramps-project/addons.git cd addons-source git checkout -b gramps60 origin/maintenance/gramps60 # for 6.0 # or for master/6.1: # git checkout -b gramps61 origin/master
The branch you check out in addons-source determines which Gramps minor your built addons target — make.py reads the branch name to pick the output directory inside addons/.
Adding a new language
# 1. Generate (or refresh) the template from extracted strings. make.py gramps60 init <Addon> # 2. Initialise a fresh language file from the template. make.py gramps60 init <Addon> fr # 3. Translator edits <Addon>/po/fr-local.po manually. # 4. Recompile so the .mo file lands under <Addon>/locale/fr/LC_MESSAGES/. make.py gramps60 compile <Addon> # 5. Commit the .po (NOT the .mo or the generated locale/ tree). git add <Addon>/po/fr-local.po git commit -m "Add French translation for <Addon>"
Refreshing an existing language
When you've changed user-visible strings in the addon, every existing <lang>-local.po needs new entries merged in:
make.py gramps60 update <Addon> fr
This preserves existing translations and marks new or changed entries as fuzzy for the translator to review.
Editing template.pot's header once
The header of <Addon>/po/template.pot carries author, maintainer, and team metadata. Edit it after the first init — the values propagate into every per-language file the next time you init <Addon> <lang>.
What to commit, what to skip
Commit:
<Addon>/po/template.pot<Addon>/po/<lang>-local.po(one per language)
Don't commit:
<Addon>/locale/**— generated bycompileandbuild. Always runmake.py gramps60 clean <Addon>(orrm -rf <Addon>/locale) beforegit add.<Addon>/*.mooutsidelocale/— same reason.
Publishing to addons/
build writes one .addon.tgz per addon; listing rebuilds the JSON catalogues the addon manager fetches. Both go into the addons/ repository and need committing there, not in addons-source/:
# In addons-source/, build the package. make.py gramps60 build <Addon> make.py gramps60 listing <Addon> # Switch to the addons/ checkout. cd ../addons # Stage the new .tgz and the refreshed listings. git add gramps60/download/<Addon>.addon.tgz git add gramps60/listings/* git commit -m "Add <Addon> for Gramps 6.0" # Push when you have write access — see [16-guidelines] for the review gate.
The in-app addon manager hits the addons repo over HTTPS and shows the addon to users on their next "Check for updates" cycle.
Editing addons-source/, not the live plugin directory
During development it's tempting to edit directly in ~/.local/share/gramps/gramps60/plugins/<Addon>/ so a Gramps restart picks up the change without copying. Don't — that directory is the auto-sync target, and Gramps writes back through it on every save. Edits made there are silently overwritten on the next source save.
Edit in addons-source/<Addon>/. The dev loop is one of:
- Gramps 6.0 — copy /
rsyncthe folder into the user plugin directory on each save. Plugin discovery doesn't follow symlinks. - Gramps 6.1+ on Linux/macOS — symlink the working tree into the user plugin directory once, then edit in place. Plugin discovery follows symlinks with realpath-based loop dedup (commit
9443dcbb30). - Windows, any version — physical copy. The 6.1 symlink test is skipped on Windows because the platform's symlink behaviour is inconsistent without elevated privileges.
See 02-get-started for the user plugin directory paths.
Submitting a new addon
The first time you add an addon to addons-source/:
cd addons-source # 1. Create the folder and the two required files. mkdir <Addon> $EDITOR <Addon>/<Addon>.gpr.py $EDITOR <Addon>/<Addon>.py # 2. (Optional, recommended) Translation scaffold + tests. mkdir <Addon>/po <Addon>/tests $EDITOR <Addon>/tests/__init__.py # empty marker — see 08-testing $EDITOR <Addon>/tests/test_<Addon>.py # 3. Clean any build artefacts before committing. make.py gramps60 clean <Addon> # 4. Commit and push to your fork, then open a PR. git add <Addon> git commit -m "Add <Addon>: <one-line description>"
Open the PR against the correct branch — for an addon targeting Gramps 6.0, that's maintenance/gramps60, which the maintainer cherry-picks forward to gramps61 (see 16-guidelines → Contributor workflowN-guidelines.md#contributor-workflow) for the full submission shape).
## Update an existing addon
After editing source:
```bash
cd addons-source
# 1. Iterate: edit, restart Gramps, verify behaviour.
# 2. Refresh translations if user-visible strings changed.
make.py gramps60 update <Addon> all
# 3. Compile-check.
make.py gramps60 compile <Addon>
# 4. Clean and commit.
make.py gramps60 clean <Addon>
git add <Addon>
git commit -m "<Addon>: <what changed>"
```
The `version` field in `<Addon>.gpr.py` **stays untouched** in PRs — the maintainer manages versions centrally. (See [15-guidelinesN-guidelines.md#contributor-workflow); this came up on PR 911 where a bump was rejected.)
## See also
- [01-overview — what an addon is.
- 05-fundamentals → Translation — the
_()injection that makes per-addon.pofiles load. - 08-testing — what to put in
tests/before packaging. - 13-compatibilityL-compatibility.md) — picking the right Gramps minor and branch for your addon. - [15-guidelinesN-guidelines.md) — the normative rules a PR must satisfy. - [Addons development — the standalone wiki page; primary scraped source for this chapter.
- addons-source CONTRIBUTING.md — the addons-source-side contributor guide.
|
This article's content is incomplete or a placeholder stub. |