Skip to content

Commit 3e47e11

Browse files
committed
Add package review metadata command
1 parent 1a412f4 commit 3e47e11

8 files changed

Lines changed: 761 additions & 8 deletions

File tree

Cargo.lock

Lines changed: 82 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ path = "src/main.rs"
1515
[dependencies]
1616
serde = { version = "1", features = ["derive"] }
1717
serde_json = "1"
18+
toml = "0.8"
1819

1920
[dev-dependencies]

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ rustc diagnostic remapping through source maps
387387
zero-argument `fn main() -> Unit` and `fn main() -> Result<Unit, E>` package harnesses for runnable Rust output
388388
core `.rssi` interface signatures
389389
HIR builtin signatures parsed from `.rssi` interface sources instead of a hand-written Rust table
390+
initial `rsspkg.toml` package review metadata
390391
CI gates for formatting, linting, tests, and generated Rust fixtures
391392
golden tests for Rust lowering and source-map shape
392393
```
@@ -404,6 +405,7 @@ rss lint [--json] [--core|--no-core] [--interface <file.rssi> ...] <file.rss>
404405
rss fmt <file.rss>
405406
rss review [--json] --diff <old.rss> <new.rss>
406407
rss review [--json] --map <file-or-directory>
408+
rss package review [--json] <package-directory>
407409
rss lower --rust <file.rss>
408410
rss lower --rust <file.rss> --out-dir <directory>
409411
rss run [--json] <file.rss>
@@ -419,6 +421,8 @@ rss verify-rust [--json] <file.rss> --out-dir <directory>
419421

420422
`rss review --map` checks inputs before emitting a map. Files with frontend errors produce diagnostics instead of potentially misleading review classifications.
421423

424+
`rss package review` reads `rsspkg.toml`, loads declared interface/source roots, and emits conservative package review metadata. It treats `.rssi` files as the public semantic contract, reports package features separately from file-level `features:`, and raises risk for native Rust wrappers, build scripts, proc macros, unsafe policy, external links, frontend diagnostics, and unknown review-map regions.
425+
422426
If a lowered package contains `fn main() -> Unit` or `fn main() -> Result<Unit, E>`, `rss lower --rust --out-dir` also emits a Rust `src/main.rs` harness. `rss run <file.rss>` uses the same lowering path, writes a temporary Rust package, and delegates execution to `cargo run`. Use `rss run <file.rss> --out-dir <directory>` to keep the generated Rust package for inspection. Frontend and RSScript runtime diagnostics from `rss run` support `--json`; successful program output remains the program's own stdout.
423427

424428
`rss verify-rust <file.rss> --out-dir <directory>` keeps the generated package used for backend checking, including `rsscript-source-map.json`, so unmappable rustc diagnostics can be inspected against the generated Rust.

src/diagnostic.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ pub mod code {
7171
pub const REVIEW_FUNCTION_KIND_CHANGED: &str = "RSR014";
7272
}
7373

74-
#[derive(Debug, Clone, PartialEq, Eq)]
74+
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
75+
#[serde(rename_all = "lowercase")]
7576
pub enum Severity {
7677
Error,
7778
Warning,
@@ -105,7 +106,7 @@ pub struct Fix {
105106
pub applicability: String,
106107
}
107108

108-
#[derive(Debug, Clone, PartialEq, Eq)]
109+
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
109110
pub struct Diagnostic {
110111
pub code: String,
111112
pub severity: Severity,

src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod hir;
55
mod interfaces;
66
mod lexer;
77
mod lint;
8+
mod package;
89
mod review;
910
mod rust_lower;
1011
pub mod syntax;
@@ -17,6 +18,11 @@ pub use diagnostic::{
1718
format_diagnostic_explanation, format_diagnostics_human, format_diagnostics_json,
1819
};
1920
pub use lint::lint_source;
21+
pub use package::{
22+
PackageIdentity, PackageNativeRustReview, PackageReview, PackageReviewFile,
23+
PackageReviewFileKind, PackageReviewSummary, PackageRisk, format_package_review_human,
24+
format_package_review_json, review_package_dir,
25+
};
2026
pub use review::{
2127
ReviewFinding, ReviewFix, ReviewMap, ReviewMapCategorySummary, ReviewMapClassification,
2228
ReviewMapFile, ReviewMapFileRisk, ReviewMapRegion, ReviewMapSummary, ReviewRisk,

src/main.rs

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ use std::time::{SystemTime, UNIX_EPOCH};
77
use rsscript::{
88
Diagnostic, analyze_source, analyze_source_with_interfaces, check_generated_rust_package,
99
core_interfaces, explain_diagnostic_code, format_diagnostic_explanation,
10-
format_diagnostics_human, format_diagnostics_json, format_review_human, format_review_json,
11-
format_review_map_human, format_review_map_json, lint_source, lower_source_to_rust,
12-
lower_source_to_rust_package, parse_runtime_diagnostics, parse_source_map_json,
13-
remap_rustc_diagnostic_json_lines, review_map_sources, review_sources,
14-
write_generated_rust_package,
10+
format_diagnostics_human, format_diagnostics_json, format_package_review_human,
11+
format_package_review_json, format_review_human, format_review_json, format_review_map_human,
12+
format_review_map_json, lint_source, lower_source_to_rust, lower_source_to_rust_package,
13+
parse_runtime_diagnostics, parse_source_map_json, remap_rustc_diagnostic_json_lines,
14+
review_map_sources, review_package_dir, review_sources, write_generated_rust_package,
1515
};
1616

1717
fn main() -> ExitCode {
@@ -26,6 +26,7 @@ fn main() -> ExitCode {
2626
"lint" => run_lint(&args[2..]),
2727
"fmt" => run_fmt(&args[2..]),
2828
"review" => run_review(&args[2..]),
29+
"package" | "pkg" => run_package(&args[2..]),
2930
"lower" => run_lower(&args[2..]),
3031
"run" => run_generated_rust(&args[2..]),
3132
"remap-rustc" => run_remap_rustc(&args[2..]),
@@ -37,6 +38,16 @@ fn main() -> ExitCode {
3738
}
3839
}
3940

41+
fn run_package(args: &[String]) -> ExitCode {
42+
match parse_package_args(args) {
43+
PackageCommand::Review { json, path } => run_package_review(json, path),
44+
PackageCommand::Invalid => {
45+
print_usage();
46+
ExitCode::from(2)
47+
}
48+
}
49+
}
50+
4051
fn run_lint(args: &[String]) -> ExitCode {
4152
let options = parse_check_args(args);
4253
let Some(path) = options.path else {
@@ -766,6 +777,32 @@ enum ReviewCommand<'a> {
766777
Invalid,
767778
}
768779

780+
enum PackageCommand<'a> {
781+
Review { json: bool, path: &'a str },
782+
Invalid,
783+
}
784+
785+
fn parse_package_args(args: &[String]) -> PackageCommand<'_> {
786+
let mut json = false;
787+
let mut command = None;
788+
let mut paths = Vec::new();
789+
790+
for arg in args {
791+
if arg == "--json" {
792+
json = true;
793+
} else if arg == "review" {
794+
command = Some(arg.as_str());
795+
} else {
796+
paths.push(arg.as_str());
797+
}
798+
}
799+
800+
match (command, paths.as_slice()) {
801+
(Some("review"), [path]) => PackageCommand::Review { json, path },
802+
_ => PackageCommand::Invalid,
803+
}
804+
}
805+
769806
fn parse_review_args(args: &[String]) -> ReviewCommand<'_> {
770807
let mut json = false;
771808
let mut command = None;
@@ -868,6 +905,35 @@ fn run_review_map(json: bool, path: &str) -> ExitCode {
868905
ExitCode::SUCCESS
869906
}
870907

908+
fn run_package_review(json: bool, path: &str) -> ExitCode {
909+
let review = match review_package_dir(Path::new(path)) {
910+
Ok(review) => review,
911+
Err(error) => {
912+
eprintln!("{error}");
913+
return ExitCode::from(2);
914+
}
915+
};
916+
917+
if json {
918+
println!("{}", format_package_review_json(&review));
919+
} else {
920+
print!("{}", format_package_review_human(&review));
921+
if !review.diagnostics.is_empty() {
922+
print!("{}", format_diagnostics_human(&review.diagnostics));
923+
}
924+
}
925+
926+
if review
927+
.diagnostics
928+
.iter()
929+
.any(|diagnostic| diagnostic.severity.is_error())
930+
{
931+
ExitCode::from(1)
932+
} else {
933+
ExitCode::SUCCESS
934+
}
935+
}
936+
871937
struct ReviewMapSource {
872938
path: String,
873939
contents: String,
@@ -944,4 +1010,5 @@ fn print_usage() {
9441010
eprintln!(" rsscript verify-rust [--json] <file.rss> --out-dir <directory>");
9451011
eprintln!(" rsscript review [--json] --diff <old.rss> <new.rss>");
9461012
eprintln!(" rsscript review [--json] --map <file-or-directory>");
1013+
eprintln!(" rsscript package review [--json] <package-directory>");
9471014
}

0 commit comments

Comments
 (0)