Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(sozo): add sozo dev command #2664

Merged
merged 2 commits into from
Nov 8, 2024
Merged

Conversation

glihm
Copy link
Collaborator

@glihm glihm commented Nov 8, 2024

Add sozo dev command which now supports regenerating the bindings on the fly.

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new Dev command for enhanced development workflows, allowing automatic builds and migrations on file changes.
    • Expanded configuration options for development commands with new fields in DevArgs.
    • Added public visibility to the fields in MigrateArgs, improving accessibility.
  • Improvements

    • Enhanced responsiveness in the development command with refined error handling and a debounce mechanism for rebuilds.
    • Enabled cloning of BuildArgs and MigrateArgs for improved usability.
  • Bug Fixes

    • Adjusted argument handling in the Build command for better functionality.

Copy link

coderabbitai bot commented Nov 8, 2024

Walkthrough

Ohayo, sensei! This pull request introduces several changes to the sozo package, including the addition of a new dependency (notify version 7.0.0) in the Cargo.toml file and updates to several command structures. The BuildArgs and MigrateArgs structs are modified to include the Clone trait, while the DevArgs struct is expanded with new fields. Additionally, a new Dev command is introduced in the command module, enhancing the development workflow by allowing for file change monitoring and automatic rebuilding.

Changes

File Change Summary
bin/sozo/Cargo.toml - Added dependency: notify = "7.0.0"
- Updated sozo-walnut to be optional: optional = true
bin/sozo/src/commands/build.rs - Updated BuildArgs to derive Clone: #[derive(Debug, Clone, Args)]
bin/sozo/src/commands/dev.rs - Updated DevArgs to include new fields: transaction, typescript, typescript_v2, unity, bindings_output, features, packages
- Restructured run method to utilize new DevArgs fields
- Improved error handling with a separate thread for file events and a debounce mechanism
bin/sozo/src/commands/migrate.rs - Updated MigrateArgs to derive Clone and made fields transaction, world, starknet, account public
bin/sozo/src/commands/mod.rs - Added new module dev
- Introduced new command Dev(Box<DevArgs>)
- Updated Build command to use Box<BuildArgs>

Possibly related PRs

Suggested reviewers

  • kariy

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@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: 2

🧹 Outside diff range and nitpick comments (8)
bin/sozo/Cargo.toml (1)

32-32: Ohayo! Consider using workspace versioning for the notify dependency.

The notify dependency is pinned to a specific version while most other dependencies use workspace versioning. For consistency and easier maintenance, consider moving the version specification to the workspace manifest.

-notify = "7.0.0"
+notify.workspace = true
bin/sozo/src/commands/build.rs (2)

Line range hint 12-37: Consider enhancing documentation for better developer experience, sensei!

While the individual field documentation is good, it would be helpful to add a struct-level documentation comment explaining the overall purpose and typical usage patterns of BuildArgs, especially in the context of the new dev command.

Add this documentation above the struct:

