R rebuilds every pane detached; r refreshes data; Author gains guidance and preview; Repair gains the rebuild log
This commit is contained in:
90
tui/rebuild.go
Normal file
90
tui/rebuild.go
Normal file
@@ -0,0 +1,90 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user