Skip to content

Comments

fix: CLI error visibility and dryRun flag isolation (#026)#26

Merged
laggu merged 2 commits intodevelopfrom
gh-025
Feb 18, 2026
Merged

fix: CLI error visibility and dryRun flag isolation (#026)#26
laggu merged 2 commits intodevelopfrom
gh-025

Conversation

@laggu
Copy link
Owner

@laggu laggu commented Feb 18, 2026

변경 사항

1. CLI 에러 가시성 개선

  • cmd/root.go: SilenceErrors: true 제거 → Cobra 기본 에러 출력 활용
  • 잘못된 플래그 사용 시 에러 메시지가 사용자에게 표시됨

2. dryRun 플래그 격리

  • cmd/sync.go: dryRunsyncDryRun (sync 전용)
  • cmd/unsync.go: dryRununsyncDryRun (unsync 전용)
  • 명령 간 결합도 제거

3. 회귀 테스트 추가 (integration.sh)

  • Error Visibility: 잘못된 플래그 → 에러 메시지 출력 확인
  • Sync Dry Run: --dry-run 시 파일 미생성 확인
  • Unsync Dry Run: --dry-run 시 파일 미삭제 확인

Closes #26

@gemini-code-assist
Copy link

Summary of Changes

Hello @laggu, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces significant architectural and functional improvements to the git-volume CLI. It focuses on enhancing user experience through clearer error messages and better flag management, while also expanding core capabilities with new global file management commands. The changes ensure more robust and predictable behavior for volume synchronization and provide a solid foundation for future development, backed by comprehensive testing.

Highlights

  • CLI Error Visibility: Improved error visibility for CLI commands by removing SilenceErrors: true from the root command, allowing Cobra to display detailed error messages to the user, especially for incorrect flag usage.
  • Dry Run Flag Isolation: Isolated the dryRun flag to be command-specific by renaming it to syncDryRun for the sync command and unsyncDryRun for the unsync command, reducing coupling between commands.
  • New Global Commands: Introduced a new global command with subcommands add, list, edit, and remove to manage files in the global git-volume storage (~/.git-volume), enhancing the tool's capability for shared configurations.
  • Enhanced Sync/Unsync Logic: Refactored sync and unsync operations to use a delete-and-recreate strategy for idempotency and improved handling of existing targets. The force option for overwriting was removed as this new strategy inherently handles it.
  • Improved Safety and Status Reporting: Added security checks to reject symlink sources for global add and sync operations. The status command now accurately reports MODIFIED for copied directories or files whose content differs from the source.
  • Comprehensive Integration Tests: Added a new integration.sh script to provide robust end-to-end testing for CLI commands, covering error visibility, dry-run functionality, and various global command scenarios.
  • Documentation Updates: Updated README.md and CLAUDE.md with new installation methods (Homebrew, Scoop), command references (e.g., status replacing list), and safety features. New command specifications were added in docs/specs/spec.md, and translated READMEs were added/renamed.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • CLAUDE.md
    • Updated test commands and architecture overview.
  • README.md
    • Updated language links to new translation paths.
    • Added Homebrew and Scoop installation instructions.
    • Replaced git volume list with git volume status in examples and command table.
    • Removed force option from configuration file example.
    • Added new safety features related to symlink rejection and status reporting.
  • cmd/add.go
    • Renamed to cmd/global_add.go.
    • Moved add command under the new global subcommand.
    • Removed the force flag from the add command.
  • cmd/global.go
    • Added new global command to manage files in global storage.
    • Added global list subcommand to display global files.
  • cmd/global_edit.go
    • Added new command global edit to open files from global storage in an editor.
  • cmd/global_remove.go
    • Added new command global remove to delete files from global storage.
  • cmd/list.go
    • Removed the list command file, replaced by status and global list.
  • cmd/root.go
    • Removed os import.
    • Modified Execute function to return an error, improving CLI error handling.
  • cmd/status.go
    • Added new status command to display the status of all volumes.
  • cmd/sync.go
    • Renamed dryRun flag to syncDryRun for command-specific isolation.
    • Removed fmt import.
    • Refactored Sync logic for better structure and idempotency.
  • cmd/unsync.go
    • Renamed dryRun flag to unsyncDryRun for command-specific isolation.
    • Removed fmt import.
    • Refactored Unsync logic for better structure and safety checks.
  • docs/specs/spec.md
    • Added a new document detailing the specifications for all git-volume commands.
  • docs/translations/README_de.md
    • Added German translation of the README.
  • docs/translations/README_es.md
    • Added Spanish translation of the README.
  • docs/translations/README_fr.md
    • Added French translation of the README.
  • docs/translations/README_it.md
    • Added Italian translation of the README.
  • docs/translations/README_ja.md
    • Added Japanese translation of the README.
  • docs/translations/README_ko.md
    • Renamed from docs/ko/README.md and updated Korean translation of the README.
  • docs/translations/README_pt.md
    • Added Portuguese translation of the README.
  • docs/translations/README_zh.md
    • Added Chinese translation of the README.
  • go.mod
    • Added github.com/google/shlex and github.com/stretchr/testify dependencies.
  • go.sum
    • Updated Go module checksums for new dependencies.
  • internal/gitvolume/add.go
    • Refactored Add function to GlobalAdd.
    • Removed Force option from AddOptions.
    • Added security checks to reject symlink sources.
    • Improved error handling and output messages.
  • internal/gitvolume/add_test.go
    • Added new unit tests for GlobalAdd covering symlink source rejection, directory symlink rejection, non-existent sources, destination symlink detection, and path traversal security.
  • internal/gitvolume/context.go
    • Removed Force field from Volume struct.
    • Added StatusModified constant for volume status.
    • Updated CheckStatus to include directory hashing and report StatusModified for changed copied directories/files.
  • internal/gitvolume/context_test.go
    • Updated tests to reflect the removal of the Force field.
    • Migrated to github.com/stretchr/testify assertions for improved test readability and robustness.
  • internal/gitvolume/edit.go
    • Added GlobalEdit function to open files in the global directory using the user's default editor.
  • internal/gitvolume/edit_test.go
    • Added unit tests for GlobalEdit, including editing existing files, handling non-existent files, and blocking path traversal.
  • internal/gitvolume/fs.go
    • Simplified copyFile to a direct copy, removing atomic rename logic.
    • Enhanced copyDir to recursively copy directories while rejecting symlinks within the source for security.
    • Introduced hashDir and verifyDirHash functions for comparing directory contents.
  • internal/gitvolume/git.go
    • Improved error messages for git rev-parse commands to include stderr output.
  • internal/gitvolume/gitvolume.go
    • Updated documentation for the Load method to reflect the new Status command.
  • internal/gitvolume/gitvolume_test.go
    • Refactored test setup functions to use require.NoError for cleaner error handling.
    • Removed old Sync, Unsync, and List tests, which are now in dedicated test files.
  • internal/gitvolume/init.go
    • Refactored Init function into beforeInit, init, and afterInit steps for better modularity and clearer output messages.
  • internal/gitvolume/list.go
    • Refactored List function to GlobalList.
    • Implemented tree-style output for listing files in the global directory.
  • internal/gitvolume/list_test.go
    • Added new unit tests for buildGlobalTree and sortTree functions to verify tree structure and sorting logic.
  • internal/gitvolume/path_test.go
    • Migrated to github.com/stretchr/testify assertions.
    • Improved symlink test setup with require.NoError.
  • internal/gitvolume/remove.go
    • Added GlobalRemove function to remove files or directories from the global storage.
  • internal/gitvolume/status.go
    • Added Status function to display the status of all configured volumes, replacing the old List command.
  • internal/gitvolume/status_test.go
    • Added new unit tests for the Status command, including checks for StatusModified on copied directories.
  • internal/gitvolume/sync.go
    • Refactored Sync function into beforeAllSync, beforeSync, sync, afterSync, and afterAllSync steps.
    • Removed force parameter from syncCopy and syncLink as a delete-and-recreate strategy is now used.
    • Implemented a delete-and-recreate strategy for sync to ensure idempotency and handle various target states.
  • internal/gitvolume/sync_test.go
    • Added new unit tests for Sync covering link and copy modes, directory copying, existing target overwrites, mode transitions, dry-run, relative links, nested targets, and global sources.
  • internal/gitvolume/unsync.go
    • Refactored Unsync function into beforeAllUnsync, beforeUnsync, unsync, afterUnsync, and afterAllUnsync steps.
    • Updated checkRemovable to verify directory content hashes for copy mode.
  • internal/gitvolume/unsync_test.go
    • Added new unit tests for Unsync covering basic removal, safety checks for modified files/hijacked links, dry-run, global sources, empty parent directory cleanup, and directory unsync scenarios.
  • main.go
    • Modified main function to check and exit on errors returned by cmd.Execute().
  • test/integration.sh
    • Added a new comprehensive integration test script to validate CLI commands and their interactions.
Ignored Files
  • Ignored by pattern: .gemini/** (1)
    • .gemini/styleguide.md
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/ci.yaml
Activity
  • The author, laggu, has introduced significant refactoring across the codebase to improve modularity and error handling.
  • New global commands (add, list, edit, remove) have been implemented and integrated into the CLI structure.
  • Extensive unit and integration tests have been added or updated to cover the new features and ensure stability, including a new integration.sh script.
  • Documentation has been updated to reflect the new command structure and features, including new command specifications and translated READMEs.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@laggu laggu changed the base branch from main to develop February 18, 2026 10:56
- Remove SilenceErrors: true from root command so Cobra prints errors
- Isolate dryRun flag: syncDryRun for sync, unsyncDryRun for unsync
- Add regression tests for error visibility and dry-run isolation

Closes #26
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이번 pull request는 CLI 에러 가시성 개선과 dryRun 플래그 격리, 그리고 internal/gitvolume 패키지로의 로직 통합을 통해 코드 구조를 체계화한 점이 돋보입니다. 특히 테스트 코드를 대폭 추가하여 안정성을 높이려 노력한 점이 긍정적입니다. 다만, 파일 복사 로직에서 기존의 원자적(atomic) 교체 방식이 제거되어 작업 중단 시 데이터 손상 위험이 생긴 점과, 리포지토리 스타일 가이드의 에러 처리 규칙(Rule 16) 및 포맷팅 규칙(Rule 6) 위반 사항이 일부 발견되었습니다. 이러한 부분들을 보완하면 더욱 견고한 도구가 될 것입니다.

I am having trouble creating individual review comments. Click here to see my feedback.

internal/gitvolume/fs.go (25)

medium

리포지토리 스타일 가이드 16번에 따라 에러는 항상 명시적으로 확인해야 하며 _로 무시해서는 안 됩니다. 읽기 전용 파일의 Close() 에러라 하더라도 스타일 가이드 준수를 위해 에러를 확인하거나, 최소한 무시하는 이유에 대한 주석을 남기는 것이 좋습니다. 이 파일 내의 다른 Close() 호출(39, 44, 124행 등)에서도 동일한 문제가 발견됩니다.

References
  1. 에러는 항상 명시적으로 확인해야 합니다. _로 에러를 무시하지 마세요. (link)

internal/gitvolume/fs.go (14-49)

medium

기존의 원자적(atomic) 파일 복사 로직(임시 파일 생성 후 Rename)이 직접 쓰기 방식으로 변경되었습니다. 이 방식은 쓰기 도중 오류가 발생하거나 프로세스가 중단될 경우 대상 파일이 불완전하거나 손상된 상태로 남을 수 있습니다. 특히 Sync 작업 시 대상 파일을 먼저 삭제(os.RemoveAll)하므로, 복사 실패 시 기존 파일까지 잃게 됩니다. 안정성을 위해 기존의 원자적 교체 방식을 복구하는 것을 권장합니다.

internal/gitvolume/sync.go (107-109)

medium

Sync 작업 시 대상 경로를 무조건 삭제(os.RemoveAll)하는 전략은 구현이 간단하지만, 이후의 복사나 링크 작업이 실패할 경우 기존 파일까지 소실되는 위험이 있습니다. 특히 copy 모드에서 원자적 교체 방식을 사용하지 않게 된 점과 결합되어 안정성이 저하될 수 있습니다. 작업 성공 시에만 기존 파일을 대체하는 방식을 고려해 보세요.

internal/gitvolume/sync.go (166)

medium

해당 라인의 들여쓰기가 잘못되어 있습니다. 리포지토리 스타일 가이드 6번에 따라 모든 코드는 gofmt로 포맷팅되어야 합니다.

	// Ensure parent directory exists
References
  1. 모든 코드는 반드시 gofmt로 포맷팅되어야 합니다. (link)

internal/gitvolume/status.go (50-54)

medium

스타일 가이드 16번에 따라 에러를 _로 무시하지 않아야 합니다. 특히 w.Flush()는 버퍼의 내용을 실제로 출력 장치에 쓰는 중요한 작업이므로 에러 발생 여부를 확인하는 것이 권장됩니다.

References
  1. 에러는 항상 명시적으로 확인해야 합니다. _로 에러를 무시하지 마세요. (link)

@laggu
Copy link
Owner Author

laggu commented Feb 18, 2026

/gemini review

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이 Pull Request는 CLI 에러 가시성을 개선하고 dryRun 플래그를 각 명령에 맞게 격리하여 코드의 명확성과 견고성을 향상시켰습니다. SilenceErrors: true를 제거하여 Cobra의 기본 에러 출력을 활용하도록 변경한 점과 syncDryRun, unsyncDryRun과 같이 플래그 변수 이름을 명확하게 분리한 점은 매우 긍정적입니다. 또한, 이러한 변경 사항을 검증하기 위한 통합 테스트가 추가되어 회귀를 방지하고 코드의 신뢰성을 높였습니다. 전반적으로 잘 구현되었으며, 코드 품질과 사용자 경험을 개선하는 훌륭한 변경 사항입니다.

@laggu laggu merged commit 7c8ca76 into develop Feb 18, 2026
6 checks passed
@laggu laggu deleted the gh-025 branch February 18, 2026 12:20
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