task: Add root flag for breaking check command#221
Conversation
There was a problem hiding this comment.
Pull request overview
Adds --root support to easyp breaking so proto import resolution can work when proto sources live under a directory that should not be part of the proto package/import path (matching the existing easyp lint --root/--path behavior).
Changes:
- Introduces
--rootflag for thebreakingcommand and wires it through CLI root resolution. - Extends breaking check core logic and git tree walking to apply a “root prefix” when opening imported proto files from a git ref.
- Updates the git walker interface and go-git adapter to accept both
rootandpath.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/api/breaking_check.go | Adds --root flag and passes resolved roots into core breaking check. |
| internal/core/breaking_check.go | Computes git-relative paths for comparing against a ref; passes root/path into git walker. |
| internal/core/dom.go | Extends CurrentProjectGitWalker interface to accept root. |
| internal/adapters/go_git/get_dir_walker.go | Plumbs root into NewGitTreeWalker. |
| internal/fs/go_git/dir_walker.go | Extends git tree walker to carry a root-aware adapter. |
| internal/fs/go_git/adapter.go | Implements root-aware import file opening for git tree reads. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| flagBreakingCheckRoot = &cli.StringFlag{ | ||
| Name: "root", | ||
| Usage: "set root directory for file search (default: current working directory)", | ||
| Required: false, | ||
| HasBeenSet: false, | ||
| Value: "", | ||
| Aliases: []string{"r"}, |
| rel, err := filepath.Rel(projectRoot, workingDir) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("filepath.Rel: %w", err) | ||
| } |
There was a problem hiding this comment.
@copilot --root флаг для команды breaking_check может быть глобальным, так же как и в других командах, то есть может быть абсолютным путем до директории
There was a problem hiding this comment.
The --root flag already accepts absolute paths via resolveRoots (same as lint/generate). The changes in commit 58dbf67 properly handle this:
- Added
filepath.IsLocal(rel)validation: absolute paths inside the project root work fine (e.g.--root=/project/protowith project root at/project→rel="proto"). Absolute paths outside the project root now return a clear error (root path "/other/path" is outside project root "/project") instead of silently producing invalid..git tree paths. - Git tree paths are now built with
path.Joinon forward-slash-converted inputs, ensuring correct cross-platform behavior. - The
CurrentProjectGitWalkermock has been updated to match the new 4-parameterGetDirWalkerinterface.
There was a problem hiding this comment.
@copilot разве это правильно? в командах generate/lint же таких ограничений нет.
There was a problem hiding this comment.
Commit 8148ffe removes the restriction. GetDirWalker now uses PlainOpenWithOptions(DetectDotGit: true) to find the git repo by searching upward from --root, then computes the git-tree path relative to the actual worktree root. This means --root can be any absolute or relative path inside the git repository — including directories outside the config file's directory — consistent with generate/lint behaviour.
| gitPath := filepath.Join(rel, path) | ||
| c.logger.Debug( | ||
| ctx, "Paths for breaking check", | ||
| slog.String("rel", rel), | ||
| slog.String("path", path), | ||
| slog.String("gitPath", gitPath), | ||
| ) | ||
|
|
||
| if err := c.Download(ctx); err != nil { | ||
| return nil, fmt.Errorf("c.Download: %w", err) | ||
| } | ||
|
|
||
| // read current state | ||
| fsWalker := fs.NewFSWalker(workingDir, path) | ||
| currentProtoFiles, err := c.readProtoFiles(ctx, fsWalker) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("c.readCurrentProtoFiles: %w", err) | ||
| } | ||
|
|
||
| // read from ref branch | ||
| againstFSWalker, err := c.currentProjectGitWalker.GetDirWalker( | ||
| workingDir, c.breakingCheckConfig.AgainstGitRef, path, | ||
| projectRoot, c.breakingCheckConfig.AgainstGitRef, rel, gitPath, | ||
| ) |
| // CurrentProjectGitWalker is provider for fs walking for current project | ||
| CurrentProjectGitWalker interface { | ||
| GetDirWalker(workingDir, gitRef, path string) (DirWalker, error) | ||
| GetDirWalker(workingDir, gitRef, root, path string) (DirWalker, error) | ||
| } |
| func (a *GitTreeDiskAdapter) Open(name string) (io.ReadCloser, error) { | ||
| gitFile, err := a.File(name) | ||
| if err == nil { | ||
| return gitFile.Reader() | ||
| } | ||
|
|
||
| // add root and try to open again | ||
| withRoot := path.Join(a.root, name) | ||
| gitFile, err = a.File(withRoot) |
| // add root and try to open again | ||
| withRoot := path.Join(a.root, name) | ||
| gitFile, err = a.File(withRoot) |
| type GitTreeWalker struct { | ||
| *GitTreeDiskAdapter | ||
|
|
||
| tree *object.Tree | ||
| root string | ||
| path string | ||
| } |
Agent-Logs-Url: https://github.com/easyp-tech/easyp/sessions/d72f719b-a9c6-4dcd-9ef5-dc3e3fd34fb3 Co-authored-by: Yakwilik <92339556+Yakwilik@users.noreply.github.com>
Agent-Logs-Url: https://github.com/easyp-tech/easyp/sessions/d72f719b-a9c6-4dcd-9ef5-dc3e3fd34fb3 Co-authored-by: Yakwilik <92339556+Yakwilik@users.noreply.github.com>
Agent-Logs-Url: https://github.com/easyp-tech/easyp/sessions/d72f719b-a9c6-4dcd-9ef5-dc3e3fd34fb3 Co-authored-by: Yakwilik <92339556+Yakwilik@users.noreply.github.com>
…amically Agent-Logs-Url: https://github.com/easyp-tech/easyp/sessions/23795cc4-821b-4d33-94e0-ffe6b20db0db Co-authored-by: Yakwilik <92339556+Yakwilik@users.noreply.github.com>
To resolve: #219