From 8186992340152bb9b8936d3943b5f35677271d06 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Sat, 6 Jul 2024 12:21:32 -0700 Subject: [PATCH] Add development guide to readme (#2226) --- README.md | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/README.md b/README.md index 997db56..fe2a549 100644 --- a/README.md +++ b/README.md @@ -3737,6 +3737,107 @@ permissive domain dedication and fallback license, so your changes must also be released under this license. +### Getting Started + +`just` is written in Rust. Use +[rustup](https://www.rust-lang.org/tools/install) to install a Rust toolchain. + +`just` is extensively tested. All new features must be covered by unit or +integration tests. Unit tests are under +[src](https://github.com/casey/just/blob/master/src), live alongside the code +being tested, and test code in isolation. Integration tests are in the [tests +directory](https://github.com/casey/just/blob/master/tests) and test the `just` +binary from the outside by invoking `just` on a given `justfile` and set of +command-line arguments, and checking the output. + +You should write whichever type of tests are easiest to write for your feature +while still providing test good coverage. + +Unit tests are useful for testing new Rust functions that are used internally, +and as an aid for development. A good example are the unit tests which cover +the +[`unindent()` function](https://github.com/casey/just/blob/master/src/unindent.rs), +used to unindent triple-quoted strings and backticks. `unindent()` has a bunch +of tricky edge cases which are easy to exercise with unit tests that call +`unindent()` directly. + +Integration tests are useful for making sure that the final behavior of the +`just` binary is correct. `unindent()` is also covered by integration tests +which make sure that evaluating a triple-quoted string produces the correct +unindented value. However, there are not integration tests for all possible +cases, since these are covered by faster, more concise unit tests that call +`unindent()` directly. + +Existing integration tests are in two forms, those that use the `test!` macro +and those that use the `Test` struct directly. The `test!` macro, while often +concise, is less flexible and harder to understand, so new tests should use the +`Test` struct. The `Test` struct is a builder which allows for easily invoking +`just` with a given `justfile`, arguments, and environment variables, and +checking the program's stdout, stderr, and exit code . + +### Contribution Workflow + +1. Make sure the feature is wanted. There should be an open issue about the + feature with a comment from [@casey](https://github.com/casey) saying that + it's a good idea or seems reasonable. If there isn't, open a new issue and + ask for feedback. + + There are lots of good features which can't be merged, either because they + aren't backwards compatible, have an implementation which would + overcomplicate the codebase, or go against `just`'s design philosophy. + +2. Settle on the design of the feature. If the feature has multiple possible + implementations or syntaxes, make sure to nail down the details in the + issue. + +3. Clone `just` and start hacking. The best workflow is to have the code you're + working on in an editor alongside a job that re-runs tests whenever a file + changes. You can run such a job by installing + [cargo-watch](https://github.com/watchexec/cargo-watch) with `cargo install + cargo-watch` and running `just watch test`. + +4. Add a failing test for your feature. Most of the time this will be an + integration test which exercises the feature end-to-end. Look for an + appropriate file to put the test in in + [tests](https://github.com/casey/just/blob/master/tests), or add a new file + in [tests](https://github.com/casey/just/blob/master/tests) and add a `mod` + statement importing that file in + [tests/lib.rs](https://github.com/casey/just/blob/master/tests/lib.rs). + +5. Implement the feature. + +6. Run `just ci` to make sure that all tests, lints, and checks pass. + +7. Open a PR with the new code that is editable by maintainers. PRs often + require rebasing and minor tweaks. If the PR is not editable by maintainers, + each rebase and tweak will require a round trip of code review. Your PR may + be summarily closed if it is not editable by maintainers. + +8. Incorporate feedback. + +9. Enjoy the sweet feeling of your PR getting merged! + +Feel free at any time to open a draft PR with your changes for discussion and +feedback. + +### Hints + +Here are some hints to get you started with specific kinds of new features, +which you can use in addition to the contribution workflow above. + +#### Adding a New Attribute + +1. Write a new integration test in + [tests/attributes.rs](https://github.com/casey/just/blob/master/tests/attributes.rs). + +2. Add a new variant to the + [`Attribute`](https://github.com/casey/just/blob/master/src/attribute.rs) + enum. + +3. Implement the functionality of the new attribute. + +4. Run `just ci` to make sure that all tests pass. + ### Janus [Janus](https://github.com/casey/janus) is a tool for checking whether a change