Skip to content

Improve compiler output, display constraints#101

Open
andrew-fleming wants to merge 5 commits into
OpenZeppelin:mainfrom
andrew-fleming:improve-compiler-output
Open

Improve compiler output, display constraints#101
andrew-fleming wants to merge 5 commits into
OpenZeppelin:mainfrom
andrew-fleming:improve-compiler-output

Conversation

@andrew-fleming
Copy link
Copy Markdown
Contributor

@andrew-fleming andrew-fleming commented May 27, 2026

compactc writes circuit constraint info (k, rows) directly to the TTY via spinner animations, making it invisible when captured programmatically. This PR proposes to use the script command to silently capture the full PTY output during compilation, parse the circuit constraints, and:

  • print a clean per-file summary after each successful compilation (works when compiling in parallel)
  • write .circuit-info.json files per source dir with the parsed constraint data

The idea is to eventually have a script/package that reads .circuit-info.json and updates @circuitInfo annotations in module docs

Tested use in contracts lib with https://www.npmjs.com/package/@buenos_andres/compact-cli

% yarn turbo compact:access

   • Packages in scope: @openzeppelin/compact-contracts
   • Running compact:access in 1 packages
   • Remote caching disabled

@openzeppelin/compact-contracts:compact:security: cache miss, executing a6783c166c9538b7
@openzeppelin/compact-contracts:compact:utils: cache miss, executing dcb682b90014e7ea
@openzeppelin/compact-contracts:compact:security: 
@openzeppelin/compact-contracts:compact:utils: 
ℹ [COMPILE] Compact compiler startedact:security: 
ℹ [COMPILE] Compact compiler startedact:utils: 
ℹ [COMPILE] TARGET_DIR: utilsts:compact:utils: 
ℹ [COMPILE] Compact developer tools: compact 0.2.0
ℹ [COMPILE] Compact toolchain: 0.29.0ct:utils: 
ℹ [COMPILE] Found 2 .compact file(s) to compile in utils/
ℹ [COMPILE] TARGET_DIR: securitycompact:security: 
ℹ [COMPILE] Compact developer tools: compact 0.2.0
ℹ [COMPILE] Compact toolchain: 0.29.0ct:security: 
ℹ [COMPILE] Found 4 .compact file(s) to compile in security/
✔ [COMPILE] [1/2] Compiled utils/Utils.compact
✔ [COMPILE] [1/4] Compiled security/Initializable.compact
✔ [COMPILE] [2/2] Compiled utils/test/mocks/MockUtils.compact
@openzeppelin/compact-contracts:compact:utils: 
✔ [COMPILE] [2/4] Compiled security/Pausable.compact
✔ [COMPILE] [3/4] Compiled security/test/mocks/MockInitializable.compact
@openzeppelin/compact-contracts:compact:security:       "assertInitialized" (k=6, rows=26)
@openzeppelin/compact-contracts:compact:security:       "assertNotInitialized" (k=6, rows=29)
@openzeppelin/compact-contracts:compact:security:       "initialize" (k=6, rows=29)
✔ [COMPILE] [4/4] Compiled security/test/mocks/MockPausable.compact
@openzeppelin/compact-contracts:compact:security:       "assertNotPaused" (k=6, rows=29)
@openzeppelin/compact-contracts:compact:security:       "assertPaused" (k=6, rows=26)
@openzeppelin/compact-contracts:compact:security:       "isPaused" (k=6, rows=26)
@openzeppelin/compact-contracts:compact:security:       "pause" (k=6, rows=29)
@openzeppelin/compact-contracts:compact:security:       "unpause" (k=6, rows=26)
@openzeppelin/compact-contracts:compact:security: 
@openzeppelin/compact-contracts:compact:access: cache miss, executing 40179a00554a7747
@openzeppelin/compact-contracts:compact:access: 
ℹ [COMPILE] Compact compiler startedact:access: 
ℹ [COMPILE] TARGET_DIR: accesss:compact:access: 
ℹ [COMPILE] Compact developer tools: compact 0.2.0
ℹ [COMPILE] Compact toolchain: 0.29.0ct:access: 
ℹ [COMPILE] Found 8 .compact file(s) to compile in access/
✔ [COMPILE] [1/8] Compiled access/AccessControl.compact
✔ [COMPILE] [2/8] Compiled access/Ownable.compact
✔ [COMPILE] [3/8] Compiled access/ShieldedAccessControl.compact
✔ [COMPILE] [4/8] Compiled access/ZOwnablePK.compact
✔ [COMPILE] [5/8] Compiled access/test/mocks/MockAccessControl.compact
@openzeppelin/compact-contracts:compact:access:       "_checkRole" (k=10, rows=999)
@openzeppelin/compact-contracts:compact:access:       "_grantRole" (k=11, rows=1143)
@openzeppelin/compact-contracts:compact:access:       "_revokeRole" (k=11, rows=1073)
@openzeppelin/compact-contracts:compact:access:       "_setRoleAdmin" (k=10, rows=581)
@openzeppelin/compact-contracts:compact:access:       "_unsafeGrantRole" (k=11, rows=1142)
@openzeppelin/compact-contracts:compact:access:       "assertOnlyRole" (k=13, rows=2669)
@openzeppelin/compact-contracts:compact:access:       "getRoleAdmin" (k=9, rows=373)
@openzeppelin/compact-contracts:compact:access:       "grantRole" (k=13, rows=3536)
@openzeppelin/compact-contracts:compact:access:       "hasRole" (k=11, rows=1019)
@openzeppelin/compact-contracts:compact:access:       "renounceRole" (k=13, rows=3322)
@openzeppelin/compact-contracts:compact:access:       "revokeRole" (k=13, rows=3466)
✔ [COMPILE] [6/8] Compiled access/test/mocks/MockOwnable.compact
@openzeppelin/compact-contracts:compact:access:       "_transferOwnership" (k=10, rows=600)
@openzeppelin/compact-contracts:compact:access:       "_unsafeTransferOwnership" (k=13, rows=2956)
@openzeppelin/compact-contracts:compact:access:       "_unsafeUncheckedTransferOwnership" (k=10, rows=597)
@openzeppelin/compact-contracts:compact:access:       "assertOnlyOwner" (k=13, rows=2360)
@openzeppelin/compact-contracts:compact:access:       "owner" (k=7, rows=76)
@openzeppelin/compact-contracts:compact:access:       "renounceOwnership" (k=13, rows=2364)
@openzeppelin/compact-contracts:compact:access:       "transferOwnership" (k=13, rows=2959)
✔ [COMPILE] [7/8] Compiled access/test/mocks/MockShieldedAccessControl.compact
@openzeppelin/compact-contracts:compact:access:       "_grantRole" (k=14, rows=12288)
@openzeppelin/compact-contracts:compact:access:       "_revokeRole" (k=14, rows=10292)
@openzeppelin/compact-contracts:compact:access:       "_setRoleAdmin" (k=10, rows=583)
@openzeppelin/compact-contracts:compact:access:       "assertOnlyRole" (k=15, rows=17082)
@openzeppelin/compact-contracts:compact:access:       "canProveRole" (k=15, rows=17082)
@openzeppelin/compact-contracts:compact:access:       "computeRoleCommitment" (k=13, rows=6421)
@openzeppelin/compact-contracts:compact:access:       "getRoleAdmin" (k=9, rows=373)
@openzeppelin/compact-contracts:compact:access:       "grantRole" (k=15, rows=29113)
@openzeppelin/compact-contracts:compact:access:       "renounceRole" (k=14, rows=14479)
@openzeppelin/compact-contracts:compact:access:       "revokeRole" (k=15, rows=27117)
✔ [COMPILE] [8/8] Compiled access/test/mocks/MockZOwnablePK.compact
@openzeppelin/compact-contracts:compact:access:       "_computeOwnerCommitment" (k=13, rows=6571)
@openzeppelin/compact-contracts:compact:access:       "_transferOwnership" (k=13, rows=6487)
@openzeppelin/compact-contracts:compact:access:       "assertOnlyOwner" (k=14, rows=10620)
@openzeppelin/compact-contracts:compact:access:       "owner" (k=6, rows=50)
@openzeppelin/compact-contracts:compact:access:       "renounceOwnership" (k=14, rows=10622)
@openzeppelin/compact-contracts:compact:access:       "transferOwnership" (k=15, rows=17096)
@openzeppelin/compact-contracts:compact:access: 

 Tasks:    3 successful, 3 total
