A vibe coded tangled fork which supports pijul.
1package vcs
2
3import (
4 "context"
5 "io"
6
7 "tangled.org/core/knotserver/pijul"
8)
9
10// pijulReadAdapter wraps a pijul.PijulRepo to implement ReadRepo.
11type pijulReadAdapter struct {
12 p *pijul.PijulRepo
13}
14
15func newPijulReadAdapter(p *pijul.PijulRepo) *pijulReadAdapter {
16 return &pijulReadAdapter{p: p}
17}
18
19func (a *pijulReadAdapter) VCSType() string { return "pijul" }
20func (a *pijulReadAdapter) Path() string { return a.p.Path() }
21
22func (a *pijulReadAdapter) History(offset, limit int) ([]HistoryEntry, error) {
23 changes, err := a.p.Changes(offset, limit)
24 if err != nil {
25 return nil, err
26 }
27
28 entries := make([]HistoryEntry, 0, len(changes))
29 for _, c := range changes {
30 var author Author
31 if len(c.Authors) > 0 {
32 author = Author{
33 Name: c.Authors[0].Name,
34 Email: c.Authors[0].Email,
35 }
36 }
37 entries = append(entries, HistoryEntry{
38 Hash: c.Hash,
39 Author: author,
40 Committer: author,
41 Message: c.Message,
42 Timestamp: c.Timestamp,
43 Parents: c.Dependencies,
44 })
45 }
46 return entries, nil
47}
48
49func (a *pijulReadAdapter) TotalHistoryEntries() (int, error) {
50 return a.p.TotalChanges()
51}
52
53func (a *pijulReadAdapter) HistoryEntry(hash string) (*HistoryEntry, error) {
54 c, err := a.p.GetChange(hash)
55 if err != nil {
56 return nil, err
57 }
58
59 var author Author
60 if len(c.Authors) > 0 {
61 author = Author{
62 Name: c.Authors[0].Name,
63 Email: c.Authors[0].Email,
64 }
65 }
66
67 return &HistoryEntry{
68 Hash: c.Hash,
69 Author: author,
70 Committer: author,
71 Message: c.Message,
72 Timestamp: c.Timestamp,
73 Parents: c.Dependencies,
74 }, nil
75}
76
77func (a *pijulReadAdapter) Branches(opts *PaginationOpts) ([]BranchInfo, error) {
78 var pijulOpts *pijul.ChannelOptions
79 if opts != nil {
80 pijulOpts = &pijul.ChannelOptions{
81 Limit: opts.Limit,
82 Offset: opts.Offset,
83 }
84 }
85
86 channels, err := a.p.ChannelsWithOptions(pijulOpts)
87 if err != nil {
88 return nil, err
89 }
90
91 infos := make([]BranchInfo, 0, len(channels))
92 for _, ch := range channels {
93 infos = append(infos, BranchInfo{
94 Name: ch.Name,
95 IsDefault: ch.IsCurrent,
96 })
97 }
98 return infos, nil
99}
100
101func (a *pijulReadAdapter) DefaultBranch() (string, error) {
102 return a.p.FindDefaultChannel()
103}
104
105func (a *pijulReadAdapter) FileTree(ctx context.Context, path string) ([]TreeEntry, error) {
106 files, err := a.p.FileTree(ctx, path)
107 if err != nil {
108 return nil, err
109 }
110
111 entries := make([]TreeEntry, 0, len(files))
112 for _, f := range files {
113 entries = append(entries, TreeEntry{
114 Name: f.Name,
115 Mode: f.Mode,
116 Size: f.Size,
117 })
118 }
119 return entries, nil
120}
121
122func (a *pijulReadAdapter) FileContentN(path string, cap int64) ([]byte, error) {
123 return a.p.FileContentN(path, cap)
124}
125
126func (a *pijulReadAdapter) RawContent(path string) ([]byte, error) {
127 return a.p.RawContent(path)
128}
129
130func (a *pijulReadAdapter) WriteTar(w io.Writer, prefix string) error {
131 return a.p.WriteTar(w, prefix)
132}
133
134func (a *pijulReadAdapter) Tags(_ *PaginationOpts) ([]TagInfo, error) {
135 // Pijul doesn't have tags.
136 return nil, nil
137}
138
139// pijulMutableAdapter wraps a pijul.PijulRepo to implement MutableRepo.
140type pijulMutableAdapter struct {
141 *pijulReadAdapter
142}
143
144func newPijulMutableAdapter(p *pijul.PijulRepo) *pijulMutableAdapter {
145 return &pijulMutableAdapter{pijulReadAdapter: newPijulReadAdapter(p)}
146}
147
148func (a *pijulMutableAdapter) SetDefaultBranch(name string) error {
149 return a.p.SetDefaultChannel(name)
150}
151
152func (a *pijulMutableAdapter) DeleteBranch(name string) error {
153 return a.p.DeleteChannel(name)
154}
155
156// Pijul returns the underlying *pijul.PijulRepo for pijul-specific operations
157// that don't belong in the VCS interface.
158func (a *pijulReadAdapter) Pijul() *pijul.PijulRepo {
159 return a.p
160}