+15
.zed/settings.json
+15
.zed/settings.json
···
1
+
// Folder-specific settings
2
+
//
3
+
// For a full list of overridable settings, and general information on folder-specific settings,
4
+
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
5
+
{
6
+
"languages": {
7
+
"HTML": {
8
+
"prettier": {
9
+
"allowed": true,
10
+
"parser": "go-template",
11
+
"plugins": ["prettier-plugin-go-template"]
12
+
}
13
+
}
14
+
}
15
+
}
+10
appview/pages/pages.go
+10
appview/pages/pages.go
···
160
160
func (p *Pages) RepoLog(w io.Writer, params RepoLogParams) error {
161
161
return p.execute("repo/log", w, params)
162
162
}
163
+
164
+
type RepoCommitParams struct {
165
+
LoggedInUser *auth.User
166
+
RepoInfo RepoInfo
167
+
types.RepoCommitResponse
168
+
}
169
+
170
+
func (p *Pages) RepoCommit(w io.Writer, params RepoCommitParams) error {
171
+
return p.execute("repo/commit", w, params)
172
+
}
+96
-96
appview/pages/templates/repo/commit.html
+96
-96
appview/pages/templates/repo/commit.html
···
1
-
<html>
2
-
{{ template "layouts/head" . }}
1
+
{{ define "title" }} commit {{ .Diff.Commit.This }} {{ end }}
3
2
4
-
{{ template "layouts/repo-header" . }}
5
-
<body>
6
-
{{ template "layouts/nav" . }}
7
-
<main>
8
-
<section class="commit">
9
-
<pre>{{- .commit.Message -}}</pre>
10
-
<div class="commit-info">
11
-
{{ .commit.Author.Name }} <a href="mailto:{{ .commit.Author.Email }}" class="commit-email">{{ .commit.Author.Email}}</a>
12
-
<div>{{ .commit.Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div>
13
-
</div>
3
+
{{ define "content" }}
14
4
15
-
<div>
16
-
<strong>commit</strong>
17
-
<p><a href="/{{ .name }}/commit/{{ .commit.This }}" class="commit-hash">
18
-
{{ .commit.This }}
19
-
</a>
20
-
</p>
21
-
</div>
5
+
{{ $repo := .RepoInfo.Name }}
6
+
{{ $commit := .Diff.Commit }}
7
+
{{ $stat := .Diff.Stat }}
8
+
{{ $diff := .Diff.Diff }}
22
9
23
-
{{ if .commit.Parent }}
24
-
<div>
25
-
<strong>parent</strong>
26
-
<p><a href="/{{ .name }}/commit/{{ .commit.Parent }}" class="commit-hash">
27
-
{{ .commit.Parent }}
28
-
</a></p>
29
-
</div>
10
+
<section class="commit">
11
+
<pre>{{- $commit.Message -}}</pre>
12
+
<div class="commit-info">
13
+
{{ $commit.Author.Name }} <a href="mailto:{{ $commit.Author.Email }}" class="commit-email">{{ $commit.Author.Email}}</a>
14
+
<div>{{ $commit.Author.When.Format "Mon, 02 Jan 2006 15:04:05 -0700" }}</div>
15
+
</div>
30
16
31
-
{{ end }}
32
-
<div class="diff-stat">
33
-
<div>
34
-
{{ .stat.FilesChanged }} files changed,
35
-
{{ .stat.Insertions }} insertions(+),
36
-
{{ .stat.Deletions }} deletions(-)
37
-
</div>
38
-
<div>
39
-
<br>
40
-
<strong>jump to</strong>
41
-
{{ range .diff }}
42
-
<ul>
43
-
<li><a href="#{{ .Name.New }}">{{ .Name.New }}</a></li>
44
-
</ul>
45
-
{{ end }}
46
-
</div>
47
-
</div>
48
-
</section>
49
-
<section>
50
-
{{ $repo := .name }}
51
-
{{ $this := .commit.This }}
52
-
{{ $parent := .commit.Parent }}
53
-
{{ range .diff }}
54
-
<div id="{{ .Name.New }}">
55
-
<div class="diff">
56
-
{{ if .IsNew }}
57
-
<span class="diff-type">A</span>
58
-
{{ end }}
59
-
{{ if .IsDelete }}
60
-
<span class="diff-type">D</span>
61
-
{{ end }}
62
-
{{ if not (or .IsNew .IsDelete) }}
63
-
<span class="diff-type">M</span>
64
-
{{ end }}
65
-
{{ if .Name.Old }}
66
-
<a href="/{{ $repo }}/blob/{{ $parent }}/{{ .Name.Old }}">{{ .Name.Old }}</a>
67
-
{{ if .Name.New }}
68
-
→
69
-
<a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>
70
-
{{ end }}
71
-
{{ else }}
72
-
<a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>
73
-
{{- end -}}
74
-
{{ if .IsBinary }}
75
-
<p>Not showing binary file.</p>
76
-
{{ else }}
77
-
<pre>
78
-
{{- range .TextFragments -}}
79
-
<p>{{- .Header -}}</p>
80
-
{{- range .Lines -}}
81
-
{{- if eq .Op.String "+" -}}
82
-
<span class="diff-add">{{ .String }}</span>
83
-
{{- end -}}
84
-
{{- if eq .Op.String "-" -}}
85
-
<span class="diff-del">{{ .String }}</span>
86
-
{{- end -}}
87
-
{{- if eq .Op.String " " -}}
88
-
<span class="diff-noop">{{ .String }}</span>
89
-
{{- end -}}
90
-
{{- end -}}
91
-
{{- end -}}
92
-
{{- end -}}
93
-
</pre>
94
-
</div>
95
-
</div>
96
-
{{ end }}
97
-
</section>
98
-
</main>
99
-
</body>
100
-
</html>
17
+
<div>
18
+
<strong>commit</strong>
19
+
<p><a href="/{{ $repo }}/commit/{{ $commit.This }}" class="commit-hash">
20
+
{{ $commit.This }}
21
+
</a>
22
+
</p>
23
+
</div>
24
+
25
+
{{ if $commit.Parent }}
26
+
<div>
27
+
<strong>parent</strong>
28
+
<p><a href="/{{ $repo }}/commit/{{ $commit.Parent }}" class="commit-hash">
29
+
{{ $commit.Parent }}
30
+
</a></p>
31
+
</div>
32
+
33
+
{{ end }}
34
+
<div class="diff-stat">
35
+
<div>
36
+
{{ $stat.FilesChanged }} files changed,
37
+
{{ $stat.Insertions }} insertions(+),
38
+
{{ $stat.Deletions }} deletions(-)
39
+
</div>
40
+
<div>
41
+
<br>
42
+
<strong>jump to</strong>
43
+
{{ range $diff }}
44
+
<ul>
45
+
<li><a href="#{{ .Name.New }}">{{ .Name.New }}</a></li>
46
+
</ul>
47
+
{{ end }}
48
+
</div>
49
+
</div>
50
+
</section>
51
+
<section>
52
+
{{ $this := $commit.This }}
53
+
{{ $parent := $commit.Parent }}
54
+
{{ range $diff }}
55
+
<div id="{{ .Name.New }}">
56
+
<div class="diff">
57
+
{{ if .IsNew }}
58
+
<span class="diff-type">A</span>
59
+
{{ end }}
60
+
{{ if .IsDelete }}
61
+
<span class="diff-type">D</span>
62
+
{{ end }}
63
+
{{ if not (or .IsNew .IsDelete) }}
64
+
<span class="diff-type">M</span>
65
+
{{ end }}
66
+
{{ if .Name.Old }}
67
+
<a href="/{{ $repo }}/blob/{{ $parent }}/{{ .Name.Old }}">{{ .Name.Old }}</a>
68
+
{{ if .Name.New }}
69
+
→
70
+
<a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>
71
+
{{ end }}
72
+
{{ else }}
73
+
<a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>
74
+
{{- end -}}
75
+
{{ if .IsBinary }}
76
+
<p>Not showing binary file.</p>
77
+
{{ else }}
78
+
<pre>
79
+
{{- range .TextFragments -}}
80
+
<p>{{- .Header -}}</p>
81
+
{{- range .Lines -}}
82
+
{{- if eq .Op.String "+" -}}
83
+
<span class="diff-add">{{ .String }}</span>
84
+
{{- end -}}
85
+
{{- if eq .Op.String "-" -}}
86
+
<span class="diff-del">{{ .String }}</span>
87
+
{{- end -}}
88
+
{{- if eq .Op.String " " -}}
89
+
<span class="diff-noop">{{ .String }}</span>
90
+
{{- end -}}
91
+
{{- end -}}
92
+
{{- end -}}
93
+
{{- end -}}
94
+
</pre>
95
+
</div>
96
+
</div>
97
+
{{ end }}
98
+
</section>
99
+
100
+
{{end}}
+1
-1
appview/pages/templates/repo/empty.html
+1
-1
appview/pages/templates/repo/empty.html
+39
appview/state/repo.go
+39
appview/state/repo.go
···
94
94
return
95
95
}
96
96
97
+
func (s *State) RepoCommit(w http.ResponseWriter, r *http.Request) {
98
+
repoName, knot, id, err := repoKnotAndId(r)
99
+
if err != nil {
100
+
log.Println("failed to get repo and knot", err)
101
+
return
102
+
}
103
+
104
+
ref := chi.URLParam(r, "ref")
105
+
resp, err := http.Get(fmt.Sprintf("http://%s/%s/%s/commit/%s", knot, id.DID.String(), repoName, ref))
106
+
if err != nil {
107
+
log.Println("failed to reach knotserver", err)
108
+
return
109
+
}
110
+
111
+
body, err := io.ReadAll(resp.Body)
112
+
if err != nil {
113
+
log.Fatalf("Error reading response body: %v", err)
114
+
return
115
+
}
116
+
117
+
var result types.RepoCommitResponse
118
+
err = json.Unmarshal(body, &result)
119
+
if err != nil {
120
+
log.Println("failed to parse response:", err)
121
+
return
122
+
}
123
+
124
+
s.pages.RepoCommit(w, pages.RepoCommitParams{
125
+
LoggedInUser: s.auth.GetUser(r),
126
+
RepoInfo: pages.RepoInfo{
127
+
OwnerDid: id.DID.String(),
128
+
OwnerHandle: id.Handle.String(),
129
+
Name: repoName,
130
+
},
131
+
RepoCommitResponse: result,
132
+
})
133
+
return
134
+
}
135
+
97
136
func repoKnotAndId(r *http.Request) (string, string, identity.Identity, error) {
98
137
repoName := chi.URLParam(r, "repo")
99
138
knot, ok := r.Context().Value("knot").(string)
+1
appview/state/state.go
+1
appview/state/state.go
+5
-36
knotserver/git/diff.go
+5
-36
knotserver/git/diff.go
···
7
7
8
8
"github.com/bluekeyes/go-gitdiff/gitdiff"
9
9
"github.com/go-git/go-git/v5/plumbing/object"
10
+
"github.com/sotangled/tangled/types"
10
11
)
11
12
12
-
type TextFragment struct {
13
-
Header string
14
-
Lines []gitdiff.Line
15
-
}
16
-
17
-
type Diff struct {
18
-
Name struct {
19
-
Old string
20
-
New string
21
-
}
22
-
TextFragments []TextFragment
23
-
IsBinary bool
24
-
IsNew bool
25
-
IsDelete bool
26
-
}
27
-
28
-
// A nicer git diff representation.
29
-
type NiceDiff struct {
30
-
Commit struct {
31
-
Message string
32
-
Author object.Signature
33
-
This string
34
-
Parent string
35
-
}
36
-
Stat struct {
37
-
FilesChanged int
38
-
Insertions int
39
-
Deletions int
40
-
}
41
-
Diff []Diff
42
-
}
43
-
44
-
func (g *GitRepo) Diff() (*NiceDiff, error) {
13
+
func (g *GitRepo) Diff() (*types.NiceDiff, error) {
45
14
c, err := g.r.CommitObject(g.h)
46
15
if err != nil {
47
16
return nil, fmt.Errorf("commit object: %w", err)
···
76
45
log.Println(err)
77
46
}
78
47
79
-
nd := NiceDiff{}
48
+
nd := types.NiceDiff{}
80
49
nd.Commit.This = c.Hash.String()
81
50
82
51
if parent.Hash.IsZero() {
···
88
57
nd.Commit.Message = c.Message
89
58
90
59
for _, d := range diffs {
91
-
ndiff := Diff{}
60
+
ndiff := types.Diff{}
92
61
ndiff.Name.New = d.NewName
93
62
ndiff.Name.Old = d.OldName
94
63
ndiff.IsBinary = d.IsBinary
···
96
65
ndiff.IsDelete = d.IsDelete
97
66
98
67
for _, tf := range d.TextFragments {
99
-
ndiff.TextFragments = append(ndiff.TextFragments, TextFragment{
68
+
ndiff.TextFragments = append(ndiff.TextFragments, types.TextFragment{
100
69
Header: tf.Header(),
101
70
Lines: tf.Lines,
102
71
})
+5
-8
knotserver/routes.go
+5
-8
knotserver/routes.go
···
299
299
return
300
300
}
301
301
302
-
data := make(map[string]interface{})
302
+
resp := types.RepoCommitResponse{
303
+
Ref: ref,
304
+
Diff: diff,
305
+
}
303
306
304
-
data["commit"] = diff.Commit
305
-
data["stat"] = diff.Stat
306
-
data["diff"] = diff.Diff
307
-
data["ref"] = ref
308
-
data["desc"] = getDescription(path)
309
-
310
-
writeJSON(w, data)
307
+
writeJSON(w, resp)
311
308
return
312
309
}
313
310
+38
types/diff.go
+38
types/diff.go
···
1
+
package types
2
+
3
+
import (
4
+
"github.com/bluekeyes/go-gitdiff/gitdiff"
5
+
"github.com/go-git/go-git/v5/plumbing/object"
6
+
)
7
+
8
+
type TextFragment struct {
9
+
Header string `json:"header"`
10
+
Lines []gitdiff.Line `json:"lines"`
11
+
}
12
+
13
+
type Diff struct {
14
+
Name struct {
15
+
Old string `json:"old"`
16
+
New string `json:"new"`
17
+
} `json:"name"`
18
+
TextFragments []TextFragment `json:"text_fragments"`
19
+
IsBinary bool `json:"is_binary"`
20
+
IsNew bool `json:"is_new"`
21
+
IsDelete bool `json:"is_delete"`
22
+
}
23
+
24
+
// A nicer git diff representation.
25
+
type NiceDiff struct {
26
+
Commit struct {
27
+
Message string `json:"message"`
28
+
Author object.Signature `json:"author"`
29
+
This string `json:"this"`
30
+
Parent string `json:"parent"`
31
+
} `json:"commit"`
32
+
Stat struct {
33
+
FilesChanged int `json:"files_changed"`
34
+
Insertions int `json:"insertions"`
35
+
Deletions int `json:"deletions"`
36
+
} `json:"stat"`
37
+
Diff []Diff `json:"diff"`
38
+
}
+11
types/repo.go
+11
types/repo.go
···
23
23
Page int `json:"page,omitempty"`
24
24
PerPage int `json:"per_page,omitempty"`
25
25
}
26
+
27
+
// data["commit"] = diff.Commit
28
+
//
29
+
// data["stat"] = diff.Stat
30
+
// data["diff"] = diff.Diff
31
+
// data["ref"] = ref
32
+
// data["desc"] = getDescription(path)
33
+
type RepoCommitResponse struct {
34
+
Ref string `json:"ref,omitempty"`
35
+
Diff *NiceDiff `json:"diff,omitempty"`
36
+
}