Cached:    0 cached, 3 total
  Time:    1m3.817s 

Summary by CodeRabbit

  • New Features

    • Circuit constraint metadata is now automatically persisted to .circuit-info.json files, enabling tracking of compiled artifacts with their constraint details.
  • Improvements

    • Compiler output display has been enhanced to remove ANSI escape sequences, control characters, and terminal artifacts, resulting in cleaner and more readable output.

Review Change Stack

@andrew-fleming andrew-fleming requested review from a team as code owners May 27, 2026 13:38
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2fbe9587-b56f-474b-9602-6c644a549980

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

This PR enhances the builder's compiler integration to capture and clean full PTY output, extracting and persisting circuit constraint metadata. It introduces output normalization utilities, updates CompilerService to use system script for PTY capture, and integrates cleaned output into user-facing compilation reports.

Changes

Compiler output cleaning and PTY capture

Layer / File(s) Summary
Output cleaning and constraint extraction utilities
packages/builder/src/utils.ts
New functions cleanCompileOutput, cleanForDisplay, parseCircuitConstraints, and writeCircuitInfoJson strip ANSI/control sequences, deduplicate compiler output, extract circuit constraints, and persist them to .circuit-info.json with timestamp management.
PTY-based process execution in CompilerService
packages/builder/src/services/CompilerService.ts
Adds spawnWithPty to run the compiler under the system script command with full PTY output captured to a temp file. Updates CompilerService constructor to make execFn optional, routing production builds through PTY capture while preserving test injectability.
Compiler output display integration
packages/builder/src/Compiler.ts
Updates Compiler to use cleanForDisplay for both success and error paths, replacing prior line-splitting with deduplicated, sanitized stdout/stderr output.
Comprehensive utility function tests
packages/builder/test/utils.test.ts
Adds Vitest coverage for output cleaning with real-world PTY scenarios, circuit constraint deduplication, metadata parsing, and .circuit-info.json file creation and merging.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 The PTY speaks in colors and spins,
We scrub its ANSI, let cleaning begin—
Circuits emerge from the spinner's refrain,
All deduplicated, persisted with care's gain. 🔧✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Improve compiler output, display constraints' accurately summarizes the main changes: enhanced compiler output handling and circuit constraint information display.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with 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.

