1package main
2
3import (
4	"bufio"
5	"fmt"
6	"io"
7	"os"
8	"strconv"
9	"strings"
10)
11
12// CmdWatchList is `direnv watch-list`
13var CmdWatchList = &Cmd{
14	Name:    "watch-list",
15	Desc:    "Pipe pairs of `mtime path` to stdin to build a list of files to watch.",
16	Args:    []string{"[SHELL]"},
17	Private: true,
18	Action:  actionSimple(watchListCommand),
19}
20
21func watchListCommand(env Env, args []string) (err error) {
22	var shellName string
23
24	if len(args) >= 2 {
25		shellName = args[1]
26	} else {
27		shellName = "bash"
28	}
29
30	shell := DetectShell(shellName)
31
32	if shell == nil {
33		return fmt.Errorf("unknown target shell '%s'", shellName)
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	// Read `mtime path` lines from stdin
46	reader := bufio.NewReader(os.Stdin)
47
48	i := 1
49	for {
50		line, err := reader.ReadString('\n')
51		if err == nil {
52			elems := strings.SplitN(line, " ", 2)
53			if len(elems) != 2 {
54				return fmt.Errorf("line %d: expected to contain two elements", i)
55			}
56			mtime, err := strconv.Atoi(elems[0])
57			if err != nil {
58				return fmt.Errorf("line %d: %s", i, err)
59			}
60			path := elems[1][:len(elems[1])-1]
61
62			// add to watches
63			err = watches.NewTime(path, int64(mtime), true)
64			if err != nil {
65				return err
66			}
67		} else if err == io.EOF {
68			break
69		} else {
70			return fmt.Errorf("line %d: %s", i, err)
71		}
72		i++
73	}
74
75	e := make(ShellExport)
76	e.Add(DIRENV_WATCHES, watches.Marshal())
77
78	os.Stdout.WriteString(shell.Export(e))
79
80	return
81}
82