3.7 KiB
Contributing to Core
foreignthon-core is the transpiler engine, CLI, and pack loader. Contributions that improve correctness, performance, or usability are welcome.
Repository
https://git.keshavanand.net/foreign-thon/foreignthon-core
Dev setup
git clone https://git.keshavanand.net/foreign-thon/foreignthon-core
cd foreignthon-core
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[dev]" # installs foreignthon + pytest + ruff
Verify the install:
fpy --version
pytest
Running tests
pytest # all tests
pytest -v # verbose
pytest -k postfix # filter by name
Tests live in tests/test_engine.py. They use a local test_pack.json fixture (a copy of the Spanish pack) so no installed language pack is needed.
Code style
ForeignThon uses Ruff for linting and formatting:
ruff check src/ # lint
ruff format src/ # format
The CI gate runs both. A PR that fails either will not be merged.
Line length is 88. Import order follows the I rule set (isort-compatible).
Project layout
foreignthon-core/
├── src/
│ └── foreignthon/
│ ├── __init__.py # version
│ ├── cli.py # click commands (fpy)
│ ├── errors.py # bilingual error hook
│ ├── pack.py # pack discovery and validation
│ ├── template.json # canonical list of all pack keys
│ └── transpiler.py # tokenizer-based engine
└── tests/
├── test_engine.py
└── test_pack.json # Spanish fixture (no install needed)
Adding new keywords or builtins
template.json is the single source of truth for the full set of keywords, builtins, exceptions, and stdlib names that all language packs must cover.
To add a new entry (e.g. a new builtin):
- Add it to
template.jsonwith the English value as the default. - Add a matching entry to
test_pack.json(Spanish values). - Update
_build_mapping()intranspiler.pyif a new section is needed. - Bump
foreignthon-coreversion. - Announce to language pack maintainers so they can update their packs.
Do not add entries to template.json that are specific to one language pack.
Adding a new CLI command
All commands are defined in cli.py using Click.
- Add your command as a function decorated with
@main.command(). - Include a docstring — Click uses it as the
--helptext. - Add
CONTEXT_SETTINGSto every command for consistent-hsupport. - Write tests in
tests/test_engine.pyor a new test file.
Submitting a PR
- Fork the repository on Gitea.
- Create a branch:
git checkout -b feature/my-change. - Make your change, add or update tests, run
pytestandruff check. - Open a PR with a clear description of the problem and the fix.
For large changes (new features, engine behaviour changes), open an issue first to discuss before writing code.
What not to change
template.jsonkeys should only grow, never shrink — removing a key is a breaking change for all existing language packs.- The tokenizer-based approach in
transpiler.pyis intentional. Do not replace it with a regex or AST-based approach without a very strong reason — the tokenizer correctly handles strings, comments, and f-strings without any special casing. - The bilingual error format (
[XX] ForeignName: msg/[EN] EnglishName: msg) is part of the public interface. Do not change the format without a major version bump.