Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@

# stella tooling

Shared TypeScript and oxlint configuration for stella public packages.
Shared TypeScript, oxlint, and Rust configuration for stella public packages.

This repo intentionally contains only portable tooling policy:

- `@stll/typescript-config`: strict TypeScript config presets.
- `@stll/oxlint-config`: general upstream oxlint rules and the shared
`stella-lowercase` and `no-raw-colors` JS plugins.
- `rust/`: source-of-truth Rust formatting, lint, and Cargo profile templates.

Repo-specific stella rules stay in the consuming repo: custom oxlint plugins,
security rules, i18n rules, generated native artifacts, benchmark exceptions,
and package-specific ignores.

## Usage

Install the shared packages:
Install the shared TypeScript and oxlint packages:

```bash
bun add -d @stll/typescript-config @stll/oxlint-config oxlint oxlint-tsgolint typescript
Expand Down Expand Up @@ -87,3 +88,15 @@ Recommended scripts:
}
}
```

Use the Rust templates by copying them into a Rust repository:

```bash
cp rust/rustfmt.toml /path/to/repo/rustfmt.toml
cp rust/clippy.toml /path/to/repo/clippy.toml
```

Then copy either `rust/cargo-root.toml` or `rust/cargo-workspace.toml` into the
repository's root `Cargo.toml`. Cargo does not support extending these settings
from another package, so the templates are kept here as the canonical source and
synced into consumers.
22 changes: 11 additions & 11 deletions cliff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,17 @@ sort_commits = "newest"
# digits leave headroom for new sections without breaking sort
# (single-digit `10` would otherwise sort before `2`).
commit_parsers = [
{ message = "^feat", group = "00:🚀 Features" },
{ message = "^fix", group = "01:🐛 Bug Fixes" },
{ message = "^perf", group = "02:⚡ Performance" },
{ message = "^refactor", group = "03:♻️ Refactor" },
{ message = "^docs", group = "04:📚 Documentation" },
{ message = "^test", group = "05:🧪 Tests" },
{ message = "^feat", group = "00:🚀 Features" },
{ message = "^fix", group = "01:🐛 Bug Fixes" },
{ message = "^perf", group = "02:⚡ Performance" },
{ message = "^refactor", group = "03:♻️ Refactor" },
{ message = "^docs", group = "04:📚 Documentation" },
{ message = "^test", group = "05:🧪 Tests" },
{ message = "^chore\\(deps[^)]*\\)", group = "06:📦 Dependencies" },
{ message = "^chore\\(release\\)", skip = true },
{ message = "^chore", group = "07:⚙️ Miscellaneous" },
{ message = "^style", skip = true },
{ message = "^ci", skip = true },
{ message = "^build", skip = true },
{ message = "^revert", group = "08:⏪ Reverts" },
{ message = "^chore", group = "07:⚙️ Miscellaneous" },
{ message = "^style", skip = true },
{ message = "^ci", skip = true },
{ message = "^build", skip = true },
{ message = "^revert", group = "08:⏪ Reverts" },
]
51 changes: 51 additions & 0 deletions rust/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# stella Rust policy

Shared Rust formatting, lint, and Cargo profile templates for stella public
packages.

Cargo cannot import `[lints]`, `[profile]`, or `clippy.toml` from another
package. Treat this directory as the source of truth and copy the templates
into Rust repositories when adding or refreshing Rust support.

## Files

- `rustfmt.toml`: formatting baseline.
- `clippy.toml`: portable disallowed APIs and lint thresholds.
- `cargo-root.toml`: root `Cargo.toml` snippets for single-crate packages.
- `cargo-workspace.toml`: root `Cargo.toml` snippets for workspaces.
- `cargo-config.toml`: optional `.cargo/config.toml` aliases for local and CI
checks.

## Recommended Checks

```bash
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo test --workspace --all-features --locked
cargo audit
cargo deny check
```

For pure Rust crates that do not call FFI at test runtime, also run:

```bash
cargo miri test --workspace
```

## Adoption

1. Copy `rustfmt.toml` and `clippy.toml` to the repository root.
2. Copy the relevant `[workspace.lints]` or `[lints]` section into
`Cargo.toml`.
3. Copy the release/profile section into the root `Cargo.toml`.
4. Add `[lints] workspace = true` to each workspace member, if using a
workspace.
5. Add local exceptions only with a short reason at the narrowest scope.

Keep repo-specific policy in the consuming repo. Examples: custom filesystem
wrappers, generated native artifacts, benchmark exceptions, or intentionally
unsafe FFI shims.

