gitd-client 0.14.0__tar.gz → 0.15.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {gitd_client-0.14.0 → gitd_client-0.15.0}/PKG-INFO +6 -5
  2. {gitd_client-0.14.0 → gitd_client-0.15.0}/README.md +5 -4
  3. {gitd_client-0.14.0 → gitd_client-0.15.0}/pyproject.toml +1 -1
  4. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/__init__.py +2 -0
  5. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/client.py +27 -11
  6. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/contract.json +66 -0
  7. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/messages.py +2 -0
  8. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/methods.py +1 -0
  9. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/models.py +20 -0
  10. {gitd_client-0.14.0 → gitd_client-0.15.0}/.gitignore +0 -0
  11. {gitd_client-0.14.0 → gitd_client-0.15.0}/examples/agent.py +0 -0
  12. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/changes.py +0 -0
  13. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/comparison.py +0 -0
  14. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/connection.py +0 -0
  15. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/contract.py +0 -0
  16. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/credentials_calls.py +0 -0
  17. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/endpoint_calls.py +0 -0
  18. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/endpoint_tokens.py +0 -0
  19. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/errors.py +0 -0
  20. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/kept_credentials.py +0 -0
  21. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/publishing_calls.py +0 -0
  22. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/publishing_settings.py +0 -0
  23. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/timestamps.py +0 -0
  24. {gitd_client-0.14.0 → gitd_client-0.15.0}/src/gitd/warm_layers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: gitd-client
3
- Version: 0.14.0
3
+ Version: 0.15.0
4
4
  Summary: Client for gitd: instant, secretless git checkouts for agent sandboxes
5
5
  Project-URL: Homepage, https://github.com/dooservice/gitd
6
6
  Project-URL: Source, https://github.com/dooservice/gitd/tree/main/sdk/python
@@ -15,7 +15,7 @@ Requires-Dist: grpcio>=1.84.0
15
15
  Requires-Dist: protobuf>=7.36.2
16
16
  Description-Content-Type: text/markdown
17
17
 
18
- # gitd for Python
18
+ # gitd-client for Python
19
19
 
20
20
  A client for [gitd](https://github.com/dooservice/gitd): instant, secretless git checkouts
21
21
  for agent sandboxes. Your agents work in their own copy and publish a branch; they never
@@ -45,12 +45,13 @@ No call takes a credential: gitd reads and publishes with the ones it keeps.
45
45
 
46
46
  | Method | What it does |
47
47
  |---|---|
48
- | `prepare(url, path, *, branch, commit, submodules, full_history, strategy, on_progress)` | A workspace of a repository at a path under gitd's roots |
49
- | `update(path, *, branch, submodules, on_progress)` | To the tip of its branch, or of the branch given |
48
+ | `prepare(url, path, *, branch, commit, submodules, full_history, strategy, warm, new_branch, on_progress)` | A workspace of a repository at a path under gitd's roots, on a new branch of its own with `new_branch` |
49
+ | `update(path, *, branch, merge, submodules, on_progress)` | To the tip of its branch, or of the branch given; with `merge`, that branch merged into the one it is on |
50
50
  | `checkout(path, commit, *, submodules, on_progress)` | To a commit, as a rollback does |
51
51
  | `describe(path)` | Its repository, commit, branch, uncommitted changes and submodules |
52
- | `publish(path, branch, *, requested_by, pull_request, provenance, sandbox, update)` | Its commits pushed to a new branch, or with `update` an earlier publish's branch moved forward; its pull request opened or updated |
52
+ | `publish(path, branch=None, *, requested_by, pull_request, provenance, sandbox, update)` | Its commits pushed to a new branch, or to the branch it is on when none is given; with `update`, or a branch it published before, that branch moved forward; its pull request opened or updated |
53
53
  | `remove(path)` | Deleted; its pool stays |
54
+ | `list()` | Every workspace gitd made, described, with the branches published from each |
54
55
  | `probe(url)` | Whether it can be read, its default branch and branches |
55
56
  | `info()` | Which gitd answers, and how it makes workspaces here and why |
56
57
  | `audit(*, since, url, limit)` | Every publish, done or refused, newest first |
@@ -1,4 +1,4 @@
1
- # gitd for Python
1
+ # gitd-client for Python
2
2
 
3
3
  A client for [gitd](https://github.com/dooservice/gitd): instant, secretless git checkouts
4
4
  for agent sandboxes. Your agents work in their own copy and publish a branch; they never
@@ -28,12 +28,13 @@ No call takes a credential: gitd reads and publishes with the ones it keeps.
28
28
 
29
29
  | Method | What it does |
30
30
  |---|---|
31
- | `prepare(url, path, *, branch, commit, submodules, full_history, strategy, on_progress)` | A workspace of a repository at a path under gitd's roots |
32
- | `update(path, *, branch, submodules, on_progress)` | To the tip of its branch, or of the branch given |
31
+ | `prepare(url, path, *, branch, commit, submodules, full_history, strategy, warm, new_branch, on_progress)` | A workspace of a repository at a path under gitd's roots, on a new branch of its own with `new_branch` |
32
+ | `update(path, *, branch, merge, submodules, on_progress)` | To the tip of its branch, or of the branch given; with `merge`, that branch merged into the one it is on |
33
33
  | `checkout(path, commit, *, submodules, on_progress)` | To a commit, as a rollback does |
34
34
  | `describe(path)` | Its repository, commit, branch, uncommitted changes and submodules |
35
- | `publish(path, branch, *, requested_by, pull_request, provenance, sandbox, update)` | Its commits pushed to a new branch, or with `update` an earlier publish's branch moved forward; its pull request opened or updated |
35
+ | `publish(path, branch=None, *, requested_by, pull_request, provenance, sandbox, update)` | Its commits pushed to a new branch, or to the branch it is on when none is given; with `update`, or a branch it published before, that branch moved forward; its pull request opened or updated |
36
36
  | `remove(path)` | Deleted; its pool stays |
37
+ | `list()` | Every workspace gitd made, described, with the branches published from each |
37
38
  | `probe(url)` | Whether it can be read, its default branch and branches |
38
39
  | `info()` | Which gitd answers, and how it makes workspaces here and why |
39
40
  | `audit(*, since, url, limit)` | Every publish, done or refused, newest first |
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "gitd-client"
7
- version = "0.14.0"
7
+ version = "0.15.0"
8
8
  description = "Client for gitd: instant, secretless git checkouts for agent sandboxes"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -15,6 +15,7 @@ from .models import (
15
15
  Description,
16
16
  Info,
17
17
  Layers,
18
+ ListedWorkspace,
18
19
  PendingSubmodule,
19
20
  Probe,
20
21
  Progress,
@@ -71,6 +72,7 @@ __all__ = [
71
72
  "GitdError",
72
73
  "Info",
73
74
  "Layers",
75
+ "ListedWorkspace",
74
76
  "PendingSubmodule",
75
77
  "Probe",
76
78
  "Progress",
@@ -12,7 +12,7 @@ from .comparison import Comparison, Conflict, Event, Side
12
12
  from .connection import Connection, OnProgress
13
13
  from .credentials_calls import Credentials
14
14
  from .endpoint_calls import Endpoint
15
- from .models import AuditEntry, Description, Info, Probe, Published, Strategy, Workspace
15
+ from .models import AuditEntry, Description, Info, ListedWorkspace, Probe, Published, Strategy, Workspace
16
16
  from .publishing_calls import Publishing
17
17
  from .publishing_settings import Provenance, PullRequestOptions
18
18
  from .timestamps import Timestamp
@@ -75,13 +75,15 @@ class Gitd:
75
75
  full_history: bool = False,
76
76
  strategy: Strategy | None = None,
77
77
  warm: str = "",
78
+ new_branch: str = "",
78
79
  on_progress: OnProgress | None = None,
79
80
  ) -> Workspace:
80
81
  """Makes a workspace of a repository at a path under gitd's roots, at a commit, a
81
82
  branch, or the default branch. strategy is a preference: gitd falls back to copy when
82
83
  it cannot make one that way here. warm names a warm layer to stand on, its
83
84
  dependencies installed already: the workspace is then made by overlay, at the commit
84
- the layer was sealed at, or not at all."""
85
+ the layer was sealed at, or not at all. new_branch starts the workspace on a branch
86
+ of its own, made there for the work: publish takes it when given no branch."""
85
87
  if commit:
86
88
  revision = messages.Revision(commit=commit)
87
89
  elif branch:
@@ -96,6 +98,7 @@ class Gitd:
96
98
  full_history=full_history,
97
99
  strategy=Strategy.preference(strategy),
98
100
  warm=warm,
101
+ new_branch=new_branch,
99
102
  )
100
103
  return Workspace.from_message(path, self.connection.follow(methods.PREPARE, request, on_progress))
101
104
 
@@ -104,11 +107,17 @@ class Gitd:
104
107
  path: str,
105
108
  *,
106
109
  branch: str | None = None,
110
+ merge: str | None = None,
107
111
  submodules: bool = False,
108
112
  on_progress: OnProgress | None = None,
109
113
  ) -> Workspace:
110
- """Brings a workspace to the tip of its branch, or of the branch given."""
111
- request = messages.UpdateRequest(path=path, branch=branch or "", with_submodules=submodules)
114
+ """Brings a workspace to the tip of its branch, or of the branch given. With merge,
115
+ merges that branch of the repository into the one the workspace is on instead, with a
116
+ merge commit; conflicts raise CONFLICT and stay marked in the workspace, to be
117
+ resolved and committed there."""
118
+ request = messages.UpdateRequest(
119
+ path=path, branch=branch or "", merge=merge or "", with_submodules=submodules
120
+ )
112
121
  return Workspace.from_message(path, self.connection.follow(methods.UPDATE, request, on_progress))
113
122
 
114
123
  def checkout(
@@ -131,7 +140,7 @@ class Gitd:
131
140
  def publish(
132
141
  self,
133
142
  path: str,
134
- branch: str,
143
+ branch: str | None = None,
135
144
  *,
136
145
  requested_by: str = "",
137
146
  pull_request: PullRequestOptions | None = None,
@@ -139,18 +148,20 @@ class Gitd:
139
148
  sandbox: str = "",
140
149
  update: bool = False,
141
150
  ) -> Published:
142
- """Pushes what was committed in a workspace to a new branch, with the credential gitd
143
- keeps, and opens its pull request when the publishing settings or pull_request say
144
- so. requested_by is who asked for the work, as their account on the host. With
145
- sandbox, and path empty, publishes the branch a sandbox pushed through the endpoint.
151
+ """Pushes what was committed in a workspace to a new branch, or to the branch it is
152
+ on when none is given, with the credential gitd keeps, and opens its pull request
153
+ when the publishing settings or pull_request say so. requested_by is who asked for
154
+ the work, as their account on the host. With sandbox, and path empty, publishes the
155
+ branch a sandbox pushed through the endpoint.
146
156
 
147
157
  With update, the branch may exist from an earlier publish: it is moved forward, only
148
158
  ever as a fast-forward (BRANCH_EXISTS otherwise), and the pull request open from it is
149
- updated rather than another opened. An update bringing nothing beyond what gitd
159
+ updated rather than another opened. A branch this workspace published before is
160
+ moved forward so without update. An update bringing nothing beyond what gitd
150
161
  published to the branch pushes nothing and still opens or updates the pull requests,
151
162
  so a publish whose pull request failed is retried by publishing again."""
152
163
  request: Any = messages.PublishRequest(
153
- path=path, branch=branch, requested_by=requested_by, sandbox=sandbox, update=update
164
+ path=path, branch=branch or "", requested_by=requested_by, sandbox=sandbox, update=update
154
165
  )
155
166
  if pull_request is not None:
156
167
  request.pull_request.CopyFrom(pull_request.to_message())
@@ -229,6 +240,11 @@ class Gitd:
229
240
  """Deletes a workspace; its pool stays."""
230
241
  self.connection.call(methods.REMOVE, messages.RemoveRequest(path=path))
231
242
 
243
+ def list(self) -> list[ListedWorkspace]:
244
+ """Every workspace gitd made, described, with the branches published from each."""
245
+ response = self.connection.call(methods.LIST, messages.ListRequest())
246
+ return [ListedWorkspace.from_message(listed) for listed in response.workspaces]
247
+
232
248
  def audit(
233
249
  self,
234
250
  *,
@@ -291,6 +291,10 @@
291
291
  {
292
292
  "name": "REASON_BRANCH_EXISTS",
293
293
  "number": 16
294
+ },
295
+ {
296
+ "name": "REASON_CONFLICT",
297
+ "number": 17
294
298
  }
295
299
  ]
296
300
  }
@@ -364,6 +368,13 @@
364
368
  "label": "LABEL_OPTIONAL",
365
369
  "type": "TYPE_BOOL",
366
370
  "jsonName": "poolInside"
371
+ },
372
+ {
373
+ "name": "new_branch",
374
+ "number": 10,
375
+ "label": "LABEL_OPTIONAL",
376
+ "type": "TYPE_STRING",
377
+ "jsonName": "newBranch"
367
378
  }
368
379
  ]
369
380
  },
@@ -516,6 +527,13 @@
516
527
  "type": "TYPE_MESSAGE",
517
528
  "typeName": ".gitd.v1.Credential",
518
529
  "jsonName": "credentials"
530
+ },
531
+ {
532
+ "name": "merge",
533
+ "number": 5,
534
+ "label": "LABEL_OPTIONAL",
535
+ "type": "TYPE_STRING",
536
+ "jsonName": "merge"
519
537
  }
520
538
  ]
521
539
  },
@@ -773,6 +791,49 @@
773
791
  }
774
792
  ]
775
793
  },
794
+ {
795
+ "name": "ListRequest"
796
+ },
797
+ {
798
+ "name": "ListResponse",
799
+ "field": [
800
+ {
801
+ "name": "workspaces",
802
+ "number": 1,
803
+ "label": "LABEL_REPEATED",
804
+ "type": "TYPE_MESSAGE",
805
+ "typeName": ".gitd.v1.ListedWorkspace",
806
+ "jsonName": "workspaces"
807
+ }
808
+ ]
809
+ },
810
+ {
811
+ "name": "ListedWorkspace",
812
+ "field": [
813
+ {
814
+ "name": "path",
815
+ "number": 1,
816
+ "label": "LABEL_OPTIONAL",
817
+ "type": "TYPE_STRING",
818
+ "jsonName": "path"
819
+ },
820
+ {
821
+ "name": "description",
822
+ "number": 2,
823
+ "label": "LABEL_OPTIONAL",
824
+ "type": "TYPE_MESSAGE",
825
+ "typeName": ".gitd.v1.DescribeResponse",
826
+ "jsonName": "description"
827
+ },
828
+ {
829
+ "name": "published",
830
+ "number": 3,
831
+ "label": "LABEL_REPEATED",
832
+ "type": "TYPE_STRING",
833
+ "jsonName": "published"
834
+ }
835
+ ]
836
+ },
776
837
  {
777
838
  "name": "RemoveResponse"
778
839
  },