+/// BuildArgs configures the contract build process and binding generation.
+/// It supports multiple binding types (TypeScript, Unity) and can be used both
+/// for one-time builds and continuous rebuilds in dev mode.
 #[derive(Debug, Clone, Args)]
 pub struct BuildArgs {

Line range hint 39-106: Consider enhancing error handling in the run method, sensei!

The run method could benefit from more specific error handling, especially around the tokio runtime creation and binding generation.

Consider wrapping the runtime operations with more specific error handling:

-        tokio::runtime::Runtime::new()
-            .unwrap()
-            .block_on(bindgen.generate(None))
-            .expect("Error generating bindings");
+        tokio::runtime::Runtime::new()
+            .map_err(|e| anyhow::anyhow!("Failed to create Tokio runtime: {}", e))?
+            .block_on(bindgen.generate(None))
+            .map_err(|e| anyhow::anyhow!("Failed to generate bindings: {}", e))?;
bin/sozo/src/commands/mod.rs (2)

42-44: Documentation could be more detailed, sensei! (。◕‿◕。)

While the command documentation is clear, consider adding more details about:

  • The watch behavior
  • File types that trigger rebuilds
  • Any performance implications

42-44: Architectural considerations for the dev command, sensei! 🎯

Since this command involves file watching and rebuilding, consider:

  1. Implementing graceful shutdown handling for the file watcher
  2. Adding configurable debounce/throttle for file change events
  3. Providing a way to exclude certain paths/patterns from triggering rebuilds
bin/sozo/src/commands/dev.rs (3)

32-56: Ohayo, sensei! Consider grouping related DevArgs fields for clarity.

The newly added fields in the DevArgs struct enhance functionality, but organizing them into logical groups (e.g., binding options, feature specifications) with documentation comments can improve readability and maintainability.


128-149: Consider optimizing the main loop to reduce CPU usage.

The use of thread::sleep(Duration::from_millis(300)) in the loop can lead to unnecessary CPU wake-ups. Using a blocking receive or increasing the sleep duration can improve efficiency.

Consider this modification:

- thread::sleep(Duration::from_millis(300));
+ // Use blocking receive with a timeout
+ if rebuild_rx.recv_timeout(Duration::from_millis(500)).is_ok() {
+     last_event_time = Some(Instant::now());
+ }

Line range hint 163-195: Ohayo, sensei! Simplify the process_event method logic.

Streamlining the event processing logic using functional programming patterns can enhance readability.

Refactored code:

- let paths = match event.kind {
-     EventKind::Modify(_) => event.paths,
-     EventKind::Remove(_) => event.paths,
-     EventKind::Create(_) => event.paths,
-     _ => vec![],
- };
+ let paths = event.paths;

 if paths.is_empty() {
     return false;
 }

- let mut is_rebuild_needed = false;
- for path in &paths {
+ let is_rebuild_needed = paths.iter().any(|path| {
     if let Some(filename) = path.file_name() {
         if filename == "Scarb.toml" {
             info!("Rebuild to include Scarb.toml changes.");
-            is_rebuild_needed = true;
+            true
         } else if let Some(extension) = path.extension() {
             if extension == "cairo" {
                 let file = path.to_string_lossy().to_string();
                 info!(file, "Rebuild from Cairo file change.");
-                is_rebuild_needed = true;
+                true
             } else {
-                false
             }
         } else {
-            false
+            false
         }
     } else {
-        false
+        false
     }
- }
+ });

 return is_rebuild_needed;
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c7900e9 and 2a0b965.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • bin/sozo/Cargo.toml (1 hunks)
  • bin/sozo/src/commands/build.rs (1 hunks)
  • bin/sozo/src/commands/dev.rs (2 hunks)
  • bin/sozo/src/commands/migrate.rs (1 hunks)
  • bin/sozo/src/commands/mod.rs (5 hunks)
🔇 Additional comments (8)
bin/sozo/Cargo.toml (1)

32-32: Verify the dependency changes impact, sensei!

The changes look good but let's verify:

  1. The new notify dependency aligns with the PR's objective for file monitoring
  2. Making sozo-walnut optional is a good practice for modularity

Let's check for any potential impact:

Also applies to: 39-39

✅ Verification successful

Ohayo! Dependencies are properly aligned, sensei! ✨

The verification shows:

  • notify is actively used in dev.rs for file watching functionality with PollWatcher
  • sozo-walnut is correctly configured as an optional dependency with proper feature flag setup:
    • Defined as optional = true in dependencies
    • Has a dedicated walnut feature that enables both sozo-walnut and sozo-ops/walnut
    • Included in default features for convenience
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the dependency usage and optional feature configuration

# Check if notify is used in the dev command implementation
rg -l "use.*notify" 

# Verify the optional dependency is properly gated with feature flags
rg -l "#\[cfg\(feature.*walnut\)\]"

Length of output: 88


Script:

#!/bin/bash
# Let's check the actual usage of notify in dev.rs and look for walnut-related code
rg "notify" bin/sozo/src/commands/dev.rs -B 2 -A 2

# Check for any walnut-related imports or uses
rg "walnut" bin/sozo/src/commands/dev.rs

# Let's also check the Cargo.toml for walnut feature configuration
cat bin/sozo/Cargo.toml

Length of output: 2359

bin/sozo/src/commands/migrate.rs (2)

22-34: Ohayo! The struct changes look good, sensei! 🎋

The addition of Clone derive and public field visibility aligns well with the needs of the new sozo dev command. These changes enable better reusability of the migration configuration across different commands.


Line range hint 38-93: Verify performance impact of cloning, sensei! 🎯

While the implementation remains solid, let's ensure that cloning MigrateArgs won't impact performance in the dev command's hot path. The struct contains nested options that might be expensive to clone repeatedly.

Let's check the size of the involved types:

✅ Verification successful

No performance concerns with MigrateArgs cloning, sensei! 🚀

After analyzing the struct composition, the cloning overhead is minimal since MigrateArgs only contains:

  • TransactionOptions: Simple enum (FeeToken) and numeric fields
  • WorldOptions: Single Option
  • StarknetOptions: Single Option
  • AccountOptions: Simple Option fields

All nested types are lightweight and implement efficient Clone. The struct is used only once during migration, not in any hot paths.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check the size and composition of involved types
ast-grep --pattern 'struct TransactionOptions {
  $$$
}'

