First go at adding the README file to the output. - staticgit - A git static site generator, the site you are viewing now!
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit a2c64544c939d0a4e67743423be339c672bc5c50
(DIR) parent 77288e9e0a99e1f8737172b46894a5dbde5cc722
(HTM) Author: Jay Scott <me@jay.scot>
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(-)
---
(DIR) diff --git a/.gitignore b/.gitignore
@@ -1 +1,2 @@
-build/
-\ No newline at end of file
+build/
+tmp/
+\ No newline at end of file
(DIR) 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..."
(DIR) 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 (required)")
flag.StringVar(&cfg.TemplatePath, "t", "", "Directory where HTML templates are stored")
flag.BoolVar(&cfg.GroupFlag, "g", false, "Group repositories based on description tags")
flag.StringVar(&ignoreDirs, "i", "", "Directories to ignore (space-separated)")
+ flag.StringVar(&outputRoot, "o", ".", "Root path where output directories will be created")
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.GroupFlag)
+ // if err != nil {
+ // log.Printf("Failed to get info for repo %s: %v", r.Name(), err)
+ // 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: %v", r.Name(), err)
+ } else {
+ readmeData := struct {
+ RepoName string
+ ReadmeContent string
+ }{
+ RepoName: r.Name(),
+ ReadmeContent: readme,
+ }
+
+ readmeTmpl := template.ParseTemplate(cfg.TemplatePath, "readme.html")
+ outputPath := filepath.Join(outputRoot, r.Name(), "README.html")
+
+ // Ensure the parent directory exists
+ if err := os.MkdirAll(filepath.Dir(outputPath), 0755); err != nil {
+ log.Fatalf("Failed to create parent directory: %v", err)
+ }
+
+ f, err := os.Create(outputPath)
+ if err != nil {
+ log.Fatalf("Failed to create README HTML file: %v", err)
+ }
+ defer f.Close()
+
+ if err := readmeTmpl.Execute(f, readmeData); err != nil {
+ log.Fatalf("Failed to execute README template: %v", err)
+ }
+ fmt.Printf("README HTML for repo %s saved to %s\n", r.Name(), outputPath)
+ }
}
}
- // 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)
+
}
(DIR) 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", err)
+ }
+
+ // Read the blob content
+ reader, err := blob.Reader()
+ if err != nil {
+ return "", fmt.Errorf("failed to get blob reader: %v", err)
+ }
+ defer reader.Close()
+
+ content, err := io.ReadAll(reader)
+ if err != nil {
+ return "", fmt.Errorf("failed to read blob content: %v", err)
+ }
+
+ 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 {
(DIR) 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