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

fix: check dir is exists before create/clone on world cardinal create command #83

Merged
merged 1 commit into from
Oct 25, 2024

Conversation

zulkhair
Copy link
Collaborator

@zulkhair zulkhair commented Oct 25, 2024

Closes: WORLD-1044

Overview

if you world create with name == "foobar" and you already have a dir named "foobar", the error message you get isn't very helpful.

Brief Changelog

  • add checking for the exists dir before doing clone

Testing and Verifying

  • Manually tested using world cardinal create command
  • Adjusted unit test

Summary by CodeRabbit

  • Bug Fixes
    • Enhanced error handling in the Git clone operation to prevent overwriting existing directories by returning an error if the target directory already exists.
  • Tests
    • Updated test cases to utilize a new directory structure for command execution, ensuring consistent behavior in command tests.
    • Modified the TestBuild function to clone repositories into a specific subdirectory within the test environment.

Copy link

graphite-app bot commented Oct 25, 2024

Your org has enabled the Graphite merge queue for merging into main

Add the label “graphite/merge” to the PR and Graphite will automatically add it to the merge queue when it’s ready to merge.

You must have a Graphite account and log in to Graphite in order to use the merge queue. Sign up using this link.

Copy link

coderabbitai bot commented Oct 25, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

The changes introduced in this pull request enhance the GitCloneCmd function by adding a check to verify if the specified targetDir already exists before proceeding with the Git clone operation. If the directory exists, an error is returned, preventing the overwriting of existing directories. This modification improves error handling related to directory creation during the cloning process. Additionally, modifications were made to the test functions to reflect changes in directory usage without altering the fundamental logic of the tests.

Changes

File Change Summary
common/teacmd/git.go Added a check in GitCloneCmd to verify if targetDir exists before cloning; returns an error if it does.
cmd/world/root/root_test.go Updated TestCreateStartStopRestartPurge and TestDev to change command argument from gameDir to sgtDir and modified working directory accordingly; TestEVMStart remains unchanged.
common/docker/client_test.go Modified TestBuild to use sgtDir for cloning instead of the original temporary directory; updated RootDir in Config to point to sgtDir.

Assessment against linked issues

Objective Addressed Explanation
Unhelpful error message if you try to world create with a dir name that already exists (WORLD-1044)

🪧 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

Join @zulkhair and the rest of your teammates on Graphite Graphite

@zulkhair zulkhair changed the title check dir exist before create/clone fix: check dir is exists before create/clone on world cardinal create command Oct 25, 2024
@zulkhair zulkhair marked this pull request as ready for review October 25, 2024 07:27
@zulkhair zulkhair force-pushed the daim/check_dir_exist_before_create_clone branch from ac81682 to 657f786 Compare October 25, 2024 07:29
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: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 84f5fb5 and 657f786.

📒 Files selected for processing (1)
  • common/teacmd/git.go (1 hunks)
🔇 Additional comments (1)
common/teacmd/git.go (1)

50-55: Implementation aligns well with PR objectives and codebase patterns.

The changes successfully address the PR objectives by adding the directory existence check before the clone operation. The implementation:

  • Provides clear error messages as required
  • Uses consistent error handling with the eris package
  • Maintains the existing code style
  • Has no impact on the rest of the clone process

Let's verify the error handling consistency:

✅ Verification successful

Error handling is consistent throughout the codebase

The verification confirms that the error handling in the new code aligns perfectly with the established pattern across the codebase. All error handling consistently uses the eris package with appropriate error wrapping and formatting methods (eris.New, eris.Wrap, eris.Errorf). The new error message follows the same style as other error messages in the codebase, particularly in the same package (common/teacmd/git.go).

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Verify consistent use of error handling package
rg "eris\." --type go

Length of output: 7274

common/teacmd/git.go Show resolved Hide resolved
@zulkhair zulkhair force-pushed the daim/check_dir_exist_before_create_clone branch from 657f786 to a1f6ab6 Compare October 25, 2024 08:03
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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 657f786 and a1f6ab6.

📒 Files selected for processing (2)
  • cmd/world/root/root_test.go (1 hunks)
  • common/teacmd/git.go (1 hunks)
🔇 Additional comments (3)
common/teacmd/git.go (2)

50-54: Implementation meets core requirements.

The added directory existence check successfully addresses the PR objective of providing a helpful error message when the target directory already exists.


50-54: 🛠️ Refactor suggestion

Consider enhancing error handling robustness.

While the current implementation works, it could be more robust by:

  1. Distinguishing between files and directories
  2. Handling permission issues explicitly
  3. Addressing potential race conditions

Consider implementing this more comprehensive check:

-	if _, err := os.Stat(targetDir); err == nil {
-		return eris.Errorf("Game shard named '%s' already exists in this directory, "+
-			"please change the directory or use another name", targetDir)
-	}
+	fileInfo, err := os.Stat(targetDir)
+	if err != nil {
+		if !os.IsNotExist(err) {
+			return eris.Wrapf(err, "failed to check if '%s' exists (possible permission issue)", targetDir)
+		}
+	} else {
+		if fileInfo.IsDir() {
+			return eris.Errorf("game shard named '%s' already exists as a directory, "+
+				"please use another name", targetDir)
+		}
+		return eris.Errorf("cannot create game shard '%s': a file with this name already exists", 
+			targetDir)
+	}

This enhancement:

  • Provides specific error messages for files vs directories
  • Explicitly handles permission issues
  • Maintains clear user guidance in error messages

Likely invalid or redundant comment.

cmd/world/root/root_test.go (1)

119-120: Verify the necessity of the subdirectory structure.

The change to use a subdirectory sgt appears unrelated to the PR's objective of adding directory existence checks. Could you explain why this directory structure change is necessary?

cmd/world/root/root_test.go Outdated Show resolved Hide resolved
cmd/world/root/root_test.go Show resolved Hide resolved
@zulkhair zulkhair force-pushed the daim/check_dir_exist_before_create_clone branch from a1f6ab6 to 1032212 Compare October 25, 2024 11:58
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: 1

🧹 Outside diff range comments (1)
cmd/world/root/root_test.go (1)

Line range hint 120-184: Add test cases for directory existence.

While the changes modify the directory structure, they don't directly test the PR's main objective: improved error handling when a directory already exists.

Consider adding a new test function to verify the improved error handling:

