package main // Rebuilding and refreshing, and the difference between them. // // r read the data again in this panel. Nothing is closed, nothing moves. // R rebuild every workspace and pane from the project file: close what the // layout owns, then build it again in order. // // A rebuild must survive the panel that started it, because that panel is one of // the things being replaced. So the rebuild runs detached, in its own session, // with its output in a log the Repair workspace can show. import ( "fmt" "os" "os/exec" "path/filepath" "syscall" "time" ) func rebuildLogPath() string { return filepath.Join(os.TempDir(), "paperclip-harness-rebuild.log") } // startRebuild launches bin/board --replace for this folder and returns at once. func startRebuild(folder string) error { board := filepath.Join(exeDir(), "board") if _, err := os.Stat(board); err != nil { return fmt.Errorf("no bin/board next to the program (%s)", board) } log, err := os.Create(rebuildLogPath()) if err != nil { return err } fmt.Fprintf(log, "rebuild started %s\n", time.Now().Format("2006-01-02 15:04:05")) cmd := exec.Command(board, "--folder", folder, "--replace") cmd.Stdout = log cmd.Stderr = log cmd.Stdin = nil // Its own session, so closing this pane does not take the rebuild with it. cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true} if err := cmd.Start(); err != nil { log.Close() return err } go func() { cmd.Wait() fmt.Fprintf(log, "rebuild finished %s\n", time.Now().Format("15:04:05")) log.Close() }() return nil } func exeDir() string { p, err := os.Executable() if err != nil { return "." } return filepath.Dir(p) } // rebuildLogTail returns the end of the last rebuild, for the Repair workspace. func rebuildLogTail(lines int) []string { b, err := os.ReadFile(rebuildLogPath()) if err != nil { return []string{"", " no rebuild has been run since this machine started"} } all := splitLines(string(b)) start := max(0, len(all)-lines) return all[start:] } func splitLines(s string) []string { var out []string cur := "" for _, r := range s { if r == '\n' { out = append(out, cur) cur = "" continue } cur += string(r) } if cur != "" { out = append(out, cur) } return out }