chore: cargo workspace skeleton
Eleven empty crates per DESIGN.md §11, versions and lints pinned once in the root manifest, Justfile carrying the §12 gate, nix dev shell. The frontend steps in `just ci` no-op until web/ exists. arr-core carries one placeholder test because `cargo nextest` fails a zero-test run, and relaxing that would let a broken filter go green later. Closes #1 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Generated
+47
@@ -0,0 +1,47 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "arr-api"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "arr-compat"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "arr-core"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "arr-daemon"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "arr-db"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "arr-dl"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "arr-e2e"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "arr-indexer"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "arr-meta"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "arr-parse"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "arr-probe"
|
||||
version = "0.1.0"
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["crates/*"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
repository = "https://git.naps.pt/yolo/arr"
|
||||
publish = false
|
||||
|
||||
[workspace.dependencies]
|
||||
# Internal
|
||||
arr-api = { path = "crates/arr-api" }
|
||||
arr-compat = { path = "crates/arr-compat" }
|
||||
arr-core = { path = "crates/arr-core" }
|
||||
arr-db = { path = "crates/arr-db" }
|
||||
arr-dl = { path = "crates/arr-dl" }
|
||||
arr-indexer = { path = "crates/arr-indexer" }
|
||||
arr-meta = { path = "crates/arr-meta" }
|
||||
arr-parse = { path = "crates/arr-parse" }
|
||||
arr-probe = { path = "crates/arr-probe" }
|
||||
|
||||
# Runtime and HTTP
|
||||
axum = "0.8"
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread", "sync", "time", "net", "io-util", "fs", "signal", "process"] }
|
||||
tower-http = { version = "0.6", features = ["trace"] }
|
||||
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
||||
|
||||
# Persistence
|
||||
sqlx = { version = "0.8", default-features = false, features = ["runtime-tokio", "sqlite", "macros", "migrate", "chrono", "json"] }
|
||||
|
||||
# API surface
|
||||
utoipa = { version = "5", features = ["axum_extras", "chrono"] }
|
||||
utoipa-axum = "0.2"
|
||||
utoipa-scalar = { version = "0.3", features = ["axum"] }
|
||||
|
||||
# Embedded frontend
|
||||
include_dir = "0.7"
|
||||
mime_guess = "2"
|
||||
|
||||
# Serialisation
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
quick-xml = { version = "0.37", features = ["serialize"] }
|
||||
toml = "0.8"
|
||||
|
||||
# Odds and ends
|
||||
chrono = { version = "0.4", default-features = false, features = ["clock", "serde"] }
|
||||
clap = { version = "4.5", features = ["derive", "env"] }
|
||||
thiserror = "2"
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
uuid = { version = "1", features = ["v4", "serde"] }
|
||||
|
||||
# Test-only
|
||||
wiremock = "0.6"
|
||||
|
||||
[workspace.lints.rust]
|
||||
unused_crate_dependencies = "warn"
|
||||
missing_debug_implementations = "warn"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
pedantic = { level = "warn", priority = -1 }
|
||||
unwrap_used = "warn"
|
||||
|
||||
[profile.release]
|
||||
lto = "thin"
|
||||
codegen-units = 1
|
||||
@@ -0,0 +1,55 @@
|
||||
# Dev entry points. `just` with no args lists them.
|
||||
|
||||
# The full per-push gate, same as CI. Run this before pushing.
|
||||
ci: fmt-check lint deps test web-check
|
||||
|
||||
# Formatting, checked not applied.
|
||||
fmt-check:
|
||||
cargo fmt --all -- --check
|
||||
|
||||
# Format every Rust source.
|
||||
fmt:
|
||||
cargo fmt --all
|
||||
|
||||
# Clippy, warnings denied.
|
||||
lint:
|
||||
cargo clippy --all-targets -- -D warnings
|
||||
|
||||
# Unused workspace dependencies. Stable toolchain, unlike cargo-udeps.
|
||||
deps:
|
||||
cargo machete
|
||||
|
||||
# Unit and integration tests, excluding the e2e crate.
|
||||
test:
|
||||
cargo nextest run --workspace --exclude arr-e2e
|
||||
|
||||
# End-to-end tests. Needs a Transmission container; not part of the push gate.
|
||||
e2e:
|
||||
cargo nextest run -p arr-e2e
|
||||
|
||||
# Frontend lint and typecheck. No-op until web/ exists (issue #6).
|
||||
web-check:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [ ! -d web ]; then echo "web/ not present yet, skipping"; exit 0; fi
|
||||
biome ci web/
|
||||
pnpm -C web install --frozen-lockfile
|
||||
pnpm -C web exec tsc -b --noEmit
|
||||
|
||||
# Build the SPA and the binary that embeds it.
|
||||
build:
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
if [ -d web ]; then
|
||||
pnpm -C web install --frozen-lockfile
|
||||
pnpm -C web build
|
||||
fi
|
||||
cargo build --release
|
||||
|
||||
# Advisory and licence scan. Scheduled, not part of the push gate.
|
||||
audit:
|
||||
cargo deny check
|
||||
|
||||
# Install the tools the gate needs.
|
||||
setup:
|
||||
cargo install cargo-nextest cargo-machete --locked
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "arr-api"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1 @@
|
||||
//! arr-api — see DESIGN.md.
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "arr-compat"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1 @@
|
||||
//! arr-compat — see DESIGN.md.
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "arr-core"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1,14 @@
|
||||
//! arr-core — domain types, policy engine, scoring. See DESIGN.md §4 and §5.
|
||||
//!
|
||||
//! This crate must never depend on `axum`, `sqlx` or `reqwest`. It holds the
|
||||
//! logic that is tested constantly and it has to stay fast to compile.
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
/// Placeholder so the test gate is meaningful on an empty workspace —
|
||||
/// `cargo nextest` fails a run with zero tests, and relaxing that would
|
||||
/// let a broken filter go green later. Replaced by real tests in the
|
||||
/// domain-types and policy-engine issues.
|
||||
#[test]
|
||||
fn workspace_builds_and_tests_run() {}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "arr-daemon"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[[bin]]
|
||||
name = "arr"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1,5 @@
|
||||
//! arr — reconcile loop and process entry point. See DESIGN.md §8.
|
||||
|
||||
fn main() {
|
||||
println!("arr");
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "arr-db"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1 @@
|
||||
//! arr-db — see DESIGN.md.
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "arr-dl"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1 @@
|
||||
//! arr-dl — see DESIGN.md.
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "arr-e2e"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1 @@
|
||||
//! arr-e2e — see DESIGN.md.
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "arr-indexer"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1 @@
|
||||
//! arr-indexer — see DESIGN.md.
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "arr-meta"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1 @@
|
||||
//! arr-meta — see DESIGN.md.
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "arr-parse"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1 @@
|
||||
//! arr-parse — see DESIGN.md.
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "arr-probe"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
@@ -0,0 +1 @@
|
||||
//! arr-probe — see DESIGN.md.
|
||||
@@ -0,0 +1,45 @@
|
||||
{
|
||||
description = "arr — single-service replacement for Radarr and Sonarr";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
rust-overlay = {
|
||||
url = "github:oxalica/rust-overlay";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, rust-overlay }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [ (import rust-overlay) ];
|
||||
};
|
||||
|
||||
rust = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
|
||||
in
|
||||
{
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
rust
|
||||
cargo-nextest
|
||||
cargo-machete
|
||||
cargo-deny
|
||||
just
|
||||
sqlite
|
||||
# arr-probe shells out to ffprobe; the e2e fixtures need ffmpeg.
|
||||
ffmpeg
|
||||
# Frontend, from issue #6 onwards.
|
||||
nodejs
|
||||
pnpm
|
||||
biome
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
echo "arr dev shell — 'just' lists the entry points"
|
||||
'';
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
[toolchain]
|
||||
channel = "stable"
|
||||
components = ["rustfmt", "clippy"]
|
||||
@@ -0,0 +1 @@
|
||||
edition = "2021"
|
||||
Reference in New Issue
Block a user