4.2 KiB
Contributing to topgrade
Thank you for your interest in contributing to topgrade!
We welcome and encourage contributions of all kinds, such as:
- Issue reports or feature requests
- Documentation improvements
- Code (PR or PR Review)
Please follow the Karma Runner guidelines for commit messages.
Adding a new step
In topgrade's term, package manager is called step.
To add a new step to topgrade:
-
Add a new variant to
enum Steppub enum Step { // Existed steps // ... // Your new step here! // You may want it to be sorted alphabetically because that looks great:) Xxx, } -
Implement the update function
You need to find the appropriate location where this update function goes, it should be a file under
src/steps, the file names are self-explanatory, for example,steps related tozshare placed insteps/zsh.rs.Then you implement the update function, and put it in the file where it belongs.
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(), wherexxxis 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 (You can find some examples where extra arguments are needed here).Update function would usually do 3 things:
- Check if the step is installed
- Output the Separator
- Invoke the step
Still, this is sufficient for most tools, but you may need some extra stuff with complicated
step. -
Finally, invoke that update function in
main.rsrunner.execute(Step::Xxx, "xxx", || ItsModule::run_xxx(&ctx))?;We use conditional compilation 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:)
Modification to the configuration entries
If your PR has the configuration options
(in src/config.rs)
modified:
- Adding new options
- Changing the existing options
Be sure to apply your changes to
config.example.toml,
and have some basic documentations guiding user how to use these options.
Before you submit your PR
Make sure your patch passes the following tests on your host:
$ 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
-
Locale
Some
steprespects locale, which means their output can be in language other than English, we should not do check on it.For example, one may want to check if a tool works by doing this:
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
xxxrespects 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.