ast-grep --pattern 'struct WorldOptions {
  $$$
}'

ast-grep --pattern 'struct StarknetOptions {
  $$$
}'

ast-grep --pattern 'struct AccountOptions {
  $$$
}'

Length of output: 222


Script:

#!/bin/bash
# Let's search for these structs in the entire codebase with more context
rg "struct.*Options" -A 10

# Also search for MigrateArgs to understand its composition
rg "struct MigrateArgs" -A 10

Length of output: 11976

bin/sozo/src/commands/build.rs (1)

12-12: Ohayo! The Clone derive addition looks good, sensei!

The addition of Clone trait is well-justified as it enables the new sozo dev command to reuse BuildArgs for dynamic binding regeneration.

bin/sozo/src/commands/mod.rs (3)

14-14: Ohayo! Module organization looks clean, sensei! ٩(◕‿◕。)۶

The new dev module and its corresponding imports are well-organized and follow the established pattern.

Also applies to: 28-28


74-74: Command execution implementation is solid! (ノ◕ヮ◕)ノ:・゚✧*

The Dev command integration into both Display and execution handling follows the established patterns perfectly.

Also applies to: 99-99


42-42: Verify the impact of Boxing BuildArgs ⚠️

The change from BuildArgs to Box<BuildArgs> might affect existing code that uses the Build command.

Let's check for potential impacts:

bin/sozo/src/commands/dev.rs (1)

61-67: ⚠️ Potential issue

Add error handling for the file watcher setup.

Currently, the code uses unwrap() when calling watcher.watch, which can cause a panic if an error occurs. It's advisable to handle this error gracefully to prevent unexpected crashes.

Apply this diff to handle potential errors:

- watcher.watch(watched_directory.as_std_path(), RecursiveMode::Recursive).unwrap();
+ watcher
+     .watch(watched_directory.as_std_path(), RecursiveMode::Recursive)
+     .unwrap_or_else(|e| {
+         error!(?e, "Failed to watch directory.");
+         std::process::exit(1);
+     });

Likely invalid or redundant comment.

Comment on lines +85 to +92
let migrate_args = MigrateArgs {
world: self.world,
starknet: self.starknet,
account: self.account,
transaction: self.transaction,
};

let _ = migrate_args.clone().run(config);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ohayo, sensei! Ensure errors in build and migrate steps are handled.

The run methods for build_args and migrate_args discard errors using let _ =. Handling these errors will provide feedback if these processes fail, improving robustness.

Apply this diff to properly handle errors:

