Skip to content
Open
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
50 changes: 13 additions & 37 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,46 +48,22 @@ jobs:
tool: cargo-llvm-cov

- name: Run coverage
# Mirrors the `cargo-test` job's exclude list (host-only UI
# backends). `--no-fail-fast` keeps the
# report comprehensive even if one crate's tests fail —
# this is a visibility job, not a gate.
# Uses the same centralized Linux test scope as `cargo-test`.
# Keep collecting and reporting partial coverage if a test fails —
# this is a visibility job, not a test gate.
run: |
cargo llvm-cov --workspace --no-fail-fast \
--exclude perry-doc-fixture-my-bindings \
--exclude perry-ui-macos \
--exclude perry-ui-ios \
--exclude perry-ui-visionos \
--exclude perry-ui-tvos \
--exclude perry-ui-watchos \
--exclude perry-ui-gtk4 \
--exclude perry-ui-android \
--exclude perry-ui-windows \
--exclude perry-ui-windows-winui \
mapfile -t excluded < <(python3 scripts/workspace_architecture.py \
--print-excluded-scope linux-test)
exclude_args=()
for package in "${excluded[@]}"; do exclude_args+=(--exclude "$package"); done
cargo llvm-cov --workspace --no-fail-fast --ignore-run-fail \
"${exclude_args[@]}" \
--html --output-dir target/llvm-cov-html
cargo llvm-cov report --no-fail-fast \
--exclude perry-doc-fixture-my-bindings \
--exclude perry-ui-macos \
--exclude perry-ui-ios \
--exclude perry-ui-visionos \
--exclude perry-ui-tvos \
--exclude perry-ui-watchos \
--exclude perry-ui-gtk4 \
--exclude perry-ui-android \
--exclude perry-ui-windows \
--exclude perry-ui-windows-winui \
cargo llvm-cov report \
"${exclude_args[@]}" \
--lcov --output-path target/lcov.info
cargo llvm-cov report --no-fail-fast \
--exclude perry-doc-fixture-my-bindings \
--exclude perry-ui-macos \
--exclude perry-ui-ios \
--exclude perry-ui-visionos \
--exclude perry-ui-tvos \
--exclude perry-ui-watchos \
--exclude perry-ui-gtk4 \
--exclude perry-ui-android \
--exclude perry-ui-windows \
--exclude perry-ui-windows-winui \
cargo llvm-cov report \
"${exclude_args[@]}" \
--summary-only > target/summary.txt
# Don't fail the workflow on a non-zero exit — the artifacts
# below are still useful, and a missing test in one crate
Expand Down
39 changes: 30 additions & 9 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ jobs:
- name: Check formatting
run: cargo fmt --all -- --check

- name: Audit workspace architecture
run: |
python3 scripts/workspace_architecture.py --self-test
python3 scripts/workspace_architecture.py --check --print-summary

- name: Public benchmark evidence freshness
run: |
PYTHONPATH=. python3 tests/test_public_baseline.py
Expand Down Expand Up @@ -167,13 +172,18 @@ jobs:
# ---------------------------------------------------------------------------
# Clippy — enforces the deny-level lints in [workspace.lints] (root
# Cargo.toml). `cargo clippy` exits nonzero only on `deny` lints, so
# warn-level output is informational and never blocks a PR. Separate from
# `lint` because it compiles the whole default-member set (~30 min cold);
# `lint` stays the fast fmt/gates job.
# warn-level output is informational and never blocks a PR. The product leg
# gives fast feedback for the CLI; the host-compatible leg names every Linux
# package explicitly. Neither scope depends on Cargo default-members.
# ---------------------------------------------------------------------------
clippy:
name: Clippy (${{ matrix.scope }})
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
fail-fast: false
matrix:
scope: [product, host-compatible]
env:
RUSTC_WRAPPER: sccache
SCCACHE_GHA_ENABLED: "false"
Expand Down Expand Up @@ -206,8 +216,19 @@ jobs:
shared-key: "${{ runner.os }}-perry"
save-if: ${{ github.ref == 'refs/heads/main' }}

- name: Run clippy
run: cargo clippy
- name: Run clippy for explicit scope
run: |
if [[ "${{ matrix.scope }}" == "product" ]]; then
cargo clippy -p perry --bins
else
mapfile -t excluded < <(python3 scripts/workspace_architecture.py \
--print-excluded-scope host-compatible)
cargo_args=(--workspace)
for package in "${excluded[@]}"; do
cargo_args+=(--exclude "$package")
done
cargo clippy "${cargo_args[@]}"
fi

# ---------------------------------------------------------------------------
# API docs drift gate (#465)
Expand Down Expand Up @@ -306,9 +327,8 @@ jobs:
# workaround). Each downstream job below builds in parallel directly.
cargo-test:
# Was macos-14 — moved to ubuntu-latest in v0.5.392 to drop the 10×
# billing weight. cargo-test's `--exclude` list already filters out
# every macOS-specific UI crate (perry-ui-{ios,visionos,tvos,
# watchos,gtk4,android,windows} per the comment block below), so
# billing weight. The centralized Linux test scope already filters out
# platform-specific UI crates, so
# the platform-independent test set runs identically on Linux. The
# macOS-host coverage we lose here is negligible — these tests
# don't exercise any platform behavior; they're pure logic +
Expand Down Expand Up @@ -392,7 +412,8 @@ jobs:
rm -rf target/perry-auto-* target/debug/libperry_ext_*.a 2>/dev/null || true

- name: Run cargo test
# Exclude UI backends that don't build on the ubuntu-latest CI image:
# The exclusions below are maintained once in
# workspace-architecture.json and consumed by ci_test_scope.py:
# - perry-ui-macos / perry-ui-ios / perry-ui-tvos / perry-ui-watchos
# / perry-ui-visionos: depend on `objc2` which only compiles on
# Apple platforms (`compile_error!` in objc2/src/lib.rs:219).
Expand Down
3 changes: 1 addition & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,7 @@ TypeScript (.ts) → Parse (SWC) → AST → Lower → HIR → Transform → Cod
|-------|---------|
| **perry** | CLI driver (parallel module codegen via rayon) |
| **perry-parser** | SWC wrapper for TypeScript parsing |
| **perry-types** | Type system definitions |
| **perry-hir** | HIR data structures (`ir.rs`) and AST→HIR lowering (`lower.rs`) |
| **perry-hir** | HIR types and data structures, plus AST→HIR lowering |
| **perry-transform** | IR passes (closure conversion, async lowering, inlining) |
| **perry-codegen** | LLVM-based native code generation |
| **perry-runtime** | Runtime: value.rs, object.rs, array.rs, string.rs, gc.rs, arena.rs, thread.rs |
Expand Down
16 changes: 0 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 2 additions & 59 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ resolver = "2"
members = [
"crates/perry",
"crates/perry-parser",
"crates/perry-types",
"crates/perry-api-manifest",
"crates/perry-hir",
"crates/perry-transform",
Expand Down Expand Up @@ -43,6 +42,7 @@ members = [
"crates/perry-ext-ws",
"crates/perry-ext-net",
"crates/perry-ext-http",
"crates/perry-ext-http-server",
"crates/perry-ext-streams",
"crates/perry-ext-fastify",
"crates/perry-ext-pdf",
Expand Down Expand Up @@ -84,63 +84,6 @@ members = [
# explicitly with -p on their target platform.
default-members = [
"crates/perry",
"crates/perry-parser",
"crates/perry-types",
"crates/perry-api-manifest",
"crates/perry-hir",
"crates/perry-transform",
"crates/perry-codegen",
"crates/perry-dispatch",
"crates/perry-runtime",
"crates/perry-ffi",
"crates/perry-ext-dotenv",
"crates/perry-ext-nanoid",
"crates/perry-ext-uuid",
"crates/perry-ext-slugify",
"crates/perry-ext-bcrypt",
"crates/perry-ext-argon2",
"crates/perry-ext-jsonwebtoken",
"crates/perry-ext-validator",
"crates/perry-ext-lru-cache",
"crates/perry-ext-better-sqlite3",
"crates/perry-ext-zlib",
"crates/perry-ext-exponential-backoff",
"crates/perry-ext-axios",
"crates/perry-ext-events",
"crates/perry-ext-decimal",
"crates/perry-ext-dayjs",
"crates/perry-ext-moment",
"crates/perry-ext-cheerio",
"crates/perry-ext-sharp",
"crates/perry-ext-ratelimit",
"crates/perry-ext-commander",
"crates/perry-ext-ethers",
"crates/perry-ext-nodemailer",
"crates/perry-ext-cron",
"crates/perry-ext-ioredis",
"crates/perry-ext-pg",
"crates/perry-ext-mysql2",
"crates/perry-ext-fetch",
"crates/perry-ext-mongodb",
"crates/perry-ext-ws",
"crates/perry-ext-net",
"crates/perry-ext-http",
"crates/perry-ext-streams",
"crates/perry-ext-fastify",
"crates/perry-ext-pdf",
"crates/perry-ext-ads",
"crates/perry-wasm-host",
"crates/perry-stdlib",
"crates/perry-diagnostics",
"crates/perry-ui",
"crates/perry-codegen-js",
"crates/perry-codegen-swiftui",
"crates/perry-codegen-arkts",
"crates/perry-codegen-glance",
"crates/perry-codegen-wear-tiles",
"crates/perry-codegen-wasm",
"crates/perry-updater",
"crates/perry-container-compose",
]

# Aggressive release optimizations for small, fast binaries
Expand Down Expand Up @@ -446,7 +389,6 @@ zstd = "0.13"

# Internal crates
perry-parser = { path = "crates/perry-parser" }
perry-types = { path = "crates/perry-types" }
perry-api-manifest = { path = "crates/perry-api-manifest" }
perry-hir = { path = "crates/perry-hir" }
perry-transform = { path = "crates/perry-transform" }
Expand Down Expand Up @@ -505,6 +447,7 @@ perry-ext-mongodb = { path = "crates/perry-ext-mongodb" }
perry-ext-ws = { path = "crates/perry-ext-ws" }
perry-ext-net = { path = "crates/perry-ext-net" }
perry-ext-http = { path = "crates/perry-ext-http" }
perry-ext-http-server = { path = "crates/perry-ext-http-server" }
perry-ext-streams = { path = "crates/perry-ext-streams" }
perry-ext-fastify = { path = "crates/perry-ext-fastify" }
perry-ext-pdf = { path = "crates/perry-ext-pdf" }
Expand Down
1 change: 1 addition & 0 deletions changelog.d/6758-workspace-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**Workspace architecture baseline:** make all 78 effective Cargo members explicit, reduce the default build to the Perry CLI and its 18-crate dependency closure, add a reproducible crate inventory and policy audit, and run Clippy against explicit product and host-compatible scopes.
1 change: 1 addition & 0 deletions changelog.d/6760-merge-types-into-hir.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
**Compiler architecture:** move the shared compiler type definitions into `perry_hir::types`, remove the standalone types crate, and reduce the Perry dependency closure from 18 crates to 17 crates.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Expand the changeset with root cause, affected paths, and validation notes.

As per coding guidelines, changelog fragments must contain the long-form root cause, relevant file paths, and validation performed; this one-line summary is insufficient for release notes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@changelog.d/6760-merge-types-into-hir.md` at line 1, Expand the changelog
entry to document the root cause of consolidating compiler type definitions,
identify the affected crate or module paths including perry_hir::types and the
removed standalone types crate, and record the validation performed, including
the dependency reduction verification.

Source: Coding guidelines

2 changes: 0 additions & 2 deletions crates/perry-codegen-arkts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ workspace = true

[dependencies]
perry-hir.workspace = true
perry-types.workspace = true
anyhow.workspace = true

[dev-dependencies]
perry-types.workspace = true
10 changes: 5 additions & 5 deletions crates/perry-codegen-arkts/src/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::*;
/// same way as real top-level lets.
pub(crate) fn inlined_analysis_init(module: &Module) -> Vec<Stmt> {
use perry_hir::analysis::remap_local_ids_in_stmts;
use perry_types::FuncId;
use perry_hir::types::FuncId;
use std::collections::HashSet;

let mut function_map: HashMap<FuncId, perry_hir::ir::Function> = HashMap::new();
Expand Down Expand Up @@ -128,7 +128,7 @@ pub(crate) fn inlined_analysis_init(module: &Module) -> Vec<Stmt> {
/// covers Mango's makePill but punts on more complex returning fns.
pub(crate) fn expr_level_inline_pass(
stmts: Vec<Stmt>,
function_map: &HashMap<perry_types::FuncId, perry_hir::ir::Function>,
function_map: &HashMap<perry_hir::types::FuncId, perry_hir::ir::Function>,
bindings: &HashMap<LocalId, Expr>,
next_local: &mut u32,
budget: &mut usize,
Expand Down Expand Up @@ -156,7 +156,7 @@ pub(crate) fn expr_level_inline_pass(

pub(crate) fn inline_calls_in_stmt(
stmt: &mut Stmt,
function_map: &HashMap<perry_types::FuncId, perry_hir::ir::Function>,
function_map: &HashMap<perry_hir::types::FuncId, perry_hir::ir::Function>,
bindings: &HashMap<LocalId, Expr>,
next_local: &mut u32,
budget: &mut usize,
Expand Down Expand Up @@ -210,7 +210,7 @@ pub(crate) fn inline_calls_in_stmt(

pub(crate) fn inline_calls_in_expr(
expr: &mut Expr,
function_map: &HashMap<perry_types::FuncId, perry_hir::ir::Function>,
function_map: &HashMap<perry_hir::types::FuncId, perry_hir::ir::Function>,
bindings: &HashMap<LocalId, Expr>,
next_local: &mut u32,
budget: &mut usize,
Expand Down Expand Up @@ -327,7 +327,7 @@ pub(crate) fn inline_calls_in_expr(
name: String::new(),
type_params: Vec::new(),
params,
return_type: perry_types::Type::Any,
return_type: perry_hir::types::Type::Any,
body,
is_strict,
is_async: false,
Expand Down
4 changes: 2 additions & 2 deletions crates/perry-codegen-arkts/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ pub fn emit_index_ets(module: &mut Module) -> Result<Option<HarvestResult>> {
// expression substitutes the call. Without this, emit_widget
// hits `[unrecognized body]` for every helper-wrapped Text /
// Stack child.
let function_map_inline: HashMap<perry_types::FuncId, perry_hir::ir::Function> =
let function_map_inline: HashMap<perry_hir::types::FuncId, perry_hir::ir::Function> =
module.functions.iter().map(|f| (f.id, f.clone())).collect();
let function_lookup: HashMap<perry_types::FuncId, &perry_hir::ir::Function> =
let function_lookup: HashMap<perry_hir::types::FuncId, &perry_hir::ir::Function> =
module.functions.iter().map(|f| (f.id, f)).collect();
// Start view-builder Phase B remap counter ABOVE the highest
// LocalId already used by `analysis_init` (Phase A + B inlining
Expand Down
Loading
Loading