1package main
2
3import (
4	"fmt"
5	"os"
6	"path/filepath"
7)
8
9// CmdWatchDir is `direnv watch-dir SHELL PATH`
10var CmdWatchDir = &Cmd{
11	Name:    "watch-dir",
12	Desc:    "Recursively adds a directory to the list that direnv watches for changes",
13	Args:    []string{"SHELL", "DIR"},
14	Private: true,
15	Action:  actionSimple(watchDirCommand),
16}
17
18func watchDirCommand(env Env, args []string) (err error) {
19	if len(args) < 3 {
20		return fmt.Errorf("a directory is required to add to the list of watches")
21	}
22
23	shellName := args[1]
24	dir := args[2]
25
26	shell := DetectShell(shellName)
27
28	if shell == nil {
29		return fmt.Errorf("unknown target shell '%s'", shellName)
30	}
31
32	if _, err := os.Stat(dir); os.IsNotExist(err) {
33		return fmt.Errorf("dir '%s' does not exist", dir)
34	}
35
36	watches := NewFileTimes()
37	watchString, ok := env[DIRENV_WATCHES]
38	if ok {
39		err = watches.Unmarshal(watchString)
40		if err != nil {
41			return err
42		}
43	}
44
45	err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
46		if err != nil {
47			return err
48		}
49		return watches.NewTime(path, info.ModTime().Unix(), true)
50	})
51	if err != nil {
52		return fmt.Errorf("failed to recursively watch dir '%s': %v", dir, err)
53	}
54
55	e := make(ShellExport)
56	e.Add(DIRENV_WATCHES, watches.Marshal())
57
58	os.Stdout.WriteString(shell.Export(e))
59
60	return
61}
62