For contributing rules and best practices please refer to CONTRIBUTING.md
For this guide we assume that you already have a GitHub account and have git and your favorite code editor or IDE installed and configured.
Before you start working on coreutils, please follow these steps:
- Fork the coreutils repository to your GitHub account. Tip: See this GitHub guide for more information on this step.
- Clone that fork to your local development environment:
git clone https://github.com/YOUR-GITHUB-ACCOUNT/coreutils
cd coreutilsYou will need the tools mentioned in this section to build and test your code changes locally. This section will explain how to install and configure these tools. We also have an extensive CI that uses these tools and will check your code before it can be merged. The next section Testing will explain how to run those checks locally to avoid waiting for the CI.
As an alternative to host installation of the tools, you can open the project with the provided development container configuration. For more information about development containers, see the Visual Studio Code Dev Containers documentation.
If you're using rustup to install and manage your Rust toolchains, clippy and rustfmt are usually already installed. If you are using one of the alternative methods, please make sure to install them manually. See following sub-sections for their usage: clippy rustfmt.
Tip You might also need to add 'llvm-tools' component if you are going to generate code coverage reports locally:
rustup component add llvm-tools-previewIf you are developing on Linux, most likely you already have all/most GNU utilities and prerequisites installed.
To make sure, please check GNU coreutils README-prereq.
You will need these to run uutils against the GNU test suite locally.
For MacOS and Windows platform specific setup please check MacOS GNU utils and Windows GNU utils sections respectfully.
A configuration for pre-commit is provided in the repository. It allows
automatically checking every git commit you make to ensure it compiles, and
passes clippy and rustfmt without warnings.
To use the provided hook:
- Install
pre-commit - Run
pre-commit installwhile in the repository directory
Your git commits will then automatically be checked. If a check fails, an error
message will explain why, and your commit will be canceled. You can then make
the suggested changes, and run git commit ... again.
NOTE: On MacOS the pre-commit hooks are currently broken. There are workarounds involving switching to unstable nightly Rust and components.
cargo clippy --all-targets --all-featuresThe msrv key in the clippy configuration file clippy.toml is used to disable
lints pertaining to newer features by specifying the minimum supported Rust
version (MSRV).
cargo fmt --allThis project uses cargo-deny to detect duplicate dependencies, checks licenses, etc. To run it locally, first install it and then run with:
cargo deny --all-features check allWe use markdownlint to lint the Markdown files in the repository.
We use cspell as spell checker for all files in the project. If you are using
VS Code, you can install the
code spell checker
extension to enable spell checking within your editor. Otherwise, you can
install cspell separately.
If you want to make the spell checker ignore a word, you can add
// spell-checker:ignore word_to_ignoreat the top of the file.
This section explains how to run our CI checks locally.
Testing can be done using either Cargo or make.
Just like with building, we follow the standard procedure for testing using Cargo:
cargo testBy default, cargo test only runs the common programs. To run also platform
specific tests, run:
cargo test --features unixIf you would prefer to test a select few utilities:
cargo test --features "chmod mv tail" --no-default-featuresIf you also want to test the core utilities:
cargo test -p uucore -p coreutils
# or
cargo test --all-features -p uucoreRunning the complete test suite might take a while. We use nextest in the CI and you might want to try it out locally. It can speed up the execution time of the whole test run significantly if the cpu has multiple cores.
cargo nextest run --features unix --no-fail-fastTo debug:
rust-gdb --args target/debug/coreutils ls
(gdb) b ls.rs:79
(gdb) runTo simply test all available utilities:
make testTo test all but a few of the available utilities:
make SKIP_UTILS='UTILITY_1 UTILITY_2' testTo test only a few of the available utilities:
make UTILS='UTILITY_1 UTILITY_2' testTo include tests for unimplemented behavior:
make UTILS='UTILITY_1 UTILITY_2' SPEC=y testTo run tests with nextest just use the nextest target. Note you'll need to
install nextest first. The nextest target accepts the
same arguments like the default test target, so it's possible to pass arguments to nextest run
via CARGOFLAGS:
make CARGOFLAGS='--no-fail-fast' UTILS='UTILITY_1 UTILITY_2' nextestThis testing functionality is only available on *nix operating systems and
requires make.
To run busybox tests for all utilities for which busybox has tests
make busytestTo run busybox tests for a few of the available utilities
make UTILS='UTILITY_1 UTILITY_2' busytestTo pass an argument like "-v" to the busybox test runtime
make UTILS='UTILITY_1 UTILITY_2' RUNTEST_ARGS='-v' busytestTo run uutils against the GNU test suite locally, run the following commands:
bash util/build-gnu.sh
# Build uutils with release optimizations
env PROFILE=release bash util/build-gnu.sh
# Build uutils with SELinux
env SELINUX_ENABLED=1 bash util/build-gnu.sh
bash util/run-gnu-test.sh
# To run a single test:
bash util/run-gnu-test.sh tests/touch/not-owner.sh # for example
# To run several tests:
bash util/run-gnu-test.sh tests/touch/not-owner.sh tests/rm/no-give-up.sh # for example
# If this is a perl (.pl) test, to run in debug:
DEBUG=1 bash util/run-gnu-test.sh tests/misc/sm3sum.plTip: First time you run bash util/build-gnu.sh command, it will provide instructions on how to checkout GNU coreutils repository at the correct release tag. Please follow those instructions and when done, run bash util/build-gnu.sh command again.
You also need to install quilt, a tool used to manage a stack of patches for modifying GNU tests.
On FreeBSD, you need to install packages for GNU coreutils and sed (used in shell scripts instead of system commands):
pkg install coreutils gsedCode coverage report can be generated using grcov.
To generate gcov-based coverage report
export CARGO_INCREMENTAL=0
export RUSTFLAGS="-Cinstrument-coverage -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
export RUSTDOCFLAGS="-Cpanic=abort"
export RUSTUP_TOOLCHAIN="nightly"
cargo build <options...> # e.g., --features feat_os_unix
cargo test <options...> # e.g., --features feat_os_unix test_pathchk
grcov . -s . --binary-path ./target/debug/ -t html --branch --ignore-not-existing --ignore build.rs --excl-br-line "^\s*((debug_)?assert(_eq|_ne)?\#\[derive\()" -o ./target/debug/coverage/
# open target/debug/coverage/index.html in browserif changes are not reflected in the report then run cargo clean and run the above commands.
On MacOS you'll need to install C compiler & linker:
xcode-select --installOn MacOS you will need to install Homebrew and use it to install the following Homebrew formulas:
brew install \
coreutils \
autoconf \
gettext \
texinfo \
xz \
automake \
gnu-sed \
m4 \
bison \
pre-commit \
findutilsAfter installing these Homebrew formulas, please make sure to add the following lines to your zsh or bash rc file, i.e. ~/.profile or ~/.zshrc or ~/.bashrc ...
(assuming Homebrew is installed at default location /opt/homebrew):
eval "$(/opt/homebrew/bin/brew shellenv)"
export PATH="/opt/homebrew/opt/coreutils/libexec/gnubin:$PATH"
export PATH="/opt/homebrew/opt/bison/bin:$PATH"
export PATH="/opt/homebrew/opt/findutils/libexec/gnubin:$PATH"Last step is to link Homebrew coreutils version of timeout to /usr/local/bin (as admin user):
sudo ln -s /opt/homebrew/bin/timeout /usr/local/bin/timeoutDo not forget to either source updated rc file or restart you terminal session to update environment variables.
On Windows you'll need the MSVC build tools for Visual Studio 2013 or later.
If you are using rustup-init.exe to install Rust toolchain, it will guide you through the process of downloading and installing these prerequisites.
Otherwise please follow this guide.
If you have used Git for Windows to install git on you Windows system you might already have some GNU core utilities installed as part of "GNU Bash" included in Git for Windows package, but it is not a complete package. This article provides instruction on how to add more to it.
Alternatively you can install Cygwin and/or use WSL2 to get access to all GNU core utilities on Windows.
- Modify
util/update-version.sh(FROM & TO) and run it - Submit a new PR with these changes and wait for it to be merged
- Tag the new release
git tag -a X.Y.Zandgit push --tags - Once the CI is green, a new release will be automatically created in draft mode. Reuse this release and make sure that assets have been added.
- Write the release notes (it takes time) following previous examples
- Run
util/publish.sh --do-itto publish the new release to crates.io