| First go at adding the README file to the output. - staticgit - A git static si… | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit a2c64544c939d0a4e67743423be339c672bc5c50 | |
| parent 77288e9e0a99e1f8737172b46894a5dbde5cc722 | |
| Author: Jay Scott <[email protected]> | |
| Date: Thu, 11 Jul 2024 11:53:37 +0100 | |
| First go at adding the README file to the output. | |
| Diffstat: | |
| M .gitignore | 5 +++-- | |
| M Makefile | 2 +- | |
| M cmd/sealgit/main.go | 64 +++++++++++++++++++++++++++++… | |
| M internal/repo/repo.go | 62 +++++++++++++++++++++++++++++… | |
| A templates/readme.html | 16 ++++++++++++++++ | |
| 5 files changed, 142 insertions(+), 7 deletions(-) | |
| --- | |
| diff --git a/.gitignore b/.gitignore | |
| @@ -1 +1,2 @@ | |
| -build/ | |
| -\ No newline at end of file | |
| +build/ | |
| +tmp/ | |
| +\ No newline at end of file | |
| diff --git a/Makefile b/Makefile | |
| @@ -13,7 +13,7 @@ all: run | |
| run: | |
| @echo "Running $(APP_NAME)..." | |
| - @go run $(MAIN_PATH) | |
| + @go run $(MAIN_PATH) -g -p /tmp/git -o tmp | |
| build: | |
| @echo "Building $(APP_NAME) for local architecture..." | |
| diff --git a/cmd/sealgit/main.go b/cmd/sealgit/main.go | |
| @@ -15,11 +15,13 @@ import ( | |
| 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 == "" { | |
| @@ -34,6 +36,19 @@ func main() { | |
| 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()] { | |
| @@ -44,13 +59,54 @@ func main() { | |
| 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 %… | |
| + } | |
| } | |
| } | |
| - // 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) | |
| + 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/internal/repo/repo.go b/internal/repo/repo.go | |
| @@ -1,6 +1,8 @@ | |
| package repo | |
| import ( | |
| + "fmt" | |
| + "io" | |
| "os" | |
| "path/filepath" | |
| "regexp" | |
| @@ -17,6 +19,66 @@ type RepoInfo struct { | |
| 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 { | |
| diff --git a/templates/readme.html b/templates/readme.html | |
| @@ -0,0 +1,15 @@ | |
| +<!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 |