diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | default.nix | 29 | ||||
-rw-r--r-- | go.mod | 7 | ||||
-rw-r--r-- | go.sum | 24 | ||||
-rwxr-xr-x | justfile | 8 | ||||
-rw-r--r-- | main.go | 123 | ||||
-rw-r--r-- | page.templ | 146 | ||||
-rw-r--r-- | shell.nix | 2 | ||||
-rwxr-xr-x | vanity-imports.toml | 20 | ||||
-rwxr-xr-x | vanity.toml | 20 |
10 files changed, 341 insertions, 40 deletions
diff --git a/.gitignore b/.gitignore index 178135c..2eaf905 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /dist/ +*_templ.* +/result diff --git a/default.nix b/default.nix index 52b4962..b6b8243 100644 --- a/default.nix +++ b/default.nix @@ -1,28 +1,23 @@ -{ lib -, buildGoModule -, fetchFromGitHub -}: +{ pkgs ? import <nixpkgs> { } }: +let + inherit (pkgs) buildGoModule lib; +in -buildGoModule rec { - pname = "vanity-imports"; - version = "0.0.13-unstable"; +buildGoModule { + pname = "gopkgs"; + version = "unstable"; - src = fetchFromGitHub { - owner = "alanpearce"; - repo = "vanity-imports"; - rev = "95d03037139c6e847d14a35f12496a6fbf2d4370"; - hash = "sha256-YxCPxJqu/e9BK7iTrn4f6ymbwAlU+RHCneO743DeH/w="; - }; + src = lib.sourceFilesBySuffices ./. [ ".go" ".templ" ".mod" ".sum" ]; - vendorHash = "sha256-w0LaXevbGm1xpHvKxxyubHCOVRN712UzLyOd+hVikKg="; + vendorHash = "sha256-ahjgTjV4xXt21DAcVqplVEeZJDszY8amYYb2WENHWq4="; ldflags = [ "-s" "-w" ]; meta = with lib; { - description = "Use a custom domain in your Go import path"; - homepage = "https://github.com/mlcdf/vanity-imports"; + description = "Site generator for go vanity imports"; + homepage = "https://git.alanpearce.eu/gopkgs"; license = licenses.mit; maintainers = with maintainers; [ alanpearce ]; - mainProgram = "vanity-imports"; + mainProgram = "gopkgs"; }; } diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..2fd9745 --- /dev/null +++ b/go.mod @@ -0,0 +1,7 @@ +module go.alanpearce.eu/gopkgs + +go 1.22.3 + +require github.com/a-h/templ v0.2.731 + +require github.com/pelletier/go-toml/v2 v2.2.2 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..268079f --- /dev/null +++ b/go.sum @@ -0,0 +1,24 @@ +github.com/a-h/templ v0.2.731 h1:yiv4C7whSUsa36y65O06DPr/U/j3+WGB0RmvLOoVFXc= +github.com/a-h/templ v0.2.731/go.mod h1:IejA/ecDD0ul0dCvgCwp9t7bUZXVpGClEAdsqZQigi8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/justfile b/justfile index 4ec188a..9de046c 100755 --- a/justfile +++ b/justfile @@ -1,6 +1,10 @@ #! /usr/bin/env cached-nix-shell #! nix-shell -i "just --justfile" -cd: - vanity-imports --config vanity-imports.toml +ci: + templ generate + nix-build + ./result/bin/gopkgs + +cd: ci rsync --recursive --delete --chmod=go+r dist/ /srv/http/go diff --git a/main.go b/main.go new file mode 100644 index 0000000..ed23069 --- /dev/null +++ b/main.go @@ -0,0 +1,123 @@ +package main + +import ( + "context" + "fmt" + "log" + "net/url" + "os" + "path/filepath" + + "github.com/a-h/templ" + "github.com/pelletier/go-toml/v2" +) + +type Config struct { + Title string + Domain string + Forge string + Menu []*Link + Packages []*Package +} + +type Link struct { + Name string + URL string +} + +type Package struct { + Name string + URL string +} + +func must[T any](t T, err error) T { + if err != nil { + panic(err) + } + return t +} + +func fatal(err error) { + if err != nil { + log.Fatal(err) + } +} + +func importString(config *Config, pkg Package) string { + return fmt.Sprintf("%s git %s", + must(url.JoinPath(config.Domain, pkg.Name)), + must(url.JoinPath(config.Forge, pkg.Name)), + ) +} + +func sourceString(config *Config, pkg Package) string { + return fmt.Sprintf("%s _ %s %s", + must(url.JoinPath(config.Domain, pkg.Name)), + must(url.JoinPath(config.Forge, pkg.Name, "tree/main{/dir}")), + must(url.JoinPath(config.Forge, pkg.Name, "tree/main{/dir}/{file}#n{line}")), + ) +} + +func godocURL(config *Config, pkg *Package) string { + return must(url.JoinPath("https://pkg.go.dev", packageImportPath(config, pkg))) +} + +func packageImportPath(config *Config, pkg *Package) string { + return must(url.JoinPath(config.Domain, pkg.Name)) +} + +func packageForgeURL(config *Config, pkg *Package) string { + return must(url.JoinPath(config.Forge, pkg.Name)) +} + +func getConfig(filename string) (cfg *Config, err error) { + cfg = new(Config) + file, err := os.Open(filename) + if err != nil { + return nil, err + } + defer file.Close() + dec := toml.NewDecoder(file) + err = dec.Decode(cfg) + if err != nil { + return nil, err + } + + return cfg, nil +} + +const destDir = "dist" + +func renderToFile(c templ.Component, filename string) error { + pathname := filepath.Join(destDir, filename) + err := os.MkdirAll(filepath.Dir(pathname), 0755) + if err != nil { + return err + } + file, err := os.Create(pathname) + if err != nil { + return err + } + defer file.Close() + + return c.Render(context.Background(), file) +} + +func main() { + cfg, err := getConfig("vanity.toml") + fatal(err) + + err = renderToFile( + ListPage(cfg), + "index.html", + ) + fatal(err) + + for _, pkg := range cfg.Packages { + err = renderToFile( + PackagePage(cfg, pkg), + filepath.Join(pkg.Name, "index.html"), + ) + fatal(err) + } +} diff --git a/page.templ b/page.templ new file mode 100644 index 0000000..d6c15ef --- /dev/null +++ b/page.templ @@ -0,0 +1,146 @@ +package main + +templ Page(config *Config, pkg *Package) { + <!DOCTYPE html> + <html lang="en"> + <head> + <meta charset="utf-8"/> + <meta name="viewport" content="width=device-width, initial-scale=1.0"/> + if pkg != nil { + <meta name="go-import" content={ importString(config, *pkg) }/> + <meta name="go-source" content={ sourceString(config, *pkg) }/> + } + <style> + :root { + --width: 800px; + --font-main: Verdana, sans-serif; + --font-secondary: Verdana, sans-serif; + --font-scale: 1em; + --background-color: #fff; + --heading-color: #222; + --text-color: #444; + --link-color: #3273dc; + --visited-color: #8b6fcb; + --code-background-color: #f2f2f2; + --code-color: #222; + --blockquote-color: #222; + --icon-external-link: url("/external-link.svg"); + } + + @media (prefers-color-scheme: dark) { + :root { + --background-color: #01242e; + --heading-color: #eee; + --text-color: #ddd; + --link-color: #8cc2dd; + --visited-color: #8b6fcb; + --code-background-color: #000; + --code-color: #ddd; + --blockquote-color: #ccc; + } + } + + body { + font-family: var(--font-secondary); + font-size: var(--font-scale); + margin: auto; + padding: 20px; + max-width: var(--width); + text-align: left; + background-color: var(--background-color); + word-wrap: break-word; + overflow-wrap: break-word; + line-height: 1.5; + color: var(--text-color); + } + + h1, + h2, + h3, + h4, + h5, + h6 { + font-family: var(--font-main); + color: var(--heading-color); + & > a { + color: var(--heading-color); + } + } + + a { + color: var(--link-color); + cursor: pointer; + } + + nav a { + margin-right: 8px; + } + + strong, + b { + color: var(--heading-color); + } + + main { + margin-top: 2ex; + line-height: 1.6; + } + + table { + width: 100%; + } + </style> + <title>{ config.Title }</title> + </head> + <body> + <header> + <h1>{ config.Title }</h1> + <nav> + for _, link := range config.Menu { + <a href={ templ.SafeURL(link.URL) }>{ link.Name }</a> + } + </nav> + </header> + <main> + { children... } + </main> + </body> + </html> +} + +templ ListPage(config *Config) { + @Page(config, nil) { + <table> + <thead> + <tr> + <th>Name</th> + <th>Source</th> + <th>Documentation</th> + </tr> + </thead> + <tbody> + for _, pkg := range config.Packages { + <tr> + <td>{ packageImportPath(config, pkg) }</td> + <td><a href={ templ.SafeURL(packageForgeURL(config, pkg)) }>Source </a></td> + <td> + @GodocBadge(config, pkg) + </td> + </tr> + } + </tbody> + </table> + } +} + +templ PackagePage(config *Config, pkg *Package) { + @Page(config, pkg) { + <p>You're probably looking for the <a href={ templ.SafeURL(godocURL(config, pkg)) }>documentation</a>.</p> + } +} + +templ GodocBadge(config *Config, pkg *Package) { + <a href={ templ.SafeURL(godocURL(config, pkg)) }> + Go Reference + </a> +} diff --git a/shell.nix b/shell.nix index f3c9676..868e8f5 100644 --- a/shell.nix +++ b/shell.nix @@ -3,6 +3,6 @@ pkgs.mkShell { buildInputs = with pkgs; [ rsync - (callPackage ./. { }) + templ ]; } diff --git a/vanity-imports.toml b/vanity-imports.toml deleted file mode 100755 index b0ecd5d..0000000 --- a/vanity-imports.toml +++ /dev/null @@ -1,20 +0,0 @@ -domain = "go.alanpearce.eu" - -[index] -description = "" -extra_head = "" -title = "Alan's go packages" - -[repos] - -[repos."/website"] -repo = "https://git.alanpearce.eu/website" -vcs = "git" - -[repos."/searchix"] -repo = "https://git.alanpearce.eu/searchix" -vcs = "git" - -[repos."/x"] -repo = "https://git.alanpearce.eu/x" -vcs = "git" diff --git a/vanity.toml b/vanity.toml new file mode 100755 index 0000000..bfe1250 --- /dev/null +++ b/vanity.toml @@ -0,0 +1,20 @@ +title = "Alan's go packages" +domain = "go.alanpearce.eu" +forge = "https://git.alanpearce.eu" + +[[menu]] +name = "Home" +URL = "https://alanpearce.eu" + +[[menu]] +name = "Repositories" +URL = "https://git.alanpearce.eu" + +[[packages]] +name = "website" + +[[packages]] +name = "searchix" + +[[packages]] +name = "x" |