@@ -3000,6 +3061,11 @@
3000
3061
  "inputType": ".gitd.v1.RemoveRequest",
3001
3062
  "outputType": ".gitd.v1.RemoveResponse"
3002
3063
  },
3064
+ {
3065
+ "name": "List",
3066
+ "inputType": ".gitd.v1.ListRequest",
3067
+ "outputType": ".gitd.v1.ListResponse"
3068
+ },
3003
3069
  {
3004
3070
  "name": "Adopt",
3005
3071
  "inputType": ".gitd.v1.AdoptRequest",
@@ -21,6 +21,8 @@ PublishRequest = contract.message("PublishRequest")
21
21
  PublishResponse = contract.message("PublishResponse")
22
22
  RemoveRequest = contract.message("RemoveRequest")
23
23
  RemoveResponse = contract.message("RemoveResponse")
24
+ ListRequest = contract.message("ListRequest")
25
+ ListResponse = contract.message("ListResponse")
24
26
  AuditRequest = contract.message("AuditRequest")
25
27
  AuditResponse = contract.message("AuditResponse")
26
28
  GitFailure = contract.message("GitFailure")
@@ -30,6 +30,7 @@ CHECKOUT = Method("WorkspaceService", "Checkout", messages.CheckoutResponse)
30
30
  DESCRIBE = Method("WorkspaceService", "Describe", messages.DescribeResponse)
31
31
  PUBLISH = Method("WorkspaceService", "Publish", messages.PublishResponse)
32
32
  REMOVE = Method("WorkspaceService", "Remove", messages.RemoveResponse)
33
+ LIST = Method("WorkspaceService", "List", messages.ListResponse)
33
34
  CHANGES = Method("WorkspaceService", "Changes", messages.ChangesResponse)
34
35
  DIFF = Method("WorkspaceService", "Diff", messages.DiffResponse)
35
36
  COMPARE = Method("WorkspaceService", "Compare", messages.CompareResponse)
@@ -164,6 +164,26 @@ class Description:
164
164
  )
165
165
 
166
166
 
167
+ @dataclass(frozen=True)
168
+ class ListedWorkspace:
169
+ """A workspace gitd made, what it is on disk, and the branches published from it, as
170
+ gitd recorded them. description is None when gitd could not describe it."""
171
+
172
+ path: str
173
+ description: Description | None
174
+ published: list[str] = field(default_factory=list)
175
+
176
+ @classmethod
177
+ def from_message(cls, listed: Any) -> ListedWorkspace:
178
+ return cls(
179
+ path=listed.path,
180
+ description=Description.from_message(listed.description)
181
+ if listed.HasField("description")
182
+ else None,
183
+ published=list(listed.published),
184
+ )
185
+
186
+
167
187
  @dataclass(frozen=True)
168
188
  class PublishedRepository:
169
189
  """A repository a publish pushed. path is the submodule's, empty for the workspace's own
File without changes