# Contributing

Before submitting a PR, unless it's something obvious, consider filing an issue or simply mention what you plan to do in the [Discord](https://discord.gg/UBa7pJUN7Z).
PRs are often either rejected or need to change significantly after submission so make sure before you start working on something it won't be a wasted effort.

Issues ideal for contributors can be found with the ["help wanted"](https://github.com/jdx/mise/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and ["good first issue"](https://github.com/jdx/mise/labels/good%20first%20issue) labels. These are issues that I feel are self-contained therefore don't require super in-depth understanding of the codebase or that require knowledge about something I don't understand very well myself.

## Testing

### Unit Tests

Unit tests are used for fast, relatively simple logic. They can be run with `cargo test`. The dev container is recommended
for executing since it does not require having a proper local setup.

To run locally you will need to first disable mise if you are using it.

```sh [local]
cargo test
```

### E2E Tests

Like unit tests, the e2e tests should be run either in the dev container (recommended) or with mise disabled locally.

:::code-group

```sh [local]
mise run test:e2e
```

Slow tests do not run by default or on PRs. They can be manually enabled with `TEST_ALL=1`.

### Windows E2E Tests

```sh
pwsh e2e-win\run.ps1
pwsh e2e-win\run.ps1 task # run tests matching `*task*`
```

## Dependencies

- [rust](https://www.rust-lang.org/) latest stable
- [just](https://github.com/casey/just) this should be removed in favor of mise tasks but it's still used for some things.
- `pipx` or `uv`
- bash newer than the 20-year-old version macOS provides

## Tasks

Mise uses mise itself to run tasks. See available tasks with `mise tasks`:

```sh
~/src/mise ❯ mise tasks
build                                                        ~/src/mise/.mise.toml
clean                                                        ~/src/mise/.mise.toml
format                                                       ~/src/mise/.mise.toml
lint                                                         ~/src/mise/.mise/config.toml
lint:fix                                                     ~/src/mise/.mise.toml
release                                                      ~/src/mise/.mise.toml
render                                                       ~/src/mise/.mise.toml
render:completions                                           ~/src/mise/.mise.toml
render:help                                                  ~/src/mise/.mise.toml
render:mangen                                                ~/src/mise/.mise.toml
signal-test                                                  ~/src/mise/.mise.toml
snapshots           Update test snapshots                    ~/src/mise/.mise.toml
test                                                         ~/src/mise/.mise.toml
test:e2e                                                     ~/src/mise/.mise.toml
```

## Setup

Shouldn't require anything special I'm aware of, but `mise run build` is a good sanity check to run and make sure it's all working.

## Dev Container

::: danger
The docker setup quit working and since I don't use it I haven't bothered to fix it. For now you'll need to run outside of
docker or you can try to fix the docker setup.
:::

There is a docker setup that makes development with mise easier. It is especially helpful for running the E2E tests.
Here's some example ways to use it:

```sh
mise run docker:cargo build
mise run docker:cargo test
mise run docker:mise --help # run `mise --help` in the dev container
mise run docker:mise run test:e2e # run the e2e tests inside of the docker container
mise run docker:e2e # shortcut for `mise run docker:mise run test:e2e`
```

## Pre-commit hook

You can optionally run a pre-commit hook which lints the codebase and updates generated code.
To do this, install [lefthook](https://github.com/evilmartians/lefthook) and run `lefthook install`.

## Running the CLI

Even if using the devcontainer, it's a good idea to create a shim to make it easy to launch mise. I use the following shim
in `~/.local/bin/@mise`:

```sh
#!/bin/sh
exec cargo run -q --all-features --manifest-path ~/src/mise/Cargo.toml -- "$@"
```

::: info
Don't forget to change the manifest path to the correct path for your setup.
:::

Then if that is in PATH just use `@mise` to run mise by compiling it on the fly.

```sh
@mise --help
@mise run docker:e2e
eval "$(@mise activate zsh)"
@mise activate fish | source
```

## Releasing

Run `mise run release -x [minor|patch]`. (minor if it is the first release in a month)

## Linting

- Lint codebase: `mise run lint`
- Lint and fix codebase: `mise run lint:fix`

## Generating readme and shell completion files

```sh
mise run render
```

## Adding a new setting

To add a new setting, add it to [`settings.toml`](https://github.com/jdx/mise/blob/main/settings.toml) in the root of the project and run `mise run render` to update the codebase.

## Testing packaging

This is only necessary to test if actually changing the packaging setup.

### Ubuntu (apt)

This is for arm64, but you can change the arch to amd64 if you want.

```sh
docker run -ti --rm ubuntu
apt update -y
apt install -y gpg sudo wget curl
sudo install -dm 755 /etc/apt/keyrings
wget -qO - https://mise.jdx.dev/gpg-key.pub | gpg --dearmor | sudo tee /etc/apt/keyrings/mise-archive-keyring.gpg 1> /dev/null
echo "deb [signed-by=/etc/apt/keyrings/mise-archive-keyring.gpg arch=arm64] https://mise.jdx.dev/deb stable main" | sudo tee /etc/apt/sources.list.d/mise.list
apt update
apt install -y mise
mise -V
```

### Amazon Linux 2 (yum)

```sh
docker run -ti --rm amazonlinux
yum install -y yum-utils
yum-config-manager --add-repo https://mise.jdx.dev/rpm/mise.repo
yum install -y mise
mise -v
```

### Fedora (dnf)

```sh
docker run -ti --rm fedora
dnf install -y dnf-plugins-core
dnf config-manager addrepo --from-repofile=https://mise.jdx.dev/rpm/mise.repo
dnf install -y mise
mise -v
```
