Skip to content

Commit

Permalink
watch: ignore ephemeral files & minor output tweaks
Browse files Browse the repository at this point in the history
Big change here is to import the ephemeral ignore set from Tilt.

The `.git` directory is also ignored for now: this restriction
should probably be lifted and made configurable in the future,
but it's not generally important to watch and triggers a LOT of
events (e.g. Git creates `index.lock` files that will appear and
disappear rapidly as terminals/IDEs/etc interact with Git, even
for read-only operations).

The Tilt-provided ephemeral file set has been slowly devised over
time based on temporary files that can cause trouble. We can also
look at a more robust/configurable solution here in the future,
but thse provide a reasonable out-of-the-box configuration for
the moment.

There's also some small tweaks to the output to add missing
newlines in a few edge cases and such.
  • Loading branch information
milas committed Feb 24, 2023
1 parent 6fae6a4 commit efdfbe7
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 19 deletions.
32 changes: 23 additions & 9 deletions pkg/compose/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ import (
"time"

"github.com/compose-spec/compose-go/types"
"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/utils"
"github.com/docker/compose/v2/pkg/watch"
"github.com/jonboulle/clockwork"
"github.com/mitchellh/mapstructure"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"

"github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/utils"
"github.com/docker/compose/v2/pkg/watch"
)

