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: improve artisan migrate:status command #780

Merged
merged 3 commits into from
Dec 21, 2024

Conversation

almas1992
Copy link
Contributor

@almas1992 almas1992 commented Dec 20, 2024

📑 Description

  • CliContext add TwoColumnDetail method.
  • Improve artisan migrate:status output.

Screenshots

image

Summary by CodeRabbit

  • New Features

    • Introduced a TwoColumnDetail method for improved console output formatting.
    • Enhanced migration status retrieval and display with better formatting and color coding.
  • Bug Fixes

    • Improved error handling in migration status methods for clearer feedback.
  • Tests

    • Added tests for the new TwoColumnDetail method.
    • Updated tests for migration status methods to ensure accurate output validation.
  • Chores

    • Updated mock implementations to reflect changes in method signatures and return types.

✅ Checks

  • Added test cases for my code

Copy link
Contributor

coderabbitai bot commented Dec 20, 2024

Walkthrough

This pull request introduces several enhancements across multiple files, focusing on improving migration status handling and console output formatting. The primary changes include adding a new TwoColumnDetail method to the CliContext struct for formatted console output, modifying the Status method in migration-related interfaces to return more detailed migration statuses, and updating corresponding mock and test files to support these changes. The modifications aim to provide more informative and structured migration status reporting while enhancing console output capabilities.

Changes

File Change Summary
console/cli_context.go Added TwoColumnDetail method to format and print two-column text with customizable spacing
console/cli_context_test.go Added TestTwoColumnDetail to validate the new TwoColumnDetail method's functionality
contracts/console/command.go Added TwoColumnDetail method to the Context interface
contracts/database/migration/migrator.go Introduced Status struct and modified Status() method to return slice of statuses
database/console/migration/migrate_status_command.go Updated Handle method to use new migration status retrieval and display logic
database/migration/default_migrator.go Replaced internal status struct with new contractsmigration.Status and updated method signatures
database/migration/sql_migrator.go Modified Status method to return slice of migration statuses
mocks/console/Context.go Added mock implementation for TwoColumnDetail method
mocks/database/migration/Migrator.go Updated mock Status method to return slice of migration statuses

Sequence Diagram

sequenceDiagram
    participant CLI as CLI Context
    participant Migrator as Database Migrator
    participant Command as Migration Status Command

    CLI->>Migrator: Request Migration Status
    Migrator-->>Command: Return Migration Statuses
    Command->>CLI: Use TwoColumnDetail to Display
    CLI->>CLI: Format and Print Statuses
Loading

Possibly related PRs

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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

codecov bot commented Dec 20, 2024

Codecov Report

Attention: Patch coverage is 71.15385% with 15 lines in your changes missing coverage. Please review.

Project coverage is 69.73%. Comparing base (be88582) to head (8d577a0).
Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
...tabase/console/migration/migrate_status_command.go 0.00% 14 Missing ⚠️
database/migration/sql_migrator.go 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #780      +/-   ##
==========================================
- Coverage   69.75%   69.73%   -0.02%     
==========================================
  Files         214      214              
  Lines       18337    18357      +20     
==========================================
+ Hits        12791    12802      +11     
- Misses       4843     4853      +10     
+ Partials      703      702       -1     

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

@hwbrzzl
Copy link
Contributor

hwbrzzl commented Dec 20, 2024

Notice: please post a comment when the PR is ready.

@almas1992
Copy link
Contributor Author

Review Ready

@almas1992 almas1992 force-pushed the optimize-migration-status-command branch 2 times, most recently from a18d8b9 to 69c65d1 Compare December 21, 2024 02:27
@almas1992 almas1992 force-pushed the optimize-migration-status-command branch from 69c65d1 to 7189f45 Compare December 21, 2024 03:58
Copy link
Contributor

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

🔭 Outside diff range comments (1)
database/migration/sql_migrator.go (1)

Line range hint 117-134: Consider enhancing error handling and return values

The Status() method could be improved in several ways:

  1. The method returns nil, nil in multiple scenarios which makes it harder for callers to distinguish between different cases
  2. The success message about migration version is printed inside this method, which mixes concerns

