feat(api): add GitService.ListPaths
- commit
- cb5699451db6f6e2b51232ccea2cf1be472dbfd3
- author
- brice · · 2026-10-11 18:27 UTC
- parent
- e9394b7
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
5 files · +297 -84
M README.md +1 -1
| @@ -17,7 +17,7 @@ Handlers are mounted under `/-/api/` by the server. Errors are Connect codes. | |||
| 17 | 17 | | Service | RPCs | | |
| 18 | 18 | |---|---| | |
| 19 | 19 | | `RepoService` | `ListRepos`, `GetRepo`, `CreateRepo`, `UpdateRepo` (field mask, merge settings), `DeleteRepo` | | |
| 20 | - | | `GitService` | `ListRefs`, `GetTree`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` | | |
| 20 | + | | `GitService` | `ListRefs`, `GetTree`, `ListPaths`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` | | |
| 21 | 21 | | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` | | |
| 22 | 22 | | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest`, `MarkRead` | | |
| 23 | 23 | | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) | | |
| @@ -17,7 +17,7 @@ Handlers are mounted under `/-/api/` by the server. Errors are Connect codes. | |||||
| 17 | | Service | RPCs | | 17 | | Service | RPCs | | ||
| 18 | |---|---| | 18 | |---|---| | ||
| 19 | | `RepoService` | `ListRepos`, `GetRepo`, `CreateRepo`, `UpdateRepo` (field mask, merge settings), `DeleteRepo` | | 19 | | `RepoService` | `ListRepos`, `GetRepo`, `CreateRepo`, `UpdateRepo` (field mask, merge settings), `DeleteRepo` | | ||
| 20 | - | | `GitService` | `ListRefs`, `GetTree`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` | | 20 | + | | `GitService` | `ListRefs`, `GetTree`, `ListPaths`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` | |
| 21 | | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` | | 21 | | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` | | ||
| 22 | | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest`, `MarkRead` | | 22 | | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest`, `MarkRead` | | ||
| 23 | | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) | | 23 | | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) | | ||
M gen/ermite/ermiteconnect/git.connect.go +40 -0
| @@ -39,6 +39,8 @@ const ( | |||
| 39 | 39 | GitServiceListRefsProcedure = "/ermite.GitService/ListRefs" | |
| 40 | 40 | // GitServiceGetTreeProcedure is the fully-qualified name of the GitService's GetTree RPC. | |
| 41 | 41 | GitServiceGetTreeProcedure = "/ermite.GitService/GetTree" | |
| 42 | + | // GitServiceListPathsProcedure is the fully-qualified name of the GitService's ListPaths RPC. | |
| 43 | + | GitServiceListPathsProcedure = "/ermite.GitService/ListPaths" | |
| 42 | 44 | // GitServiceGetBlobProcedure is the fully-qualified name of the GitService's GetBlob RPC. | |
| 43 | 45 | GitServiceGetBlobProcedure = "/ermite.GitService/GetBlob" | |
| 44 | 46 | // GitServiceListCommitsProcedure is the fully-qualified name of the GitService's ListCommits RPC. | |
| @@ -59,6 +61,13 @@ type GitServiceClient interface { | |||
| 59 | 61 | // not_found if the path does not exist and invalid_argument if it is not a | |
| 60 | 62 | // directory. | |
| 61 | 63 | GetTree(context.Context, *connect.Request[ermite.GetTreeRequest]) (*connect.Response[ermite.GetTreeResponse], error) | |
| 64 | + | // ListPaths lists the paths of every file and symbolic link of a revision, | |
| 65 | + | // recursively, in Git tree order (the order of `git ls-tree -r`). Directories | |
| 66 | + | // and submodules are not listed, nor paths GetBlob cannot address (not valid | |
| 67 | + | // UTF-8, or with a control character). Fails with not_found for an unknown | |
| 68 | + | // revision or an empty repository. Servers that have it advertise the | |
| 69 | + | // feature "git.list_paths" in GetVersion. | |
| 70 | + | ListPaths(context.Context, *connect.Request[ermite.ListPathsRequest]) (*connect.Response[ermite.ListPathsResponse], error) | |
| 62 | 71 | // GetBlob streams the content of a file at a revision, in chunks of at most | |
| 63 | 72 | // 64 KiB. The first message carries the metadata in info, then the chunks | |
| 64 | 73 | // follow; the memory used by the server does not depend on the file size. | |
| @@ -99,6 +108,12 @@ func NewGitServiceClient(httpClient connect.HTTPClient, baseURL string, opts ... | |||
| 99 | 108 | connect.WithSchema(gitServiceMethods.ByName("GetTree")), | |
| 100 | 109 | connect.WithClientOptions(opts...), | |
| 101 | 110 | ), | |
| 111 | + | listPaths: connect.NewClient[ermite.ListPathsRequest, ermite.ListPathsResponse]( | |
| 112 | + | httpClient, | |
| 113 | + | baseURL+GitServiceListPathsProcedure, | |
| 114 | + | connect.WithSchema(gitServiceMethods.ByName("ListPaths")), | |
| 115 | + | connect.WithClientOptions(opts...), | |
| 116 | + | ), | |
| 102 | 117 | getBlob: connect.NewClient[ermite.GetBlobRequest, ermite.GetBlobResponse]( | |
| 103 | 118 | httpClient, | |
| 104 | 119 | baseURL+GitServiceGetBlobProcedure, | |
| @@ -130,6 +145,7 @@ func NewGitServiceClient(httpClient connect.HTTPClient, baseURL string, opts ... | |||
| 130 | 145 | type gitServiceClient struct { | |
| 131 | 146 | listRefs *connect.Client[ermite.ListRefsRequest, ermite.ListRefsResponse] | |
| 132 | 147 | getTree *connect.Client[ermite.GetTreeRequest, ermite.GetTreeResponse] | |
| 148 | + | listPaths *connect.Client[ermite.ListPathsRequest, ermite.ListPathsResponse] | |
| 133 | 149 | getBlob *connect.Client[ermite.GetBlobRequest, ermite.GetBlobResponse] | |
| 134 | 150 | listCommits *connect.Client[ermite.ListCommitsRequest, ermite.ListCommitsResponse] | |
| 135 | 151 | getCommit *connect.Client[ermite.GetCommitRequest, ermite.GetCommitResponse] | |
| @@ -146,6 +162,11 @@ func (c *gitServiceClient) GetTree(ctx context.Context, req *connect.Request[erm | |||
| 146 | 162 | return c.getTree.CallUnary(ctx, req) | |
| 147 | 163 | } | |
| 148 | 164 | ||
| 165 | + | // ListPaths calls ermite.GitService.ListPaths. | |
| 166 | + | func (c *gitServiceClient) ListPaths(ctx context.Context, req *connect.Request[ermite.ListPathsRequest]) (*connect.Response[ermite.ListPathsResponse], error) { | |
| 167 | + | return c.listPaths.CallUnary(ctx, req) | |
| 168 | + | } | |
| 169 | + | ||
| 149 | 170 | // GetBlob calls ermite.GitService.GetBlob. | |
| 150 | 171 | func (c *gitServiceClient) GetBlob(ctx context.Context, req *connect.Request[ermite.GetBlobRequest]) (*connect.ServerStreamForClient[ermite.GetBlobResponse], error) { | |
| 151 | 172 | return c.getBlob.CallServerStream(ctx, req) | |
| @@ -175,6 +196,13 @@ type GitServiceHandler interface { | |||
| 175 | 196 | // not_found if the path does not exist and invalid_argument if it is not a | |
| 176 | 197 | // directory. | |
| 177 | 198 | GetTree(context.Context, *connect.Request[ermite.GetTreeRequest]) (*connect.Response[ermite.GetTreeResponse], error) | |
| 199 | + | // ListPaths lists the paths of every file and symbolic link of a revision, | |
| 200 | + | // recursively, in Git tree order (the order of `git ls-tree -r`). Directories | |
| 201 | + | // and submodules are not listed, nor paths GetBlob cannot address (not valid | |
| 202 | + | // UTF-8, or with a control character). Fails with not_found for an unknown | |
| 203 | + | // revision or an empty repository. Servers that have it advertise the | |
| 204 | + | // feature "git.list_paths" in GetVersion. | |
| 205 | + | ListPaths(context.Context, *connect.Request[ermite.ListPathsRequest]) (*connect.Response[ermite.ListPathsResponse], error) | |
| 178 | 206 | // GetBlob streams the content of a file at a revision, in chunks of at most | |
| 179 | 207 | // 64 KiB. The first message carries the metadata in info, then the chunks | |
| 180 | 208 | // follow; the memory used by the server does not depend on the file size. | |
| @@ -211,6 +239,12 @@ func NewGitServiceHandler(svc GitServiceHandler, opts ...connect.HandlerOption) | |||
| 211 | 239 | connect.WithSchema(gitServiceMethods.ByName("GetTree")), | |
| 212 | 240 | connect.WithHandlerOptions(opts...), | |
| 213 | 241 | ) | |
| 242 | + | gitServiceListPathsHandler := connect.NewUnaryHandler( | |
| 243 | + | GitServiceListPathsProcedure, | |
| 244 | + | svc.ListPaths, | |
| 245 | + | connect.WithSchema(gitServiceMethods.ByName("ListPaths")), | |
| 246 | + | connect.WithHandlerOptions(opts...), | |
| 247 | + | ) | |
| 214 | 248 | gitServiceGetBlobHandler := connect.NewServerStreamHandler( | |
| 215 | 249 | GitServiceGetBlobProcedure, | |
| 216 | 250 | svc.GetBlob, | |
| @@ -241,6 +275,8 @@ func NewGitServiceHandler(svc GitServiceHandler, opts ...connect.HandlerOption) | |||
| 241 | 275 | gitServiceListRefsHandler.ServeHTTP(w, r) | |
| 242 | 276 | case GitServiceGetTreeProcedure: | |
| 243 | 277 | gitServiceGetTreeHandler.ServeHTTP(w, r) | |
| 278 | + | case GitServiceListPathsProcedure: | |
| 279 | + | gitServiceListPathsHandler.ServeHTTP(w, r) | |
| 244 | 280 | case GitServiceGetBlobProcedure: | |
| 245 | 281 | gitServiceGetBlobHandler.ServeHTTP(w, r) | |
| 246 | 282 | case GitServiceListCommitsProcedure: | |
| @@ -266,6 +302,10 @@ func (UnimplementedGitServiceHandler) GetTree(context.Context, *connect.Request[ | |||
| 266 | 302 | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.GitService.GetTree is not implemented")) | |
| 267 | 303 | } | |
| 268 | 304 | ||
| 305 | + | func (UnimplementedGitServiceHandler) ListPaths(context.Context, *connect.Request[ermite.ListPathsRequest]) (*connect.Response[ermite.ListPathsResponse], error) { | |
| 306 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.GitService.ListPaths is not implemented")) | |
| 307 | + | } | |
| 308 | + | ||
| 269 | 309 | func (UnimplementedGitServiceHandler) GetBlob(context.Context, *connect.Request[ermite.GetBlobRequest], *connect.ServerStream[ermite.GetBlobResponse]) error { | |
| 270 | 310 | return connect.NewError(connect.CodeUnimplemented, errors.New("ermite.GitService.GetBlob is not implemented")) | |
| 271 | 311 | } | |
| @@ -39,6 +39,8 @@ const ( | |||||
| 39 | GitServiceListRefsProcedure = "/ermite.GitService/ListRefs" | 39 | GitServiceListRefsProcedure = "/ermite.GitService/ListRefs" | ||
| 40 | // GitServiceGetTreeProcedure is the fully-qualified name of the GitService's GetTree RPC. | 40 | // GitServiceGetTreeProcedure is the fully-qualified name of the GitService's GetTree RPC. | ||
| 41 | GitServiceGetTreeProcedure = "/ermite.GitService/GetTree" | 41 | GitServiceGetTreeProcedure = "/ermite.GitService/GetTree" | ||
| 42 | + | // GitServiceListPathsProcedure is the fully-qualified name of the GitService's ListPaths RPC. | |||
| 43 | + | GitServiceListPathsProcedure = "/ermite.GitService/ListPaths" | |||
| 42 | // GitServiceGetBlobProcedure is the fully-qualified name of the GitService's GetBlob RPC. | 44 | // GitServiceGetBlobProcedure is the fully-qualified name of the GitService's GetBlob RPC. | ||
| 43 | GitServiceGetBlobProcedure = "/ermite.GitService/GetBlob" | 45 | GitServiceGetBlobProcedure = "/ermite.GitService/GetBlob" | ||
| 44 | // GitServiceListCommitsProcedure is the fully-qualified name of the GitService's ListCommits RPC. | 46 | // GitServiceListCommitsProcedure is the fully-qualified name of the GitService's ListCommits RPC. | ||
| @@ -59,6 +61,13 @@ type GitServiceClient interface { | |||||
| 59 | // not_found if the path does not exist and invalid_argument if it is not a | 61 | // not_found if the path does not exist and invalid_argument if it is not a | ||
| 60 | // directory. | 62 | // directory. | ||
| 61 | GetTree(context.Context, *connect.Request[ermite.GetTreeRequest]) (*connect.Response[ermite.GetTreeResponse], error) | 63 | GetTree(context.Context, *connect.Request[ermite.GetTreeRequest]) (*connect.Response[ermite.GetTreeResponse], error) | ||
| 64 | + | // ListPaths lists the paths of every file and symbolic link of a revision, | |||
| 65 | + | // recursively, in Git tree order (the order of `git ls-tree -r`). Directories | |||
| 66 | + | // and submodules are not listed, nor paths GetBlob cannot address (not valid | |||
| 67 | + | // UTF-8, or with a control character). Fails with not_found for an unknown | |||
| 68 | + | // revision or an empty repository. Servers that have it advertise the | |||
| 69 | + | // feature "git.list_paths" in GetVersion. | |||
| 70 | + | ListPaths(context.Context, *connect.Request[ermite.ListPathsRequest]) (*connect.Response[ermite.ListPathsResponse], error) | |||
| 62 | // GetBlob streams the content of a file at a revision, in chunks of at most | 71 | // GetBlob streams the content of a file at a revision, in chunks of at most | ||
| 63 | // 64 KiB. The first message carries the metadata in info, then the chunks | 72 | // 64 KiB. The first message carries the metadata in info, then the chunks | ||
| 64 | // follow; the memory used by the server does not depend on the file size. | 73 | // follow; the memory used by the server does not depend on the file size. | ||
| @@ -99,6 +108,12 @@ func NewGitServiceClient(httpClient connect.HTTPClient, baseURL string, opts ... | |||||
| 99 | connect.WithSchema(gitServiceMethods.ByName("GetTree")), | 108 | connect.WithSchema(gitServiceMethods.ByName("GetTree")), | ||
| 100 | connect.WithClientOptions(opts...), | 109 | connect.WithClientOptions(opts...), | ||
| 101 | ), | 110 | ), | ||
| 111 | + | listPaths: connect.NewClient[ermite.ListPathsRequest, ermite.ListPathsResponse]( | |||
| 112 | + | httpClient, | |||
| 113 | + | baseURL+GitServiceListPathsProcedure, | |||
| 114 | + | connect.WithSchema(gitServiceMethods.ByName("ListPaths")), | |||
| 115 | + | connect.WithClientOptions(opts...), | |||
| 116 | + | ), | |||
| 102 | getBlob: connect.NewClient[ermite.GetBlobRequest, ermite.GetBlobResponse]( | 117 | getBlob: connect.NewClient[ermite.GetBlobRequest, ermite.GetBlobResponse]( | ||
| 103 | httpClient, | 118 | httpClient, | ||
| 104 | baseURL+GitServiceGetBlobProcedure, | 119 | baseURL+GitServiceGetBlobProcedure, | ||
| @@ -130,6 +145,7 @@ func NewGitServiceClient(httpClient connect.HTTPClient, baseURL string, opts ... | |||||
| 130 | type gitServiceClient struct { | 145 | type gitServiceClient struct { | ||
| 131 | listRefs *connect.Client[ermite.ListRefsRequest, ermite.ListRefsResponse] | 146 | listRefs *connect.Client[ermite.ListRefsRequest, ermite.ListRefsResponse] | ||
| 132 | getTree *connect.Client[ermite.GetTreeRequest, ermite.GetTreeResponse] | 147 | getTree *connect.Client[ermite.GetTreeRequest, ermite.GetTreeResponse] | ||
| 148 | + | listPaths *connect.Client[ermite.ListPathsRequest, ermite.ListPathsResponse] | |||
| 133 | getBlob *connect.Client[ermite.GetBlobRequest, ermite.GetBlobResponse] | 149 | getBlob *connect.Client[ermite.GetBlobRequest, ermite.GetBlobResponse] | ||
| 134 | listCommits *connect.Client[ermite.ListCommitsRequest, ermite.ListCommitsResponse] | 150 | listCommits *connect.Client[ermite.ListCommitsRequest, ermite.ListCommitsResponse] | ||
| 135 | getCommit *connect.Client[ermite.GetCommitRequest, ermite.GetCommitResponse] | 151 | getCommit *connect.Client[ermite.GetCommitRequest, ermite.GetCommitResponse] | ||
| @@ -146,6 +162,11 @@ func (c *gitServiceClient) GetTree(ctx context.Context, req *connect.Request[erm | |||||
| 146 | return c.getTree.CallUnary(ctx, req) | 162 | return c.getTree.CallUnary(ctx, req) | ||
| 147 | } | 163 | } | ||
| 148 | 164 | ||||
| 165 | + | // ListPaths calls ermite.GitService.ListPaths. | |||
| 166 | + | func (c *gitServiceClient) ListPaths(ctx context.Context, req *connect.Request[ermite.ListPathsRequest]) (*connect.Response[ermite.ListPathsResponse], error) { | |||
| 167 | + | return c.listPaths.CallUnary(ctx, req) | |||
| 168 | + | } | |||
| 169 | + | ||||
| 149 | // GetBlob calls ermite.GitService.GetBlob. | 170 | // GetBlob calls ermite.GitService.GetBlob. | ||
| 150 | func (c *gitServiceClient) GetBlob(ctx context.Context, req *connect.Request[ermite.GetBlobRequest]) (*connect.ServerStreamForClient[ermite.GetBlobResponse], error) { | 171 | func (c *gitServiceClient) GetBlob(ctx context.Context, req *connect.Request[ermite.GetBlobRequest]) (*connect.ServerStreamForClient[ermite.GetBlobResponse], error) { | ||
| 151 | return c.getBlob.CallServerStream(ctx, req) | 172 | return c.getBlob.CallServerStream(ctx, req) | ||
| @@ -175,6 +196,13 @@ type GitServiceHandler interface { | |||||
| 175 | // not_found if the path does not exist and invalid_argument if it is not a | 196 | // not_found if the path does not exist and invalid_argument if it is not a | ||
| 176 | // directory. | 197 | // directory. | ||
| 177 | GetTree(context.Context, *connect.Request[ermite.GetTreeRequest]) (*connect.Response[ermite.GetTreeResponse], error) | 198 | GetTree(context.Context, *connect.Request[ermite.GetTreeRequest]) (*connect.Response[ermite.GetTreeResponse], error) | ||
| 199 | + | // ListPaths lists the paths of every file and symbolic link of a revision, | |||
| 200 | + | // recursively, in Git tree order (the order of `git ls-tree -r`). Directories | |||
| 201 | + | // and submodules are not listed, nor paths GetBlob cannot address (not valid | |||
| 202 | + | // UTF-8, or with a control character). Fails with not_found for an unknown | |||
| 203 | + | // revision or an empty repository. Servers that have it advertise the | |||
| 204 | + | // feature "git.list_paths" in GetVersion. | |||
| 205 | + | ListPaths(context.Context, *connect.Request[ermite.ListPathsRequest]) (*connect.Response[ermite.ListPathsResponse], error) | |||
| 178 | // GetBlob streams the content of a file at a revision, in chunks of at most | 206 | // GetBlob streams the content of a file at a revision, in chunks of at most | ||
| 179 | // 64 KiB. The first message carries the metadata in info, then the chunks | 207 | // 64 KiB. The first message carries the metadata in info, then the chunks | ||
| 180 | // follow; the memory used by the server does not depend on the file size. | 208 | // follow; the memory used by the server does not depend on the file size. | ||
| @@ -211,6 +239,12 @@ func NewGitServiceHandler(svc GitServiceHandler, opts ...connect.HandlerOption) | |||||
| 211 | connect.WithSchema(gitServiceMethods.ByName("GetTree")), | 239 | connect.WithSchema(gitServiceMethods.ByName("GetTree")), | ||
| 212 | connect.WithHandlerOptions(opts...), | 240 | connect.WithHandlerOptions(opts...), | ||
| 213 | ) | 241 | ) | ||
| 242 | + | gitServiceListPathsHandler := connect.NewUnaryHandler( | |||
| 243 | + | GitServiceListPathsProcedure, | |||
| 244 | + | svc.ListPaths, | |||
| 245 | + | connect.WithSchema(gitServiceMethods.ByName("ListPaths")), | |||
| 246 | + | connect.WithHandlerOptions(opts...), | |||
| 247 | + | ) | |||
| 214 | gitServiceGetBlobHandler := connect.NewServerStreamHandler( | 248 | gitServiceGetBlobHandler := connect.NewServerStreamHandler( | ||
| 215 | GitServiceGetBlobProcedure, | 249 | GitServiceGetBlobProcedure, | ||
| 216 | svc.GetBlob, | 250 | svc.GetBlob, | ||
| @@ -241,6 +275,8 @@ func NewGitServiceHandler(svc GitServiceHandler, opts ...connect.HandlerOption) | |||||
| 241 | gitServiceListRefsHandler.ServeHTTP(w, r) | 275 | gitServiceListRefsHandler.ServeHTTP(w, r) | ||
| 242 | case GitServiceGetTreeProcedure: | 276 | case GitServiceGetTreeProcedure: | ||
| 243 | gitServiceGetTreeHandler.ServeHTTP(w, r) | 277 | gitServiceGetTreeHandler.ServeHTTP(w, r) | ||
| 278 | + | case GitServiceListPathsProcedure: | |||
| 279 | + | gitServiceListPathsHandler.ServeHTTP(w, r) | |||
| 244 | case GitServiceGetBlobProcedure: | 280 | case GitServiceGetBlobProcedure: | ||
| 245 | gitServiceGetBlobHandler.ServeHTTP(w, r) | 281 | gitServiceGetBlobHandler.ServeHTTP(w, r) | ||
| 246 | case GitServiceListCommitsProcedure: | 282 | case GitServiceListCommitsProcedure: | ||
| @@ -266,6 +302,10 @@ func (UnimplementedGitServiceHandler) GetTree(context.Context, *connect.Request[ | |||||
| 266 | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.GitService.GetTree is not implemented")) | 302 | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.GitService.GetTree is not implemented")) | ||
| 267 | } | 303 | } | ||
| 268 | 304 | ||||
| 305 | + | func (UnimplementedGitServiceHandler) ListPaths(context.Context, *connect.Request[ermite.ListPathsRequest]) (*connect.Response[ermite.ListPathsResponse], error) { | |||
| 306 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.GitService.ListPaths is not implemented")) | |||
| 307 | + | } | |||
| 308 | + | ||||
| 269 | func (UnimplementedGitServiceHandler) GetBlob(context.Context, *connect.Request[ermite.GetBlobRequest], *connect.ServerStream[ermite.GetBlobResponse]) error { | 309 | func (UnimplementedGitServiceHandler) GetBlob(context.Context, *connect.Request[ermite.GetBlobRequest], *connect.ServerStream[ermite.GetBlobResponse]) error { | ||
| 270 | return connect.NewError(connect.CodeUnimplemented, errors.New("ermite.GitService.GetBlob is not implemented")) | 310 | return connect.NewError(connect.CodeUnimplemented, errors.New("ermite.GitService.GetBlob is not implemented")) | ||
| 271 | } | 311 | } | ||
M gen/ermite/git.pb.go +226 -83 generated file: collapsed
M gen_test.go +1 -0
| @@ -22,6 +22,7 @@ func TestProcedures(t *testing.T) { | |||
| 22 | 22 | {ermiteconnect.RepoServiceDeleteRepoProcedure, "/ermite.RepoService/DeleteRepo"}, | |
| 23 | 23 | {ermiteconnect.GitServiceListRefsProcedure, "/ermite.GitService/ListRefs"}, | |
| 24 | 24 | {ermiteconnect.GitServiceGetTreeProcedure, "/ermite.GitService/GetTree"}, | |
| 25 | + | {ermiteconnect.GitServiceListPathsProcedure, "/ermite.GitService/ListPaths"}, | |
| 25 | 26 | {ermiteconnect.GitServiceGetBlobProcedure, "/ermite.GitService/GetBlob"}, | |
| 26 | 27 | {ermiteconnect.GitServiceListCommitsProcedure, "/ermite.GitService/ListCommits"}, | |
| 27 | 28 | {ermiteconnect.GitServiceGetCommitProcedure, "/ermite.GitService/GetCommit"}, | |
| @@ -22,6 +22,7 @@ func TestProcedures(t *testing.T) { | |||||
| 22 | {ermiteconnect.RepoServiceDeleteRepoProcedure, "/ermite.RepoService/DeleteRepo"}, | 22 | {ermiteconnect.RepoServiceDeleteRepoProcedure, "/ermite.RepoService/DeleteRepo"}, | ||
| 23 | {ermiteconnect.GitServiceListRefsProcedure, "/ermite.GitService/ListRefs"}, | 23 | {ermiteconnect.GitServiceListRefsProcedure, "/ermite.GitService/ListRefs"}, | ||
| 24 | {ermiteconnect.GitServiceGetTreeProcedure, "/ermite.GitService/GetTree"}, | 24 | {ermiteconnect.GitServiceGetTreeProcedure, "/ermite.GitService/GetTree"}, | ||
| 25 | + | {ermiteconnect.GitServiceListPathsProcedure, "/ermite.GitService/ListPaths"}, | |||
| 25 | {ermiteconnect.GitServiceGetBlobProcedure, "/ermite.GitService/GetBlob"}, | 26 | {ermiteconnect.GitServiceGetBlobProcedure, "/ermite.GitService/GetBlob"}, | ||
| 26 | {ermiteconnect.GitServiceListCommitsProcedure, "/ermite.GitService/ListCommits"}, | 27 | {ermiteconnect.GitServiceListCommitsProcedure, "/ermite.GitService/ListCommits"}, | ||
| 27 | {ermiteconnect.GitServiceGetCommitProcedure, "/ermite.GitService/GetCommit"}, | 28 | {ermiteconnect.GitServiceGetCommitProcedure, "/ermite.GitService/GetCommit"}, | ||
M proto/ermite/git.proto +29 -0
| @@ -81,6 +81,13 @@ service GitService { | |||
| 81 | 81 | // not_found if the path does not exist and invalid_argument if it is not a | |
| 82 | 82 | // directory. | |
| 83 | 83 | rpc GetTree(GetTreeRequest) returns (GetTreeResponse); | |
| 84 | + | // ListPaths lists the paths of every file and symbolic link of a revision, | |
| 85 | + | // recursively, in Git tree order (the order of `git ls-tree -r`). Directories | |
| 86 | + | // and submodules are not listed, nor paths GetBlob cannot address (not valid | |
| 87 | + | // UTF-8, or with a control character). Fails with not_found for an unknown | |
| 88 | + | // revision or an empty repository. Servers that have it advertise the | |
| 89 | + | // feature "git.list_paths" in GetVersion. | |
| 90 | + | rpc ListPaths(ListPathsRequest) returns (ListPathsResponse); | |
| 84 | 91 | // GetBlob streams the content of a file at a revision, in chunks of at most | |
| 85 | 92 | // 64 KiB. The first message carries the metadata in info, then the chunks | |
| 86 | 93 | // follow; the memory used by the server does not depend on the file size. | |
| @@ -199,6 +206,28 @@ message GetTreeResponse { | |||
| 199 | 206 | bool truncated = 5; | |
| 200 | 207 | } | |
| 201 | 208 | ||
| 209 | + | // ListPathsRequest selects a revision. | |
| 210 | + | message ListPathsRequest { | |
| 211 | + | // Repo is the repository name. | |
| 212 | + | string repo = 1; | |
| 213 | + | // Revision is a branch, a tag or a commit id. Empty means HEAD. | |
| 214 | + | string revision = 2; | |
| 215 | + | } | |
| 216 | + | ||
| 217 | + | // ListPathsResponse lists the file paths of a revision. | |
| 218 | + | message ListPathsResponse { | |
| 219 | + | // CommitId is the id of the commit the revision resolved to. | |
| 220 | + | string commit_id = 1; | |
| 221 | + | // TreeId is the object id of its root tree. | |
| 222 | + | string tree_id = 2; | |
| 223 | + | // Paths are the paths of the files and symbolic links, in Git tree order. A | |
| 224 | + | // response holds at most 100,000 paths and 8 MiB of path bytes (server limits | |
| 225 | + | // that may change; rely on truncated, not on the numbers). | |
| 226 | + | repeated string paths = 3; | |
| 227 | + | // Truncated is true when more paths exist past the first ones returned. | |
| 228 | + | bool truncated = 4; | |
| 229 | + | } | |
| 230 | + | ||
| 202 | 231 | // BlobInfo describes a file. | |
| 203 | 232 | message BlobInfo { | |
| 204 | 233 | // Id is the object id of the blob. | |
| @@ -81,6 +81,13 @@ service GitService { | |||||
| 81 | // not_found if the path does not exist and invalid_argument if it is not a | 81 | // not_found if the path does not exist and invalid_argument if it is not a | ||
| 82 | // directory. | 82 | // directory. | ||
| 83 | rpc GetTree(GetTreeRequest) returns (GetTreeResponse); | 83 | rpc GetTree(GetTreeRequest) returns (GetTreeResponse); | ||
| 84 | + | // ListPaths lists the paths of every file and symbolic link of a revision, | |||
| 85 | + | // recursively, in Git tree order (the order of `git ls-tree -r`). Directories | |||
| 86 | + | // and submodules are not listed, nor paths GetBlob cannot address (not valid | |||
| 87 | + | // UTF-8, or with a control character). Fails with not_found for an unknown | |||
| 88 | + | // revision or an empty repository. Servers that have it advertise the | |||
| 89 | + | // feature "git.list_paths" in GetVersion. | |||
| 90 | + | rpc ListPaths(ListPathsRequest) returns (ListPathsResponse); | |||
| 84 | // GetBlob streams the content of a file at a revision, in chunks of at most | 91 | // GetBlob streams the content of a file at a revision, in chunks of at most | ||
| 85 | // 64 KiB. The first message carries the metadata in info, then the chunks | 92 | // 64 KiB. The first message carries the metadata in info, then the chunks | ||
| 86 | // follow; the memory used by the server does not depend on the file size. | 93 | // follow; the memory used by the server does not depend on the file size. | ||
| @@ -199,6 +206,28 @@ message GetTreeResponse { | |||||
| 199 | bool truncated = 5; | 206 | bool truncated = 5; | ||
| 200 | } | 207 | } | ||
| 201 | 208 | ||||
| 209 | + | // ListPathsRequest selects a revision. | |||
| 210 | + | message ListPathsRequest { | |||
| 211 | + | // Repo is the repository name. | |||
| 212 | + | string repo = 1; | |||
| 213 | + | // Revision is a branch, a tag or a commit id. Empty means HEAD. | |||
| 214 | + | string revision = 2; | |||
| 215 | + | } | |||
| 216 | + | ||||
| 217 | + | // ListPathsResponse lists the file paths of a revision. | |||
| 218 | + | message ListPathsResponse { | |||
| 219 | + | // CommitId is the id of the commit the revision resolved to. | |||
| 220 | + | string commit_id = 1; | |||
| 221 | + | // TreeId is the object id of its root tree. | |||
| 222 | + | string tree_id = 2; | |||
| 223 | + | // Paths are the paths of the files and symbolic links, in Git tree order. A | |||
| 224 | + | // response holds at most 100,000 paths and 8 MiB of path bytes (server limits | |||
| 225 | + | // that may change; rely on truncated, not on the numbers). | |||
| 226 | + | repeated string paths = 3; | |||
| 227 | + | // Truncated is true when more paths exist past the first ones returned. | |||
| 228 | + | bool truncated = 4; | |||
| 229 | + | } | |||
| 230 | + | ||||
| 202 | // BlobInfo describes a file. | 231 | // BlobInfo describes a file. | ||
| 203 | message BlobInfo { | 232 | message BlobInfo { | ||
| 204 | // Id is the object id of the blob. | 233 | // Id is the object id of the blob. | ||