air-verse / air

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

`exclude_dir/include_dir`: Being below `root` dir #396

Closed Dragomir-Ivanov closed 1 year ago

Dragomir-Ivanov commented 1 year ago

Greetings, I have the following project structure, which is common among Go projects:

root-|
       | - cmd/ - |
       |          | - executable1/
       |          | - executable2/
       |
       | - pkg/ - |
       |          | - package1/
       |          | - package2/

The issue is that I cannot setup air to watch over the pkg/. I start air from within each executable1/2 directories, so air doesn't want to go outside them.

What is the reason air works the way it does, and is anything we can do about it?

Thank you!

makiuchi-d commented 1 year ago

edit your .air.toml:

[build]
  bin = "/bin/sh -c './tmp/executable1 & ./tmp/executable2 & wait'"
  cmd = "/bin/sh -c 'go build -o ./tmp/executable1 ./cmd/executable1/main.go && go build -o ./tmp/executable2 ./cmd/executable2/main.go'"
Dragomir-Ivanov commented 1 year ago

@makiuchi-d Thank you for your fast response. However the instructions doesn't work if there are more files beside main.go. E.g. having a project, and not a simple main.go only tool.

Can't we have air listen on the include_dir unconditionally?

makiuchi-d commented 1 year ago

@Dragomir-Ivanov Sorry, I answered too quickly. I run the air with that toml in the root directory and run both programs in a single air process.

go build -o ./tmp/executable1 ./cmd/executable1/main.go and ... executable2 ... are simply the go build command. Replace them with the commands you normally use.

Or do executable1 and executable2 commands need to be run in their own directories?

Dragomir-Ivanov commented 1 year ago

@makiuchi-d Your answer was fine, I understood what you mean. However my projects usually this structure:

root/ - |
          |  - cmds/ - |
          |                 | - cmd1/ - |
          |                 |                | - main.go
          |                 |                | - subpackage/
          |                 |                | - [other files in main package].go
          |
          | - pkg/ - |
          |             | - sharedpackages_among_cmds/

Trying to build with your advice from root/ gives:

#go build cmds/cmd1
package cmds/cmd1 is not in GOROOT (/usr/local/go/src/cmds/cmd1)

Which is the case, as I am using Go modules outside GOROOT.

#go build cmd/apiserver/main.go
cmds/cmd1/main.go:265:45: undefined: authLimiter
cmds/cmd1/main.go:267:40: undefined: authLimiter

Where authLimiter is defined in package main, but in a separate file from main.go

Building from root/cmds/cmd1 with go build . or even just air works fine.

makiuchi-d commented 1 year ago

go build ./cmds/cmd1 in root direcotry. You must specify the source package as a relative path. (this is not an air's issue :) )

Dragomir-Ivanov commented 1 year ago

So cmds/cmd1 and ./cmds/cmd1 are different beasts after all. Who knew! Thank you.

Would you like a PR to the documentation for this specific case?

oderwat commented 1 year ago

I just ran into the same(?) problem. I have multiple services that are all inside cmd/ directories like cmd/service1 cmd/service2. Likewise, I want to use Air in service1 … or in service2, or in both. But especially, I do want to have each of them running independently of the other. Then I have ../../pkg and even ../../../somemodule1/, ../../../somemoduel2/. I would like to use Air to watch for changes in all of them. So, I tried include_dir = ["../../pkg"] but it does not pick up changes inside that path and I wondered.

So, from what I read here, there is no way to include other directories than ones below the folder of the directory where I start Air? This is actually hard to believe, as this would be an integral part of such a tool in my eyes. In fact, I use mage and configure testing for changed files all over my hard-drive and wanted to save some time using Air instead.

makiuchi-d commented 1 year ago

Put root = "../../.." in your .air.toml, and make include_dir relative path from the root.

Alternatively, please try arelo, a command line auto-reload tool:

go install github.com/makiuchi-d/arelo@latest
cd cmd/service1
arelo -t . -t ../../pkg -t ../../../somemodule1 -p '**/*.go' -- go run .

You can simply add the watching target directory by the -t option.

oderwat commented 1 year ago

@makiuchi-d Thank you. I also started to extend my own tool based on some code I wrote in the past, that actually gathers all the sources of a go module and the packages it uses, like the compiler does. This will be part of a tool that also checks for go.work files and gives hints about which modules differ and need to be uploaded. I think I need a solution that makes it hard to miss some dependencies.