Inline comments:
In `@packages/builder/src/Compiler.ts`:
- Around line 321-322: The error path currently prints stderr twice—once cleaned
and once raw—so remove the duplicate raw print by deleting the
UIService.printOutput(execError.stderr, chalk.red) call and keep only
UIService.printOutput(cleanForDisplay(execError.stderr), chalk.red); verify this
change in the error handling block where execError.stderr is used (look for the
calls to UIService.printOutput and cleanForDisplay in Compiler.ts) so only the
cleaned stderr is output.
- Around line 304-305: The code prints duplicate stderr output:
UIService.printOutput(cleanForDisplay(result.stderr), chalk.yellow) and
immediately UIService.printOutput(result.stderr, chalk.yellow); remove the
raw-print call so only the cleaned stderr is printed (delete or comment out the
UIService.printOutput(result.stderr, chalk.yellow) line) or, if raw output is
desired in some cases, wrap the raw call behind an explicit flag and reference
the same result.stderr/cleanForDisplay logic in the Compiler code path where
these lines live.

In `@packages/builder/src/services/CompilerService.ts`:
- Around line 51-104: spawnWithPty leaks the devNull file descriptor because
openSync('/dev/null', 'w') result (devNull) is never closed; ensure you close it
after the child process finishes or errors. Modify spawnWithPty to call
closeSync(devNull) in both the proc.on('error') handler and the proc.on('close')
handler (after unlinkSync(tmpFile) and before resolve/reject) so the fd is
always closed, and keep the existing unlinkSync(tmpFile)/readFileSync logic
intact; reference the devNull variable, proc.on('error'), and proc.on('close')
when applying the changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 48ee58de-bd19-4ef0-9184-511019c065af

📥 Commits

Reviewing files that changed from the base of the PR and between dea0884 and afbc898.

📒 Files selected for processing (4)
  • packages/builder/src/Compiler.ts
  • packages/builder/src/services/CompilerService.ts
  • packages/builder/src/utils.ts
  • packages/builder/test/utils.test.ts

Comment thread packages/builder/src/Compiler.ts Outdated
Comment thread packages/builder/src/Compiler.ts Outdated
Comment thread packages/builder/src/services/CompilerService.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant