91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
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
|
|
}
|