func TestCreateWithExistingDirectory(t *testing.T) {
	// Create a temporary directory
	parentDir, err := os.MkdirTemp("", "world-cli-test")
	assert.NilError(t, err)
	defer os.RemoveAll(parentDir)

	// Create the target directory that will conflict
	targetDir := filepath.Join(parentDir, "sgt")
	err = os.Mkdir(targetDir, 0755)
	assert.NilError(t, err)

	// Attempt to create a world in the existing directory
	teaOut := &bytes.Buffer{}
	createCmd := getCreateCmd(teaOut)
	createCmd.SetArgs([]string{targetDir})

	// Verify that we get the expected error
	err = createCmd.Execute()
	assert.ErrorContains(t, err, "directory already exists")
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between a1f6ab6 and 1032212.

📒 Files selected for processing (2)
  • cmd/world/root/root_test.go (2 hunks)
  • common/teacmd/git.go (1 hunks)
🔇 Additional comments (4)
common/teacmd/git.go (2)

50-54: Implementation meets the basic requirement.

The check successfully prevents overwriting existing directories and provides a clear error message to users, which addresses the core issue WORLD-1044.


50-54: 🛠️ Refactor suggestion

Consider enhancing the directory check for better error handling.

While the current implementation works, we could make it more robust by distinguishing between different error cases. This would provide even clearer guidance to users.

Consider this enhanced implementation:

-	if _, err := os.Stat(targetDir); err == nil {
-		return eris.Errorf("Game shard named '%s' already exists in this directory, "+
-			"please change the directory or use another name", targetDir)
-	}
+	fileInfo, err := os.Stat(targetDir)
+	if err != nil {
+		if !os.IsNotExist(err) {
+			return eris.Wrapf(err, "failed to check if '%s' exists (possible permission issue)", targetDir)
+		}
+	} else {
+		if fileInfo.IsDir() {
+			return eris.Errorf("game shard named '%s' already exists as a directory, "+
+				"please use another name", targetDir)
+		}
+		return eris.Errorf("cannot create game shard '%s': a file with this name already exists", 
+			targetDir)
+	}

This enhancement:

  1. Distinguishes between files and directories
  2. Provides specific error messages for different scenarios
  3. Explicitly handles permission issues

Likely invalid or redundant comment.

cmd/world/root/root_test.go (2)

120-122: Verify test isolation with subdirectory creation.

The test now creates a subdirectory "sgt" under the temporary directory. While this change aligns with the PR's goal of improving directory handling, we should ensure proper cleanup and test isolation.

✅ Verification successful

Test isolation is properly maintained

The usage of "sgt" in both locations follows the same pattern - creating temporary test directories. In common/docker/client_test.go, it's used as a prefix for MkdirTemp, while in the reviewed code it's a subdirectory under another temporary directory. Both approaches maintain proper test isolation as they:

  • Use separate temporary directories
  • Follow cleanup patterns
  • Don't interfere with each other's execution
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if other tests might be affected by this directory structure change
rg -l "sgt" --type go

Length of output: 50


Script:

#!/bin/bash
# Let's check the content of the found file to understand the usage of "sgt"
rg "sgt" -C 3 common/docker/client_test.go

Length of output: 185


126-129: ⚠️ Potential issue

Consider potential test interference.

Changing the working directory without restoring it could affect subsequent tests. Consider adding a deferred cleanup to restore the original working directory.

Apply this diff to ensure proper cleanup:

 	// Change dir
 	err = os.Chdir(sgtDir)
 	assert.NilError(t, err)
+
+	// Store and restore original directory
+	origDir, err := os.Getwd()
+	assert.NilError(t, err)
+	defer func() {
+		err = os.Chdir(origDir)
+		assert.NilError(t, err)
+	}()

Likely invalid or redundant comment.

@zulkhair zulkhair force-pushed the daim/check_dir_exist_before_create_clone branch from 1032212 to e2d9513 Compare October 25, 2024 12:13
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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between 1032212 and e2d9513.

📒 Files selected for processing (2)
  • cmd/world/root/root_test.go (3 hunks)
  • common/teacmd/git.go (1 hunks)
🔇 Additional comments (3)
common/teacmd/git.go (2)

50-54: Implementation meets the basic requirements.

The directory existence check successfully prevents the unhelpful error message mentioned in WORLD-1044 by providing a clear error message when the target directory already exists.


50-54: 🛠️ Refactor suggestion

Consider enhancing the directory check implementation.

While the current implementation works, it could be more robust by:

  1. Distinguishing between files and directories
  2. Handling different error cases (e.g., permission issues)
  3. Providing more specific error messages

The previous review already provided a comprehensive implementation suggestion that addresses these points. Consider implementing those improvements to make the code more robust and maintainable.

cmd/world/root/root_test.go (1)

126-129: ⚠️ Potential issue

Restore working directory after test completion.

Changing the working directory without restoring it could affect subsequent tests. Consider adding a deferred function to restore the original working directory.

Apply this change:

 	// Change dir
+	originalDir, err := os.Getwd()
+	assert.NilError(t, err)
+	defer func() {
+		err = os.Chdir(originalDir)
+		assert.NilError(t, err)
+	}()
 	err = os.Chdir(sgtDir)
 	assert.NilError(t, err)

Likely invalid or redundant comment.

@zulkhair zulkhair force-pushed the daim/check_dir_exist_before_create_clone branch from e2d9513 to 9e8086f Compare October 25, 2024 12:33
Copy link

codecov bot commented Oct 25, 2024

Codecov Report

Attention: Patch coverage is 20.00000% with 4 lines in your changes missing coverage. Please review.

Project coverage is 46.84%. Comparing base (6abf03c) to head (64feb1f).
Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
common/teacmd/git.go 20.00% 3 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #83      +/-   ##
==========================================
- Coverage   46.87%   46.84%   -0.04%     
==========================================
  Files          56       56              
  Lines        3541     3546       +5     
==========================================
+ Hits         1660     1661       +1     
- Misses       1672     1675       +3     
- Partials      209      210       +1     

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

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: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE

📥 Commits

Files that changed from the base of the PR and between e2d9513 and 9e8086f.

📒 Files selected for processing (3)
  • cmd/world/root/root_test.go (3 hunks)
  • common/docker/client_test.go (1 hunks)
  • common/teacmd/git.go (1 hunks)
🔇 Additional comments (5)
common/teacmd/git.go (2)

50-54: Basic directory check meets requirements.

The implementation successfully addresses the PR objective by checking directory existence and providing a clear, actionable error message to users.


50-54: 🛠️ Refactor suggestion

Consider enhancing error handling robustness.

While the current implementation works, the previous review suggestion for more comprehensive error handling remains valid. Consider distinguishing between files and directories, and handling different error cases.

Here's an enhanced implementation:

-	if _, err := os.Stat(targetDir); err == nil {
-		return eris.Errorf("Game shard named '%s' already exists in this directory, "+
-			"please change the directory or use another name", targetDir)
-	}
+	fileInfo, err := os.Stat(targetDir)
+	if err != nil {
+		if !os.IsNotExist(err) {
+			return eris.Wrapf(err, "failed to check if '%s' exists", targetDir)
+		}
+	} else {
+		if fileInfo.IsDir() {
+			return eris.Errorf("game shard named '%s' already exists as a directory, "+
+				"please use another name", targetDir)
+		}
+		return eris.Errorf("cannot create game shard '%s': a file with this name already exists", 
+			targetDir)
+	}

Likely invalid or redundant comment.

common/docker/client_test.go (2)

187-195: LGTM! Changes align with PR objectives.

The modifications to use sgtDir for both the Git clone operation and configuration setup properly support the PR's goal of improving directory handling. The error handling is maintained, and the test structure remains clear.


187-187: Verify GitCloneCmd implementation.

Since this test relies on teacmd.GitCloneCmd, let's verify its implementation to ensure it includes the directory existence check mentioned in the PR objectives.

✅ Verification successful

GitCloneCmd implementation has proper directory existence check

The implementation in common/teacmd/git.go already includes the directory existence check before cloning:

  • Verifies if target directory exists using os.Stat()
  • Returns an error if directory already exists
  • Only proceeds with git clone if directory check passes
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for GitCloneCmd implementation to verify directory existence check
ast-grep --pattern 'func GitCloneCmd($_, $_, $_) {
  $$$
}'

