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)
In topgrade
's term, package manager is called step
. To add a new step
to
topgrade
:
-
Add a new variant to
enum Step
pub enum Step { // Existed steps // ... // Your new step here! // You may want it to be sorted alphabetically becauses 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,step
s related tozsh
are 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()
, wherexxx
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).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.rs
runner.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
:)
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.
-
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:
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.