air-verse / air

☁️ Live reload for Go apps
GNU General Public License v3.0
16.38k stars 772 forks source link

Files in `root_dir` not watched properly when using `include_dir` #496

Open tprestegard opened 8 months ago

tprestegard commented 8 months ago

air version: 1.49.0

I would like to be able to watch all files with specific extensions in a set of directories as well as some files in root_dir. I have an example module layout like this:

$ tree
.
├── air.toml
├── go.mod
├── main.go
├── mypkg
|   └── exec.go
└── otherpkg
    └── file.go

For example, I would like to watch all .go files in mypkg, main.go, and go.mod. I first tried the following config:

include_dir = ["mypkg"]
include_ext = ["go"]
include_file = ["go.mod"]

I ran this in Docker with the following command:

docker run --rm -v $PWD:/src -w /src cosmtrek/air:v1.49.0 -d -c /src/air.toml

With this config, changes to mypkg/exec.go were detected fine and triggered a rebuild, no changes to main.go were detected, and some changes to go.mod were detected, but it did not trigger a rebuild. For go.mod it seems to not process all the same file events as for mypkg/exec.go.

Specifically, the first save to go.mod produces these file events:

[17:09:38] event: REMOVE        "/src/go.mod"                                                                                                                                                              
[17:09:38] event: CHMOD         "/src/go.mod"

and successive changes to go.mod do not produce any file events.

For mypkg/exec.go, many more file events are detected when the file is saved, and they are observed on every save:

[17:16:16] event: RENAME        "/src/mypkg/exec.go"
[17:16:16] event: WRITE         "/src/mypkg/exec.go"
[17:16:16] event: CREATE        "/src/mypkg/exec.go"
[17:16:16] mypkg/exec.go has changed
[17:16:16] mypkg/exec.go has changed
[17:16:16] event: CHMOD         "/src/mypkg/exec.go"
[17:16:17] flushing events
[17:16:17] mypkg/exec.go has changed

So it seems like I could get main.go to be watched by adding it to include_file. But the watching provided by this configuration seems incomplete as file events are not always detected and do not trigger rebuilds, as seen for the example with go.mod above. I could also remove the include_dir setting and then things mostly work as desired, but then it also watches the otherpkg directory, which is not desired. Maybe I could do that and then used exclude_dir = ["otherpkg"]? That seems to work, but it doesn't scale well when there are lots of directories and you really only want to include one or a few of them. I also tried adding "." to include_dir, which seems to have no effect.

Maybe this is a misunderstanding on my part of how the various parameters for including and excluding things are supposed to be used. For example, maybe I need to include "mod" in the include_ext to have go.mod watched properly? It's not clear (I did try it and it didn't help). These could really use some documentation because it's not clear at all how they interact, which take precedence, which can work together, etc.

To summarize: