forked from tangled.org/core
this repo has no description

Compare changes

Choose any two refs to compare.

Changed files
+148 -103
appview
db
pages
markup
templates
repo
state
docs
knotserver
nix
+8 -4
appview/db/issues.go
··· 359 359 repoMap[string(repos[i].RepoAt())] = &repos[i] 360 360 } 361 361 362 - for issueAt := range issueMap { 363 - i := issueMap[issueAt] 364 - r := repoMap[string(i.RepoAt)] 365 - i.Repo = r 362 + for issueAt, i := range issueMap { 363 + if r, ok := repoMap[string(i.RepoAt)]; ok { 364 + i.Repo = r 365 + } else { 366 + // do not show up the issue if the repo is deleted 367 + // TODO: foreign key where? 368 + delete(issueMap, issueAt) 369 + } 366 370 } 367 371 368 372 // collect comments
+2 -2
appview/db/profile.go
··· 553 553 query = `select count(id) from pulls where owner_did = ? and state = ?` 554 554 args = append(args, did, PullOpen) 555 555 case VanityStatOpenIssueCount: 556 - query = `select count(id) from issues where owner_did = ? and open = 1` 556 + query = `select count(id) from issues where did = ? and open = 1` 557 557 args = append(args, did) 558 558 case VanityStatClosedIssueCount: 559 - query = `select count(id) from issues where owner_did = ? and open = 0` 559 + query = `select count(id) from issues where did = ? and open = 0` 560 560 args = append(args, did) 561 561 case VanityStatRepositoryCount: 562 562 query = `select count(id) from repos where did = ?`
+1 -1
appview/pages/markup/markdown.go
··· 235 235 repoName := fmt.Sprintf("%s/%s", rctx.RepoInfo.OwnerDid, rctx.RepoInfo.Name) 236 236 237 237 query := fmt.Sprintf("repo=%s&ref=%s&path=%s&raw=true", 238 - repoName, url.PathEscape(rctx.RepoInfo.Ref), actualPath) 238 + url.PathEscape(repoName), url.PathEscape(rctx.RepoInfo.Ref), actualPath) 239 239 240 240 parsedURL := &url.URL{ 241 241 Scheme: scheme,
+1 -1
appview/pages/templates/banner.html
··· 30 30 <div class="mx-6"> 31 31 These services may not be fully accessible until upgraded. 32 32 <a class="underline text-red-800 dark:text-red-200" 33 - href="https://tangled.sh/@tangled.sh/core/tree/master/docs/migrations/"> 33 + href="https://tangled.sh/@tangled.sh/core/tree/master/docs/migrations.md"> 34 34 Click to read the upgrade guide</a>. 35 35 </div> 36 36 </details>
+8
appview/pages/templates/fragments/logotype.html
··· 1 + {{ define "fragments/logotype" }} 2 + <span class="flex items-center gap-2"> 3 + <span class="font-bold italic">tangled</span> 4 + <span class="font-normal not-italic text-xs rounded bg-gray-100 dark:bg-gray-700 px-1"> 5 + alpha 6 + </span> 7 + <span> 8 + {{ end }}
+3 -6
appview/pages/templates/knots/index.html
··· 1 1 {{ define "title" }}knots{{ end }} 2 2 3 3 {{ define "content" }} 4 - <div class="px-6 py-4 flex items-end justify-start gap-4 align-bottom"> 4 + <div class="px-6 py-4 flex items-center justify-between gap-4 align-bottom"> 5 5 <h1 class="text-xl font-bold dark:text-white">Knots</h1> 6 - 7 - <span class="flex items-center gap-1 text-sm"> 6 + <span class="flex items-center gap-1"> 8 7 {{ i "book" "w-3 h-3" }} 9 - <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/knot-hosting.md"> 10 - docs 11 - </a> 8 + <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/knot-hosting.md">docs</a> 12 9 </span> 13 10 </div> 14 11
+1 -3
appview/pages/templates/layouts/fragments/topbar.html
··· 2 2 <nav class="space-x-4 px-6 py-2 rounded bg-white dark:bg-gray-800 dark:text-white drop-shadow-sm"> 3 3 <div class="flex justify-between p-0 items-center"> 4 4 <div id="left-items"> 5 - <a href="/" hx-boost="true" class="flex gap-2 font-bold italic"> 6 - tangled<sub>alpha</sub> 7 - </a> 5 + <a href="/" hx-boost="true" class="text-lg">{{ template "fragments/logotype" }}</a> 8 6 </div> 9 7 10 8 <div id="right-items" class="flex items-center gap-2">
+3 -7
appview/pages/templates/spindles/index.html
··· 1 1 {{ define "title" }}spindles{{ end }} 2 2 3 3 {{ define "content" }} 4 - <div class="px-6 py-4 flex items-end justify-start gap-4 align-bottom"> 4 + <div class="px-6 py-4 flex items-center justify-between gap-4 align-bottom"> 5 5 <h1 class="text-xl font-bold dark:text-white">Spindles</h1> 6 - 7 - 8 - <span class="flex items-center gap-1 text-sm"> 6 + <span class="flex items-center gap-1"> 9 7 {{ i "book" "w-3 h-3" }} 10 - <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/spindle/hosting.md"> 11 - docs 12 - </a> 8 + <a href="https://tangled.sh/@tangled.sh/core/blob/master/docs/spindle/hosting.md">docs</a> 13 9 </span> 14 10 </div> 15 11
+2 -4
appview/pages/templates/user/completeSignup.html
··· 29 29 </head> 30 30 <body class="flex items-center justify-center min-h-screen"> 31 31 <main class="max-w-md px-6 -mt-4"> 32 - <h1 33 - class="text-center text-2xl font-semibold italic dark:text-white" 34 - > 35 - tangled 32 + <h1 class="flex place-content-center text-2xl font-semibold italic dark:text-white" > 33 + {{ template "fragments/logotype" }} 36 34 </h1> 37 35 <h2 class="text-center text-xl italic dark:text-white"> 38 36 tightly-knit social coding.
+2 -2
appview/pages/templates/user/login.html
··· 13 13 </head> 14 14 <body class="flex items-center justify-center min-h-screen"> 15 15 <main class="max-w-md px-6 -mt-4"> 16 - <h1 class="text-center text-2xl font-semibold italic dark:text-white" > 17 - tangled 16 + <h1 class="flex place-content-center text-2xl font-semibold italic dark:text-white" > 17 + {{ template "fragments/logotype" }} 18 18 </h1> 19 19 <h2 class="text-center text-xl italic dark:text-white"> 20 20 tightly-knit social coding.
+3 -1
appview/pages/templates/user/signup.html
··· 13 13 </head> 14 14 <body class="flex items-center justify-center min-h-screen"> 15 15 <main class="max-w-md px-6 -mt-4"> 16 - <h1 class="text-center text-2xl font-semibold italic dark:text-white" >tangled</h1> 16 + <h1 class="flex place-content-center text-2xl font-semibold italic dark:text-white" > 17 + {{ template "fragments/logotype" }} 18 + </h1> 17 19 <h2 class="text-center text-xl italic dark:text-white">tightly-knit social coding.</h2> 18 20 <form 19 21 class="mt-4 max-w-sm mx-auto"
+1 -2
appview/repo/repo.go
··· 11 11 "log/slog" 12 12 "net/http" 13 13 "net/url" 14 - "path" 15 14 "path/filepath" 16 15 "slices" 17 16 "strconv" ··· 710 709 } 711 710 712 711 // fetch the raw binary content using sh.tangled.repo.blob xrpc 713 - repoName := path.Join("%s/%s", f.OwnerDid(), f.Name) 712 + repoName := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 714 713 blobURL := fmt.Sprintf("%s://%s/xrpc/sh.tangled.repo.blob?repo=%s&ref=%s&path=%s&raw=true", 715 714 scheme, f.Knot, url.QueryEscape(repoName), url.QueryEscape(ref), url.QueryEscape(filePath)) 716 715
+10 -9
appview/state/profile.go
··· 17 17 "github.com/gorilla/feeds" 18 18 "tangled.sh/tangled.sh/core/api/tangled" 19 19 "tangled.sh/tangled.sh/core/appview/db" 20 - // "tangled.sh/tangled.sh/core/appview/oauth" 21 20 "tangled.sh/tangled.sh/core/appview/pages" 22 21 ) 23 22 ··· 284 283 l = l.With("profileDid", profile.UserDid, "profileHandle", profile.UserHandle) 285 284 286 285 loggedInUser := s.oauth.GetUser(r) 286 + params := FollowsPageParams{ 287 + Card: profile, 288 + } 287 289 288 290 follows, err := fetchFollows(s.db, profile.UserDid) 289 291 if err != nil { 290 292 l.Error("failed to fetch follows", "err", err) 291 - return nil, err 293 + return &params, err 292 294 } 293 295 294 296 if len(follows) == 0 { 295 - return nil, nil 297 + return &params, nil 296 298 } 297 299 298 300 followDids := make([]string, 0, len(follows)) ··· 303 305 profiles, err := db.GetProfiles(s.db, db.FilterIn("did", followDids)) 304 306 if err != nil { 305 307 l.Error("failed to get profiles", "followDids", followDids, "err", err) 306 - return nil, err 308 + return &params, err 307 309 } 308 310 309 311 followStatsMap, err := db.GetFollowerFollowingCounts(s.db, followDids) ··· 316 318 following, err := db.GetFollowing(s.db, loggedInUser.Did) 317 319 if err != nil { 318 320 l.Error("failed to get follow list", "err", err, "loggedInUser", loggedInUser.Did) 319 - return nil, err 321 + return &params, err 320 322 } 321 323 loggedInUserFollowing = make(map[string]struct{}, len(following)) 322 324 for _, follow := range following { ··· 350 352 } 351 353 } 352 354 353 - return &FollowsPageParams{ 354 - Follows: followCards, 355 - Card: profile, 356 - }, nil 355 + params.Follows = followCards 356 + 357 + return &params, nil 357 358 } 358 359 359 360 func (s *State) followersPage(w http.ResponseWriter, r *http.Request) {
-35
docs/migrations/knot-1.7.0.md
··· 1 - # Upgrading from v1.7.0 2 - 3 - After v1.7.0, knot secrets have been deprecated. You no 4 - longer need a secret from the appview to run a knot. All 5 - authorized commands to knots are managed via [Inter-Service 6 - Authentication](https://atproto.com/specs/xrpc#inter-service-authentication-jwt). 7 - Knots will be read-only until upgraded. 8 - 9 - Upgrading is quite easy, in essence: 10 - 11 - - `KNOT_SERVER_SECRET` is no more, you can remove this 12 - environment variable entirely 13 - - `KNOT_SERVER_OWNER` is now required on boot, set this to 14 - your DID. You can find your DID in the 15 - [settings](https://tangled.sh/settings) page. 16 - - Restart your knot once you have replaced the environment 17 - variable 18 - - Head to the [knot dashboard](https://tangled.sh/knots) and 19 - hit the "retry" button to verify your knot. This simply 20 - writes a `sh.tangled.knot` record to your PDS. 21 - 22 - ## Nix 23 - 24 - If you use the nix module, simply bump the flake to the 25 - latest revision, and change your config block like so: 26 - 27 - ```diff 28 - services.tangled-knot = { 29 - enable = true; 30 - server = { 31 - - secretFile = /path/to/secret; 32 - + owner = "did:plc:foo"; 33 - }; 34 - }; 35 - ```
+60
docs/migrations.md
··· 1 + # Migrations 2 + 3 + This document is laid out in reverse-chronological order. 4 + Newer migration guides are listed first, and older guides 5 + are further down the page. 6 + 7 + ## Upgrading from v1.8.x 8 + 9 + After v1.8.2, the HTTP API for knot and spindles have been 10 + deprecated and replaced with XRPC. Repositories on outdated 11 + knots will not be viewable from the appview. Upgrading is 12 + straightforward however. 13 + 14 + For knots: 15 + 16 + - Upgrade to latest tag (v1.9.0 or above) 17 + - Head to the [knot dashboard](https://tangled.sh/knots) and 18 + hit the "retry" button to verify your knot 19 + 20 + For spindles: 21 + 22 + - Upgrade to latest tag (v1.9.0 or above) 23 + - Head to the [spindle 24 + dashboard](https://tangled.sh/spindles) and hit the 25 + "retry" button to verify your spindle 26 + 27 + ## Upgrading from v1.7.x 28 + 29 + After v1.7.0, knot secrets have been deprecated. You no 30 + longer need a secret from the appview to run a knot. All 31 + authorized commands to knots are managed via [Inter-Service 32 + Authentication](https://atproto.com/specs/xrpc#inter-service-authentication-jwt). 33 + Knots will be read-only until upgraded. 34 + 35 + Upgrading is quite easy, in essence: 36 + 37 + - `KNOT_SERVER_SECRET` is no more, you can remove this 38 + environment variable entirely 39 + - `KNOT_SERVER_OWNER` is now required on boot, set this to 40 + your DID. You can find your DID in the 41 + [settings](https://tangled.sh/settings) page. 42 + - Restart your knot once you have replaced the environment 43 + variable 44 + - Head to the [knot dashboard](https://tangled.sh/knots) and 45 + hit the "retry" button to verify your knot. This simply 46 + writes a `sh.tangled.knot` record to your PDS. 47 + 48 + If you use the nix module, simply bump the flake to the 49 + latest revision, and change your config block like so: 50 + 51 + ```diff 52 + services.tangled-knot = { 53 + enable = true; 54 + server = { 55 + - secretFile = /path/to/secret; 56 + + owner = "did:plc:foo"; 57 + }; 58 + }; 59 + ``` 60 +
+1
knotserver/xrpc/repo_blob.go
··· 69 69 return 70 70 } 71 71 w.Header().Set("ETag", eTag) 72 + w.Header().Set("Content-Type", mimeType) 72 73 73 74 case strings.HasPrefix(mimeType, "text/"): 74 75 w.Header().Set("Cache-Control", "public, no-cache")
+8 -6
knotserver/xrpc/repo_branches.go
··· 20 20 21 21 cursor := r.URL.Query().Get("cursor") 22 22 23 - limit := 50 // default 24 - if limitStr := r.URL.Query().Get("limit"); limitStr != "" { 25 - if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 100 { 26 - limit = l 27 - } 28 - } 23 + // limit := 50 // default 24 + // if limitStr := r.URL.Query().Get("limit"); limitStr != "" { 25 + // if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 100 { 26 + // limit = l 27 + // } 28 + // } 29 + 30 + limit := 500 29 31 30 32 gr, err := git.PlainOpen(repoPath) 31 33 if err != nil {
+11 -1
knotserver/xrpc/repo_log.go
··· 73 73 return 74 74 } 75 75 76 + total, err := gr.TotalCommits() 77 + if err != nil { 78 + x.Logger.Error("fetching total commits", "error", err.Error()) 79 + writeError(w, xrpcerr.NewXrpcError( 80 + xrpcerr.WithTag("InternalServerError"), 81 + xrpcerr.WithMessage("failed to fetch total commits"), 82 + ), http.StatusNotFound) 83 + return 84 + } 85 + 76 86 // Create response using existing types.RepoLogResponse 77 87 response := types.RepoLogResponse{ 78 88 Commits: commits, 79 89 Ref: ref, 80 90 Page: (offset / limit) + 1, 81 91 PerPage: limit, 82 - Total: len(commits), // This is not accurate for pagination, but matches existing behavior 92 + Total: total, 83 93 } 84 94 85 95 if path != "" {
+8 -2
nix/gomod2nix.toml
··· 425 425 [mod."github.com/whyrusleeping/cbor-gen"] 426 426 version = "v0.3.1" 427 427 hash = "sha256-PAd8M2Z8t6rVRBII+Rg8Bz+QaJIwbW64bfyqsv31kgc=" 428 + [mod."github.com/wyatt915/goldmark-treeblood"] 429 + version = "v0.0.0-20250825231212-5dcbdb2f4b57" 430 + hash = "sha256-IZEsUXTBTsNgWoD7vqRUc9aFCCHNjzk1IUmI9O+NCnM=" 431 + [mod."github.com/wyatt915/treeblood"] 432 + version = "v0.1.15" 433 + hash = "sha256-hb99exdkoY2Qv8WdDxhwgPXGbEYimUr6wFtPXEvcO9g=" 428 434 [mod."github.com/yuin/goldmark"] 429 - version = "v1.4.15" 430 - hash = "sha256-MvSOT6dwf5hVYkIg4MnqMpsy5ZtWZ7amAE7Zo9HkEa0=" 435 + version = "v1.7.12" 436 + hash = "sha256-thLYBS4woL2X5qRdo7vP+xCvjlGRDU0jXtDCUt6vvWM=" 431 437 [mod."github.com/yuin/goldmark-highlighting/v2"] 432 438 version = "v2.0.0-20230729083705-37449abec8cc" 433 439 hash = "sha256-HpiwU7jIeDUAg2zOpTIiviQir8dpRPuXYh2nqFFccpg="
+15 -17
nix/pkgs/knot-unwrapped.nix
··· 3 3 modules, 4 4 sqlite-lib, 5 5 src, 6 - }: 7 - let 8 - version = "1.8.1-alpha"; 6 + }: let 7 + version = "1.9.0-alpha"; 9 8 in 10 - buildGoApplication { 11 - pname = "knot"; 12 - version = "1.8.1"; 13 - inherit src modules; 9 + buildGoApplication { 10 + pname = "knot"; 11 + inherit src version modules; 14 12 15 - doCheck = false; 13 + doCheck = false; 16 14 17 - subPackages = ["cmd/knot"]; 18 - tags = ["libsqlite3"]; 15 + subPackages = ["cmd/knot"]; 16 + tags = ["libsqlite3"]; 19 17 20 - ldflags = [ 21 - "-X tangled.sh/tangled.sh/core/knotserver/xrpc.version=${version}" 22 - ]; 18 + ldflags = [ 19 + "-X tangled.sh/tangled.sh/core/knotserver/xrpc.version=${version}" 20 + ]; 23 21 24 - env.CGO_CFLAGS = "-I ${sqlite-lib}/include "; 25 - env.CGO_LDFLAGS = "-L ${sqlite-lib}/lib"; 26 - CGO_ENABLED = 1; 27 - } 22 + env.CGO_CFLAGS = "-I ${sqlite-lib}/include "; 23 + env.CGO_LDFLAGS = "-L ${sqlite-lib}/lib"; 24 + CGO_ENABLED = 1; 25 + }