tangled
alpha
login
or
join now
tjh.dev
/
core
forked from
tangled.org/core
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
add repo-tree template
oppi.li
1 year ago
eeef9e0b
9a5b1de9
+116
-54
9 changed files
expand all
collapse all
unified
split
appview
pages
pages.go
templates
repo
index.html
tree.html
state
repo.go
state.go
knotserver
git
tree.go
routes.go
types
repo.go
tree.go
+10
appview/pages/pages.go
···
175
175
func (p *Pages) RepoCommit(w io.Writer, params RepoCommitParams) error {
176
176
return p.execute("repo/commit", w, params)
177
177
}
178
178
+
179
179
+
type RepoTreeParams struct {
180
180
+
LoggedInUser *auth.User
181
181
+
RepoInfo RepoInfo
182
182
+
types.RepoTreeResponse
183
183
+
}
184
184
+
185
185
+
func (p *Pages) RepoTree(w io.Writer, params RepoTreeParams) error {
186
186
+
return p.execute("repo/tree", w, params)
187
187
+
}
+2
-2
appview/pages/templates/repo/index.html
···
1
1
-
{{define "title"}} {{ .RepoInfo.OwnerWithAt }} / {{ .RepoInfo.Name }} {{end}}
1
1
+
{{define "title"}} {{ .RepoInfo.FullName }} {{end}}
2
2
3
3
{{define "content"}}
4
4
5
5
<h1>
6
6
-
{{ .RepoInfo.OwnerWithAt }} / {{ .RepoInfo.Name }}
6
6
+
{{ .RepoInfo.FullName }}
7
7
</h1>
8
8
<main>
9
9
{{- if .IsEmpty }}
+21
-26
appview/pages/templates/repo/tree.html
···
1
1
-
<html>
1
1
+
{{define "title"}} {{ .RepoInfo.FullName }} {{end}}
2
2
3
3
-
{{ template "layouts/head" . }}
3
3
+
{{define "content"}}
4
4
5
5
-
{{ template "layouts/repo-header" . }}
6
6
-
<body>
7
7
-
{{ template "layouts/nav" . }}
5
5
+
<h1>
6
6
+
{{ .RepoInfo.FullName }}
7
7
+
</h1>
8
8
<main>
9
9
-
{{ $repo := .name }}
10
10
-
{{ $ref := .ref }}
11
11
-
{{ $parent := .parent }}
12
12
-
13
9
<div class="tree">
14
14
-
{{ if $parent }}
10
10
+
11
11
+
{{ if .Parent }}
15
12
<div></div>
16
13
<div></div>
17
17
-
<div><a href="/{{ $repo }}/tree/{{ $ref }}/{{ .dotdot }}">..</a></div>
14
14
+
<div><a href="/{{ .RepoInfo.FullName }}/tree/{{ .Ref }}/{{ .DotDot }}">..</a></div>
18
15
{{ end }}
19
19
-
{{ range .files }}
16
16
+
17
17
+
{{ range .Files }}
20
18
{{ if not .IsFile }}
21
19
<div class="mode">{{ .Mode }}</div>
22
20
<div class="size">{{ .Size }}</div>
23
21
<div>
24
24
-
{{ if $parent }}
25
25
-
<a href="/{{ $repo }}/tree/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}/</a>
22
22
+
{{ if $.Parent }}
23
23
+
<a href="/{{ .RepoInfo.FullName }}/tree/{{ $.Ref }}/{{ $.Parent }}/{{ .Name }}">{{ .Name }}/</a>
26
24
{{ else }}
27
27
-
<a href="/{{ $repo }}/tree/{{ $ref }}/{{ .Name }}">{{ .Name }}/</a>
25
25
+
<a href="/{{ .RepoInfo.FullName }}/tree/{{ $.Ref }}/{{ .Name }}">{{ .Name }}/</a>
28
26
{{ end }}
29
27
</div>
28
28
+
<hr />
30
29
{{ end }}
31
30
{{ end }}
32
32
-
{{ range .files }}
31
31
+
32
32
+
{{ range .Files }}
33
33
{{ if .IsFile }}
34
34
<div class="mode">{{ .Mode }}</div>
35
35
<div class="size">{{ .Size }}</div>
36
36
<div>
37
37
-
{{ if $parent }}
38
38
-
<a href="/{{ $repo }}/blob/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a>
37
37
+
{{ if $.Parent }}
38
38
+
<a href="/{{ $.RepoInfo.FullName }}/blob/{{ $.Ref }}/{{ $.Parent }}/{{ .Name }}">{{ .Name }}</a>
39
39
{{ else }}
40
40
-
<a href="/{{ $repo }}/blob/{{ $ref }}/{{ .Name }}">{{ .Name }}</a>
40
40
+
<a href="/{{ $.RepoInfo.FullName }}/blob/{{ $.Ref }}/{{ .Name }}">{{ .Name }}</a>
41
41
{{ end }}
42
42
</div>
43
43
+
<hr />
43
44
{{ end }}
44
45
{{ end }}
45
46
</div>
46
46
-
<article>
47
47
-
<pre>
48
48
-
{{- if .readme }}{{ .readme }}{{- end -}}
49
49
-
</pre>
50
50
-
</article>
51
47
</main>
52
52
-
</body>
53
53
-
</html>
48
48
+
{{end}}
+42
appview/state/repo.go
···
133
133
return
134
134
}
135
135
136
136
+
func (s *State) RepoTree(w http.ResponseWriter, r *http.Request) {
137
137
+
repoName, knot, id, err := repoKnotAndId(r)
138
138
+
if err != nil {
139
139
+
log.Println("failed to get repo and knot", err)
140
140
+
return
141
141
+
}
142
142
+
143
143
+
ref := chi.URLParam(r, "ref")
144
144
+
treePath := chi.URLParam(r, "*")
145
145
+
resp, err := http.Get(fmt.Sprintf("http://%s/%s/%s/tree/%s/%s", knot, id.DID.String(), repoName, ref, treePath))
146
146
+
if err != nil {
147
147
+
log.Println("failed to reach knotserver", err)
148
148
+
return
149
149
+
}
150
150
+
151
151
+
body, err := io.ReadAll(resp.Body)
152
152
+
if err != nil {
153
153
+
log.Fatalf("Error reading response body: %v", err)
154
154
+
return
155
155
+
}
156
156
+
157
157
+
var result types.RepoTreeResponse
158
158
+
err = json.Unmarshal(body, &result)
159
159
+
if err != nil {
160
160
+
log.Println("failed to parse response:", err)
161
161
+
return
162
162
+
}
163
163
+
164
164
+
log.Println(result)
165
165
+
166
166
+
s.pages.RepoTree(w, pages.RepoTreeParams{
167
167
+
LoggedInUser: s.auth.GetUser(r),
168
168
+
RepoInfo: pages.RepoInfo{
169
169
+
OwnerDid: id.DID.String(),
170
170
+
OwnerHandle: id.Handle.String(),
171
171
+
Name: repoName,
172
172
+
},
173
173
+
RepoTreeResponse: result,
174
174
+
})
175
175
+
return
176
176
+
}
177
177
+
136
178
func repoKnotAndId(r *http.Request) (string, string, identity.Identity, error) {
137
179
repoName := chi.URLParam(r, "repo")
138
180
knot, ok := r.Context().Value("knot").(string)
+3
appview/state/state.go
···
602
602
r.With(ResolveRepoKnot(s)).Route("/{repo}", func(r chi.Router) {
603
603
r.Get("/", s.RepoIndex)
604
604
r.Get("/log/{ref}", s.RepoLog)
605
605
+
r.Route("/tree/{ref}", func(r chi.Router) {
606
606
+
r.Get("/*", s.RepoTree)
607
607
+
})
605
608
r.Get("/commit/{ref}", s.RepoCommit)
606
609
607
610
// These routes get proxied to the knot
+6
-14
knotserver/git/tree.go
···
4
4
"fmt"
5
5
6
6
"github.com/go-git/go-git/v5/plumbing/object"
7
7
+
"github.com/sotangled/tangled/types"
7
8
)
8
9
9
9
-
func (g *GitRepo) FileTree(path string) ([]NiceTree, error) {
10
10
+
func (g *GitRepo) FileTree(path string) ([]types.NiceTree, error) {
10
11
c, err := g.r.CommitObject(g.h)
11
12
if err != nil {
12
13
return nil, fmt.Errorf("commit object: %w", err)
13
14
}
14
15
15
15
-
files := []NiceTree{}
16
16
+
files := []types.NiceTree{}
16
17
tree, err := c.Tree()
17
18
if err != nil {
18
19
return nil, fmt.Errorf("file tree: %w", err)
···
39
40
return files, nil
40
41
}
41
42
42
42
-
// A nicer git tree representation.
43
43
-
type NiceTree struct {
44
44
-
Name string
45
45
-
Mode string
46
46
-
Size int64
47
47
-
IsFile bool
48
48
-
IsSubtree bool
49
49
-
}
50
50
-
51
51
-
func makeNiceTree(t *object.Tree) []NiceTree {
52
52
-
nts := []NiceTree{}
43
43
+
func makeNiceTree(t *object.Tree) []types.NiceTree {
44
44
+
nts := []types.NiceTree{}
53
45
54
46
for _, e := range t.Entries {
55
47
mode, _ := e.Mode.ToOSFileMode()
56
48
sz, _ := t.Size(e.Name)
57
57
-
nts = append(nts, NiceTree{
49
49
+
nts = append(nts, types.NiceTree{
58
50
Name: e.Name,
59
51
Mode: mode.String(),
60
52
IsFile: e.Mode.IsFile(),
+14
-6
knotserver/routes.go
···
122
122
return
123
123
}
124
124
125
125
-
data := make(map[string]any)
126
126
-
data["ref"] = ref
127
127
-
data["parent"] = treePath
128
128
-
data["desc"] = getDescription(path)
129
129
-
data["dotdot"] = filepath.Dir(treePath)
125
125
+
resp := types.RepoTreeResponse{
126
126
+
Ref: ref,
127
127
+
Parent: treePath,
128
128
+
Description: getDescription(path),
129
129
+
DotDot: filepath.Dir(treePath),
130
130
+
Files: files,
131
131
+
}
132
132
+
// data := make(map[string]any)
133
133
+
// data["ref"] = ref
134
134
+
// data["parent"] = treePath
135
135
+
// data["desc"] = getDescription(path)
136
136
+
// data["dotdot"] = filepath.Dir(treePath)
130
137
131
131
-
h.listFiles(files, data, w)
138
138
+
writeJSON(w, resp)
139
139
+
// h.listFiles(files, data, w)
132
140
return
133
141
}
134
142
+8
-6
types/repo.go
···
24
24
PerPage int `json:"per_page,omitempty"`
25
25
}
26
26
27
27
-
// data["commit"] = diff.Commit
28
28
-
//
29
29
-
// data["stat"] = diff.Stat
30
30
-
// data["diff"] = diff.Diff
31
31
-
// data["ref"] = ref
32
32
-
// data["desc"] = getDescription(path)
33
27
type RepoCommitResponse struct {
34
28
Ref string `json:"ref,omitempty"`
35
29
Diff *NiceDiff `json:"diff,omitempty"`
36
30
}
31
31
+
32
32
+
type RepoTreeResponse struct {
33
33
+
Ref string `json:"ref,omitempty"`
34
34
+
Parent string `json:"parent,omitempty"`
35
35
+
Description string `json:"description,omitempty"`
36
36
+
DotDot string `json:"dotdot,omitempty"`
37
37
+
Files []NiceTree `json:"files,omitempty"`
38
38
+
}
+10
types/tree.go
···
1
1
+
package types
2
2
+
3
3
+
// A nicer git tree representation.
4
4
+
type NiceTree struct {
5
5
+
Name string
6
6
+
Mode string
7
7
+
Size int64
8
8
+
IsFile bool
9
9
+
IsSubtree bool
10
10
+
}