Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 11 additions & 23 deletions src/git_draft/drafter.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ async def generate_draft(
{
"prompt_id": prompt_id,
"tool": o.tool,
"reason": o.reason,
"details": json.dumps(o.details),
"started_at": o.start,
}
Expand Down Expand Up @@ -440,53 +439,43 @@ def __init__(self, progress: Progress) -> None:
self.operations = list[_Operation]()
self._progress = progress

def on_list_files(
self, paths: Sequence[PurePosixPath], reason: str | None
) -> None:
def on_list_files(self, paths: Sequence[PurePosixPath]) -> None:
count = len(paths)
self._progress.report("Listed available files.", count=count)
self._record(reason, "list_files", count=count)
self._record("list_files", count=count)

def on_read_file(
self, path: PurePosixPath, contents: str | None, reason: str | None
) -> None:
def on_read_file(self, path: PurePosixPath, contents: str | None) -> None:
size = -1 if contents is None else len(contents)
self._progress.report(f"Read {path}.", length=size)
self._record(reason, "read_file", path=str(path), size=size)
self._record("read_file", path=str(path), size=size)

def on_write_file(
self, path: PurePosixPath, contents: str, reason: str | None
) -> None:
def on_write_file(self, path: PurePosixPath, contents: str) -> None:
size = len(contents)
self._progress.report(f"Wrote {path}.", length=size)
self._record(reason, "write_file", path=str(path), size=size)
self._record("write_file", path=str(path), size=size)

def on_delete_file(self, path: PurePosixPath, reason: str | None) -> None:
def on_delete_file(self, path: PurePosixPath) -> None:
self._progress.report(f"Deleted {path}.")
self._record(reason, "delete_file", path=str(path))
self._record("delete_file", path=str(path))

def on_rename_file(
self,
src_path: PurePosixPath,
dst_path: PurePosixPath,
reason: str | None,
) -> None:
self._progress.report(f"Renamed {src_path} to {dst_path}.")
self._record(
reason,
"rename_file",
src_path=str(src_path),
dst_path=str(dst_path),
)

def on_expose_files(self) -> None:
self._progress.report("Exposed files.")
self._record(None, "expose_files")
self._record("expose_files")

def _record(self, reason: str | None, tool: str, **kwargs) -> None:
op = _Operation(
tool=tool, details=kwargs, reason=reason, start=datetime.now()
)
def _record(self, tool: str, **kwargs) -> None:
op = _Operation(tool=tool, details=kwargs, start=datetime.now())
_logger.debug("Recorded operation. [op=%s]", op)
self.operations.append(op)

Expand All @@ -497,7 +486,6 @@ class _Operation:

tool: str
details: JSONObject
reason: str | None
start: datetime


Expand Down
4 changes: 2 additions & 2 deletions src/git_draft/queries/add-operation.sql
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
insert into operations (prompt_id, tool, reason, details, started_at)
values (:prompt_id, :tool, :reason, :details, :started_at)
insert into operations (prompt_id, tool, details, started_at)
values (:prompt_id, :tool, :details, :started_at)
1 change: 0 additions & 1 deletion src/git_draft/queries/create-tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ create table if not exists operations (
id integer primary key,
prompt_id integer not null,
tool text not null,
reason text,
details text not null,
started_at timestamp not null,
foreign key (prompt_id) references actions (prompt_id) on delete cascade
Expand Down
2 changes: 1 addition & 1 deletion src/git_draft/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
class Store:
"""Lightweight sqlite wrapper"""

_name = "v3.sqlite3"
_name = "v4.sqlite3"

def __init__(self, conn: sqlite3.Connection) -> None:
self._connection = conn
Expand Down
79 changes: 30 additions & 49 deletions src/git_draft/toolbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,58 +36,41 @@ class Toolbox:
# feedback more than once during a bot action, which leads to a better
# experience when used interactively.

# TODO: Remove all reason arguments. They are not currently used, and there
# is no obvious use-case at the moment.

def __init__(self, visitors: Sequence[ToolVisitor] | None = None) -> None:
self._visitors = visitors or []

def _dispatch(self, effect: Callable[[ToolVisitor], None]) -> None:
for visitor in self._visitors:
effect(visitor)

def list_files(self, reason: str | None = None) -> Sequence[PurePosixPath]:
def list_files(self) -> Sequence[PurePosixPath]:
paths = self._list()
self._dispatch(lambda v: v.on_list_files(paths, reason))
self._dispatch(lambda v: v.on_list_files(paths))
return paths

def read_file(
self,
path: PurePosixPath,
reason: str | None = None,
) -> str | None:
def read_file(self, path: PurePosixPath) -> str | None:
try:
contents = self._read(path)
except FileNotFoundError:
contents = None
self._dispatch(lambda v: v.on_read_file(path, contents, reason))
self._dispatch(lambda v: v.on_read_file(path, contents))
return contents

def write_file(
self,
path: PurePosixPath,
contents: str,
reason: str | None = None,
) -> None:
self._dispatch(lambda v: v.on_write_file(path, contents, reason))
def write_file(self, path: PurePosixPath, contents: str) -> None:
self._dispatch(lambda v: v.on_write_file(path, contents))
return self._write(path, contents)

def delete_file(
self,
path: PurePosixPath,
reason: str | None = None,
) -> None:
self._dispatch(lambda v: v.on_delete_file(path, reason))
def delete_file(self, path: PurePosixPath) -> None:
self._dispatch(lambda v: v.on_delete_file(path))
self._delete(path)

def rename_file(
self,
src_path: PurePosixPath,
dst_path: PurePosixPath,
reason: str | None = None,
) -> None:
"""Rename a single file"""
self._dispatch(lambda v: v.on_rename_file(src_path, dst_path, reason))
self._dispatch(lambda v: v.on_rename_file(src_path, dst_path))
self._rename(src_path, dst_path)

def expose_files(
Expand Down Expand Up @@ -134,26 +117,25 @@ class ToolVisitor(Protocol):
"""Tool usage hook"""

def on_list_files(
self, paths: Sequence[PurePosixPath], reason: str | None
self, paths: Sequence[PurePosixPath]
) -> None: ... # pragma: no cover

def on_read_file(
self, path: PurePosixPath, contents: str | None, reason: str | None
self, path: PurePosixPath, contents: str | None
) -> None: ... # pragma: no cover

def on_write_file(
self, path: PurePosixPath, contents: str, reason: str | None
self, path: PurePosixPath, contents: str
) -> None: ... # pragma: no cover

def on_delete_file(
self, path: PurePosixPath, reason: str | None
self, path: PurePosixPath
) -> None: ... # pragma: no cover

def on_rename_file(
self,
src_path: PurePosixPath,
dst_path: PurePosixPath,
reason: str | None,
) -> None: ... # pragma: no cover

def on_expose_files(self) -> None: ... # pragma: no cover
Expand Down Expand Up @@ -266,24 +248,6 @@ def _write(self, path: PurePosixPath, contents: str) -> None:
temp.close()
self._write_from_disk(path, Path(temp.name))

@override
@contextlib.contextmanager
def _expose(self) -> Iterator[Path]:
tree_sha = self.tree_sha()
commit_sha = self._repo.git(
"commit-tree", "-m", "draft! worktree", tree_sha
).stdout
with tempfile.TemporaryDirectory() as path_str:
try:
self._repo.git(
"worktree", "add", "--detach", path_str, commit_sha
)
path = Path(path_str)
yield path
self._sync_updates(worktree_path=path)
finally:
self._repo.git("worktree", "remove", "-f", path_str)

def _write_from_disk(
self, path: PurePosixPath, contents_path: Path
) -> None:
Expand All @@ -300,6 +264,23 @@ def _write_from_disk(
def _delete(self, path: PurePosixPath) -> None:
self._tree_updates.append(_DeleteBlob(path))

@override
@contextlib.contextmanager
def _expose(self) -> Iterator[Path]:
commit_sha = self._repo.git(
"commit-tree", "-m", "draft! worktree", self.tree_sha()
).stdout
with tempfile.TemporaryDirectory() as path_str:
try:
self._repo.git(
"worktree", "add", "--detach", path_str, commit_sha
)
path = Path(path_str)
yield path
self._sync_updates(worktree_path=path)
finally:
self._repo.git("worktree", "remove", "-f", path_str)


class _TreeUpdate:
"""Generic tree update"""
Expand Down