+24
.air.toml
+24
.air.toml
···
···
1
+
root = "."
2
+
testdata_dir = "testdata"
3
+
tmp_dir = "tmp"
4
+
5
+
[build]
6
+
bin = "./ugitd"
7
+
cmd = "go build ./cmd/ugitd"
8
+
delay = 1000
9
+
exclude_file = ["internal/html/tailwind.go"]
10
+
exclude_regex = ["_test.go"]
11
+
exclude_unchanged = true
12
+
include_ext = ["go"]
13
+
pre_cmd = ["go generate ./..."]
14
+
15
+
[misc]
16
+
clean_on_exit = true
17
+
18
+
[proxy]
19
+
app_port = 8449
20
+
enabled = true
21
+
proxy_port = 8450
22
+
23
+
[screen]
24
+
clear_on_rebuild = true
-5
.helix/languages.toml
-5
.helix/languages.toml
+4
-4
README.md
+4
-4
README.md
···
2
<picture>
3
<img alt="ugit logo" width="250" src="./assets/ugit.svg" />
4
</picture>
5
-
<h3 align="center">ugit</h3>
6
</p>
7
8
Minimal git server
9
10
-
ugit allows cloning via HTTPS/SSH, but can only be pushed to via SSH.
11
12
There are no plans to directly support issues or PR workflows, although webhooks are planned and auxillary software may be created to facilitate these things.
13
-
For now, if you wish to collaborate, please send me patches at [ugit@jolheiser.com](mailto:git@jolheiser.com).
14
15
-
Currently all HTML is allowed in markdown, ugit is intended to be run by/for a trusted user.
16
17
## Getting your public SSH keys from another forge
18
···
2
<picture>
3
<img alt="ugit logo" width="250" src="./assets/ugit.svg" />
4
</picture>
5
+
<h3 align="center">ยตgit</h3>
6
</p>
7
8
Minimal git server
9
10
+
ยตgit allows cloning via HTTPS/SSH, but can only be pushed to via SSH.
11
12
There are no plans to directly support issues or PR workflows, although webhooks are planned and auxillary software may be created to facilitate these things.
13
+
If you wish to collaborate, please send me patches via [git-pr](https://pr.jolheiser.com/repos/ugit).
14
15
+
Currently all HTML is allowed in markdown, ยตgit is intended to be run by/for a trusted user.
16
17
## Getting your public SSH keys from another forge
18
+1
-1
assets/ugit.svg
+1
-1
assets/ugit.svg
···
1
<?xml version="1.0" encoding="UTF-8"?>
2
<svg viewBox="0 0 24 24" stroke="#de4c36" fill="#de4c36" stroke-width="1" xmlns="http://www.w3.org/2000/svg">
3
-
<title>ugit icon</title>
4
<rect fill="none" x="1" y="1" rx="1" ry="1" width="22" height="22"></rect>
5
<ellipse cx="6" cy="6" rx="2" ry="2"></ellipse>
6
<ellipse cx="18" cy="6" rx="2" ry="2"></ellipse>
···
1
<?xml version="1.0" encoding="UTF-8"?>
2
<svg viewBox="0 0 24 24" stroke="#de4c36" fill="#de4c36" stroke-width="1" xmlns="http://www.w3.org/2000/svg">
3
+
<title>ยตgit icon</title>
4
<rect fill="none" x="1" y="1" rx="1" ry="1" width="22" height="22"></rect>
5
<ellipse cx="6" cy="6" rx="2" ry="2"></ellipse>
6
<ellipse cx="18" cy="6" rx="2" ry="2"></ellipse>
+69
cmd/ugitd/args.cue
+69
cmd/ugitd/args.cue
···
···
1
+
import "strings"
2
+
3
+
// Schema
4
+
#Port: int & >0 & <65536
5
+
#Link: string & strings.Contains(",")
6
+
7
+
#Config: {
8
+
"repo-dir": string
9
+
"show-private": bool
10
+
ssh: {
11
+
enable: bool
12
+
"authorized-keys": string
13
+
"clone-url": string
14
+
port: #Port
15
+
"host-key": string
16
+
}
17
+
http: {
18
+
enable: bool
19
+
"clone-url": string
20
+
port: #Port
21
+
}
22
+
meta: {
23
+
title: string
24
+
description: string
25
+
}
26
+
profile?: {
27
+
username?: string
28
+
email?: string
29
+
links?: [...#Link]
30
+
}
31
+
log: {
32
+
json: bool
33
+
level: "debug" | "info" | "warn" | "warning" | "error"
34
+
}
35
+
36
+
// Constraints
37
+
if ssh.port == http.port {
38
+
error("ssh.port and http.port cannot be the same")
39
+
}
40
+
}
41
+
42
+
// Defaults
43
+
#Config: {
44
+
"repo-dir": ".ugit"
45
+
"show-private": false
46
+
ssh: {
47
+
enable: true
48
+
"authorized-keys": ".ssh/authorized_keys"
49
+
"clone-url": "ssh://localhost:8448"
50
+
port: 8448
51
+
"host-key": ".ssh/ugit_ed25519"
52
+
}
53
+
http: {
54
+
enable: true
55
+
"clone-url": "http://localhost:8449"
56
+
port: 8449
57
+
}
58
+
meta: {
59
+
title: "uGit"
60
+
description: "Minimal git server"
61
+
}
62
+
log: {
63
+
json: false
64
+
level: "info"
65
+
}
66
+
}
67
+
68
+
// Apply schema
69
+
#Config
+39
-15
cmd/ugitd/args.go
+39
-15
cmd/ugitd/args.go
···
1
package main
2
3
import (
4
"flag"
5
"fmt"
6
"strings"
7
8
-
"github.com/charmbracelet/log"
9
"github.com/peterbourgon/ff/v3"
10
-
"github.com/peterbourgon/ff/v3/ffyaml"
11
)
12
13
type cliArgs struct {
14
-
RepoDir string
15
-
SSH sshArgs
16
-
HTTP httpArgs
17
-
Meta metaArgs
18
-
Profile profileArgs
19
-
Log logArgs
20
}
21
22
type sshArgs struct {
23
AuthorizedKeys string
24
CloneURL string
25
Port int
···
27
}
28
29
type httpArgs struct {
30
CloneURL string
31
Port int
32
}
···
48
}
49
50
type logArgs struct {
51
-
Level log.Level
52
JSON bool
53
}
54
55
func parseArgs(args []string) (c cliArgs, e error) {
56
fs := flag.NewFlagSet("ugitd", flag.ContinueOnError)
57
-
fs.String("config", "ugit.yaml", "Path to config file")
58
59
c = cliArgs{
60
RepoDir: ".ugit",
61
SSH: sshArgs{
62
AuthorizedKeys: ".ssh/authorized_keys",
63
CloneURL: "ssh://localhost:8448",
64
Port: 8448,
65
HostKey: ".ssh/ugit_ed25519",
66
},
67
HTTP: httpArgs{
68
CloneURL: "http://localhost:8449",
69
Port: 8449,
70
},
···
73
Description: "Minimal git server",
74
},
75
Log: logArgs{
76
-
Level: log.InfoLevel,
77
},
78
}
79
80
fs.Func("log.level", "Logging level", func(s string) error {
81
-
lvl, err := log.ParseLevel(s)
82
-
if err != nil {
83
-
return err
84
}
85
c.Log.Level = lvl
86
return nil
87
})
88
fs.BoolVar(&c.Log.JSON, "log.json", c.Log.JSON, "Print logs in JSON(L) format")
89
fs.StringVar(&c.RepoDir, "repo-dir", c.RepoDir, "Path to directory containing repositories")
90
fs.StringVar(&c.SSH.AuthorizedKeys, "ssh.authorized-keys", c.SSH.AuthorizedKeys, "Path to authorized_keys")
91
fs.StringVar(&c.SSH.CloneURL, "ssh.clone-url", c.SSH.CloneURL, "SSH clone URL base")
92
fs.IntVar(&c.SSH.Port, "ssh.port", c.SSH.Port, "SSH port")
93
fs.StringVar(&c.SSH.HostKey, "ssh.host-key", c.SSH.HostKey, "SSH host key (created if it doesn't exist)")
94
fs.StringVar(&c.HTTP.CloneURL, "http.clone-url", c.HTTP.CloneURL, "HTTP clone URL base")
95
fs.IntVar(&c.HTTP.Port, "http.port", c.HTTP.Port, "HTTP port")
96
fs.StringVar(&c.Meta.Title, "meta.title", c.Meta.Title, "App title")
···
109
return nil
110
})
111
112
return c, ff.Parse(fs, args,
113
ff.WithEnvVarPrefix("UGIT"),
114
ff.WithConfigFileFlag("config"),
115
ff.WithAllowMissingConfigFile(true),
116
-
ff.WithConfigFileParser(ffyaml.Parser),
117
)
118
}
···
1
package main
2
3
import (
4
+
_ "embed"
5
"flag"
6
"fmt"
7
+
"log/slog"
8
"strings"
9
10
"github.com/peterbourgon/ff/v3"
11
+
"go.jolheiser.com/ffcue"
12
)
13
14
+
//go:embed args.cue
15
+
var schema string
16
+
17
type cliArgs struct {
18
+
RepoDir string
19
+
SSH sshArgs
20
+
HTTP httpArgs
21
+
Meta metaArgs
22
+
Profile profileArgs
23
+
Log logArgs
24
+
ShowPrivate bool
25
}
26
27
type sshArgs struct {
28
+
Enable bool
29
AuthorizedKeys string
30
CloneURL string
31
Port int
···
33
}
34
35
type httpArgs struct {
36
+
Enable bool
37
CloneURL string
38
Port int
39
}
···
55
}
56
57
type logArgs struct {
58
+
Level slog.Level
59
JSON bool
60
}
61
62
func parseArgs(args []string) (c cliArgs, e error) {
63
fs := flag.NewFlagSet("ugitd", flag.ContinueOnError)
64
+
fs.String("config", "ugit.cue", "Path to config file")
65
66
c = cliArgs{
67
RepoDir: ".ugit",
68
SSH: sshArgs{
69
+
Enable: true,
70
AuthorizedKeys: ".ssh/authorized_keys",
71
CloneURL: "ssh://localhost:8448",
72
Port: 8448,
73
HostKey: ".ssh/ugit_ed25519",
74
},
75
HTTP: httpArgs{
76
+
Enable: true,
77
CloneURL: "http://localhost:8449",
78
Port: 8449,
79
},
···
82
Description: "Minimal git server",
83
},
84
Log: logArgs{
85
+
Level: slog.LevelError,
86
},
87
}
88
89
fs.Func("log.level", "Logging level", func(s string) error {
90
+
var lvl slog.Level
91
+
switch strings.ToLower(s) {
92
+
case "debug":
93
+
lvl = slog.LevelDebug
94
+
case "info":
95
+
lvl = slog.LevelInfo
96
+
case "warn", "warning":
97
+
lvl = slog.LevelWarn
98
+
case "error":
99
+
lvl = slog.LevelError
100
+
default:
101
+
return fmt.Errorf("unknown log level %q: options are [debug, info, warn, error]", s)
102
}
103
c.Log.Level = lvl
104
return nil
105
})
106
fs.BoolVar(&c.Log.JSON, "log.json", c.Log.JSON, "Print logs in JSON(L) format")
107
fs.StringVar(&c.RepoDir, "repo-dir", c.RepoDir, "Path to directory containing repositories")
108
+
fs.BoolVar(&c.ShowPrivate, "show-private", c.ShowPrivate, "Show private repos in web interface")
109
+
fs.BoolVar(&c.SSH.Enable, "ssh.enable", c.SSH.Enable, "Enable SSH server")
110
fs.StringVar(&c.SSH.AuthorizedKeys, "ssh.authorized-keys", c.SSH.AuthorizedKeys, "Path to authorized_keys")
111
fs.StringVar(&c.SSH.CloneURL, "ssh.clone-url", c.SSH.CloneURL, "SSH clone URL base")
112
fs.IntVar(&c.SSH.Port, "ssh.port", c.SSH.Port, "SSH port")
113
fs.StringVar(&c.SSH.HostKey, "ssh.host-key", c.SSH.HostKey, "SSH host key (created if it doesn't exist)")
114
+
fs.BoolVar(&c.HTTP.Enable, "http.enable", c.HTTP.Enable, "Enable HTTP server")
115
fs.StringVar(&c.HTTP.CloneURL, "http.clone-url", c.HTTP.CloneURL, "HTTP clone URL base")
116
fs.IntVar(&c.HTTP.Port, "http.port", c.HTTP.Port, "HTTP port")
117
fs.StringVar(&c.Meta.Title, "meta.title", c.Meta.Title, "App title")
···
130
return nil
131
})
132
133
+
parser := &ffcue.ParseConfig{
134
+
Constraints: schema,
135
+
}
136
return c, ff.Parse(fs, args,
137
ff.WithEnvVarPrefix("UGIT"),
138
ff.WithConfigFileFlag("config"),
139
ff.WithAllowMissingConfigFile(true),
140
+
ff.WithConfigFileParser(parser.Parse),
141
)
142
}
+43
-28
cmd/ugitd/main.go
+43
-28
cmd/ugitd/main.go
···
4
"errors"
5
"flag"
6
"fmt"
7
"log/slog"
8
"os"
9
"os/signal"
10
"path/filepath"
11
"strconv"
12
"strings"
13
14
-
"github.com/charmbracelet/log"
15
"github.com/go-chi/chi/v5/middleware"
16
"github.com/go-chi/httplog/v2"
17
"github.com/go-git/go-git/v5/plumbing/protocol/packp"
···
39
panic(err)
40
}
41
42
-
log.SetLevel(args.Log.Level)
43
middleware.DefaultLogger = httplog.RequestLogger(httplog.NewLogger("ugit", httplog.Options{
44
JSON: args.Log.JSON,
45
LogLevel: slog.Level(args.Log.Level),
46
-
Concise: args.Log.Level != log.DebugLevel,
47
}))
48
49
-
if args.Log.Level == log.DebugLevel {
50
trace.SetTarget(trace.Packet)
51
} else {
52
middleware.DefaultLogger = http.NoopLogger
···
54
}
55
56
if args.Log.JSON {
57
-
log.SetFormatter(log.JSONFormatter)
58
}
59
60
if err := requiredFS(args.RepoDir); err != nil {
61
panic(err)
62
}
63
64
-
sshSettings := ssh.Settings{
65
-
AuthorizedKeys: args.SSH.AuthorizedKeys,
66
-
CloneURL: args.SSH.CloneURL,
67
-
Port: args.SSH.Port,
68
-
HostKey: args.SSH.HostKey,
69
-
RepoDir: args.RepoDir,
70
-
}
71
-
sshSrv, err := ssh.New(sshSettings)
72
-
if err != nil {
73
-
panic(err)
74
-
}
75
-
go func() {
76
-
log.Debugf("SSH listening on ssh://localhost:%d\n", sshSettings.Port)
77
-
if err := sshSrv.ListenAndServe(); err != nil {
78
panic(err)
79
}
80
-
}()
81
82
httpSettings := http.Settings{
83
Title: args.Meta.Title,
···
89
Username: args.Profile.Username,
90
Email: args.Profile.Email,
91
},
92
}
93
for _, link := range args.Profile.Links {
94
httpSettings.Profile.Links = append(httpSettings.Profile.Links, http.Link{
···
96
URL: link.URL,
97
})
98
}
99
-
httpSrv := http.New(httpSettings)
100
-
go func() {
101
-
log.Debugf("HTTP listening on http://localhost:%d\n", httpSettings.Port)
102
-
if err := httpSrv.ListenAndServe(); err != nil {
103
-
panic(err)
104
-
}
105
-
}()
106
107
ch := make(chan os.Signal, 1)
108
-
signal.Notify(ch, os.Kill, os.Interrupt)
109
<-ch
110
}
111
···
128
}
129
fp = filepath.Join(fp, "pre-receive")
130
131
fi, err := os.Create(fp)
132
if err != nil {
133
return err
134
}
135
fi.WriteString("#!/usr/bin/env bash\n")
136
fi.WriteString(fmt.Sprintf("%s pre-receive-hook\n", bin))
137
fi.Close()
138
139
return os.Chmod(fp, 0o755)
···
4
"errors"
5
"flag"
6
"fmt"
7
+
"log"
8
"log/slog"
9
"os"
10
"os/signal"
11
"path/filepath"
12
"strconv"
13
"strings"
14
+
"syscall"
15
16
"github.com/go-chi/chi/v5/middleware"
17
"github.com/go-chi/httplog/v2"
18
"github.com/go-git/go-git/v5/plumbing/protocol/packp"
···
40
panic(err)
41
}
42
43
+
slog.SetLogLoggerLevel(args.Log.Level)
44
middleware.DefaultLogger = httplog.RequestLogger(httplog.NewLogger("ugit", httplog.Options{
45
JSON: args.Log.JSON,
46
LogLevel: slog.Level(args.Log.Level),
47
+
Concise: args.Log.Level != slog.LevelDebug,
48
}))
49
50
+
if args.Log.Level == slog.LevelDebug {
51
trace.SetTarget(trace.Packet)
52
} else {
53
middleware.DefaultLogger = http.NoopLogger
···
55
}
56
57
if args.Log.JSON {
58
+
logger := slog.New(slog.NewJSONHandler(os.Stderr, nil))
59
+
slog.SetDefault(logger)
60
}
61
62
if err := requiredFS(args.RepoDir); err != nil {
63
panic(err)
64
}
65
66
+
if args.SSH.Enable {
67
+
sshSettings := ssh.Settings{
68
+
AuthorizedKeys: args.SSH.AuthorizedKeys,
69
+
CloneURL: args.SSH.CloneURL,
70
+
Port: args.SSH.Port,
71
+
HostKey: args.SSH.HostKey,
72
+
RepoDir: args.RepoDir,
73
+
}
74
+
sshSrv, err := ssh.New(sshSettings)
75
+
if err != nil {
76
panic(err)
77
}
78
+
go func() {
79
+
log.Printf("SSH listening on ssh://localhost:%d\n", sshSettings.Port)
80
+
if err := sshSrv.ListenAndServe(); err != nil {
81
+
panic(err)
82
+
}
83
+
}()
84
+
}
85
86
httpSettings := http.Settings{
87
Title: args.Meta.Title,
···
93
Username: args.Profile.Username,
94
Email: args.Profile.Email,
95
},
96
+
ShowPrivate: args.ShowPrivate,
97
}
98
for _, link := range args.Profile.Links {
99
httpSettings.Profile.Links = append(httpSettings.Profile.Links, http.Link{
···
101
URL: link.URL,
102
})
103
}
104
+
if args.HTTP.Enable {
105
+
httpSrv := http.New(httpSettings)
106
+
go func() {
107
+
log.Printf("HTTP listening on http://localhost:%d\n", httpSettings.Port)
108
+
if err := httpSrv.ListenAndServe(); err != nil {
109
+
panic(err)
110
+
}
111
+
}()
112
+
}
113
114
ch := make(chan os.Signal, 1)
115
+
signal.Notify(ch, syscall.SIGTERM, os.Interrupt)
116
<-ch
117
}
118
···
135
}
136
fp = filepath.Join(fp, "pre-receive")
137
138
+
if err := os.MkdirAll(fp+".d", os.ModePerm); err != nil {
139
+
return err
140
+
}
141
+
142
fi, err := os.Create(fp)
143
if err != nil {
144
return err
145
}
146
fi.WriteString("#!/usr/bin/env bash\n")
147
fi.WriteString(fmt.Sprintf("%s pre-receive-hook\n", bin))
148
+
fi.WriteString(fmt.Sprintf(`for hook in %s.d/*; do
149
+
test -x "${hook}" && test -f "${hook}" || continue
150
+
"${hook}"
151
+
done`, fp))
152
fi.Close()
153
154
return os.Chmod(fp, 0o755)
+3
-9
contrib/layout.kdl
+3
-9
contrib/layout.kdl
···
5
command "nix"
6
args "develop"
7
size "90%"
8
-
start_suspended true
9
}
10
pane split_direction="vertical" {
11
pane {
12
-
name "run"
13
-
command "go"
14
-
args "run" "./cmd/ugitd"
15
-
start_suspended true
16
-
}
17
-
pane {
18
-
name "watch"
19
command "nix"
20
-
args "develop" "--command" "nu" "-c" "watch --glob *.templ ./internal/html/ {|| go generate ./...}"
21
}
22
}
23
}
+3
-58
flake.lock
+3
-58
flake.lock
···
1
{
2
"nodes": {
3
-
"flake-utils": {
4
-
"inputs": {
5
-
"systems": "systems"
6
-
},
7
-
"locked": {
8
-
"lastModified": 1694529238,
9
-
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
10
-
"owner": "numtide",
11
-
"repo": "flake-utils",
12
-
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
13
-
"type": "github"
14
-
},
15
-
"original": {
16
-
"owner": "numtide",
17
-
"repo": "flake-utils",
18
-
"type": "github"
19
-
}
20
-
},
21
-
"gomod2nix": {
22
-
"inputs": {
23
-
"flake-utils": "flake-utils",
24
-
"nixpkgs": [
25
-
"nixpkgs"
26
-
]
27
-
},
28
-
"locked": {
29
-
"lastModified": 1717050755,
30
-
"narHash": "sha256-C9IEHABulv2zEDFA+Bf0E1nmfN4y6MIUe5eM2RCrDC0=",
31
-
"owner": "nix-community",
32
-
"repo": "gomod2nix",
33
-
"rev": "31b6d2e40b36456e792cd6cf50d5a8ddd2fa59a1",
34
-
"type": "github"
35
-
},
36
-
"original": {
37
-
"owner": "nix-community",
38
-
"repo": "gomod2nix",
39
-
"type": "github"
40
-
}
41
-
},
42
"nixpkgs": {
43
"locked": {
44
-
"lastModified": 1719379843,
45
-
"narHash": "sha256-u+D+IOAMMl70+CJ9NKB+RMrASjInuIWMHzjLWQjPZ6c=",
46
"owner": "nixos",
47
"repo": "nixpkgs",
48
-
"rev": "b3f3c1b13fb08f3828442ee86630362e81136bbc",
49
"type": "github"
50
},
51
"original": {
···
57
},
58
"root": {
59
"inputs": {
60
-
"gomod2nix": "gomod2nix",
61
"nixpkgs": "nixpkgs",
62
"tailwind-ctp": "tailwind-ctp",
63
"tailwind-ctp-lsp": "tailwind-ctp-lsp"
64
-
}
65
-
},
66
-
"systems": {
67
-
"locked": {
68
-
"lastModified": 1681028828,
69
-
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
70
-
"owner": "nix-systems",
71
-
"repo": "default",
72
-
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
73
-
"type": "github"
74
-
},
75
-
"original": {
76
-
"owner": "nix-systems",
77
-
"repo": "default",
78
-
"type": "github"
79
}
80
},
81
"tailwind-ctp": {
···
1
{
2
"nodes": {
3
"nixpkgs": {
4
"locked": {
5
+
"lastModified": 1755205935,
6
+
"narHash": "sha256-EQ6qHuJWguaoBZyxdqsgJqyEdS77k+2CnlKrfFxlkRY=",
7
"owner": "nixos",
8
"repo": "nixpkgs",
9
+
"rev": "c5e2e42c112de623adfd662b3e51f0805bf9ff83",
10
"type": "github"
11
},
12
"original": {
···
18
},
19
"root": {
20
"inputs": {
21
"nixpkgs": "nixpkgs",
22
"tailwind-ctp": "tailwind-ctp",
23
"tailwind-ctp-lsp": "tailwind-ctp-lsp"
24
}
25
},
26
"tailwind-ctp": {
+67
-153
flake.nix
+67
-153
flake.nix
···
3
4
inputs = {
5
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
6
-
gomod2nix = {
7
-
url = "github:nix-community/gomod2nix";
8
-
inputs.nixpkgs.follows = "nixpkgs";
9
-
};
10
tailwind-ctp = {
11
url = "git+https://git.jolheiser.com/tailwind-ctp";
12
inputs.nixpkgs.follows = "nixpkgs";
···
17
};
18
};
19
20
-
outputs = {
21
-
self,
22
-
nixpkgs,
23
-
gomod2nix,
24
-
tailwind-ctp,
25
-
tailwind-ctp-lsp,
26
-
} @ inputs: let
27
-
system = "x86_64-linux";
28
-
pkgs = nixpkgs.legacyPackages.${system};
29
-
tailwind-ctp = inputs.tailwind-ctp.packages.${system}.default;
30
-
tailwind-ctp-lsp = inputs.tailwind-ctp-lsp.packages.${system}.default;
31
-
ugit = gomod2nix.legacyPackages.${system}.buildGoApplication rec {
32
-
name = "ugitd";
33
-
src = pkgs.nix-gitignore.gitignoreSource [] (builtins.path {
34
-
inherit name;
35
-
path = ./.;
36
-
});
37
-
pwd = ./.;
38
-
subPackages = ["cmd/ugitd"];
39
-
CGO_ENABLED = 0;
40
-
flags = [
41
-
"-trimpath"
42
-
];
43
-
ldflags = [
44
-
"-s"
45
-
"-w"
46
-
"-extldflags -static"
47
-
];
48
-
meta = with pkgs.lib; {
49
-
description = "Minimal git server";
50
-
homepage = "https://git.jolheiser.com/ugit";
51
-
maintainers = with maintainers; [jolheiser];
52
-
mainProgram = "ugitd";
53
-
};
54
-
};
55
-
in {
56
-
packages.${system}.default = ugit;
57
-
devShells.${system}.default = pkgs.mkShell {
58
-
nativeBuildInputs = with pkgs; [
59
-
go
60
-
gopls
61
-
gomod2nix.legacyPackages.${system}.gomod2nix
62
-
templ
63
-
tailwind-ctp
64
-
tailwind-ctp-lsp
65
-
vscode-langservers-extracted
66
];
67
-
};
68
-
nixosModules.default = {
69
-
pkgs,
70
-
lib,
71
-
config,
72
-
...
73
-
}: let
74
-
cfg = config.services.ugit;
75
-
yamlFormat = pkgs.formats.yaml {};
76
-
configFile = pkgs.writeText "ugit.yaml" (builtins.readFile (yamlFormat.generate "ugit-yaml" cfg.config));
77
-
authorizedKeysFile = pkgs.writeText "ugit_keys" (builtins.concatStringsSep "\n" cfg.authorizedKeys);
78
-
in {
79
-
options = with lib; {
80
-
services.ugit = {
81
-
enable = mkEnableOption "Enable ugit";
82
-
83
-
package = mkOption {
84
-
type = types.package;
85
-
description = "ugit package to use";
86
-
default = ugit;
87
-
};
88
-
89
-
repoDir = mkOption {
90
-
type = types.str;
91
-
description = "where ugit stores repositories";
92
-
default = "/var/lib/ugit/repos";
93
-
};
94
-
95
-
authorizedKeys = mkOption {
96
-
type = types.listOf types.str;
97
-
description = "list of keys to use for authorized_keys";
98
-
default = [];
99
-
};
100
-
101
-
authorizedKeysFile = mkOption {
102
-
type = types.str;
103
-
description = "path to authorized_keys file ugit uses for auth";
104
-
default = "/var/lib/ugit/authorized_keys";
105
-
};
106
-
107
-
hostKeyFile = mkOption {
108
-
type = types.str;
109
-
description = "path to host key file (will be created if it doesn't exist)";
110
-
default = "/var/lib/ugit/ugit_ed25519";
111
-
};
112
-
113
-
config = mkOption {
114
-
type = types.attrs;
115
-
default = {};
116
-
description = "config.yaml contents";
117
};
118
-
119
-
user = mkOption {
120
-
type = types.str;
121
-
default = "ugit";
122
-
description = "User account under which ugit runs";
123
-
};
124
-
125
-
group = mkOption {
126
-
type = types.str;
127
-
default = "ugit";
128
-
description = "Group account under which ugit runs";
129
-
};
130
-
131
-
openFirewall = mkOption {
132
-
type = types.bool;
133
-
default = false;
134
-
};
135
-
};
136
};
137
-
config = lib.mkIf cfg.enable {
138
-
users.users."${cfg.user}" = {
139
-
home = "/var/lib/ugit";
140
-
createHome = true;
141
-
group = "${cfg.group}";
142
-
isSystemUser = true;
143
-
isNormalUser = false;
144
-
description = "user for ugit service";
145
-
};
146
-
users.groups."${cfg.group}" = {};
147
-
networking.firewall = lib.mkIf cfg.openFirewall {
148
-
allowedTCPPorts = [8448 8449];
149
-
};
150
-
151
-
systemd.services.ugit = {
152
-
enable = true;
153
-
script = let
154
-
authorizedKeysPath =
155
-
if (builtins.length cfg.authorizedKeys) > 0
156
-
then authorizedKeysFile
157
-
else cfg.authorizedKeysFile;
158
-
args = ["--config=${configFile}" "--repo-dir=${cfg.repoDir}" "--ssh.authorized-keys=${authorizedKeysPath}" "--ssh.host-key=${cfg.hostKeyFile}"];
159
-
in "${cfg.package}/bin/ugitd ${builtins.concatStringsSep " " args}";
160
-
wantedBy = ["multi-user.target"];
161
-
after = ["network.target"];
162
-
path = [cfg.package pkgs.git pkgs.bash];
163
-
serviceConfig = {
164
-
User = cfg.user;
165
-
Group = cfg.group;
166
-
Restart = "always";
167
-
RestartSec = "15";
168
-
WorkingDirectory = "/var/lib/ugit";
169
};
170
-
};
171
-
};
172
};
173
-
};
174
}
···
3
4
inputs = {
5
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
6
tailwind-ctp = {
7
url = "git+https://git.jolheiser.com/tailwind-ctp";
8
inputs.nixpkgs.follows = "nixpkgs";
···
13
};
14
};
15
16
+
outputs =
17
+
{
18
+
self,
19
+
nixpkgs,
20
+
tailwind-ctp,
21
+
tailwind-ctp-lsp,
22
+
}:
23
+
let
24
+
systems = [
25
+
"x86_64-linux"
26
+
"i686-linux"
27
+
"x86_64-darwin"
28
+
"aarch64-linux"
29
+
"armv6l-linux"
30
+
"armv7l-linux"
31
];
32
+
forAllSystems = f: nixpkgs.lib.genAttrs systems f;
33
+
tctp = forAllSystems (system: tailwind-ctp.packages.${system}.default);
34
+
tctpl = forAllSystems (system: tailwind-ctp-lsp.packages.${system}.default);
35
+
in
36
+
{
37
+
packages = forAllSystems (system: import ./nix { pkgs = import nixpkgs { inherit system; }; });
38
+
devShells = forAllSystems (
39
+
system:
40
+
let
41
+
pkgs = import nixpkgs { inherit system; };
42
+
in
43
+
{
44
+
default = pkgs.mkShell {
45
+
nativeBuildInputs = with pkgs; [
46
+
go
47
+
gopls
48
+
air
49
+
tctp.${system}
50
+
#tctpl.${system}
51
+
#vscode-langservers-extracted
52
+
];
53
};
54
+
}
55
+
);
56
+
nixosModules.default = import ./nix/module.nix;
57
+
nixosConfigurations.ugitVM = nixpkgs.lib.nixosSystem {
58
+
system = "x86_64-linux";
59
+
modules = [
60
+
./nix/vm.nix
61
+
{
62
+
virtualisation.vmVariant.virtualisation = {
63
+
cores = 2;
64
+
memorySize = 2048;
65
+
graphics = false;
66
+
};
67
+
system.stateVersion = "23.11";
68
+
}
69
+
];
70
};
71
+
apps = forAllSystems (
72
+
system:
73
+
let
74
+
pkgs = import nixpkgs { inherit system; };
75
+
in
76
+
{
77
+
vm = {
78
+
type = "app";
79
+
program = "${pkgs.writeShellScript "vm" ''
80
+
nixos-rebuild build-vm --flake .#ugitVM
81
+
./result/bin/run-nixos-vm
82
+
rm nixos.qcow2
83
+
''}";
84
};
85
+
}
86
+
);
87
};
88
}
+66
-54
go.mod
+66
-54
go.mod
···
1
module go.jolheiser.com/ugit
2
3
-
go 1.21
4
5
-
toolchain go1.21.5
6
7
require (
8
-
github.com/a-h/templ v0.2.543
9
-
github.com/alecthomas/chroma/v2 v2.12.0
10
-
github.com/charmbracelet/log v0.3.1
11
-
github.com/charmbracelet/ssh v0.0.0-20240201134204-3f297de25560
12
-
github.com/charmbracelet/wish v1.3.0
13
github.com/dustin/go-humanize v1.0.1
14
-
github.com/go-chi/chi/v5 v5.0.11
15
github.com/go-chi/httplog/v2 v2.1.1
16
-
github.com/go-git/go-billy/v5 v5.5.0
17
-
github.com/go-git/go-git/v5 v5.11.0
18
github.com/peterbourgon/ff/v3 v3.4.0
19
-
github.com/yuin/goldmark v1.6.0
20
-
github.com/yuin/goldmark-emoji v1.0.2
21
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
22
-
golang.org/x/net v0.25.0
23
)
24
25
require (
26
-
dario.cat/mergo v1.0.0 // indirect
27
-
github.com/Microsoft/go-winio v0.6.1 // indirect
28
-
github.com/ProtonMail/go-crypto v1.0.0 // indirect
29
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
30
-
github.com/atotto/clipboard v0.1.4 // indirect
31
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
32
-
github.com/catppuccin/go v0.2.0 // indirect
33
-
github.com/charmbracelet/bubbles v0.18.0 // indirect
34
-
github.com/charmbracelet/bubbletea v0.26.4 // indirect
35
-
github.com/charmbracelet/huh v0.5.1 // indirect
36
-
github.com/charmbracelet/keygen v0.5.0 // indirect
37
-
github.com/charmbracelet/lipgloss v0.11.0 // indirect
38
-
github.com/charmbracelet/x/ansi v0.1.2 // indirect
39
-
github.com/charmbracelet/x/errors v0.0.0-20240130180102-bafe6fbaee60 // indirect
40
-
github.com/charmbracelet/x/exp/strings v0.0.0-20240617190524-788ec55faed1 // indirect
41
-
github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a // indirect
42
-
github.com/charmbracelet/x/input v0.1.2 // indirect
43
-
github.com/charmbracelet/x/term v0.1.1 // indirect
44
-
github.com/charmbracelet/x/windows v0.1.2 // indirect
45
-
github.com/cloudflare/circl v1.3.7 // indirect
46
-
github.com/containerd/console v1.0.4-0.20230706203907-8f6c4e4faef5 // indirect
47
-
github.com/creack/pty v1.1.21 // indirect
48
-
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
49
-
github.com/dlclark/regexp2 v1.10.0 // indirect
50
github.com/emirpasic/gods v1.18.1 // indirect
51
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
52
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
53
github.com/go-logfmt/logfmt v0.6.0 // indirect
54
-
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
55
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
56
github.com/kevinburke/ssh_config v1.2.0 // indirect
57
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
58
github.com/mattn/go-isatty v0.0.20 // indirect
59
github.com/mattn/go-localereader v0.0.1 // indirect
60
-
github.com/mattn/go-runewidth v0.0.15 // indirect
61
-
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
62
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
63
github.com/muesli/cancelreader v0.2.2 // indirect
64
-
github.com/muesli/reflow v0.3.0 // indirect
65
-
github.com/muesli/termenv v0.15.2 // indirect
66
-
github.com/pjbgf/sha1cd v0.3.0 // indirect
67
github.com/rivo/uniseg v0.4.7 // indirect
68
-
github.com/sergi/go-diff v1.3.1 // indirect
69
-
github.com/skeema/knownhosts v1.2.1 // indirect
70
-
github.com/u-root/u-root v0.12.0 // indirect
71
github.com/xanzy/ssh-agent v0.3.3 // indirect
72
-
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
73
-
golang.org/x/crypto v0.23.0 // indirect
74
-
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
75
-
golang.org/x/mod v0.17.0 // indirect
76
-
golang.org/x/sync v0.7.0 // indirect
77
-
golang.org/x/sys v0.21.0 // indirect
78
-
golang.org/x/term v0.20.0 // indirect
79
-
golang.org/x/text v0.16.0 // indirect
80
-
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
81
gopkg.in/warnings.v0 v0.1.2 // indirect
82
-
gopkg.in/yaml.v2 v2.4.0 // indirect
83
)
···
1
module go.jolheiser.com/ugit
2
3
+
go 1.23.1
4
5
+
toolchain go1.23.3
6
7
require (
8
+
github.com/a-h/templ v0.3.924
9
+
github.com/alecthomas/assert/v2 v2.11.0
10
+
github.com/alecthomas/chroma/v2 v2.15.0
11
+
github.com/charmbracelet/ssh v0.0.0-20241211182756-4fe22b0f1b7c
12
+
github.com/charmbracelet/wish v1.4.4
13
github.com/dustin/go-humanize v1.0.1
14
+
github.com/go-chi/chi/v5 v5.2.0
15
github.com/go-chi/httplog/v2 v2.1.1
16
+
github.com/go-git/go-billy/v5 v5.6.1
17
+
github.com/go-git/go-git/v5 v5.13.1
18
github.com/peterbourgon/ff/v3 v3.4.0
19
+
github.com/yuin/goldmark v1.7.12
20
+
github.com/yuin/goldmark-emoji v1.0.4
21
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
22
+
go.jolheiser.com/ffcue v0.0.0-20250816031459-3e3e4f232e75
23
+
golang.org/x/net v0.42.0
24
)
25
26
require (
27
+
cuelang.org/go v0.14.1 // indirect
28
+
dario.cat/mergo v1.0.1 // indirect
29
+
github.com/Microsoft/go-winio v0.6.2 // indirect
30
+
github.com/ProtonMail/go-crypto v1.1.4 // indirect
31
+
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e // indirect
32
+
github.com/alecthomas/repr v0.4.0 // indirect
33
+
github.com/andybalholm/brotli v1.1.0 // indirect
34
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
35
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
36
+
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
37
+
github.com/charmbracelet/bubbletea v1.2.4 // indirect
38
+
github.com/charmbracelet/keygen v0.5.1 // indirect
39
+
github.com/charmbracelet/lipgloss v1.0.0 // indirect
40
+
github.com/charmbracelet/log v0.4.0 // indirect
41
+
github.com/charmbracelet/x/ansi v0.6.0 // indirect
42
+
github.com/charmbracelet/x/conpty v0.1.0 // indirect
43
+
github.com/charmbracelet/x/errors v0.0.0-20250107110353-48b574af22a5 // indirect
44
+
github.com/charmbracelet/x/term v0.2.1 // indirect
45
+
github.com/charmbracelet/x/termios v0.1.0 // indirect
46
+
github.com/cli/browser v1.3.0 // indirect
47
+
github.com/cloudflare/circl v1.5.0 // indirect
48
+
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
49
+
github.com/creack/pty v1.1.24 // indirect
50
+
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
51
+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
52
+
github.com/dlclark/regexp2 v1.11.4 // indirect
53
+
github.com/emicklei/proto v1.14.2 // indirect
54
github.com/emirpasic/gods v1.18.1 // indirect
55
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
56
+
github.com/fatih/color v1.16.0 // indirect
57
+
github.com/fsnotify/fsnotify v1.7.0 // indirect
58
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
59
github.com/go-logfmt/logfmt v0.6.0 // indirect
60
+
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
61
+
github.com/google/uuid v1.6.0 // indirect
62
+
github.com/hexops/gotextdiff v1.0.3 // indirect
63
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
64
github.com/kevinburke/ssh_config v1.2.0 // indirect
65
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
66
+
github.com/mattn/go-colorable v0.1.13 // indirect
67
github.com/mattn/go-isatty v0.0.20 // indirect
68
github.com/mattn/go-localereader v0.0.1 // indirect
69
+
github.com/mattn/go-runewidth v0.0.16 // indirect
70
+
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
71
+
github.com/mmcloughlin/avo v0.6.0 // indirect
72
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
73
github.com/muesli/cancelreader v0.2.2 // indirect
74
+
github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5 // indirect
75
+
github.com/natefinch/atomic v1.0.1 // indirect
76
+
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
77
+
github.com/pjbgf/sha1cd v0.3.1 // indirect
78
+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
79
+
github.com/protocolbuffers/txtpbfmt v0.0.0-20250627152318-f293424e46b5 // indirect
80
github.com/rivo/uniseg v0.4.7 // indirect
81
+
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect
82
+
github.com/skeema/knownhosts v1.3.0 // indirect
83
github.com/xanzy/ssh-agent v0.3.3 // indirect
84
+
golang.org/x/crypto v0.40.0 // indirect
85
+
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
86
+
golang.org/x/mod v0.26.0 // indirect
87
+
golang.org/x/sync v0.16.0 // indirect
88
+
golang.org/x/sys v0.34.0 // indirect
89
+
golang.org/x/text v0.27.0 // indirect
90
+
golang.org/x/tools v0.35.0 // indirect
91
gopkg.in/warnings.v0 v0.1.2 // indirect
92
+
gopkg.in/yaml.v3 v3.0.1 // indirect
93
)
94
+
95
+
tool github.com/a-h/templ/cmd/templ
+1
-1
go.mod.sri
+1
-1
go.mod.sri
+151
-189
go.sum
+151
-189
go.sum
···
1
-
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
2
-
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
3
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
4
-
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
5
-
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
6
-
github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
7
-
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
8
-
github.com/a-h/templ v0.2.543 h1:8YyLvyUtf0/IE2nIwZ62Z/m2o2NqwhnMynzOL78Lzbk=
9
-
github.com/a-h/templ v0.2.543/go.mod h1:jP908DQCwI08IrnTalhzSEH9WJqG/Q94+EODQcJGFUA=
10
-
github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink=
11
-
github.com/alecthomas/assert/v2 v2.2.1/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ=
12
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
13
-
github.com/alecthomas/chroma/v2 v2.12.0 h1:Wh8qLEgMMsN7mgyG8/qIpegky2Hvzr4By6gEF7cmWgw=
14
-
github.com/alecthomas/chroma/v2 v2.12.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurGF0EpseFXdKMBw=
15
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
16
-
github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk=
17
-
github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
18
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
19
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
20
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
21
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
22
-
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
23
-
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
24
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
25
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
26
-
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
27
-
github.com/catppuccin/go v0.2.0 h1:ktBeIrIP42b/8FGiScP9sgrWOss3lw0Z5SktRoithGA=
28
-
github.com/catppuccin/go v0.2.0/go.mod h1:8IHJuMGaUUjQM82qBrGNBv7LFq6JI3NnQCF6MOlZjpc=
29
-
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
30
-
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
31
-
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
32
-
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
33
-
github.com/charmbracelet/bubbletea v0.26.4 h1:2gDkkzLZaTjMl/dQBpNVtnvcCxsh/FCkimep7FC9c40=
34
-
github.com/charmbracelet/bubbletea v0.26.4/go.mod h1:P+r+RRA5qtI1DOHNFn0otoNwB4rn+zNAzSj/EXz6xU0=
35
-
github.com/charmbracelet/huh v0.5.1 h1:t5j6g9sMjAE2a9AQuc4lNL7pf/0X4WdHiiMGkL8v/aM=
36
-
github.com/charmbracelet/huh v0.5.1/go.mod h1:gs7b2brpzXkY0PBWUqJrlzvOowTCL0vNAR6OTItc+kA=
37
-
github.com/charmbracelet/keygen v0.5.0 h1:XY0fsoYiCSM9axkrU+2ziE6u6YjJulo/b9Dghnw6MZc=
38
-
github.com/charmbracelet/keygen v0.5.0/go.mod h1:DfvCgLHxZ9rJxdK0DGw3C/LkV4SgdGbnliHcObV3L+8=
39
-
github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg=
40
-
github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I=
41
-
github.com/charmbracelet/lipgloss v0.11.0 h1:UoAcbQ6Qml8hDwSWs0Y1cB5TEQuZkDPH/ZqwWWYTG4g=
42
-
github.com/charmbracelet/lipgloss v0.11.0/go.mod h1:1UdRTH9gYgpcdNN5oBtjbu/IzNKtzVtb7sqN1t9LNn8=
43
-
github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMTYw=
44
-
github.com/charmbracelet/log v0.3.1/go.mod h1:OR4E1hutLsax3ZKpXbgUqPtTjQfrh1pG3zwHGWuuq8g=
45
-
github.com/charmbracelet/ssh v0.0.0-20240201134204-3f297de25560 h1:kUYiDRF04AsyJvWi4HrklXXSU7+S7qjExusfDnYbVGg=
46
-
github.com/charmbracelet/ssh v0.0.0-20240201134204-3f297de25560/go.mod h1:IHy7o73i1MrQ5lmyJjjJ0g7y4+V+g69cm+Y7JCiZWPo=
47
-
github.com/charmbracelet/wish v1.3.0 h1:SYV5TIlzDb6WaxjkkYXxv2WZsTu/QZGwfGVc0UB5M48=
48
-
github.com/charmbracelet/wish v1.3.0/go.mod h1:1U/bI7zX+IE26ThD5gxtLgeRzctVhSrTpjucPqw4Pos=
49
-
github.com/charmbracelet/x/ansi v0.1.2 h1:6+LR39uG8DE6zAmbu023YlqjJHkYXDF1z36ZwzO4xZY=
50
-
github.com/charmbracelet/x/ansi v0.1.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
51
-
github.com/charmbracelet/x/errors v0.0.0-20240130180102-bafe6fbaee60 h1:u0XFhTN81zvoGwyQWOYjjkrimEQj5L2DPECCX5cBsRw=
52
-
github.com/charmbracelet/x/errors v0.0.0-20240130180102-bafe6fbaee60/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0=
53
-
github.com/charmbracelet/x/exp/strings v0.0.0-20240617190524-788ec55faed1 h1:VZIQzjwFE0EamzG2v8HfemeisB8X02Tl0BZBnJ0PeU8=
54
-
github.com/charmbracelet/x/exp/strings v0.0.0-20240617190524-788ec55faed1/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ=
55
-
github.com/charmbracelet/x/exp/term v0.0.0-20240130180102-bafe6fbaee60 h1:IV19YKUZVf6ATrhiPSCirZ4Bs7EsenYwOWcUHngV+q0=
56
-
github.com/charmbracelet/x/exp/term v0.0.0-20240130180102-bafe6fbaee60/go.mod h1:kOOxxyxgAFQVcR5yQJWTuLjzt5dR2pcgwy3WaLEudjE=
57
-
github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a h1:k/s6UoOSVynWiw7PlclyGO2VdVs5ZLbMIHiGp4shFZE=
58
-
github.com/charmbracelet/x/exp/term v0.0.0-20240524151031-ff83003bf67a/go.mod h1:YBotIGhfoWhHDlnUpJMkjebGV2pdGRCn1Y4/Nk/vVcU=
59
-
github.com/charmbracelet/x/input v0.1.2 h1:QJAZr33eOhDowkkEQ24rsJy4Llxlm+fRDf/cQrmqJa0=
60
-
github.com/charmbracelet/x/input v0.1.2/go.mod h1:LGBim0maUY4Pitjn/4fHnuXb4KirU3DODsyuHuXdOyA=
61
-
github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI=
62
-
github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw=
63
-
github.com/charmbracelet/x/windows v0.1.2 h1:Iumiwq2G+BRmgoayww/qfcvof7W/3uLoelhxojXlRWg=
64
-
github.com/charmbracelet/x/windows v0.1.2/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ=
65
-
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
66
-
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
67
-
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
68
-
github.com/containerd/console v1.0.4-0.20230706203907-8f6c4e4faef5 h1:Ig+OPkE3XQrrl+SKsOqAjlkrBN/zrr+Qpw7rCuDjRCE=
69
-
github.com/containerd/console v1.0.4-0.20230706203907-8f6c4e4faef5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
70
-
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
71
-
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
72
-
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
73
-
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
74
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
75
-
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
76
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
77
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
78
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
79
-
github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0=
80
-
github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
81
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
82
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
83
-
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
84
-
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
85
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
86
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
87
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
88
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
89
-
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
90
-
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
91
-
github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
92
-
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
93
github.com/go-chi/httplog/v2 v2.1.1 h1:ojojiu4PIaoeJ/qAO4GWUxJqvYUTobeo7zmuHQJAxRk=
94
github.com/go-chi/httplog/v2 v2.1.1/go.mod h1:/XXdxicJsp4BA5fapgIC3VuTD+z0Z/VzukoB3VDc1YE=
95
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
96
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
97
-
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
98
-
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
99
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
100
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
101
-
github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
102
-
github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
103
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
104
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
105
-
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
106
-
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
107
-
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
108
-
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
109
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
110
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
111
-
github.com/hugelgupf/vmtest v0.0.0-20240102225328-693afabdd27f h1:ov45/OzrJG8EKbGjn7jJZQJTN7Z1t73sFYNIRd64YlI=
112
-
github.com/hugelgupf/vmtest v0.0.0-20240102225328-693afabdd27f/go.mod h1:JoDrYMZpDPYo6uH9/f6Peqms3zNNWT2XiGgioMOIGuI=
113
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
114
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
115
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
···
121
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
122
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
123
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
124
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
125
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
126
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
127
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
128
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
129
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
130
-
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
131
-
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
132
-
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
133
-
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
134
-
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
135
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
136
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
137
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
138
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
139
-
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
140
-
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
141
-
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
142
-
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
143
-
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
144
-
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
145
github.com/peterbourgon/ff/v3 v3.4.0 h1:QBvM/rizZM1cB0p0lGMdmR7HxZeI/ZrBWB4DqLkMUBc=
146
github.com/peterbourgon/ff/v3 v3.4.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ=
147
-
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
148
-
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
149
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
150
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
151
-
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
152
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
153
-
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
154
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
155
-
github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg=
156
-
github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
157
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
158
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
159
-
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
160
-
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
161
-
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
162
-
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
163
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
164
-
github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
165
-
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
166
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
167
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
168
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
169
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
170
-
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
171
-
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
172
-
github.com/u-root/gobusybox/src v0.0.0-20231228173702-b69f654846aa h1:unMPGGK/CRzfg923allsikmvk2l7beBeFPUNC4RVX/8=
173
-
github.com/u-root/gobusybox/src v0.0.0-20231228173702-b69f654846aa/go.mod h1:Zj4Tt22fJVn/nz/y6Ergm1SahR9dio1Zm/D2/S0TmXM=
174
-
github.com/u-root/u-root v0.12.0 h1:K0AuBFriwr0w/PGS3HawiAw89e3+MU7ks80GpghAsNs=
175
-
github.com/u-root/u-root v0.12.0/go.mod h1:FYjTOh4IkIZHhjsd17lb8nYW6udgXdJhG1c0r6u0arI=
176
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
177
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
178
-
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
179
-
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
180
-
github.com/yuin/goldmark v1.3.7/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
181
-
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
182
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
183
-
github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
184
-
github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
185
-
github.com/yuin/goldmark-emoji v1.0.2 h1:c/RgTShNgHTtc6xdz2KKI74jJr6rWi7FPgnP9GAsO5s=
186
-
github.com/yuin/goldmark-emoji v1.0.2/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY=
187
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
188
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
189
-
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
190
-
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
191
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
192
-
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
193
-
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
194
-
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
195
-
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
196
-
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
197
-
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
198
-
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
199
-
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
200
-
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
201
-
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
202
-
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
203
-
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
204
-
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
205
-
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
206
-
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
207
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
208
-
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
209
-
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
210
-
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
211
-
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
212
-
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
213
-
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
214
-
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
215
-
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
216
-
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
217
-
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
218
-
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
219
-
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
220
-
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
221
-
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
222
-
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
223
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
224
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
225
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
226
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
227
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
228
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
229
-
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
230
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
231
-
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
232
-
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
233
-
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
234
-
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
235
-
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
236
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
237
-
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
238
-
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
239
-
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
240
-
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
241
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
242
-
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
243
-
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
244
-
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
245
-
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
246
-
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
247
-
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
248
-
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
249
-
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
250
-
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
251
-
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
252
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
253
-
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
254
-
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
255
-
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
256
-
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
257
-
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
258
-
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
259
-
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
260
-
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
261
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
262
-
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
263
-
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
264
-
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
265
-
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
266
-
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
267
-
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
268
-
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
269
-
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
270
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
271
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
272
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
···
274
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
275
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
276
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
277
-
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
278
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
279
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
280
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
···
1
+
cuelabs.dev/go/oci/ociregistry v0.0.0-20250715075730-49cab49c8e9d h1:lX0EawyoAu4kgMJJfy7MmNkIHioBcdBGFRSKDZ+CWo0=
2
+
cuelabs.dev/go/oci/ociregistry v0.0.0-20250715075730-49cab49c8e9d/go.mod h1:4WWeZNxUO1vRoZWAHIG0KZOd6dA25ypyWuwD3ti0Tdc=
3
+
cuelang.org/go v0.14.1 h1:kxFAHr7bvrCikbtVps2chPIARazVdnRmlz65dAzKyWg=
4
+
cuelang.org/go v0.14.1/go.mod h1:aSP9UZUM5m2izHAHUvqtq0wTlWn5oLjuv2iBMQZBLLs=
5
+
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
6
+
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
7
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
8
+
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
9
+
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
10
+
github.com/ProtonMail/go-crypto v1.1.4 h1:G5U5asvD5N/6/36oIw3k2bOfBn5XVcZrb7PBjzzKKoE=
11
+
github.com/ProtonMail/go-crypto v1.1.4/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
12
+
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e h1:HjVbSQHy+dnlS6C3XajZ69NYAb5jbGNfHanvm1+iYlo=
13
+
github.com/a-h/parse v0.0.0-20250122154542-74294addb73e/go.mod h1:3mnrkvGpurZ4ZrTDbYU84xhwXW2TjTKShSwjRi2ihfQ=
14
+
github.com/a-h/templ v0.3.924 h1:t5gZqTneXqvehpNZsgtnlOscnBboNh9aASBH2MgV/0k=
15
+
github.com/a-h/templ v0.3.924/go.mod h1:FFAu4dI//ESmEN7PQkJ7E7QfnSEMdcnu7QrAY8Dn334=
16
+
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
17
+
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
18
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
19
+
github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc=
20
+
github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio=
21
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
22
+
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
23
+
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
24
+
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
25
+
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
26
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
27
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
28
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
29
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
30
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
31
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
32
+
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
33
+
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
34
+
github.com/charmbracelet/bubbletea v1.2.4 h1:KN8aCViA0eps9SCOThb2/XPIlea3ANJLUkv3KnQRNCE=
35
+
github.com/charmbracelet/bubbletea v1.2.4/go.mod h1:Qr6fVQw+wX7JkWWkVyXYk/ZUQ92a6XNekLXa3rR18MM=
36
+
github.com/charmbracelet/keygen v0.5.1 h1:zBkkYPtmKDVTw+cwUyY6ZwGDhRxXkEp0Oxs9sqMLqxI=
37
+
github.com/charmbracelet/keygen v0.5.1/go.mod h1:zznJVmK/GWB6dAtjluqn2qsttiCBhA5MZSiwb80fcHw=
38
+
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
39
+
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
40
+
github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM=
41
+
github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM=
42
+
github.com/charmbracelet/ssh v0.0.0-20241211182756-4fe22b0f1b7c h1:treQxMBdI2PaD4eOYfFux8stfCkUxhuUxaqGcxKqVpI=
43
+
github.com/charmbracelet/ssh v0.0.0-20241211182756-4fe22b0f1b7c/go.mod h1:CY1xbl2z+ZeBmNWItKZyxx0zgDgnhmR57+DTsHOobJ4=
44
+
github.com/charmbracelet/wish v1.4.4 h1:wtfoAMkf8Db9zi+9Lme2f7XKMxL6BqfgDWbqcTUHLaU=
45
+
github.com/charmbracelet/wish v1.4.4/go.mod h1:XB8v51UxIFMRlUod9lLaAgOsj/wpe+qW9HjsoYIiNMo=
46
+
github.com/charmbracelet/x/ansi v0.6.0 h1:qOznutrb93gx9oMiGf7caF7bqqubh6YIM0SWKyA08pA=
47
+
github.com/charmbracelet/x/ansi v0.6.0/go.mod h1:KBUFw1la39nl0dLl10l5ORDAqGXaeurTQmwyyVKse/Q=
48
+
github.com/charmbracelet/x/conpty v0.1.0 h1:4zc8KaIcbiL4mghEON8D72agYtSeIgq8FSThSPQIb+U=
49
+
github.com/charmbracelet/x/conpty v0.1.0/go.mod h1:rMFsDJoDwVmiYM10aD4bH2XiRgwI7NYJtQgl5yskjEQ=
50
+
github.com/charmbracelet/x/errors v0.0.0-20250107110353-48b574af22a5 h1:Hx72S6S4jAfrrWE3pv9IbudVdUV4htBgkOX800o17Bk=
51
+
github.com/charmbracelet/x/errors v0.0.0-20250107110353-48b574af22a5/go.mod h1:2P0UgXMEa6TsToMSuFqKFQR+fZTO9CNGUNokkPatT/0=
52
+
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
53
+
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
54
+
github.com/charmbracelet/x/termios v0.1.0 h1:y4rjAHeFksBAfGbkRDmVinMg7x7DELIGAFbdNvxg97k=
55
+
github.com/charmbracelet/x/termios v0.1.0/go.mod h1:H/EVv/KRnrYjz+fCYa9bsKdqF3S8ouDK0AZEbG7r+/U=
56
+
github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
57
+
github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
58
+
github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys=
59
+
github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
60
+
github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg=
61
+
github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc=
62
+
github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s=
63
+
github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
64
+
github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
65
+
github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
66
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
67
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
68
+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
69
+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
70
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
71
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
72
+
github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
73
+
github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
74
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
75
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
76
+
github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ=
77
+
github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64=
78
+
github.com/emicklei/proto v1.14.2 h1:wJPxPy2Xifja9cEMrcA/g08art5+7CGJNFNk35iXC1I=
79
+
github.com/emicklei/proto v1.14.2/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
80
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
81
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
82
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
83
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
84
+
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
85
+
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
86
+
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
87
+
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
88
+
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
89
+
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
90
+
github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0=
91
+
github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
92
github.com/go-chi/httplog/v2 v2.1.1 h1:ojojiu4PIaoeJ/qAO4GWUxJqvYUTobeo7zmuHQJAxRk=
93
github.com/go-chi/httplog/v2 v2.1.1/go.mod h1:/XXdxicJsp4BA5fapgIC3VuTD+z0Z/VzukoB3VDc1YE=
94
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
95
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
96
+
github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA=
97
+
github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE=
98
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
99
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
100
+
github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M=
101
+
github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc=
102
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
103
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
104
+
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
105
+
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
106
+
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
107
+
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
108
+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
109
+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
110
+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
111
+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
112
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
113
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
114
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
115
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
116
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
···
122
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
123
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
124
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
125
+
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
126
+
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
127
+
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
128
+
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
129
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
130
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
131
+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
132
+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
133
+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
134
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
135
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
136
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
137
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
138
+
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
139
+
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
140
+
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
141
+
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
142
+
github.com/mmcloughlin/avo v0.6.0 h1:QH6FU8SKoTLaVs80GA8TJuLNkUYl4VokHKlPhVDg4YY=
143
+
github.com/mmcloughlin/avo v0.6.0/go.mod h1:8CoAGaCSYXtCPR+8y18Y9aB/kxb8JSS6FRI7mSkvD+8=
144
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
145
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
146
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
147
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
148
+
github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5 h1:NiONcKK0EV5gUZcnCiPMORaZA0eBDc+Fgepl9xl4lZ8=
149
+
github.com/muesli/termenv v0.15.3-0.20240509142007-81b8f94111d5/go.mod h1:hxSnBBYLK21Vtq/PHd0S2FYCxBXzBua8ov5s1RobyRQ=
150
+
github.com/natefinch/atomic v1.0.1 h1:ZPYKxkqQOx3KZ+RsbnP/YsgvxWQPGxjC0oBt2AhwV0A=
151
+
github.com/natefinch/atomic v1.0.1/go.mod h1:N/D/ELrljoqDyT3rZrsUmtsuzvHkeB/wWjHV22AZRbM=
152
+
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
153
+
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
154
+
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
155
+
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
156
+
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
157
+
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
158
+
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
159
+
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
160
github.com/peterbourgon/ff/v3 v3.4.0 h1:QBvM/rizZM1cB0p0lGMdmR7HxZeI/ZrBWB4DqLkMUBc=
161
github.com/peterbourgon/ff/v3 v3.4.0/go.mod h1:zjJVUhx+twciwfDl0zBcFzl4dW8axCRyXE/eKY9RztQ=
162
+
github.com/pjbgf/sha1cd v0.3.1 h1:Dh2GYdpJnO84lIw0LJwTFXjcNbasP/bklicSznyAaPI=
163
+
github.com/pjbgf/sha1cd v0.3.1/go.mod h1:Y8t7jSB/dEI/lQE04A1HVKteqjj9bX5O4+Cex0TCu8s=
164
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
165
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
166
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
167
+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
168
+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
169
+
github.com/protocolbuffers/txtpbfmt v0.0.0-20250627152318-f293424e46b5 h1:WWs1ZFnGobK5ZXNu+N9If+8PDNVB9xAqrib/stUXsV4=
170
+
github.com/protocolbuffers/txtpbfmt v0.0.0-20250627152318-f293424e46b5/go.mod h1:BnHogPTyzYAReeQLZrOxyxzS739DaTNtTvohVdbENmA=
171
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
172
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
173
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
174
+
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
175
+
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
176
+
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
177
+
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
178
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
179
+
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
180
+
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
181
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
182
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
183
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
184
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
185
+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
186
+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
187
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
188
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
189
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
190
+
github.com/yuin/goldmark v1.7.1/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
191
+
github.com/yuin/goldmark v1.7.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY=
192
+
github.com/yuin/goldmark v1.7.12/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
193
+
github.com/yuin/goldmark-emoji v1.0.4 h1:vCwMkPZSNefSUnOW2ZKRUjBSD5Ok3W78IXhGxxAEF90=
194
+
github.com/yuin/goldmark-emoji v1.0.4/go.mod h1:tTkZEbwu5wkPmgTcitqddVxY9osFZiavD+r4AzQrh1U=
195
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
196
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
197
+
go.jolheiser.com/ffcue v0.0.0-20250816031459-3e3e4f232e75 h1:hu2LcTy2bvgmfEDuaDCfpWIzWN1pHAKfUkAnpgjZYco=
198
+
go.jolheiser.com/ffcue v0.0.0-20250816031459-3e3e4f232e75/go.mod h1:IrDGUkvU3xl27+Seb20ZE/H2dzG95m/xmu0Z/B3crUE=
199
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
200
+
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
201
+
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
202
+
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA=
203
+
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
204
+
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
205
+
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
206
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
207
+
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
208
+
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
209
+
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
210
+
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
211
+
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
212
+
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
213
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
214
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
215
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
216
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
217
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
218
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
219
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
220
+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
221
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
222
+
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
223
+
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
224
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
225
+
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
226
+
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
227
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
228
+
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
229
+
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
230
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
231
+
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
232
+
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
233
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
234
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
235
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
···
237
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
238
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
239
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
240
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
241
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
242
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-180
gomod2nix.toml
-180
gomod2nix.toml
···
1
-
schema = 3
2
-
3
-
[mod]
4
-
[mod."dario.cat/mergo"]
5
-
version = "v1.0.0"
6
-
hash = "sha256-jlpc8dDj+DmiOU4gEawBu8poJJj9My0s9Mvuk9oS8ww="
7
-
[mod."github.com/Microsoft/go-winio"]
8
-
version = "v0.6.1"
9
-
hash = "sha256-BL0BVaHtmPKQts/711W59AbHXjGKqFS4ZTal0RYnR9I="
10
-
[mod."github.com/ProtonMail/go-crypto"]
11
-
version = "v1.0.0"
12
-
hash = "sha256-Gflazvyv+457FpUTtPafJ+SdolYSalpsU0tragTxNi8="
13
-
[mod."github.com/a-h/templ"]
14
-
version = "v0.2.543"
15
-
hash = "sha256-1BvIj9UPZJp8SOXMPIGdHyZLIvjORHg2UY3pRZJM01s="
16
-
[mod."github.com/alecthomas/chroma/v2"]
17
-
version = "v2.12.0"
18
-
hash = "sha256-w3gKGPwsoayknuU4ifPaF0JOMNqnKjIEutbIkR9c2Ag="
19
-
[mod."github.com/anmitsu/go-shlex"]
20
-
version = "v0.0.0-20200514113438-38f4b401e2be"
21
-
hash = "sha256-L3Ak4X2z7WXq7vMKuiHCOJ29nlpajUQ08Sfb9T0yP54="
22
-
[mod."github.com/aymanbagabas/go-osc52/v2"]
23
-
version = "v2.0.1"
24
-
hash = "sha256-6Bp0jBZ6npvsYcKZGHHIUSVSTAMEyieweAX2YAKDjjg="
25
-
[mod."github.com/charmbracelet/bubbletea"]
26
-
version = "v0.25.0"
27
-
hash = "sha256-A0WjFRFAUhwO3m7uvCOeefPPIM8ReU+xTtIRxG0aH+Y="
28
-
[mod."github.com/charmbracelet/keygen"]
29
-
version = "v0.5.0"
30
-
hash = "sha256-JFD2SdFL7tq3oVhnBEgiBTrJvjqdUtIuodAJuSFcJoA="
31
-
[mod."github.com/charmbracelet/lipgloss"]
32
-
version = "v0.9.1"
33
-
hash = "sha256-AHbabOymgDRIXsMBgJHS25/GgBWT54oGbd15EBWKeZc="
34
-
[mod."github.com/charmbracelet/log"]
35
-
version = "v0.3.1"
36
-
hash = "sha256-Er60POPID2eNrRZnBHxoI4yHn0mIKnXYftGKSslbXx0="
37
-
[mod."github.com/charmbracelet/ssh"]
38
-
version = "v0.0.0-20240201134204-3f297de25560"
39
-
hash = "sha256-r4h4bym47rs3C2us+sCgVfwAl4TCbm3bDCTsXKYREz8="
40
-
[mod."github.com/charmbracelet/wish"]
41
-
version = "v1.3.0"
42
-
hash = "sha256-3Uq1PDu5DMoWgJykFx/roGk20x8jdb7o5JFPpmEtX/c="
43
-
[mod."github.com/charmbracelet/x/errors"]
44
-
version = "v0.0.0-20240130180102-bafe6fbaee60"
45
-
hash = "sha256-GO8hf0lhVtl00C+xoTzvBtPU2cO0PymSLc2szBRUNtE="
46
-
[mod."github.com/charmbracelet/x/exp/term"]
47
-
version = "v0.0.0-20240130180102-bafe6fbaee60"
48
-
hash = "sha256-hEj/Gj1U1ahk5EFVZVAL52yrdBNO47yXykpiehJICbc="
49
-
[mod."github.com/cloudflare/circl"]
50
-
version = "v1.3.7"
51
-
hash = "sha256-AkOpcZ+evLxLJStvvr01+TLeWDqcLxY3e/AhGggzh40="
52
-
[mod."github.com/containerd/console"]
53
-
version = "v1.0.4-0.20230706203907-8f6c4e4faef5"
54
-
hash = "sha256-mxRERsgS6TmI5I0UYblhzl2FZlbtkJhUkfF1x6mZINw="
55
-
[mod."github.com/creack/pty"]
56
-
version = "v1.1.21"
57
-
hash = "sha256-pjGw6wQlrVhN65XaIxZueNJqnXThGu00u24rKOLzxS0="
58
-
[mod."github.com/cyphar/filepath-securejoin"]
59
-
version = "v0.2.4"
60
-
hash = "sha256-heCD0xMxlwnHCHcRBgTjVexHOLyWI2zRW3E8NFKoLzk="
61
-
[mod."github.com/dlclark/regexp2"]
62
-
version = "v1.10.0"
63
-
hash = "sha256-Jxzj/O/Q9tIWBOOgCkCibhrgJBzzfVIxYDsabt7O8ow="
64
-
[mod."github.com/dustin/go-humanize"]
65
-
version = "v1.0.1"
66
-
hash = "sha256-yuvxYYngpfVkUg9yAmG99IUVmADTQA0tMbBXe0Fq0Mc="
67
-
[mod."github.com/emirpasic/gods"]
68
-
version = "v1.18.1"
69
-
hash = "sha256-hGDKddjLj+5dn2woHtXKUdd49/3xdsqnhx7VEdCu1m4="
70
-
[mod."github.com/go-chi/chi/v5"]
71
-
version = "v5.0.11"
72
-
hash = "sha256-95LKg/OVzhik2HUz6cirHH3eAT4qbHSg52bSvkc+XOY="
73
-
[mod."github.com/go-git/gcfg"]
74
-
version = "v1.5.1-0.20230307220236-3a3c6141e376"
75
-
hash = "sha256-f4k0gSYuo0/q3WOoTxl2eFaj7WZpdz29ih6CKc8Ude8="
76
-
[mod."github.com/go-git/go-billy/v5"]
77
-
version = "v5.5.0"
78
-
hash = "sha256-4XUoD2bOCMCdu83egb/y8kY/Fm0s1rWgPMtiahh38OQ="
79
-
[mod."github.com/go-git/go-git/v5"]
80
-
version = "v5.11.0"
81
-
hash = "sha256-2yUM/FlV+nYxacVynJCnDZeMub4Iu8JL2WBHmlnwOkE="
82
-
[mod."github.com/go-logfmt/logfmt"]
83
-
version = "v0.6.0"
84
-
hash = "sha256-RtIG2qARd5sT10WQ7F3LR8YJhS8exs+KiuUiVf75bWg="
85
-
[mod."github.com/golang/groupcache"]
86
-
version = "v0.0.0-20210331224755-41bb18bfe9da"
87
-
hash = "sha256-7Gs7CS9gEYZkbu5P4hqPGBpeGZWC64VDwraSKFF+VR0="
88
-
[mod."github.com/jbenet/go-context"]
89
-
version = "v0.0.0-20150711004518-d14ea06fba99"
90
-
hash = "sha256-VANNCWNNpARH/ILQV9sCQsBWgyL2iFT+4AHZREpxIWE="
91
-
[mod."github.com/kevinburke/ssh_config"]
92
-
version = "v1.2.0"
93
-
hash = "sha256-Ta7ZOmyX8gG5tzWbY2oES70EJPfI90U7CIJS9EAce0s="
94
-
[mod."github.com/lucasb-eyer/go-colorful"]
95
-
version = "v1.2.0"
96
-
hash = "sha256-Gg9dDJFCTaHrKHRR1SrJgZ8fWieJkybljybkI9x0gyE="
97
-
[mod."github.com/mattn/go-isatty"]
98
-
version = "v0.0.20"
99
-
hash = "sha256-qhw9hWtU5wnyFyuMbKx+7RB8ckQaFQ8D+8GKPkN3HHQ="
100
-
[mod."github.com/mattn/go-localereader"]
101
-
version = "v0.0.1"
102
-
hash = "sha256-JlWckeGaWG+bXK8l8WEdZqmSiTwCA8b1qbmBKa/Fj3E="
103
-
[mod."github.com/mattn/go-runewidth"]
104
-
version = "v0.0.15"
105
-
hash = "sha256-WP39EU2UrQbByYfnwrkBDoKN7xzXsBssDq3pNryBGm0="
106
-
[mod."github.com/muesli/ansi"]
107
-
version = "v0.0.0-20230316100256-276c6243b2f6"
108
-
hash = "sha256-qRKn0Bh2yvP0QxeEMeZe11Vz0BPFIkVcleKsPeybKMs="
109
-
[mod."github.com/muesli/cancelreader"]
110
-
version = "v0.2.2"
111
-
hash = "sha256-uEPpzwRJBJsQWBw6M71FDfgJuR7n55d/7IV8MO+rpwQ="
112
-
[mod."github.com/muesli/reflow"]
113
-
version = "v0.3.0"
114
-
hash = "sha256-Pou2ybE9SFSZG6YfZLVV1Eyfm+X4FuVpDPLxhpn47Cc="
115
-
[mod."github.com/muesli/termenv"]
116
-
version = "v0.15.2"
117
-
hash = "sha256-Eum/SpyytcNIchANPkG4bYGBgcezLgej7j/+6IhqoMU="
118
-
[mod."github.com/peterbourgon/ff/v3"]
119
-
version = "v3.4.0"
120
-
hash = "sha256-rmRl4GSmc2atnMbw6hTs6jwxW5lO4ivYuF2VN3jacZM="
121
-
[mod."github.com/pjbgf/sha1cd"]
122
-
version = "v0.3.0"
123
-
hash = "sha256-kX9BdLh2dxtGNaDvc24NORO+C0AZ7JzbrXrtecCdB7w="
124
-
[mod."github.com/rivo/uniseg"]
125
-
version = "v0.4.6"
126
-
hash = "sha256-zGfzO8FWj03POzo47SzrK1B4yLMKJ7iic6ium76ZLzI="
127
-
[mod."github.com/sergi/go-diff"]
128
-
version = "v1.3.1"
129
-
hash = "sha256-XLA/BLIPuUU76yikXqIeRSXr7T7A3Uz6I27+mDxGj7w="
130
-
[mod."github.com/skeema/knownhosts"]
131
-
version = "v1.2.1"
132
-
hash = "sha256-u0jB6ahTdGa+SvcIvPNRLnbSHvgmW9X/ThRq0nWQrJs="
133
-
[mod."github.com/u-root/u-root"]
134
-
version = "v0.12.0"
135
-
hash = "sha256-B9Qoq1S0l0W6twET54uxiWjh2ulxN/zMLAeWJX4cXW0="
136
-
[mod."github.com/xanzy/ssh-agent"]
137
-
version = "v0.3.3"
138
-
hash = "sha256-l3pGB6IdzcPA/HLk93sSN6NM2pKPy+bVOoacR5RC2+c="
139
-
[mod."github.com/yuin/goldmark"]
140
-
version = "v1.6.0"
141
-
hash = "sha256-0PeGjGxxM7lUSx2dn8yPUBpilPQzEN9nkgf3s+5zGTY="
142
-
[mod."github.com/yuin/goldmark-emoji"]
143
-
version = "v1.0.2"
144
-
hash = "sha256-RvzhNXlF98fu9SD/Rve9JMtR4bcRh7rN56Twhh/kmt4="
145
-
[mod."github.com/yuin/goldmark-highlighting/v2"]
146
-
version = "v2.0.0-20230729083705-37449abec8cc"
147
-
hash = "sha256-HpiwU7jIeDUAg2zOpTIiviQir8dpRPuXYh2nqFFccpg="
148
-
[mod."golang.org/x/crypto"]
149
-
version = "v0.18.0"
150
-
hash = "sha256-BuMVUxOIyfLo8MOhqYt+uQ8NDN6P2KdblKyfPxINzQ4="
151
-
[mod."golang.org/x/exp"]
152
-
version = "v0.0.0-20240119083558-1b970713d09a"
153
-
hash = "sha256-JQ3JLywTjgboNhs12blhOkS3ty7m8sUa/zaWv1k/X28="
154
-
[mod."golang.org/x/mod"]
155
-
version = "v0.14.0"
156
-
hash = "sha256-sx3hWp5l99DBfIrn821ohfoBwvaITSHMWbzPvX0btLM="
157
-
[mod."golang.org/x/net"]
158
-
version = "v0.20.0"
159
-
hash = "sha256-PCttIsWSBQd6fDXL49jepszUAMLnAGAKR//5EDO3XDk="
160
-
[mod."golang.org/x/sync"]
161
-
version = "v0.6.0"
162
-
hash = "sha256-LLims/wjDZtIqlYCVHREewcUOX4hwRwplEuZKPOJ/HI="
163
-
[mod."golang.org/x/sys"]
164
-
version = "v0.16.0"
165
-
hash = "sha256-ZkGclbp2S7NQYhbuGji6XokCn2Qi1BJy8dwyAOTV8sY="
166
-
[mod."golang.org/x/term"]
167
-
version = "v0.16.0"
168
-
hash = "sha256-9qlHcsCI1sa7ZI4Q+fJbOp3mG5Y+uV16e+pGmG+MQe0="
169
-
[mod."golang.org/x/text"]
170
-
version = "v0.14.0"
171
-
hash = "sha256-yh3B0tom1RfzQBf1RNmfdNWF1PtiqxV41jW1GVS6JAg="
172
-
[mod."golang.org/x/tools"]
173
-
version = "v0.17.0"
174
-
hash = "sha256-CxuHfKKtUkn3VjA7D9WQjzvV1EUbyI/xMNhb5CxO6IQ="
175
-
[mod."gopkg.in/warnings.v0"]
176
-
version = "v0.1.2"
177
-
hash = "sha256-ATVL9yEmgYbkJ1DkltDGRn/auGAjqGOfjQyBYyUo8s8="
178
-
[mod."gopkg.in/yaml.v2"]
179
-
version = "v2.4.0"
180
-
hash = "sha256-uVEGglIedjOIGZzHW4YwN1VoRSTK8o0eGZqzd+TNdd0="
···
+20
-2
internal/git/git.go
+20
-2
internal/git/git.go
···
98
}
99
}
100
101
-
fis := make([]FileInfo, 0)
102
for _, entry := range t.Entries {
103
fm, err := entry.Mode.ToOSFileMode()
104
if err != nil {
···
118
sort.Slice(fis, func(i, j int) bool {
119
fi1 := fis[i]
120
fi2 := fis[j]
121
-
return (fi1.IsDir && !fi2.IsDir) || fi1.Name() < fi2.Name()
122
})
123
124
return fis, nil
125
}
126
127
// FileContent returns the content of a file in the git tree at a given ref/rev
···
98
}
99
}
100
101
+
fis := make([]FileInfo, 0, len(t.Entries))
102
for _, entry := range t.Entries {
103
fm, err := entry.Mode.ToOSFileMode()
104
if err != nil {
···
118
sort.Slice(fis, func(i, j int) bool {
119
fi1 := fis[i]
120
fi2 := fis[j]
121
+
if fi1.IsDir != fi2.IsDir {
122
+
return fi1.IsDir
123
+
}
124
+
return fi1.Name() < fi2.Name()
125
})
126
127
return fis, nil
128
+
}
129
+
130
+
// GetCommitFromRef returns the commit object for a given ref
131
+
func (r Repo) GetCommitFromRef(ref string) (*object.Commit, error) {
132
+
g, err := r.Git()
133
+
if err != nil {
134
+
return nil, err
135
+
}
136
+
137
+
hash, err := g.ResolveRevision(plumbing.Revision(ref))
138
+
if err != nil {
139
+
return nil, err
140
+
}
141
+
142
+
return g.CommitObject(*hash)
143
}
144
145
// FileContent returns the content of a file in the git tree at a given ref/rev
+276
internal/git/git_test.go
+276
internal/git/git_test.go
···
···
1
+
package git_test
2
+
3
+
import (
4
+
"path/filepath"
5
+
"testing"
6
+
"time"
7
+
8
+
"github.com/alecthomas/assert/v2"
9
+
"github.com/go-git/go-git/v5/plumbing/protocol/packp"
10
+
"go.jolheiser.com/ugit/internal/git"
11
+
)
12
+
13
+
func TestEnsureRepo(t *testing.T) {
14
+
tmp := t.TempDir()
15
+
16
+
ok, err := git.PathExists(filepath.Join(tmp, "test"))
17
+
assert.False(t, ok, "repo should not exist yet")
18
+
assert.NoError(t, err, "PathExists should not error when repo doesn't exist")
19
+
20
+
err = git.EnsureRepo(tmp, "test")
21
+
assert.NoError(t, err, "repo should be created")
22
+
23
+
ok, err = git.PathExists(filepath.Join(tmp, "test"))
24
+
assert.True(t, ok, "repo should exist")
25
+
assert.NoError(t, err, "EnsureRepo should not error when path exists")
26
+
27
+
err = git.EnsureRepo(tmp, "test")
28
+
assert.NoError(t, err, "repo should already exist")
29
+
}
30
+
31
+
func TestRepo(t *testing.T) {
32
+
tmp := t.TempDir()
33
+
err := git.EnsureRepo(tmp, "test.git")
34
+
assert.NoError(t, err, "should create repo")
35
+
36
+
repo, err := git.NewRepo(tmp, "test")
37
+
assert.NoError(t, err, "should init new repo")
38
+
assert.True(t, repo.Meta.Private, "repo should default to private")
39
+
40
+
repo.Meta.Private = false
41
+
err = repo.SaveMeta()
42
+
assert.NoError(t, err, "should save repo meta")
43
+
44
+
repo, err = git.NewRepo(tmp, "test")
45
+
assert.NoError(t, err, "should not error when getting existing repo")
46
+
assert.False(t, repo.Meta.Private, "repo should be public after saving meta")
47
+
}
48
+
49
+
func TestPathExists(t *testing.T) {
50
+
tmp := t.TempDir()
51
+
exists, err := git.PathExists(tmp)
52
+
assert.NoError(t, err)
53
+
assert.True(t, exists)
54
+
55
+
doesNotExist := filepath.Join(tmp, "does-not-exist")
56
+
exists, err = git.PathExists(doesNotExist)
57
+
assert.NoError(t, err)
58
+
assert.False(t, exists)
59
+
}
60
+
61
+
func TestRepoMetaUpdate(t *testing.T) {
62
+
original := git.RepoMeta{
63
+
Description: "Original description",
64
+
Private: true,
65
+
Tags: git.TagSet{"tag1": struct{}{}, "tag2": struct{}{}},
66
+
}
67
+
68
+
update := git.RepoMeta{
69
+
Description: "Updated description",
70
+
Private: false,
71
+
Tags: git.TagSet{"tag3": struct{}{}},
72
+
}
73
+
74
+
err := original.Update(update)
75
+
assert.NoError(t, err)
76
+
77
+
assert.Equal(t, "Updated description", original.Description)
78
+
assert.False(t, original.Private)
79
+
assert.Equal(t, []string{"tag1", "tag2", "tag3"}, original.Tags.Slice())
80
+
}
81
+
82
+
func TestFileInfoName(t *testing.T) {
83
+
testCases := []struct {
84
+
path string
85
+
expected string
86
+
}{
87
+
{path: "file.txt", expected: "file.txt"},
88
+
{path: "dir/file.txt", expected: "file.txt"},
89
+
{path: "nested/path/to/file.go", expected: "file.go"},
90
+
{path: "README.md", expected: "README.md"},
91
+
}
92
+
93
+
for _, tc := range testCases {
94
+
t.Run(tc.path, func(t *testing.T) {
95
+
fi := git.FileInfo{Path: tc.path}
96
+
assert.Equal(t, tc.expected, fi.Name())
97
+
})
98
+
}
99
+
}
100
+
101
+
func TestCommitSummaryAndDetails(t *testing.T) {
102
+
testCases := []struct {
103
+
message string
104
+
expectedSummary string
105
+
expectedDetails string
106
+
}{
107
+
{
108
+
message: "Simple commit message",
109
+
expectedSummary: "Simple commit message",
110
+
expectedDetails: "",
111
+
},
112
+
{
113
+
message: "Add feature X\n\nThis commit adds feature X\nWith multiple details\nAcross multiple lines",
114
+
expectedSummary: "Add feature X",
115
+
expectedDetails: "\nThis commit adds feature X\nWith multiple details\nAcross multiple lines",
116
+
},
117
+
{
118
+
message: "Fix bug\n\nDetailed explanation",
119
+
expectedSummary: "Fix bug",
120
+
expectedDetails: "\nDetailed explanation",
121
+
},
122
+
}
123
+
124
+
for _, tc := range testCases {
125
+
t.Run(tc.message, func(t *testing.T) {
126
+
commit := git.Commit{
127
+
SHA: "abcdef1234567890",
128
+
Message: tc.message,
129
+
Signature: "",
130
+
Author: "Test User",
131
+
Email: "test@example.com",
132
+
When: time.Now(),
133
+
}
134
+
135
+
assert.Equal(t, tc.expectedSummary, commit.Summary())
136
+
assert.Equal(t, tc.expectedDetails, commit.Details())
137
+
})
138
+
}
139
+
}
140
+
141
+
func TestCommitShort(t *testing.T) {
142
+
commit := git.Commit{
143
+
SHA: "abcdef1234567890abcdef1234567890",
144
+
}
145
+
146
+
assert.Equal(t, "abcdef12", commit.Short())
147
+
}
148
+
149
+
func TestCommitFilePath(t *testing.T) {
150
+
testCases := []struct {
151
+
name string
152
+
fromPath string
153
+
toPath string
154
+
expected string
155
+
}{
156
+
{
157
+
name: "to path preferred",
158
+
fromPath: "old/path.txt",
159
+
toPath: "new/path.txt",
160
+
expected: "new/path.txt",
161
+
},
162
+
{
163
+
name: "fallback to from path",
164
+
fromPath: "deleted/file.txt",
165
+
toPath: "",
166
+
expected: "deleted/file.txt",
167
+
},
168
+
{
169
+
name: "both paths empty",
170
+
fromPath: "",
171
+
toPath: "",
172
+
expected: "",
173
+
},
174
+
}
175
+
176
+
for _, tc := range testCases {
177
+
t.Run(tc.name, func(t *testing.T) {
178
+
cf := git.CommitFile{
179
+
From: git.CommitFileEntry{Path: tc.fromPath},
180
+
To: git.CommitFileEntry{Path: tc.toPath},
181
+
}
182
+
assert.Equal(t, tc.expected, cf.Path())
183
+
})
184
+
}
185
+
}
186
+
187
+
func TestRepoName(t *testing.T) {
188
+
tmp := t.TempDir()
189
+
190
+
repoName := "testrepo"
191
+
err := git.EnsureRepo(tmp, repoName+".git")
192
+
assert.NoError(t, err)
193
+
194
+
repo, err := git.NewRepo(tmp, repoName)
195
+
assert.NoError(t, err)
196
+
assert.Equal(t, repoName, repo.Name())
197
+
198
+
repoName2 := "test-repo-with-hyphens"
199
+
err = git.EnsureRepo(tmp, repoName2+".git")
200
+
assert.NoError(t, err)
201
+
202
+
repo2, err := git.NewRepo(tmp, repoName2)
203
+
assert.NoError(t, err)
204
+
assert.Equal(t, repoName2, repo2.Name())
205
+
}
206
+
207
+
func TestHandlePushOptions(t *testing.T) {
208
+
tmp := t.TempDir()
209
+
err := git.EnsureRepo(tmp, "test.git")
210
+
assert.NoError(t, err)
211
+
212
+
repo, err := git.NewRepo(tmp, "test")
213
+
assert.NoError(t, err)
214
+
215
+
opts := []*packp.Option{
216
+
{Key: "description", Value: "New description"},
217
+
}
218
+
err = git.HandlePushOptions(repo, opts)
219
+
assert.NoError(t, err)
220
+
assert.Equal(t, "New description", repo.Meta.Description)
221
+
222
+
opts = []*packp.Option{
223
+
{Key: "private", Value: "false"},
224
+
}
225
+
err = git.HandlePushOptions(repo, opts)
226
+
assert.NoError(t, err)
227
+
assert.False(t, repo.Meta.Private)
228
+
229
+
repo.Meta.Private = true
230
+
opts = []*packp.Option{
231
+
{Key: "private", Value: "invalid"},
232
+
}
233
+
err = git.HandlePushOptions(repo, opts)
234
+
assert.NoError(t, err)
235
+
assert.True(t, repo.Meta.Private)
236
+
237
+
opts = []*packp.Option{
238
+
{Key: "tags", Value: "tag1,tag2"},
239
+
}
240
+
err = git.HandlePushOptions(repo, opts)
241
+
assert.NoError(t, err)
242
+
243
+
opts = []*packp.Option{
244
+
{Key: "description", Value: "Combined update"},
245
+
{Key: "private", Value: "true"},
246
+
}
247
+
err = git.HandlePushOptions(repo, opts)
248
+
assert.NoError(t, err)
249
+
assert.Equal(t, "Combined update", repo.Meta.Description)
250
+
assert.True(t, repo.Meta.Private)
251
+
}
252
+
253
+
func TestRepoPath(t *testing.T) {
254
+
tmp := t.TempDir()
255
+
err := git.EnsureRepo(tmp, "test.git")
256
+
assert.NoError(t, err)
257
+
258
+
repo, err := git.NewRepo(tmp, "test")
259
+
assert.NoError(t, err)
260
+
261
+
expected := filepath.Join(tmp, "test.git")
262
+
assert.Equal(t, expected, repo.Path())
263
+
}
264
+
265
+
func TestEnsureJSONFile(t *testing.T) {
266
+
tmp := t.TempDir()
267
+
err := git.EnsureRepo(tmp, "test.git")
268
+
assert.NoError(t, err)
269
+
270
+
repo, err := git.NewRepo(tmp, "test")
271
+
assert.NoError(t, err)
272
+
273
+
assert.True(t, repo.Meta.Private, "default repo should be private")
274
+
assert.Equal(t, "", repo.Meta.Description, "default description should be empty")
275
+
assert.Equal(t, 0, len(repo.Meta.Tags), "default tags should be empty")
276
+
}
+4
-2
internal/git/grep.go
+4
-2
internal/git/grep.go
···
18
19
// Grep performs a naive "code search" via git grep
20
func (r Repo) Grep(search string) ([]GrepResult, error) {
21
+
if strings.HasPrefix(search, "=") {
22
+
search = regexp.QuoteMeta(strings.TrimPrefix(search, "="))
23
+
}
24
+
re, err := regexp.Compile(search)
25
if err != nil {
26
return nil, err
27
}
+66
-4
internal/git/meta.go
+66
-4
internal/git/meta.go
···
3
import (
4
"encoding/json"
5
"errors"
6
"io/fs"
7
"os"
8
"path/filepath"
9
)
10
11
// RepoMeta is the meta information a Repo can have
12
type RepoMeta struct {
13
-
Description string `json:"description"`
14
-
Private bool `json:"private"`
15
-
Tags []string `json:"tags"`
16
}
17
18
// Update updates meta given another RepoMeta
···
46
return json.NewEncoder(fi).Encode(r.Meta)
47
}
48
49
func ensureJSONFile(path string) error {
50
_, err := os.Stat(path)
51
if err == nil {
···
59
return err
60
}
61
defer fi.Close()
62
-
if _, err := fi.WriteString(`{"private":true}`); err != nil {
63
return err
64
}
65
return nil
···
3
import (
4
"encoding/json"
5
"errors"
6
+
"fmt"
7
"io/fs"
8
"os"
9
"path/filepath"
10
+
"slices"
11
)
12
13
// RepoMeta is the meta information a Repo can have
14
type RepoMeta struct {
15
+
Description string `json:"description"`
16
+
Private bool `json:"private"`
17
+
Tags TagSet `json:"tags"`
18
+
}
19
+
20
+
// TagSet is a Set of tags
21
+
type TagSet map[string]struct{}
22
+
23
+
// Add adds a tag to the set
24
+
func (t TagSet) Add(tag string) {
25
+
t[tag] = struct{}{}
26
+
}
27
+
28
+
// Remove removes a tag from the set
29
+
func (t TagSet) Remove(tag string) {
30
+
delete(t, tag)
31
+
}
32
+
33
+
// Contains checks if a tag is in the set
34
+
func (t TagSet) Contains(tag string) bool {
35
+
_, ok := t[tag]
36
+
return ok
37
+
}
38
+
39
+
// Slice returns the set as a (sorted) slice
40
+
func (t TagSet) Slice() []string {
41
+
s := make([]string, 0, len(t))
42
+
for k := range t {
43
+
s = append(s, k)
44
+
}
45
+
slices.Sort(s)
46
+
return s
47
+
}
48
+
49
+
// MarshalJSON implements [json.Marshaler]
50
+
func (t TagSet) MarshalJSON() ([]byte, error) {
51
+
return json.Marshal(t.Slice())
52
+
}
53
+
54
+
// UnmarshalJSON implements [json.Unmarshaler]
55
+
func (t *TagSet) UnmarshalJSON(b []byte) error {
56
+
if *t == nil {
57
+
ts := make(TagSet)
58
+
t = &ts
59
+
}
60
+
var s []string
61
+
if err := json.Unmarshal(b, &s); err != nil {
62
+
return err
63
+
}
64
+
for _, ss := range s {
65
+
t.Add(ss)
66
+
}
67
+
return nil
68
}
69
70
// Update updates meta given another RepoMeta
···
98
return json.NewEncoder(fi).Encode(r.Meta)
99
}
100
101
+
var defaultMeta = func() []byte {
102
+
b, err := json.Marshal(RepoMeta{
103
+
Private: true,
104
+
})
105
+
if err != nil {
106
+
panic(fmt.Sprintf("could not init default meta: %v", err))
107
+
}
108
+
return b
109
+
}()
110
+
111
func ensureJSONFile(path string) error {
112
_, err := os.Stat(path)
113
if err == nil {
···
121
return err
122
}
123
defer fi.Close()
124
+
if _, err := fi.Write(defaultMeta); err != nil {
125
return err
126
}
127
return nil
+53
internal/git/meta_test.go
+53
internal/git/meta_test.go
···
···
1
+
package git
2
+
3
+
import (
4
+
"encoding/json"
5
+
"testing"
6
+
7
+
"github.com/alecthomas/assert/v2"
8
+
)
9
+
10
+
func TestTagSet(t *testing.T) {
11
+
set := make(TagSet)
12
+
assert.Equal(t, 0, len(set))
13
+
assert.Equal(t, 0, len(set.Slice()))
14
+
15
+
set.Add("foo")
16
+
assert.Equal(t, 1, len(set))
17
+
assert.Equal(t, 1, len(set.Slice()))
18
+
assert.True(t, set.Contains("foo"))
19
+
20
+
set.Add("bar")
21
+
assert.Equal(t, 2, len(set))
22
+
assert.Equal(t, 2, len(set.Slice()))
23
+
assert.True(t, set.Contains("foo"))
24
+
assert.True(t, set.Contains("bar"))
25
+
26
+
set.Add("bar")
27
+
assert.Equal(t, 2, len(set))
28
+
assert.Equal(t, 2, len(set.Slice()))
29
+
assert.True(t, set.Contains("foo"))
30
+
assert.True(t, set.Contains("bar"))
31
+
32
+
set.Remove("foo")
33
+
assert.Equal(t, 1, len(set))
34
+
assert.Equal(t, 1, len(set.Slice()))
35
+
assert.False(t, set.Contains("foo"))
36
+
assert.True(t, set.Contains("bar"))
37
+
38
+
set.Add("foo")
39
+
set.Add("baz")
40
+
j, err := json.Marshal(set)
41
+
assert.NoError(t, err)
42
+
assert.Equal(t, `["bar","baz","foo"]`, string(j))
43
+
44
+
set = make(TagSet)
45
+
b := []byte(`["foo","bar","baz"]`)
46
+
err = json.Unmarshal(b, &set)
47
+
assert.NoError(t, err)
48
+
assert.Equal(t, 3, len(set))
49
+
assert.Equal(t, 3, len(set.Slice()))
50
+
assert.True(t, set.Contains("foo"))
51
+
assert.True(t, set.Contains("bar"))
52
+
assert.True(t, set.Contains("baz"))
53
+
}
+5
-9
internal/git/protocol.go
+5
-9
internal/git/protocol.go
···
58
remove = true
59
tagValue = strings.TrimPrefix(tagValue, "-")
60
}
61
-
for idx, tag := range repo.Meta.Tags {
62
-
if strings.EqualFold(tag, tagValue) {
63
-
if remove {
64
-
repo.Meta.Tags = append(repo.Meta.Tags[:idx], repo.Meta.Tags[idx+1:]...)
65
-
} else {
66
-
repo.Meta.Tags = append(repo.Meta.Tags, strings.ToLower(tagValue))
67
-
}
68
-
break
69
-
}
70
}
71
}
72
}
-1
internal/git/protocol_git.go
-1
internal/git/protocol_git.go
+11
internal/git/repo.go
+11
internal/git/repo.go
···
57
if err := json.NewDecoder(fi).Decode(&r.Meta); err != nil {
58
return nil, err
59
}
60
+
if r.Meta.Tags == nil {
61
+
r.Meta.Tags = make(TagSet)
62
+
}
63
64
return r, nil
65
}
···
135
type CommitFileEntry struct {
136
Path string
137
Commit string
138
+
}
139
+
140
+
// Path returns either the To or From path, in order of preference
141
+
func (c CommitFile) Path() string {
142
+
if c.To.Path != "" {
143
+
return c.To.Path
144
+
}
145
+
return c.From.Path
146
}
147
148
// Short returns the first eight characters of the SHA
+3
-1
internal/html/base.templ
+3
-1
internal/html/base.templ
···
18
<meta property="og:description" content={ bc.Description }/>
19
</head>
20
<body class="latte dark:mocha bg-base/50 dark:bg-base/95 max-w-7xl mx-5 sm:mx-auto my-10">
21
-
<h2 class="text-text text-xl mb-3"><a class="underline decoration-text/50 decoration-dashed hover:decoration-solid" href="/">Home</a></h2>
22
{ children... }
23
</body>
24
</html>
···
18
<meta property="og:description" content={ bc.Description }/>
19
</head>
20
<body class="latte dark:mocha bg-base/50 dark:bg-base/95 max-w-7xl mx-5 sm:mx-auto my-10">
21
+
<h2 class="text-text text-xl mb-3">
22
+
<a class="underline decoration-text/50 decoration-dashed hover:decoration-solid" href="/">Home</a>
23
+
</h2>
24
{ children... }
25
</body>
26
</html>
+22
-17
internal/html/base_templ.go
+22
-17
internal/html/base_templ.go
···
1
// Code generated by templ - DO NOT EDIT.
2
3
-
// templ: version: v0.2.707
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
-
import "context"
10
-
import "io"
11
-
import "bytes"
12
13
type BaseContext struct {
14
Title string
···
16
}
17
18
func base(bc BaseContext) templ.Component {
19
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
20
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
21
if !templ_7745c5c3_IsBuffer {
22
-
templ_7745c5c3_Buffer = templ.GetBuffer()
23
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
24
}
25
ctx = templ.InitializeContext(ctx)
26
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
28
templ_7745c5c3_Var1 = templ.NopComponent
29
}
30
ctx = templ.ClearChildren(ctx)
31
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>")
32
if templ_7745c5c3_Err != nil {
33
return templ_7745c5c3_Err
34
}
···
41
if templ_7745c5c3_Err != nil {
42
return templ_7745c5c3_Err
43
}
44
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</title><link rel=\"icon\" href=\"/_/favicon.svg\"><link rel=\"stylesheet\" href=\"/_/tailwind.css\"><meta property=\"og:title\" content=\"")
45
if templ_7745c5c3_Err != nil {
46
return templ_7745c5c3_Err
47
}
···
54
if templ_7745c5c3_Err != nil {
55
return templ_7745c5c3_Err
56
}
57
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><meta property=\"og:description\" content=\"")
58
if templ_7745c5c3_Err != nil {
59
return templ_7745c5c3_Err
60
}
···
67
if templ_7745c5c3_Err != nil {
68
return templ_7745c5c3_Err
69
}
70
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></head><body class=\"latte dark:mocha bg-base/50 dark:bg-base/95 max-w-7xl mx-5 sm:mx-auto my-10\"><h2 class=\"text-text text-xl mb-3\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"/\">Home</a></h2>")
71
if templ_7745c5c3_Err != nil {
72
return templ_7745c5c3_Err
73
}
···
75
if templ_7745c5c3_Err != nil {
76
return templ_7745c5c3_Err
77
}
78
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</body></html>")
79
if templ_7745c5c3_Err != nil {
80
return templ_7745c5c3_Err
81
}
82
-
if !templ_7745c5c3_IsBuffer {
83
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
84
-
}
85
-
return templ_7745c5c3_Err
86
})
87
}
···
1
// Code generated by templ - DO NOT EDIT.
2
3
+
// templ: version: v0.3.924
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
11
type BaseContext struct {
12
Title string
···
14
}
15
16
func base(bc BaseContext) templ.Component {
17
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
18
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
19
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
20
+
return templ_7745c5c3_CtxErr
21
+
}
22
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
23
if !templ_7745c5c3_IsBuffer {
24
+
defer func() {
25
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
26
+
if templ_7745c5c3_Err == nil {
27
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
28
+
}
29
+
}()
30
}
31
ctx = templ.InitializeContext(ctx)
32
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
34
templ_7745c5c3_Var1 = templ.NopComponent
35
}
36
ctx = templ.ClearChildren(ctx)
37
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype html><html><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>")
38
if templ_7745c5c3_Err != nil {
39
return templ_7745c5c3_Err
40
}
···
47
if templ_7745c5c3_Err != nil {
48
return templ_7745c5c3_Err
49
}
50
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</title><link rel=\"icon\" href=\"/_/favicon.svg\"><link rel=\"stylesheet\" href=\"/_/tailwind.css\"><meta property=\"og:title\" content=\"")
51
if templ_7745c5c3_Err != nil {
52
return templ_7745c5c3_Err
53
}
···
60
if templ_7745c5c3_Err != nil {
61
return templ_7745c5c3_Err
62
}
63
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"><meta property=\"og:description\" content=\"")
64
if templ_7745c5c3_Err != nil {
65
return templ_7745c5c3_Err
66
}
···
73
if templ_7745c5c3_Err != nil {
74
return templ_7745c5c3_Err
75
}
76
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\"></head><body class=\"latte dark:mocha bg-base/50 dark:bg-base/95 max-w-7xl mx-5 sm:mx-auto my-10\"><h2 class=\"text-text text-xl mb-3\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"/\">Home</a></h2>")
77
if templ_7745c5c3_Err != nil {
78
return templ_7745c5c3_Err
79
}
···
81
if templ_7745c5c3_Err != nil {
82
return templ_7745c5c3_Err
83
}
84
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</body></html>")
85
if templ_7745c5c3_Err != nil {
86
return templ_7745c5c3_Err
87
}
88
+
return nil
89
})
90
}
91
+
92
+
var _ = templruntime.GeneratedTemplate
-4
internal/html/generate.css
-4
internal/html/generate.css
+6
-4
internal/html/generate.go
+6
-4
internal/html/generate.go
···
12
13
"go.jolheiser.com/ugit/internal/html/markup"
14
15
"github.com/alecthomas/chroma/v2/styles"
16
)
17
···
25
otherCSS string
26
)
27
28
-
//go:generate templ generate
29
//go:generate go run generate.go
30
func main() {
31
if err := tailwind(); err != nil {
···
33
}
34
}
35
36
-
// Generate tailwind code from templ templates and combine with other misc CSS
37
func tailwind() error {
38
fmt.Println("generating tailwind...")
39
···
47
}
48
49
fmt.Println("generating chroma styles...")
50
51
latte := styles.Get("catppuccin-latte")
52
-
if err := markup.Formatter.WriteCSS(tmp, latte); err != nil {
53
return err
54
}
55
56
tmp.WriteString("@media (prefers-color-scheme: dark) {")
57
mocha := styles.Get("catppuccin-mocha")
58
-
if err := markup.Formatter.WriteCSS(tmp, mocha); err != nil {
59
return err
60
}
61
tmp.WriteString("}")
···
12
13
"go.jolheiser.com/ugit/internal/html/markup"
14
15
+
"github.com/alecthomas/chroma/v2/formatters/html"
16
"github.com/alecthomas/chroma/v2/styles"
17
)
18
···
26
otherCSS string
27
)
28
29
+
//go:generate go tool templ generate
30
//go:generate go run generate.go
31
func main() {
32
if err := tailwind(); err != nil {
···
34
}
35
}
36
37
+
// Generate tailwind code from templates and combine with other misc CSS
38
func tailwind() error {
39
fmt.Println("generating tailwind...")
40
···
48
}
49
50
fmt.Println("generating chroma styles...")
51
+
formatter := html.New(markup.Options("")...)
52
53
latte := styles.Get("catppuccin-latte")
54
+
if err := formatter.WriteCSS(tmp, latte); err != nil {
55
return err
56
}
57
58
tmp.WriteString("@media (prefers-color-scheme: dark) {")
59
mocha := styles.Get("catppuccin-mocha")
60
+
if err := formatter.WriteCSS(tmp, mocha); err != nil {
61
return err
62
}
63
tmp.WriteString("}")
+28
-8
internal/html/index.templ
+28
-8
internal/html/index.templ
···
1
package html
2
3
-
import "go.jolheiser.com/ugit/internal/git"
4
-
import "github.com/dustin/go-humanize"
5
-
import "go.jolheiser.com/ugit/assets"
6
7
type IndexContext struct {
8
BaseContext
···
21
URL string
22
}
23
24
-
func lastCommit(repo *git.Repo, human bool) string {
25
c, err := repo.LastCommit()
26
if err != nil {
27
return ""
···
32
return c.When.Format("01/02/2006 03:04:05 PM")
33
}
34
35
templ Index(ic IndexContext) {
36
@base(ic.BaseContext) {
37
<header>
···
62
</div>
63
}
64
</div>
65
-
<div class="grid sm:grid-cols-8 gap-2 mt-5">
66
for _, repo := range ic.Repos {
67
<div class="sm:col-span-2 text-blue dark:text-lavender"><a class="underline decoration-blue/50 dark:decoration-lavender/50 decoration-dashed hover:decoration-solid" href={ templ.URL("/" + repo.Name()) }>{ repo.Name() }</a></div>
68
-
<div class="sm:col-span-4 text-subtext0">{ repo.Meta.Description }</div>
69
<div class="sm:col-span-1 text-subtext0">
70
-
for _, tag := range repo.Meta.Tags {
71
<a href={ templ.SafeURL("?tag=" + tag) } class="rounded border-rosewater border-solid border pb-0.5 px-1 mr-1 mb-1 inline-block">{ tag }</a>
72
}
73
</div>
74
-
<div class="sm:col-span-1 text-text/80 mb-4 sm:mb-0" title={ lastCommit(repo, false) }>{ lastCommit(repo, true) }</div>
75
}
76
</div>
77
</main>
···
1
package html
2
3
+
import (
4
+
"fmt"
5
+
"github.com/dustin/go-humanize"
6
+
"go.jolheiser.com/ugit/assets"
7
+
"go.jolheiser.com/ugit/internal/git"
8
+
)
9
10
type IndexContext struct {
11
BaseContext
···
24
URL string
25
}
26
27
+
func lastCommitTime(repo *git.Repo, human bool) string {
28
c, err := repo.LastCommit()
29
if err != nil {
30
return ""
···
35
return c.When.Format("01/02/2006 03:04:05 PM")
36
}
37
38
+
func lastCommit(repo *git.Repo) *git.Commit {
39
+
c, err := repo.LastCommit()
40
+
if err != nil {
41
+
return nil
42
+
}
43
+
return &c
44
+
}
45
+
46
templ Index(ic IndexContext) {
47
@base(ic.BaseContext) {
48
<header>
···
73
</div>
74
}
75
</div>
76
+
<div class="grid sm:grid-cols-10 gap-2 mt-5">
77
for _, repo := range ic.Repos {
78
+
{{ commit := lastCommit(repo) }}
79
<div class="sm:col-span-2 text-blue dark:text-lavender"><a class="underline decoration-blue/50 dark:decoration-lavender/50 decoration-dashed hover:decoration-solid" href={ templ.URL("/" + repo.Name()) }>{ repo.Name() }</a></div>
80
+
<div class="sm:col-span-3 text-subtext0">{ repo.Meta.Description }</div>
81
+
<div class="sm:col-span-3 text-subtext0">
82
+
if commit != nil {
83
+
<div title={ commit.Message }>
84
+
<a class="underline text-blue dark:text-lavender decoration-blue/50 dark:decoration-lavender/50 decoration-dashed hover:decoration-solid" href={ fmt.Sprintf("/%s/commit/%s", repo.Name(), commit.SHA) }>{ commit.Short() }</a>
85
+
{ ": " + commit.Summary() }
86
+
</div>
87
+
}
88
+
</div>
89
<div class="sm:col-span-1 text-subtext0">
90
+
for _, tag := range repo.Meta.Tags.Slice() {
91
<a href={ templ.SafeURL("?tag=" + tag) } class="rounded border-rosewater border-solid border pb-0.5 px-1 mr-1 mb-1 inline-block">{ tag }</a>
92
}
93
</div>
94
+
<div class="sm:col-span-1 text-text/80 mb-4 sm:mb-0" title={ lastCommitTime(repo, false) }>{ lastCommitTime(repo, true) }</div>
95
}
96
</div>
97
</main>
+175
-77
internal/html/index_templ.go
+175
-77
internal/html/index_templ.go
···
1
// Code generated by templ - DO NOT EDIT.
2
3
-
// templ: version: v0.2.707
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
-
import "context"
10
-
import "io"
11
-
import "bytes"
12
13
-
import "go.jolheiser.com/ugit/internal/git"
14
-
import "github.com/dustin/go-humanize"
15
-
import "go.jolheiser.com/ugit/assets"
16
17
type IndexContext struct {
18
BaseContext
···
31
URL string
32
}
33
34
-
func lastCommit(repo *git.Repo, human bool) string {
35
c, err := repo.LastCommit()
36
if err != nil {
37
return ""
···
42
return c.When.Format("01/02/2006 03:04:05 PM")
43
}
44
45
func Index(ic IndexContext) templ.Component {
46
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
47
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
48
if !templ_7745c5c3_IsBuffer {
49
-
templ_7745c5c3_Buffer = templ.GetBuffer()
50
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
51
}
52
ctx = templ.InitializeContext(ctx)
53
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
55
templ_7745c5c3_Var1 = templ.NopComponent
56
}
57
ctx = templ.ClearChildren(ctx)
58
-
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
59
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
60
if !templ_7745c5c3_IsBuffer {
61
-
templ_7745c5c3_Buffer = templ.GetBuffer()
62
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
63
}
64
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<header><h1 class=\"text-text text-xl font-bold\">")
65
if templ_7745c5c3_Err != nil {
66
return templ_7745c5c3_Err
67
}
68
var templ_7745c5c3_Var3 string
69
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(ic.Title)
70
if templ_7745c5c3_Err != nil {
71
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 38, Col: 53}
72
}
73
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
74
if templ_7745c5c3_Err != nil {
75
return templ_7745c5c3_Err
76
}
77
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h1><h2 class=\"text-subtext1 text-lg\">")
78
if templ_7745c5c3_Err != nil {
79
return templ_7745c5c3_Err
80
}
81
var templ_7745c5c3_Var4 string
82
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(ic.Description)
83
if templ_7745c5c3_Err != nil {
84
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 39, Col: 53}
85
}
86
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
87
if templ_7745c5c3_Err != nil {
88
return templ_7745c5c3_Err
89
}
90
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</h2></header><main class=\"mt-5\"><div class=\"grid grid-cols-1 sm:grid-cols-8\">")
91
if templ_7745c5c3_Err != nil {
92
return templ_7745c5c3_Err
93
}
94
if ic.Profile.Username != "" {
95
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"text-mauve\">")
96
if templ_7745c5c3_Err != nil {
97
return templ_7745c5c3_Err
98
}
99
var templ_7745c5c3_Var5 string
100
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(`@` + ic.Profile.Username)
101
if templ_7745c5c3_Err != nil {
102
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 44, Col: 56}
103
}
104
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
105
if templ_7745c5c3_Err != nil {
106
return templ_7745c5c3_Err
107
}
108
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
109
if templ_7745c5c3_Err != nil {
110
return templ_7745c5c3_Err
111
}
112
}
113
if ic.Profile.Email != "" {
114
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"text-mauve col-span-2\"><div class=\"w-5 h-5 stroke-mauve inline-block mr-1 align-middle\">")
115
if templ_7745c5c3_Err != nil {
116
return templ_7745c5c3_Err
117
}
···
119
if templ_7745c5c3_Err != nil {
120
return templ_7745c5c3_Err
121
}
122
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><a class=\"underline decoration-mauve/50 decoration-dashed hover:decoration-solid\" href=\"")
123
if templ_7745c5c3_Err != nil {
124
return templ_7745c5c3_Err
125
}
126
-
var templ_7745c5c3_Var6 templ.SafeURL = templ.SafeURL("mailto:" + ic.Profile.Email)
127
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var6)))
128
if templ_7745c5c3_Err != nil {
129
return templ_7745c5c3_Err
130
}
131
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
132
if templ_7745c5c3_Err != nil {
133
return templ_7745c5c3_Err
134
}
135
var templ_7745c5c3_Var7 string
136
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(ic.Profile.Email)
137
if templ_7745c5c3_Err != nil {
138
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 51, Col: 159}
139
}
140
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
141
if templ_7745c5c3_Err != nil {
142
return templ_7745c5c3_Err
143
}
144
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div>")
145
if templ_7745c5c3_Err != nil {
146
return templ_7745c5c3_Err
147
}
148
}
149
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"grid grid-cols-1 sm:grid-cols-8\">")
150
if templ_7745c5c3_Err != nil {
151
return templ_7745c5c3_Err
152
}
153
for _, link := range ic.Profile.Links {
154
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"text-mauve\"><div class=\"w-5 h-5 stroke-mauve inline-block mr-1 align-middle\">")
155
if templ_7745c5c3_Err != nil {
156
return templ_7745c5c3_Err
157
}
···
159
if templ_7745c5c3_Err != nil {
160
return templ_7745c5c3_Err
161
}
162
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><a class=\"underline decoration-mauve/50 decoration-dashed hover:decoration-solid\" rel=\"me\" href=\"")
163
if templ_7745c5c3_Err != nil {
164
return templ_7745c5c3_Err
165
}
166
-
var templ_7745c5c3_Var8 templ.SafeURL = templ.SafeURL(link.URL)
167
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var8)))
168
if templ_7745c5c3_Err != nil {
169
return templ_7745c5c3_Err
170
}
171
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
172
if templ_7745c5c3_Err != nil {
173
return templ_7745c5c3_Err
174
}
175
var templ_7745c5c3_Var9 string
176
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(link.Name)
177
if templ_7745c5c3_Err != nil {
178
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 61, Col: 141}
179
}
180
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
181
if templ_7745c5c3_Err != nil {
182
return templ_7745c5c3_Err
183
}
184
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div>")
185
if templ_7745c5c3_Err != nil {
186
return templ_7745c5c3_Err
187
}
188
}
189
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"grid sm:grid-cols-8 gap-2 mt-5\">")
190
if templ_7745c5c3_Err != nil {
191
return templ_7745c5c3_Err
192
}
193
for _, repo := range ic.Repos {
194
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"sm:col-span-2 text-blue dark:text-lavender\"><a class=\"underline decoration-blue/50 dark:decoration-lavender/50 decoration-dashed hover:decoration-solid\" href=\"")
195
if templ_7745c5c3_Err != nil {
196
return templ_7745c5c3_Err
197
}
198
-
var templ_7745c5c3_Var10 templ.SafeURL = templ.URL("/" + repo.Name())
199
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var10)))
200
if templ_7745c5c3_Err != nil {
201
return templ_7745c5c3_Err
202
}
203
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
204
if templ_7745c5c3_Err != nil {
205
return templ_7745c5c3_Err
206
}
207
var templ_7745c5c3_Var11 string
208
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(repo.Name())
209
if templ_7745c5c3_Err != nil {
210
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 67, Col: 221}
211
}
212
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
213
if templ_7745c5c3_Err != nil {
214
return templ_7745c5c3_Err
215
}
216
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div><div class=\"sm:col-span-4 text-subtext0\">")
217
if templ_7745c5c3_Err != nil {
218
return templ_7745c5c3_Err
219
}
220
var templ_7745c5c3_Var12 string
221
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(repo.Meta.Description)
222
if templ_7745c5c3_Err != nil {
223
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 68, Col: 69}
224
}
225
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
226
if templ_7745c5c3_Err != nil {
227
return templ_7745c5c3_Err
228
}
229
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"sm:col-span-1 text-subtext0\">")
230
if templ_7745c5c3_Err != nil {
231
return templ_7745c5c3_Err
232
}
233
-
for _, tag := range repo.Meta.Tags {
234
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a href=\"")
235
if templ_7745c5c3_Err != nil {
236
return templ_7745c5c3_Err
237
}
238
-
var templ_7745c5c3_Var13 templ.SafeURL = templ.SafeURL("?tag=" + tag)
239
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var13)))
240
if templ_7745c5c3_Err != nil {
241
return templ_7745c5c3_Err
242
}
243
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" class=\"rounded border-rosewater border-solid border pb-0.5 px-1 mr-1 mb-1 inline-block\">")
244
if templ_7745c5c3_Err != nil {
245
return templ_7745c5c3_Err
246
}
247
-
var templ_7745c5c3_Var14 string
248
-
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(tag)
249
if templ_7745c5c3_Err != nil {
250
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 71, Col: 141}
251
}
252
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
253
if templ_7745c5c3_Err != nil {
254
return templ_7745c5c3_Err
255
}
256
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a>")
257
if templ_7745c5c3_Err != nil {
258
return templ_7745c5c3_Err
259
}
260
}
261
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"sm:col-span-1 text-text/80 mb-4 sm:mb-0\" title=\"")
262
if templ_7745c5c3_Err != nil {
263
return templ_7745c5c3_Err
264
}
265
-
var templ_7745c5c3_Var15 string
266
-
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(lastCommit(repo, false))
267
if templ_7745c5c3_Err != nil {
268
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 74, Col: 89}
269
}
270
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
271
if templ_7745c5c3_Err != nil {
272
return templ_7745c5c3_Err
273
}
274
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
275
if templ_7745c5c3_Err != nil {
276
return templ_7745c5c3_Err
277
}
278
-
var templ_7745c5c3_Var16 string
279
-
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(lastCommit(repo, true))
280
if templ_7745c5c3_Err != nil {
281
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 74, Col: 116}
282
}
283
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
284
if templ_7745c5c3_Err != nil {
285
return templ_7745c5c3_Err
286
}
287
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
288
if templ_7745c5c3_Err != nil {
289
return templ_7745c5c3_Err
290
}
291
}
292
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></main>")
293
if templ_7745c5c3_Err != nil {
294
return templ_7745c5c3_Err
295
}
296
-
if !templ_7745c5c3_IsBuffer {
297
-
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
298
-
}
299
-
return templ_7745c5c3_Err
300
})
301
templ_7745c5c3_Err = base(ic.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
302
if templ_7745c5c3_Err != nil {
303
return templ_7745c5c3_Err
304
}
305
-
if !templ_7745c5c3_IsBuffer {
306
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
307
-
}
308
-
return templ_7745c5c3_Err
309
})
310
}
···
1
// Code generated by templ - DO NOT EDIT.
2
3
+
// templ: version: v0.3.924
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
11
+
import (
12
+
"fmt"
13
+
"github.com/dustin/go-humanize"
14
+
"go.jolheiser.com/ugit/assets"
15
+
"go.jolheiser.com/ugit/internal/git"
16
+
)
17
18
type IndexContext struct {
19
BaseContext
···
32
URL string
33
}
34
35
+
func lastCommitTime(repo *git.Repo, human bool) string {
36
c, err := repo.LastCommit()
37
if err != nil {
38
return ""
···
43
return c.When.Format("01/02/2006 03:04:05 PM")
44
}
45
46
+
func lastCommit(repo *git.Repo) *git.Commit {
47
+
c, err := repo.LastCommit()
48
+
if err != nil {
49
+
return nil
50
+
}
51
+
return &c
52
+
}
53
+
54
func Index(ic IndexContext) templ.Component {
55
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
56
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
57
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
58
+
return templ_7745c5c3_CtxErr
59
+
}
60
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
61
if !templ_7745c5c3_IsBuffer {
62
+
defer func() {
63
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
64
+
if templ_7745c5c3_Err == nil {
65
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
66
+
}
67
+
}()
68
}
69
ctx = templ.InitializeContext(ctx)
70
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
72
templ_7745c5c3_Var1 = templ.NopComponent
73
}
74
ctx = templ.ClearChildren(ctx)
75
+
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
76
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
77
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
78
if !templ_7745c5c3_IsBuffer {
79
+
defer func() {
80
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
81
+
if templ_7745c5c3_Err == nil {
82
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
83
+
}
84
+
}()
85
}
86
+
ctx = templ.InitializeContext(ctx)
87
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<header><h1 class=\"text-text text-xl font-bold\">")
88
if templ_7745c5c3_Err != nil {
89
return templ_7745c5c3_Err
90
}
91
var templ_7745c5c3_Var3 string
92
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(ic.Title)
93
if templ_7745c5c3_Err != nil {
94
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 49, Col: 53}
95
}
96
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
97
if templ_7745c5c3_Err != nil {
98
return templ_7745c5c3_Err
99
}
100
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</h1><h2 class=\"text-subtext1 text-lg\">")
101
if templ_7745c5c3_Err != nil {
102
return templ_7745c5c3_Err
103
}
104
var templ_7745c5c3_Var4 string
105
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(ic.Description)
106
if templ_7745c5c3_Err != nil {
107
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 50, Col: 53}
108
}
109
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
110
if templ_7745c5c3_Err != nil {
111
return templ_7745c5c3_Err
112
}
113
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</h2></header><main class=\"mt-5\"><div class=\"grid grid-cols-1 sm:grid-cols-8\">")
114
if templ_7745c5c3_Err != nil {
115
return templ_7745c5c3_Err
116
}
117
if ic.Profile.Username != "" {
118
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<div class=\"text-mauve\">")
119
if templ_7745c5c3_Err != nil {
120
return templ_7745c5c3_Err
121
}
122
var templ_7745c5c3_Var5 string
123
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(`@` + ic.Profile.Username)
124
if templ_7745c5c3_Err != nil {
125
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 55, Col: 56}
126
}
127
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
128
if templ_7745c5c3_Err != nil {
129
return templ_7745c5c3_Err
130
}
131
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</div>")
132
if templ_7745c5c3_Err != nil {
133
return templ_7745c5c3_Err
134
}
135
}
136
if ic.Profile.Email != "" {
137
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<div class=\"text-mauve col-span-2\"><div class=\"w-5 h-5 stroke-mauve inline-block mr-1 align-middle\">")
138
if templ_7745c5c3_Err != nil {
139
return templ_7745c5c3_Err
140
}
···
142
if templ_7745c5c3_Err != nil {
143
return templ_7745c5c3_Err
144
}
145
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div><a class=\"underline decoration-mauve/50 decoration-dashed hover:decoration-solid\" href=\"")
146
if templ_7745c5c3_Err != nil {
147
return templ_7745c5c3_Err
148
}
149
+
var templ_7745c5c3_Var6 templ.SafeURL
150
+
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("mailto:" + ic.Profile.Email))
151
+
if templ_7745c5c3_Err != nil {
152
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 62, Col: 138}
153
+
}
154
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
155
if templ_7745c5c3_Err != nil {
156
return templ_7745c5c3_Err
157
}
158
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\">")
159
if templ_7745c5c3_Err != nil {
160
return templ_7745c5c3_Err
161
}
162
var templ_7745c5c3_Var7 string
163
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(ic.Profile.Email)
164
if templ_7745c5c3_Err != nil {
165
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 62, Col: 159}
166
}
167
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
168
if templ_7745c5c3_Err != nil {
169
return templ_7745c5c3_Err
170
}
171
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</a></div>")
172
if templ_7745c5c3_Err != nil {
173
return templ_7745c5c3_Err
174
}
175
}
176
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</div><div class=\"grid grid-cols-1 sm:grid-cols-8\">")
177
if templ_7745c5c3_Err != nil {
178
return templ_7745c5c3_Err
179
}
180
for _, link := range ic.Profile.Links {
181
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<div class=\"text-mauve\"><div class=\"w-5 h-5 stroke-mauve inline-block mr-1 align-middle\">")
182
if templ_7745c5c3_Err != nil {
183
return templ_7745c5c3_Err
184
}
···
186
if templ_7745c5c3_Err != nil {
187
return templ_7745c5c3_Err
188
}
189
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</div><a class=\"underline decoration-mauve/50 decoration-dashed hover:decoration-solid\" rel=\"me\" href=\"")
190
if templ_7745c5c3_Err != nil {
191
return templ_7745c5c3_Err
192
}
193
+
var templ_7745c5c3_Var8 templ.SafeURL
194
+
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(link.URL))
195
+
if templ_7745c5c3_Err != nil {
196
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 72, Col: 127}
197
+
}
198
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
199
if templ_7745c5c3_Err != nil {
200
return templ_7745c5c3_Err
201
}
202
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\">")
203
if templ_7745c5c3_Err != nil {
204
return templ_7745c5c3_Err
205
}
206
var templ_7745c5c3_Var9 string
207
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(link.Name)
208
if templ_7745c5c3_Err != nil {
209
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 72, Col: 141}
210
}
211
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
212
if templ_7745c5c3_Err != nil {
213
return templ_7745c5c3_Err
214
}
215
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</a></div>")
216
if templ_7745c5c3_Err != nil {
217
return templ_7745c5c3_Err
218
}
219
}
220
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</div><div class=\"grid sm:grid-cols-10 gap-2 mt-5\">")
221
if templ_7745c5c3_Err != nil {
222
return templ_7745c5c3_Err
223
}
224
for _, repo := range ic.Repos {
225
+
commit := lastCommit(repo)
226
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<div class=\"sm:col-span-2 text-blue dark:text-lavender\"><a class=\"underline decoration-blue/50 dark:decoration-lavender/50 decoration-dashed hover:decoration-solid\" href=\"")
227
if templ_7745c5c3_Err != nil {
228
return templ_7745c5c3_Err
229
}
230
+
var templ_7745c5c3_Var10 templ.SafeURL
231
+
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinURLErrs(templ.URL("/" + repo.Name()))
232
+
if templ_7745c5c3_Err != nil {
233
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 79, Col: 205}
234
+
}
235
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
236
if templ_7745c5c3_Err != nil {
237
return templ_7745c5c3_Err
238
}
239
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\">")
240
if templ_7745c5c3_Err != nil {
241
return templ_7745c5c3_Err
242
}
243
var templ_7745c5c3_Var11 string
244
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(repo.Name())
245
if templ_7745c5c3_Err != nil {
246
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 79, Col: 221}
247
}
248
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
249
if templ_7745c5c3_Err != nil {
250
return templ_7745c5c3_Err
251
}
252
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</a></div><div class=\"sm:col-span-3 text-subtext0\">")
253
if templ_7745c5c3_Err != nil {
254
return templ_7745c5c3_Err
255
}
256
var templ_7745c5c3_Var12 string
257
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(repo.Meta.Description)
258
if templ_7745c5c3_Err != nil {
259
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 80, Col: 69}
260
}
261
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
262
if templ_7745c5c3_Err != nil {
263
return templ_7745c5c3_Err
264
}
265
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</div><div class=\"sm:col-span-3 text-subtext0\">")
266
if templ_7745c5c3_Err != nil {
267
return templ_7745c5c3_Err
268
}
269
+
if commit != nil {
270
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<div title=\"")
271
if templ_7745c5c3_Err != nil {
272
return templ_7745c5c3_Err
273
}
274
+
var templ_7745c5c3_Var13 string
275
+
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(commit.Message)
276
+
if templ_7745c5c3_Err != nil {
277
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 83, Col: 34}
278
+
}
279
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
280
if templ_7745c5c3_Err != nil {
281
return templ_7745c5c3_Err
282
}
283
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\"><a class=\"underline text-blue dark:text-lavender decoration-blue/50 dark:decoration-lavender/50 decoration-dashed hover:decoration-solid\" href=\"")
284
if templ_7745c5c3_Err != nil {
285
return templ_7745c5c3_Err
286
}
287
+
var templ_7745c5c3_Var14 templ.SafeURL
288
+
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinURLErrs(fmt.Sprintf("/%s/commit/%s", repo.Name(), commit.SHA))
289
if templ_7745c5c3_Err != nil {
290
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 84, Col: 206}
291
}
292
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
293
if templ_7745c5c3_Err != nil {
294
return templ_7745c5c3_Err
295
}
296
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "\">")
297
+
if templ_7745c5c3_Err != nil {
298
+
return templ_7745c5c3_Err
299
+
}
300
+
var templ_7745c5c3_Var15 string
301
+
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(commit.Short())
302
+
if templ_7745c5c3_Err != nil {
303
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 84, Col: 225}
304
+
}
305
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
306
+
if templ_7745c5c3_Err != nil {
307
+
return templ_7745c5c3_Err
308
+
}
309
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "</a> ")
310
+
if templ_7745c5c3_Err != nil {
311
+
return templ_7745c5c3_Err
312
+
}
313
+
var templ_7745c5c3_Var16 string
314
+
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(": " + commit.Summary())
315
+
if templ_7745c5c3_Err != nil {
316
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 85, Col: 33}
317
+
}
318
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
319
+
if templ_7745c5c3_Err != nil {
320
+
return templ_7745c5c3_Err
321
+
}
322
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "</div>")
323
if templ_7745c5c3_Err != nil {
324
return templ_7745c5c3_Err
325
}
326
}
327
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "</div><div class=\"sm:col-span-1 text-subtext0\">")
328
if templ_7745c5c3_Err != nil {
329
return templ_7745c5c3_Err
330
}
331
+
for _, tag := range repo.Meta.Tags.Slice() {
332
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<a href=\"")
333
+
if templ_7745c5c3_Err != nil {
334
+
return templ_7745c5c3_Err
335
+
}
336
+
var templ_7745c5c3_Var17 templ.SafeURL
337
+
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("?tag=" + tag))
338
+
if templ_7745c5c3_Err != nil {
339
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 91, Col: 45}
340
+
}
341
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
342
+
if templ_7745c5c3_Err != nil {
343
+
return templ_7745c5c3_Err
344
+
}
345
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "\" class=\"rounded border-rosewater border-solid border pb-0.5 px-1 mr-1 mb-1 inline-block\">")
346
+
if templ_7745c5c3_Err != nil {
347
+
return templ_7745c5c3_Err
348
+
}
349
+
var templ_7745c5c3_Var18 string
350
+
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(tag)
351
+
if templ_7745c5c3_Err != nil {
352
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 91, Col: 141}
353
+
}
354
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
355
+
if templ_7745c5c3_Err != nil {
356
+
return templ_7745c5c3_Err
357
+
}
358
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "</a>")
359
+
if templ_7745c5c3_Err != nil {
360
+
return templ_7745c5c3_Err
361
+
}
362
+
}
363
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "</div><div class=\"sm:col-span-1 text-text/80 mb-4 sm:mb-0\" title=\"")
364
if templ_7745c5c3_Err != nil {
365
+
return templ_7745c5c3_Err
366
+
}
367
+
var templ_7745c5c3_Var19 string
368
+
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(lastCommitTime(repo, false))
369
+
if templ_7745c5c3_Err != nil {
370
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 94, Col: 93}
371
}
372
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
373
if templ_7745c5c3_Err != nil {
374
return templ_7745c5c3_Err
375
}
376
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "\">")
377
if templ_7745c5c3_Err != nil {
378
return templ_7745c5c3_Err
379
}
380
+
var templ_7745c5c3_Var20 string
381
+
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(lastCommitTime(repo, true))
382
if templ_7745c5c3_Err != nil {
383
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `index.templ`, Line: 94, Col: 124}
384
}
385
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
386
if templ_7745c5c3_Err != nil {
387
return templ_7745c5c3_Err
388
}
389
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "</div>")
390
if templ_7745c5c3_Err != nil {
391
return templ_7745c5c3_Err
392
}
393
}
394
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "</div></main>")
395
if templ_7745c5c3_Err != nil {
396
return templ_7745c5c3_Err
397
}
398
+
return nil
399
})
400
templ_7745c5c3_Err = base(ic.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
401
if templ_7745c5c3_Err != nil {
402
return templ_7745c5c3_Err
403
}
404
+
return nil
405
})
406
}
407
+
408
+
var _ = templruntime.GeneratedTemplate
+16
-24
internal/html/markup/chroma.go
+16
-24
internal/html/markup/chroma.go
···
2
3
import (
4
"io"
5
6
"github.com/alecthomas/chroma/v2"
7
"github.com/alecthomas/chroma/v2/formatters/html"
···
9
"github.com/alecthomas/chroma/v2/styles"
10
)
11
12
-
var (
13
-
// Formatter is the default formatter
14
-
Formatter = html.New(
15
html.WithLineNumbers(true),
16
-
html.WithLinkableLineNumbers(true, "L"),
17
html.WithClasses(true),
18
html.LineNumbersInTable(true),
19
-
)
20
-
basicFormatter = html.New(
21
-
html.WithClasses(true),
22
-
)
23
-
// Code is the entrypoint for formatting
24
-
Code = code{}
25
-
)
26
-
27
-
type code struct{}
28
29
func setup(source []byte, fileName string) (chroma.Iterator, *chroma.Style, error) {
30
lexer := lexers.Match(fileName)
31
if lexer == nil {
32
lexer = lexers.Fallback
33
}
34
lexer = chroma.Coalesce(lexer)
35
···
46
return iter, style, nil
47
}
48
49
-
// Basic formats code without any extras
50
-
func (c code) Basic(source []byte, fileName string, writer io.Writer) error {
51
-
iter, style, err := setup(source, fileName)
52
-
if err != nil {
53
-
return err
54
-
}
55
-
return basicFormatter.Format(writer, style, iter)
56
-
}
57
-
58
// Convert formats code with line numbers, links, etc.
59
-
func (c code) Convert(source []byte, fileName string, writer io.Writer) error {
60
iter, style, err := setup(source, fileName)
61
if err != nil {
62
return err
63
}
64
-
return Formatter.Format(writer, style, iter)
65
}
66
67
// Snippet formats code with line numbers starting at a specific line
···
2
3
import (
4
"io"
5
+
"path/filepath"
6
7
"github.com/alecthomas/chroma/v2"
8
"github.com/alecthomas/chroma/v2/formatters/html"
···
10
"github.com/alecthomas/chroma/v2/styles"
11
)
12
13
+
var customReg = map[string]string{
14
+
".hujson": "json",
15
+
}
16
+
17
+
// Options are the default set of formatting options
18
+
func Options(linePrefix string) []html.Option {
19
+
return []html.Option{
20
html.WithLineNumbers(true),
21
+
html.WithLinkableLineNumbers(true, linePrefix),
22
html.WithClasses(true),
23
html.LineNumbersInTable(true),
24
+
}
25
+
}
26
27
func setup(source []byte, fileName string) (chroma.Iterator, *chroma.Style, error) {
28
lexer := lexers.Match(fileName)
29
if lexer == nil {
30
lexer = lexers.Fallback
31
+
if name, ok := customReg[filepath.Ext(fileName)]; ok {
32
+
lexer = lexers.Get(name)
33
+
}
34
}
35
lexer = chroma.Coalesce(lexer)
36
···
47
return iter, style, nil
48
}
49
50
// Convert formats code with line numbers, links, etc.
51
+
func Convert(source []byte, fileName, linePrefix string, writer io.Writer) error {
52
iter, style, err := setup(source, fileName)
53
if err != nil {
54
return err
55
}
56
+
return html.New(Options(linePrefix)...).Format(writer, style, iter)
57
}
58
59
// Snippet formats code with line numbers starting at a specific line
+1
internal/html/markup/markdown.go
+1
internal/html/markup/markdown.go
+4
-3
internal/html/readme.templ
+4
-3
internal/html/readme.templ
+19
-14
internal/html/readme_templ.go
+19
-14
internal/html/readme_templ.go
···
1
// Code generated by templ - DO NOT EDIT.
2
3
-
// templ: version: v0.2.707
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
-
import "context"
10
-
import "io"
11
-
import "bytes"
12
13
type ReadmeComponentContext struct {
14
Markdown string
15
}
16
17
func readmeComponent(rcc ReadmeComponentContext) templ.Component {
18
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
19
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
20
if !templ_7745c5c3_IsBuffer {
21
-
templ_7745c5c3_Buffer = templ.GetBuffer()
22
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
23
}
24
ctx = templ.InitializeContext(ctx)
25
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
28
}
29
ctx = templ.ClearChildren(ctx)
30
if rcc.Markdown != "" {
31
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"bg-base dark:bg-base/50 p-5 mt-5 rounded markdown\">")
32
if templ_7745c5c3_Err != nil {
33
return templ_7745c5c3_Err
34
}
···
36
if templ_7745c5c3_Err != nil {
37
return templ_7745c5c3_Err
38
}
39
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
40
if templ_7745c5c3_Err != nil {
41
return templ_7745c5c3_Err
42
}
43
}
44
-
if !templ_7745c5c3_IsBuffer {
45
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
46
-
}
47
-
return templ_7745c5c3_Err
48
})
49
}
···
1
// Code generated by templ - DO NOT EDIT.
2
3
+
// templ: version: v0.3.924
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
11
type ReadmeComponentContext struct {
12
Markdown string
13
}
14
15
func readmeComponent(rcc ReadmeComponentContext) templ.Component {
16
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
17
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
18
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
19
+
return templ_7745c5c3_CtxErr
20
+
}
21
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
22
if !templ_7745c5c3_IsBuffer {
23
+
defer func() {
24
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
25
+
if templ_7745c5c3_Err == nil {
26
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
27
+
}
28
+
}()
29
}
30
ctx = templ.InitializeContext(ctx)
31
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
34
}
35
ctx = templ.ClearChildren(ctx)
36
if rcc.Markdown != "" {
37
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"bg-base dark:bg-base/50 p-5 mt-5 rounded markdown\">")
38
if templ_7745c5c3_Err != nil {
39
return templ_7745c5c3_Err
40
}
···
42
if templ_7745c5c3_Err != nil {
43
return templ_7745c5c3_Err
44
}
45
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</div>")
46
if templ_7745c5c3_Err != nil {
47
return templ_7745c5c3_Err
48
}
49
}
50
+
return nil
51
})
52
}
53
+
54
+
var _ = templruntime.GeneratedTemplate
+16
-8
internal/html/repo_commit.templ
+16
-8
internal/html/repo_commit.templ
···
4
import "github.com/dustin/go-humanize"
5
import "go.jolheiser.com/ugit/internal/git"
6
7
-
type RepoCommitContext struct{
8
-
BaseContext
9
-
RepoHeaderComponentContext
10
-
Commit git.Commit
11
}
12
13
templ RepoCommit(rcc RepoCommitContext) {
···
25
<div>{ rcc.Commit.Author }{ " " }<a class="underline decoration-text/50 decoration-dashed hover:decoration-solid" href={ templ.SafeURL(fmt.Sprintf("mailto:%s", rcc.Commit.Email)) }>{ fmt.Sprintf("<%s>", rcc.Commit.Email) }</a></div>
26
<div title={ rcc.Commit.When.Format("01/02/2006 03:04:05 PM") }>{ humanize.Time(rcc.Commit.When) }</div>
27
</div>
28
-
<div class="text-text mt-5">{ fmt.Sprintf("%d changed files, %d additions(+), %d deletions(-)", rcc.Commit.Stats.Changed, rcc.Commit.Stats.Additions, rcc.Commit.Stats.Deletions) }</div>
29
for _, file := range rcc.Commit.Files {
30
-
<div class="text-text mt-5">
31
<span class="text-text/80" title={ file.Action }>{ string(file.Action[0]) }</span>
32
{ " " }
33
if file.From.Path != "" {
···
40
<a class="underline decoration-text/50 decoration-dashed hover:decoration-solid" href={ templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s", rcc.RepoHeaderComponentContext.Name, file.To.Commit, file.To.Path)) }>{ file.To.Path }</a>
41
}
42
</div>
43
-
<div class="whitespace-pre code">@templ.Raw(file.Patch)</div>
44
}
45
}
46
}
47
-
···
4
import "github.com/dustin/go-humanize"
5
import "go.jolheiser.com/ugit/internal/git"
6
7
+
type RepoCommitContext struct {
8
+
BaseContext
9
+
RepoHeaderComponentContext
10
+
Commit git.Commit
11
}
12
13
templ RepoCommit(rcc RepoCommitContext) {
···
25
<div>{ rcc.Commit.Author }{ " " }<a class="underline decoration-text/50 decoration-dashed hover:decoration-solid" href={ templ.SafeURL(fmt.Sprintf("mailto:%s", rcc.Commit.Email)) }>{ fmt.Sprintf("<%s>", rcc.Commit.Email) }</a></div>
26
<div title={ rcc.Commit.When.Format("01/02/2006 03:04:05 PM") }>{ humanize.Time(rcc.Commit.When) }</div>
27
</div>
28
+
<details class="text-text mt-5">
29
+
<summary class="cursor-pointer">{ fmt.Sprintf("%d changed files, %d additions(+), %d deletions(-)", rcc.Commit.Stats.Changed, rcc.Commit.Stats.Additions, rcc.Commit.Stats.Deletions) }</summary>
30
+
<div class="p-3 bg-base rounded">
31
+
for _, file := range rcc.Commit.Files {
32
+
<a class="block underline decoration-text/50 decoration-dashed hover:decoration-solid" href={ "#" + file.Path() }>{ file.Path() }</a>
33
+
}
34
+
</div>
35
+
</details>
36
for _, file := range rcc.Commit.Files {
37
+
<div class="text-text mt-5" id={ file.Path() }>
38
<span class="text-text/80" title={ file.Action }>{ string(file.Action[0]) }</span>
39
{ " " }
40
if file.From.Path != "" {
···
47
<a class="underline decoration-text/50 decoration-dashed hover:decoration-solid" href={ templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s", rcc.RepoHeaderComponentContext.Name, file.To.Commit, file.To.Path)) }>{ file.To.Path }</a>
48
}
49
</div>
50
+
<div class="code">
51
+
@templ.Raw(file.Patch)
52
+
</div>
53
}
54
}
55
}
+162
-81
internal/html/repo_commit_templ.go
+162
-81
internal/html/repo_commit_templ.go
···
1
// Code generated by templ - DO NOT EDIT.
2
3
-
// templ: version: v0.2.707
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
-
import "context"
10
-
import "io"
11
-
import "bytes"
12
13
import "fmt"
14
import "github.com/dustin/go-humanize"
···
21
}
22
23
func RepoCommit(rcc RepoCommitContext) templ.Component {
24
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
25
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
26
if !templ_7745c5c3_IsBuffer {
27
-
templ_7745c5c3_Buffer = templ.GetBuffer()
28
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
29
}
30
ctx = templ.InitializeContext(ctx)
31
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
33
templ_7745c5c3_Var1 = templ.NopComponent
34
}
35
ctx = templ.ClearChildren(ctx)
36
-
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
37
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
38
if !templ_7745c5c3_IsBuffer {
39
-
templ_7745c5c3_Buffer = templ.GetBuffer()
40
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
41
}
42
templ_7745c5c3_Err = repoHeaderComponent(rcc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
43
if templ_7745c5c3_Err != nil {
44
return templ_7745c5c3_Err
45
}
46
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"text-text mt-5\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
47
if templ_7745c5c3_Err != nil {
48
return templ_7745c5c3_Err
49
}
50
-
var templ_7745c5c3_Var3 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/tree/%s/", rcc.RepoHeaderComponentContext.Name, rcc.Commit.SHA))
51
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var3)))
52
if templ_7745c5c3_Err != nil {
53
return templ_7745c5c3_Err
54
}
55
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">tree</a>")
56
if templ_7745c5c3_Err != nil {
57
return templ_7745c5c3_Err
58
}
···
65
if templ_7745c5c3_Err != nil {
66
return templ_7745c5c3_Err
67
}
68
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
69
if templ_7745c5c3_Err != nil {
70
return templ_7745c5c3_Err
71
}
72
-
var templ_7745c5c3_Var5 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/log/%s", rcc.RepoHeaderComponentContext.Name, rcc.Commit.SHA))
73
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var5)))
74
if templ_7745c5c3_Err != nil {
75
return templ_7745c5c3_Err
76
}
77
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">log</a>")
78
if templ_7745c5c3_Err != nil {
79
return templ_7745c5c3_Err
80
}
···
87
if templ_7745c5c3_Err != nil {
88
return templ_7745c5c3_Err
89
}
90
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
91
if templ_7745c5c3_Err != nil {
92
return templ_7745c5c3_Err
93
}
94
-
var templ_7745c5c3_Var7 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/commit/%s.patch", rcc.RepoHeaderComponentContext.Name, rcc.Commit.SHA))
95
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var7)))
96
if templ_7745c5c3_Err != nil {
97
return templ_7745c5c3_Err
98
}
99
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">patch</a></div><div class=\"text-text whitespace-pre mt-5 p-3 bg-base rounded\">")
100
if templ_7745c5c3_Err != nil {
101
return templ_7745c5c3_Err
102
}
···
109
if templ_7745c5c3_Err != nil {
110
return templ_7745c5c3_Err
111
}
112
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
113
if templ_7745c5c3_Err != nil {
114
return templ_7745c5c3_Err
115
}
116
if rcc.Commit.Signature != "" {
117
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<details class=\"text-text whitespace-pre\"><summary class=\"cursor-pointer\">Signature</summary><div class=\"p-3 bg-base rounded\"><code>")
118
if templ_7745c5c3_Err != nil {
119
return templ_7745c5c3_Err
120
}
···
127
if templ_7745c5c3_Err != nil {
128
return templ_7745c5c3_Err
129
}
130
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</code></div></details>")
131
if templ_7745c5c3_Err != nil {
132
return templ_7745c5c3_Err
133
}
134
}
135
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"text-text mt-3\"><div>")
136
if templ_7745c5c3_Err != nil {
137
return templ_7745c5c3_Err
138
}
···
154
if templ_7745c5c3_Err != nil {
155
return templ_7745c5c3_Err
156
}
157
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
158
if templ_7745c5c3_Err != nil {
159
return templ_7745c5c3_Err
160
}
161
-
var templ_7745c5c3_Var12 templ.SafeURL = templ.SafeURL(fmt.Sprintf("mailto:%s", rcc.Commit.Email))
162
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var12)))
163
if templ_7745c5c3_Err != nil {
164
return templ_7745c5c3_Err
165
}
166
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
167
if templ_7745c5c3_Err != nil {
168
return templ_7745c5c3_Err
169
}
···
176
if templ_7745c5c3_Err != nil {
177
return templ_7745c5c3_Err
178
}
179
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div><div title=\"")
180
if templ_7745c5c3_Err != nil {
181
return templ_7745c5c3_Err
182
}
···
189
if templ_7745c5c3_Err != nil {
190
return templ_7745c5c3_Err
191
}
192
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
193
if templ_7745c5c3_Err != nil {
194
return templ_7745c5c3_Err
195
}
···
202
if templ_7745c5c3_Err != nil {
203
return templ_7745c5c3_Err
204
}
205
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div><div class=\"text-text mt-5\">")
206
if templ_7745c5c3_Err != nil {
207
return templ_7745c5c3_Err
208
}
209
var templ_7745c5c3_Var16 string
210
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d changed files, %d additions(+), %d deletions(-)", rcc.Commit.Stats.Changed, rcc.Commit.Stats.Additions, rcc.Commit.Stats.Deletions))
211
if templ_7745c5c3_Err != nil {
212
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 28, Col: 179}
213
}
214
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
215
if templ_7745c5c3_Err != nil {
216
return templ_7745c5c3_Err
217
}
218
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
219
if templ_7745c5c3_Err != nil {
220
return templ_7745c5c3_Err
221
}
222
for _, file := range rcc.Commit.Files {
223
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"text-text mt-5\"><span class=\"text-text/80\" title=\"")
224
if templ_7745c5c3_Err != nil {
225
return templ_7745c5c3_Err
226
}
227
-
var templ_7745c5c3_Var17 string
228
-
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(file.Action)
229
if templ_7745c5c3_Err != nil {
230
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 31, Col: 50}
231
}
232
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
233
if templ_7745c5c3_Err != nil {
234
return templ_7745c5c3_Err
235
}
236
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
237
if templ_7745c5c3_Err != nil {
238
return templ_7745c5c3_Err
239
}
240
var templ_7745c5c3_Var18 string
241
-
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(string(file.Action[0]))
242
if templ_7745c5c3_Err != nil {
243
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 31, Col: 77}
244
}
245
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
246
if templ_7745c5c3_Err != nil {
247
return templ_7745c5c3_Err
248
}
249
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span> ")
250
if templ_7745c5c3_Err != nil {
251
return templ_7745c5c3_Err
252
}
253
var templ_7745c5c3_Var19 string
254
-
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
255
if templ_7745c5c3_Err != nil {
256
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 32, Col: 9}
257
}
258
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
259
if templ_7745c5c3_Err != nil {
260
return templ_7745c5c3_Err
261
}
262
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
263
if templ_7745c5c3_Err != nil {
264
return templ_7745c5c3_Err
265
}
266
if file.From.Path != "" {
267
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
268
if templ_7745c5c3_Err != nil {
269
return templ_7745c5c3_Err
270
}
271
-
var templ_7745c5c3_Var20 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s", rcc.RepoHeaderComponentContext.Name, file.From.Commit, file.From.Path))
272
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var20)))
273
if templ_7745c5c3_Err != nil {
274
return templ_7745c5c3_Err
275
}
276
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
277
if templ_7745c5c3_Err != nil {
278
return templ_7745c5c3_Err
279
}
280
-
var templ_7745c5c3_Var21 string
281
-
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(file.From.Path)
282
if templ_7745c5c3_Err != nil {
283
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 34, Col: 227}
284
}
285
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
286
if templ_7745c5c3_Err != nil {
287
return templ_7745c5c3_Err
288
}
289
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a> ")
290
if templ_7745c5c3_Err != nil {
291
return templ_7745c5c3_Err
292
}
293
}
294
if file.From.Path != "" && file.To.Path != "" {
295
-
var templ_7745c5c3_Var22 string
296
-
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(" -> ")
297
if templ_7745c5c3_Err != nil {
298
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 37, Col: 13}
299
}
300
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
301
if templ_7745c5c3_Err != nil {
302
return templ_7745c5c3_Err
303
}
304
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
305
if templ_7745c5c3_Err != nil {
306
return templ_7745c5c3_Err
307
}
308
}
309
if file.To.Path != "" {
310
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
311
if templ_7745c5c3_Err != nil {
312
return templ_7745c5c3_Err
313
}
314
-
var templ_7745c5c3_Var23 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s", rcc.RepoHeaderComponentContext.Name, file.To.Commit, file.To.Path))
315
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var23)))
316
if templ_7745c5c3_Err != nil {
317
return templ_7745c5c3_Err
318
}
319
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
320
if templ_7745c5c3_Err != nil {
321
return templ_7745c5c3_Err
322
}
323
-
var templ_7745c5c3_Var24 string
324
-
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(file.To.Path)
325
if templ_7745c5c3_Err != nil {
326
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 40, Col: 221}
327
}
328
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
329
if templ_7745c5c3_Err != nil {
330
return templ_7745c5c3_Err
331
}
332
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a>")
333
if templ_7745c5c3_Err != nil {
334
return templ_7745c5c3_Err
335
}
336
}
337
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"whitespace-pre code\">")
338
if templ_7745c5c3_Err != nil {
339
return templ_7745c5c3_Err
340
}
···
342
if templ_7745c5c3_Err != nil {
343
return templ_7745c5c3_Err
344
}
345
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
346
if templ_7745c5c3_Err != nil {
347
return templ_7745c5c3_Err
348
}
349
}
350
-
if !templ_7745c5c3_IsBuffer {
351
-
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
352
-
}
353
-
return templ_7745c5c3_Err
354
})
355
templ_7745c5c3_Err = base(rcc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
356
if templ_7745c5c3_Err != nil {
357
return templ_7745c5c3_Err
358
}
359
-
if !templ_7745c5c3_IsBuffer {
360
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
361
-
}
362
-
return templ_7745c5c3_Err
363
})
364
}
···
1
// Code generated by templ - DO NOT EDIT.
2
3
+
// templ: version: v0.3.924
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
11
import "fmt"
12
import "github.com/dustin/go-humanize"
···
19
}
20
21
func RepoCommit(rcc RepoCommitContext) templ.Component {
22
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
23
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
24
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
25
+
return templ_7745c5c3_CtxErr
26
+
}
27
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
28
if !templ_7745c5c3_IsBuffer {
29
+
defer func() {
30
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
31
+
if templ_7745c5c3_Err == nil {
32
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
33
+
}
34
+
}()
35
}
36
ctx = templ.InitializeContext(ctx)
37
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
39
templ_7745c5c3_Var1 = templ.NopComponent
40
}
41
ctx = templ.ClearChildren(ctx)
42
+
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
43
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
44
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
45
if !templ_7745c5c3_IsBuffer {
46
+
defer func() {
47
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
48
+
if templ_7745c5c3_Err == nil {
49
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
50
+
}
51
+
}()
52
}
53
+
ctx = templ.InitializeContext(ctx)
54
templ_7745c5c3_Err = repoHeaderComponent(rcc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
55
if templ_7745c5c3_Err != nil {
56
return templ_7745c5c3_Err
57
}
58
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, " <div class=\"text-text mt-5\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
59
if templ_7745c5c3_Err != nil {
60
return templ_7745c5c3_Err
61
}
62
+
var templ_7745c5c3_Var3 templ.SafeURL
63
+
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/tree/%s/", rcc.RepoHeaderComponentContext.Name, rcc.Commit.SHA)))
64
+
if templ_7745c5c3_Err != nil {
65
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 16, Col: 213}
66
+
}
67
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
68
if templ_7745c5c3_Err != nil {
69
return templ_7745c5c3_Err
70
}
71
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">tree</a>")
72
if templ_7745c5c3_Err != nil {
73
return templ_7745c5c3_Err
74
}
···
81
if templ_7745c5c3_Err != nil {
82
return templ_7745c5c3_Err
83
}
84
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
85
if templ_7745c5c3_Err != nil {
86
return templ_7745c5c3_Err
87
}
88
+
var templ_7745c5c3_Var5 templ.SafeURL
89
+
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/log/%s", rcc.RepoHeaderComponentContext.Name, rcc.Commit.SHA)))
90
+
if templ_7745c5c3_Err != nil {
91
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 16, Col: 412}
92
+
}
93
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
94
if templ_7745c5c3_Err != nil {
95
return templ_7745c5c3_Err
96
}
97
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\">log</a>")
98
if templ_7745c5c3_Err != nil {
99
return templ_7745c5c3_Err
100
}
···
107
if templ_7745c5c3_Err != nil {
108
return templ_7745c5c3_Err
109
}
110
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
111
if templ_7745c5c3_Err != nil {
112
return templ_7745c5c3_Err
113
}
114
+
var templ_7745c5c3_Var7 templ.SafeURL
115
+
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/commit/%s.patch", rcc.RepoHeaderComponentContext.Name, rcc.Commit.SHA)))
116
+
if templ_7745c5c3_Err != nil {
117
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 16, Col: 619}
118
+
}
119
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
120
if templ_7745c5c3_Err != nil {
121
return templ_7745c5c3_Err
122
}
123
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\">patch</a></div><div class=\"text-text whitespace-pre mt-5 p-3 bg-base rounded\">")
124
if templ_7745c5c3_Err != nil {
125
return templ_7745c5c3_Err
126
}
···
133
if templ_7745c5c3_Err != nil {
134
return templ_7745c5c3_Err
135
}
136
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div>")
137
if templ_7745c5c3_Err != nil {
138
return templ_7745c5c3_Err
139
}
140
if rcc.Commit.Signature != "" {
141
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<details class=\"text-text whitespace-pre\"><summary class=\"cursor-pointer\">Signature</summary><div class=\"p-3 bg-base rounded\"><code>")
142
if templ_7745c5c3_Err != nil {
143
return templ_7745c5c3_Err
144
}
···
151
if templ_7745c5c3_Err != nil {
152
return templ_7745c5c3_Err
153
}
154
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</code></div></details>")
155
if templ_7745c5c3_Err != nil {
156
return templ_7745c5c3_Err
157
}
158
}
159
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " <div class=\"text-text mt-3\"><div>")
160
if templ_7745c5c3_Err != nil {
161
return templ_7745c5c3_Err
162
}
···
178
if templ_7745c5c3_Err != nil {
179
return templ_7745c5c3_Err
180
}
181
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
182
if templ_7745c5c3_Err != nil {
183
return templ_7745c5c3_Err
184
}
185
+
var templ_7745c5c3_Var12 templ.SafeURL
186
+
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("mailto:%s", rcc.Commit.Email)))
187
+
if templ_7745c5c3_Err != nil {
188
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 25, Col: 181}
189
+
}
190
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
191
if templ_7745c5c3_Err != nil {
192
return templ_7745c5c3_Err
193
}
194
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\">")
195
if templ_7745c5c3_Err != nil {
196
return templ_7745c5c3_Err
197
}
···
204
if templ_7745c5c3_Err != nil {
205
return templ_7745c5c3_Err
206
}
207
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</a></div><div title=\"")
208
if templ_7745c5c3_Err != nil {
209
return templ_7745c5c3_Err
210
}
···
217
if templ_7745c5c3_Err != nil {
218
return templ_7745c5c3_Err
219
}
220
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\">")
221
if templ_7745c5c3_Err != nil {
222
return templ_7745c5c3_Err
223
}
···
230
if templ_7745c5c3_Err != nil {
231
return templ_7745c5c3_Err
232
}
233
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</div></div><details class=\"text-text mt-5\"><summary class=\"cursor-pointer\">")
234
if templ_7745c5c3_Err != nil {
235
return templ_7745c5c3_Err
236
}
237
var templ_7745c5c3_Var16 string
238
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d changed files, %d additions(+), %d deletions(-)", rcc.Commit.Stats.Changed, rcc.Commit.Stats.Additions, rcc.Commit.Stats.Deletions))
239
if templ_7745c5c3_Err != nil {
240
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 29, Col: 184}
241
}
242
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
243
if templ_7745c5c3_Err != nil {
244
return templ_7745c5c3_Err
245
}
246
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</summary><div class=\"p-3 bg-base rounded\">")
247
if templ_7745c5c3_Err != nil {
248
return templ_7745c5c3_Err
249
}
250
for _, file := range rcc.Commit.Files {
251
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<a class=\"block underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
252
if templ_7745c5c3_Err != nil {
253
return templ_7745c5c3_Err
254
}
255
+
var templ_7745c5c3_Var17 templ.SafeURL
256
+
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinURLErrs("#" + file.Path())
257
if templ_7745c5c3_Err != nil {
258
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 32, Col: 116}
259
}
260
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
261
if templ_7745c5c3_Err != nil {
262
return templ_7745c5c3_Err
263
}
264
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "\">")
265
if templ_7745c5c3_Err != nil {
266
return templ_7745c5c3_Err
267
}
268
var templ_7745c5c3_Var18 string
269
+
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(file.Path())
270
if templ_7745c5c3_Err != nil {
271
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 32, Col: 132}
272
}
273
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
274
if templ_7745c5c3_Err != nil {
275
return templ_7745c5c3_Err
276
}
277
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</a>")
278
+
if templ_7745c5c3_Err != nil {
279
+
return templ_7745c5c3_Err
280
+
}
281
+
}
282
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</div></details> ")
283
+
if templ_7745c5c3_Err != nil {
284
+
return templ_7745c5c3_Err
285
+
}
286
+
for _, file := range rcc.Commit.Files {
287
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "<div class=\"text-text mt-5\" id=\"")
288
if templ_7745c5c3_Err != nil {
289
return templ_7745c5c3_Err
290
}
291
var templ_7745c5c3_Var19 string
292
+
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(file.Path())
293
if templ_7745c5c3_Err != nil {
294
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 37, Col: 47}
295
}
296
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
297
if templ_7745c5c3_Err != nil {
298
return templ_7745c5c3_Err
299
}
300
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "\"><span class=\"text-text/80\" title=\"")
301
+
if templ_7745c5c3_Err != nil {
302
+
return templ_7745c5c3_Err
303
+
}
304
+
var templ_7745c5c3_Var20 string
305
+
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(file.Action)
306
+
if templ_7745c5c3_Err != nil {
307
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 38, Col: 50}
308
+
}
309
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
310
+
if templ_7745c5c3_Err != nil {
311
+
return templ_7745c5c3_Err
312
+
}
313
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "\">")
314
+
if templ_7745c5c3_Err != nil {
315
+
return templ_7745c5c3_Err
316
+
}
317
+
var templ_7745c5c3_Var21 string
318
+
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(string(file.Action[0]))
319
+
if templ_7745c5c3_Err != nil {
320
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 38, Col: 77}
321
+
}
322
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
323
+
if templ_7745c5c3_Err != nil {
324
+
return templ_7745c5c3_Err
325
+
}
326
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "</span> ")
327
+
if templ_7745c5c3_Err != nil {
328
+
return templ_7745c5c3_Err
329
+
}
330
+
var templ_7745c5c3_Var22 string
331
+
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(" ")
332
+
if templ_7745c5c3_Err != nil {
333
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 39, Col: 9}
334
+
}
335
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
336
+
if templ_7745c5c3_Err != nil {
337
+
return templ_7745c5c3_Err
338
+
}
339
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " ")
340
if templ_7745c5c3_Err != nil {
341
return templ_7745c5c3_Err
342
}
343
if file.From.Path != "" {
344
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
345
if templ_7745c5c3_Err != nil {
346
return templ_7745c5c3_Err
347
}
348
+
var templ_7745c5c3_Var23 templ.SafeURL
349
+
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s", rcc.RepoHeaderComponentContext.Name, file.From.Commit, file.From.Path)))
350
+
if templ_7745c5c3_Err != nil {
351
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 41, Col: 208}
352
+
}
353
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
354
if templ_7745c5c3_Err != nil {
355
return templ_7745c5c3_Err
356
}
357
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "\">")
358
if templ_7745c5c3_Err != nil {
359
return templ_7745c5c3_Err
360
}
361
+
var templ_7745c5c3_Var24 string
362
+
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(file.From.Path)
363
if templ_7745c5c3_Err != nil {
364
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 41, Col: 227}
365
}
366
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
367
if templ_7745c5c3_Err != nil {
368
return templ_7745c5c3_Err
369
}
370
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "</a> ")
371
if templ_7745c5c3_Err != nil {
372
return templ_7745c5c3_Err
373
}
374
}
375
if file.From.Path != "" && file.To.Path != "" {
376
+
var templ_7745c5c3_Var25 string
377
+
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(" -> ")
378
if templ_7745c5c3_Err != nil {
379
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 44, Col: 13}
380
}
381
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
382
if templ_7745c5c3_Err != nil {
383
return templ_7745c5c3_Err
384
}
385
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, " ")
386
if templ_7745c5c3_Err != nil {
387
return templ_7745c5c3_Err
388
}
389
}
390
if file.To.Path != "" {
391
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
392
if templ_7745c5c3_Err != nil {
393
return templ_7745c5c3_Err
394
}
395
+
var templ_7745c5c3_Var26 templ.SafeURL
396
+
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s", rcc.RepoHeaderComponentContext.Name, file.To.Commit, file.To.Path)))
397
+
if templ_7745c5c3_Err != nil {
398
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 47, Col: 204}
399
+
}
400
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
401
if templ_7745c5c3_Err != nil {
402
return templ_7745c5c3_Err
403
}
404
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "\">")
405
if templ_7745c5c3_Err != nil {
406
return templ_7745c5c3_Err
407
}
408
+
var templ_7745c5c3_Var27 string
409
+
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(file.To.Path)
410
if templ_7745c5c3_Err != nil {
411
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_commit.templ`, Line: 47, Col: 221}
412
}
413
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
414
if templ_7745c5c3_Err != nil {
415
return templ_7745c5c3_Err
416
}
417
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "</a>")
418
if templ_7745c5c3_Err != nil {
419
return templ_7745c5c3_Err
420
}
421
}
422
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "</div><div class=\"code\">")
423
if templ_7745c5c3_Err != nil {
424
return templ_7745c5c3_Err
425
}
···
427
if templ_7745c5c3_Err != nil {
428
return templ_7745c5c3_Err
429
}
430
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "</div>")
431
if templ_7745c5c3_Err != nil {
432
return templ_7745c5c3_Err
433
}
434
}
435
+
return nil
436
})
437
templ_7745c5c3_Err = base(rcc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
438
if templ_7745c5c3_Err != nil {
439
return templ_7745c5c3_Err
440
}
441
+
return nil
442
})
443
}
444
+
445
+
var _ = templruntime.GeneratedTemplate
+42
-5
internal/html/repo_file.templ
+42
-5
internal/html/repo_file.templ
···
1
package html
2
3
type RepoFileContext struct {
4
BaseContext
5
RepoHeaderComponentContext
6
RepoBreadcrumbComponentContext
7
-
Code string
8
}
9
10
templ RepoFile(rfc RepoFileContext) {
···
14
@repoBreadcrumbComponent(rfc.RepoBreadcrumbComponentContext)
15
{ " - " }
16
<a class="text-text underline decoration-text/50 decoration-dashed hover:decoration-solid" href="?raw">raw</a>
17
-
<div class="code">
18
@templ.Raw(rfc.Code)
19
</div>
20
</div>
21
}
···
23
const lineRe = /#L(\d+)(?:-L(\d+))?/g
24
const $lineLines = document.querySelectorAll(".chroma .lntable .lnt");
25
const $codeLines = document.querySelectorAll(".chroma .lntable .line");
26
let start = 0;
27
let end = 0;
28
···
31
start = results[0][1] !== undefined ? parseInt(results[0][1]) : 0;
32
end = results[0][2] !== undefined ? parseInt(results[0][2]) : 0;
33
}
34
-
if (start != 0) {
35
deactivateLines();
36
activateLines(start, end);
37
}
38
39
for (let line of $lineLines) {
···
45
if (event.shiftKey) {
46
end = n;
47
anchor = `#L${start}-L${end}`;
48
} else {
49
start = n;
50
end = 0;
51
anchor = `#L${start}`;
52
}
53
-
history.replaceState(null, null, anchor);
54
-
activateLines(start, end);
55
});
56
}
57
58
function activateLines(start, end) {
59
if (end < start) end = start;
···
1
package html
2
3
+
import "fmt"
4
+
5
type RepoFileContext struct {
6
BaseContext
7
RepoHeaderComponentContext
8
RepoBreadcrumbComponentContext
9
+
Code string
10
+
Commit string
11
+
Path string
12
+
}
13
+
14
+
func (rfc RepoFileContext) Permalink() string {
15
+
return fmt.Sprintf("/%s/tree/%s/%s", rfc.RepoBreadcrumbComponentContext.Repo, rfc.Commit, rfc.Path)
16
}
17
18
templ RepoFile(rfc RepoFileContext) {
···
22
@repoBreadcrumbComponent(rfc.RepoBreadcrumbComponentContext)
23
{ " - " }
24
<a class="text-text underline decoration-text/50 decoration-dashed hover:decoration-solid" href="?raw">raw</a>
25
+
{ " - " }
26
+
<a class="text-text underline decoration-text/50 decoration-dashed hover:decoration-solid" id="permalink" data-permalink={ rfc.Permalink() } href={ rfc.Permalink() }>permalink</a>
27
+
<div class="code relative">
28
@templ.Raw(rfc.Code)
29
+
<button id="copy" class="absolute top-0 right-0 rounded bg-base hover:bg-surface0"></button>
30
</div>
31
</div>
32
}
···
34
const lineRe = /#L(\d+)(?:-L(\d+))?/g
35
const $lineLines = document.querySelectorAll(".chroma .lntable .lnt");
36
const $codeLines = document.querySelectorAll(".chroma .lntable .line");
37
+
const $copyButton = document.getElementById('copy');
38
+
const $permalink = document.getElementById('permalink');
39
+
const $copyIcon = "๐";
40
+
const $copiedIcon = "โ
";
41
+
let $code = ""
42
+
for (let codeLine of $codeLines) $code += codeLine.innerText;
43
let start = 0;
44
let end = 0;
45
···
48
start = results[0][1] !== undefined ? parseInt(results[0][1]) : 0;
49
end = results[0][2] !== undefined ? parseInt(results[0][2]) : 0;
50
}
51
+
if (start !== 0) {
52
deactivateLines();
53
activateLines(start, end);
54
+
let anchor = `#${start}`;
55
+
if (end !== 0) anchor += `-${end}`;
56
+
if (anchor !== "") $permalink.href = $permalink.dataset.permalink + anchor;
57
+
$lineLines[start-1].scrollIntoView(true);
58
}
59
60
for (let line of $lineLines) {
···
66
if (event.shiftKey) {
67
end = n;
68
anchor = `#L${start}-L${end}`;
69
+
} else if (start === n) {
70
+
start = 0;
71
+
end = 0;
72
} else {
73
start = n;
74
end = 0;
75
anchor = `#L${start}`;
76
}
77
+
history.replaceState(null, null, window.location.pathname + anchor);
78
+
$permalink.href = $permalink.dataset.permalink + anchor;
79
+
if (start !== 0) activateLines(start, end);
80
});
81
}
82
+
83
+
if (navigator.clipboard && navigator.clipboard.writeText) {
84
+
$copyButton.innerText = $copyIcon;
85
+
$copyButton.classList.remove("hidden");
86
+
}
87
+
$copyButton.addEventListener("click", () => {
88
+
navigator.clipboard.writeText($code);
89
+
$copyButton.innerText = $copiedIcon;
90
+
setTimeout(() => {
91
+
$copyButton.innerText = $copyIcon;
92
+
}, 1000);
93
+
});
94
95
function activateLines(start, end) {
96
if (end < start) end = start;
+81
-26
internal/html/repo_file_templ.go
+81
-26
internal/html/repo_file_templ.go
···
1
// Code generated by templ - DO NOT EDIT.
2
3
-
// templ: version: v0.2.707
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
-
import "context"
10
-
import "io"
11
-
import "bytes"
12
13
type RepoFileContext struct {
14
BaseContext
15
RepoHeaderComponentContext
16
RepoBreadcrumbComponentContext
17
-
Code string
18
}
19
20
func RepoFile(rfc RepoFileContext) templ.Component {
21
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
22
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
23
if !templ_7745c5c3_IsBuffer {
24
-
templ_7745c5c3_Buffer = templ.GetBuffer()
25
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
26
}
27
ctx = templ.InitializeContext(ctx)
28
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
30
templ_7745c5c3_Var1 = templ.NopComponent
31
}
32
ctx = templ.ClearChildren(ctx)
33
-
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
34
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
35
if !templ_7745c5c3_IsBuffer {
36
-
templ_7745c5c3_Buffer = templ.GetBuffer()
37
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
38
}
39
templ_7745c5c3_Err = repoHeaderComponent(rfc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
40
if templ_7745c5c3_Err != nil {
41
return templ_7745c5c3_Err
42
}
43
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"mt-2 text-text\">")
44
if templ_7745c5c3_Err != nil {
45
return templ_7745c5c3_Err
46
}
···
51
var templ_7745c5c3_Var3 string
52
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(" - ")
53
if templ_7745c5c3_Err != nil {
54
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_file.templ`, Line: 15, Col: 10}
55
}
56
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
57
if templ_7745c5c3_Err != nil {
58
return templ_7745c5c3_Err
59
}
60
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <a class=\"text-text underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"?raw\">raw</a><div class=\"code\">")
61
if templ_7745c5c3_Err != nil {
62
return templ_7745c5c3_Err
63
}
64
-
templ_7745c5c3_Err = templ.Raw(rfc.Code).Render(ctx, templ_7745c5c3_Buffer)
65
if templ_7745c5c3_Err != nil {
66
return templ_7745c5c3_Err
67
}
68
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
69
if templ_7745c5c3_Err != nil {
70
return templ_7745c5c3_Err
71
}
72
-
if !templ_7745c5c3_IsBuffer {
73
-
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
74
}
75
-
return templ_7745c5c3_Err
76
})
77
templ_7745c5c3_Err = base(rfc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
78
if templ_7745c5c3_Err != nil {
79
return templ_7745c5c3_Err
80
}
81
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script>\n\t\tconst lineRe = /#L(\\d+)(?:-L(\\d+))?/g\n\t\tconst $lineLines = document.querySelectorAll(\".chroma .lntable .lnt\");\n\t\tconst $codeLines = document.querySelectorAll(\".chroma .lntable .line\");\n\t\tlet start = 0;\n\t\tlet end = 0;\n\n\t\tconst results = [...location.hash.matchAll(lineRe)];\t\t\n\t\tif (0 in results) {\n\t\t\tstart = results[0][1] !== undefined ? parseInt(results[0][1]) : 0;\n\t\t\tend = results[0][2] !== undefined ? parseInt(results[0][2]) : 0;\n\t\t}\n\t\tif (start != 0) {\n\t\t\tdeactivateLines();\n\t\t\tactivateLines(start, end);\n\t\t}\n\n\t\tfor (let line of $lineLines) {\n\t\t\tline.addEventListener(\"click\", (event) => {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tdeactivateLines();\n\t\t\t\tconst n = parseInt(line.id.substring(1));\n\t\t\t\tlet anchor = \"\";\n\t\t\t\tif (event.shiftKey) {\n\t\t\t\t\tend = n;\n\t\t\t\t\tanchor = `#L${start}-L${end}`;\n\t\t\t\t} else {\n\t\t\t\t\tstart = n;\n\t\t\t\t\tend = 0;\n\t\t\t\t\tanchor = `#L${start}`;\n\t\t\t\t}\n\t\t\t\thistory.replaceState(null, null, anchor);\n\t\t\t\tactivateLines(start, end);\n\t\t\t});\n\t\t}\n\n\t\tfunction activateLines(start, end) {\n\t\t\tif (end < start) end = start;\n\t\t\tfor (let idx = start - 1; idx < end; idx++) {\n\t\t\t\t$codeLines[idx].classList.add(\"active\");\n\t\t\t}\n\t\t}\n\n\t\tfunction deactivateLines() {\n\t\t\tfor (let code of $codeLines) {\n\t\t\t\tcode.classList.remove(\"active\");\n\t\t\t}\n\t\t}\n\n\t\t\n\t\t\n\t</script>")
82
if templ_7745c5c3_Err != nil {
83
return templ_7745c5c3_Err
84
}
85
-
if !templ_7745c5c3_IsBuffer {
86
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
87
-
}
88
-
return templ_7745c5c3_Err
89
})
90
}
···
1
// Code generated by templ - DO NOT EDIT.
2
3
+
// templ: version: v0.3.924
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
+
11
+
import "fmt"
12
13
type RepoFileContext struct {
14
BaseContext
15
RepoHeaderComponentContext
16
RepoBreadcrumbComponentContext
17
+
Code string
18
+
Commit string
19
+
Path string
20
+
}
21
+
22
+
func (rfc RepoFileContext) Permalink() string {
23
+
return fmt.Sprintf("/%s/tree/%s/%s", rfc.RepoBreadcrumbComponentContext.Repo, rfc.Commit, rfc.Path)
24
}
25
26
func RepoFile(rfc RepoFileContext) templ.Component {
27
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
28
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
29
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
30
+
return templ_7745c5c3_CtxErr
31
+
}
32
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
33
if !templ_7745c5c3_IsBuffer {
34
+
defer func() {
35
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
36
+
if templ_7745c5c3_Err == nil {
37
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
38
+
}
39
+
}()
40
}
41
ctx = templ.InitializeContext(ctx)
42
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
44
templ_7745c5c3_Var1 = templ.NopComponent
45
}
46
ctx = templ.ClearChildren(ctx)
47
+
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
48
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
49
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
50
if !templ_7745c5c3_IsBuffer {
51
+
defer func() {
52
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
53
+
if templ_7745c5c3_Err == nil {
54
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
55
+
}
56
+
}()
57
}
58
+
ctx = templ.InitializeContext(ctx)
59
templ_7745c5c3_Err = repoHeaderComponent(rfc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
60
if templ_7745c5c3_Err != nil {
61
return templ_7745c5c3_Err
62
}
63
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, " <div class=\"mt-2 text-text\">")
64
if templ_7745c5c3_Err != nil {
65
return templ_7745c5c3_Err
66
}
···
71
var templ_7745c5c3_Var3 string
72
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(" - ")
73
if templ_7745c5c3_Err != nil {
74
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_file.templ`, Line: 23, Col: 10}
75
}
76
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
77
if templ_7745c5c3_Err != nil {
78
return templ_7745c5c3_Err
79
}
80
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " <a class=\"text-text underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"?raw\">raw</a> ")
81
+
if templ_7745c5c3_Err != nil {
82
+
return templ_7745c5c3_Err
83
+
}
84
+
var templ_7745c5c3_Var4 string
85
+
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(" - ")
86
+
if templ_7745c5c3_Err != nil {
87
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_file.templ`, Line: 25, Col: 10}
88
+
}
89
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
90
+
if templ_7745c5c3_Err != nil {
91
+
return templ_7745c5c3_Err
92
+
}
93
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " <a class=\"text-text underline decoration-text/50 decoration-dashed hover:decoration-solid\" id=\"permalink\" data-permalink=\"")
94
+
if templ_7745c5c3_Err != nil {
95
+
return templ_7745c5c3_Err
96
+
}
97
+
var templ_7745c5c3_Var5 string
98
+
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(rfc.Permalink())
99
+
if templ_7745c5c3_Err != nil {
100
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_file.templ`, Line: 26, Col: 141}
101
+
}
102
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
103
+
if templ_7745c5c3_Err != nil {
104
+
return templ_7745c5c3_Err
105
+
}
106
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\" href=\"")
107
+
if templ_7745c5c3_Err != nil {
108
+
return templ_7745c5c3_Err
109
+
}
110
+
var templ_7745c5c3_Var6 templ.SafeURL
111
+
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinURLErrs(rfc.Permalink())
112
+
if templ_7745c5c3_Err != nil {
113
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_file.templ`, Line: 26, Col: 166}
114
+
}
115
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
116
if templ_7745c5c3_Err != nil {
117
return templ_7745c5c3_Err
118
}
119
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\">permalink</a><div class=\"code relative\">")
120
if templ_7745c5c3_Err != nil {
121
return templ_7745c5c3_Err
122
}
123
+
templ_7745c5c3_Err = templ.Raw(rfc.Code).Render(ctx, templ_7745c5c3_Buffer)
124
if templ_7745c5c3_Err != nil {
125
return templ_7745c5c3_Err
126
}
127
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<button id=\"copy\" class=\"absolute top-0 right-0 rounded bg-base hover:bg-surface0\"></button></div></div>")
128
+
if templ_7745c5c3_Err != nil {
129
+
return templ_7745c5c3_Err
130
}
131
+
return nil
132
})
133
templ_7745c5c3_Err = base(rfc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
134
if templ_7745c5c3_Err != nil {
135
return templ_7745c5c3_Err
136
}
137
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<script>\n\t\tconst lineRe = /#L(\\d+)(?:-L(\\d+))?/g\n\t\tconst $lineLines = document.querySelectorAll(\".chroma .lntable .lnt\");\n\t\tconst $codeLines = document.querySelectorAll(\".chroma .lntable .line\");\n\t\tconst $copyButton = document.getElementById('copy');\n\t\tconst $permalink = document.getElementById('permalink');\n\t\tconst $copyIcon = \"๐\";\n\t\tconst $copiedIcon = \"โ
\";\n\t\tlet $code = \"\"\n\t\tfor (let codeLine of $codeLines) $code += codeLine.innerText;\n\t\tlet start = 0;\n\t\tlet end = 0;\n\n\t\tconst results = [...location.hash.matchAll(lineRe)];\t\t\n\t\tif (0 in results) {\n\t\t\tstart = results[0][1] !== undefined ? parseInt(results[0][1]) : 0;\n\t\t\tend = results[0][2] !== undefined ? parseInt(results[0][2]) : 0;\n\t\t}\n\t\tif (start !== 0) {\n\t\t\tdeactivateLines();\n\t\t\tactivateLines(start, end);\n\t\t\tlet anchor = `#${start}`;\n if (end !== 0) anchor += `-${end}`;\n if (anchor !== \"\") $permalink.href = $permalink.dataset.permalink + anchor;\n\t\t\t$lineLines[start-1].scrollIntoView(true);\n\t\t}\n\n\t\tfor (let line of $lineLines) {\n\t\t\tline.addEventListener(\"click\", (event) => {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tdeactivateLines();\n\t\t\t\tconst n = parseInt(line.id.substring(1));\n\t\t\t\tlet anchor = \"\";\n\t\t\t\tif (event.shiftKey) {\n\t\t\t\t\tend = n;\n\t\t\t\t\tanchor = `#L${start}-L${end}`;\n\t\t\t\t} else if (start === n) {\n\t\t\t\t\tstart = 0;\n\t\t\t\t\tend = 0;\n\t\t\t\t} else {\n\t\t\t\t\tstart = n;\n\t\t\t\t\tend = 0;\n\t\t\t\t\tanchor = `#L${start}`;\n\t\t\t\t}\n\t\t\t\thistory.replaceState(null, null, window.location.pathname + anchor);\n\t\t\t\t$permalink.href = $permalink.dataset.permalink + anchor;\n\t\t\t\tif (start !== 0) activateLines(start, end);\n\t\t\t});\n\t\t}\n\n\t\tif (navigator.clipboard && navigator.clipboard.writeText) {\n\t\t\t$copyButton.innerText = $copyIcon;\n\t\t\t$copyButton.classList.remove(\"hidden\");\n }\n\t\t$copyButton.addEventListener(\"click\", () => {\n navigator.clipboard.writeText($code);\n\t\t\t$copyButton.innerText = $copiedIcon;\n\t\t\tsetTimeout(() => {\n\t\t\t\t$copyButton.innerText = $copyIcon;\n\t\t\t}, 1000);\n });\n\n\t\tfunction activateLines(start, end) {\n\t\t\tif (end < start) end = start;\n\t\t\tfor (let idx = start - 1; idx < end; idx++) {\n\t\t\t\t$codeLines[idx].classList.add(\"active\");\n\t\t\t}\n\t\t}\n\n\t\tfunction deactivateLines() {\n\t\t\tfor (let code of $codeLines) {\n\t\t\t\tcode.classList.remove(\"active\");\n\t\t\t}\n\t\t}\n\n\t\t\n\t\t\n\t</script>")
138
if templ_7745c5c3_Err != nil {
139
return templ_7745c5c3_Err
140
}
141
+
return nil
142
})
143
}
144
+
145
+
var _ = templruntime.GeneratedTemplate
+3
-4
internal/html/repo_log.templ
+3
-4
internal/html/repo_log.templ
+54
-38
internal/html/repo_log_templ.go
+54
-38
internal/html/repo_log_templ.go
···
1
// Code generated by templ - DO NOT EDIT.
2
3
-
// templ: version: v0.2.707
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
-
import "context"
10
-
import "io"
11
-
import "bytes"
12
13
import "fmt"
14
import "github.com/dustin/go-humanize"
···
21
}
22
23
func RepoLog(rlc RepoLogContext) templ.Component {
24
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
25
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
26
if !templ_7745c5c3_IsBuffer {
27
-
templ_7745c5c3_Buffer = templ.GetBuffer()
28
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
29
}
30
ctx = templ.InitializeContext(ctx)
31
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
33
templ_7745c5c3_Var1 = templ.NopComponent
34
}
35
ctx = templ.ClearChildren(ctx)
36
-
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
37
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
38
if !templ_7745c5c3_IsBuffer {
39
-
templ_7745c5c3_Buffer = templ.GetBuffer()
40
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
41
}
42
templ_7745c5c3_Err = repoHeaderComponent(rlc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
43
if templ_7745c5c3_Err != nil {
44
return templ_7745c5c3_Err
45
}
46
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <div class=\"grid sm:grid-cols-8 gap-1 text-text mt-5\">")
47
if templ_7745c5c3_Err != nil {
48
return templ_7745c5c3_Err
49
}
50
for _, commit := range rlc.Commits {
51
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"sm:col-span-5\"><div><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
52
if templ_7745c5c3_Err != nil {
53
return templ_7745c5c3_Err
54
}
55
-
var templ_7745c5c3_Var3 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/commit/%s", rlc.RepoHeaderComponentContext.Name, commit.SHA))
56
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var3)))
57
if templ_7745c5c3_Err != nil {
58
return templ_7745c5c3_Err
59
}
60
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
61
if templ_7745c5c3_Err != nil {
62
return templ_7745c5c3_Err
63
}
···
70
if templ_7745c5c3_Err != nil {
71
return templ_7745c5c3_Err
72
}
73
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div><div class=\"whitespace-pre\">")
74
if templ_7745c5c3_Err != nil {
75
return templ_7745c5c3_Err
76
}
77
if commit.Details() != "" {
78
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<details><summary class=\"cursor-pointer\">")
79
if templ_7745c5c3_Err != nil {
80
return templ_7745c5c3_Err
81
}
···
88
if templ_7745c5c3_Err != nil {
89
return templ_7745c5c3_Err
90
}
91
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</summary><div class=\"p-3 bg-base rounded\">")
92
if templ_7745c5c3_Err != nil {
93
return templ_7745c5c3_Err
94
}
···
101
if templ_7745c5c3_Err != nil {
102
return templ_7745c5c3_Err
103
}
104
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></details>")
105
if templ_7745c5c3_Err != nil {
106
return templ_7745c5c3_Err
107
}
···
116
return templ_7745c5c3_Err
117
}
118
}
119
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div><div class=\"sm:col-span-3 mb-4\"><div>")
120
if templ_7745c5c3_Err != nil {
121
return templ_7745c5c3_Err
122
}
···
138
if templ_7745c5c3_Err != nil {
139
return templ_7745c5c3_Err
140
}
141
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
142
if templ_7745c5c3_Err != nil {
143
return templ_7745c5c3_Err
144
}
145
-
var templ_7745c5c3_Var10 templ.SafeURL = templ.SafeURL(fmt.Sprintf("mailto:%s", commit.Email))
146
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var10)))
147
if templ_7745c5c3_Err != nil {
148
return templ_7745c5c3_Err
149
}
150
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
151
if templ_7745c5c3_Err != nil {
152
return templ_7745c5c3_Err
153
}
···
160
if templ_7745c5c3_Err != nil {
161
return templ_7745c5c3_Err
162
}
163
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div><div title=\"")
164
if templ_7745c5c3_Err != nil {
165
return templ_7745c5c3_Err
166
}
···
173
if templ_7745c5c3_Err != nil {
174
return templ_7745c5c3_Err
175
}
176
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
177
if templ_7745c5c3_Err != nil {
178
return templ_7745c5c3_Err
179
}
···
186
if templ_7745c5c3_Err != nil {
187
return templ_7745c5c3_Err
188
}
189
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div></div>")
190
if templ_7745c5c3_Err != nil {
191
return templ_7745c5c3_Err
192
}
193
}
194
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
195
if templ_7745c5c3_Err != nil {
196
return templ_7745c5c3_Err
197
}
198
-
if !templ_7745c5c3_IsBuffer {
199
-
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
200
-
}
201
-
return templ_7745c5c3_Err
202
})
203
templ_7745c5c3_Err = base(rlc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
204
if templ_7745c5c3_Err != nil {
205
return templ_7745c5c3_Err
206
}
207
-
if !templ_7745c5c3_IsBuffer {
208
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
209
-
}
210
-
return templ_7745c5c3_Err
211
})
212
}
···
1
// Code generated by templ - DO NOT EDIT.
2
3
+
// templ: version: v0.3.924
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
11
import "fmt"
12
import "github.com/dustin/go-humanize"
···
19
}
20
21
func RepoLog(rlc RepoLogContext) templ.Component {
22
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
23
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
24
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
25
+
return templ_7745c5c3_CtxErr
26
+
}
27
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
28
if !templ_7745c5c3_IsBuffer {
29
+
defer func() {
30
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
31
+
if templ_7745c5c3_Err == nil {
32
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
33
+
}
34
+
}()
35
}
36
ctx = templ.InitializeContext(ctx)
37
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
39
templ_7745c5c3_Var1 = templ.NopComponent
40
}
41
ctx = templ.ClearChildren(ctx)
42
+
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
43
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
44
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
45
if !templ_7745c5c3_IsBuffer {
46
+
defer func() {
47
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
48
+
if templ_7745c5c3_Err == nil {
49
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
50
+
}
51
+
}()
52
}
53
+
ctx = templ.InitializeContext(ctx)
54
templ_7745c5c3_Err = repoHeaderComponent(rlc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
55
if templ_7745c5c3_Err != nil {
56
return templ_7745c5c3_Err
57
}
58
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, " <div class=\"grid sm:grid-cols-8 gap-1 text-text mt-5\">")
59
if templ_7745c5c3_Err != nil {
60
return templ_7745c5c3_Err
61
}
62
for _, commit := range rlc.Commits {
63
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<div class=\"sm:col-span-5\"><div><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
64
if templ_7745c5c3_Err != nil {
65
return templ_7745c5c3_Err
66
}
67
+
var templ_7745c5c3_Var3 templ.SafeURL
68
+
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/commit/%s", rlc.RepoHeaderComponentContext.Name, commit.SHA)))
69
+
if templ_7745c5c3_Err != nil {
70
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_log.templ`, Line: 19, Col: 190}
71
+
}
72
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
73
if templ_7745c5c3_Err != nil {
74
return templ_7745c5c3_Err
75
}
76
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\">")
77
if templ_7745c5c3_Err != nil {
78
return templ_7745c5c3_Err
79
}
···
86
if templ_7745c5c3_Err != nil {
87
return templ_7745c5c3_Err
88
}
89
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</a></div><div class=\"whitespace-pre\">")
90
if templ_7745c5c3_Err != nil {
91
return templ_7745c5c3_Err
92
}
93
if commit.Details() != "" {
94
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<details><summary class=\"cursor-pointer\">")
95
if templ_7745c5c3_Err != nil {
96
return templ_7745c5c3_Err
97
}
···
104
if templ_7745c5c3_Err != nil {
105
return templ_7745c5c3_Err
106
}
107
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</summary><div class=\"p-3 bg-base rounded\">")
108
if templ_7745c5c3_Err != nil {
109
return templ_7745c5c3_Err
110
}
···
117
if templ_7745c5c3_Err != nil {
118
return templ_7745c5c3_Err
119
}
120
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div></details>")
121
if templ_7745c5c3_Err != nil {
122
return templ_7745c5c3_Err
123
}
···
132
return templ_7745c5c3_Err
133
}
134
}
135
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</div></div><div class=\"sm:col-span-3 mb-4\"><div>")
136
if templ_7745c5c3_Err != nil {
137
return templ_7745c5c3_Err
138
}
···
154
if templ_7745c5c3_Err != nil {
155
return templ_7745c5c3_Err
156
}
157
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
158
if templ_7745c5c3_Err != nil {
159
return templ_7745c5c3_Err
160
}
161
+
var templ_7745c5c3_Var10 templ.SafeURL
162
+
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("mailto:%s", commit.Email)))
163
+
if templ_7745c5c3_Err != nil {
164
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_log.templ`, Line: 32, Col: 175}
165
+
}
166
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
167
if templ_7745c5c3_Err != nil {
168
return templ_7745c5c3_Err
169
}
170
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\">")
171
if templ_7745c5c3_Err != nil {
172
return templ_7745c5c3_Err
173
}
···
180
if templ_7745c5c3_Err != nil {
181
return templ_7745c5c3_Err
182
}
183
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</a></div><div title=\"")
184
if templ_7745c5c3_Err != nil {
185
return templ_7745c5c3_Err
186
}
···
193
if templ_7745c5c3_Err != nil {
194
return templ_7745c5c3_Err
195
}
196
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\">")
197
if templ_7745c5c3_Err != nil {
198
return templ_7745c5c3_Err
199
}
···
206
if templ_7745c5c3_Err != nil {
207
return templ_7745c5c3_Err
208
}
209
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</div></div>")
210
if templ_7745c5c3_Err != nil {
211
return templ_7745c5c3_Err
212
}
213
}
214
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</div>")
215
if templ_7745c5c3_Err != nil {
216
return templ_7745c5c3_Err
217
}
218
+
return nil
219
})
220
templ_7745c5c3_Err = base(rlc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
221
if templ_7745c5c3_Err != nil {
222
return templ_7745c5c3_Err
223
}
224
+
return nil
225
})
226
}
227
+
228
+
var _ = templruntime.GeneratedTemplate
+4
-5
internal/html/repo_refs.templ
+4
-5
internal/html/repo_refs.templ
+73
-49
internal/html/repo_refs_templ.go
+73
-49
internal/html/repo_refs_templ.go
···
1
// Code generated by templ - DO NOT EDIT.
2
3
-
// templ: version: v0.2.707
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
-
import "context"
10
-
import "io"
11
-
import "bytes"
12
13
import "fmt"
14
import "go.jolheiser.com/ugit/internal/git"
···
21
}
22
23
func RepoRefs(rrc RepoRefsContext) templ.Component {
24
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
25
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
26
if !templ_7745c5c3_IsBuffer {
27
-
templ_7745c5c3_Buffer = templ.GetBuffer()
28
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
29
}
30
ctx = templ.InitializeContext(ctx)
31
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
33
templ_7745c5c3_Var1 = templ.NopComponent
34
}
35
ctx = templ.ClearChildren(ctx)
36
-
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
37
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
38
if !templ_7745c5c3_IsBuffer {
39
-
templ_7745c5c3_Buffer = templ.GetBuffer()
40
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
41
}
42
templ_7745c5c3_Err = repoHeaderComponent(rrc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
43
if templ_7745c5c3_Err != nil {
44
return templ_7745c5c3_Err
45
}
46
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
47
if templ_7745c5c3_Err != nil {
48
return templ_7745c5c3_Err
49
}
50
if len(rrc.Branches) > 0 {
51
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h3 class=\"text-text text-lg mt-5\">Branches</h3><div class=\"text-text grid grid-cols-4 sm:grid-cols-8\">")
52
if templ_7745c5c3_Err != nil {
53
return templ_7745c5c3_Err
54
}
55
for _, branch := range rrc.Branches {
56
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"col-span-2 sm:col-span-1 font-bold\">")
57
if templ_7745c5c3_Err != nil {
58
return templ_7745c5c3_Err
59
}
···
66
if templ_7745c5c3_Err != nil {
67
return templ_7745c5c3_Err
68
}
69
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"col-span-2 sm:col-span-7\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
70
if templ_7745c5c3_Err != nil {
71
return templ_7745c5c3_Err
72
}
73
-
var templ_7745c5c3_Var4 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/tree/%s/", rrc.RepoHeaderComponentContext.Name, branch))
74
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4)))
75
if templ_7745c5c3_Err != nil {
76
return templ_7745c5c3_Err
77
}
78
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">tree</a>")
79
if templ_7745c5c3_Err != nil {
80
return templ_7745c5c3_Err
81
}
···
88
if templ_7745c5c3_Err != nil {
89
return templ_7745c5c3_Err
90
}
91
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
92
if templ_7745c5c3_Err != nil {
93
return templ_7745c5c3_Err
94
}
95
-
var templ_7745c5c3_Var6 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/log/%s", rrc.RepoHeaderComponentContext.Name, branch))
96
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var6)))
97
if templ_7745c5c3_Err != nil {
98
return templ_7745c5c3_Err
99
}
100
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">log</a></div>")
101
if templ_7745c5c3_Err != nil {
102
return templ_7745c5c3_Err
103
}
104
}
105
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
106
if templ_7745c5c3_Err != nil {
107
return templ_7745c5c3_Err
108
}
109
}
110
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
111
if templ_7745c5c3_Err != nil {
112
return templ_7745c5c3_Err
113
}
114
if len(rrc.Tags) > 0 {
115
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<h3 class=\"text-text text-lg mt-5\">Tags</h3><div class=\"text-text grid grid-cols-8\">")
116
if templ_7745c5c3_Err != nil {
117
return templ_7745c5c3_Err
118
}
119
for _, tag := range rrc.Tags {
120
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"col-span-1 font-bold\">")
121
if templ_7745c5c3_Err != nil {
122
return templ_7745c5c3_Err
123
}
···
130
if templ_7745c5c3_Err != nil {
131
return templ_7745c5c3_Err
132
}
133
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"col-span-7\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
134
if templ_7745c5c3_Err != nil {
135
return templ_7745c5c3_Err
136
}
137
-
var templ_7745c5c3_Var8 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/tree/%s/", rrc.RepoHeaderComponentContext.Name, tag.Name))
138
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var8)))
139
if templ_7745c5c3_Err != nil {
140
return templ_7745c5c3_Err
141
}
142
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">tree</a>")
143
if templ_7745c5c3_Err != nil {
144
return templ_7745c5c3_Err
145
}
···
152
if templ_7745c5c3_Err != nil {
153
return templ_7745c5c3_Err
154
}
155
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
156
if templ_7745c5c3_Err != nil {
157
return templ_7745c5c3_Err
158
}
159
-
var templ_7745c5c3_Var10 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/log/%s", rrc.RepoHeaderComponentContext.Name, tag.Name))
160
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var10)))
161
if templ_7745c5c3_Err != nil {
162
return templ_7745c5c3_Err
163
}
164
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">log</a></div>")
165
if templ_7745c5c3_Err != nil {
166
return templ_7745c5c3_Err
167
}
168
if tag.Signature != "" {
169
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<details class=\"col-span-8 whitespace-pre\"><summary class=\"cursor-pointer\">Signature</summary><code>")
170
if templ_7745c5c3_Err != nil {
171
return templ_7745c5c3_Err
172
}
···
179
if templ_7745c5c3_Err != nil {
180
return templ_7745c5c3_Err
181
}
182
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</code></details>")
183
if templ_7745c5c3_Err != nil {
184
return templ_7745c5c3_Err
185
}
186
}
187
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
188
if templ_7745c5c3_Err != nil {
189
return templ_7745c5c3_Err
190
}
191
if tag.Annotation != "" {
192
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"col-span-8 mb-3\">")
193
if templ_7745c5c3_Err != nil {
194
return templ_7745c5c3_Err
195
}
···
202
if templ_7745c5c3_Err != nil {
203
return templ_7745c5c3_Err
204
}
205
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
206
if templ_7745c5c3_Err != nil {
207
return templ_7745c5c3_Err
208
}
209
}
210
}
211
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
212
if templ_7745c5c3_Err != nil {
213
return templ_7745c5c3_Err
214
}
215
}
216
-
if !templ_7745c5c3_IsBuffer {
217
-
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
218
-
}
219
-
return templ_7745c5c3_Err
220
})
221
templ_7745c5c3_Err = base(rrc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
222
if templ_7745c5c3_Err != nil {
223
return templ_7745c5c3_Err
224
}
225
-
if !templ_7745c5c3_IsBuffer {
226
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
227
-
}
228
-
return templ_7745c5c3_Err
229
})
230
}
···
1
// Code generated by templ - DO NOT EDIT.
2
3
+
// templ: version: v0.3.924
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
11
import "fmt"
12
import "go.jolheiser.com/ugit/internal/git"
···
19
}
20
21
func RepoRefs(rrc RepoRefsContext) templ.Component {
22
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
23
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
24
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
25
+
return templ_7745c5c3_CtxErr
26
+
}
27
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
28
if !templ_7745c5c3_IsBuffer {
29
+
defer func() {
30
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
31
+
if templ_7745c5c3_Err == nil {
32
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
33
+
}
34
+
}()
35
}
36
ctx = templ.InitializeContext(ctx)
37
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
39
templ_7745c5c3_Var1 = templ.NopComponent
40
}
41
ctx = templ.ClearChildren(ctx)
42
+
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
43
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
44
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
45
if !templ_7745c5c3_IsBuffer {
46
+
defer func() {
47
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
48
+
if templ_7745c5c3_Err == nil {
49
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
50
+
}
51
+
}()
52
}
53
+
ctx = templ.InitializeContext(ctx)
54
templ_7745c5c3_Err = repoHeaderComponent(rrc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
55
if templ_7745c5c3_Err != nil {
56
return templ_7745c5c3_Err
57
}
58
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, " ")
59
if templ_7745c5c3_Err != nil {
60
return templ_7745c5c3_Err
61
}
62
if len(rrc.Branches) > 0 {
63
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<h3 class=\"text-text text-lg mt-5\">Branches</h3><div class=\"text-text grid grid-cols-4 sm:grid-cols-8\">")
64
if templ_7745c5c3_Err != nil {
65
return templ_7745c5c3_Err
66
}
67
for _, branch := range rrc.Branches {
68
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<div class=\"col-span-2 sm:col-span-1 font-bold\">")
69
if templ_7745c5c3_Err != nil {
70
return templ_7745c5c3_Err
71
}
···
78
if templ_7745c5c3_Err != nil {
79
return templ_7745c5c3_Err
80
}
81
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</div><div class=\"col-span-2 sm:col-span-7\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
82
if templ_7745c5c3_Err != nil {
83
return templ_7745c5c3_Err
84
}
85
+
var templ_7745c5c3_Var4 templ.SafeURL
86
+
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/tree/%s/", rrc.RepoHeaderComponentContext.Name, branch)))
87
+
if templ_7745c5c3_Err != nil {
88
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_refs.templ`, Line: 21, Col: 218}
89
+
}
90
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
91
if templ_7745c5c3_Err != nil {
92
return templ_7745c5c3_Err
93
}
94
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\">tree</a>")
95
if templ_7745c5c3_Err != nil {
96
return templ_7745c5c3_Err
97
}
···
104
if templ_7745c5c3_Err != nil {
105
return templ_7745c5c3_Err
106
}
107
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
108
if templ_7745c5c3_Err != nil {
109
return templ_7745c5c3_Err
110
}
111
+
var templ_7745c5c3_Var6 templ.SafeURL
112
+
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/log/%s", rrc.RepoHeaderComponentContext.Name, branch)))
113
+
if templ_7745c5c3_Err != nil {
114
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_refs.templ`, Line: 21, Col: 409}
115
+
}
116
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
117
if templ_7745c5c3_Err != nil {
118
return templ_7745c5c3_Err
119
}
120
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\">log</a></div>")
121
if templ_7745c5c3_Err != nil {
122
return templ_7745c5c3_Err
123
}
124
}
125
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</div>")
126
if templ_7745c5c3_Err != nil {
127
return templ_7745c5c3_Err
128
}
129
}
130
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " ")
131
if templ_7745c5c3_Err != nil {
132
return templ_7745c5c3_Err
133
}
134
if len(rrc.Tags) > 0 {
135
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<h3 class=\"text-text text-lg mt-5\">Tags</h3><div class=\"text-text grid grid-cols-8\">")
136
if templ_7745c5c3_Err != nil {
137
return templ_7745c5c3_Err
138
}
139
for _, tag := range rrc.Tags {
140
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<div class=\"col-span-1 font-bold\">")
141
if templ_7745c5c3_Err != nil {
142
return templ_7745c5c3_Err
143
}
···
150
if templ_7745c5c3_Err != nil {
151
return templ_7745c5c3_Err
152
}
153
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</div><div class=\"col-span-7\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
154
if templ_7745c5c3_Err != nil {
155
return templ_7745c5c3_Err
156
}
157
+
var templ_7745c5c3_Var8 templ.SafeURL
158
+
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/tree/%s/", rrc.RepoHeaderComponentContext.Name, tag.Name)))
159
+
if templ_7745c5c3_Err != nil {
160
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_refs.templ`, Line: 30, Col: 206}
161
+
}
162
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
163
if templ_7745c5c3_Err != nil {
164
return templ_7745c5c3_Err
165
}
166
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\">tree</a>")
167
if templ_7745c5c3_Err != nil {
168
return templ_7745c5c3_Err
169
}
···
176
if templ_7745c5c3_Err != nil {
177
return templ_7745c5c3_Err
178
}
179
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
180
if templ_7745c5c3_Err != nil {
181
return templ_7745c5c3_Err
182
}
183
+
var templ_7745c5c3_Var10 templ.SafeURL
184
+
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/log/%s", rrc.RepoHeaderComponentContext.Name, tag.Name)))
185
+
if templ_7745c5c3_Err != nil {
186
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_refs.templ`, Line: 30, Col: 399}
187
+
}
188
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
189
if templ_7745c5c3_Err != nil {
190
return templ_7745c5c3_Err
191
}
192
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\">log</a></div>")
193
if templ_7745c5c3_Err != nil {
194
return templ_7745c5c3_Err
195
}
196
if tag.Signature != "" {
197
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<details class=\"col-span-8 whitespace-pre\"><summary class=\"cursor-pointer\">Signature</summary><code>")
198
if templ_7745c5c3_Err != nil {
199
return templ_7745c5c3_Err
200
}
···
207
if templ_7745c5c3_Err != nil {
208
return templ_7745c5c3_Err
209
}
210
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</code></details>")
211
if templ_7745c5c3_Err != nil {
212
return templ_7745c5c3_Err
213
}
214
}
215
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " ")
216
if templ_7745c5c3_Err != nil {
217
return templ_7745c5c3_Err
218
}
219
if tag.Annotation != "" {
220
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<div class=\"col-span-8 mb-3\">")
221
if templ_7745c5c3_Err != nil {
222
return templ_7745c5c3_Err
223
}
···
230
if templ_7745c5c3_Err != nil {
231
return templ_7745c5c3_Err
232
}
233
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</div>")
234
if templ_7745c5c3_Err != nil {
235
return templ_7745c5c3_Err
236
}
237
}
238
}
239
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</div>")
240
if templ_7745c5c3_Err != nil {
241
return templ_7745c5c3_Err
242
}
243
}
244
+
return nil
245
})
246
templ_7745c5c3_Err = base(rrc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
247
if templ_7745c5c3_Err != nil {
248
return templ_7745c5c3_Err
249
}
250
+
return nil
251
})
252
}
253
+
254
+
var _ = templruntime.GeneratedTemplate
+6
-8
internal/html/repo_search.templ
+6
-8
internal/html/repo_search.templ
···
11
12
func (s SearchContext) DedupeResults() [][]git.GrepResult {
13
var (
14
-
results [][]git.GrepResult
15
-
currentFile string
16
-
currentResults []git.GrepResult
17
)
18
for _, result := range s.Results {
19
if result.File == currentFile {
20
-
currentResults = append(currentResults, result)
21
continue
22
}
23
-
if currentFile != "" {
24
-
results = append(results, currentResults)
25
-
}
26
currentFile = result.File
27
-
currentResults = []git.GrepResult{result}
28
}
29
30
return results
···
11
12
func (s SearchContext) DedupeResults() [][]git.GrepResult {
13
var (
14
+
results [][]git.GrepResult
15
+
currentFile string
16
)
17
+
var idx int
18
for _, result := range s.Results {
19
if result.File == currentFile {
20
+
results[idx-1] = append(results[idx-1], result)
21
continue
22
}
23
+
results = append(results, []git.GrepResult{result})
24
currentFile = result.File
25
+
idx++
26
}
27
28
return results
+76
-57
internal/html/repo_search_templ.go
+76
-57
internal/html/repo_search_templ.go
···
1
// Code generated by templ - DO NOT EDIT.
2
3
-
// templ: version: v0.2.707
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
-
import "context"
10
-
import "io"
11
-
import "bytes"
12
13
import "fmt"
14
import "go.jolheiser.com/ugit/internal/git"
···
21
22
func (s SearchContext) DedupeResults() [][]git.GrepResult {
23
var (
24
-
results [][]git.GrepResult
25
-
currentFile string
26
-
currentResults []git.GrepResult
27
)
28
for _, result := range s.Results {
29
if result.File == currentFile {
30
-
currentResults = append(currentResults, result)
31
continue
32
}
33
-
if currentFile != "" {
34
-
results = append(results, currentResults)
35
-
}
36
currentFile = result.File
37
-
currentResults = []git.GrepResult{result}
38
}
39
40
return results
41
}
42
43
func RepoSearch(sc SearchContext) templ.Component {
44
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
45
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
46
if !templ_7745c5c3_IsBuffer {
47
-
templ_7745c5c3_Buffer = templ.GetBuffer()
48
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
49
}
50
ctx = templ.InitializeContext(ctx)
51
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
53
templ_7745c5c3_Var1 = templ.NopComponent
54
}
55
ctx = templ.ClearChildren(ctx)
56
-
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
57
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
58
if !templ_7745c5c3_IsBuffer {
59
-
templ_7745c5c3_Buffer = templ.GetBuffer()
60
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
61
}
62
templ_7745c5c3_Err = repoHeaderComponent(sc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
63
if templ_7745c5c3_Err != nil {
64
return templ_7745c5c3_Err
···
69
return templ_7745c5c3_Err
70
}
71
}
72
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
73
if templ_7745c5c3_Err != nil {
74
return templ_7745c5c3_Err
75
}
76
if len(sc.DedupeResults()) == 0 {
77
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<p class=\"text-text mt-5 text-lg\">No results</p>")
78
if templ_7745c5c3_Err != nil {
79
return templ_7745c5c3_Err
80
}
81
}
82
-
if !templ_7745c5c3_IsBuffer {
83
-
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
84
-
}
85
-
return templ_7745c5c3_Err
86
})
87
templ_7745c5c3_Err = base(sc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
88
if templ_7745c5c3_Err != nil {
89
return templ_7745c5c3_Err
90
}
91
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script>\n\t\tconst search = new URLSearchParams(window.location.search).get(\"q\");\n\t\tif (search !== \"\") document.querySelector(\"#search\").value = search;\n\t</script>")
92
if templ_7745c5c3_Err != nil {
93
return templ_7745c5c3_Err
94
}
95
-
if !templ_7745c5c3_IsBuffer {
96
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
97
-
}
98
-
return templ_7745c5c3_Err
99
})
100
}
101
102
func repoSearchResult(repo, ref string, results []git.GrepResult) templ.Component {
103
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
104
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
105
if !templ_7745c5c3_IsBuffer {
106
-
templ_7745c5c3_Buffer = templ.GetBuffer()
107
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
108
}
109
ctx = templ.InitializeContext(ctx)
110
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
···
112
templ_7745c5c3_Var3 = templ.NopComponent
113
}
114
ctx = templ.ClearChildren(ctx)
115
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"text-text mt-5\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
116
if templ_7745c5c3_Err != nil {
117
return templ_7745c5c3_Err
118
}
119
-
var templ_7745c5c3_Var4 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s#L%d", repo, ref, results[0].File, results[0].Line))
120
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4)))
121
if templ_7745c5c3_Err != nil {
122
return templ_7745c5c3_Err
123
}
124
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
125
if templ_7745c5c3_Err != nil {
126
return templ_7745c5c3_Err
127
}
128
var templ_7745c5c3_Var5 string
129
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(results[0].File)
130
if templ_7745c5c3_Err != nil {
131
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 50, Col: 230}
132
}
133
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
134
if templ_7745c5c3_Err != nil {
135
return templ_7745c5c3_Err
136
}
137
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div><div class=\"code\">")
138
if templ_7745c5c3_Err != nil {
139
return templ_7745c5c3_Err
140
}
···
142
if templ_7745c5c3_Err != nil {
143
return templ_7745c5c3_Err
144
}
145
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
146
if templ_7745c5c3_Err != nil {
147
return templ_7745c5c3_Err
148
}
149
if len(results) > 1 {
150
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<details class=\"text-text cursor-pointer\"><summary>")
151
if templ_7745c5c3_Err != nil {
152
return templ_7745c5c3_Err
153
}
154
var templ_7745c5c3_Var6 string
155
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d ", len(results[1:])))
156
if templ_7745c5c3_Err != nil {
157
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 56, Col: 50}
158
}
159
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
160
if templ_7745c5c3_Err != nil {
161
return templ_7745c5c3_Err
162
}
163
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("more</summary> ")
164
if templ_7745c5c3_Err != nil {
165
return templ_7745c5c3_Err
166
}
167
for _, result := range results[1:] {
168
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"text-text mt-5 ml-5\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
169
if templ_7745c5c3_Err != nil {
170
return templ_7745c5c3_Err
171
}
172
-
var templ_7745c5c3_Var7 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s#L%d", repo, ref, result.File, result.Line))
173
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var7)))
174
if templ_7745c5c3_Err != nil {
175
return templ_7745c5c3_Err
176
}
177
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
178
if templ_7745c5c3_Err != nil {
179
return templ_7745c5c3_Err
180
}
181
var templ_7745c5c3_Var8 string
182
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(results[0].File)
183
if templ_7745c5c3_Err != nil {
184
-
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 58, Col: 230}
185
}
186
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
187
if templ_7745c5c3_Err != nil {
188
return templ_7745c5c3_Err
189
}
190
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div><div class=\"code ml-5\">")
191
if templ_7745c5c3_Err != nil {
192
return templ_7745c5c3_Err
193
}
···
195
if templ_7745c5c3_Err != nil {
196
return templ_7745c5c3_Err
197
}
198
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
199
if templ_7745c5c3_Err != nil {
200
return templ_7745c5c3_Err
201
}
202
}
203
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</details>")
204
if templ_7745c5c3_Err != nil {
205
return templ_7745c5c3_Err
206
}
207
}
208
-
if !templ_7745c5c3_IsBuffer {
209
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
210
-
}
211
-
return templ_7745c5c3_Err
212
})
213
}
···
1
// Code generated by templ - DO NOT EDIT.
2
3
+
// templ: version: v0.3.924
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
11
import "fmt"
12
import "go.jolheiser.com/ugit/internal/git"
···
19
20
func (s SearchContext) DedupeResults() [][]git.GrepResult {
21
var (
22
+
results [][]git.GrepResult
23
+
currentFile string
24
)
25
+
var idx int
26
for _, result := range s.Results {
27
if result.File == currentFile {
28
+
results[idx-1] = append(results[idx-1], result)
29
continue
30
}
31
+
results = append(results, []git.GrepResult{result})
32
currentFile = result.File
33
+
idx++
34
}
35
36
return results
37
}
38
39
func RepoSearch(sc SearchContext) templ.Component {
40
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
41
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
42
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
43
+
return templ_7745c5c3_CtxErr
44
+
}
45
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
46
if !templ_7745c5c3_IsBuffer {
47
+
defer func() {
48
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
49
+
if templ_7745c5c3_Err == nil {
50
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
51
+
}
52
+
}()
53
}
54
ctx = templ.InitializeContext(ctx)
55
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
57
templ_7745c5c3_Var1 = templ.NopComponent
58
}
59
ctx = templ.ClearChildren(ctx)
60
+
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
61
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
62
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
63
if !templ_7745c5c3_IsBuffer {
64
+
defer func() {
65
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
66
+
if templ_7745c5c3_Err == nil {
67
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
68
+
}
69
+
}()
70
}
71
+
ctx = templ.InitializeContext(ctx)
72
templ_7745c5c3_Err = repoHeaderComponent(sc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
73
if templ_7745c5c3_Err != nil {
74
return templ_7745c5c3_Err
···
79
return templ_7745c5c3_Err
80
}
81
}
82
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, " ")
83
if templ_7745c5c3_Err != nil {
84
return templ_7745c5c3_Err
85
}
86
if len(sc.DedupeResults()) == 0 {
87
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<p class=\"text-text mt-5 text-lg\">No results</p>")
88
if templ_7745c5c3_Err != nil {
89
return templ_7745c5c3_Err
90
}
91
}
92
+
return nil
93
})
94
templ_7745c5c3_Err = base(sc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
95
if templ_7745c5c3_Err != nil {
96
return templ_7745c5c3_Err
97
}
98
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<script>\n\t\tconst search = new URLSearchParams(window.location.search).get(\"q\");\n\t\tif (search !== \"\") document.querySelector(\"#search\").value = search;\n\t</script>")
99
if templ_7745c5c3_Err != nil {
100
return templ_7745c5c3_Err
101
}
102
+
return nil
103
})
104
}
105
106
func repoSearchResult(repo, ref string, results []git.GrepResult) templ.Component {
107
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
108
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
109
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
110
+
return templ_7745c5c3_CtxErr
111
+
}
112
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
113
if !templ_7745c5c3_IsBuffer {
114
+
defer func() {
115
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
116
+
if templ_7745c5c3_Err == nil {
117
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
118
+
}
119
+
}()
120
}
121
ctx = templ.InitializeContext(ctx)
122
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
···
124
templ_7745c5c3_Var3 = templ.NopComponent
125
}
126
ctx = templ.ClearChildren(ctx)
127
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<div class=\"text-text mt-5\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
128
if templ_7745c5c3_Err != nil {
129
return templ_7745c5c3_Err
130
}
131
+
var templ_7745c5c3_Var4 templ.SafeURL
132
+
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s#L%d", repo, ref, results[0].File, results[0].Line)))
133
+
if templ_7745c5c3_Err != nil {
134
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 48, Col: 210}
135
+
}
136
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
137
if templ_7745c5c3_Err != nil {
138
return templ_7745c5c3_Err
139
}
140
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\">")
141
if templ_7745c5c3_Err != nil {
142
return templ_7745c5c3_Err
143
}
144
var templ_7745c5c3_Var5 string
145
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(results[0].File)
146
if templ_7745c5c3_Err != nil {
147
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 48, Col: 230}
148
}
149
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
150
if templ_7745c5c3_Err != nil {
151
return templ_7745c5c3_Err
152
}
153
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</a></div><div class=\"code\">")
154
if templ_7745c5c3_Err != nil {
155
return templ_7745c5c3_Err
156
}
···
158
if templ_7745c5c3_Err != nil {
159
return templ_7745c5c3_Err
160
}
161
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</div>")
162
if templ_7745c5c3_Err != nil {
163
return templ_7745c5c3_Err
164
}
165
if len(results) > 1 {
166
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<details class=\"text-text cursor-pointer\"><summary>")
167
if templ_7745c5c3_Err != nil {
168
return templ_7745c5c3_Err
169
}
170
var templ_7745c5c3_Var6 string
171
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d ", len(results[1:])))
172
if templ_7745c5c3_Err != nil {
173
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 54, Col: 50}
174
}
175
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
176
if templ_7745c5c3_Err != nil {
177
return templ_7745c5c3_Err
178
}
179
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "more</summary> ")
180
if templ_7745c5c3_Err != nil {
181
return templ_7745c5c3_Err
182
}
183
for _, result := range results[1:] {
184
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<div class=\"text-text mt-5 ml-5\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
185
if templ_7745c5c3_Err != nil {
186
return templ_7745c5c3_Err
187
}
188
+
var templ_7745c5c3_Var7 templ.SafeURL
189
+
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s#L%d", repo, ref, result.File, result.Line)))
190
+
if templ_7745c5c3_Err != nil {
191
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 56, Col: 210}
192
+
}
193
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
194
if templ_7745c5c3_Err != nil {
195
return templ_7745c5c3_Err
196
}
197
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\">")
198
if templ_7745c5c3_Err != nil {
199
return templ_7745c5c3_Err
200
}
201
var templ_7745c5c3_Var8 string
202
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(results[0].File)
203
if templ_7745c5c3_Err != nil {
204
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_search.templ`, Line: 56, Col: 230}
205
}
206
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
207
if templ_7745c5c3_Err != nil {
208
return templ_7745c5c3_Err
209
}
210
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</a></div><div class=\"code ml-5\">")
211
if templ_7745c5c3_Err != nil {
212
return templ_7745c5c3_Err
213
}
···
215
if templ_7745c5c3_Err != nil {
216
return templ_7745c5c3_Err
217
}
218
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</div>")
219
if templ_7745c5c3_Err != nil {
220
return templ_7745c5c3_Err
221
}
222
}
223
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</details>")
224
if templ_7745c5c3_Err != nil {
225
return templ_7745c5c3_Err
226
}
227
}
228
+
return nil
229
})
230
}
231
+
232
+
var _ = templruntime.GeneratedTemplate
+65
-40
internal/html/repo_templ.go
+65
-40
internal/html/repo_templ.go
···
1
// Code generated by templ - DO NOT EDIT.
2
3
-
// templ: version: v0.2.707
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
-
import "context"
10
-
import "io"
11
-
import "bytes"
12
13
import "fmt"
14
···
21
}
22
23
func repoHeaderComponent(rhcc RepoHeaderComponentContext) templ.Component {
24
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
25
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
26
if !templ_7745c5c3_IsBuffer {
27
-
templ_7745c5c3_Buffer = templ.GetBuffer()
28
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
29
}
30
ctx = templ.InitializeContext(ctx)
31
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
33
templ_7745c5c3_Var1 = templ.NopComponent
34
}
35
ctx = templ.ClearChildren(ctx)
36
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"mb-1 text-text\"><a class=\"text-lg underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
37
if templ_7745c5c3_Err != nil {
38
return templ_7745c5c3_Err
39
}
40
-
var templ_7745c5c3_Var2 templ.SafeURL = templ.SafeURL("/" + rhcc.Name)
41
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var2)))
42
if templ_7745c5c3_Err != nil {
43
return templ_7745c5c3_Err
44
}
45
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
46
if templ_7745c5c3_Err != nil {
47
return templ_7745c5c3_Err
48
}
···
55
if templ_7745c5c3_Err != nil {
56
return templ_7745c5c3_Err
57
}
58
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a> ")
59
if templ_7745c5c3_Err != nil {
60
return templ_7745c5c3_Err
61
}
···
69
if templ_7745c5c3_Err != nil {
70
return templ_7745c5c3_Err
71
}
72
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <a class=\"text-text/80 text-sm underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
73
if templ_7745c5c3_Err != nil {
74
return templ_7745c5c3_Err
75
}
76
-
var templ_7745c5c3_Var5 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/tree/%s/", rhcc.Name, rhcc.Ref))
77
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var5)))
78
if templ_7745c5c3_Err != nil {
79
return templ_7745c5c3_Err
80
}
81
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
82
if templ_7745c5c3_Err != nil {
83
return templ_7745c5c3_Err
84
}
···
91
if templ_7745c5c3_Err != nil {
92
return templ_7745c5c3_Err
93
}
94
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a> ")
95
if templ_7745c5c3_Err != nil {
96
return templ_7745c5c3_Err
97
}
···
105
if templ_7745c5c3_Err != nil {
106
return templ_7745c5c3_Err
107
}
108
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
109
if templ_7745c5c3_Err != nil {
110
return templ_7745c5c3_Err
111
}
112
-
var templ_7745c5c3_Var8 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/refs", rhcc.Name))
113
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var8)))
114
if templ_7745c5c3_Err != nil {
115
return templ_7745c5c3_Err
116
}
117
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">refs</a> ")
118
if templ_7745c5c3_Err != nil {
119
return templ_7745c5c3_Err
120
}
···
127
if templ_7745c5c3_Err != nil {
128
return templ_7745c5c3_Err
129
}
130
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
131
if templ_7745c5c3_Err != nil {
132
return templ_7745c5c3_Err
133
}
134
-
var templ_7745c5c3_Var10 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/log/%s", rhcc.Name, rhcc.Ref))
135
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var10)))
136
if templ_7745c5c3_Err != nil {
137
return templ_7745c5c3_Err
138
}
139
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">log</a> ")
140
if templ_7745c5c3_Err != nil {
141
return templ_7745c5c3_Err
142
}
···
149
if templ_7745c5c3_Err != nil {
150
return templ_7745c5c3_Err
151
}
152
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<form class=\"inline-block\" action=\"")
153
if templ_7745c5c3_Err != nil {
154
return templ_7745c5c3_Err
155
}
156
-
var templ_7745c5c3_Var12 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/search", rhcc.Name))
157
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var12)))
158
if templ_7745c5c3_Err != nil {
159
return templ_7745c5c3_Err
160
}
161
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" method=\"get\"><input class=\"rounded p-1 bg-mantle focus:border-lavender focus:outline-none focus:ring-0\" id=\"search\" type=\"text\" name=\"q\" placeholder=\"search\"></form>")
162
if templ_7745c5c3_Err != nil {
163
return templ_7745c5c3_Err
164
}
···
171
if templ_7745c5c3_Err != nil {
172
return templ_7745c5c3_Err
173
}
174
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<pre class=\"text-text inline select-all bg-base dark:bg-base/50 p-1 rounded\">")
175
if templ_7745c5c3_Err != nil {
176
return templ_7745c5c3_Err
177
}
···
184
if templ_7745c5c3_Err != nil {
185
return templ_7745c5c3_Err
186
}
187
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</pre></div><div class=\"text-subtext0 mb-1\">")
188
if templ_7745c5c3_Err != nil {
189
return templ_7745c5c3_Err
190
}
191
for _, tag := range rhcc.Tags {
192
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<span class=\"rounded border-rosewater border-solid border pb-0.5 px-1 mr-1 mb-1 inline-block\">")
193
if templ_7745c5c3_Err != nil {
194
return templ_7745c5c3_Err
195
}
···
202
if templ_7745c5c3_Err != nil {
203
return templ_7745c5c3_Err
204
}
205
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</span>")
206
if templ_7745c5c3_Err != nil {
207
return templ_7745c5c3_Err
208
}
209
}
210
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"text-text/80 mb-1\">")
211
if templ_7745c5c3_Err != nil {
212
return templ_7745c5c3_Err
213
}
···
220
if templ_7745c5c3_Err != nil {
221
return templ_7745c5c3_Err
222
}
223
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
224
if templ_7745c5c3_Err != nil {
225
return templ_7745c5c3_Err
226
}
227
-
if !templ_7745c5c3_IsBuffer {
228
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
229
-
}
230
-
return templ_7745c5c3_Err
231
})
232
}
···
1
// Code generated by templ - DO NOT EDIT.
2
3
+
// templ: version: v0.3.924
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
11
import "fmt"
12
···
19
}
20
21
func repoHeaderComponent(rhcc RepoHeaderComponentContext) templ.Component {
22
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
23
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
24
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
25
+
return templ_7745c5c3_CtxErr
26
+
}
27
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
28
if !templ_7745c5c3_IsBuffer {
29
+
defer func() {
30
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
31
+
if templ_7745c5c3_Err == nil {
32
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
33
+
}
34
+
}()
35
}
36
ctx = templ.InitializeContext(ctx)
37
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
39
templ_7745c5c3_Var1 = templ.NopComponent
40
}
41
ctx = templ.ClearChildren(ctx)
42
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"mb-1 text-text\"><a class=\"text-lg underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
43
if templ_7745c5c3_Err != nil {
44
return templ_7745c5c3_Err
45
}
46
+
var templ_7745c5c3_Var2 templ.SafeURL
47
+
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL("/" + rhcc.Name))
48
+
if templ_7745c5c3_Err != nil {
49
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo.templ`, Line: 15, Col: 128}
50
+
}
51
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
52
if templ_7745c5c3_Err != nil {
53
return templ_7745c5c3_Err
54
}
55
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">")
56
if templ_7745c5c3_Err != nil {
57
return templ_7745c5c3_Err
58
}
···
65
if templ_7745c5c3_Err != nil {
66
return templ_7745c5c3_Err
67
}
68
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</a> ")
69
if templ_7745c5c3_Err != nil {
70
return templ_7745c5c3_Err
71
}
···
79
if templ_7745c5c3_Err != nil {
80
return templ_7745c5c3_Err
81
}
82
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " <a class=\"text-text/80 text-sm underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
83
if templ_7745c5c3_Err != nil {
84
return templ_7745c5c3_Err
85
}
86
+
var templ_7745c5c3_Var5 templ.SafeURL
87
+
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/tree/%s/", rhcc.Name, rhcc.Ref)))
88
+
if templ_7745c5c3_Err != nil {
89
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo.templ`, Line: 18, Col: 175}
90
+
}
91
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
92
if templ_7745c5c3_Err != nil {
93
return templ_7745c5c3_Err
94
}
95
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\">")
96
if templ_7745c5c3_Err != nil {
97
return templ_7745c5c3_Err
98
}
···
105
if templ_7745c5c3_Err != nil {
106
return templ_7745c5c3_Err
107
}
108
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</a> ")
109
if templ_7745c5c3_Err != nil {
110
return templ_7745c5c3_Err
111
}
···
119
if templ_7745c5c3_Err != nil {
120
return templ_7745c5c3_Err
121
}
122
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " <a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
123
if templ_7745c5c3_Err != nil {
124
return templ_7745c5c3_Err
125
}
126
+
var templ_7745c5c3_Var8 templ.SafeURL
127
+
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/refs", rhcc.Name)))
128
+
if templ_7745c5c3_Err != nil {
129
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo.templ`, Line: 21, Col: 139}
130
+
}
131
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
132
if templ_7745c5c3_Err != nil {
133
return templ_7745c5c3_Err
134
}
135
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\">refs</a> ")
136
if templ_7745c5c3_Err != nil {
137
return templ_7745c5c3_Err
138
}
···
145
if templ_7745c5c3_Err != nil {
146
return templ_7745c5c3_Err
147
}
148
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " <a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
149
if templ_7745c5c3_Err != nil {
150
return templ_7745c5c3_Err
151
}
152
+
var templ_7745c5c3_Var10 templ.SafeURL
153
+
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/log/%s", rhcc.Name, rhcc.Ref)))
154
+
if templ_7745c5c3_Err != nil {
155
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo.templ`, Line: 23, Col: 151}
156
+
}
157
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
158
if templ_7745c5c3_Err != nil {
159
return templ_7745c5c3_Err
160
}
161
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\">log</a> ")
162
if templ_7745c5c3_Err != nil {
163
return templ_7745c5c3_Err
164
}
···
171
if templ_7745c5c3_Err != nil {
172
return templ_7745c5c3_Err
173
}
174
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<form class=\"inline-block\" action=\"")
175
if templ_7745c5c3_Err != nil {
176
return templ_7745c5c3_Err
177
}
178
+
var templ_7745c5c3_Var12 templ.SafeURL
179
+
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/search", rhcc.Name)))
180
+
if templ_7745c5c3_Err != nil {
181
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo.templ`, Line: 25, Col: 89}
182
+
}
183
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
184
if templ_7745c5c3_Err != nil {
185
return templ_7745c5c3_Err
186
}
187
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\" method=\"get\"><input class=\"rounded p-1 bg-mantle focus:border-lavender focus:outline-none focus:ring-0\" id=\"search\" type=\"text\" name=\"q\" placeholder=\"search\"></form>")
188
if templ_7745c5c3_Err != nil {
189
return templ_7745c5c3_Err
190
}
···
197
if templ_7745c5c3_Err != nil {
198
return templ_7745c5c3_Err
199
}
200
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<pre class=\"text-text inline select-all bg-base dark:bg-base/50 p-1 rounded\">")
201
if templ_7745c5c3_Err != nil {
202
return templ_7745c5c3_Err
203
}
···
210
if templ_7745c5c3_Err != nil {
211
return templ_7745c5c3_Err
212
}
213
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</pre></div><div class=\"text-subtext0 mb-1\">")
214
if templ_7745c5c3_Err != nil {
215
return templ_7745c5c3_Err
216
}
217
for _, tag := range rhcc.Tags {
218
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<span class=\"rounded border-rosewater border-solid border pb-0.5 px-1 mr-1 mb-1 inline-block\">")
219
if templ_7745c5c3_Err != nil {
220
return templ_7745c5c3_Err
221
}
···
228
if templ_7745c5c3_Err != nil {
229
return templ_7745c5c3_Err
230
}
231
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</span>")
232
if templ_7745c5c3_Err != nil {
233
return templ_7745c5c3_Err
234
}
235
}
236
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</div><div class=\"text-text/80 mb-1\">")
237
if templ_7745c5c3_Err != nil {
238
return templ_7745c5c3_Err
239
}
···
246
if templ_7745c5c3_Err != nil {
247
return templ_7745c5c3_Err
248
}
249
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</div>")
250
if templ_7745c5c3_Err != nil {
251
return templ_7745c5c3_Err
252
}
253
+
return nil
254
})
255
}
256
+
257
+
var _ = templruntime.GeneratedTemplate
+65
-44
internal/html/repo_tree_templ.go
+65
-44
internal/html/repo_tree_templ.go
···
1
// Code generated by templ - DO NOT EDIT.
2
3
-
// templ: version: v0.2.707
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
-
import "context"
10
-
import "io"
11
-
import "bytes"
12
13
import (
14
"fmt"
···
25
}
26
27
func RepoTree(rtc RepoTreeContext) templ.Component {
28
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
29
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
30
if !templ_7745c5c3_IsBuffer {
31
-
templ_7745c5c3_Buffer = templ.GetBuffer()
32
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
33
}
34
ctx = templ.InitializeContext(ctx)
35
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
37
templ_7745c5c3_Var1 = templ.NopComponent
38
}
39
ctx = templ.ClearChildren(ctx)
40
-
templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
41
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
42
if !templ_7745c5c3_IsBuffer {
43
-
templ_7745c5c3_Buffer = templ.GetBuffer()
44
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
45
}
46
templ_7745c5c3_Err = repoHeaderComponent(rtc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
47
if templ_7745c5c3_Err != nil {
48
return templ_7745c5c3_Err
49
}
50
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
51
if templ_7745c5c3_Err != nil {
52
return templ_7745c5c3_Err
53
}
···
55
if templ_7745c5c3_Err != nil {
56
return templ_7745c5c3_Err
57
}
58
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
59
if templ_7745c5c3_Err != nil {
60
return templ_7745c5c3_Err
61
}
···
63
if templ_7745c5c3_Err != nil {
64
return templ_7745c5c3_Err
65
}
66
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ")
67
if templ_7745c5c3_Err != nil {
68
return templ_7745c5c3_Err
69
}
···
71
if templ_7745c5c3_Err != nil {
72
return templ_7745c5c3_Err
73
}
74
-
if !templ_7745c5c3_IsBuffer {
75
-
_, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer)
76
-
}
77
-
return templ_7745c5c3_Err
78
})
79
templ_7745c5c3_Err = base(rtc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
80
if templ_7745c5c3_Err != nil {
81
return templ_7745c5c3_Err
82
}
83
-
if !templ_7745c5c3_IsBuffer {
84
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
85
-
}
86
-
return templ_7745c5c3_Err
87
})
88
}
89
···
102
}
103
104
func repoTreeComponent(rtcc RepoTreeComponentContext) templ.Component {
105
-
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
106
-
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
107
if !templ_7745c5c3_IsBuffer {
108
-
templ_7745c5c3_Buffer = templ.GetBuffer()
109
-
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
110
}
111
ctx = templ.InitializeContext(ctx)
112
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
···
114
templ_7745c5c3_Var3 = templ.NopComponent
115
}
116
ctx = templ.ClearChildren(ctx)
117
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"grid grid-cols-3 sm:grid-cols-8 text-text py-5 rounded px-5 gap-x-3 gap-y-1 bg-base dark:bg-base/50\">")
118
if templ_7745c5c3_Err != nil {
119
return templ_7745c5c3_Err
120
}
121
if rtcc.Back != "" {
122
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"col-span-2\"></div><div class=\"sm:col-span-6\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
123
if templ_7745c5c3_Err != nil {
124
return templ_7745c5c3_Err
125
}
126
-
var templ_7745c5c3_Var4 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s", rtcc.Repo, rtcc.Ref, rtcc.Back))
127
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var4)))
128
if templ_7745c5c3_Err != nil {
129
return templ_7745c5c3_Err
130
}
131
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">..</a></div>")
132
if templ_7745c5c3_Err != nil {
133
return templ_7745c5c3_Err
134
}
135
}
136
for _, fi := range rtcc.Tree {
137
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"sm:col-span-1 break-keep\">")
138
if templ_7745c5c3_Err != nil {
139
return templ_7745c5c3_Err
140
}
···
147
if templ_7745c5c3_Err != nil {
148
return templ_7745c5c3_Err
149
}
150
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"sm:col-span-1 text-right\">")
151
if templ_7745c5c3_Err != nil {
152
return templ_7745c5c3_Err
153
}
···
160
if templ_7745c5c3_Err != nil {
161
return templ_7745c5c3_Err
162
}
163
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div><div class=\"sm:col-span-6 overflow-hidden text-ellipsis\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
164
if templ_7745c5c3_Err != nil {
165
return templ_7745c5c3_Err
166
}
167
-
var templ_7745c5c3_Var7 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s", rtcc.Repo, rtcc.Ref, fi.Path))
168
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var7)))
169
if templ_7745c5c3_Err != nil {
170
return templ_7745c5c3_Err
171
}
172
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">")
173
if templ_7745c5c3_Err != nil {
174
return templ_7745c5c3_Err
175
}
···
182
if templ_7745c5c3_Err != nil {
183
return templ_7745c5c3_Err
184
}
185
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</a></div>")
186
if templ_7745c5c3_Err != nil {
187
return templ_7745c5c3_Err
188
}
189
}
190
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</div>")
191
if templ_7745c5c3_Err != nil {
192
return templ_7745c5c3_Err
193
}
194
-
if !templ_7745c5c3_IsBuffer {
195
-
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
196
-
}
197
-
return templ_7745c5c3_Err
198
})
199
}
···
1
// Code generated by templ - DO NOT EDIT.
2
3
+
// templ: version: v0.3.924
4
package html
5
6
//lint:file-ignore SA4006 This context is only used if a nested component is present.
7
8
import "github.com/a-h/templ"
9
+
import templruntime "github.com/a-h/templ/runtime"
10
11
import (
12
"fmt"
···
23
}
24
25
func RepoTree(rtc RepoTreeContext) templ.Component {
26
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
27
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
28
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
29
+
return templ_7745c5c3_CtxErr
30
+
}
31
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
32
if !templ_7745c5c3_IsBuffer {
33
+
defer func() {
34
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
35
+
if templ_7745c5c3_Err == nil {
36
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
37
+
}
38
+
}()
39
}
40
ctx = templ.InitializeContext(ctx)
41
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
···
43
templ_7745c5c3_Var1 = templ.NopComponent
44
}
45
ctx = templ.ClearChildren(ctx)
46
+
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
47
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
48
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
49
if !templ_7745c5c3_IsBuffer {
50
+
defer func() {
51
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
52
+
if templ_7745c5c3_Err == nil {
53
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
54
+
}
55
+
}()
56
}
57
+
ctx = templ.InitializeContext(ctx)
58
templ_7745c5c3_Err = repoHeaderComponent(rtc.RepoHeaderComponentContext).Render(ctx, templ_7745c5c3_Buffer)
59
if templ_7745c5c3_Err != nil {
60
return templ_7745c5c3_Err
61
}
62
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, " ")
63
if templ_7745c5c3_Err != nil {
64
return templ_7745c5c3_Err
65
}
···
67
if templ_7745c5c3_Err != nil {
68
return templ_7745c5c3_Err
69
}
70
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " ")
71
if templ_7745c5c3_Err != nil {
72
return templ_7745c5c3_Err
73
}
···
75
if templ_7745c5c3_Err != nil {
76
return templ_7745c5c3_Err
77
}
78
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " ")
79
if templ_7745c5c3_Err != nil {
80
return templ_7745c5c3_Err
81
}
···
83
if templ_7745c5c3_Err != nil {
84
return templ_7745c5c3_Err
85
}
86
+
return nil
87
})
88
templ_7745c5c3_Err = base(rtc.BaseContext).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
89
if templ_7745c5c3_Err != nil {
90
return templ_7745c5c3_Err
91
}
92
+
return nil
93
})
94
}
95
···
108
}
109
110
func repoTreeComponent(rtcc RepoTreeComponentContext) templ.Component {
111
+
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
112
+
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
113
+
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
114
+
return templ_7745c5c3_CtxErr
115
+
}
116
+
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
117
if !templ_7745c5c3_IsBuffer {
118
+
defer func() {
119
+
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
120
+
if templ_7745c5c3_Err == nil {
121
+
templ_7745c5c3_Err = templ_7745c5c3_BufErr
122
+
}
123
+
}()
124
}
125
ctx = templ.InitializeContext(ctx)
126
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
···
128
templ_7745c5c3_Var3 = templ.NopComponent
129
}
130
ctx = templ.ClearChildren(ctx)
131
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<div class=\"grid grid-cols-3 sm:grid-cols-8 text-text py-5 rounded px-5 gap-x-3 gap-y-1 bg-base dark:bg-base/50\">")
132
if templ_7745c5c3_Err != nil {
133
return templ_7745c5c3_Err
134
}
135
if rtcc.Back != "" {
136
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<div class=\"col-span-2\"></div><div class=\"sm:col-span-6\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
137
if templ_7745c5c3_Err != nil {
138
return templ_7745c5c3_Err
139
}
140
+
var templ_7745c5c3_Var4 templ.SafeURL
141
+
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s", rtcc.Repo, rtcc.Ref, rtcc.Back)))
142
+
if templ_7745c5c3_Err != nil {
143
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_tree.templ`, Line: 44, Col: 194}
144
+
}
145
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
146
if templ_7745c5c3_Err != nil {
147
return templ_7745c5c3_Err
148
}
149
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\">..</a></div>")
150
if templ_7745c5c3_Err != nil {
151
return templ_7745c5c3_Err
152
}
153
}
154
for _, fi := range rtcc.Tree {
155
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<div class=\"sm:col-span-1 break-keep\">")
156
if templ_7745c5c3_Err != nil {
157
return templ_7745c5c3_Err
158
}
···
165
if templ_7745c5c3_Err != nil {
166
return templ_7745c5c3_Err
167
}
168
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</div><div class=\"sm:col-span-1 text-right\">")
169
if templ_7745c5c3_Err != nil {
170
return templ_7745c5c3_Err
171
}
···
178
if templ_7745c5c3_Err != nil {
179
return templ_7745c5c3_Err
180
}
181
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</div><div class=\"sm:col-span-6 overflow-hidden text-ellipsis\"><a class=\"underline decoration-text/50 decoration-dashed hover:decoration-solid\" href=\"")
182
if templ_7745c5c3_Err != nil {
183
return templ_7745c5c3_Err
184
}
185
+
var templ_7745c5c3_Var7 templ.SafeURL
186
+
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinURLErrs(templ.SafeURL(fmt.Sprintf("/%s/tree/%s/%s", rtcc.Repo, rtcc.Ref, fi.Path)))
187
+
if templ_7745c5c3_Err != nil {
188
+
return templ.Error{Err: templ_7745c5c3_Err, FileName: `repo_tree.templ`, Line: 49, Col: 222}
189
+
}
190
+
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
191
if templ_7745c5c3_Err != nil {
192
return templ_7745c5c3_Err
193
}
194
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\">")
195
if templ_7745c5c3_Err != nil {
196
return templ_7745c5c3_Err
197
}
···
204
if templ_7745c5c3_Err != nil {
205
return templ_7745c5c3_Err
206
}
207
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</a></div>")
208
if templ_7745c5c3_Err != nil {
209
return templ_7745c5c3_Err
210
}
211
}
212
+
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "</div>")
213
if templ_7745c5c3_Err != nil {
214
return templ_7745c5c3_Err
215
}
216
+
return nil
217
})
218
}
219
+
220
+
var _ = templruntime.GeneratedTemplate
+1
-1
internal/html/tailwind.config.js
+1
-1
internal/html/tailwind.config.js
+1
-1
internal/html/tailwind.go
+1
-1
internal/html/tailwind.go
···
5
6
func TailwindHandler(w http.ResponseWriter, r *http.Request) {
7
w.Header().Set("Content-Type", "text/css")
8
-
w.Write([]byte("/*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:\"\"}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}.latte{--ctp-rosewater:220,138,120;--ctp-flamingo:221,120,120;--ctp-pink:234,118,203;--ctp-mauve:136,57,239;--ctp-red:210,15,57;--ctp-maroon:230,69,83;--ctp-peach:254,100,11;--ctp-yellow:223,142,29;--ctp-green:64,160,43;--ctp-teal:23,146,153;--ctp-sky:4,165,229;--ctp-sapphire:32,159,181;--ctp-blue:30,102,245;--ctp-lavender:114,135,253;--ctp-text:76,79,105;--ctp-subtext1:92,95,119;--ctp-subtext0:108,111,133;--ctp-overlay2:124,127,147;--ctp-overlay1:140,143,161;--ctp-overlay0:156,160,176;--ctp-surface2:172,176,190;--ctp-surface1:188,192,204;--ctp-surface0:204,208,218;--ctp-base:239,241,245;--ctp-mantle:230,233,239;--ctp-crust:220,224,232}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.col-span-7{grid-column:span 7/span 7}.col-span-8{grid-column:span 8/span 8}.mx-5{margin-left:1.25rem;margin-right:1.25rem}.my-10{margin-top:2.5rem;margin-bottom:2.5rem}.mb-1{margin-bottom:.25rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-5{margin-left:1.25rem}.mr-1{margin-right:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-5{margin-top:1.25rem}.inline-block{display:inline-block}.inline{display:inline}.grid{display:grid}.h-5{height:1.25rem}.w-5{width:1.25rem}.max-w-7xl{max-width:80rem}.cursor-pointer{cursor:pointer}.select-all{-webkit-user-select:all;-moz-user-select:all;user-select:all}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-y-1{row-gap:.25rem}.overflow-hidden{overflow:hidden}.text-ellipsis{text-overflow:ellipsis}.whitespace-pre{white-space:pre}.break-keep{word-break:keep-all}.rounded{border-radius:.25rem}.border{border-width:1px}.border-solid{border-style:solid}.border-rosewater{--tw-border-opacity:1;border-color:rgba(var(--ctp-rosewater),var(--tw-border-opacity))}.bg-base{--tw-bg-opacity:1;background-color:rgba(var(--ctp-base),var(--tw-bg-opacity))}.bg-base\\/50{background-color:rgba(var(--ctp-base),.5)}.bg-mantle{--tw-bg-opacity:1;background-color:rgba(var(--ctp-mantle),var(--tw-bg-opacity))}.stroke-mauve{stroke:rgb(var(--ctp-mauve))}.p-1{padding:.25rem}.p-3{padding:.75rem}.p-5{padding:1.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.pb-0{padding-bottom:0}.pb-0\\.5{padding-bottom:.125rem}.text-right{text-align:right}.align-middle{vertical-align:middle}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.text-blue{--tw-text-opacity:1;color:rgba(var(--ctp-blue),var(--tw-text-opacity))}.text-mauve{--tw-text-opacity:1;color:rgba(var(--ctp-mauve),var(--tw-text-opacity))}.text-subtext0{--tw-text-opacity:1;color:rgba(var(--ctp-subtext0),var(--tw-text-opacity))}.text-subtext1{--tw-text-opacity:1;color:rgba(var(--ctp-subtext1),var(--tw-text-opacity))}.text-text{--tw-text-opacity:1;color:rgba(var(--ctp-text),var(--tw-text-opacity))}.text-text\\/80{color:rgba(var(--ctp-text),.8)}.underline{text-decoration-line:underline}.decoration-blue\\/50{text-decoration-color:rgba(var(--ctp-blue),.5)}.decoration-mauve\\/50{text-decoration-color:rgba(var(--ctp-mauve),.5)}.decoration-text\\/50{text-decoration-color:rgba(var(--ctp-text),.5)}.decoration-dashed{text-decoration-style:dashed}.markdown *{all:revert-layer;color:rgb(var(--ctp-text))}.markdown code,.markdown pre{background-color:rgb(var(--ctp-base))}.markdown a{color:rgb(var(--ctp-blue));text-decoration-line:underline;text-decoration-style:dashed}.markdown a:hover{text-decoration-style:solid}.markdown .chroma{border-radius:.25rem;padding:.75rem}.chroma *{background-color:rgb(var(--ctp-base))!important}.chroma table{border-spacing:5px 0!important}.chroma .lnt{color:rgb(var(--ctp-subtext1))!important}.chroma .lnt:focus,.chroma .lnt:target{color:rgb(var(--ctp-subtext0))!important}.chroma .line.active,.chroma .line.active *{background:rgb(var(--ctp-surface0))!important}.code>.chroma{overflow:scroll;border-radius:.25rem;padding:.75rem;font-size:.875rem;line-height:1.25rem}.chroma .line{overflow:scroll}.bg,.chroma{color:#4c4f69;background-color:#eff1f5}.chroma .lntd:last-child{width:100%}.chroma .ln:target,.chroma .lnt:target{color:#bcc0cc;background-color:#eff1f5}.chroma .err{color:#d20f39}.chroma .lnlinks{outline:none;text-decoration:none;color:inherit}.chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}.chroma .lntable{border-spacing:0;padding:0;margin:0;border:0}.chroma .hl{color:#bcc0cc}.chroma .ln,.chroma .lnt{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#8c8fa1}.chroma .line{display:flex}.chroma .k{color:#8839ef}.chroma .kc{color:#fe640b}.chroma .kd{color:#d20f39}.chroma .kn{color:#179299}.chroma .kp,.chroma .kr{color:#8839ef}.chroma .kt{color:#d20f39}.chroma .na{color:#1e66f5}.chroma .bp,.chroma .nb{color:#04a5e5}.chroma .nc,.chroma .no{color:#df8e1d}.chroma .nd{color:#1e66f5;font-weight:700}.chroma .ni{color:#179299}.chroma .ne{color:#fe640b}.chroma .fm,.chroma .nf{color:#1e66f5}.chroma .nl{color:#04a5e5}.chroma .nn,.chroma .py{color:#fe640b}.chroma .nt{color:#8839ef}.chroma .nv,.chroma .vc,.chroma .vg,.chroma .vi,.chroma .vm{color:#dc8a78}.chroma .s{color:#40a02b}.chroma .sa{color:#d20f39}.chroma .sb,.chroma .sc{color:#40a02b}.chroma .dl{color:#1e66f5}.chroma .sd{color:#9ca0b0}.chroma .s2{color:#40a02b}.chroma .se{color:#1e66f5}.chroma .sh{color:#9ca0b0}.chroma .si,.chroma .sx{color:#40a02b}.chroma .sr{color:#179299}.chroma .s1,.chroma .ss{color:#40a02b}.chroma .il,.chroma .m,.chroma .mb,.chroma .mf,.chroma .mh,.chroma .mi,.chroma .mo{color:#fe640b}.chroma .o,.chroma .ow{color:#04a5e5;font-weight:700}.chroma .c,.chroma .c1,.chroma .ch,.chroma .cm,.chroma .cp,.chroma .cpf,.chroma .cs{color:#9ca0b0;font-style:italic}.chroma .cpf{font-weight:700}.chroma .gd{color:#d20f39;background-color:#ccd0da}.chroma .ge{font-style:italic}.chroma .gr{color:#d20f39}.chroma .gh{color:#fe640b;font-weight:700}.chroma .gi{color:#40a02b;background-color:#ccd0da}.chroma .gs,.chroma .gu{font-weight:700}.chroma .gu{color:#fe640b}.chroma .gt{color:#d20f39}.chroma .gl{text-decoration:underline}@media (prefers-color-scheme:dark){.bg,.chroma{color:#cdd6f4;background-color:#1e1e2e}.chroma .lntd:last-child{width:100%}.chroma .ln:target,.chroma .lnt:target{color:#45475a;background-color:#1e1e2e}.chroma .err{color:#f38ba8}.chroma .lnlinks{outline:none;text-decoration:none;color:inherit}.chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}.chroma .lntable{border-spacing:0;padding:0;margin:0;border:0}.chroma .hl{color:#45475a}.chroma .ln,.chroma .lnt{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f849c}.chroma .line{display:flex}.chroma .k{color:#cba6f7}.chroma .kc{color:#fab387}.chroma .kd{color:#f38ba8}.chroma .kn{color:#94e2d5}.chroma .kp,.chroma .kr{color:#cba6f7}.chroma .kt{color:#f38ba8}.chroma .na{color:#89b4fa}.chroma .bp,.chroma .nb{color:#89dceb}.chroma .nc,.chroma .no{color:#f9e2af}.chroma .nd{color:#89b4fa;font-weight:700}.chroma .ni{color:#94e2d5}.chroma .ne{color:#fab387}.chroma .fm,.chroma .nf{color:#89b4fa}.chroma .nl{color:#89dceb}.chroma .nn,.chroma .py{color:#fab387}.chroma .nt{color:#cba6f7}.chroma .nv,.chroma .vc,.chroma .vg,.chroma .vi,.chroma .vm{color:#f5e0dc}.chroma .s{color:#a6e3a1}.chroma .sa{color:#f38ba8}.chroma .sb,.chroma .sc{color:#a6e3a1}.chroma .dl{color:#89b4fa}.chroma .sd{color:#6c7086}.chroma .s2{color:#a6e3a1}.chroma .se{color:#89b4fa}.chroma .sh{color:#6c7086}.chroma .si,.chroma .sx{color:#a6e3a1}.chroma .sr{color:#94e2d5}.chroma .s1,.chroma .ss{color:#a6e3a1}.chroma .il,.chroma .m,.chroma .mb,.chroma .mf,.chroma .mh,.chroma .mi,.chroma .mo{color:#fab387}.chroma .o,.chroma .ow{color:#89dceb;font-weight:700}.chroma .c,.chroma .c1,.chroma .ch,.chroma .cm,.chroma .cp,.chroma .cpf,.chroma .cs{color:#6c7086;font-style:italic}.chroma .cpf{font-weight:700}.chroma .gd{color:#f38ba8;background-color:#313244}.chroma .ge{font-style:italic}.chroma .gr{color:#f38ba8}.chroma .gh{color:#fab387;font-weight:700}.chroma .gi{color:#a6e3a1;background-color:#313244}.chroma .gs,.chroma .gu{font-weight:700}.chroma .gu{color:#fab387}.chroma .gt{color:#f38ba8}.chroma .gl{text-decoration:underline}.dark\\:mocha{--ctp-rosewater:245,224,220;--ctp-flamingo:242,205,205;--ctp-pink:245,194,231;--ctp-mauve:203,166,247;--ctp-red:243,139,168;--ctp-maroon:235,160,172;--ctp-peach:250,179,135;--ctp-yellow:249,226,175;--ctp-green:166,227,161;--ctp-teal:148,226,213;--ctp-sky:137,220,235;--ctp-sapphire:116,199,236;--ctp-blue:137,180,250;--ctp-lavender:180,190,254;--ctp-text:205,214,244;--ctp-subtext1:186,194,222;--ctp-subtext0:166,173,200;--ctp-overlay2:147,153,178;--ctp-overlay1:127,132,156;--ctp-overlay0:108,112,134;--ctp-surface2:88,91,112;--ctp-surface1:69,71,90;--ctp-surface0:49,50,68;--ctp-base:30,30,46;--ctp-mantle:24,24,37;--ctp-crust:17,17,27}}.hover\\:decoration-solid:hover{text-decoration-style:solid}.focus\\:border-lavender:focus{--tw-border-opacity:1;border-color:rgba(var(--ctp-lavender),var(--tw-border-opacity))}.focus\\:outline-none:focus{outline:2px solid #0000;outline-offset:2px}.focus\\:ring-0:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}@media (prefers-color-scheme:dark){.dark\\:bg-base\\/50{background-color:rgba(var(--ctp-base),.5)}.dark\\:bg-base\\/95{background-color:rgba(var(--ctp-base),.95)}.dark\\:text-lavender{--tw-text-opacity:1;color:rgba(var(--ctp-lavender),var(--tw-text-opacity))}.dark\\:decoration-lavender\\/50{text-decoration-color:rgba(var(--ctp-lavender),.5)}}@media (min-width:640px){.sm\\:col-span-1{grid-column:span 1/span 1}.sm\\:col-span-2{grid-column:span 2/span 2}.sm\\:col-span-3{grid-column:span 3/span 3}.sm\\:col-span-4{grid-column:span 4/span 4}.sm\\:col-span-5{grid-column:span 5/span 5}.sm\\:col-span-6{grid-column:span 6/span 6}.sm\\:col-span-7{grid-column:span 7/span 7}.sm\\:mx-auto{margin-left:auto;margin-right:auto}.sm\\:mb-0{margin-bottom:0}.sm\\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}}"))
9
}
···
5
6
func TailwindHandler(w http.ResponseWriter, r *http.Request) {
7
w.Header().Set("Content-Type", "text/css")
8
+
w.Write([]byte("/*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:\"\"}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}.latte{--ctp-rosewater:220,138,120;--ctp-flamingo:221,120,120;--ctp-pink:234,118,203;--ctp-mauve:136,57,239;--ctp-red:210,15,57;--ctp-maroon:230,69,83;--ctp-peach:254,100,11;--ctp-yellow:223,142,29;--ctp-green:64,160,43;--ctp-teal:23,146,153;--ctp-sky:4,165,229;--ctp-sapphire:32,159,181;--ctp-blue:30,102,245;--ctp-lavender:114,135,253;--ctp-text:76,79,105;--ctp-subtext1:92,95,119;--ctp-subtext0:108,111,133;--ctp-overlay2:124,127,147;--ctp-overlay1:140,143,161;--ctp-overlay0:156,160,176;--ctp-surface2:172,176,190;--ctp-surface1:188,192,204;--ctp-surface0:204,208,218;--ctp-base:239,241,245;--ctp-mantle:230,233,239;--ctp-crust:220,224,232}.mocha{--ctp-rosewater:245,224,220;--ctp-flamingo:242,205,205;--ctp-pink:245,194,231;--ctp-mauve:203,166,247;--ctp-red:243,139,168;--ctp-maroon:235,160,172;--ctp-peach:250,179,135;--ctp-yellow:249,226,175;--ctp-green:166,227,161;--ctp-teal:148,226,213;--ctp-sky:137,220,235;--ctp-sapphire:116,199,236;--ctp-blue:137,180,250;--ctp-lavender:180,190,254;--ctp-text:205,214,244;--ctp-subtext1:186,194,222;--ctp-subtext0:166,173,200;--ctp-overlay2:147,153,178;--ctp-overlay1:127,132,156;--ctp-overlay0:108,112,134;--ctp-surface2:88,91,112;--ctp-surface1:69,71,90;--ctp-surface0:49,50,68;--ctp-base:30,30,46;--ctp-mantle:24,24,37;--ctp-crust:17,17,27}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.absolute{position:absolute}.relative{position:relative}.right-0{right:0}.start-1{inset-inline-start:.25rem}.top-0{top:0}.col-span-1{grid-column:span 1/span 1}.col-span-2{grid-column:span 2/span 2}.col-span-7{grid-column:span 7/span 7}.col-span-8{grid-column:span 8/span 8}.mx-5{margin-left:1.25rem;margin-right:1.25rem}.my-10{margin-top:2.5rem;margin-bottom:2.5rem}.mb-1{margin-bottom:.25rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-5{margin-left:1.25rem}.mr-1{margin-right:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-5{margin-top:1.25rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.grid{display:grid}.hidden{display:none}.h-5{height:1.25rem}.w-5{width:1.25rem}.max-w-7xl{max-width:80rem}.cursor-pointer{cursor:pointer}.select-all{-webkit-user-select:all;-moz-user-select:all;user-select:all}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-x-3{-moz-column-gap:.75rem;column-gap:.75rem}.gap-y-1{row-gap:.25rem}.overflow-hidden{overflow:hidden}.text-ellipsis{text-overflow:ellipsis}.whitespace-pre{white-space:pre}.break-keep{word-break:keep-all}.rounded{border-radius:.25rem}.border{border-width:1px}.border-solid{border-style:solid}.border-rosewater{--tw-border-opacity:1;border-color:rgba(var(--ctp-rosewater),var(--tw-border-opacity))}.bg-base{--tw-bg-opacity:1;background-color:rgba(var(--ctp-base),var(--tw-bg-opacity))}.bg-base\\/50{background-color:rgba(var(--ctp-base),.5)}.bg-mantle{--tw-bg-opacity:1;background-color:rgba(var(--ctp-mantle),var(--tw-bg-opacity))}.stroke-mauve{stroke:rgb(var(--ctp-mauve))}.p-1{padding:.25rem}.p-3{padding:.75rem}.p-5{padding:1.25rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-5{padding-top:1.25rem;padding-bottom:1.25rem}.pb-0{padding-bottom:0}.pb-0\\.5{padding-bottom:.125rem}.text-right{text-align:right}.align-middle{vertical-align:middle}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.text-blue{--tw-text-opacity:1;color:rgba(var(--ctp-blue),var(--tw-text-opacity))}.text-mauve{--tw-text-opacity:1;color:rgba(var(--ctp-mauve),var(--tw-text-opacity))}.text-subtext0{--tw-text-opacity:1;color:rgba(var(--ctp-subtext0),var(--tw-text-opacity))}.text-subtext1{--tw-text-opacity:1;color:rgba(var(--ctp-subtext1),var(--tw-text-opacity))}.text-text{--tw-text-opacity:1;color:rgba(var(--ctp-text),var(--tw-text-opacity))}.text-text\\/80{color:rgba(var(--ctp-text),.8)}.underline{text-decoration-line:underline}.decoration-blue\\/50{text-decoration-color:rgba(var(--ctp-blue),.5)}.decoration-mauve\\/50{text-decoration-color:rgba(var(--ctp-mauve),.5)}.decoration-text\\/50{text-decoration-color:rgba(var(--ctp-text),.5)}.decoration-dashed{text-decoration-style:dashed}.markdown *{all:revert-layer;color:rgb(var(--ctp-text))}.markdown code,.markdown pre{background-color:rgb(var(--ctp-base))}.markdown a{color:rgb(var(--ctp-blue));text-decoration-line:underline;text-decoration-style:dashed}.markdown a:hover{text-decoration-style:solid}.markdown .chroma{border-radius:.25rem;padding:.75rem}.chroma *{background-color:rgb(var(--ctp-base))!important}.chroma table{border-spacing:5px 0!important}.chroma .lnt{color:rgb(var(--ctp-subtext1))!important}.chroma .lnt:focus,.chroma .lnt:target{color:rgb(var(--ctp-subtext0))!important}.chroma .line.active,.chroma .line.active *{background:rgb(var(--ctp-surface0))!important}.code>.chroma{overflow:scroll;border-radius:.25rem;padding:.75rem;font-size:.875rem;line-height:1.25rem}.bg,.chroma{color:#4c4f69;background-color:#eff1f5}.chroma .lntd:last-child{width:100%}.chroma .ln:target,.chroma .lnt:target{color:#4c4f69;background-color:#bcc0cc}.chroma .err{color:#d20f39}.chroma .lnlinks{outline:none;text-decoration:none;color:inherit}.chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}.chroma .lntable{border-spacing:0;padding:0;margin:0;border:0}.chroma .hl{background-color:#bcc0cc}.chroma .ln,.chroma .lnt{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#8c8fa1}.chroma .line{display:flex}.chroma .k{color:#8839ef}.chroma .kc{color:#fe640b}.chroma .kd{color:#d20f39}.chroma .kn{color:#179299}.chroma .kp,.chroma .kr{color:#8839ef}.chroma .kt{color:#d20f39}.chroma .na{color:#1e66f5}.chroma .bp,.chroma .nb{color:#04a5e5}.chroma .nc,.chroma .no{color:#df8e1d}.chroma .nd{color:#1e66f5;font-weight:700}.chroma .ni{color:#179299}.chroma .ne{color:#fe640b}.chroma .fm,.chroma .nf{color:#1e66f5}.chroma .nl{color:#04a5e5}.chroma .nn,.chroma .py{color:#fe640b}.chroma .nt{color:#8839ef}.chroma .nv,.chroma .vc,.chroma .vg,.chroma .vi,.chroma .vm{color:#dc8a78}.chroma .s{color:#40a02b}.chroma .sa{color:#d20f39}.chroma .sb,.chroma .sc{color:#40a02b}.chroma .dl{color:#1e66f5}.chroma .sd{color:#9ca0b0}.chroma .s2{color:#40a02b}.chroma .se{color:#1e66f5}.chroma .sh{color:#9ca0b0}.chroma .si,.chroma .sx{color:#40a02b}.chroma .sr{color:#179299}.chroma .s1,.chroma .ss{color:#40a02b}.chroma .il,.chroma .m,.chroma .mb,.chroma .mf,.chroma .mh,.chroma .mi,.chroma .mo{color:#fe640b}.chroma .o,.chroma .ow{color:#04a5e5;font-weight:700}.chroma .c,.chroma .c1,.chroma .ch,.chroma .cm,.chroma .cp,.chroma .cpf,.chroma .cs{color:#9ca0b0;font-style:italic}.chroma .cpf{font-weight:700}.chroma .gd{color:#d20f39;background-color:#ccd0da}.chroma .ge{font-style:italic}.chroma .gr{color:#d20f39}.chroma .gh{color:#fe640b;font-weight:700}.chroma .gi{color:#40a02b;background-color:#ccd0da}.chroma .gs,.chroma .gu{font-weight:700}.chroma .gu{color:#fe640b}.chroma .gt{color:#d20f39}.chroma .gl{text-decoration:underline}@media (prefers-color-scheme:dark){.bg,.chroma{color:#cdd6f4;background-color:#1e1e2e}.chroma .lntd:last-child{width:100%}.chroma .ln:target,.chroma .lnt:target{color:#cdd6f4;background-color:#45475a}.chroma .err{color:#f38ba8}.chroma .lnlinks{outline:none;text-decoration:none;color:inherit}.chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}.chroma .lntable{border-spacing:0;padding:0;margin:0;border:0}.chroma .hl{background-color:#45475a}.chroma .ln,.chroma .lnt{white-space:pre;-webkit-user-select:none;-moz-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#7f849c}.chroma .line{display:flex}.chroma .k{color:#cba6f7}.chroma .kc{color:#fab387}.chroma .kd{color:#f38ba8}.chroma .kn{color:#94e2d5}.chroma .kp,.chroma .kr{color:#cba6f7}.chroma .kt{color:#f38ba8}.chroma .na{color:#89b4fa}.chroma .bp,.chroma .nb{color:#89dceb}.chroma .nc,.chroma .no{color:#f9e2af}.chroma .nd{color:#89b4fa;font-weight:700}.chroma .ni{color:#94e2d5}.chroma .ne{color:#fab387}.chroma .fm,.chroma .nf{color:#89b4fa}.chroma .nl{color:#89dceb}.chroma .nn,.chroma .py{color:#fab387}.chroma .nt{color:#cba6f7}.chroma .nv,.chroma .vc,.chroma .vg,.chroma .vi,.chroma .vm{color:#f5e0dc}.chroma .s{color:#a6e3a1}.chroma .sa{color:#f38ba8}.chroma .sb,.chroma .sc{color:#a6e3a1}.chroma .dl{color:#89b4fa}.chroma .sd{color:#6c7086}.chroma .s2{color:#a6e3a1}.chroma .se{color:#89b4fa}.chroma .sh{color:#6c7086}.chroma .si,.chroma .sx{color:#a6e3a1}.chroma .sr{color:#94e2d5}.chroma .s1,.chroma .ss{color:#a6e3a1}.chroma .il,.chroma .m,.chroma .mb,.chroma .mf,.chroma .mh,.chroma .mi,.chroma .mo{color:#fab387}.chroma .o,.chroma .ow{color:#89dceb;font-weight:700}.chroma .c,.chroma .c1,.chroma .ch,.chroma .cm,.chroma .cp,.chroma .cpf,.chroma .cs{color:#6c7086;font-style:italic}.chroma .cpf{font-weight:700}.chroma .gd{color:#f38ba8;background-color:#313244}.chroma .ge{font-style:italic}.chroma .gr{color:#f38ba8}.chroma .gh{color:#fab387;font-weight:700}.chroma .gi{color:#a6e3a1;background-color:#313244}.chroma .gs,.chroma .gu{font-weight:700}.chroma .gu{color:#fab387}.chroma .gt{color:#f38ba8}.chroma .gl{text-decoration:underline}.dark\\:mocha{--ctp-rosewater:245,224,220;--ctp-flamingo:242,205,205;--ctp-pink:245,194,231;--ctp-mauve:203,166,247;--ctp-red:243,139,168;--ctp-maroon:235,160,172;--ctp-peach:250,179,135;--ctp-yellow:249,226,175;--ctp-green:166,227,161;--ctp-teal:148,226,213;--ctp-sky:137,220,235;--ctp-sapphire:116,199,236;--ctp-blue:137,180,250;--ctp-lavender:180,190,254;--ctp-text:205,214,244;--ctp-subtext1:186,194,222;--ctp-subtext0:166,173,200;--ctp-overlay2:147,153,178;--ctp-overlay1:127,132,156;--ctp-overlay0:108,112,134;--ctp-surface2:88,91,112;--ctp-surface1:69,71,90;--ctp-surface0:49,50,68;--ctp-base:30,30,46;--ctp-mantle:24,24,37;--ctp-crust:17,17,27}}.hover\\:bg-surface0:hover{--tw-bg-opacity:1;background-color:rgba(var(--ctp-surface0),var(--tw-bg-opacity))}.hover\\:decoration-solid:hover{text-decoration-style:solid}.focus\\:border-lavender:focus{--tw-border-opacity:1;border-color:rgba(var(--ctp-lavender),var(--tw-border-opacity))}.focus\\:outline-none:focus{outline:2px solid #0000;outline-offset:2px}.focus\\:ring-0:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}@media (prefers-color-scheme:dark){.dark\\:bg-base\\/50{background-color:rgba(var(--ctp-base),.5)}.dark\\:bg-base\\/95{background-color:rgba(var(--ctp-base),.95)}.dark\\:text-lavender{--tw-text-opacity:1;color:rgba(var(--ctp-lavender),var(--tw-text-opacity))}.dark\\:decoration-lavender\\/50{text-decoration-color:rgba(var(--ctp-lavender),.5)}}@media (min-width:640px){.sm\\:col-span-1{grid-column:span 1/span 1}.sm\\:col-span-2{grid-column:span 2/span 2}.sm\\:col-span-3{grid-column:span 3/span 3}.sm\\:col-span-5{grid-column:span 5/span 5}.sm\\:col-span-6{grid-column:span 6/span 6}.sm\\:col-span-7{grid-column:span 7/span 7}.sm\\:mx-auto{margin-left:auto;margin-right:auto}.sm\\:mb-0{margin-bottom:0}.sm\\:grid-cols-10{grid-template-columns:repeat(10,minmax(0,1fr))}.sm\\:grid-cols-8{grid-template-columns:repeat(8,minmax(0,1fr))}}"))
9
}
+5
-4
internal/http/http.go
+5
-4
internal/http/http.go
···
18
// Server is the container struct for the HTTP server
19
type Server struct {
20
port int
21
-
mux *chi.Mux
22
}
23
24
// ListenAndServe simply wraps http.ListenAndServe to contain the functionality here
25
func (s Server) ListenAndServe() error {
26
-
return http.ListenAndServe(fmt.Sprintf("localhost:%d", s.port), s.mux)
27
}
28
29
// Settings is the configuration for the HTTP server
···
34
Port int
35
RepoDir string
36
Profile Profile
37
}
38
39
// Profile is the index profile
···
101
r.Get("/tailwind.css", html.TailwindHandler)
102
})
103
104
-
return Server{mux: mux, port: settings.Port}
105
}
106
107
type repoHandler struct {
···
125
Name: chi.URLParam(r, "repo"),
126
Ref: ref,
127
CloneURL: rh.s.CloneURL,
128
-
Tags: repo.Meta.Tags,
129
}
130
}
131
···
18
// Server is the container struct for the HTTP server
19
type Server struct {
20
port int
21
+
Mux *chi.Mux
22
}
23
24
// ListenAndServe simply wraps http.ListenAndServe to contain the functionality here
25
func (s Server) ListenAndServe() error {
26
+
return http.ListenAndServe(fmt.Sprintf("localhost:%d", s.port), s.Mux)
27
}
28
29
// Settings is the configuration for the HTTP server
···
34
Port int
35
RepoDir string
36
Profile Profile
37
+
ShowPrivate bool
38
}
39
40
// Profile is the index profile
···
102
r.Get("/tailwind.css", html.TailwindHandler)
103
})
104
105
+
return Server{Mux: mux, port: settings.Port}
106
}
107
108
type repoHandler struct {
···
126
Name: chi.URLParam(r, "repo"),
127
Ref: ref,
128
CloneURL: rh.s.CloneURL,
129
+
Tags: repo.Meta.Tags.Slice(),
130
}
131
}
132
+2
-3
internal/http/httperr/httperr.go
+2
-3
internal/http/httperr/httperr.go
+122
internal/http/httperr/httperr_test.go
+122
internal/http/httperr/httperr_test.go
···
···
1
+
package httperr_test
2
+
3
+
import (
4
+
"errors"
5
+
"net/http"
6
+
"net/http/httptest"
7
+
"testing"
8
+
9
+
"github.com/alecthomas/assert/v2"
10
+
"go.jolheiser.com/ugit/internal/http/httperr"
11
+
)
12
+
13
+
func successHandler(w http.ResponseWriter, r *http.Request) error {
14
+
w.WriteHeader(http.StatusOK)
15
+
return nil
16
+
}
17
+
18
+
func errorHandler(w http.ResponseWriter, r *http.Request) error {
19
+
return errors.New("test error")
20
+
}
21
+
22
+
func statusErrorHandler(status int) func(w http.ResponseWriter, r *http.Request) error {
23
+
return func(w http.ResponseWriter, r *http.Request) error {
24
+
return httperr.Status(errors.New("test error"), status)
25
+
}
26
+
}
27
+
28
+
func TestHandler_Success(t *testing.T) {
29
+
handler := httperr.Handler(successHandler)
30
+
31
+
req := httptest.NewRequest("GET", "/", nil)
32
+
recorder := httptest.NewRecorder()
33
+
34
+
handler.ServeHTTP(recorder, req)
35
+
36
+
assert.Equal(t, http.StatusOK, recorder.Code)
37
+
}
38
+
39
+
func TestHandler_Error(t *testing.T) {
40
+
handler := httperr.Handler(errorHandler)
41
+
42
+
req := httptest.NewRequest("GET", "/", nil)
43
+
recorder := httptest.NewRecorder()
44
+
45
+
handler.ServeHTTP(recorder, req)
46
+
47
+
assert.Equal(t, http.StatusInternalServerError, recorder.Code)
48
+
}
49
+
50
+
func TestHandler_StatusError(t *testing.T) {
51
+
testCases := []struct {
52
+
name string
53
+
status int
54
+
expectedStatus int
55
+
}{
56
+
{
57
+
name: "not found",
58
+
status: http.StatusNotFound,
59
+
expectedStatus: http.StatusNotFound,
60
+
},
61
+
{
62
+
name: "bad request",
63
+
status: http.StatusBadRequest,
64
+
expectedStatus: http.StatusBadRequest,
65
+
},
66
+
{
67
+
name: "unauthorized",
68
+
status: http.StatusUnauthorized,
69
+
expectedStatus: http.StatusUnauthorized,
70
+
},
71
+
}
72
+
73
+
for _, tc := range testCases {
74
+
t.Run(tc.name, func(t *testing.T) {
75
+
handler := httperr.Handler(statusErrorHandler(tc.status))
76
+
77
+
req := httptest.NewRequest("GET", "/", nil)
78
+
recorder := httptest.NewRecorder()
79
+
80
+
handler.ServeHTTP(recorder, req)
81
+
82
+
assert.Equal(t, tc.expectedStatus, recorder.Code)
83
+
})
84
+
}
85
+
}
86
+
87
+
type unwrapper interface {
88
+
Unwrap() error
89
+
}
90
+
91
+
func TestError(t *testing.T) {
92
+
originalErr := errors.New("original error")
93
+
httpErr := httperr.Error(originalErr)
94
+
95
+
assert.Equal(t, originalErr.Error(), httpErr.Error())
96
+
97
+
unwrapper, ok := any(httpErr).(unwrapper)
98
+
assert.True(t, ok)
99
+
assert.Equal(t, originalErr, unwrapper.Unwrap())
100
+
}
101
+
102
+
func TestStatus(t *testing.T) {
103
+
originalErr := errors.New("original error")
104
+
httpErr := httperr.Status(originalErr, http.StatusNotFound)
105
+
106
+
assert.Equal(t, originalErr.Error(), httpErr.Error())
107
+
108
+
unwrapper, ok := any(httpErr).(unwrapper)
109
+
assert.True(t, ok)
110
+
assert.Equal(t, originalErr, unwrapper.Unwrap())
111
+
112
+
handler := httperr.Handler(func(w http.ResponseWriter, r *http.Request) error {
113
+
return httpErr
114
+
})
115
+
116
+
req := httptest.NewRequest("GET", "/", nil)
117
+
recorder := httptest.NewRecorder()
118
+
119
+
handler.ServeHTTP(recorder, req)
120
+
121
+
assert.Equal(t, http.StatusNotFound, recorder.Code)
122
+
}
+6
-3
internal/http/index.go
+6
-3
internal/http/index.go
···
3
import (
4
"net/http"
5
"os"
6
"sort"
7
"strings"
8
"time"
···
30
return httperr.Error(err)
31
}
32
if repo.Meta.Private {
33
+
if !rh.s.ShowPrivate {
34
+
continue
35
+
}
36
+
repo.Meta.Tags.Add("private")
37
}
38
+
39
+
if tagFilter != "" && !repo.Meta.Tags.Contains(strings.ToLower(tagFilter)) {
40
continue
41
}
42
repos = append(repos, repo)
+4
-1
internal/http/middleware.go
+4
-1
internal/http/middleware.go
···
27
return httperr.Status(err, httpErr)
28
}
29
if repo.Meta.Private {
30
+
if !rh.s.ShowPrivate {
31
+
return httperr.Status(errors.New("could not get git repo"), http.StatusNotFound)
32
+
}
33
+
repo.Meta.Tags.Add("private")
34
}
35
r = r.WithContext(context.WithValue(r.Context(), repoCtxKey, repo))
36
next.ServeHTTP(w, r)
+12
-3
internal/http/repo.go
+12
-3
internal/http/repo.go
···
88
}
89
90
var buf bytes.Buffer
91
-
if err := markup.Code.Convert([]byte(content), filepath.Base(path), &buf); err != nil {
92
return httperr.Error(err)
93
}
94
95
if err := html.RepoFile(html.RepoFileContext{
96
BaseContext: rh.baseContext(),
97
RepoHeaderComponentContext: rh.repoHeaderContext(repo, r),
98
RepoBreadcrumbComponentContext: rh.repoBreadcrumbContext(repo, r, path),
99
Code: buf.String(),
100
}).Render(r.Context(), w); err != nil {
101
return httperr.Error(err)
102
}
···
158
159
for idx, p := range commit.Files {
160
var patch bytes.Buffer
161
-
if err := markup.Code.Basic([]byte(p.Patch), "commit.patch", &patch); err != nil {
162
return httperr.Error(err)
163
}
164
commit.Files[idx].Patch = patch.String()
···
206
}
207
results[idx].Content = buf.String()
208
}
209
-
210
}
211
212
if err := html.RepoSearch(html.SearchContext{
···
88
}
89
90
var buf bytes.Buffer
91
+
if err := markup.Convert([]byte(content), filepath.Base(path), "L", &buf); err != nil {
92
return httperr.Error(err)
93
}
94
95
+
commit := ref
96
+
if len(ref) < 40 {
97
+
commitObj, err := repo.GetCommitFromRef(ref)
98
+
if err == nil {
99
+
commit = commitObj.Hash.String()
100
+
}
101
+
}
102
+
103
if err := html.RepoFile(html.RepoFileContext{
104
BaseContext: rh.baseContext(),
105
RepoHeaderComponentContext: rh.repoHeaderContext(repo, r),
106
RepoBreadcrumbComponentContext: rh.repoBreadcrumbContext(repo, r, path),
107
Code: buf.String(),
108
+
Commit: commit,
109
+
Path: path,
110
}).Render(r.Context(), w); err != nil {
111
return httperr.Error(err)
112
}
···
168
169
for idx, p := range commit.Files {
170
var patch bytes.Buffer
171
+
if err := markup.Convert([]byte(p.Patch), "commit.patch", p.Path()+"-L", &patch); err != nil {
172
return httperr.Error(err)
173
}
174
commit.Files[idx].Patch = patch.String()
···
216
}
217
results[idx].Content = buf.String()
218
}
219
}
220
221
if err := html.RepoSearch(html.SearchContext{
-37
internal/ssh/form.go
-37
internal/ssh/form.go
···
1
-
package ssh
2
-
3
-
import (
4
-
"strings"
5
-
6
-
"github.com/charmbracelet/huh"
7
-
"go.jolheiser.com/ugit/internal/git"
8
-
)
9
-
10
-
type stringSliceAccessor []string
11
-
12
-
func (s stringSliceAccessor) Get() string {
13
-
return strings.Join(s, "\n")
14
-
}
15
-
16
-
func (s stringSliceAccessor) Set(value string) {
17
-
s = strings.Split(value, "\n")
18
-
}
19
-
20
-
func newForm(meta git.RepoMeta) *huh.Form {
21
-
return huh.NewForm(
22
-
huh.NewGroup(
23
-
huh.NewText().
24
-
Title("Description").
25
-
Value(&meta.Description),
26
-
huh.NewConfirm().
27
-
Title("Visibility").
28
-
Affirmative("Public").
29
-
Negative("Private").
30
-
Value(&meta.Private),
31
-
huh.NewText().
32
-
Title("Tags").
33
-
Description("One per line").
34
-
Accessor(stringSliceAccessor(meta.Tags)),
35
-
),
36
-
)
37
-
}
···
+2
-2
internal/ssh/ssh.go
+2
-2
internal/ssh/ssh.go
···
2
3
import (
4
"fmt"
5
6
-
"github.com/charmbracelet/log"
7
"github.com/charmbracelet/ssh"
8
"github.com/charmbracelet/wish"
9
"github.com/charmbracelet/wish/logging"
···
42
func (a hooks) Fetch(_ string, _ ssh.PublicKey) {}
43
44
var (
45
-
DefaultLogger logging.Logger = log.StandardLog()
46
NoopLogger logging.Logger = noopLogger{}
47
)
48
···
2
3
import (
4
"fmt"
5
+
"log"
6
7
"github.com/charmbracelet/ssh"
8
"github.com/charmbracelet/wish"
9
"github.com/charmbracelet/wish/logging"
···
42
func (a hooks) Fetch(_ string, _ ssh.PublicKey) {}
43
44
var (
45
+
DefaultLogger logging.Logger = log.Default()
46
NoopLogger logging.Logger = noopLogger{}
47
)
48
+3
-13
internal/ssh/wish.go
+3
-13
internal/ssh/wish.go
···
5
"errors"
6
"fmt"
7
"io/fs"
8
"os"
9
"path/filepath"
10
"strings"
···
12
13
"go.jolheiser.com/ugit/internal/git"
14
15
-
"github.com/charmbracelet/log"
16
"github.com/charmbracelet/ssh"
17
"github.com/charmbracelet/wish"
18
)
···
91
if errors.Is(err, ErrInvalidRepo) {
92
Fatal(s, ErrInvalidRepo)
93
}
94
-
log.Error("unknown git error", "error", err)
95
Fatal(s, ErrSystemMalfunction)
96
}
97
gh.Fetch(repo, pk)
···
103
if len(cmd) == 0 {
104
des, err := os.ReadDir(repoDir)
105
if err != nil && err != fs.ErrNotExist {
106
-
log.Error("invalid repository", "error", err)
107
}
108
tw := tabwriter.NewWriter(s, 0, 0, 1, ' ', 0)
109
for _, de := range des {
···
122
}
123
tw.Flush()
124
}
125
-
126
-
// Edit repo
127
-
if len(cmd) == 1 {
128
-
repo, err := git.NewRepo(cmd[0])
129
-
if err != nil {
130
-
Fatal(s, ErrInvalidRepo)
131
-
}
132
-
133
-
}
134
-
135
sh(s)
136
}
137
}
···
5
"errors"
6
"fmt"
7
"io/fs"
8
+
"log/slog"
9
"os"
10
"path/filepath"
11
"strings"
···
13
14
"go.jolheiser.com/ugit/internal/git"
15
16
"github.com/charmbracelet/ssh"
17
"github.com/charmbracelet/wish"
18
)
···
91
if errors.Is(err, ErrInvalidRepo) {
92
Fatal(s, ErrInvalidRepo)
93
}
94
+
slog.Error("unknown git error", "error", err)
95
Fatal(s, ErrSystemMalfunction)
96
}
97
gh.Fetch(repo, pk)
···
103
if len(cmd) == 0 {
104
des, err := os.ReadDir(repoDir)
105
if err != nil && err != fs.ErrNotExist {
106
+
slog.Error("invalid repository", "error", err)
107
}
108
tw := tabwriter.NewWriter(s, 0, 0, 1, ' ', 0)
109
for _, de := range des {
···
122
}
123
tw.Flush()
124
}
125
sh(s)
126
}
127
}
+10
nix/default.nix
+10
nix/default.nix
+228
nix/module.nix
+228
nix/module.nix
···
···
1
+
{
2
+
pkgs,
3
+
lib,
4
+
config,
5
+
...
6
+
}:
7
+
let
8
+
cfg = config.services.ugit;
9
+
pkg = pkgs.callPackage ./pkg.nix { inherit pkgs; };
10
+
yamlFormat = pkgs.formats.yaml { };
11
+
instanceOptions =
12
+
{ name, config, ... }:
13
+
let
14
+
inherit (lib) mkEnableOption mkOption types;
15
+
baseDir = "/var/lib/ugit-${name}";
16
+
in
17
+
{
18
+
options = {
19
+
enable = mkEnableOption "Enable ugit";
20
+
21
+
package = mkOption {
22
+
type = types.package;
23
+
description = "ugit package to use";
24
+
default = pkg;
25
+
};
26
+
27
+
homeDir = mkOption {
28
+
type = types.str;
29
+
description = "ugit home directory";
30
+
default = baseDir;
31
+
};
32
+
33
+
repoDir = mkOption {
34
+
type = types.str;
35
+
description = "where ugit stores repositories";
36
+
default = "${baseDir}/repos";
37
+
};
38
+
39
+
authorizedKeys = mkOption {
40
+
type = types.listOf types.str;
41
+
description = "list of keys to use for authorized_keys";
42
+
default = [ ];
43
+
};
44
+
45
+
authorizedKeysFile = mkOption {
46
+
type = types.str;
47
+
description = "path to authorized_keys file ugit uses for auth";
48
+
default = "${baseDir}/authorized_keys";
49
+
};
50
+
51
+
hostKeyFile = mkOption {
52
+
type = types.str;
53
+
description = "path to host key file (will be created if it doesn't exist)";
54
+
default = "${baseDir}/ugit_ed25519";
55
+
};
56
+
57
+
config = mkOption {
58
+
type = types.attrs;
59
+
default = { };
60
+
description = "config.yaml contents";
61
+
};
62
+
63
+
user = mkOption {
64
+
type = types.str;
65
+
default = "ugit-${name}";
66
+
description = "User account under which ugit runs";
67
+
};
68
+
69
+
group = mkOption {
70
+
type = types.str;
71
+
default = "ugit-${name}";
72
+
description = "Group account under which ugit runs";
73
+
};
74
+
75
+
hooks = mkOption {
76
+
type = types.listOf (
77
+
types.submodule {
78
+
options = {
79
+
name = mkOption {
80
+
type = types.str;
81
+
description = "Hook name";
82
+
};
83
+
content = mkOption {
84
+
type = types.str;
85
+
description = "Hook contents";
86
+
};
87
+
};
88
+
}
89
+
);
90
+
description = "A list of pre-receive hooks to run";
91
+
default = [ ];
92
+
};
93
+
};
94
+
};
95
+
in
96
+
{
97
+
options = {
98
+
services.ugit = lib.mkOption {
99
+
type = lib.types.attrsOf (lib.types.submodule instanceOptions);
100
+
default = { };
101
+
description = "Attribute set of ugit instances";
102
+
};
103
+
};
104
+
config = lib.mkIf (cfg != { }) {
105
+
users.users = lib.mapAttrs' (
106
+
name: instanceCfg:
107
+
lib.nameValuePair instanceCfg.user {
108
+
home = instanceCfg.homeDir;
109
+
createHome = true;
110
+
group = instanceCfg.group;
111
+
isSystemUser = true;
112
+
isNormalUser = false;
113
+
description = "user for ugit ${name} service";
114
+
}
115
+
) (lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg);
116
+
117
+
users.groups = lib.mapAttrs' (name: instanceCfg: lib.nameValuePair instanceCfg.group { }) (
118
+
lib.filterAttrs (name: instanceCfg: instanceCfg.enable) cfg
119
+
);
120
+
121
+
systemd.services = lib.foldl' (
122
+
acc: name:
123
+
let
124
+
instanceCfg = cfg.${name};
125
+
in
126
+
lib.recursiveUpdate acc (
127
+
lib.optionalAttrs instanceCfg.enable {
128
+
"ugit-${name}" = {
129
+
enable = true;
130
+
description = "ugit instance ${name}";
131
+
wantedBy = [ "multi-user.target" ];
132
+
after = [ "network.target" ];
133
+
path = [
134
+
instanceCfg.package
135
+
pkgs.git
136
+
pkgs.bash
137
+
];
138
+
serviceConfig = {
139
+
User = instanceCfg.user;
140
+
Group = instanceCfg.group;
141
+
Restart = "always";
142
+
RestartSec = "15";
143
+
WorkingDirectory = instanceCfg.homeDir;
144
+
ReadWritePaths = [ instanceCfg.homeDir ];
145
+
CapabilityBoundingSet = "";
146
+
NoNewPrivileges = true;
147
+
ProtectSystem = "strict";
148
+
ProtectHome = true;
149
+
PrivateTmp = true;
150
+
PrivateDevices = true;
151
+
PrivateUsers = true;
152
+
ProtectHostname = true;
153
+
ProtectClock = true;
154
+
ProtectKernelTunables = true;
155
+
ProtectKernelModules = true;
156
+
ProtectKernelLogs = true;
157
+
ProtectControlGroups = true;
158
+
RestrictAddressFamilies = [
159
+
"AF_UNIX"
160
+
"AF_INET"
161
+
"AF_INET6"
162
+
];
163
+
RestrictNamespaces = true;
164
+
LockPersonality = true;
165
+
MemoryDenyWriteExecute = true;
166
+
RestrictRealtime = true;
167
+
RestrictSUIDSGID = true;
168
+
RemoveIPC = true;
169
+
PrivateMounts = true;
170
+
SystemCallArchitectures = "native";
171
+
ExecStart =
172
+
let
173
+
configFile = pkgs.writeText "ugit-${name}.yaml" (
174
+
builtins.readFile (yamlFormat.generate "ugit-${name}-yaml" instanceCfg.config)
175
+
);
176
+
authorizedKeysFile = pkgs.writeText "ugit_${name}_keys" (
177
+
builtins.concatStringsSep "\n" instanceCfg.authorizedKeys
178
+
);
179
+
180
+
authorizedKeysPath =
181
+
if (builtins.length instanceCfg.authorizedKeys) > 0 then
182
+
authorizedKeysFile
183
+
else
184
+
instanceCfg.authorizedKeysFile;
185
+
args = [
186
+
"--config=${configFile}"
187
+
"--repo-dir=${instanceCfg.repoDir}"
188
+
"--ssh.authorized-keys=${authorizedKeysPath}"
189
+
"--ssh.host-key=${instanceCfg.hostKeyFile}"
190
+
];
191
+
in
192
+
"${instanceCfg.package}/bin/ugitd ${builtins.concatStringsSep " " args}";
193
+
};
194
+
};
195
+
196
+
"ugit-${name}-hooks" = {
197
+
description = "Setup hooks for ugit instance ${name}";
198
+
wantedBy = [ "multi-user.target" ];
199
+
after = [ "ugit-${name}.service" ];
200
+
requires = [ "ugit-${name}.service" ];
201
+
serviceConfig = {
202
+
Type = "oneshot";
203
+
RemainAfterExit = true;
204
+
User = instanceCfg.user;
205
+
Group = instanceCfg.group;
206
+
ExecStart =
207
+
let
208
+
hookDir = "${instanceCfg.repoDir}/hooks/pre-receive.d";
209
+
mkHookScript =
210
+
hook:
211
+
let
212
+
script = pkgs.writeShellScript "ugit-${name}-${hook.name}" hook.content;
213
+
in
214
+
''
215
+
mkdir -p ${hookDir}
216
+
ln -sf ${script} ${hookDir}/${hook.name}
217
+
'';
218
+
in
219
+
pkgs.writeShellScript "ugit-${name}-hooks-setup" ''
220
+
${builtins.concatStringsSep "\n" (map mkHookScript instanceCfg.hooks)}
221
+
'';
222
+
};
223
+
};
224
+
}
225
+
)
226
+
) { } (builtins.attrNames cfg);
227
+
};
228
+
}
+32
nix/pkg.nix
+32
nix/pkg.nix
···
···
1
+
{
2
+
pkgs ? import <nixpkgs> { },
3
+
}:
4
+
let
5
+
name = "ugitd";
6
+
in
7
+
pkgs.buildGoModule {
8
+
pname = name;
9
+
version = "main";
10
+
src = pkgs.nix-gitignore.gitignoreSource [ ] (
11
+
builtins.path {
12
+
inherit name;
13
+
path = ../.;
14
+
}
15
+
);
16
+
subPackages = [
17
+
"cmd/ugitd"
18
+
];
19
+
vendorHash = pkgs.lib.fileContents ../go.mod.sri;
20
+
env.CGO_ENABLED = 0;
21
+
flags = [ "-trimpath" ];
22
+
ldflags = [
23
+
"-s"
24
+
"-w"
25
+
"-extldflags -static"
26
+
];
27
+
meta = {
28
+
description = "Minimal git server";
29
+
homepage = "https://git.jolheiser.com/ugit";
30
+
mainProgram = "ugitd";
31
+
};
32
+
}
+84
nix/vm.nix
+84
nix/vm.nix
···
···
1
+
{ pkgs, ... }:
2
+
let
3
+
privKey = ''
4
+
-----BEGIN OPENSSH PRIVATE KEY-----
5
+
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
6
+
QyNTUxOQAAACBIpmLtcHhECei1ls6s0kKUehjpRCP9yel/c5YCIb5DpQAAAIgAYtkzAGLZ
7
+
MwAAAAtzc2gtZWQyNTUxOQAAACBIpmLtcHhECei1ls6s0kKUehjpRCP9yel/c5YCIb5DpQ
8
+
AAAEDFY3M69VfnFbyE67r3l4lDcf5eht5qgNemE9xtMhRkBkimYu1weEQJ6LWWzqzSQpR6
9
+
GOlEI/3J6X9zlgIhvkOlAAAAAAECAwQF
10
+
-----END OPENSSH PRIVATE KEY-----
11
+
'';
12
+
pubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEimYu1weEQJ6LWWzqzSQpR6GOlEI/3J6X9zlgIhvkOl";
13
+
sshConfig = ''
14
+
Host ugit
15
+
HostName localhost
16
+
Port 8448
17
+
User ugit
18
+
IdentityFile ~/.ssh/vm
19
+
IdentitiesOnly yes
20
+
'';
21
+
in
22
+
{
23
+
imports = [ ./module.nix ];
24
+
environment.systemPackages = with pkgs; [ git ];
25
+
services.getty.autologinUser = "root";
26
+
services.openssh.enable = true;
27
+
services.ugit.vm = {
28
+
enable = true;
29
+
authorizedKeys = [ pubKey ];
30
+
hooks = [
31
+
{
32
+
name = "pre-receive";
33
+
content = ''
34
+
echo "Pre-receive hook executed"
35
+
'';
36
+
}
37
+
];
38
+
};
39
+
systemd.services."setup-vm" = {
40
+
wantedBy = [ "multi-user.target" ];
41
+
after = [ "ugit-vm.service" ];
42
+
path = with pkgs; [
43
+
git
44
+
];
45
+
serviceConfig = {
46
+
Type = "oneshot";
47
+
RemainAfterExit = true;
48
+
User = "root";
49
+
Group = "root";
50
+
ExecStart =
51
+
let
52
+
privSSH = pkgs.writeText "vm-privkey" privKey;
53
+
sshConfigFile = pkgs.writeText "vm-sshconfig" sshConfig;
54
+
in
55
+
pkgs.writeShellScript "setup-vm-script" ''
56
+
# Hack to let ugit start up and generate its SSH keypair
57
+
sleep 3
58
+
59
+
# Set up git
60
+
git config --global user.name "NixUser"
61
+
git config --global user.email "nixuser@example.com"
62
+
git config --global init.defaultBranch main
63
+
git config --global push.autoSetupRemote true
64
+
65
+
# Set up SSH files
66
+
mkdir ~/.ssh
67
+
ln -sf ${sshConfigFile} ~/.ssh/config
68
+
cp ${privSSH} ~/.ssh/vm
69
+
chmod 600 ~/.ssh/vm
70
+
echo "[localhost]:8448 $(cat /var/lib/ugit-vm/ugit_ed25519.pub)" > ~/.ssh/known_hosts
71
+
72
+
# Stage some git activity
73
+
mkdir ~/repo
74
+
cd ~/repo
75
+
git init
76
+
git remote add origin ugit:repo.git
77
+
touch README.md
78
+
git add README.md
79
+
git commit -m "Test"
80
+
'';
81
+
};
82
+
};
83
+
84
+
}