Community

Contributing to Netsuke

Netsuke is open-source and welcoming to contributors of all backgrounds. Whether you fix a bug, write a test, improve documentation, or translate a message string, every contribution matters.

Ways to Contribute

Code

Fix bugs, add features, improve tests. Check the issue tracker for items tagged good first issue or help wanted.

Documentation

Improve explanations, add examples, fix typos, or write guides. Documentation contributions are reviewed just like code.

Translations

Netsuke's CLI messages and error text are fully localisable. Help make Netsuke accessible to users in your language.

Before you start

For significant changes, open a GitHub issue first to discuss the approach. This prevents duplicate effort and ensures your work fits the project's direction. All contributors must follow the Code of Conduct.

Development Workflow

Netsuke is written in Rust. You will need a recent stable Rust toolchain and ninja installed on your PATH.

Getting started
# Clone the repository
$ git clone https://github.com/leynos/netsuke.git
$ cd netsuke

# Build in release mode
$ cargo build --release

# Run the test suite
$ cargo test

# Run all quality gates (preferred)
$ make check-fmt lint test

Test suite structure

  • Unit tests live alongside source in src/ using #[cfg(test)] modules.
  • Integration tests live in tests/ and exercise the full manifest-to-Ninja pipeline.
  • Behavioural tests validate expected CLI output and error messages, ensuring diagnostics remain user-friendly across changes.

Compile-time validation

Several checks happen at build time to catch regressions early:

  • Manifest schema types are fully derived — new fields must include serde attributes.
  • Standard-library function signatures are tested with property-based inputs to catch edge cases.
  • Fluent message keys are verified at startup — missing keys cause a panic in development builds.

Quality Gates

Every commit must pass all quality gates before being merged. Run make check-fmt lint test locally before opening a pull request.

Format

make check-fmt

Enforces rustfmt style. Run cargo fmt to fix.

Lint

make lint

Runs clippy with project-level lints. Zero warnings allowed.

Tests

make test

Runs all unit and integration tests. All must pass.

Whitespace

git diff --check

No trailing whitespace or stray blank lines at end of file.

Documentation must be updated alongside behaviour

If you change a command-line flag, a standard-library function, or a configuration key, update the corresponding documentation in the same pull request. Reviewers will check for documentation gaps as part of code review.

Translating Netsuke

Netsuke uses Project Fluent for all user-facing text. Every message is defined in a .ftl file — one per locale — rather than as hard-coded strings. Thirty-five locale catalogues ship; English (en-US) is the source locale and the fallback for anything a translation has not yet covered. Before translating, read the upstream localization style guide for voice, tone, and register, and keep the localization glossary open for the preferred, allowed, and forbidden form of every term in your locale.

File locations

locales/
en-US/messages.ftl (source locale)
es-ES/messages.ftl
(35 shipped tags)
is/messages.ftl (your new locale)

Translation workflow

  1. 1 Copy locales/en-US/messages.ftl to a new directory named after your locale tag (e.g. locales/is/messages.ftl), then register the tag in src/locale_catalogues.rs, Cargo.toml, and the registry test.
  2. 2 Translate the message values in the style guide's voice and with the glossary's terminology. Do not rename keys — key names are used by the Rust code and must stay identical.
  3. 3 Test with NETSUKE_LOCALE=is netsuke --help to verify your strings appear correctly, and run make test.
  4. 4 Open a pull request. Include the locale file and a brief note about the translation's completeness.

Fluent format essentials

Fluent handles pluralisation and variable substitution natively. Here is an extract from en-US/messages.ftl to orient you:

en-US/messages.ftl (excerpt)
# Simple message
cli-help-description = A modern build system for intuitive, fast builds.

# Message with a variable
error-file-not-found = Error: File "{ $path }" was not found.
    .hint = Check that the path exists and is readable.

# Message with pluralisation
progress-target-count = Building { $count ->
    [one] { $count } target...
   *[other] { $count } targets...
}

Do

  • Keep key names identical to en-US/messages.ftl
  • Translate the values on the right of =
  • Keep all { $variable } placeholders
  • Adapt plural forms to your language's rules
  • Translate .hint and .label attributes
  • Use one address form consistently, per the style guide
  • Follow the glossary's per-locale terminology table

Do not

  • Rename message keys
  • Add keys that do not exist in en-US/messages.ftl
  • Remove or rename { $variable } placeholders
  • Translate product names, identifiers, or literal values such as auto and never
  • Add humour, idiom, or remediation absent from the source
  • Use machine translation without human review

Want the full picture?

This section is the short version. The full localization guide covers message-key domains, variable catalogues, CLDR plural categories, locale registration in Rust, the compile-time audit, and where the style guide and glossary fit.

Read the Translating Netsuke guide

Commit Style

Netsuke follows conventional commit style. Commit messages should be concise, use the imperative mood in the subject line, and reference the relevant issue where applicable.

Good commit message examples
fix: handle empty PATH in which() resolver

feat: add --fetch-default-deny network policy flag

docs: document accessible output mode on CLI page

test: add integration test for locale fallback to en-US

chore: update es-ES translation for progress messages
Subject line
  • Imperative mood (add, fix, not added)
  • No trailing period
  • 50 characters or fewer
Body (optional)
  • Blank line between subject and body
  • Wrap at 72 characters
  • Explain why, not just what
Trailers
  • Fixes #123 closes the issue
  • Co-authored-by: for paired work