- let _ = build_args.clone().run(config);
- let _ = migrate_args.clone().run(config);
+ if let Err(e) = build_args.clone().run(config) {
+     error!(?e, "Build failed.");
+ }
+ if let Err(e) = migrate_args.clone().run(config) {
+     error!(?e, "Migration failed.");
+ }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +99 to +126
let e_handler = EventHandler;
let rebuild_tx_clone = rebuild_tx.clone();

// Independent thread to handle file events and trigger rebuilds.
config.tokio_handle().spawn(async move {
loop {
match file_rx.recv() {
Ok(maybe_event) => match maybe_event {
Ok(event) => {
trace!(?event, "Event received.");

if e_handler.process_event(event) && rebuild_tx_clone.send(()).is_err()
{
break;
}
}
Err(error) => {
error!(?error, "Processing event.");
break;
}
},
Err(error) => {
error!(?error, "Processing event.");
error!(?error, "Receiving event.");
break;
}
},
Err(error) => {
error!(?error, "Receiving event.");
break;
}
};

if is_rebuild_needed {
// Ignore the fails of those commands as the `run` function
// already logs the error.
let _ = BuildArgs::default().run(config);

let _ = MigrateArgs::new_apply(
self.world.clone(),
self.starknet.clone(),
self.account.clone(),
)
.run(config);
}
});
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Thread and channel cleanup needed in dev command

Ohayo sensei! After analyzing the code, there are indeed concerns about thread and channel management:

  • The tokio task spawned for event handling has no explicit cleanup mechanism
  • The PollWatcher instance is not explicitly dropped or cleaned up
  • The channels (file_tx/rx and rebuild_tx/rx) are not properly closed

To fix this, consider:

  • Implementing a proper shutdown mechanism using a shutdown channel or flag
  • Adding proper cleanup in a Drop implementation or explicit cleanup method
  • Using tokio::select! to handle graceful shutdown of the spawned task
🔗 Analysis chain

Verify proper closure of threads and channels.

The spawned thread may outlive the run function scope, potentially causing issues during shutdown. Ensure threads and channels are properly managed to avoid panics or resource leaks.

Run the following script to check for proper thread and channel management:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that all threads are joined and channels are closed appropriately.

# Expected: No threads left running unexpectedly; channels are properly closed.

# Check for thread joins
rg 'spawn' -A 5 | rg -q 'join\(\)' && echo "All threads are joined." || echo "Threads may not be properly joined."

# Check for channel closure
rg 'channel' -A 5 | rg -q 'drop\(' && echo "Channels are properly closed." || echo "Channels may not be properly closed."

Length of output: 233


Script:

#!/bin/bash
# Let's check the full context of the thread spawning and channel usage in dev.rs
rg -l "spawn|channel" bin/sozo/src/commands/dev.rs

# If found, let's see the full implementation
cat bin/sozo/src/commands/dev.rs

# Let's also check for any cleanup or drop implementations
ast-grep --pattern 'impl Drop for $_ { $$ }'

# Check for any shutdown or cleanup related functions
rg -A 5 "shutdown|cleanup|drop|close" bin/sozo/src/commands/dev.rs

Length of output: 6439

Copy link

codecov bot commented Nov 8, 2024

Codecov Report

Attention: Patch coverage is 0% with 67 lines in your changes missing coverage. Please review.

Project coverage is 57.36%. Comparing base (c7900e9) to head (2a0b965).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
bin/sozo/src/commands/dev.rs 0.00% 65 Missing ⚠️
bin/sozo/src/commands/mod.rs 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2664      +/-   ##
==========================================
- Coverage   57.48%   57.36%   -0.13%     
==========================================
  Files         400      401       +1     
  Lines       50277    50387     +110     
==========================================
+ Hits        28904    28906       +2     
- Misses      21373    21481     +108     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@glihm glihm merged commit 61febd5 into dojoengine:main Nov 8, 2024
12 of 14 checks passed
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