Introduction
Introduction Statistics Contact Development Disclaimer Help
Adding commit history page and.. - staticgit - A git static site generator, the…
Log
Files
Refs
README
---
commit 040e0e7448c05b1ad6b46fa90b2305d249f05ecf
parent a2c64544c939d0a4e67743423be339c672bc5c50
Author: Jay Scott <[email protected]>
Date: Thu, 11 Jul 2024 20:45:37 +0100
Adding commit history page and..
- Updating index page to show readme and commit history links.
- Updating file structure, opting for a more simple layout.
- Loading the templates from a const instead of files.
- Improving performance.
Diffstat:
M .gitignore | 4 ++--
M Makefile | 26 +++-----------------------
D cmd/sealgit/main.go | 112 -----------------------------…
M go.mod | 39 +++++++++++++++++------------…
M go.sum | 184 +++++++++++++++++++----------…
D internal/config/config.go | 20 --------------------
D internal/repo/repo.go | 148 -----------------------------…
D internal/template/template.go | 31 -----------------------------…
A main.go | 41 +++++++++++++++++++++++++++++…
A sealgit.go | 380 ++++++++++++++++++++++++++++++
D templates/index.html | 34 -----------------------------…
D templates/readme.html | 16 ----------------
12 files changed, 562 insertions(+), 473 deletions(-)
---
diff --git a/.gitignore b/.gitignore
@@ -1,2 +1,3 @@
build/
-tmp/
-\ No newline at end of file
+tmp/
+git/
diff --git a/Makefile b/Makefile
@@ -1,35 +1,20 @@
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
+.PHONY: all run build clean fmt vet check
all: run
run:
@echo "Running $(APP_NAME)..."
- @go run $(MAIN_PATH) -g -p /tmp/git -o tmp
+ @go run . -g -p ./git -o tmp -i .ssh,dotfiles
build:
@echo "Building $(APP_NAME) for local architecture..."
- @go build $(GO_FLAGS) -o $(BUILD_DIR)/$(APP_NAME) $(MAIN_PATH)
+ @go build $(GO_FLAGS) -o $(BUILD_DIR)/$(APP_NAME) .
@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 .
@@ -45,8 +30,3 @@ clean:
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
@@ -1,112 +0,0 @@
-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
- var outputRoot 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.StringVar(&outputRoot, "o", ".", "Root path where output director…
- 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.Gro…
- // if err != nil {
- // log.Printf("Failed to get info for repo %s:…
- // continue
- // }
- // repoInfos = append(repoInfos, repoInfo)
- // }
- // }
-
- 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)
-
- // Retrieve README content
- readme, err := repo.GetReadme(repoPath)
- if err != nil {
- log.Printf("Failed to get README for repo %s: …
- } else {
- readmeData := struct {
- RepoName string
- ReadmeContent string
- }{
- RepoName: r.Name(),
- ReadmeContent: readme,
- }
-
- readmeTmpl := template.ParseTemplate(cfg.Templ…
- outputPath := filepath.Join(outputRoot, r.Name…
-
- // Ensure the parent directory exists
- if err := os.MkdirAll(filepath.Dir(outputPath)…
- log.Fatalf("Failed to create parent di…
- }
-
- f, err := os.Create(outputPath)
- if err != nil {
- log.Fatalf("Failed to create README HT…
- }
- defer f.Close()
-
- if err := readmeTmpl.Execute(f, readmeData); e…
- log.Fatalf("Failed to execute README t…
- }
- fmt.Printf("README HTML for repo %s saved to %…
- }
- }
- }
-
- groupedRepos := repo.GroupRepos(repoInfos, cfg.GroupFlag)
- indexTmpl := template.ParseTemplate(cfg.TemplatePath, "index.html")
- indexOutputPath := filepath.Join(outputRoot, "index.html")
- indexFile, err := os.Create(indexOutputPath)
- if err != nil {
- log.Fatalf("Failed to create index HTML file: %v", err)
- }
- defer indexFile.Close()
-
- if err := indexTmpl.Execute(indexFile, groupedRepos); err != nil {
- log.Fatalf("Failed to execute index template: %v", err)
- }
- fmt.Printf("Index HTML saved to %s\n", indexOutputPath)
-
-}
diff --git a/go.mod b/go.mod
@@ -1,24 +1,29 @@
-module sealgit
+module main
-go 1.20
+go 1.22.5
-require github.com/go-git/go-git/v5 v5.4.2 // Replace with the actual version …
+require github.com/go-git/go-git/v5 v5.12.0
require (
- 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
+ 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/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // ind…
- 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
+ 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
gopkg.in/warnings.v0 v0.1.2 // indirect
)
diff --git a/go.sum b/go.sum
@@ -1,101 +1,145 @@
-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…
+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/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuG…
+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/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/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/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/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/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/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaARe…
+github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9Cx…
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJO…
-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/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG…
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/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/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/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/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/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/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.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…
+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…
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl…
-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/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/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW…
-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/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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9…
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+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/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.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…
+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=
diff --git a/internal/config/config.go b/internal/config/config.go
@@ -1,20 +0,0 @@
-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
@@ -1,148 +0,0 @@
-package repo
-
-import (
- "fmt"
- "io"
- "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
-}
-
-// GetReadme reads the README file from a bare git repository.
-func GetReadme(repoPath string) (string, error) {
- // Open the git repository
- repo, err := git.PlainOpen(repoPath)
- if err != nil {
- return "", fmt.Errorf("failed to open git repository: %v", err)
- }
-
- // Get the HEAD reference
- headRef, err := repo.Head()
- if err != nil {
- return "", fmt.Errorf("failed to get HEAD reference: %v", err)
- }
-
- // Get the commit object for the HEAD
- commit, err := repo.CommitObject(headRef.Hash())
- if err != nil {
- return "", fmt.Errorf("failed to get commit object: %v", err)
- }
-
- // Get the tree for the commit
- tree, err := commit.Tree()
- if err != nil {
- return "", fmt.Errorf("failed to get tree: %v", err)
- }
-
- // Common README file names
- readmeFiles := []string{"README.md", "README.txt", "README"}
-
- for _, fileName := range readmeFiles {
- // Find the file entry in the tree
- entry, err := tree.FindEntry(fileName)
- if err != nil {
- continue // Try the next possible README file
- }
-
- // Get the blob for the file entry
- blob, err := repo.BlobObject(entry.Hash)
- if err != nil {
- return "", fmt.Errorf("failed to get blob object: %v",…
- }
-
- // Read the blob content
- reader, err := blob.Reader()
- if err != nil {
- return "", fmt.Errorf("failed to get blob reader: %v",…
- }
- defer reader.Close()
-
- content, err := io.ReadAll(reader)
- if err != nil {
- return "", fmt.Errorf("failed to read blob content: %v…
- }
-
- return string(content), nil
- }
-
- return "No README found!", nil
-}
-
-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
@@ -1,31 +0,0 @@
-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
@@ -0,0 +1,41 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "log"
+ "os"
+)
+
+func main() {
+ reposPath := flag.String("p", "", "Path to the git repositories (requi…
+ groupFlag := flag.Bool("g", false, "Group repositories based on descri…
+ ignoreDirs := flag.String("i", "", "Directories to ignore (comma-separ…
+ outputRoot := flag.String("o", ".", "Root path where output directorie…
+
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, "Usage: %s [options]\n\n", os.Args[0])
+ fmt.Fprintf(os.Stderr, "Options:\n")
+ flag.PrintDefaults()
+ fmt.Fprintf(os.Stderr, "\nExample:\n")
+ fmt.Fprintf(os.Stderr, " %s -p /path/to/repos -g -i dir1,dir2…
+ }
+
+ flag.Parse()
+
+ if *reposPath == "" {
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ cfg := &Config{
+ ReposPath: *reposPath,
+ GroupFlag: *groupFlag,
+ IgnoreDirs: parseIgnoreDirs(*ignoreDirs),
+ OutputRoot: *outputRoot,
+ }
+
+ if err := processRepositories(cfg); err != nil {
+ log.Fatalf("Error processing repositories: %v", err)
+ }
+}
diff --git a/sealgit.go b/sealgit.go
@@ -0,0 +1,380 @@
+package main
+
+import (
+ "fmt"
+ "html/template"
+ "os"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strings"
+
+ git "github.com/go-git/go-git/v5"
+ "github.com/go-git/go-git/v5/plumbing/object"
+)
+
+type Config struct {
+ ReposPath string
+ GroupFlag bool
+ IgnoreDirs map[string]bool
+ OutputRoot string
+}
+
+type RepoInfo struct {
+ Name string
+ Description string
+ LastCommit string
+ Group string
+}
+
+type CommitInfo struct {
+ Hash string
+ Author string
+ Date string
+ Message string
+}
+
+const (
+ indexTemplate = `
+<!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="4"><b>{{if eq $group ""}} {{else}}<hr>{{end}}</b></td></tr>
+ {{range $repos}}
+ <tr>
+ <td>{{.Name}}</td>
+ <td>{{.Description}}</td>
+ <td>| {{.LastCommit}} | </td>
+ <td>
+ <a href="{{.Name}}/README.html">README</a> |
+ <a href="{{.Name}}/commit.html">COMMITS</a>
+ </td>
+ </tr>
+ {{end}}
+{{end}}
+</tbody>
+</table>
+</div>
+</body>
+</html>
+`
+
+ readmeTemplate = `
+<!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>{{.RepoName}} - Readme!</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"><a href='../index.html'>..back</a></span></td></tr><tr>…
+</td></tr>
+</table>
+<hr/>
+<h1>{{.RepoName}}</h1>
+<div id="content">
+<pre>{{.ReadmeContent}}</pre>
+</div>
+</body>
+</html>
+`
+
+ commitHistoryTemplate = `
+<!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>{{.RepoName}} - History</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"><a href='../index.html'>..back</a></span></td></tr><tr>…
+</td></tr>
+</table>
+<hr/>
+<h1>{{.RepoName}} - Commit History</h1>
+<div id="content">
+<table>
+<thead>
+<tr><td><b>Hash</b></td><td><b>Author</b></td><td><b>Date</b></td><td><b>Messa…
+</thead>
+<tbody>
+{{range .Commits}}
+<tr><td>{{.Hash}}</td><td>{{.Author}}</td><td>{{.Date}}</td><td>{{.Message}}</…
+{{end}}
+</tbody>
+</table>
+</div>
+</body>
+</html>
+`
+)
+
+var (
+ indexTmpl = template.Must(template.New("index").Parse(indexTem…
+ readmeTmpl = template.Must(template.New("readme").Parse(readmeT…
+ commitHistoryTmpl = template.Must(template.New("commitHistory").Parse(…
+)
+
+func parseIgnoreDirs(ignoreDirs string) map[string]bool {
+ ignoreMap := make(map[string]bool)
+ for _, dir := range strings.Split(ignoreDirs, ",") {
+ if trimmedDir := strings.TrimSpace(dir); trimmedDir != "" {
+ ignoreMap[trimmedDir] = true
+ }
+ }
+ return ignoreMap
+}
+
+func processRepositories(cfg *Config) error {
+ repos, err := os.ReadDir(cfg.ReposPath)
+ if err != nil {
+ return fmt.Errorf("failed to read repos directory: %w", err)
+ }
+
+ var repoInfos []RepoInfo
+ for _, r := range repos {
+ if r.IsDir() && !cfg.IgnoreDirs[r.Name()] {
+ repoPath := filepath.Join(cfg.ReposPath, r.Name())
+ repoInfo, err := getRepoInfo(repoPath, cfg.GroupFlag)
+ if err != nil {
+ fmt.Printf("Failed to get info for repo %s: %v…
+ continue
+ }
+ repoInfos = append(repoInfos, repoInfo)
+
+ outputDir := filepath.Join(cfg.OutputRoot, r.Name())
+ if err := os.MkdirAll(outputDir, 0755); err != nil {
+ fmt.Printf("Failed to create output directory …
+ continue
+ }
+
+ if err := processReadme(cfg, r.Name(), repoPath, outpu…
+ fmt.Printf("Failed to process README for repo …
+ }
+
+ if err := processCommitHistory(cfg, r.Name(), repoPath…
+ fmt.Printf("Failed to process commit history f…
+ }
+ }
+ }
+
+ return generateIndexHTML(cfg, repoInfos)
+}
+
+func getRepoInfo(repoPath string, groupFlag bool) (RepoInfo, error) {
+ repo, err := git.PlainOpen(repoPath)
+ if err != nil {
+ return RepoInfo{}, fmt.Errorf("failed to open repository: %w",…
+ }
+
+ headRef, err := repo.Head()
+ if err != nil {
+ return RepoInfo{}, fmt.Errorf("failed to get HEAD reference: %…
+ }
+
+ commit, err := repo.CommitObject(headRef.Hash())
+ if err != nil {
+ return RepoInfo{}, fmt.Errorf("failed to get commit object: %w…
+ }
+
+ 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")
+ description, _ := os.ReadFile(descPath)
+ desc := strings.TrimSpace(string(description))
+ groupRegex := regexp.MustCompile(`\[(.*?)\]`)
+
+ var group string
+ if groupFlag {
+ matches := groupRegex.FindStringSubmatch(desc)
+ if len(matches) > 1 {
+ group = matches[1]
+ }
+ }
+
+ return desc, group
+}
+
+func getCommitHistory(repo *git.Repository) ([]CommitInfo, error) {
+ ref, err := repo.Head()
+ if err != nil {
+ return nil, fmt.Errorf("failed to get HEAD reference: %w", err)
+ }
+
+ commits, err := repo.Log(&git.LogOptions{From: ref.Hash()})
+ if err != nil {
+ return nil, fmt.Errorf("failed to get commit log: %w", err)
+ }
+
+ var commitHistory []CommitInfo
+ err = commits.ForEach(func(c *object.Commit) error {
+ commitHistory = append(commitHistory, CommitInfo{
+ Hash: c.Hash.String()[:7],
+ Author: c.Author.Name,
+ Date: c.Author.When.Format("02 Jan 2006 15:04:05"),
+ Message: strings.Split(c.Message, "\n")[0], // Get onl…
+ })
+ return nil
+ })
+
+ if err != nil {
+ return nil, fmt.Errorf("failed to iterate over commits: %w", e…
+ }
+
+ return commitHistory, nil
+}
+
+func processCommitHistory(cfg *Config, repoName, repoPath, outputDir string) e…
+ repo, err := git.PlainOpen(repoPath)
+ if err != nil {
+ return fmt.Errorf("failed to open git repository: %w", err)
+ }
+
+ commits, err := getCommitHistory(repo)
+ if err != nil {
+ return fmt.Errorf("failed to get commit history: %w", err)
+ }
+
+ outputPath := filepath.Join(outputDir, "commit.html")
+
+ f, err := os.Create(outputPath)
+ if err != nil {
+ return fmt.Errorf("failed to create commit history HTML file: …
+ }
+ defer f.Close()
+
+ return commitHistoryTmpl.Execute(f, struct {
+ RepoName string
+ Commits []CommitInfo
+ }{RepoName: repoName, Commits: commits})
+}
+
+func processReadme(cfg *Config, repoName, repoPath, outputDir string) error {
+ readme, err := getReadme(repoPath)
+ if err != nil {
+ return fmt.Errorf("failed to get README: %w", err)
+ }
+
+ outputPath := filepath.Join(outputDir, "README.html")
+
+ f, err := os.Create(outputPath)
+ if err != nil {
+ return fmt.Errorf("failed to create README HTML file: %w", err)
+ }
+ defer f.Close()
+
+ return readmeTmpl.Execute(f, struct {
+ RepoName string
+ ReadmeContent string
+ }{RepoName: repoName, ReadmeContent: readme})
+}
+
+func getReadme(repoPath string) (string, error) {
+ readmeFiles := []string{"README.md", "README.txt", "README"}
+ repo, err := git.PlainOpen(repoPath)
+ if err != nil {
+ return "", fmt.Errorf("failed to open git repository: %w", err)
+ }
+
+ headRef, err := repo.Head()
+ if err != nil {
+ return "", fmt.Errorf("failed to get HEAD reference: %w", err)
+ }
+
+ commit, err := repo.CommitObject(headRef.Hash())
+ if err != nil {
+ return "", fmt.Errorf("failed to get commit object: %w", err)
+ }
+
+ tree, err := commit.Tree()
+ if err != nil {
+ return "", fmt.Errorf("failed to get tree: %w", err)
+ }
+
+ for _, fileName := range readmeFiles {
+ file, err := tree.File(fileName)
+ if err != nil {
+ continue
+ }
+
+ content, err := file.Contents()
+ if err != nil {
+ return "", fmt.Errorf("failed to read file contents: %…
+ }
+
+ return content, nil
+ }
+
+ return "No README found!", nil
+}
+
+func generateIndexHTML(cfg *Config, repoInfos []RepoInfo) error {
+ groupedRepos := groupRepos(repoInfos, cfg.GroupFlag)
+ indexOutputPath := filepath.Join(cfg.OutputRoot, "index.html")
+
+ indexFile, err := os.Create(indexOutputPath)
+ if err != nil {
+ return fmt.Errorf("failed to create index HTML file: %w", err)
+ }
+ defer indexFile.Close()
+
+ return indexTmpl.Execute(indexFile, groupedRepos)
+}
+
+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/templates/index.html b/templates/index.html
@@ -1,33 +0,0 @@
-<!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
diff --git a/templates/readme.html b/templates/readme.html
@@ -1,15 +0,0 @@
-<!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>{{.RepoName}} - README</title>
-<link rel="stylesheet" type="text/css" href="style.css" />
-</head>
-<body>
-<h1>{{.RepoName}}</h1>
-<div id="readme">
-<pre>{{.ReadmeContent}}</pre>
-</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.