Skip to content

Conversation

@simone-stacks
Copy link
Contributor

@simone-stacks simone-stacks commented Nov 27, 2025

Description

Refactors the clarity-cli command-line interface to use clap for argument parsing, replacing the previous manual argument handling.

Applicable issues

Additional info (benefits, drawbacks, caveats)

Benefits:

  • Auto-generated --help output for all commands and subcommands
  • Better error messages for invalid arguments
  • Cleaner, more maintainable argument parsing code

Checklist

  • Test coverage for new or modified code paths
  • Changelog is updated
  • Required documentation changes (e.g., docs/rpc/openapi.yaml and rpc-endpoints.md for v2 endpoints, event-dispatcher.md for new events)
  • New clarity functions have corresponding PR in clarity-benchmarking repo

@codecov
Copy link

codecov bot commented Nov 27, 2025

Codecov Report

❌ Patch coverage is 2.91971% with 266 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.26%. Comparing base (c9003aa) to head (9b60242).

Files with missing lines Patch % Lines
contrib/clarity-cli/src/main.rs 2.91% 266 Missing ⚠️

❌ Your project check has failed because the head coverage (63.26%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

❗ There is a different number of reports uploaded between BASE (c9003aa) and HEAD (9b60242). Click for more details.

HEAD has 11 uploads less than BASE
Flag BASE (c9003aa) HEAD (9b60242)
73 62
Additional details and impacted files
@@             Coverage Diff              @@
##           develop    #6720       +/-   ##
============================================
- Coverage    77.90%   63.26%   -14.64%     
============================================
  Files          580      580               
  Lines       361187   361351      +164     
============================================
- Hits        281374   228626    -52748     
- Misses       79813   132725    +52912     
Files with missing lines Coverage Δ
contrib/clarity-cli/src/lib.rs 65.99% <ø> (-10.29%) ⬇️
contrib/stacks-inspect/src/main.rs 0.00% <ø> (ø)
contrib/clarity-cli/src/main.rs 3.26% <2.91%> (+3.26%) ⬆️

... and 367 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c9003aa...9b60242. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@simone-stacks
Copy link
Contributor Author

/// Execute program in a transient environment. To be used only by CLI tools
/// for program evaluation, not by consensus critical code.
pub fn vm_execute_in_epoch(
program: &str,
clarity_version: ClarityVersion,
epoch: StacksEpochId,
) -> Result<Option<Value>, VmExecutionError> {
let contract_id = QualifiedContractIdentifier::transient();
let mut contract_context = ContractContext::new(contract_id.clone(), clarity_version);
let mut marf = MemoryBackingStore::new();
let conn = marf.as_clarity_db();
let mut global_context = GlobalContext::new(
false,
default_chain_id(false),
conn,
LimitedCostTracker::new_free(),
epoch,
);
global_context.execute(|g| {
let parsed =
ast::build_ast(&contract_id, program, &mut (), clarity_version, epoch)?.expressions;
eval_all(&parsed, &mut contract_context, g, None)
})
}
/// Execute program in a transient environment in the latest epoch.
/// To be used only by CLI tools for program evaluation, not by consensus
/// critical code.
/// TODO: Unused internally in the cli, but used in other functions - Shall we use vm_execute_in_epoch with StacksEpochId::latest() instead, so we can remove this function?
pub fn vm_execute(
program: &str,
clarity_version: ClarityVersion,
) -> Result<Option<Value>, VmExecutionError> {
let contract_id = QualifiedContractIdentifier::transient();
let mut contract_context = ContractContext::new(contract_id.clone(), clarity_version);
let mut marf = MemoryBackingStore::new();
let conn = marf.as_clarity_db();
let mut global_context = GlobalContext::new(
false,
default_chain_id(false),
conn,
LimitedCostTracker::new_free(),
StacksEpochId::latest(),
);
global_context.execute(|g| {
let parsed = ast::build_ast(
&contract_id,
program,
&mut (),
clarity_version,
StacksEpochId::latest(),
)?
.expressions;
eval_all(&parsed, &mut contract_context, g, None)
})
}

I noticed that vm_execute and vm_execute_in_epoch are basically the same function - with the only difference that vm_execute just hardcodes StacksEpochId::latest().

I think we could either remove vm_execute and update all callers to pass the epoch explicitly, or turn it into a simple wrapper that calls vm_execute_in_epoch with StacksEpochId::latest() parameter.

What do you think? If it makese sense, I'd tackle this in a separate PR.

@simone-stacks simone-stacks marked this pull request as ready for review November 28, 2025 16:30
@simone-stacks simone-stacks requested a review from a team December 9, 2025 12:16
@brice-stacks brice-stacks self-requested a review December 12, 2025 19:33
@@ -471,6 +462,7 @@ pub fn vm_execute_in_epoch(
/// Execute program in a transient environment in the latest epoch.
/// To be used only by CLI tools for program evaluation, not by consensus
/// critical code.
/// TODO: Unused internally in the cli, but used in other functions - Shall we use vm_execute_in_epoch with StacksEpochId::latest() instead, so we can remove this function?
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, this sounds good to me.

Copy link
Contributor

@brice-stacks brice-stacks left a comment

Choose a reason for hiding this comment

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

This is a great improvement. Just a couple minor comments.

Comment on lines +952 to 968
if mainnet {
(
0,
Some(json!({
"message": "Database created.",
"network": "mainnet"
})),
)
} else {
ClarityVersion::default_for_epoch(epoch)
(
0,
Some(json!({
"message": "Database created.",
"network": "testnet"
})),
)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

How about flattening this to:

(
    0,
    Some(json!({
        "message": "Database created.",
        "network": if mainnet { "mainnet" } else { "testnet" }
    })),
)

None
};

// Run analysis and initialize contract in a new block?
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Run analysis and initialize contract in a new block?
// Run analysis and initialize contract in a new block

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.

2 participants