type DevelopmentConfig struct {
Expand Down Expand Up @@ -82,10 +83,23 @@ func (s *composeService) Watch(ctx context.Context, project *types.Project, serv
}
bc := service.Build.Context

ignore, err := watch.LoadDockerIgnore(bc)
dockerIgnores, err := watch.LoadDockerIgnore(bc)
if err != nil {
return err
}

// add a hardcoded set of ignores on top of what came from .dockerignore
// some of this should likely be configurable (e.g. there could be cases
// where you want `.git` to be synced) but this is suitable for now
dotGitIgnore, err := watch.NewDockerPatternMatcher("/", []string{".git/"})
if err != nil {
return err
}
ignore := watch.NewCompositeMatcher(
dockerIgnores,
watch.EphemeralPathMatcher,
dotGitIgnore,
)

watcher, err := watch.NewWatcher([]string{bc}, ignore)
if err != nil {
Expand All @@ -109,7 +123,7 @@ func (s *composeService) Watch(ctx context.Context, project *types.Project, serv
path := event.Path()

for _, trigger := range config.Watch {
logrus.Debugf("change deteced on %s - comparing with %s", path, trigger.Path)
logrus.Debugf("change detected on %s - comparing with %s", path, trigger.Path)
if watch.IsChild(trigger.Path, path) {
fmt.Fprintf(s.stderr(), "change detected on %s\n", path)

Expand All @@ -126,7 +140,7 @@ func (s *composeService) Watch(ctx context.Context, project *types.Project, serv
Destination: fmt.Sprintf("%s:%s", name, dest),
}
case WatchActionRebuild:
logrus.Debugf("modified file %s require image to be rebuilt", path)
logrus.Debugf("modified file %s requires image to be rebuilt", path)
needRebuild <- name
default:
return fmt.Errorf("watch action %q is not supported", trigger)
Expand Down Expand Up @@ -176,7 +190,7 @@ func (s *composeService) makeRebuildFn(ctx context.Context, project *types.Proje
Services: services,
})
if err != nil {
fmt.Fprintf(s.stderr(), "Build failed")
fmt.Fprintf(s.stderr(), "Build failed\n")
}
for i, service := range project.Services {
if id, ok := imageIds[service.Name]; ok {
Expand All @@ -196,7 +210,7 @@ func (s *composeService) makeRebuildFn(ctx context.Context, project *types.Proje
},
})
if err != nil {
fmt.Fprintf(s.stderr(), "Application failed to start after update")
fmt.Fprintf(s.stderr(), "Application failed to start after update\n")
}
}
}
Expand All @@ -212,7 +226,7 @@ func (s *composeService) makeSyncFn(ctx context.Context, project *types.Project,
if err != nil {
return err
}
fmt.Fprintf(s.stderr(), "%s updated\n", opt.Source)
fmt.Fprintf(s.stderr(), "%s updated\n", opt.Destination)
}
}
}
Expand Down
27 changes: 19 additions & 8 deletions pkg/watch/ephemeral.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
package ignore
/*
Copyright 2020 Docker Compose CLI authors
import (
"github.com/tilt-dev/tilt/internal/dockerignore"
"github.com/tilt-dev/tilt/pkg/model"
)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package watch

// EphemeralPathMatcher filters out spurious changes that we don't want to
// rebuild on, like IDE temp/lock files.
Expand All @@ -16,7 +27,7 @@ import (
// https://app.clubhouse.io/windmill/story/691/filter-out-ephemeral-file-changes
var EphemeralPathMatcher = initEphemeralPathMatcher()

func initEphemeralPathMatcher() model.PathMatcher {
func initEphemeralPathMatcher() PathMatcher {
golandPatterns := []string{"**/*___jb_old___", "**/*___jb_tmp___", "**/.idea/**"}
emacsPatterns := []string{"**/.#*", "**/#*#"}
// if .swp is taken (presumably because multiple vims are running in that dir),
Expand All @@ -34,14 +45,14 @@ func initEphemeralPathMatcher() model.PathMatcher {
// https://github.com/golang/go/blob/0b5218cf4e3e5c17344ea113af346e8e0836f6c4/src/cmd/go/internal/work/exec.go#L1764
goPatterns := []string{"**/*-go-tmp-umask"}

allPatterns := []string{}
var allPatterns []string
allPatterns = append(allPatterns, golandPatterns...)
allPatterns = append(allPatterns, emacsPatterns...)
allPatterns = append(allPatterns, vimPatterns...)
allPatterns = append(allPatterns, katePatterns...)
allPatterns = append(allPatterns, goPatterns...)

matcher, err := dockerignore.NewDockerPatternMatcher("/", allPatterns)
matcher, err := NewDockerPatternMatcher("/", allPatterns)
if err != nil {
panic(err)
}
Expand Down
36 changes: 36 additions & 0 deletions pkg/watch/notify.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,39 @@ func DesiredWindowsBufferSize() int {
func IsWindowsShortReadError(err error) bool {
return runtime.GOOS == "windows" && !errors.Is(err, fsnotify.ErrEventOverflow)
}

type CompositePathMatcher struct {
Matchers []PathMatcher
}

func NewCompositeMatcher(matchers ...PathMatcher) PathMatcher {
if len(matchers) == 0 {
return EmptyMatcher{}
}
return CompositePathMatcher{Matchers: matchers}
}

func (c CompositePathMatcher) Matches(f string) (bool, error) {
for _, t := range c.Matchers {
ret, err := t.Matches(f)
if err != nil {
return false, err
}
if ret {
return true, nil
}
}
return false, nil
}

func (c CompositePathMatcher) MatchesEntireDir(f string) (bool, error) {
for _, t := range c.Matchers {
matches, err := t.MatchesEntireDir(f)
if matches || err != nil {
return matches, err
}
}
return false, nil
}

var _ PathMatcher = CompositePathMatcher{}
3 changes: 1 addition & 2 deletions pkg/watch/watcher_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package watch

import (
"fmt"
"path/filepath"
"time"

Expand Down Expand Up @@ -53,7 +52,6 @@ func (d *fseventNotify) loop() {
}

for _, e := range events {
fmt.Println(e)
e.Path = filepath.Join("/", e.Path)

_, isPathWereWatching := d.pathsWereWatching[e.Path]
Expand All @@ -67,6 +65,7 @@ func (d *fseventNotify) loop() {
if err != nil {
logrus.Infof("Error matching path %q: %v", e.Path, err)
} else if ignore {
logrus.Tracef("Ignoring event for path: %v", e.Path)
continue
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/watch/watcher_naive.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ func (d *naiveNotify) watchRecursively(dir string) error {
}

if shouldSkipDir {
logrus.Debugf("Ignoring directory and its contents (recursively): %s", path)
return filepath.SkipDir
}

Expand Down Expand Up @@ -234,6 +235,7 @@ func (d *naiveNotify) shouldNotify(path string) bool {
if err != nil {
logrus.Infof("Error matching path %q: %v", path, err)
} else if ignore {
logrus.Tracef("Ignoring event for path: %v", path)
return false
}

Expand Down

0 comments on commit efdfbe7

Please sign in to comment.