Skip to content

Commit 83e9462

Browse files
misc: Document and automate development environment setup (#176)
Adds `DEVELOPMENT.md` with local PC development environment setup instructions. Adds a `justfile` with (incomplete set of) commands for various relevant activities. Rewires the brains of the spell check logic so we do not need to babysit the dictionary - you can simply yolo it and `just spellcheck` will preprocess the dictionary before giving it to the nitpicky `cargo-spellcheck` utility. We are now required to use `just spellcheck` instead of `cargo spellcheck`. Adds execution of all standalone examples into the `testing` check in the GitHub workflows. Fixes #173, #174 Justfile commands: ```text build PROFILE='dev' careful FILTER="" # Run unit and integration tests with extra standard libbrary debug assertions enabled. check PROFILE='dev' clippy PROFILE='dev' coverage-measure coverage-report deny docs examples PROFILE='dev' # Run all stand-alone example binaries to ensure they complete with exit code 0. format format-check hack install-tools # Installs the complete set of Rust toolchains and other tools for local PC development. miri FILTER="" # Run unit and integration tests under Miri. miri-example EXAMPLE_NAME # Run an example binary under Miri. readme # Update README.md files for all packges. readme-check # Check that README.md files for all packges are up to date. spellcheck # Check the spelling of the workspace contents. test FILTER="" # Runs unit and integration tests. test-docs FILTER="" # Runs inline examples in documentation comments (doctests). test-more FILTER="" # Same as 'test' but also run one iteration of benchmarks. udeps # Detect unused dependencies. ``` --------- Co-authored-by: martintmk <103487740+martintmk@users.noreply.github.com> Co-authored-by: martintomka <martintomka@microsoft.com>
1 parent ac52183 commit 83e9462

File tree

17 files changed

+632
-85
lines changed

17 files changed

+632
-85
lines changed

.github/actions/setup/action.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ inputs:
1010
required: false
1111
default: 'false'
1212
rust-toolchain:
13-
description: Rust toolchain to install. Can be a version (e.g., "stable", "1.70"), multiple (e.g., "stable,nightly"), or environment variable names from constants.toml (e.g., "RUST_MSRV" or "RUST_LATEST,RUST_NIGHTLY"). Leave empty to skip Rust installation.
13+
description: Rust toolchain to install. Can be a version (e.g., "stable", "1.70"), multiple (e.g., "stable,nightly"), or environment variable names from constants.env (e.g., "RUST_MSRV" or "RUST_LATEST,RUST_NIGHTLY"). Leave empty to skip Rust installation.
1414
required: false
1515
default: ''
1616
rust-components:
@@ -34,9 +34,9 @@ runs:
3434
run: |
3535
echo "CARGO_TERM_COLOR=always" >> "$GITHUB_ENV"
3636
37-
constants_path="${{ github.workspace }}/constants.toml"
37+
constants_path="${{ github.workspace }}/constants.env"
3838
while IFS= read -r line; do
39-
if [[ "$line" =~ ^([A-Z0-9_]+)[[:space:]]*=[[:space:]]*\"([^\"]+)\" ]]; then
39+
if [[ "$line" =~ ^([A-Z0-9_]+)=([^[:space:]]+) ]]; then
4040
echo "${BASH_REMATCH[1]}=${BASH_REMATCH[2]}" >> "$GITHUB_ENV"
4141
fi
4242
done < "$constants_path"
@@ -70,6 +70,10 @@ runs:
7070
name=$(echo "${BASH_REMATCH[1]}" | tr 'A-Z_' 'a-z-')
7171
val="${!tool}"
7272
[[ -n "$val" ]] && tool="cargo-$name@$val"
73+
elif [[ "$tool" =~ ^([A-Z0-9_]+)_VERSION$ ]]; then
74+
name=$(echo "${BASH_REMATCH[1]}" | tr 'A-Z_' 'a-z-')
75+
val="${!tool}"
76+
[[ -n "$val" ]] && tool="$name@$val"
7377
elif [[ "$tool" =~ ^(.+)@([A-Z0-9_]+)$ ]]; then
7478
val="${!BASH_REMATCH[2]}"
7579
[[ -n "$val" ]] && tool="${BASH_REMATCH[1]}@$val"

.github/license-check/config.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@
3434
{
3535
"include": [
3636
"**/*.toml",
37-
"**/*.ps1"
37+
"**/*.ps1",
38+
"**/*.env",
39+
"justfile",
40+
"**/*.just"
3841
],
3942
"exclude": [
4043
"target"

.github/workflows/main.yml

Lines changed: 5 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
with:
2727
enable-sccache: true
2828
rust-toolchain: RUST_MSRV, RUST_NIGHTLY
29-
cargo-tools: CARGO_NEXTEST_VERSION, CARGO_HACK_VERSION
29+
cargo-tools: CARGO_NEXTEST_VERSION, CARGO_HACK_VERSION, JUST_VERSION
3030

3131
# execute
3232
- name: Build
@@ -42,6 +42,8 @@ jobs:
4242
- name: Doc Tests
4343
if: success() || failure()
4444
run: cargo test --doc --verbose --workspace --all-features
45+
- name: Examples
46+
run: just examples
4547

4648
static-analysis:
4749
runs-on: ${{ matrix.os }}
@@ -95,53 +97,10 @@ jobs:
9597
uses: ./.github/actions/setup
9698
with:
9799
rust-toolchain: RUST_LATEST
98-
cargo-tools: CARGO_SPELLCHECK_VERSION
100+
cargo-tools: CARGO_SPELLCHECK_VERSION, JUST_VERSION
99101

100-
# execute
101-
- name: Validate Dictionary
102-
run: |
103-
FILE=".spelling"
104-
105-
# Verify the first line is an integer
106-
first_line=$(head -n 1 "$FILE")
107-
if ! [[ "$first_line" =~ ^[0-9]+$ ]]; then
108-
echo "Error: The first line of $FILE must be an integer, but got: '$first_line'"
109-
exit 1
110-
fi
111-
expected_count="$first_line"
112-
113-
# Check that the number of lines matches the integer
114-
actual_count=$(sed '1d' "$FILE" | wc -l | xargs)
115-
if [ "$expected_count" -ne "$actual_count" ]; then
116-
echo "Error: The number of lines ($actual_count) does not match $expected_count."
117-
exit 1
118-
fi
119-
120-
# Verify words are sorted and contain no duplicates
121-
# Use LC_ALL=en_US.UTF8 for consistent sorting across environments
122-
(
123-
sed '1d' $FILE | LC_ALL=en_US.UTF8 sort -uc
124-
) || {
125-
echo "Error: Dictionary is not in sorted order or contains duplicates."
126-
echo "Expected order:"
127-
LC_ALL=en_US.UTF8 sort -u <(sed '1d' $FILE)
128-
exit 1
129-
}
130-
131-
echo "Dictionary format is valid ($expected_count words)"
132102
- name: Check Spelling
133-
run: |
134-
if ! cargo spellcheck --cfg spellcheck.toml --code 1
135-
then
136-
echo ''
137-
echo ''
138-
echo 'If this is a Rust method/type/variable name, then you should'
139-
echo 'enclose it in backticks like this: `MyRustType`.'
140-
echo ''
141-
echo 'If this is a real word, then you can add it to .spelling'
142-
echo '(add the word in sorted order and update the count on line 1)'
143-
exit 1
144-
fi
103+
run: just spellcheck
145104

146105
semver:
147106
if: github.event_name == 'pull_request'

.spelling

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
299
21
32
0.X.Y
43
100k
@@ -16,6 +15,7 @@ Ani
1615
api
1716
APIs
1817
appender
18+
Cargo.toml
1919
args
2020
AspNet
2121
async
@@ -37,7 +37,6 @@ btree_map
3737
buildable
3838
bytesbuf
3939
callee
40-
Cargo.toml
4140
C-BITFLAG
4241
C-CONV
4342
C-CONV-SPECIFIC
@@ -298,4 +297,4 @@ workflows
298297
workspace
299298
w.r.t.
300299
Xamarin
301-
xxH3
300+
xxH3

DEVELOPMENT.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Development environment setup
2+
3+
The standard development environment is a Windows PC, with Windows Subsystem for Linux (WSL) used for Linux development.
4+
After following this guide, you will be able to execute all the local PC development tooling associated with this repository.
5+
6+
> 💡 Development on a Linux or Mac system is also possible, though the setup process is not documented here.
7+
8+
To run all repository tooling locally, you will need the following prerequisites:
9+
10+
* [Latest version of LLVM](https://github.com/llvm/llvm-project/releases)
11+
* Select: ☑️ Add LLVM to the system PATH for the current user
12+
* [Visual Studio Build Tools for C++](https://visualstudio.microsoft.com/visual-cpp-build-tools/) with components:
13+
* Workload: Desktop development with C++
14+
* [Latest version of Visual Studio Code](https://code.visualstudio.com/Download) with extensions:
15+
* C/C++ (ms-vscode.cpptools)
16+
* rust-analyzer (rust-lang.rust-analyzer)
17+
* WSL (ms-vscode-remote.remote-wsl)
18+
19+
> 💡 Using an IDE other than Visual Studio Code is possible, though the setup process is not documented here.
20+
21+
* [Latest version of Git](https://git-scm.com/downloads/win) with components:
22+
* Git LFS (Large File Storage)
23+
* [Latest version of PowerShell 7](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows)
24+
25+
For detailed configuration of the above, use your own judgement - the defaults should work but customization is also generally fine.
26+
27+
This guide assumes a clean Windows PC in other regards.
28+
29+
# Windows environment setup
30+
31+
1. If you had to install any of the above prerequisites, restart your PC to ensure a complete installation.
32+
1. Install Rust using [Rustup](https://rustup.rs/), with all default settings.
33+
1. Execute `cargo install just --locked` to install the Just utility (unless already installed).
34+
35+
After installing the Rust toolchain, we setup repository-specific tooling:
36+
37+
1. In a directory of your choosing, clone the `oxidizer` repo: `git clone https://github.com/microsoft/oxidizer.git`.
38+
39+
> 💡 Even though the Windows and Linux development environments are largely independent, they will both use the same working directory (created by the above `git clone` command). This allows you to build and test your changes immediately on both operating systems.
40+
41+
2. Switch to the `oxidizer` directory: `cd oxidizer`.
42+
2. Execute `git config --local include.path ./.gitconfig` to attach the repo-specific Git configuration.
43+
2. Execute `just install-tools` to install all necessary Rust toolchain versions and development tooling.
44+
2. Open `.vscode/settings.template.jsonc` and save a copy as `.vscode/settings.json` to apply repo-specific settings for Visual Studio Code. Part of this file should be the same for everyone but the rest you can customize - refer to inline comments.
45+
46+
## Validate Windows environment
47+
48+
1. Execute `just build` to build the workspace. Verify that the build is successful.
49+
1. Execute `just test` to execute all tests in the workspace. Verify that all tests pass.
50+
1. Validate that debugging works by opening `crates/tick/examples/basic.rs` and pressing the `Debug` link that appears above `main()`. This should successfully launch the example app under the debugger.
51+
52+
# Linux (WSL) environment setup
53+
54+
The Linux distribution we use for development is **Ubuntu 24.04**, running as a WSL virtual machine.
55+
56+
1. Install [Ubuntu 24.04.1 LTS](https://apps.microsoft.com/detail/9NZ3KLHXDJP5?hl=en-us&gl=US&ocid=pdpshare) from the Microsoft Store.
57+
1. Open an Ubuntu terminal (e.g. from the Microsoft Store page, from the Start menu or in Windows Terminal).
58+
* If you get an error about a required feature not being installed, try first restarting the PC to complete the feature installation.
59+
1. You will be asked to create a user account the first time you run Ubuntu. This is a local account unique to the Linux VM and is not related to your account on the host machine.
60+
61+
All commands that follow are to be executed in the Ubuntu terminal.
62+
63+
Next, we upgrade, install and configure development prerequisites:
64+
65+
1. Execute `sudo apt update && sudo apt dist-upgrade -y` to upgrade everything that is already installed.
66+
1. Execute `sudo apt install -y curl clang llvm libclang-dev gdb perl python3 python3-pip git git-lfs build-essential cmake pkg-config libssl-dev` to ensure that essential packages are installed.
67+
1. [Install PowerShell 7](https://learn.microsoft.com/en-us/powershell/scripting/install/install-ubuntu?view=powershell-7.5#installation-via-package-repository-the-package-repository).
68+
1. Execute `git config --global credential.helper "/mnt/c/Program\ Files/Git/mingw64/bin/git-credential-manager.exe"` to set the correct Git authentication flow.
69+
1. Execute `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh` and install Rust with all default settings.
70+
1. Reopen the terminal to apply changes.
71+
1. Execute `cargo install just --locked` to install the Just utility (unless already installed).
72+
73+
Next, we setup repository-specific tooling on Linux:
74+
75+
1. Switch to the `oxidizer` directory you previously cloned on Windows, using a `/mnt/c` style path to access the Windows filesystem: `cd /mnt/c/Users/username/Desktop/oxidizer` (adjusting the path to match your chosen location).
76+
1. Execute `just install-tools` to install all necessary Rust toolchain versions and development tooling.
77+
78+
## Optimize Linux build performance
79+
80+
> ⚠️ This chapter may conflict with other repos in the same WSL instance. Skip or undo if you experience problems.
81+
82+
After installing the Rust toolchains, we setup the build target directory for fast build times:
83+
84+
1. Execute `mkdir ~/target` to create a directory for Linux build outputs. While the repo directory itself is shared between Windows and Linux, we will use a dedicated directory for build outputs on Linux to improve Linux build performance.
85+
1. Execute `nano ~/.bashrc` to open a text editor on this file.
86+
1. Add `export CARGO_TARGET_DIR=~/target` near the end of the file.
87+
1. Save & exit.
88+
1. Reopen the terminal to apply changes.
89+
90+
## Validate Linux (WSL) environment
91+
92+
1. Execute `just build` to build the workspace. Verify that the build is successful.
93+
1. Execute `just test` to execute all tests in the workspace. Verify that all tests pass.
94+
95+
## Setup Visual Studio Code integration
96+
97+
Visual Studio Code is also our standard Linux IDE and requires some additional setup to work with the Linux workspace.
98+
99+
> ⚠️ While the IDE runs on the Windows desktop, all tooling runs in the Linux VM, including Visual Studio Code extensions. The below steps will instruct you to install the minimum set of required Visual Studio Code extensions for the Linux environment.
100+
101+
1. In an Ubuntu terminal, in the `oxidizer` directory, execute `code .` to open the project in Visual Studio Code.
102+
1. Open the Extensions panel in Visual Studio Code.
103+
1. Install following extensions by selecting "Install in WSL" for each:
104+
* C/C++ (ms-vscode.cpptools)
105+
* rust-analyzer (rust-lang.rust-analyzer)
106+
1. Close Visual Studio Code and open it again via `code .` to complete extension setup.
107+
108+
Validate the setup by executing the following tasks from the task palette (F1):
109+
110+
1. `Tasks: Run Build Task`
111+
1. `Tasks: Run Test Task`
112+
113+
Validate that debugging works by opening `crates/tick/examples/basic.rs` and pressing the `Debug` link that appears above `main()`. This should successfully launch the example app under the debugger.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ These are the crates built out of this repo:
4646
The following sections explain the overall engineering process we use
4747
in this repo.
4848

49+
To set up a local PC environment capable of exercising all the tooling used by this repo's development processes,
50+
you can follow the guide in [DEVELOPMENT.md](./DEVELOPMENT.md).
51+
4952
### Adding New Crates
5053

5154
Adding a new crate to this repo is done by running the `scripts\add-crate.ps1` script.

constants.env

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
# Shared constants for GitHub workflows and repository automation.
5+
6+
# Rust toolchain versions
7+
8+
# used for testing, ensures the MSRV promise is kept; must match Cargo.toml [workspace.package].rust-version
9+
RUST_MSRV=1.88
10+
# used for static analysis & mutation testing; must match rust-toolchain.toml
11+
RUST_LATEST=1.92
12+
# used for coverage and extended analysis; update on a regular basis
13+
RUST_NIGHTLY=nightly-2025-12-29
14+
# used for external type exposure checks; update alongside updates to cargo-check-external-types
15+
RUST_NIGHTLY_EXTERNAL_TYPES=nightly-2025-10-18
16+
17+
# Cargo tools
18+
CARGO_CAREFUL_VERSION=0.4.9
19+
CARGO_CHECK_EXTERNAL_TYPES_VERSION=0.4.0
20+
CARGO_DENY_VERSION=0.18.9
21+
CARGO_DOC2README_VERSION=0.6.3
22+
CARGO_ENSURE_NO_CYCLIC_DEPS_VERSION=0.2.0
23+
CARGO_ENSURE_NO_DEFAULT_FEATURES_VERSION=1.0.0
24+
CARGO_HACK_VERSION=0.6.39
25+
CARGO_LLVM_COV_VERSION=0.6.21
26+
CARGO_MUTANTS_VERSION=26.0.0
27+
CARGO_NEXTEST_VERSION=0.9.115
28+
CARGO_SEMVER_CHECKS_VERSION=0.45.0
29+
CARGO_SORT_VERSION=2.0.2
30+
CARGO_SPELLCHECK_VERSION=0.15.1
31+
CARGO_UDEPS_VERSION=0.1.60
32+
CARGO_WORKSPACES_VERSION=0.4.2
33+
34+
# Other tools
35+
JUST_VERSION=1.46.0
36+
SCCACHE_VERSION=v0.12.0

constants.toml

Lines changed: 0 additions & 30 deletions
This file was deleted.

justfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
# Required by [script]
5+
set unstable
6+
7+
set windows-shell := ["pwsh.exe", "-NoLogo", "-NoProfile", "-NonInteractive", "-Command"]
8+
set script-interpreter := ["pwsh"]
9+
10+
# Constants shared by Just commands and GitHub workflows.
11+
set dotenv-path := "./constants.env"
12+
set dotenv-required := true
13+
14+
package := ""
15+
target_package := if package == "" { "--workspace" } else { "-p " + package }
16+
17+
_default:
18+
@just --list
19+
20+
import 'justfiles/basic.just'
21+
import 'justfiles/coverage.just'
22+
import 'justfiles/format.just'
23+
import 'justfiles/setup.just'
24+
import 'justfiles/spelling.just'

0 commit comments

Comments
 (0)