Refactoring pass number 2. - staticgit - A git static site generator, the site you are viewing now!
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
(DIR) commit 884ed087159dcf350421c692b8c530b7db260c28
(DIR) parent 91bdb33c51f86b1de9afbcc1f73122c300049226
(HTM) Author: Jay Scott <me@jay.scot>
Date: Fri, 12 Jul 2024 08:26:18 +0100
Refactoring pass number 2.
Diffstat:
M main.go | 466 ++++++++++++++++++++++++++++++-
D sealgit.go | 460 -------------------------------
2 files changed, 454 insertions(+), 472 deletions(-)
---
(DIR) diff --git a/main.go b/main.go
@@ -3,15 +3,462 @@ package main
import (
"flag"
"fmt"
+ "html/template"
"log"
"os"
+ "path/filepath"
+ "regexp"
+ "sort"
+ "strings"
+
+ "github.com/go-git/go-git/v5"
+ "github.com/go-git/go-git/v5/plumbing"
+ "github.com/go-git/go-git/v5/plumbing/object"
+)
+
+type BranchInfo struct {
+ Name string
+ LastCommit string
+ LastCommitDate string
+}
+
+type CommitInfo struct {
+ Hash string
+ Author string
+ Date string
+ Message string
+}
+
+type RepoInfo struct {
+ Name string
+ Description string
+ LastCommit string
+}
+
+const (
+ baseTemplate = `
+<!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>{{.Title}}</title>
+<link rel="icon" type="image/png" href="{{.IconPath}}favicon.png" />
+<link rel="stylesheet" type="text/css" href="{{.IconPath}}style.css" />
+</head>
+<body>
+<table>
+<tr><td><img src="{{.IconPath}}logo.png" alt="" width="32" height="32" /></td>
+<td><span class="desc">{{.Title}}</span></td></tr><tr><td></td><td>
+</td></tr>
+</table>
+<hr/>
+<div id="content">
+{{template "content" .}}
+</div>
+</body>
+</html>
+`
+
+ branchesContent = `
+{{define "content"}}
+<h1>{{.RepoName}} - Branches</h1>
+<table>
+<thead>
+<tr><td><b>Branch Name</b></td><td><b>Last Commit</b></td><td><b>Last Commit Date</b></td></tr>
+</thead>
+<tbody>
+{{range .Branches}}
+<tr><td>{{.Name}}</td><td>{{.LastCommit}}</td><td>{{.LastCommitDate}}</td></tr>
+{{end}}
+</tbody>
+</table>
+{{end}}
+`
+
+ commitHistoryContent = `
+{{define "content"}}
+<h1>{{.RepoName}} - Commit History</h1>
+<table>
+<thead>
+<tr><td><b>Hash</b></td><td><b>Author</b></td><td><b>Date</b></td><td><b>Message</b></td></tr>
+</thead>
+<tbody>
+{{range .Commits}}
+<tr><td>{{.Hash}}</td><td>{{.Author}}</td><td>{{.Date}}</td><td>{{.Message}}</td></tr>
+{{end}}
+</tbody>
+</table>
+{{end}}
+`
+
+ indexContent = `
+{{define "content"}}
+<table id="index">
+<thead>
+<tr><td><b>Name</b></td><td><b>Description</b></td><td><b>Last commit</b></td><td><b>Links</b></td></tr>
+</thead>
+<tbody>
+{{range $group, $repos := .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}}/commits.html">commits</a> |
+ <a href="{{.Name}}/branches.html">branches</a>
+ </td>
+ </tr>
+ {{end}}
+{{end}}
+</tbody>
+</table>
+{{end}}
+`
+ readmeContent = `
+{{define "content"}}
+<h1>{{.RepoName}}</h1>
+<pre>{{.ReadmeContent}}</pre>
+{{end}}
+`
+)
+
+var (
+ reposPath string
+ groupFlag bool
+ ignoreDirs map[string]bool
+ outputRoot string
+
+ branchesTmpl = template.Must(template.New("base").Parse(baseTemplate + branchesContent))
+ commitHistoryTmpl = template.Must(template.New("base").Parse(baseTemplate + commitHistoryContent))
+ indexTmpl = template.Must(template.New("base").Parse(baseTemplate + indexContent))
+ readmeTmpl = template.Must(template.New("base").Parse(baseTemplate + readmeContent))
)
+func generateIndexHTML(repoInfos []RepoInfo) error {
+ groupedRepos := groupRepos(repoInfos)
+ indexOutputPath := filepath.Join(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, struct {
+ Title string
+ IconPath string
+ Repos map[string][]RepoInfo
+ }{
+ Title: "git clone git@git.jay.scot:<reponame>",
+ IconPath: "./",
+ Repos: groupedRepos,
+ })
+}
+
+func getBranchInfo(repo *git.Repository) ([]BranchInfo, error) {
+ branches, err := repo.Branches()
+ if err != nil {
+ return nil, fmt.Errorf("failed to get branches: %w", err)
+ }
+
+ var branchInfos []BranchInfo
+ err = branches.ForEach(func(branch *plumbing.Reference) error {
+ commit, err := repo.CommitObject(branch.Hash())
+ if err != nil {
+ return fmt.Errorf("failed to get commit for branch %s: %w", branch.Name().Short(), err)
+ }
+
+ branchInfos = append(branchInfos, BranchInfo{
+ Name: branch.Name().Short(),
+ LastCommit: commit.Hash.String()[:7],
+ LastCommitDate: commit.Author.When.Format("02 Jan 2006 15:04:05"),
+ })
+ return nil
+ })
+
+ if err != nil {
+ return nil, fmt.Errorf("failed to iterate over branches: %w", err)
+ }
+
+ return branchInfos, nil
+}
+
+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 only the first line of the commit message
+ })
+ return nil
+ })
+
+ if err != nil {
+ return nil, fmt.Errorf("failed to iterate over commits: %w", err)
+ }
+
+ return commitHistory, nil
+}
+
+func getDescription(repoPath string) string {
+ descPath := filepath.Join(repoPath, "description")
+ description, _ := os.ReadFile(descPath)
+ return strings.TrimSpace(string(description))
+}
+
+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: %w", err)
+ }
+
+ return content, nil
+ }
+
+ return "No README found!", nil
+}
+
+func getRepoInfo(repoPath string) (RepoInfo, error) {
+ repo, err := git.PlainOpen(repoPath)
+ if err != nil {
+ return RepoInfo{}, fmt.Errorf("failed to open repository: %w", err)
+ }
+
+ headRef, err := repo.Head()
+ if err != nil {
+ return RepoInfo{}, fmt.Errorf("failed to get HEAD reference: %w", err)
+ }
+
+ commit, err := repo.CommitObject(headRef.Hash())
+ if err != nil {
+ return RepoInfo{}, fmt.Errorf("failed to get commit object: %w", err)
+ }
+
+ description := getDescription(repoPath)
+
+ return RepoInfo{
+ Name: filepath.Base(repoPath),
+ Description: description,
+ LastCommit: commit.Committer.When.Format("02 Jan 2006"),
+ }, nil
+}
+
+func groupRepos(repos []RepoInfo) map[string][]RepoInfo {
+ groupedRepos := make(map[string][]RepoInfo)
+ for _, repo := range repos {
+ group := getGroup(repo.Description)
+ 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.ToLower(repoList[j].Name)
+ })
+ }
+
+ return groupedRepos
+}
+
+func getGroup(description string) string {
+ if groupFlag {
+ groupRegex := regexp.MustCompile(`\[(.*?)\]`)
+ matches := groupRegex.FindStringSubmatch(description)
+ if len(matches) > 1 {
+ return matches[1]
+ }
+ }
+ return ""
+}
+
+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 processBranches(repoName, repoPath, outputDir string) error {
+ repo, err := git.PlainOpen(repoPath)
+ if err != nil {
+ return fmt.Errorf("failed to open git repository: %w", err)
+ }
+
+ branches, err := getBranchInfo(repo)
+ if err != nil {
+ return fmt.Errorf("failed to get branch information: %w", err)
+ }
+
+ outputPath := filepath.Join(outputDir, "branches.html")
+
+ f, err := os.Create(outputPath)
+ if err != nil {
+ return fmt.Errorf("failed to create branches HTML file: %w", err)
+ }
+ defer f.Close()
+
+ return branchesTmpl.Execute(f, struct {
+ Title string
+ IconPath string
+ RepoName string
+ Branches []BranchInfo
+ }{
+ Title: repoName + " - Branches",
+ IconPath: "../",
+ RepoName: repoName,
+ Branches: branches,
+ })
+}
+
+func processCommitHistory(repoName, repoPath, outputDir string) error {
+ 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, "commits.html")
+
+ f, err := os.Create(outputPath)
+ if err != nil {
+ return fmt.Errorf("failed to create commit history HTML file: %w", err)
+ }
+ defer f.Close()
+
+ return commitHistoryTmpl.Execute(f, struct {
+ Title string
+ IconPath string
+ RepoName string
+ Commits []CommitInfo
+ }{
+ Title: repoName + " - History",
+ IconPath: "../",
+ RepoName: repoName,
+ Commits: commits,
+ })
+}
+
+func processReadme(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 {
+ Title string
+ IconPath string
+ RepoName string
+ ReadmeContent string
+ }{
+ Title: repoName + " - Readme!",
+ IconPath: "../",
+ RepoName: repoName,
+ ReadmeContent: readme,
+ })
+}
+
+func processRepositories() error {
+ repos, err := os.ReadDir(reposPath)
+ if err != nil {
+ return fmt.Errorf("failed to read repos directory: %w", err)
+ }
+
+ var repoInfos []RepoInfo
+ for _, r := range repos {
+ if r.IsDir() && !ignoreDirs[r.Name()] {
+ repoPath := filepath.Join(reposPath, r.Name())
+ repoInfo, err := getRepoInfo(repoPath)
+ if err != nil {
+ fmt.Printf("Failed to get info for repo %s: %v\n", r.Name(), err)
+ continue
+ }
+ repoInfos = append(repoInfos, repoInfo)
+
+ outputDir := filepath.Join(outputRoot, r.Name())
+ if err := os.MkdirAll(outputDir, 0755); err != nil {
+ fmt.Printf("Failed to create output directory for repo %s: %v\n", r.Name(), err)
+ continue
+ }
+
+ if err := processReadme(r.Name(), repoPath, outputDir); err != nil {
+ fmt.Printf("Failed to process README for repo %s: %v\n", r.Name(), err)
+ }
+
+ if err := processCommitHistory(r.Name(), repoPath, outputDir); err != nil {
+ fmt.Printf("Failed to process commit history for repo %s: %v\n", r.Name(), err)
+ }
+
+ if err := processBranches(r.Name(), repoPath, outputDir); err != nil {
+ fmt.Printf("Failed to process branches for repo %s: %v\n", r.Name(), err)
+ }
+ }
+ }
+
+ return generateIndexHTML(repoInfos)
+}
+
func main() {
- reposPath := flag.String("p", "", "Path to the git repositories (required)")
- groupFlag := flag.Bool("g", false, "Group repositories based on description tags")
- ignoreDirs := flag.String("i", "", "Directories to ignore (comma-separated)")
- outputRoot := flag.String("o", ".", "Root path where output directories will be created")
+ flag.StringVar(&reposPath, "p", "", "Path to the git repositories (required)")
+ flag.BoolVar(&groupFlag, "g", false, "Group repositories based on description tags")
+ ignoreFlag := flag.String("i", "", "Directories to ignore (comma-separated)")
+ flag.StringVar(&outputRoot, "o", ".", "Root path where output directories will be created")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage: %s [options]\n\n", os.Args[0])
@@ -23,19 +470,14 @@ func main() {
flag.Parse()
- if *reposPath == "" {
+ if reposPath == "" {
flag.Usage()
os.Exit(1)
}
- cfg := &Config{
- ReposPath: *reposPath,
- GroupFlag: *groupFlag,
- IgnoreDirs: parseIgnoreDirs(*ignoreDirs),
- OutputRoot: *outputRoot,
- }
+ ignoreDirs = parseIgnoreDirs(*ignoreFlag)
- if err := processRepositories(cfg); err != nil {
+ if err := processRepositories(); err != nil {
log.Fatalf("Error processing repositories: %v", err)
}
}
(DIR) diff --git a/sealgit.go b/sealgit.go
@@ -1,460 +0,0 @@
-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"
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-type BranchInfo struct {
- Name string
- LastCommit string
- LastCommitDate string
-}
-
-type CommitInfo struct {
- Hash string
- Author string
- Date string
- Message string
-}
-
-type Config struct {
- ReposPath string
- GroupFlag bool
- IgnoreDirs map[string]bool
- OutputRoot string
-}
-
-type RepoInfo struct {
- Name string
- Description string
- LastCommit string
- Group string
-}
-
-const (
- baseTemplate = `
-<!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>{{.Title}}</title>
-<link rel="icon" type="image/png" href="{{.IconPath}}favicon.png" />
-<link rel="stylesheet" type="text/css" href="{{.IconPath}}style.css" />
-</head>
-<body>
-<table>
-<tr><td><img src="{{.IconPath}}logo.png" alt="" width="32" height="32" /></td>
-<td><span class="desc">{{.Title}}</span></td></tr><tr><td></td><td>
-</td></tr>
-</table>
-<hr/>
-<div id="content">
-{{template "content" .}}
-</div>
-</body>
-</html>
-`
-
- branchesContent = `
-{{define "content"}}
-<h1>{{.RepoName}} - Branches</h1>
-<table>
-<thead>
-<tr><td><b>Branch Name</b></td><td><b>Last Commit</b></td><td><b>Last Commit Date</b></td></tr>
-</thead>
-<tbody>
-{{range .Branches}}
-<tr><td>{{.Name}}</td><td>{{.LastCommit}}</td><td>{{.LastCommitDate}}</td></tr>
-{{end}}
-</tbody>
-</table>
-{{end}}
-`
-
- commitHistoryContent = `
-{{define "content"}}
-<h1>{{.RepoName}} - Commit History</h1>
-<table>
-<thead>
-<tr><td><b>Hash</b></td><td><b>Author</b></td><td><b>Date</b></td><td><b>Message</b></td></tr>
-</thead>
-<tbody>
-{{range .Commits}}
-<tr><td>{{.Hash}}</td><td>{{.Author}}</td><td>{{.Date}}</td><td>{{.Message}}</td></tr>
-{{end}}
-</tbody>
-</table>
-{{end}}
-`
-
- indexContent = `
-{{define "content"}}
-<table id="index">
-<thead>
-<tr><td><b>Name</b></td><td><b>Description</b></td><td><b>Last commit</b></td><td><b>Links</b></td></tr>
-</thead>
-<tbody>
-{{range $group, $repos := .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}}/commits.html">commits</a> |
- <a href="{{.Name}}/branches.html">branches</a>
- </td>
- </tr>
- {{end}}
-{{end}}
-</tbody>
-</table>
-{{end}}
-`
- readmeContent = `
-{{define "content"}}
-<h1>{{.RepoName}}</h1>
-<pre>{{.ReadmeContent}}</pre>
-{{end}}
-`
-)
-
-var (
- branchesTmpl = template.Must(template.New("base").Parse(baseTemplate + branchesContent))
- commitHistoryTmpl = template.Must(template.New("base").Parse(baseTemplate + commitHistoryContent))
- indexTmpl = template.Must(template.New("base").Parse(baseTemplate + indexContent))
- readmeTmpl = template.Must(template.New("base").Parse(baseTemplate + readmeContent))
-)
-
-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, struct {
- Title string
- IconPath string
- Repos map[string][]RepoInfo
- }{
- Title: "git clone git@git.jay.scot:<reponame>",
- IconPath: "./",
- Repos: groupedRepos,
- })
-}
-
-func getBranchInfo(repo *git.Repository) ([]BranchInfo, error) {
- branches, err := repo.Branches()
- if err != nil {
- return nil, fmt.Errorf("failed to get branches: %w", err)
- }
-
- var branchInfos []BranchInfo
- err = branches.ForEach(func(branch *plumbing.Reference) error {
- commit, err := repo.CommitObject(branch.Hash())
- if err != nil {
- return fmt.Errorf("failed to get commit for branch %s: %w", branch.Name().Short(), err)
- }
-
- branchInfos = append(branchInfos, BranchInfo{
- Name: branch.Name().Short(),
- LastCommit: commit.Hash.String()[:7],
- LastCommitDate: commit.Author.When.Format("02 Jan 2006 15:04:05"),
- })
- return nil
- })
-
- if err != nil {
- return nil, fmt.Errorf("failed to iterate over branches: %w", err)
- }
-
- return branchInfos, nil
-}
-
-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 only the first line of the commit message
- })
- return nil
- })
-
- if err != nil {
- return nil, fmt.Errorf("failed to iterate over commits: %w", err)
- }
-
- return commitHistory, 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 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: %w", err)
- }
-
- return 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{}, fmt.Errorf("failed to open repository: %w", err)
- }
-
- headRef, err := repo.Head()
- if err != nil {
- return RepoInfo{}, fmt.Errorf("failed to get HEAD reference: %w", err)
- }
-
- commit, err := repo.CommitObject(headRef.Hash())
- if err != nil {
- return RepoInfo{}, fmt.Errorf("failed to get commit object: %w", 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 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.ToLower(repoList[j].Name)
- })
- }
-
- return groupedRepos
-}
-
-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 processBranches(cfg *Config, repoName, repoPath, outputDir string) error {
- repo, err := git.PlainOpen(repoPath)
- if err != nil {
- return fmt.Errorf("failed to open git repository: %w", err)
- }
-
- branches, err := getBranchInfo(repo)
- if err != nil {
- return fmt.Errorf("failed to get branch information: %w", err)
- }
-
- outputPath := filepath.Join(outputDir, "branches.html")
-
- f, err := os.Create(outputPath)
- if err != nil {
- return fmt.Errorf("failed to create branches HTML file: %w", err)
- }
- defer f.Close()
-
- return branchesTmpl.Execute(f, struct {
- Title string
- IconPath string
- RepoName string
- Branches []BranchInfo
- }{
- Title: repoName + " - Branches",
- IconPath: "../",
- RepoName: repoName,
- Branches: branches,
- })
-}
-
-func processCommitHistory(cfg *Config, repoName, repoPath, outputDir string) error {
- 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, "commits.html")
-
- f, err := os.Create(outputPath)
- if err != nil {
- return fmt.Errorf("failed to create commit history HTML file: %w", err)
- }
- defer f.Close()
-
- return commitHistoryTmpl.Execute(f, struct {
- Title string
- IconPath string
- RepoName string
- Commits []CommitInfo
- }{
- Title: repoName + " - History",
- IconPath: "../",
- 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 {
- Title string
- IconPath string
- RepoName string
- ReadmeContent string
- }{
- Title: repoName + " - Readme!",
- IconPath: "../",
- RepoName: repoName,
- ReadmeContent: readme,
- })
-}
-
-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\n", r.Name(), err)
- 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 for repo %s: %v\n", r.Name(), err)
- continue
- }
-
- if err := processReadme(cfg, r.Name(), repoPath, outputDir); err != nil {
- fmt.Printf("Failed to process README for repo %s: %v\n", r.Name(), err)
- }
-
- if err := processCommitHistory(cfg, r.Name(), repoPath, outputDir); err != nil {
- fmt.Printf("Failed to process commit history for repo %s: %v\n", r.Name(), err)
- }
-
- if err := processBranches(cfg, r.Name(), repoPath, outputDir); err != nil {
- fmt.Printf("Failed to process branches for repo %s: %v\n", r.Name(), err)
- }
- }
- }
-
- return generateIndexHTML(cfg, repoInfos)
-}