+130
-85
appview/pulls/pulls.go
+130
-85
appview/pulls/pulls.go
···
2
2
3
3
import (
4
4
"database/sql"
5
-
"encoding/json"
6
5
"errors"
7
6
"fmt"
8
-
"io"
9
7
"log"
10
8
"net/http"
11
9
"sort"
···
96
94
return
97
95
}
98
96
99
-
mergeCheckResponse := s.mergeCheck(f, pull, stack)
97
+
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
100
98
resubmitResult := pages.Unknown
101
99
if user.Did == pull.OwnerDid {
102
100
resubmitResult = s.resubmitCheck(f, pull, stack)
···
151
149
}
152
150
}
153
151
154
-
mergeCheckResponse := s.mergeCheck(f, pull, stack)
152
+
mergeCheckResponse := s.mergeCheck(r, f, pull, stack)
155
153
resubmitResult := pages.Unknown
156
154
if user != nil && user.Did == pull.OwnerDid {
157
155
resubmitResult = s.resubmitCheck(f, pull, stack)
···
215
213
})
216
214
}
217
215
218
-
func (s *Pulls) mergeCheck(f *reporesolver.ResolvedRepo, pull *db.Pull, stack db.Stack) types.MergeCheckResponse {
216
+
func (s *Pulls) mergeCheck(r *http.Request, f *reporesolver.ResolvedRepo, pull *db.Pull, stack db.Stack) types.MergeCheckResponse {
219
217
if pull.State == db.PullMerged {
220
218
return types.MergeCheckResponse{}
221
219
}
222
220
223
-
secret, err := db.GetRegistrationKey(s.db, f.Knot)
224
-
if err != nil {
225
-
log.Printf("failed to get registration key: %v", err)
226
-
return types.MergeCheckResponse{
227
-
Error: "failed to check merge status: this knot is unregistered",
228
-
}
229
-
}
230
-
231
-
ksClient, err := knotclient.NewSignedClient(f.Knot, secret, s.config.Core.Dev)
221
+
client, err := s.oauth.ServiceClient(
222
+
r,
223
+
oauth.WithService(f.Knot),
224
+
oauth.WithLxm(tangled.RepoMergeCheckNSID),
225
+
oauth.WithDev(s.config.Core.Dev),
226
+
)
232
227
if err != nil {
233
-
log.Printf("failed to setup signed client for %s; ignoring: %v", f.Knot, err)
228
+
log.Printf("failed to connect to knot server: %v", err)
234
229
return types.MergeCheckResponse{
235
-
Error: "failed to check merge status",
230
+
Error: "failed to check merge status: could not connect to knot server",
236
231
}
237
232
}
238
233
···
246
241
patch = mergeable.CombinedPatch()
247
242
}
248
243
249
-
resp, err := ksClient.MergeCheck([]byte(patch), f.OwnerDid(), f.Name, pull.TargetBranch)
250
-
if err != nil {
251
-
log.Println("failed to check for mergeability:", err)
244
+
resp, xe := tangled.RepoMergeCheck(
245
+
r.Context(),
246
+
&xrpcc,
247
+
&tangled.RepoMergeCheck_Input{
248
+
Did: f.OwnerDid(),
249
+
Name: f.Name,
250
+
Branch: pull.TargetBranch,
251
+
Patch: patch,
252
+
},
253
+
)
254
+
if err := xrpcclient.HandleXrpcErr(xe); err != nil {
255
+
log.Println("failed to check for mergeability", "err", err)
252
256
return types.MergeCheckResponse{
253
-
Error: "failed to check merge status",
257
+
Error: fmt.Sprintf("failed to check merge status: %s", err.Error()),
254
258
}
255
259
}
256
-
switch resp.StatusCode {
257
-
case 404:
258
-
return types.MergeCheckResponse{
259
-
Error: "failed to check merge status: this knot does not support PRs",
260
-
}
261
-
case 400:
262
-
return types.MergeCheckResponse{
263
-
Error: "failed to check merge status: does this knot support PRs?",
260
+
261
+
// convert xrpc response to internal types
262
+
conflicts := make([]types.ConflictInfo, len(resp.Conflicts))
263
+
for i, conflict := range resp.Conflicts {
264
+
conflicts[i] = types.ConflictInfo{
265
+
Filename: conflict.Filename,
266
+
Reason: conflict.Reason,
264
267
}
265
268
}
266
269
267
-
respBody, err := io.ReadAll(resp.Body)
268
-
if err != nil {
269
-
log.Println("failed to read merge check response body")
270
-
return types.MergeCheckResponse{
271
-
Error: "failed to check merge status: knot is not speaking the right language",
272
-
}
270
+
result := types.MergeCheckResponse{
271
+
IsConflicted: resp.Is_conflicted,
272
+
Conflicts: conflicts,
273
+
}
274
+
275
+
if resp.Message != nil {
276
+
result.Message = *resp.Message
273
277
}
274
-
defer resp.Body.Close()
275
278
276
-
var mergeCheckResponse types.MergeCheckResponse
277
-
err = json.Unmarshal(respBody, &mergeCheckResponse)
278
-
if err != nil {
279
-
log.Println("failed to unmarshal merge check response", err)
280
-
return types.MergeCheckResponse{
281
-
Error: "failed to check merge status: knot is not speaking the right language",
282
-
}
279
+
if resp.Error != nil {
280
+
result.Error = *resp.Error
283
281
}
284
282
285
-
return mergeCheckResponse
283
+
return result
286
284
}
287
285
288
286
func (s *Pulls) resubmitCheck(f *reporesolver.ResolvedRepo, pull *db.Pull, stack db.Stack) pages.ResubmitResult {
···
867
865
return
868
866
}
869
867
870
-
secret, err := db.GetRegistrationKey(s.db, fork.Knot)
871
-
if err != nil {
872
-
log.Println("failed to fetch registration key:", err)
873
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
874
-
return
875
-
}
876
-
877
-
sc, err := knotclient.NewSignedClient(fork.Knot, secret, s.config.Core.Dev)
868
+
client, err := s.oauth.ServiceClient(
869
+
r,
870
+
oauth.WithService(fork.Knot),
871
+
oauth.WithLxm(tangled.RepoHiddenRefNSID),
872
+
oauth.WithDev(s.config.Core.Dev),
873
+
)
878
874
if err != nil {
879
-
log.Println("failed to create signed client:", err)
875
+
log.Printf("failed to connect to knot server: %v", err)
880
876
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
881
877
return
882
878
}
···
888
884
return
889
885
}
890
886
891
-
resp, err := sc.NewHiddenRef(user.Did, fork.Name, sourceBranch, targetBranch)
887
+
resp, err := tangled.RepoHiddenRef(
888
+
r.Context(),
889
+
client,
890
+
&tangled.RepoHiddenRef_Input{
891
+
ForkRef: sourceBranch,
892
+
RemoteRef: targetBranch,
893
+
Repo: fork.RepoAt().String(),
894
+
},
895
+
)
892
896
if err != nil {
893
-
log.Println("failed to create hidden ref:", err, resp.StatusCode)
894
-
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
897
+
xe, parseErr := xrpcerr.Unmarshal(err.Error())
898
+
if parseErr != nil {
899
+
log.Printf("failed to create hidden ref: %v", err)
900
+
s.pages.Notice(w, "pull", "Failed to create pull request. Try again later.")
901
+
} else {
902
+
log.Printf("failed to create hidden ref: %s", xe.Error())
903
+
if xe.Tag == "AccessControl" {
904
+
s.pages.Notice(w, "pull", "Branch based pull requests are not supported on this knot.")
905
+
} else {
906
+
s.pages.Notice(w, "pull", fmt.Sprintf("Failed to create pull request: %s", xe.Message))
907
+
}
908
+
}
895
909
return
896
910
}
897
911
898
-
switch resp.StatusCode {
899
-
case 404:
900
-
case 400:
901
-
s.pages.Notice(w, "pull", "Branch based pull requests are not supported on this knot.")
912
+
if !resp.Success {
913
+
errorMsg := "Failed to create pull request"
914
+
if resp.Error != nil {
915
+
errorMsg = fmt.Sprintf("Failed to create pull request: %s", *resp.Error)
916
+
}
917
+
s.pages.Notice(w, "pull", errorMsg)
902
918
return
903
919
}
904
920
···
1464
1480
return
1465
1481
}
1466
1482
1467
-
secret, err := db.GetRegistrationKey(s.db, forkRepo.Knot)
1468
-
if err != nil {
1469
-
log.Printf("failed to get registration key for %s: %s", forkRepo.Knot, err)
1470
-
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1471
-
return
1472
-
}
1473
-
1474
1483
// update the hidden tracking branch to latest
1475
-
signedClient, err := knotclient.NewSignedClient(forkRepo.Knot, secret, s.config.Core.Dev)
1484
+
client, err := s.oauth.ServiceClient(
1485
+
r,
1486
+
oauth.WithService(forkRepo.Knot),
1487
+
oauth.WithLxm(tangled.RepoHiddenRefNSID),
1488
+
oauth.WithDev(s.config.Core.Dev),
1489
+
)
1476
1490
if err != nil {
1477
-
log.Printf("failed to create signed client for %s: %s", forkRepo.Knot, err)
1478
-
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1491
+
log.Printf("failed to connect to knot server: %v", err)
1479
1492
return
1480
1493
}
1481
1494
1482
-
resp, err := signedClient.NewHiddenRef(forkRepo.Did, forkRepo.Name, pull.PullSource.Branch, pull.TargetBranch)
1483
-
if err != nil || resp.StatusCode != http.StatusNoContent {
1484
-
log.Printf("failed to update tracking branch: %s", err)
1495
+
resp, err := tangled.RepoHiddenRef(
1496
+
r.Context(),
1497
+
client,
1498
+
&tangled.RepoHiddenRef_Input{
1499
+
ForkRef: pull.PullSource.Branch,
1500
+
RemoteRef: pull.TargetBranch,
1501
+
Repo: forkRepo.RepoAt().String(),
1502
+
},
1503
+
)
1504
+
if err != nil || !resp.Success {
1505
+
if err != nil {
1506
+
log.Printf("failed to update tracking branch: %s", err)
1507
+
} else {
1508
+
log.Printf("failed to update tracking branch: success=false")
1509
+
}
1485
1510
s.pages.Notice(w, "resubmit-error", "Failed to create pull request. Try again later.")
1486
1511
return
1487
1512
}
···
1908
1933
1909
1934
patch := pullsToMerge.CombinedPatch()
1910
1935
1911
-
secret, err := db.GetRegistrationKey(s.db, f.Knot)
1936
+
client, err := s.oauth.ServiceClient(
1937
+
r,
1938
+
oauth.WithService(f.Knot),
1939
+
oauth.WithLxm(tangled.RepoMergeNSID),
1940
+
oauth.WithDev(s.config.Core.Dev),
1941
+
)
1912
1942
if err != nil {
1913
-
log.Printf("no registration key found for domain %s: %s\n", f.Knot, err)
1943
+
log.Printf("failed to connect to knot server: %v", err)
1914
1944
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
1915
1945
return
1916
1946
}
···
1927
1957
log.Printf("failed to get primary email: %s", err)
1928
1958
}
1929
1959
1930
-
ksClient, err := knotclient.NewSignedClient(f.Knot, secret, s.config.Core.Dev)
1931
-
if err != nil {
1932
-
log.Printf("failed to create signed client for %s: %s", f.Knot, err)
1933
-
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
1934
-
return
1960
+
authorName := ident.Handle.String()
1961
+
mergeInput := &tangled.RepoMerge_Input{
1962
+
Did: f.OwnerDid(),
1963
+
Name: f.Name,
1964
+
Branch: pull.TargetBranch,
1965
+
Patch: patch,
1966
+
CommitMessage: &pull.Title,
1967
+
AuthorName: &authorName,
1935
1968
}
1936
1969
1937
-
// Merge the pull request
1938
-
resp, err := ksClient.Merge([]byte(patch), f.OwnerDid(), f.Name, pull.TargetBranch, pull.Title, pull.Body, ident.Handle.String(), email.Address)
1970
+
if pull.Body != "" {
1971
+
mergeInput.CommitBody = &pull.Body
1972
+
}
1973
+
1974
+
if email.Address != "" {
1975
+
mergeInput.AuthorEmail = &email.Address
1976
+
}
1977
+
1978
+
client, err := s.oauth.ServiceClient(
1979
+
r,
1980
+
oauth.WithService(f.Knot),
1981
+
oauth.WithLxm(tangled.RepoMergeNSID),
1982
+
oauth.WithDev(s.config.Core.Dev),
1983
+
)
1939
1984
if err != nil {
1940
-
log.Printf("failed to merge pull request: %s", err)
1985
+
log.Printf("failed to connect to knot server: %v", err)
1941
1986
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
1942
1987
return
1943
1988
}
1944
1989
1945
-
if resp.StatusCode != http.StatusOK {
1946
-
log.Printf("knotserver returned non-OK status code for merge: %d", resp.StatusCode)
1947
-
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
1990
+
err = tangled.RepoMerge(r.Context(), client, mergeInput)
1991
+
if err := xrpcclient.HandleXrpcErr(err); err != nil {
1992
+
s.pages.Notice(w, "pull-merge-error", err.Error())
1948
1993
return
1949
1994
}
1950
1995
+28
-4
appview/repo/index.go
+28
-4
appview/repo/index.go
···
119
119
120
120
var forkInfo *types.ForkInfo
121
121
if user != nil && (repoInfo.Roles.IsOwner() || repoInfo.Roles.IsCollaborator()) {
122
-
forkInfo, err = getForkInfo(repoInfo, rp, f, result.Ref, user, signedClient)
122
+
forkInfo, err = getForkInfo(r, repoInfo, rp, f, result.Ref, user, signedClient)
123
123
if err != nil {
124
124
log.Printf("Failed to fetch fork information: %v", err)
125
125
return
···
233
233
}
234
234
235
235
func getForkInfo(
236
+
r *http.Request,
236
237
repoInfo repoinfo.RepoInfo,
237
238
rp *Repo,
238
239
f *reporesolver.ResolvedRepo,
···
273
274
return &forkInfo, nil
274
275
}
275
276
276
-
newHiddenRefResp, err := signedClient.NewHiddenRef(user.Did, repoInfo.Name, currentRef, currentRef)
277
-
if err != nil || newHiddenRefResp.StatusCode != http.StatusNoContent {
278
-
log.Printf("failed to update tracking branch: %s", err)
277
+
client, err := rp.oauth.ServiceClient(
278
+
r,
279
+
oauth.WithService(f.Knot),
280
+
oauth.WithLxm(tangled.RepoHiddenRefNSID),
281
+
oauth.WithDev(rp.config.Core.Dev),
282
+
)
283
+
if err != nil {
284
+
log.Printf("failed to connect to knot server: %v", err)
279
285
return nil, err
286
+
}
287
+
288
+
resp, err := tangled.RepoHiddenRef(
289
+
r.Context(),
290
+
client,
291
+
&tangled.RepoHiddenRef_Input{
292
+
ForkRef: currentRef,
293
+
RemoteRef: currentRef,
294
+
Repo: f.RepoAt().String(),
295
+
},
296
+
)
297
+
if err != nil || !resp.Success {
298
+
if err != nil {
299
+
log.Printf("failed to update tracking branch: %s", err)
300
+
} else {
301
+
log.Printf("failed to update tracking branch: success=false")
302
+
}
303
+
return nil, fmt.Errorf("failed to update tracking branch")
280
304
}
281
305
282
306
hiddenRef := fmt.Sprintf("hidden/%s/%s", currentRef, currentRef)
+99
-67
appview/repo/repo.go
+99
-67
appview/repo/repo.go
···
17
17
"strings"
18
18
"time"
19
19
20
+
comatproto "github.com/bluesky-social/indigo/api/atproto"
21
+
lexutil "github.com/bluesky-social/indigo/lex/util"
20
22
"tangled.sh/tangled.sh/core/api/tangled"
21
23
"tangled.sh/tangled.sh/core/appview/commitverify"
22
24
"tangled.sh/tangled.sh/core/appview/config"
···
33
35
"tangled.sh/tangled.sh/core/rbac"
34
36
"tangled.sh/tangled.sh/core/tid"
35
37
"tangled.sh/tangled.sh/core/types"
38
+
"tangled.sh/tangled.sh/core/xrpc/serviceauth"
36
39
37
40
securejoin "github.com/cyphar/filepath-securejoin"
38
41
"github.com/go-chi/chi/v5"
39
42
"github.com/go-git/go-git/v5/plumbing"
40
43
41
-
comatproto "github.com/bluesky-social/indigo/api/atproto"
42
44
"github.com/bluesky-social/indigo/atproto/syntax"
43
-
lexutil "github.com/bluesky-social/indigo/lex/util"
44
45
)
45
46
46
47
type Repo struct {
···
54
55
enforcer *rbac.Enforcer
55
56
notifier notify.Notifier
56
57
logger *slog.Logger
58
+
serviceAuth *serviceauth.ServiceAuth
57
59
}
58
60
59
61
func New(
···
960
962
}
961
963
log.Println("removed repo record ", f.RepoAt().String())
962
964
963
-
secret, err := db.GetRegistrationKey(rp.db, f.Knot)
965
+
client, err := rp.oauth.ServiceClient(
966
+
r,
967
+
oauth.WithService(f.Knot),
968
+
oauth.WithLxm(tangled.RepoDeleteNSID),
969
+
oauth.WithDev(rp.config.Core.Dev),
970
+
)
964
971
if err != nil {
965
-
log.Printf("no key found for domain %s: %s\n", f.Knot, err)
972
+
log.Println("failed to connect to knot server:", err)
966
973
return
967
974
}
968
975
969
-
ksClient, err := knotclient.NewSignedClient(f.Knot, secret, rp.config.Core.Dev)
976
+
err = tangled.RepoDelete(
977
+
r.Context(),
978
+
client,
979
+
&tangled.RepoDelete_Input{
980
+
Did: f.OwnerDid(),
981
+
Name: f.Name,
982
+
},
983
+
)
970
984
if err != nil {
971
-
log.Println("failed to create client to ", f.Knot)
972
-
return
973
-
}
974
-
975
-
ksResp, err := ksClient.RemoveRepo(f.OwnerDid(), f.Name)
976
-
if err != nil {
977
-
log.Printf("failed to make request to %s: %s", f.Knot, err)
978
-
return
979
-
}
980
-
981
-
if ksResp.StatusCode != http.StatusNoContent {
982
-
log.Println("failed to remove repo from knot, continuing anyway ", f.Knot)
985
+
xe, parseErr := xrpcerr.Unmarshal(err.Error())
986
+
if parseErr != nil {
987
+
log.Printf("failed to delete repo from knot %s: %s", f.Knot, err)
988
+
} else {
989
+
log.Printf("failed to delete repo from knot %s: %s", f.Knot, xe.Error())
990
+
}
991
+
// Continue anyway since we want to clean up local state
983
992
} else {
984
993
log.Println("removed repo from knot ", f.Knot)
985
994
}
···
1055
1064
return
1056
1065
}
1057
1066
1058
-
secret, err := db.GetRegistrationKey(rp.db, f.Knot)
1067
+
client, err := rp.oauth.ServiceClient(
1068
+
r,
1069
+
oauth.WithService(f.Knot),
1070
+
oauth.WithLxm(tangled.RepoSetDefaultBranchNSID),
1071
+
oauth.WithDev(rp.config.Core.Dev),
1072
+
)
1059
1073
if err != nil {
1060
-
log.Printf("no key found for domain %s: %s\n", f.Knot, err)
1074
+
log.Println("failed to connect to knot server:", err)
1075
+
rp.pages.Notice(w, noticeId, "Failed to connect to knot server.")
1061
1076
return
1062
1077
}
1063
1078
1064
-
ksClient, err := knotclient.NewSignedClient(f.Knot, secret, rp.config.Core.Dev)
1065
-
if err != nil {
1066
-
log.Println("failed to create client to ", f.Knot)
1067
-
return
1068
-
}
1069
-
1070
-
ksResp, err := ksClient.SetDefaultBranch(f.OwnerDid(), f.Name, branch)
1071
-
if err != nil {
1072
-
log.Printf("failed to make request to %s: %s", f.Knot, err)
1073
-
return
1074
-
}
1075
-
1076
-
if ksResp.StatusCode != http.StatusNoContent {
1077
-
rp.pages.Notice(w, "repo-settings", "Failed to set default branch. Try again later.")
1079
+
xe := tangled.RepoSetDefaultBranch(
1080
+
r.Context(),
1081
+
client,
1082
+
&tangled.RepoSetDefaultBranch_Input{
1083
+
Repo: f.RepoAt().String(),
1084
+
DefaultBranch: branch,
1085
+
},
1086
+
)
1087
+
if err := xrpcclient.HandleXrpcErr(xe); err != nil {
1088
+
log.Println("xrpc failed", "err", xe)
1089
+
rp.pages.Notice(w, noticeId, err.Error())
1078
1090
return
1079
1091
}
1080
1092
···
1373
1385
1374
1386
switch r.Method {
1375
1387
case http.MethodPost:
1376
-
secret, err := db.GetRegistrationKey(rp.db, f.Knot)
1388
+
client, err := rp.oauth.ServiceClient(
1389
+
r,
1390
+
oauth.WithService(f.Knot),
1391
+
oauth.WithLxm(tangled.RepoForkSyncNSID),
1392
+
oauth.WithDev(rp.config.Core.Dev),
1393
+
)
1377
1394
if err != nil {
1378
-
rp.pages.Notice(w, "repo", fmt.Sprintf("No registration key found for knot %s.", f.Knot))
1395
+
rp.pages.Notice(w, "repo", "Failed to connect to knot server.")
1379
1396
return
1380
1397
}
1381
1398
1382
-
client, err := knotclient.NewSignedClient(f.Knot, secret, rp.config.Core.Dev)
1383
-
if err != nil {
1384
-
rp.pages.Notice(w, "repo", "Failed to reach knot server.")
1399
+
repoInfo := f.RepoInfo(user)
1400
+
if repoInfo.Source == nil {
1401
+
rp.pages.Notice(w, "repo", "This repository is not a fork.")
1385
1402
return
1386
1403
}
1387
1404
1388
-
var uri string
1389
-
if rp.config.Core.Dev {
1390
-
uri = "http"
1391
-
} else {
1392
-
uri = "https"
1393
-
}
1394
-
forkName := fmt.Sprintf("%s", f.Name)
1395
-
forkSourceUrl := fmt.Sprintf("%s://%s/%s/%s", uri, f.Knot, f.OwnerDid(), f.Repo.Name)
1396
-
1397
-
_, err = client.SyncRepoFork(user.Did, forkSourceUrl, forkName, ref)
1405
+
err = tangled.RepoForkSync(
1406
+
r.Context(),
1407
+
client,
1408
+
&tangled.RepoForkSync_Input{
1409
+
Did: user.Did,
1410
+
Name: f.Name,
1411
+
Source: repoInfo.Source.RepoAt().String(),
1412
+
Branch: ref,
1413
+
},
1414
+
)
1398
1415
if err != nil {
1399
-
rp.pages.Notice(w, "repo", "Failed to sync repository fork.")
1416
+
xe, parseErr := xrpcerr.Unmarshal(err.Error())
1417
+
if parseErr != nil {
1418
+
log.Printf("failed to sync repository fork: %s", err)
1419
+
rp.pages.Notice(w, "repo", "Failed to sync repository fork.")
1420
+
} else {
1421
+
log.Printf("failed to sync repository fork: %s", xe.Error())
1422
+
rp.pages.Notice(w, "repo", fmt.Sprintf("Failed to sync repository fork: %s", xe.Message))
1423
+
}
1400
1424
return
1401
1425
}
1402
1426
···
1459
1483
// repo with this name already exists, append random string
1460
1484
forkName = fmt.Sprintf("%s-%s", forkName, randomString(3))
1461
1485
}
1462
-
secret, err := db.GetRegistrationKey(rp.db, knot)
1463
-
if err != nil {
1464
-
rp.pages.Notice(w, "repo", fmt.Sprintf("No registration key found for knot %s.", knot))
1465
-
return
1466
-
}
1486
+
client, err := rp.oauth.ServiceClient(
1487
+
r,
1488
+
oauth.WithService(knot),
1489
+
oauth.WithLxm(tangled.RepoForkNSID),
1490
+
oauth.WithDev(rp.config.Core.Dev),
1491
+
)
1467
1492
1468
-
client, err := knotclient.NewSignedClient(knot, secret, rp.config.Core.Dev)
1469
1493
if err != nil {
1470
-
rp.pages.Notice(w, "repo", "Failed to reach knot server.")
1494
+
log.Printf("error creating client for knot server: %v", err)
1495
+
rp.pages.Notice(w, "repo", "Failed to connect to knot server.")
1471
1496
return
1472
1497
}
1473
1498
···
1503
1528
}
1504
1529
}()
1505
1530
1506
-
resp, err := client.ForkRepo(user.Did, forkSourceUrl, forkName)
1531
+
err = tangled.RepoFork(
1532
+
r.Context(),
1533
+
client,
1534
+
&tangled.RepoFork_Input{
1535
+
Did: user.Did,
1536
+
Name: &forkName,
1537
+
Source: forkSourceUrl,
1538
+
},
1539
+
)
1540
+
1507
1541
if err != nil {
1508
-
rp.pages.Notice(w, "repo", "Failed to create repository on knot server.")
1509
-
return
1510
-
}
1542
+
xe, err := xrpcerr.Unmarshal(err.Error())
1543
+
if err != nil {
1544
+
log.Println(err)
1545
+
rp.pages.Notice(w, "repo", "Failed to create repository on knot server.")
1546
+
return
1547
+
}
1511
1548
1512
-
switch resp.StatusCode {
1513
-
case http.StatusConflict:
1514
-
rp.pages.Notice(w, "repo", "A repository with that name already exists.")
1549
+
log.Println(xe.Error())
1550
+
rp.pages.Notice(w, "repo", fmt.Sprintf("Failed to create repository on knot server: %s.", xe.Message))
1515
1551
return
1516
-
case http.StatusInternalServerError:
1517
-
rp.pages.Notice(w, "repo", "Failed to create repository on knot. Try again later.")
1518
-
case http.StatusNoContent:
1519
-
// continue
1520
1552
}
1521
1553
1522
1554
xrpcClient, err := rp.oauth.AuthorizedClient(r)
+24
-19
appview/state/state.go
+24
-19
appview/state/state.go
···
28
28
"tangled.sh/tangled.sh/core/eventconsumer"
29
29
"tangled.sh/tangled.sh/core/idresolver"
30
30
"tangled.sh/tangled.sh/core/jetstream"
31
-
"tangled.sh/tangled.sh/core/knotclient"
32
31
tlog "tangled.sh/tangled.sh/core/log"
33
32
"tangled.sh/tangled.sh/core/rbac"
34
33
"tangled.sh/tangled.sh/core/tid"
34
+
// xrpcerr "tangled.sh/tangled.sh/core/xrpc/errors"
35
35
)
36
36
37
37
type State struct {
···
327
327
328
328
existingRepo, err := db.GetRepo(s.db, user.Did, repoName)
329
329
if err == nil && existingRepo != nil {
330
-
s.pages.Notice(w, "repo", fmt.Sprintf("A repo by this name already exists on %s", existingRepo.Knot))
330
+
l.Info("repo exists")
331
+
s.pages.Notice(w, "repo", fmt.Sprintf("You already have a repository by this name on %s", existingRepo.Knot))
331
332
return
332
333
}
333
334
334
-
secret, err := db.GetRegistrationKey(s.db, domain)
335
-
if err != nil {
336
-
s.pages.Notice(w, "repo", fmt.Sprintf("No registration key found for knot %s.", domain))
337
-
return
338
-
}
335
+
client, err := s.oauth.ServiceClient(
336
+
r,
337
+
oauth.WithService(domain),
338
+
oauth.WithLxm(tangled.RepoCreateNSID),
339
+
oauth.WithDev(s.config.Core.Dev),
340
+
)
339
341
340
-
client, err := knotclient.NewSignedClient(domain, secret, s.config.Core.Dev)
341
342
if err != nil {
342
343
s.pages.Notice(w, "repo", "Failed to connect to knot server.")
343
344
return
···
392
393
}
393
394
}()
394
395
395
-
resp, err := client.NewRepo(user.Did, repoName, defaultBranch)
396
+
xe := tangled.RepoCreate(
397
+
r.Context(),
398
+
client,
399
+
&tangled.RepoCreate_Input{
400
+
Rkey: rkey,
401
+
},
402
+
)
396
403
if err != nil {
397
-
s.pages.Notice(w, "repo", "Failed to create repository on knot server.")
398
-
return
399
-
}
404
+
xe, err := xrpcerr.Unmarshal(err.Error())
405
+
if err != nil {
406
+
log.Println(err)
407
+
s.pages.Notice(w, "repo", "Failed to create repository on knot server.")
408
+
return
409
+
}
400
410
401
-
switch resp.StatusCode {
402
-
case http.StatusConflict:
403
-
s.pages.Notice(w, "repo", "A repository with that name already exists.")
411
+
log.Println(xe.Error())
412
+
s.pages.Notice(w, "repo", fmt.Sprintf("Failed to create repository on knot server: %s.", xe.Message))
404
413
return
405
-
case http.StatusInternalServerError:
406
-
s.pages.Notice(w, "repo", "Failed to create repository on knot. Try again later.")
407
-
case http.StatusNoContent:
408
-
// continue
409
414
}
410
415
411
416
err = db.AddRepo(tx, repo)