The shared baseline targets Rust 2024. Repositories still on Rust 2021 can copy
the templates and temporarily set `edition = "2021"` in `rustfmt.toml` until
they migrate.
6 changes: 6 additions & 0 deletions rust/cargo-config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Optional .cargo/config.toml snippet for Rust repositories.

[alias]
ci-fmt = "fmt --all -- --check"
ci-clippy = "clippy --workspace --all-targets --all-features --locked -- -D warnings"
ci-test = "test --workspace --all-features --locked"
113 changes: 113 additions & 0 deletions rust/cargo-root.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Copy these snippets into the root Cargo.toml for a single-crate package.

[lints.rust]
warnings = { level = "deny", priority = -1 }
dead_code = "deny"
future_incompatible = { level = "deny", priority = -1 }
nonstandard_style = { level = "deny", priority = -1 }
rust_2018_idioms = { level = "deny", priority = -1 }
unreachable_code = "deny"
unreachable_patterns = "deny"
unreachable_pub = "deny"
unsafe_code = "deny"
unused_imports = "deny"
unused_macros = "deny"
unused_mut = "deny"
unused_variables = "deny"

[lints.rustdoc]
broken_intra_doc_links = "deny"
bare_urls = "deny"

[lints.clippy]
all = { level = "deny", priority = -1 }
pedantic = { level = "warn", priority = -1 }
cargo = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }

dbg_macro = "deny"
todo = "deny"
unimplemented = "deny"
panic = "deny"
unwrap_used = "deny"
expect_used = "deny"
indexing_slicing = "warn"
integer_division = "warn"
arithmetic_side_effects = "warn"
as_conversions = "warn"
cast_possible_truncation = "warn"
cast_possible_wrap = "warn"
cast_precision_loss = "warn"
cast_sign_loss = "warn"
clone_on_ref_ptr = "deny"
create_dir = "deny"
decimal_literal_representation = "warn"
derive_partial_eq_without_eq = "deny"
disallowed_macros = "deny"
disallowed_methods = "deny"
disallowed_types = "deny"
empty_enum_variants_with_brackets = "deny"
empty_structs_with_brackets = "deny"
enum_glob_use = "deny"
exit = "deny"
filetype_is_file = "deny"
float_cmp = "warn"
fn_to_numeric_cast_any = "deny"
format_collect = "deny"
if_then_some_else_none = "deny"
implicit_clone = "deny"
inefficient_to_string = "deny"
large_enum_variant = "deny"
large_stack_arrays = "deny"
large_stack_frames = "deny"
manual_let_else = "deny"
manual_memcpy = "deny"
map_unwrap_or = "deny"
mem_forget = "deny"
missing_assert_message = "warn"
missing_errors_doc = "allow"
missing_panics_doc = "allow"
module_name_repetitions = "allow"
multiple_crate_versions = "allow"
needless_collect = "deny"
needless_continue = "deny"
needless_pass_by_ref_mut = "deny"
needless_pass_by_value = "deny"
or_fun_call = "deny"
print_stderr = "deny"
print_stdout = "deny"
redundant_clone = "deny"
same_name_method = "deny"
self_named_module_files = "allow"
semicolon_if_nothing_returned = "deny"
shadow_reuse = "allow"
shadow_same = "warn"
shadow_unrelated = "warn"
std_instead_of_alloc = "allow"
std_instead_of_core = "allow"
string_slice = "warn"
tests_outside_test_module = "allow"
trivially_copy_pass_by_ref = "deny"
unnecessary_wraps = "deny"
unneeded_field_pattern = "deny"
unreachable = "deny"
unused_async = "deny"
unused_self = "deny"
use_self = "warn"
used_underscore_binding = "deny"
verbose_file_reads = "deny"
wildcard_imports = "deny"

[profile.release]
lto = "fat"
codegen-units = 1
panic = "abort"
strip = "symbols"

[profile.dev]
debug = "line-tables-only"

[profile.ci]
inherits = "dev"
debug-assertions = true
overflow-checks = true
120 changes: 120 additions & 0 deletions rust/cargo-workspace.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Copy these snippets into the root Cargo.toml for a workspace.
# Add this to each member crate:
#
# [lints]
# workspace = true

[workspace]
resolver = "2"

