130 lines
5.0 KiB
Python
Executable File
130 lines
5.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Build or repair a project's panes, in a fixed order.
|
|
|
|
bin/board # the project in the current folder
|
|
bin/board --folder ~/src/x # or another one
|
|
bin/board --replace # close this project's panes and build again
|
|
|
|
Every page is a workspace with one pane, named after the page. The first
|
|
workspace holds a shell: it is the pane that never exits, so the session cannot
|
|
lose its first workspace to TUIOS cleanup.
|
|
|
|
Nothing here holds a workspace number. Each page asks for its workspace by name
|
|
at the moment it opens, because closing a pane deletes an emptied workspace and
|
|
renumbers the rest. Run it twice and nothing is duplicated.
|
|
"""
|
|
|
|
import os
|
|
import shlex
|
|
import sys
|
|
|
|
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
sys.path.insert(0, os.path.join(HERE, "lib"))
|
|
import harness as h # noqa: E402
|
|
import tuios # noqa: E402
|
|
import project as pj # noqa: E402
|
|
|
|
BIN = os.path.join(os.path.dirname(HERE), "bin", "harness")
|
|
|
|
|
|
def parse(argv):
|
|
opts = {"folder": os.getcwd(), "replace": "--replace" in argv}
|
|
for i, a in enumerate(argv):
|
|
if a == "--folder" and i + 1 < len(argv):
|
|
opts["folder"] = argv[i + 1]
|
|
return opts
|
|
|
|
|
|
def pages(cfg, folder):
|
|
"""The pages, in the order they must appear on the workspace rail."""
|
|
bin_path = BIN
|
|
proj = cfg["paperclip"]["project"]
|
|
task = pj.watch_task(cfg)
|
|
# (pane name, workspace name, command). The workspace is what a person reads
|
|
# on the rail; the pane keeps its own name. Written Workspace>pane.
|
|
# Each workspace holds several real panes, not one program drawing panels.
|
|
b = shlex.quote(bin_path)
|
|
f = shlex.quote(folder)
|
|
def pane(name, panel, extra):
|
|
return "%s -screen %s -panel %s -folder %s %s" % (b, name, panel, f, extra)
|
|
return task, [
|
|
("shell", "Shell", "exec zsh -i"),
|
|
|
|
("tasks", "Board", pane("board", "tasks", "-project " + shlex.quote(proj))),
|
|
("detail", "Board", pane("board", "detail", "-project " + shlex.quote(proj))),
|
|
("needs", "Board", pane("board", "needs", "-project " + shlex.quote(proj))),
|
|
|
|
("runs", "Work", pane("work", "runs", "")),
|
|
("change", "Work", pane("work", "change", "")),
|
|
("facts", "Work", pane("work", "facts", "")),
|
|
|
|
("task", "Reply", pane("reply", "task", "")),
|
|
("thread", "Reply", pane("reply", "thread", "")),
|
|
("replybox", "Reply", pane("reply", "reply", "")),
|
|
|
|
("form", "New task", pane("new", "form", "-project " + shlex.quote(proj))),
|
|
("guidance", "New task", pane("new", "guidance", "-project " + shlex.quote(proj))),
|
|
("preview", "New task", pane("new", "preview", "-project " + shlex.quote(proj))),
|
|
|
|
("facts-p", "Project", pane("project", "facts", "")),
|
|
("costs", "Project", pane("project", "costs", "")),
|
|
("settings", "Project", pane("project", "settings", "")),
|
|
|
|
("health", "Repair", pane("repair", "health", "")),
|
|
("layout", "Repair", pane("repair", "layout", "")),
|
|
("rebuild-log", "Repair", pane("repair", "log", "")),
|
|
]
|
|
|
|
|
|
def main():
|
|
opts = parse(sys.argv[1:])
|
|
folder = os.path.abspath(os.path.expanduser(opts["folder"]))
|
|
cfg = pj.load(folder)
|
|
pj.check_machine(cfg)
|
|
session = cfg["session"]
|
|
tuios.require_session(session)
|
|
os.environ["PAPERCLIP_HARNESS_SESSION"] = session
|
|
|
|
if not os.path.isfile(BIN):
|
|
raise h.Refused(2, "no harness binary at %s; build it with 'cd tui && go build -o ../bin/harness .'" % BIN)
|
|
|
|
task, page_list = pages(cfg, folder)
|
|
h.say("board: %s (session %s, folder %s)" % (cfg["paperclip"]["project"], session, folder))
|
|
h.say("watching: %s" % task)
|
|
|
|
if opts["replace"]:
|
|
for name, _, _ in page_list:
|
|
if tuios.close_pane(name, session):
|
|
h.say(" closed %s" % name)
|
|
|
|
# Group the panes by the workspace they belong to, in first-seen order, so a
|
|
# workspace is claimed once and all of its panes are made inside it.
|
|
order = []
|
|
groups = {}
|
|
for name, workspace, command in page_list:
|
|
if workspace not in groups:
|
|
groups[workspace] = []
|
|
order.append(workspace)
|
|
groups[workspace].append((name, command))
|
|
|
|
for workspace in order:
|
|
number = tuios.claim(workspace, session)
|
|
for name, command in groups[workspace]:
|
|
if any((w.get("custom_name") or "") == name for w in tuios.windows(session)):
|
|
h.say(" %-11s adopted %s" % (name, workspace))
|
|
continue
|
|
tuios.new_window(name, number, folder, command, session)
|
|
h.say(" %-11s created %s" % (name, workspace))
|
|
|
|
# Number the workspaces in the order a person reads them.
|
|
for number, name in tuios.arrange([(p[0], p[1]) for p in page_list], session):
|
|
h.say(" placed %-11s workspace %s" % (name, number))
|
|
|
|
in_use = [w for w in tuios.workspaces(session) if (w.get("window_count") or 0) > 0]
|
|
h.say("workspaces in use: %d" % len(in_use))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
h.main_guard(main)
|