From 1af1801065a56d8ea06037efdcb0dfe6a59bddcc Mon Sep 17 00:00:00 2001 From: KeshavAnandCode Date: Thu, 21 May 2026 14:37:27 +0000 Subject: [PATCH] added lang pack contribution guide --- docs/contributing/language-packs.md | 188 ++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/docs/contributing/language-packs.md b/docs/contributing/language-packs.md index ad03e25..b3cb2ee 100644 --- a/docs/contributing/language-packs.md +++ b/docs/contributing/language-packs.md @@ -1 +1,189 @@ # Contributing Language Packs + +Language packs are published independently to PyPI — no access to the `foreignthon-core` repo is needed. There are more packs than the ones listed here; the ones on the official docs site are the ones hosted under the [`foreign-thon` org on Gitea](https://git.keshavanand.net/foreign-thon/). + +--- + +## The right starting point + +**Do not start from scratch.** Fork the official language template: + +``` +https://git.keshavanand.net/foreign-thon/language-template.git +``` + +The template gives you: + +| File | Purpose | +|---|---| +| `src/foreignthon_xx/__init__.py` | Exposes `get_pack_path()` and reads version/author metadata | +| `src/foreignthon_xx/xx.json` | The pack file — all keys are English stubs to replace | +| `tests/test_pack.py` | Universal test suite shared by every official pack | +| `.gitea/workflows/ci.yml` | Runs `pytest` on every push and PR | +| `.gitea/workflows/publish.yml` | Builds and uploads to PyPI on a `v*` tag | +| `.gitea/workflows/trigger-docs.yml` | Pings the docs site to rebuild when `README.md` changes | +| `pyproject.toml` | Pre-wired entry points, hatchling build, GPL v3 | + +--- + +## Step 1 — Fork and rename + +Fork the template on Gitea (or GitHub mirror). Rename your fork to `foreignthon-xx` where `xx` is the [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes) two-letter code for your language (use ISO 639-2 three-letter code if no two-letter code exists). + +Clone your fork locally: + +```bash +git clone https://git.keshavanand.net/yourname/foreignthon-xx +cd foreignthon-xx +``` + +--- + +## Step 2 — Rename the template files + +The template uses placeholder names. Rename: + +``` +src/foreignthon_xx/xx.json → src/foreignthon_fr/fr.json (example: French) +src/foreignthon_xx/ → src/foreignthon_fr/ +``` + +Then update every occurrence of `xx` in: + +- `pyproject.toml` — `name`, `entry-points` key, `packages` path, `keywords`, `description` +- `src/foreignthon_fr/__init__.py` — the `get_pack_path()` return value + +--- + +## Step 3 — Fill in the JSON + +Open `src/foreignthon_fr/fr.json`. Every value is an English Python identifier — **never change the values**. Replace the **keys** with your language's words. + +```json +{ + "meta": { + "name": "French", + "native_name": "Français", + "code": "fr" + }, + "keywords": { + "si": "if", + "sinon": "else", + ... + }, + "builtins": { ... }, + "exceptions": { ... }, + "error_messages": { ... }, + "stdlib": { ... }, + "postfix_keywords": [] +} +``` + +The filename must exactly match `meta.code` (e.g. `fr.json` for code `"fr"`). + +Set `postfix_keywords` to a list of English keywords (e.g. `["if", "elif", "while"]`) if your language is SOV and benefits from `@@` postfix style on decompile. Set it to `[]` for SVO languages. + +For a full reference on the JSON schema see [Custom Packs → Pack schema](../custom-packs.md#pack-schema). + +--- + +## Step 4 — Validate and test + +Install your pack in editable mode and run the test suite: + +```bash +pip install -e . +pip install pytest + +fpy pack src/foreignthon_fr/fr.json +# ✓ Pack 'French' is valid. + +pytest tests/ -v +``` + +The shared test suite (`tests/test_pack.py`) checks: + +- All required sections exist (`meta`, `keywords`, `builtins`, `exceptions`, `error_messages`, `stdlib`, `postfix_keywords`) +- Every keyword value is a real Python keyword +- Every builtin/exception value is a real Python builtin +- The filename matches `meta.code` +- All `postfix_keywords` entries have a matching translation in `keywords` + +The CI (`ci.yml`) runs this same suite on every push and pull request automatically. + +--- + +## Step 5 — Publish to PyPI + +You can publish from your own fork at any time — the pack works as soon as it is on PyPI, regardless of whether it is in the official org. + +Tag a release and push: + +```bash +git tag v0.1.0 +git push origin v0.1.0 +``` + +The `publish.yml` workflow builds the wheel and uploads it to PyPI using the `PYPI_TOKEN` secret. If you are working from your personal fork you will need to add your own `PYPI_TOKEN` secret in your fork's Gitea/GitHub settings. + +Once published, anyone can install your pack: + +```bash +pip install foreignthon-fr +fpy new myproject --lang fr +``` + +--- + +## Getting hosted under the official org + +The `foreign-thon` org on Gitea is where official packs live and where the org-level CI secrets (`PYPI_TOKEN`, `GIT_RELEASE_TOKEN`, `DOCS_TRIGGER_TOKEN`) are inherited automatically. + +**Nobody has direct repo-creation access in the org.** To get your pack hosted there: + +1. Make sure your pack is working and published to PyPI. +2. Open an issue or PR on [foreignthon-docs](https://git.keshavanand.net/foreign-thon/foreignthon-docs) requesting inclusion, and include: + - Your language code, English name, and native name + - A link to your published PyPI package + - Your Gitea handle +3. The maintainer will transfer or mirror your repo into the org and wire up the secrets. + +--- + +## Getting listed on the docs site + +The docs site table in [Language Packs → Overview](../language-packs/index.md) is maintained in `languages.yml` in the `foreignthon-docs` repo. Open a PR to add your entry: + +```yaml +- code: fr + name: French + repo: foreignthon-fr +``` + +The `trigger-docs.yml` workflow in your pack repo fires a rebuild of the docs site whenever `README.md` is pushed to `main`. + +--- + +## Quality bar + +Before submitting for listing, your pack should satisfy: + +- [ ] `fpy pack xx.json` passes +- [ ] `pytest tests/` passes +- [ ] Every foreign key is unique within the pack +- [ ] No English words used as foreign keys unless the language genuinely keeps them (e.g. `lambda`) +- [ ] `meta.code` matches the JSON filename and the entry-point key in `pyproject.toml` +- [ ] Package name is `foreignthon-xx` (hyphen), module name is `foreignthon_xx` (underscore) +- [ ] `pip install foreignthon-xx` works from PyPI + +--- + +## Versioning and updates + +When `foreignthon-core` releases a new version that adds entries to `template.json`, update your pack to cover them and release a new version. Update the `foreignthon` lower-bound dependency in `pyproject.toml` if your pack requires the new core: + +```toml +dependencies = ["foreignthon>=0.5.4"] +``` + +Follow [Semantic Versioning](https://semver.org/). Use `0.x.y` while the keyword set is still being refined; move to `1.0.0` once stable.