Length of output: 61


Script:

#!/bin/bash
# Let's try a broader search for GitCloneCmd using ripgrep
rg "GitCloneCmd" -A 10

Length of output: 2263

cmd/world/root/root_test.go (1)

126-129: **** The previous review comment about potential cleanup implications and working directory restoration is still valid.

common/docker/client_test.go Show resolved Hide resolved
cmd/world/root/root_test.go Show resolved Hide resolved
cmd/world/root/root_test.go Show resolved Hide resolved
Copy link

graphite-app bot commented Oct 25, 2024

Merge activity

… command (#83)

Closes: WORLD-1044

## Overview

if you world create with name == "foobar" and you already have a dir named "foobar", the error message you get isn't very helpful.

## Brief Changelog

- add checking for the exists dir before doing clone

## Testing and Verifying

- Manually tested using `world cardinal create` command
- Adjusted unit test

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **Bug Fixes**
	- Enhanced error handling in the Git clone operation to prevent overwriting existing directories by returning an error if the target directory already exists.
- **Tests**
	- Updated test cases to utilize a new directory structure for command execution, ensuring consistent behavior in command tests.
	- Modified the `TestBuild` function to clone repositories into a specific subdirectory within the test environment.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@zulkhair zulkhair force-pushed the daim/check_dir_exist_before_create_clone branch from 9e8086f to 64feb1f Compare October 25, 2024 18:27
@graphite-app graphite-app bot merged commit 64feb1f into main Oct 25, 2024
6 of 7 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.

2 participants