Introduction
Introduction Statistics Contact Development Disclaimer Help
Refactor project structure and update templates - staticgit - A git static site…
Log
Files
Refs
README
---
commit 77288e9e0a99e1f8737172b46894a5dbde5cc722
parent 39192917737e32a91c65d56d5c1e657e45df6382
Author: Jay Scott <[email protected]>
Date: Sun, 30 Jun 2024 11:27:52 +0100
Refactor project structure and update templates
- Reorganized project directories for better modularity and clarity.
- Moved default HTML template to a separate file for easier maintenance.
- Updated code references and paths to reflect new project structure.
- Adjusted configuration handling to accommodate future template flexibility.
Diffstat:
A .gitignore | 2 ++
A Makefile | 52 +++++++++++++++++++++++++++++…
A cmd/sealgit/main.go | 56 +++++++++++++++++++++++++++++…
M go.mod | 39 ++++++++++++++---------------…
M go.sum | 184 ++++++++++++-----------------…
A internal/config/config.go | 20 ++++++++++++++++++++
A internal/repo/repo.go | 86 ++++++++++++++++++++++++++++++
A internal/template/template.go | 31 +++++++++++++++++++++++++++++…
D main.go | 205 ------------------------------
A templates/index.html | 34 +++++++++++++++++++++++++++++…
10 files changed, 368 insertions(+), 341 deletions(-)
---
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1 @@
+build/
+\ No newline at end of file
diff --git a/Makefile b/Makefile
@@ -0,0 +1,52 @@
+APP_NAME := sealgit
+MAIN_PATH := cmd/sealgit/main.go
+
+OS := linux darwin windows
+ARCH := amd64 arm64
+BUILD_DIR := build
+
+GO_FLAGS := -ldflags="-s -w"
+
+.PHONY: all run build clean fmt vet
+
+all: run
+
+run:
+ @echo "Running $(APP_NAME)..."
+ @go run $(MAIN_PATH)
+
+build:
+ @echo "Building $(APP_NAME) for local architecture..."
+ @go build $(GO_FLAGS) -o $(BUILD_DIR)/$(APP_NAME) $(MAIN_PATH)
+ @echo "Binary created at $(BUILD_DIR)/$(APP_NAME)"
+
+build-cross:
+ @echo "Building $(APP_NAME) for multiple architectures..."
+ @for os in $(OS); do \
+ for arch in $(ARCH); do \
+ output_name=$(BUILD_DIR)/$(APP_NAME)-$$os-$$arch; \
+ echo "Building $$output_name..."; \
+ GOOS=$$os GOARCH=$$arch go build $(GO_FLAGS) -o $$outp…
+ done; \
+ done
+
+fmt:
+ @echo "Running gofmt..."
+ @gofmt -l -s -w .
+
+vet:
+ @echo "Running govet..."
+ @go vet ./...
+
+clean:
+ @echo "Cleaning build directory..."
+ @rm -rf $(BUILD_DIR)
+ @echo "Build directory cleaned."
+
+check: fmt vet
+ @echo "All checks passed."
+
+strip: build
+ @echo "Stripping binary..."
+ @strip $(BUILD_DIR)/$(APP_NAME)
+ @echo "Binary stripped."
diff --git a/cmd/sealgit/main.go b/cmd/sealgit/main.go
@@ -0,0 +1,56 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+
+ "sealgit/internal/config"
+ "sealgit/internal/repo"
+ "sealgit/internal/template"
+)
+
+func main() {
+ var cfg config.Config
+ var ignoreDirs string
+
+ flag.StringVar(&cfg.ReposPath, "p", "", "Path to the git repositories …
+ flag.StringVar(&cfg.TemplatePath, "t", "", "Directory where HTML templ…
+ flag.BoolVar(&cfg.GroupFlag, "g", false, "Group repositories based on …
+ flag.StringVar(&ignoreDirs, "i", "", "Directories to ignore (space-sep…
+ flag.Parse()
+
+ if cfg.ReposPath == "" {
+ fmt.Println("Usage: generate_repos_html -p <path> [-t <templat…
+ log.Fatalf("The -p flag (path to the git repositories) is requ…
+ }
+
+ cfg.IgnoreDirs = config.ParseIgnoreDirs(ignoreDirs)
+
+ repos, err := os.ReadDir(cfg.ReposPath)
+ if err != nil {
+ log.Fatalf("Failed to read repos directory: %v", err)
+ }
+
+ var repoInfos []repo.RepoInfo
+ for _, r := range repos {
+ if r.IsDir() && !cfg.IgnoreDirs[r.Name()] {
+ repoPath := filepath.Join(cfg.ReposPath, r.Name())
+ repoInfo, err := repo.GetRepoInfo(repoPath, cfg.GroupF…
+ if err != nil {
+ log.Printf("Failed to get info for repo %s: %v…
+ continue
+ }
+ repoInfos = append(repoInfos, repoInfo)
+ }
+ }
+
+ // only generate an index for now.
+ groupedRepos := repo.GroupRepos(repoInfos, cfg.GroupFlag)
+ tmpl := template.ParseTemplate(cfg.TemplatePath, "index.html")
+ if err := tmpl.Execute(os.Stdout, groupedRepos); err != nil {
+ log.Fatalf("Failed to execute template: %v", err)
+ }
+}
diff --git a/go.mod b/go.mod
@@ -1,29 +1,24 @@
-module main
+module sealgit
-go 1.22.2
+go 1.20
-require github.com/go-git/go-git/v5 v5.12.0
+require github.com/go-git/go-git/v5 v5.4.2 // Replace with the actual version …
require (
- dario.cat/mergo v1.0.0 // indirect
- github.com/Microsoft/go-winio v0.6.1 // indirect
- github.com/ProtonMail/go-crypto v1.0.0 // indirect
- github.com/cloudflare/circl v1.3.7 // indirect
- github.com/cyphar/filepath-securejoin v0.2.4 // indirect
- github.com/emirpasic/gods v1.18.1 // indirect
- github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
- github.com/go-git/go-billy/v5 v5.5.0 // indirect
- github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // ind…
+ github.com/Microsoft/go-winio v0.4.16 // indirect
+ github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // …
+ github.com/acomagu/bufpipe v1.0.3 // indirect
+ github.com/emirpasic/gods v1.12.0 // indirect
+ github.com/go-git/gcfg v1.5.0 // indirect
+ github.com/go-git/go-billy/v5 v5.3.1 // indirect
+ github.com/imdario/mergo v0.3.12 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // ind…
- github.com/kevinburke/ssh_config v1.2.0 // indirect
- github.com/pjbgf/sha1cd v0.3.0 // indirect
- github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indir…
- github.com/skeema/knownhosts v1.2.2 // indirect
- github.com/xanzy/ssh-agent v0.3.3 // indirect
- golang.org/x/crypto v0.21.0 // indirect
- golang.org/x/mod v0.12.0 // indirect
- golang.org/x/net v0.22.0 // indirect
- golang.org/x/sys v0.18.0 // indirect
- golang.org/x/tools v0.13.0 // indirect
+ github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 //…
+ github.com/mitchellh/go-homedir v1.1.0 // indirect
+ github.com/sergi/go-diff v1.1.0 // indirect
+ github.com/xanzy/ssh-agent v0.3.0 // indirect
+ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect
+ golang.org/x/net v0.0.0-20210326060303-6b1517762897 // indirect
+ golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
)
diff --git a/go.sum b/go.sum
@@ -1,145 +1,101 @@
-dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
-dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
-github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk…
-github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Mi…
-github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6sv…
-github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE…
-github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8a…
-github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjC…
-github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOL…
+github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8…
+github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923…
+github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76Wu…
+github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9…
+github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z…
+github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLup…
+github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4je…
+github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1h…
+github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKh…
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SH…
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iH…
-github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj…
-github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nn…
-github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5…
-github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0k…
-github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH5…
-github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aR…
+github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuG…
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHj…
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU9…
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHj…
-github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvc…
-github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/…
-github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1…
-github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/…
-github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODR…
-github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/sn…
-github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U6…
-github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlB…
-github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhi…
-github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sH…
-github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:e…
-github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.m…
-github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrj…
-github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHn…
-github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo56…
-github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4…
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elm…
+github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGl…
+github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSD…
+github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPg…
+github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI…
+github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0a…
+github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
+github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF…
+github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJl…
+github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4…
+github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJl…
+github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2…
+github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6…
+github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4…
+github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+z…
+github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddM…
+github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/H…
+github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjj…
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJ…
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo…
-github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaARe…
-github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9Cx…
+github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj…
+github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hv…
+github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:…
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFL…
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJO…
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
-github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG…
+github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWz…
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArN…
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2gr…
-github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
-github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3…
-github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
-github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKy…
+github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
+github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdw…
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5…
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJ…
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mRO…
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NI…
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NI…
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1l…
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7g…
-github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISo…
-github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvd…
-github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPL…
-github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQc…
-github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONW…
-github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj4…
-github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nT…
+github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
+github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbu…
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPys…
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GF…
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GF…
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7p…
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+8…
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpT…
-github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFy…
-github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQ…
-github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3Kg…
-github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy…
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05A…
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK…
-golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3…
-golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2…
-golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dX…
-golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
-golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYA…
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd…
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
-golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677Tz…
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5…
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX96…
+github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACC…
+github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY…
+golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeD…
+golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7Otx…
+golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDk…
+golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7Otx…
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl…
-golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5…
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWL…
-golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
-golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
-golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/…
-golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/…
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
-golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T…
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW…
+golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsTh…
+golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN…
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T…
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW…
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW…
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW…
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW…
-golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW…
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW…
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepC…
-golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepC…
-golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepC…
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepC…
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
-golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW…
+golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW…
+golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79 h1:RX8C8PRZc2hTIod4ds8ij+/…
+golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW…
+golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZx…
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9…
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQf…
-golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
-golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
-golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx5…
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzS…
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxV…
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZw…
-golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxY…
-golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaI…
-golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
-golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl…
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka…
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkq…
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkq…
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkq…
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqn…
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/…
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVW…
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
-gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
-gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8…
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E…
diff --git a/internal/config/config.go b/internal/config/config.go
@@ -0,0 +1,20 @@
+package config
+
+import "strings"
+
+type Config struct {
+ ReposPath string
+ TemplatePath string
+ GroupFlag bool
+ IgnoreDirs map[string]bool
+}
+
+func ParseIgnoreDirs(ignoreDirs string) map[string]bool {
+ ignoreMap := make(map[string]bool)
+ if ignoreDirs != "" {
+ for _, dir := range strings.Fields(ignoreDirs) {
+ ignoreMap[dir] = true
+ }
+ }
+ return ignoreMap
+}
diff --git a/internal/repo/repo.go b/internal/repo/repo.go
@@ -0,0 +1,86 @@
+package repo
+
+import (
+ "os"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strings"
+
+ git "github.com/go-git/go-git/v5"
+)
+
+type RepoInfo struct {
+ Name string
+ Description string
+ LastCommit string
+ Group string
+}
+
+func GetRepoInfo(repoPath string, groupFlag bool) (RepoInfo, error) {
+ repo, err := git.PlainOpen(repoPath)
+ if err != nil {
+ return RepoInfo{}, err
+ }
+
+ headRef, err := repo.Head()
+ if err != nil {
+ return RepoInfo{}, err
+ }
+
+ commit, err := repo.CommitObject(headRef.Hash())
+ if err != nil {
+ return RepoInfo{}, err
+ }
+
+ description, group := getDescriptionAndGroup(repoPath, groupFlag)
+
+ return RepoInfo{
+ Name: filepath.Base(repoPath),
+ Description: description,
+ LastCommit: commit.Committer.When.Format("02 Jan 2006"),
+ Group: group,
+ }, nil
+}
+
+func getDescriptionAndGroup(repoPath string, groupFlag bool) (string, string) {
+ descPath := filepath.Join(repoPath, "description")
+ data, err := os.ReadFile(descPath)
+ if err != nil {
+ return "", ""
+ }
+ description := string(data)
+ group := ""
+ if groupFlag {
+ group = extractGroup(description)
+ }
+ return description, group
+}
+
+func extractGroup(description string) string {
+ re := regexp.MustCompile(`\[(.*?)\]`)
+ matches := re.FindStringSubmatch(description)
+ if len(matches) > 1 {
+ return matches[1]
+ }
+ return ""
+}
+
+func GroupRepos(repos []RepoInfo, groupFlag bool) map[string][]RepoInfo {
+ groupedRepos := make(map[string][]RepoInfo)
+ for _, repo := range repos {
+ group := ""
+ if groupFlag {
+ group = repo.Group
+ }
+ groupedRepos[group] = append(groupedRepos[group], repo)
+ }
+
+ for _, repoList := range groupedRepos {
+ sort.Slice(repoList, func(i, j int) bool {
+ return strings.ToLower(repoList[i].Name) < strings.ToL…
+ })
+ }
+
+ return groupedRepos
+}
diff --git a/internal/template/template.go b/internal/template/template.go
@@ -0,0 +1,31 @@
+package template
+
+import (
+ "html/template"
+ "log"
+ "os"
+ "path/filepath"
+)
+
+const DefaultTemplateDir = "templates"
+
+func ParseTemplate(templateDir, templateName string) *template.Template {
+ if templateDir == "" {
+ templateDir = DefaultTemplateDir
+ }
+
+ if templateName == "" {
+ templateName = "index.html"
+ }
+
+ templatePath := filepath.Join(templateDir, templateName)
+ tmplData, err := os.ReadFile(templatePath)
+ if err != nil {
+ log.Fatalf("Failed to read template file: %v", err)
+ }
+ tmpl, err := template.New(templateName).Parse(string(tmplData))
+ if err != nil {
+ log.Fatalf("Failed to parse template: %v", err)
+ }
+ return tmpl
+}
diff --git a/main.go b/main.go
@@ -1,205 +0,0 @@
-package main
-
-import (
- "flag"
- "fmt"
- "html/template"
- "log"
- "os"
- "path/filepath"
- "regexp"
- "sort"
- "strings"
-
- git "github.com/go-git/go-git/v5"
-)
-
-type Config struct {
- ReposPath string
- TemplatePath string
- GroupFlag bool
- IgnoreDirs map[string]bool
-}
-
-type RepoInfo struct {
- Name string
- Description string
- LastCommit string
- Group string
-}
-
-const defaultHTMLTemplate = `
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-<meta name="viewport" content="width=device-width, initial-scale=1" />
-<title>repos for days!</title>
-<link rel="icon" type="image/png" href="favicon.png" />
-<link rel="stylesheet" type="text/css" href="style.css" />
-</head>
-<body>
-<table>
-<tr><td><img src="logo.png" alt="" width="32" height="32" /></td>
-<td><span class="desc">repos for days!</span></td></tr><tr><td></td><td>
-</td></tr>
-</table>
-<hr/>
-<div id="content">
-<table id="index">
-<thead>
-<tr><td><b>Name</b></td><td><b>Description</b></td><td><b>Last commit</b></td>…
-</thead>
-<tbody>
-{{range $group, $repos := .}}
-<tr><td colspan="3"><b>{{if eq $group ""}} {{else}}<hr>{{end}}</b></td></tr>
- {{range $repos}}
- <tr><td><a href="{{.Name}}">{{.Name}}</a></td><td>{{.Description}}</td><td>{…
- {{end}}
-{{end}}
-</tbody>
-</table>
-</div>
-</body>
-</html>
-`
-
-func main() {
- var config Config
- var ignoreDirs string
-
- flag.StringVar(&config.ReposPath, "p", "", "Path to the git repositori…
- flag.StringVar(&config.TemplatePath, "t", "", "Path to the HTML templa…
- flag.BoolVar(&config.GroupFlag, "g", false, "Group repositories based …
- flag.StringVar(&ignoreDirs, "i", "", "Directories to ignore (space-sep…
- flag.Parse()
-
- if config.ReposPath == "" {
- fmt.Println("Usage: generate_repos_html -p <path> [-t <templat…
- log.Fatalf("The -p flag (path to the git repositories) is requ…
- }
-
- config.IgnoreDirs = parseIgnoreDirs(ignoreDirs)
-
- repos, err := os.ReadDir(config.ReposPath)
- if err != nil {
- log.Fatalf("Failed to read repos directory: %v", err)
- }
-
- var repoInfos []RepoInfo
- for _, repo := range repos {
- if repo.IsDir() && !config.IgnoreDirs[repo.Name()] {
- repoPath := filepath.Join(config.ReposPath, repo.Name(…
- repoInfo, err := getRepoInfo(repoPath, config.GroupFla…
- if err != nil {
- log.Printf("Failed to get info for repo %s: %v…
- continue
- }
- repoInfos = append(repoInfos, repoInfo)
- }
- }
-
- groupedRepos := groupRepos(repoInfos, config.GroupFlag)
- tmpl := parseTemplate(config.TemplatePath)
- if err := tmpl.Execute(os.Stdout, groupedRepos); err != nil {
- log.Fatalf("Failed to execute template: %v", err)
- }
-}
-
-func parseIgnoreDirs(ignoreDirs string) map[string]bool {
- ignoreMap := make(map[string]bool)
- if ignoreDirs != "" {
- for _, dir := range strings.Fields(ignoreDirs) {
- ignoreMap[dir] = true
- }
- }
- return ignoreMap
-}
-
-func getRepoInfo(repoPath string, groupFlag bool) (RepoInfo, error) {
- repo, err := git.PlainOpen(repoPath)
- if err != nil {
- return RepoInfo{}, err
- }
-
- headRef, err := repo.Head()
- if err != nil {
- return RepoInfo{}, err
- }
-
- commit, err := repo.CommitObject(headRef.Hash())
- if err != nil {
- return RepoInfo{}, err
- }
-
- description, group := getDescriptionAndGroup(repoPath, groupFlag)
-
- return RepoInfo{
- Name: filepath.Base(repoPath),
- Description: description,
- LastCommit: commit.Committer.When.Format("02 Jan 2006"),
- Group: group,
- }, nil
-}
-
-func getDescriptionAndGroup(repoPath string, groupFlag bool) (string, string) {
- descPath := filepath.Join(repoPath, "description")
- data, err := os.ReadFile(descPath)
- if err != nil {
- return "", ""
- }
- description := string(data)
- group := ""
- if groupFlag {
- group = extractGroup(description)
- }
- return description, group
-}
-
-func extractGroup(description string) string {
- re := regexp.MustCompile(`\[(.*?)\]`)
- matches := re.FindStringSubmatch(description)
- if len(matches) > 1 {
- return matches[1]
- }
- return ""
-}
-
-func groupRepos(repos []RepoInfo, groupFlag bool) map[string][]RepoInfo {
- groupedRepos := make(map[string][]RepoInfo)
- for _, repo := range repos {
- group := ""
- if groupFlag {
- group = repo.Group
- }
- groupedRepos[group] = append(groupedRepos[group], repo)
- }
-
- for _, repoList := range groupedRepos {
- sort.Slice(repoList, func(i, j int) bool {
- return strings.ToLower(repoList[i].Name) < strings.ToL…
- })
- }
-
- return groupedRepos
-}
-
-func parseTemplate(templatePath string) *template.Template {
- if templatePath != "" {
- tmplData, err := os.ReadFile(templatePath)
- if err != nil {
- log.Fatalf("Failed to read template file: %v", err)
- }
- tmpl, err := template.New("index").Parse(string(tmplData))
- if err != nil {
- log.Fatalf("Failed to parse template: %v", err)
- }
- return tmpl
- }
-
- tmpl, err := template.New("index").Parse(defaultHTMLTemplate)
- if err != nil {
- log.Fatalf("Failed to parse default template: %v", err)
- }
- return tmpl
-}
diff --git a/templates/index.html b/templates/index.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<title>repos for days!</title>
+<link rel="icon" type="image/png" href="favicon.png" />
+<link rel="stylesheet" type="text/css" href="style.css" />
+</head>
+<body>
+<table>
+<tr><td><img src="logo.png" alt="" width="32" height="32" /></td>
+<td><span class="desc">repos for days!</span></td></tr><tr><td></td><td>
+</td></tr>
+</table>
+<hr/>
+<div id="content">
+<table id="index">
+<thead>
+<tr><td><b>Name</b></td><td><b>Description</b></td><td><b>Last commit</b></td>…
+</thead>
+<tbody>
+{{range $group, $repos := .}}
+<tr><td colspan="3"><b>{{if eq $group ""}} {{else}}<hr>{{end}}</b></td></tr>
+ {{range $repos}}
+ <tr><td><a href="{{.Name}}">{{.Name}}</a></td><td>{{.Description}}</td><td>{…
+ {{end}}
+{{end}}
+</tbody>
+</table>
+</div>
+</body>
+</html>
+\ No newline at end of file
You are viewing proxied material from jay.scot. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.