We want the command we defined before, Stack, to be able to save its state between sessions. The simplest solution is to save the contents of the stack as a text file, with one element per line. We can make this file unique for each user, using the OS/user package to place it in the user home directory:
func (s *Stack) getPath() (string, error) {
u, err := user.Current()
if err != nil {
return "", err
}
return filepath.Join(u.HomeDir, ".stack"), nil
}
Let's start writing; we will create and truncate the file (setting its size to 0 using the TRUNC flag) and write the following lines:
func (s *Stack) Shutdown(w io.Writer) error {
path, err := s.getPath()
if err != nil {
return err
}
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
if err != nil {
return err
}
defer f.Close()
for _, v := range s.data {
if _, err := fmt.Fprintln(f, v); err != nil {
return err
}
}
return nil
}
The method used during the shutdown will read the file line by line and will add the elements to the stack. We can use bufio.Scanner, as we saw in a previous chapter, to do this easily:
func (s *Stack) Startup(w io.Writer) error {
path, err := s.getPath()
if err != nil {
return err
}
f, err := os.Open(path)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
defer f.Close()
s.data = s.data[:0]
scanner := bufio.NewScanner(f)
for scanner.Scan() {
s.push(string(scanner.Bytes()))
}
return nil
}