key and API address fall back to the person's secrets file; a non-git folder becomes a local_path project
This commit is contained in:
BIN
bin/harness
BIN
bin/harness
Binary file not shown.
@@ -28,9 +28,63 @@ for _p in (
|
||||
if _p not in os.environ.get("PATH", ""):
|
||||
os.environ["PATH"] = _p + ":" + os.environ.get("PATH", "")
|
||||
|
||||
API = os.environ.get("PAPERCLIP_API_URL", "http://127.0.0.1:3100").rstrip("/")
|
||||
COMPANY = os.environ.get("PAPERCLIP_COMPANY_ID", "d4921013-e5da-4d88-8016-57d5746e2d03")
|
||||
KEY = os.environ.get("PAPERCLIP_BOARD_KEY", "")
|
||||
|
||||
def _from_secrets(name):
|
||||
"""Read one variable out of the person's own secrets file.
|
||||
|
||||
A terminal started by a desktop session does not inherit systemd's
|
||||
environment.d, so the key can be missing from the shell on a machine where
|
||||
the file is right there. The file is the person's; this only reads it.
|
||||
"""
|
||||
path = os.path.join(_HOME, ".config", "environment.d")
|
||||
try:
|
||||
names = sorted(os.listdir(path))
|
||||
except OSError:
|
||||
return ""
|
||||
for fn in names:
|
||||
if not fn.endswith(".conf"):
|
||||
continue
|
||||
try:
|
||||
with open(os.path.join(path, fn)) as fh:
|
||||
for line in fh:
|
||||
line = line.strip()
|
||||
if line.startswith("#") or "=" not in line:
|
||||
continue
|
||||
k, _, v = line.partition("=")
|
||||
if k.strip() == name:
|
||||
return v.strip().strip('"').strip("'")
|
||||
except OSError:
|
||||
continue
|
||||
return ""
|
||||
|
||||
|
||||
def _var(name, default=""):
|
||||
return os.environ.get(name) or _from_secrets(name) or default
|
||||
|
||||
|
||||
def _resolve_api():
|
||||
"""Where Paperclip is. Its own address if given, else this machine, else .13.
|
||||
|
||||
Paperclip runs on one machine in this house. A session on another machine
|
||||
has to ask that one, so the fallback is the machine that hosts it rather
|
||||
than a loopback address that answers nothing there.
|
||||
"""
|
||||
told = _var("PAPERCLIP_API_URL")
|
||||
if told:
|
||||
return told.rstrip("/")
|
||||
here = "http://127.0.0.1:3100"
|
||||
try:
|
||||
with urllib.request.urlopen(here + "/api/health", timeout=2) as f:
|
||||
if f.status == 200:
|
||||
return here
|
||||
except Exception:
|
||||
pass
|
||||
return "http://192.168.20.13:3100"
|
||||
|
||||
|
||||
API = _resolve_api()
|
||||
COMPANY = _var("PAPERCLIP_COMPANY_ID", "d4921013-e5da-4d88-8016-57d5746e2d03")
|
||||
KEY = _var("PAPERCLIP_BOARD_KEY")
|
||||
|
||||
BLOCKING_SEVERITIES = {"critical", "high"}
|
||||
|
||||
|
||||
22
bin/office
22
bin/office
@@ -74,19 +74,33 @@ def create_project(name, folder, dry):
|
||||
Adopting a folder that Paperclip has never heard of needed two steps before:
|
||||
make the project in the browser, then run this command. One command is enough.
|
||||
"""
|
||||
# A folder that is a git repository gets a branch per task in its own
|
||||
# worktree. A folder that is not cannot: asking for a worktree would create
|
||||
# a project whose every run fails. Those keep the folder in place instead.
|
||||
is_repo = subprocess.run(["git", "-C", folder, "rev-parse", "--is-inside-work-tree"],
|
||||
capture_output=True, text=True, timeout=30).stdout.strip() == "true"
|
||||
body = {
|
||||
"name": name,
|
||||
"description": "Adopted from %s by bin/office." % folder,
|
||||
"status": "backlog",
|
||||
"workspace": {"name": name, "sourceType": "git_repo", "cwd": folder, "isPrimary": True},
|
||||
"executionWorkspacePolicy": {
|
||||
"workspace": {
|
||||
"name": name,
|
||||
"sourceType": "git_repo" if is_repo else "local_path",
|
||||
"cwd": folder,
|
||||
"isPrimary": True,
|
||||
},
|
||||
}
|
||||
if is_repo:
|
||||
body["executionWorkspacePolicy"] = {
|
||||
"enabled": True,
|
||||
"defaultMode": "isolated_workspace",
|
||||
"allowIssueOverride": True,
|
||||
"workspaceStrategy": {"type": "git_worktree", "baseRef": "main",
|
||||
"branchTemplate": "{{issue.identifier}}-{{slug}}"},
|
||||
},
|
||||
}
|
||||
}
|
||||
else:
|
||||
h.say(" not a git repository: the project keeps the folder in place,")
|
||||
h.say(" so a task changes these files directly. No branch, no worktree.")
|
||||
if dry:
|
||||
h.say("would create Paperclip project %r for %s" % (name, folder))
|
||||
return "(dry run)"
|
||||
|
||||
Reference in New Issue
Block a user