docs: CONTRIBUTING.md (#439)
This commit is contained in:
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,6 +1,7 @@
|
|||||||
## Standards checklist:
|
## Standards checklist:
|
||||||
|
|
||||||
- [ ] The PR title is descriptive.
|
- [ ] The PR title is descriptive.
|
||||||
|
- [ ] I have read `CONTRIBUTING.md`
|
||||||
- [ ] The code compiles (`cargo build`)
|
- [ ] The code compiles (`cargo build`)
|
||||||
- [ ] The code passes rustfmt (`cargo fmt`)
|
- [ ] The code passes rustfmt (`cargo fmt`)
|
||||||
- [ ] The code passes clippy (`cargo clippy`)
|
- [ ] The code passes clippy (`cargo clippy`)
|
||||||
|
|||||||
120
CONTRIBUTING.md
Normal file
120
CONTRIBUTING.md
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
## Contributing to `topgrade`
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to `topgrade`! We welcome and encourage
|
||||||
|
contributions of all kinds, such as:
|
||||||
|
|
||||||
|
1. Issue reports or feature requests
|
||||||
|
2. Documentation improvements
|
||||||
|
3. Code (PR or PR Review)
|
||||||
|
|
||||||
|
## Adding a new `step`
|
||||||
|
|
||||||
|
In `topgrade`'s term, package manager is called `step`. To add a new `step` to
|
||||||
|
`topgrade`:
|
||||||
|
|
||||||
|
1. Add a new variant to
|
||||||
|
[`enum Step`](https://github.com/topgrade-rs/topgrade/blob/cb7adc8ced8a77addf2cb051d18bba9f202ab866/src/config.rs#L100)
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub enum Step {
|
||||||
|
// Existed steps
|
||||||
|
// ...
|
||||||
|
|
||||||
|
// Your new step here!
|
||||||
|
// You may want it to be sorted alphabetically becauses that looks great:)
|
||||||
|
Xxx,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Implement the update function
|
||||||
|
|
||||||
|
You need to find the appropriate location where this update function goes, it should be
|
||||||
|
a file under [`src/steps`](https://github.com/topgrade-rs/topgrade/tree/master/src/steps),
|
||||||
|
the file names are self-explanatory, for example, `step`s related to `zsh` are
|
||||||
|
placed in [`steps/zsh.rs`](https://github.com/topgrade-rs/topgrade/blob/master/src/steps/zsh.rs).
|
||||||
|
|
||||||
|
Then you implement the update function, and put it in the file where it belongs.
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub fn run_xxx(ctx: &ExecutionContext) -> Result<()> {
|
||||||
|
// Check if this step is installed, if not, then this update will be skipped.
|
||||||
|
let xxx = require("xxx")?;
|
||||||
|
|
||||||
|
// Print the separator
|
||||||
|
print_separator("xxx");
|
||||||
|
|
||||||
|
// Invoke the new step to get things updated!
|
||||||
|
ctx.run_type()
|
||||||
|
.execute("xxx")
|
||||||
|
.arg(/* args required by this step */)
|
||||||
|
.status_checked()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Such a update function would be conventionally named `run_xxx()`, where `xxx`
|
||||||
|
is the name of the new step, and it should take a argument of type
|
||||||
|
`&ExecutionContext`, this is adequate for most cases unless some extra stuff is
|
||||||
|
needed (e.g., [you need to cleanup after update](https://github.com/topgrade-rs/topgrade/blob/cb7adc8ced8a77addf2cb051d18bba9f202ab866/src/steps/os/windows.rs#L56)).
|
||||||
|
|
||||||
|
Update function would usually do 3 things:
|
||||||
|
1. Check if the step is installed
|
||||||
|
2. Output the Separator
|
||||||
|
3. Invoke the step
|
||||||
|
|
||||||
|
Still, this is sufficient for most tools, but you may need some extra stuff
|
||||||
|
with complicated `step`.
|
||||||
|
|
||||||
|
3. Finally, invoke that update function in `main.rs`
|
||||||
|
|
||||||
|
```rust
|
||||||
|
runner.execute(Step::Xxx, "xxx", || ItsModule::run_xxx(&ctx))?;
|
||||||
|
```
|
||||||
|
|
||||||
|
We use [conditional compilation](https://doc.rust-lang.org/reference/conditional-compilation.html)
|
||||||
|
to separate the steps, for example, for steps that are Linux-only, it goes
|
||||||
|
like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
{
|
||||||
|
// Xxx is Linux-only
|
||||||
|
runner.execute(Step::Xxx, "xxx", || ItsModule::run_xxx(&ctx))?;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Congrats, you just added a new `step`:)
|
||||||
|
|
||||||
|
## Before you submit your PR
|
||||||
|
|
||||||
|
Make sure your patch passes the following tests on your host:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ cargo build
|
||||||
|
$ cargo fmt
|
||||||
|
$ cargo clippy
|
||||||
|
$ cargo test
|
||||||
|
```
|
||||||
|
|
||||||
|
Don't worry about other platforms, we have most of them covered in our CI.
|
||||||
|
|
||||||
|
## Some tips
|
||||||
|
|
||||||
|
1. Locale
|
||||||
|
|
||||||
|
Some `step` respects locale, which means their output can be in language other
|
||||||
|
then English, we should not do check on it.
|
||||||
|
|
||||||
|
For example, one may want to check if a tool works by doing this:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let output = Command::new("xxx").arg("--help").output().unwrap();
|
||||||
|
let stdout = from_utf8(output.stdout).expect("Assume it is UTF-8 encoded");
|
||||||
|
|
||||||
|
if stdout.contains("help") {
|
||||||
|
// xxx works
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If `xxx` respects locale, then the above code should work on English system,
|
||||||
|
on a system that does not use English, e.g., it uses Chinese, that `"help"` may be
|
||||||
|
translated to `"帮助"`, and the above code won't work.
|
||||||
@@ -100,8 +100,8 @@ Just fork the repository and start coding.
|
|||||||
|
|
||||||
### Contribution Guidelines
|
### Contribution Guidelines
|
||||||
|
|
||||||
- Check if your code passes `cargo fmt` and `cargo clippy`.
|
See [CONTRIBUTING.md](https://github.com/topgrade-rs/topgrade/blob/master/CONTRIBUTING.md)
|
||||||
- Check if your code is self explanatory, if not it should be documented by comments.
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
- [ ] Add a proper testing framework to the code base.
|
- [ ] Add a proper testing framework to the code base.
|
||||||
|
|||||||
Reference in New Issue
Block a user