air icon indicating copy to clipboard operation
air copied to clipboard

Bug: Adding entries to `include_dir` excludes directories

Open soypat opened this issue 1 year ago • 1 comments

I'm working on https://github.com/soypat/upsya and am unable to use air due to this bug.

Steps to reproduce

My .air.toml looks like (click Details)

root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
  args_bin = ["-evalglob=testdata/evaluations/*/*.py"]
  bin = ";PYTHON3=python3 ./tmp/main"
  cmd = "go build -o ./tmp/main ."
  delay = 1000
  exclude_dir = ["assets", "tmp", "vendor"]
  exclude_file = []
  exclude_regex = ["_test.go"]
  exclude_unchanged = false
  follow_symlink = false
  full_bin = ""
  include_dir = []
  include_ext = ["go", "tpl", "tmpl", "html", "py"]
  kill_delay = "0s"
  log = "build-errors.log"
  send_interrupt = false
  stop_on_error = true

[color]
  app = ""
  build = "yellow"
  main = "magenta"
  runner = "green"
  watcher = "cyan"

[log]
  time = false

[misc]
  clean_on_exit = false

[screen]
  clear_on_rebuild = false

air shows the following with the above config:

watching .
!exclude assets
watching evaluations
watching templates
!exclude testdata
!exclude tmp
building...
running..

I change include_dir to be

  include_dir = ["testdata"]

What I expected

The same message but with watching testdata instead of excluding.

What I saw

Then air excludes folders which are irrelevant to the directive provided, which should be included since they contain .tmpl files

!exclude assets
!exclude evaluations
!exclude templates
!exclude testdata
!exclude tmp
building...
running...

soypat avatar Jul 27 '22 14:07 soypat

So I was looking into your issue. By default, Air will exclude any directory that is specified in the testdata_dir. So if you pass your testdata directory into the include_dir, it will still be excluded. A simple work around is to change your testdata_dir="test" and include_dir="testdata"

@xiantang Maybe we can add a check to see if any directories in the include_dir match the testdata_dir, we do not exclude the testdata_dir by default? Or we can reorder the below function like so:

func (e *Engine) watching(root string) error {
	return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		// NOTE: path is absolute
		if info != nil && !info.IsDir() {
			return nil
		}
		isIn, walkDir := e.checkIncludeDir(path)
		if !walkDir {
			e.watcherLog("!exclude %s", e.config.rel(path))
			return filepath.SkipDir
		}
		if isIn {
			return e.watchDir(path)
		}
		// exclude tmp dir
		if e.isTmpDir(path) {
			e.watcherLog("!exclude %s", e.config.rel(path))
			return filepath.SkipDir
		}
		// exclude testdata dir
		if e.isTestDataDir(path) {
			e.watcherLog("!exclude %s", e.config.rel(path))
			return filepath.SkipDir
		}
		// exclude hidden directories like .git, .idea, etc.
		if isHiddenDirectory(path) {
			return filepath.SkipDir
		}
		// exclude user specified directories
		if e.isExcludeDir(path) {
			e.watcherLog("!exclude %s", e.config.rel(path))
			return filepath.SkipDir
		}
		return nil
	})
}

The only caveat to this solution is determining which do we want to have a higher priority. Do we want to exclude files even if they are specified in include? or vice versa?

navazjm avatar Aug 07 '22 11:08 navazjm