feat(shared-skills): add user skill sources
This commit is contained in:
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env -S uv run --script
|
||||
# /// script
|
||||
# requires-python = ">=3.11"
|
||||
# dependencies = [
|
||||
# "typer",
|
||||
# "rich",
|
||||
# ]
|
||||
# ///
|
||||
|
||||
# ─── How to run ───
|
||||
# 1. Install uv (if not installed):
|
||||
# curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
# 2. Run:
|
||||
# uv run new-project.py myproject
|
||||
# uv run new-project.py myproject --path ./workspace
|
||||
# ──────────────────
|
||||
#
|
||||
# Creates a new Rust project with strict lints, deny.toml, rustfmt.toml,
|
||||
# rust-toolchain.toml, and .cargo/config.toml pre-configured.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import typer
|
||||
from rich.console import Console
|
||||
|
||||
console = Console(stderr=True)
|
||||
|
||||
# ── Embedded config contents ─────────────────────────────────────────────
|
||||
|
||||
RUST_TOOLCHAIN_TOML = """\
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
components = ["rustfmt", "clippy", "rust-src"]
|
||||
profile = "default"
|
||||
"""
|
||||
|
||||
CARGO_TOML_LINTS = """
|
||||
[lints.rust]
|
||||
unsafe_op_in_unsafe_fn = "deny"
|
||||
missing_docs = "warn"
|
||||
missing_debug_implementations = "warn"
|
||||
unreachable_pub = "warn"
|
||||
unused_must_use = "deny"
|
||||
elided_lifetimes_in_paths = "warn"
|
||||
non_ascii_idents = "deny"
|
||||
trivial_numeric_casts = "warn"
|
||||
unused_lifetimes = "warn"
|
||||
single_use_lifetimes = "warn"
|
||||
|
||||
[lints.clippy]
|
||||
all = { level = "deny", priority = -1 }
|
||||
pedantic = { level = "warn", priority = -1 }
|
||||
nursery = { level = "warn", priority = -1 }
|
||||
cargo = { level = "warn", priority = -1 }
|
||||
undocumented_unsafe_blocks = "deny"
|
||||
multiple_unsafe_ops_per_block = "deny"
|
||||
unwrap_used = "deny"
|
||||
expect_used = "deny"
|
||||
panic = "deny"
|
||||
todo = "deny"
|
||||
unimplemented = "deny"
|
||||
dbg_macro = "deny"
|
||||
print_stdout = "warn"
|
||||
print_stderr = "warn"
|
||||
module_name_repetitions = { level = "allow" }
|
||||
must_use_candidate = { level = "allow" }
|
||||
missing_errors_doc = { level = "allow" }
|
||||
missing_panics_doc = { level = "allow" }
|
||||
"""
|
||||
|
||||
CARGO_CONFIG_TOML = """\
|
||||
[build]
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=lld"]
|
||||
|
||||
[target.x86_64-unknown-linux-gnu]
|
||||
linker = "clang"
|
||||
rustflags = ["-C", "link-arg=-fuse-ld=lld"]
|
||||
|
||||
[target.aarch64-apple-darwin]
|
||||
rustflags = []
|
||||
"""
|
||||
|
||||
DENY_TOML = """\
|
||||
[advisories]
|
||||
vulnerability = "deny"
|
||||
unmaintained = "warn"
|
||||
yanked = "deny"
|
||||
|
||||
[licenses]
|
||||
unlicensed = "deny"
|
||||
allow = ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "ISC", "Unicode-3.0", "Zlib"]
|
||||
|
||||
[bans]
|
||||
multiple-versions = "warn"
|
||||
wildcards = "deny"
|
||||
|
||||
[sources]
|
||||
unknown-registry = "deny"
|
||||
unknown-git = "deny"
|
||||
"""
|
||||
|
||||
RUSTFMT_TOML = """\
|
||||
edition = "2024"
|
||||
max_width = 100
|
||||
use_field_init_shorthand = true
|
||||
use_try_shorthand = true
|
||||
"""
|
||||
|
||||
# ── Main ─────────────────────────────────────────────────────────────────
|
||||
|
||||
app = typer.Typer(add_completion=False)
|
||||
|
||||
|
||||
@app.command()
|
||||
def main(
|
||||
name: str = typer.Argument(help="Name of the new Rust project"),
|
||||
path: Path = typer.Option(
|
||||
Path.cwd(),
|
||||
"--path",
|
||||
"-p",
|
||||
help="Parent directory where the project folder is created",
|
||||
),
|
||||
) -> None:
|
||||
"""Scaffold a new Rust project with strict lints and tooling configs."""
|
||||
project_dir = path / name
|
||||
|
||||
# ── cargo init ───────────────────────────────────────────────────
|
||||
console.print(f"[bold green]Creating[/] project [cyan]{name}[/] at [dim]{project_dir}[/]")
|
||||
try:
|
||||
subprocess.run(
|
||||
["cargo", "init", str(project_dir), "--name", name],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
except FileNotFoundError:
|
||||
console.print("[bold red]Error:[/] cargo not found. Install Rust via https://rustup.rs")
|
||||
sys.exit(1)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
console.print(f"[bold red]cargo init failed:[/]\n{exc.stderr}")
|
||||
sys.exit(1)
|
||||
|
||||
# ── rust-toolchain.toml ──────────────────────────────────────────
|
||||
(project_dir / "rust-toolchain.toml").write_text(RUST_TOOLCHAIN_TOML)
|
||||
console.print(" [dim]wrote[/] rust-toolchain.toml")
|
||||
|
||||
# ── Append [lints] to Cargo.toml ─────────────────────────────────
|
||||
cargo_toml = project_dir / "Cargo.toml"
|
||||
with cargo_toml.open("a") as f:
|
||||
f.write(CARGO_TOML_LINTS)
|
||||
console.print(" [dim]appended[/] [lints] to Cargo.toml")
|
||||
|
||||
# ── .cargo/config.toml ───────────────────────────────────────────
|
||||
cargo_config_dir = project_dir / ".cargo"
|
||||
cargo_config_dir.mkdir(parents=True, exist_ok=True)
|
||||
(cargo_config_dir / "config.toml").write_text(CARGO_CONFIG_TOML)
|
||||
console.print(" [dim]wrote[/] .cargo/config.toml")
|
||||
|
||||
# ── deny.toml ────────────────────────────────────────────────────
|
||||
(project_dir / "deny.toml").write_text(DENY_TOML)
|
||||
console.print(" [dim]wrote[/] deny.toml")
|
||||
|
||||
# ── rustfmt.toml ─────────────────────────────────────────────────
|
||||
(project_dir / "rustfmt.toml").write_text(RUSTFMT_TOML)
|
||||
console.print(" [dim]wrote[/] rustfmt.toml")
|
||||
|
||||
console.print(f"\n[bold green]Done![/] cd {project_dir} && cargo check")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app()
|
||||
Reference in New Issue
Block a user