mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(agent/agentcontainers): respect ignore files (#19016)
Closes https://github.com/coder/coder/issues/19011 We now use [go-git](https://pkg.go.dev/github.com/go-git/go-git/v5@v5.16.2/plumbing/format/gitignore)'s `gitignore` plumbing implementation to parse the `.gitignore` files and match against the patterns generated. We use this to ignore any ignored files in the git repository. Unfortunately I've had to slightly re-implement some of the interface exposed by `go-git` because they use `billy.Filesystem` instead of `afero.Fs`.
This commit is contained in:
@@ -21,11 +21,13 @@ import (
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing/format/gitignore"
|
||||
"github.com/google/uuid"
|
||||
"github.com/spf13/afero"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"cdr.dev/slog"
|
||||
"github.com/coder/coder/v2/agent/agentcontainers/ignore"
|
||||
"github.com/coder/coder/v2/agent/agentcontainers/watcher"
|
||||
"github.com/coder/coder/v2/agent/agentexec"
|
||||
"github.com/coder/coder/v2/agent/usershell"
|
||||
@@ -469,13 +471,49 @@ func (api *API) discoverDevcontainerProjects() error {
|
||||
}
|
||||
|
||||
func (api *API) discoverDevcontainersInProject(projectPath string) error {
|
||||
logger := api.logger.
|
||||
Named("project-discovery").
|
||||
With(slog.F("project_path", projectPath))
|
||||
|
||||
globalPatterns, err := ignore.LoadGlobalPatterns(api.fs)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("read global git ignore patterns: %w", err)
|
||||
}
|
||||
|
||||
patterns, err := ignore.ReadPatterns(api.ctx, logger, api.fs, projectPath)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("read git ignore patterns: %w", err)
|
||||
}
|
||||
|
||||
matcher := gitignore.NewMatcher(append(globalPatterns, patterns...))
|
||||
|
||||
devcontainerConfigPaths := []string{
|
||||
"/.devcontainer/devcontainer.json",
|
||||
"/.devcontainer.json",
|
||||
}
|
||||
|
||||
return afero.Walk(api.fs, projectPath, func(path string, info fs.FileInfo, _ error) error {
|
||||
return afero.Walk(api.fs, projectPath, func(path string, info fs.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
logger.Error(api.ctx, "encountered error while walking for dev container projects",
|
||||
slog.F("path", path),
|
||||
slog.Error(err))
|
||||
return nil
|
||||
}
|
||||
|
||||
pathParts := ignore.FilePathToParts(path)
|
||||
|
||||
// We know that a directory entry cannot be a `devcontainer.json` file, so we
|
||||
// always skip processing directories. If the directory happens to be ignored
|
||||
// by git then we'll make sure to ignore all of the children of that directory.
|
||||
if info.IsDir() {
|
||||
if matcher.Match(pathParts, true) {
|
||||
return fs.SkipDir
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if matcher.Match(pathParts, false) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -486,11 +524,11 @@ func (api *API) discoverDevcontainersInProject(projectPath string) error {
|
||||
|
||||
workspaceFolder := strings.TrimSuffix(path, relativeConfigPath)
|
||||
|
||||
api.logger.Debug(api.ctx, "discovered dev container project", slog.F("workspace_folder", workspaceFolder))
|
||||
logger.Debug(api.ctx, "discovered dev container project", slog.F("workspace_folder", workspaceFolder))
|
||||
|
||||
api.mu.Lock()
|
||||
if _, found := api.knownDevcontainers[workspaceFolder]; !found {
|
||||
api.logger.Debug(api.ctx, "adding dev container project", slog.F("workspace_folder", workspaceFolder))
|
||||
logger.Debug(api.ctx, "adding dev container project", slog.F("workspace_folder", workspaceFolder))
|
||||
|
||||
dc := codersdk.WorkspaceAgentDevcontainer{
|
||||
ID: uuid.New(),
|
||||
|
||||
Reference in New Issue
Block a user