[workspace.lints.rust]
warnings = { level = "deny", priority = -1 }
dead_code = "deny"
future_incompatible = { level = "deny", priority = -1 }
nonstandard_style = { level = "deny", priority = -1 }
rust_2018_idioms = { level = "deny", priority = -1 }
unreachable_code = "deny"
unreachable_patterns = "deny"
unreachable_pub = "deny"
unsafe_code = "deny"
unused_imports = "deny"
unused_macros = "deny"
unused_mut = "deny"
unused_variables = "deny"

[workspace.lints.rustdoc]
broken_intra_doc_links = "deny"
bare_urls = "deny"

[workspace.lints.clippy]
all = { level = "deny", priority = -1 }
pedantic = { level = "warn", priority = -1 }
cargo = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }

dbg_macro = "deny"
todo = "deny"
unimplemented = "deny"
panic = "deny"
unwrap_used = "deny"
expect_used = "deny"
indexing_slicing = "warn"
integer_division = "warn"
arithmetic_side_effects = "warn"
as_conversions = "warn"
cast_possible_truncation = "warn"
cast_possible_wrap = "warn"
cast_precision_loss = "warn"
cast_sign_loss = "warn"
clone_on_ref_ptr = "deny"
create_dir = "deny"
decimal_literal_representation = "warn"
derive_partial_eq_without_eq = "deny"
disallowed_macros = "deny"
disallowed_methods = "deny"
disallowed_types = "deny"
empty_enum_variants_with_brackets = "deny"
empty_structs_with_brackets = "deny"
enum_glob_use = "deny"
exit = "deny"
filetype_is_file = "deny"
float_cmp = "warn"
fn_to_numeric_cast_any = "deny"
format_collect = "deny"
if_then_some_else_none = "deny"
implicit_clone = "deny"
inefficient_to_string = "deny"
large_enum_variant = "deny"
large_stack_arrays = "deny"
large_stack_frames = "deny"
manual_let_else = "deny"
manual_memcpy = "deny"
map_unwrap_or = "deny"
mem_forget = "deny"
missing_assert_message = "warn"
missing_errors_doc = "allow"
missing_panics_doc = "allow"
module_name_repetitions = "allow"
multiple_crate_versions = "allow"
needless_collect = "deny"
needless_continue = "deny"
needless_pass_by_ref_mut = "deny"
needless_pass_by_value = "deny"
or_fun_call = "deny"
print_stderr = "deny"
print_stdout = "deny"
redundant_clone = "deny"
same_name_method = "deny"
self_named_module_files = "allow"
semicolon_if_nothing_returned = "deny"
shadow_reuse = "allow"
shadow_same = "warn"
shadow_unrelated = "warn"
std_instead_of_alloc = "allow"
std_instead_of_core = "allow"
string_slice = "warn"
tests_outside_test_module = "allow"
trivially_copy_pass_by_ref = "deny"
unnecessary_wraps = "deny"
unneeded_field_pattern = "deny"
unreachable = "deny"
unused_async = "deny"
unused_self = "deny"
use_self = "warn"
used_underscore_binding = "deny"
verbose_file_reads = "deny"
wildcard_imports = "deny"

[profile.release]
lto = "fat"
codegen-units = 1
panic = "abort"
strip = "symbols"

[profile.dev]
debug = "line-tables-only"

[profile.ci]
inherits = "dev"
debug-assertions = true
overflow-checks = true
26 changes: 26 additions & 0 deletions rust/clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Portable stella Rust lint configuration. Keep repo-specific wrappers and
# exceptions in consuming repositories.

disallowed-macros = [
{ path = "std::dbg", reason = "remove debug output before commit" },
{ path = "std::print", reason = "library crates should return data or use structured logging" },
{ path = "std::println", reason = "library crates should return data or use structured logging" },
{ path = "std::eprint", reason = "library crates should return data or use structured logging" },
{ path = "std::eprintln", reason = "library crates should return data or use structured logging" },
]

disallowed-methods = [
{ path = "std::mem::forget", reason = "leaks ownership; use a narrow ownership type or ManuallyDrop with justification" },
{ path = "std::string::String::from_utf8_lossy", reason = "lossy decoding can corrupt offsets and user data; validate or keep bytes" },
]

disallowed-types = [
{ path = "std::collections::LinkedList", reason = "prefer Vec, VecDeque, or an explicit intrusive structure" },
]

pass-by-value-size-limit = 64
stack-size-threshold = 131072
enum-variant-size-threshold = 128
too-large-for-stack = 4096
avoid-breaking-exported-api = false
accept-comment-above-attributes = true
4 changes: 4 additions & 0 deletions rust/rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
edition = "2024"
max_width = 80
reorder_imports = true
tab_spaces = 2