#!/usr/bin/env python3 """Open a folder as a project: adopt it, remember it, build its pages. bin/office [--project ] [--session NAME] [--dry] bin/office . # the folder you are in Adopting writes one file, /.harness/harness.toml, and nothing else. An existing folder is never overwritten: what is already there stays, and only the missing file is written. Paperclip's project record is read, never created — bin/office adopts a project that exists, it does not invent one. The machine is remembered, so the flag is stated once. Running the same command on a machine that is not the recorded one is refused rather than silently producing a second copy of the same project. """ import os 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 project as pj # noqa: E402 import tuios # noqa: E402 def parse(argv): opts = {"folder": ".", "project": "", "session": "", "dry": "--dry" in argv, "host": ""} args = [a for a in argv if not a.startswith("--")] if args: opts["folder"] = args[0] for i, a in enumerate(argv): if a == "--project" and i + 1 < len(argv): opts["project"] = argv[i + 1] if a == "--session" and i + 1 < len(argv): opts["session"] = argv[i + 1] if a == "--host" and i + 1 < len(argv): opts["host"] = argv[i + 1] return opts def main(): opts = parse(sys.argv[1:]) folder = os.path.abspath(os.path.expanduser(opts["folder"])) if not os.path.isdir(folder): raise h.Refused(2, "no folder at %s" % folder) host = opts["host"] or pj.this_machine() # An adopted project already knows its session. Only a new one needs a # default, and a default that names a session nobody made is worse than an # error, so the session is checked before anything is written. existing = {} if pj.exists(folder): existing = pj.load(folder) session = ( opts["session"] or existing.get("session") or os.path.basename(folder) ) tuios.require_session(session) if opts["host"] and opts["host"] not in (pj.this_machine(), pj.this_machine().split(".")[0]): # Only a note, because the panes are built by the machine that owns them. h.say("host: %s (build the pages there)" % host) ref = opts["project"] if not ref and pj.exists(folder): ref = pj.load(folder)["paperclip"]["project"] if not ref: raise h.Refused( 2, "which Paperclip project is %s? pass --project " % folder, ) proj = pj.resolve_project(ref) h.say("project: %s (%s)" % (proj["name"], proj["id"])) h.say("folder: %s" % folder) h.say("session: %s" % session) h.say("machine: %s" % host) tasks = pj.active_tasks(proj["id"]) watching = next((t["identifier"] for t in tasks if t["status"] not in ("done", "cancelled")), tasks[0]["identifier"] if tasks else "") cfg = { "session": session, "paperclip": {"company": h.COMPANY, "project": proj["id"]}, "machine": {"host": host, "folder": folder}, "watching": watching, } if opts["dry"]: h.say("would write %s" % pj.path(folder)) h.say("would build pages: shell, tree, reply, log, new") return 0 pj.save(folder, cfg) h.say("wrote %s" % pj.path(folder)) # The pages are built by this machine, from this folder, in this session. code = os.spawnv( os.P_WAIT, sys.executable, [sys.executable, os.path.join(HERE, "board"), "--folder", folder], ) return code if __name__ == "__main__": h.main_guard(main)