Consider this refactoring:

 func (r *SqlMigrator) Status() ([]migration.Status, error) {
 	version, dirty, err := r.migrator.Version()
 	if err != nil {
 		if errors.Is(err, migrate.ErrNilVersion) {
-			color.Warningln("No migrations found")
-			return nil, nil
+			return []migration.Status{}, nil
 		} else {
 			return nil, errors.MigrationGetStatusFailed.Args(err)
 		}
 	}
 	if dirty {
-		color.Warningln("Migration status: dirty")
+		return []migration.Status{}, errors.New("Migration status: dirty")
 	}
 
-	color.Successln(fmt.Sprintf("Migration version: %d", version))
-	return nil, nil
+	return []migration.Status{{
+		Version: version,
+		Dirty:   dirty,
+	}}, nil
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 125-125: database/migration/sql_migrator.go#L125
Added line #L125 was not covered by tests

🧹 Nitpick comments (8)
database/migration/default_migrator.go (2)

115-134: Refactor for improved separation of concerns
In the current implementation of Status(), the function logs warnings and informational messages (e.g., “Migration table not found” or “No migrations found”) and also returns data. Moving console output to the caller or a dedicated utility would keep this core logic more concise and testable.


159-160: Preallocate the slice to reduce allocations
Consider declaring the slice with an initial capacity to optimize memory usage, for example:
var migrationStatus = make([]contractsmigration.Status, 0, len(batches))

database/console/migration/migrate_status_command.go (1)

43-56: Comprehensive status output with color
The approach to print both columns using color-coded statuses is neat. However, the entire block is uncovered by tests, per the static analysis. You can add a test that invokes this command and verifies the output (possibly using a mocked console).

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 43-53: database/console/migration/migrate_status_command.go#L43-L53
Added lines #L43 - L53 were not covered by tests


[warning] 55-55: database/console/migration/migrate_status_command.go#L55
Added line #L55 was not covered by tests

database/migration/sql_migrator_test.go (2)

136-138: Consider using s.Empty() instead of s.Nil() for slices
When checking that status is empty, it’s more semantically clear to use the assertion for emptiness:

- s.Nil(status)
+ s.Empty(status)

This more precisely checks that the slice has zero length (rather than being nil).


145-147: Use s.Empty() for slice checks
For consistency and clarity, do the same change as above here:

- s.Nil(status)
+ s.Empty(status)
console/cli_context_test.go (1)

269-289: Consider adding more test cases

While the current test cases are good, consider adding these scenarios:

  1. Empty strings for both columns
  2. Very long strings that exceed terminal width
  3. Custom filler character using the optional rune parameter

Here's an example of additional test cases:

 tests := []struct {
     name   string
     first  string
     second string
+    filler rune
     output string
 }{
     // ... existing test cases ...
+    {
+        name:   "empty strings",
+        first:  "",
+        second: "",
+        output: color.Default().Sprintln("   " + color.Gray().Sprint(
+            strings.Repeat(".", pterm.GetTerminalWidth()-6),
+        ) + "   "),
+    },
+    {
+        name:   "custom filler",
+        first:  "Test",
+        second: "Result",
+        filler: '-',
+        output: color.Default().Sprintln("  Test " + color.Gray().Sprint(
+            strings.Repeat("-", pterm.GetTerminalWidth()-len("Test")-len("Result")-6),
+        ) + " Result  "),
+    },
 }
console/cli_context.go (1)

282-308: LGTM! The implementation handles terminal width and ANSI colors correctly.

The TwoColumnDetail method effectively formats two-column output with proper handling of:

  • Unicode character widths using runewidth
  • ANSI color codes
  • Terminal width constraints
  • Dynamic filling

Consider these minor improvements:

  1. Pre-allocate the strings.Builder capacity:
 func (r *CliContext) TwoColumnDetail(first, second string, filler ...rune) {
 	margin := func(s string, left, right int) string {
-		var builder strings.Builder
+		builder := strings.Builder{}
+		builder.Grow(len(s) + left + right)
 		if left > 0 {
 			builder.WriteString(strings.Repeat(" ", left))
 		}
  1. Extract the default filler character to a constant:
+const defaultFiller = '.'
+
 func (r *CliContext) TwoColumnDetail(first, second string, filler ...rune) {
     // ...
-    fillingText = color.Gray().Sprint(strings.Repeat(string(append(filler, '.')[0]), w))
+    fillingText = color.Gray().Sprint(strings.Repeat(string(append(filler, defaultFiller)[0]), w))
mocks/console/Context.go (1)

1229-1241: Consider adding error handling for type assertions

While the implementation is functionally correct, consider adding error handling for the type assertions to make the mock more robust.

 func (_c *Context_TwoColumnDetail_Call) Run(run func(first string, second string, filler ...rune)) *Context_TwoColumnDetail_Call {
 	_c.Call.Run(func(args mock.Arguments) {
 		variadicArgs := make([]rune, len(args)-2)
 		for i, a := range args[2:] {
 			if a != nil {
-				variadicArgs[i] = a.(rune)
+				if r, ok := a.(rune); ok {
+					variadicArgs[i] = r
+				} else {
+					panic(fmt.Sprintf("argument %d is not of type rune", i+2))
+				}
 			}
 		}
 		run(args[0].(string), args[1].(string), variadicArgs...)
 	})
 	return _c
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3e77574 and 7189f45.

📒 Files selected for processing (11)
  • console/cli_context.go (2 hunks)
  • console/cli_context_test.go (2 hunks)
  • contracts/console/command.go (1 hunks)
  • contracts/database/migration/migrator.go (2 hunks)
  • database/console/migration/migrate_status_command.go (2 hunks)
  • database/migration/default_migrator.go (3 hunks)
  • database/migration/default_migrator_test.go (8 hunks)
  • database/migration/sql_migrator.go (3 hunks)
  • database/migration/sql_migrator_test.go (1 hunks)
  • mocks/console/Context.go (1 hunks)
  • mocks/database/migration/Migrator.go (3 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
database/console/migration/migrate_status_command.go

[warning] 39-40: database/console/migration/migrate_status_command.go#L39-L40
Added lines #L39 - L40 were not covered by tests


[warning] 43-53: database/console/migration/migrate_status_command.go#L43-L53
Added lines #L43 - L53 were not covered by tests


[warning] 55-55: database/console/migration/migrate_status_command.go#L55
Added line #L55 was not covered by tests

database/migration/sql_migrator.go

[warning] 125-125: database/migration/sql_migrator.go#L125
Added line #L125 was not covered by tests

🔇 Additional comments (17)
database/migration/default_migrator.go (1)

172-180: Implementation is correct
Appended fields align well with the new contractsmigration.Status struct. No functional issues found.

contracts/database/migration/migrator.go (2)

8-12: Excellent approach to typed migration status
Defining the Status struct clarifies the data model and improves maintainability.


26-26: Signature change fosters clearer status reporting
Switching from returning error-only to returning ([]Status, error) offers richer migration info.

database/console/migration/migrate_status_command.go (1)

39-40: Add test coverage for lines 39-40
The static analysis flags these lines for missing coverage. Consider adding unit tests or integration tests to ensure the status retrieval and error handling logic is validated.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 39-40: database/console/migration/migrate_status_command.go#L39-L40
Added lines #L39 - L40 were not covered by tests

database/migration/sql_migrator.go (1)

125-125: ⚠️ Potential issue

Add test coverage for error handling

The error handling branch at line 125 is not covered by tests according to static analysis.

Please add test cases to cover the error handling scenario. I can help generate the test cases if needed.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 125-125: database/migration/sql_migrator.go#L125
Added line #L125 was not covered by tests

contracts/console/command.go (1)

73-74: LGTM! Clean interface addition

The new TwoColumnDetail method is well-defined with flexible parameters that allow for customized formatting.

console/cli_context_test.go (1)

292-294: LGTM! Clean test implementation

The test implementation is clean and uses appropriate test utilities for output capture and validation.

mocks/database/migration/Migrator.go (2)

252-278: LGTM! The mock implementation correctly handles the new Status return type.

The changes properly implement the updated Status method signature with appropriate type assertions and error handling.


298-299: LGTM! The mock helper methods are correctly updated.

The Return and RunAndReturn methods are properly updated to handle the new Status return type.

Also applies to: 303-304

database/migration/default_migrator_test.go (3)

91-93: LGTM! TestRun properly verifies the migration status.

The test correctly validates both the migration execution and its status.


142-144: LGTM! TestStatus comprehensively tests the status functionality.

The test covers both initial empty state and post-migration state with proper assertions.

Also applies to: 152-160


788-790: LGTM! The Status test cases cover all scenarios.

The test suite thoroughly covers:

  • Migration table not found
  • Error handling
  • No migrations
  • Successful status retrieval with proper batch information

Also applies to: 801-803, 815-817, 837-849

mocks/console/Context.go (5)

1203-1214: LGTM: TwoColumnDetail method implementation is correct

The implementation properly handles the variadic arguments and follows the established pattern in the mock file.


1215-1219: LGTM: Context_TwoColumnDetail_Call struct is properly defined

The struct definition correctly embeds mock.Call and follows the established pattern.


1220-1228: LGTM: TwoColumnDetail expecter method is well implemented

The method properly handles all parameters, includes appropriate documentation, and follows the established pattern.


1242-1250: LGTM: Return and RunAndReturn methods are properly implemented

Both methods follow the established pattern and are correctly implemented.


1203-1250: Verify interface compliance

Let's verify that the mock implementation matches the interface definition.

✅ Verification successful

Mock implementation matches the interface definition

The mock implementation in mocks/console/Context.go correctly matches the interface definition found in contracts/console/command.go. The method signature TwoColumnDetail(first, second string, filler ...rune) is identical in both the interface and the mock implementation, including the parameter types and variadic rune parameter.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the TwoColumnDetail method signature matches the interface definition

# Search for the interface definition
ast-grep --pattern 'interface {
  $$$
  TwoColumnDetail($$$)
  $$$
}'

Length of output: 4696

Copy link
Contributor

@hwbrzzl hwbrzzl left a comment

Choose a reason for hiding this comment

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

Pretty good 👍

@hwbrzzl hwbrzzl merged commit 498ef6a into goravel:master Dec 21, 2024
12 checks passed
@almas1992 almas1992 deleted the optimize-migration-status-command branch December 21, 2024 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants