alpha
Login
or
Join now
4uffin.bsky.social
/
core
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
My own copy of Tangled :)
Star
0
Fork
0
Atom
Configure Feed
Issues
Pull Requests
Commits
Tags
Feed URL
Select the types of activity you want to include in your feed.
Overview
Issues
Pulls
Pipelines
add nicediff view to pulls
author
Akshay
date
1 year ago
(Mar 17, 2025, 7:23 PM UTC)
commit
5b96cada
5b96cadaf3be524556cf0403e97c232913ecacc6
parent
943975c2
943975c25ff6a34a3a1d6bdc5141bdb598948148
+175
-110
6 changed files
Expand all
Collapse all
Unified
Split
appview
db
pulls.go
pages
templates
fragments
diff.html
repo
commit.html
index.html
pulls
pull.html
flake.nix
+44
appview/db/pulls.go
Reviewed
···
3
3
import (
4
4
"database/sql"
5
5
"fmt"
6
6
+
"log"
6
7
"strings"
7
8
"time"
8
9
10
10
+
"github.com/bluekeyes/go-gitdiff/gitdiff"
9
11
"github.com/bluesky-social/indigo/atproto/syntax"
12
12
+
"github.com/sotangled/tangled/types"
10
13
)
11
14
12
15
type PullState int
···
100
103
func (p *Pull) LatestPatch() string {
101
104
latestSubmission := p.Submissions[len(p.Submissions)-1]
102
105
return latestSubmission.Patch
106
106
+
}
107
107
+
108
108
+
func (s PullSubmission) AsNiceDiff(targetBranch string) types.NiceDiff {
109
109
+
patch := s.Patch
110
110
+
111
111
+
diffs, _, err := gitdiff.Parse(strings.NewReader(patch))
112
112
+
if err != nil {
113
113
+
log.Println(err)
114
114
+
}
115
115
+
116
116
+
nd := types.NiceDiff{}
117
117
+
nd.Commit.Parent = targetBranch
118
118
+
119
119
+
for _, d := range diffs {
120
120
+
ndiff := types.Diff{}
121
121
+
ndiff.Name.New = d.NewName
122
122
+
ndiff.Name.Old = d.OldName
123
123
+
ndiff.IsBinary = d.IsBinary
124
124
+
ndiff.IsNew = d.IsNew
125
125
+
ndiff.IsDelete = d.IsDelete
126
126
+
ndiff.IsCopy = d.IsCopy
127
127
+
ndiff.IsRename = d.IsRename
128
128
+
129
129
+
for _, tf := range d.TextFragments {
130
130
+
ndiff.TextFragments = append(ndiff.TextFragments, *tf)
131
131
+
for _, l := range tf.Lines {
132
132
+
switch l.Op {
133
133
+
case gitdiff.OpAdd:
134
134
+
nd.Stat.Insertions += 1
135
135
+
case gitdiff.OpDelete:
136
136
+
nd.Stat.Deletions += 1
137
137
+
}
138
138
+
}
139
139
+
}
140
140
+
141
141
+
nd.Diff = append(nd.Diff, ndiff)
142
142
+
}
143
143
+
144
144
+
nd.Stat.FilesChanged = len(diffs)
145
145
+
146
146
+
return nd
103
147
}
104
148
105
149
func NewPull(tx *sql.Tx, pull *Pull) error {
+112
appview/pages/templates/fragments/diff.html
Reviewed
···
1
1
+
{{ define "fragments/diff" }}
2
2
+
{{ $repo := index . 0 }}
3
3
+
{{ $diff := index . 1 }}
4
4
+
{{ $commit := $diff.Commit }}
5
5
+
{{ $stat := $diff.Stat }}
6
6
+
{{ $diff := $diff.Diff }}
7
7
+
8
8
+
{{ $this := $commit.This }}
9
9
+
{{ $parent := $commit.Parent }}
10
10
+
11
11
+
{{ $last := sub (len $diff) 1 }}
12
12
+
{{ range $idx, $hunk := $diff }}
13
13
+
{{ with $hunk }}
14
14
+
<section class="mt-6 border border-gray-200 w-full mx-auto rounded bg-white drop-shadow-sm">
15
15
+
<div id="file-{{ .Name.New }}">
16
16
+
<div id="diff-file">
17
17
+
<details open>
18
18
+
<summary class="list-none cursor-pointer sticky top-0">
19
19
+
<div id="diff-file-header" class="rounded cursor-pointer bg-white flex justify-between">
20
20
+
<div id="left-side-items" class="p-2 flex gap-2 items-center">
21
21
+
{{ $markerstyle := "diff-type p-1 mr-1 font-mono text-sm rounded select-none" }}
22
22
+
23
23
+
{{ if .IsNew }}
24
24
+
<span class="bg-green-100 text-green-700 {{ $markerstyle }}">ADDED</span>
25
25
+
{{ else if .IsDelete }}
26
26
+
<span class="bg-red-100 text-red-700 {{ $markerstyle }}">DELETED</span>
27
27
+
{{ else if .IsCopy }}
28
28
+
<span class="bg-gray-100 text-gray-700 {{ $markerstyle }}">COPIED</span>
29
29
+
{{ else if .IsRename }}
30
30
+
<span class="bg-gray-100 text-gray-700 {{ $markerstyle }}">RENAMED</span>
31
31
+
{{ else }}
32
32
+
<span class="bg-gray-100 text-gray-700 {{ $markerstyle }}">MODIFIED</span>
33
33
+
{{ end }}
34
34
+
35
35
+
{{ if .IsDelete }}
36
36
+
<a {{if $this }}href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.Old }}"{{end}}>
37
37
+
{{ .Name.Old }}
38
38
+
</a>
39
39
+
{{ else if (or .IsCopy .IsRename) }}
40
40
+
<a {{if $parent}}href="/{{ $repo }}/blob/{{ $parent }}/{{ .Name.Old }}"{{end}}>
41
41
+
{{ .Name.Old }}
42
42
+
</a>
43
43
+
<i class="w-4 h-4" data-lucide="arrow-right"></i>
44
44
+
<a {{if $this}}href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}"{{end}}>
45
45
+
{{ .Name.New }}
46
46
+
</a>
47
47
+
{{ else }}
48
48
+
<a {{if $this}}href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}"{{end}}>
49
49
+
{{ .Name.New }}
50
50
+
</a>
51
51
+
{{ end }}
52
52
+
</div>
53
53
+
54
54
+
{{ $iconstyle := "p-1 mx-1 hover:bg-gray-100 rounded" }}
55
55
+
<div id="right-side-items" class="p-2 flex items-center">
56
56
+
<a title="top of file" href="#file-{{ .Name.New }}" class="{{ $iconstyle }}"><i class="w-4 h-4" data-lucide="arrow-up-to-line"></i></a>
57
57
+
{{ if gt $idx 0 }}
58
58
+
{{ $prev := index $diff (sub $idx 1) }}
59
59
+
<a title="previous file" href="#file-{{ $prev.Name.New }}" class="{{ $iconstyle }}"><i class="w-4 h-4" data-lucide="arrow-up"></i></a>
60
60
+
{{ end }}
61
61
+
62
62
+
{{ if lt $idx $last }}
63
63
+
{{ $next := index $diff (add $idx 1) }}
64
64
+
<a title="next file" href="#file-{{ $next.Name.New }}" class="{{ $iconstyle }}"><i class="w-4 h-4" data-lucide="arrow-down"></i></a>
65
65
+
{{ end }}
66
66
+
</div>
67
67
+
68
68
+
</div>
69
69
+
</summary>
70
70
+
71
71
+
<div class="transition-all duration-700 ease-in-out">
72
72
+
{{ if .IsDelete }}
73
73
+
<p class="text-center text-gray-400 p-4">
74
74
+
This file has been deleted in this commit.
75
75
+
</p>
76
76
+
{{ else }}
77
77
+
{{ if .IsBinary }}
78
78
+
<p class="text-center text-gray-400 p-4">
79
79
+
This is a binary file and will not be displayed.
80
80
+
</p>
81
81
+
{{ else }}
82
82
+
<pre class="overflow-auto">
83
83
+
{{- range .TextFragments -}}
84
84
+
<div class="bg-gray-100 text-gray-500 select-none">{{ .Header }}</div>
85
85
+
{{- range .Lines -}}
86
86
+
{{- if eq .Op.String "+" -}}
87
87
+
<div class="bg-green-100 text-green-700 p-1"><span class="select-none mx-2">{{ .Op.String }}</span><span>{{ .Line }}</span></div>
88
88
+
{{- end -}}
89
89
+
90
90
+
{{- if eq .Op.String "-" -}}
91
91
+
<div class="bg-red-100 text-red-700 p-1"><span class="select-none mx-2">{{ .Op.String }}</span><span>{{ .Line }}</span></div>
92
92
+
{{- end -}}
93
93
+
94
94
+
{{- if eq .Op.String " " -}}
95
95
+
<div class="bg-white text-gray-500 px"><span class="select-none mx-2">{{ .Op.String }}</span><span>{{ .Line }}</span></div>
96
96
+
{{- end -}}
97
97
+
98
98
+
{{- end -}}
99
99
+
{{- end -}}
100
100
+
</pre>
101
101
+
{{- end -}}
102
102
+
{{ end }}
103
103
+
</div>
104
104
+
105
105
+
</details>
106
106
+
107
107
+
</div>
108
108
+
</div>
109
109
+
</section>
110
110
+
{{ end }}
111
111
+
{{ end }}
112
112
+
{{ end }}
+1
-103
appview/pages/templates/repo/commit.html
Reviewed
···
55
55
{{end}}
56
56
57
57
{{ define "repoAfter" }}
58
58
-
59
59
-
{{ $repo := .RepoInfo.FullName }}
60
60
-
{{ $commit := .Diff.Commit }}
61
61
-
{{ $stat := .Diff.Stat }}
62
62
-
{{ $diff := .Diff.Diff }}
63
63
-
64
64
-
{{ $this := $commit.This }}
65
65
-
{{ $parent := $commit.Parent }}
66
66
-
67
67
-
{{ $last := sub (len $diff) 1 }}
68
68
-
{{ range $idx, $hunk := $diff }}
69
69
-
{{ with $hunk }}
70
70
-
<section class="mt-6 border border-gray-200 w-full mx-auto rounded bg-white drop-shadow-sm">
71
71
-
<div id="file-{{ .Name.New }}">
72
72
-
<div id="diff-file">
73
73
-
<details open>
74
74
-
<summary class="list-none cursor-pointer sticky top-0">
75
75
-
<div id="diff-file-header" class="rounded cursor-pointer bg-white flex justify-between">
76
76
-
<div id="left-side-items" class="p-2 flex gap-2 items-center">
77
77
-
{{ $markerstyle := "diff-type p-1 mr-1 font-mono text-sm rounded select-none" }}
78
78
-
79
79
-
{{ if .IsNew }}
80
80
-
<span class="bg-green-100 text-green-700 {{ $markerstyle }}">ADDED</span>
81
81
-
{{ else if .IsDelete }}
82
82
-
<span class="bg-red-100 text-red-700 {{ $markerstyle }}">DELETED</span>
83
83
-
{{ else if .IsCopy }}
84
84
-
<span class="bg-gray-100 text-gray-700 {{ $markerstyle }}">COPIED</span>
85
85
-
{{ else if .IsRename }}
86
86
-
<span class="bg-gray-100 text-gray-700 {{ $markerstyle }}">RENAMED</span>
87
87
-
{{ else }}
88
88
-
<span class="bg-gray-100 text-gray-700 {{ $markerstyle }}">MODIFIED</span>
89
89
-
{{ end }}
90
90
-
91
91
-
{{ if .IsDelete }}
92
92
-
<a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.Old }}">{{ .Name.Old }}</a>
93
93
-
{{ else if (or .IsCopy .IsRename) }}
94
94
-
<a href="/{{ $repo }}/blob/{{ $parent }}/{{ .Name.Old }}">{{ .Name.Old }}</a>
95
95
-
<i class="w-4 h-4" data-lucide="arrow-right"></i>
96
96
-
<a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>
97
97
-
{{ else }}
98
98
-
<a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>
99
99
-
{{ end }}
100
100
-
</div>
101
101
-
102
102
-
{{ $iconstyle := "p-1 mx-1 hover:bg-gray-100 rounded" }}
103
103
-
<div id="right-side-items" class="p-2 flex items-center">
104
104
-
<a title="top of file" href="#file-{{ .Name.New }}" class="{{ $iconstyle }}"><i class="w-4 h-4" data-lucide="arrow-up-to-line"></i></a>
105
105
-
{{ if gt $idx 0 }}
106
106
-
{{ $prev := index $diff (sub $idx 1) }}
107
107
-
<a title="previous file" href="#file-{{ $prev.Name.New }}" class="{{ $iconstyle }}"><i class="w-4 h-4" data-lucide="arrow-up"></i></a>
108
108
-
{{ end }}
109
109
-
110
110
-
{{ if lt $idx $last }}
111
111
-
{{ $next := index $diff (add $idx 1) }}
112
112
-
<a title="next file" href="#file-{{ $next.Name.New }}" class="{{ $iconstyle }}"><i class="w-4 h-4" data-lucide="arrow-down"></i></a>
113
113
-
{{ end }}
114
114
-
</div>
115
115
-
116
116
-
</div>
117
117
-
</summary>
118
118
-
119
119
-
<div class="transition-all duration-700 ease-in-out">
120
120
-
{{ if .IsDelete }}
121
121
-
<p class="text-center text-gray-400 p-4">
122
122
-
This file has been deleted in this commit.
123
123
-
</p>
124
124
-
{{ else }}
125
125
-
{{ if .IsBinary }}
126
126
-
<p class="text-center text-gray-400 p-4">
127
127
-
This is a binary file and will not be displayed.
128
128
-
</p>
129
129
-
{{ else }}
130
130
-
<pre class="overflow-auto">
131
131
-
{{- range .TextFragments -}}
132
132
-
<div class="bg-gray-100 text-gray-500 select-none">{{ .Header }}</div>
133
133
-
{{- range .Lines -}}
134
134
-
{{- if eq .Op.String "+" -}}
135
135
-
<div class="bg-green-100 text-green-700 p-1"><span class="select-none mx-2">{{ .Op.String }}</span><span>{{ .Line }}</span></div>
136
136
-
{{- end -}}
137
137
-
138
138
-
{{- if eq .Op.String "-" -}}
139
139
-
<div class="bg-red-100 text-red-700 p-1"><span class="select-none mx-2">{{ .Op.String }}</span><span>{{ .Line }}</span></div>
140
140
-
{{- end -}}
141
141
-
142
142
-
{{- if eq .Op.String " " -}}
143
143
-
<div class="bg-white text-gray-500 px"><span class="select-none mx-2">{{ .Op.String }}</span><span>{{ .Line }}</span></div>
144
144
-
{{- end -}}
145
145
-
146
146
-
{{- end -}}
147
147
-
{{- end -}}
148
148
-
</pre>
149
149
-
{{- end -}}
150
150
-
{{ end }}
151
151
-
</div>
152
152
-
153
153
-
</details>
154
154
-
155
155
-
</div>
156
156
-
</div>
157
157
-
</section>
158
158
-
{{ end }}
159
159
-
{{ end }}
160
160
-
58
58
+
{{ template "fragments/diff" (list .RepoInfo.FullName .Diff) }}
161
59
{{end}}
+1
-1
appview/pages/templates/repo/index.html
Reviewed
···
13
13
{{ define "branchSelector" }}
14
14
<div class="flex justify-between pb-5">
15
15
<select
16
16
-
onchange="window.location.href = '/{{ .RepoInfo.FullName }}/tree/' + this.value"
16
16
+
onchange="window.location.href = '/{{ .RepoInfo.FullName }}/tree/' + encodeURIComponent(this.value)"
17
17
class="p-1 border border-gray-200 bg-white"
18
18
>
19
19
<optgroup label="branches" class="bold text-sm">
+6
-5
appview/pages/templates/repo/pulls/pull.html
Reviewed
···
93
93
94
94
{{ define "submissions" }}
95
95
{{ $lastIdx := sub (len .Pull.Submissions) 1 }}
96
96
+
{{ $targetBranch := .Pull.TargetBranch }}
97
97
+
{{ $repoName := .RepoInfo.FullName }}
96
98
{{ range $idx, $item := .Pull.Submissions }}
99
99
+
{{ $diff := $item.AsNiceDiff $targetBranch }}
97
100
{{ with $item }}
98
101
{{ $oneIndexedRound := add .RoundNumber 1 }}
99
102
<details {{ if eq $idx $lastIdx }}open{{ end }}>
···
106
109
<span>
107
110
{{ $owner := index $.DidHandleMap $.Pull.OwnerDid }}
108
111
submitted by <a href="/{{ $owner }}">{{ $owner }}</a>
109
109
-
<span class="before:content-['·']"></span>
110
110
-
<a href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/patch">view patch</a>
111
112
<span class="select-none before:content-['\00B7']"></span>
112
113
<time>{{ .Created | timeFmt }}</time>
113
114
<span class="select-none before:content-['·']"></span>
···
121
122
</div>
122
123
</summary>
123
124
<div class="pl-12 flex flex-col gap-2 mt-2 relative">
124
124
-
<!--div class="bg-white rounded drop-shadow-sm p-4">
125
125
-
<pre class="overflow-auto"><code>{{- .Patch -}}</code></pre>
126
126
-
</div-->
125
125
+
<div>
126
126
+
{{ template "fragments/diff" (list $repoName $diff) }}
127
127
+
</div>
127
128
128
129
{{ range .Comments }}
129
130
<div id="comment-{{.ID}}" class="bg-white rounded drop-shadow-sm py-2 px-4 relative w-fit">
+11
-1
flake.nix
Reviewed
···
313
313
314
314
environment.systemPackages = with pkgs; [git];
315
315
316
316
+
system.activationScripts.gitConfig = ''
317
317
+
mkdir -p /home/git/.config/git
318
318
+
cat > /home/git/.config/git/config << EOF
319
319
+
[user]
320
320
+
name = Git User
321
321
+
email = git@example.com
322
322
+
EOF
323
323
+
chown -R git:git /home/git/.config
324
324
+
'';
325
325
+
316
326
users.users.git = {
317
327
isNormalUser = true;
318
328
home = "/home/git";
···
380
390
services.tangled-knotserver = {
381
391
enable = true;
382
392
server = {
383
383
-
secret = "ad7b32ded52fbe96e09f469a288084ee01cd12c971da87a1cbb87ef67081bd87";
393
393
+
secret = "6995e040e80e2d593b5e5e9ca611a70140b9ef8044add0a28b48b1ee34aa3e85";
384
394
hostname = "localhost:6000";
385
395
listenAddr = "0.0.0.0:6000";
386
396
};