| repo.go - staticgit - A git static site generator in GO with HTML output! | |
| git clone git://jay.scot/staticgit | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| repo.go (3132B) | |
| --- | |
| 1 package repo | |
| 2 | |
| 3 import ( | |
| 4 "fmt" | |
| 5 "os" | |
| 6 "path/filepath" | |
| 7 "sort" | |
| 8 "strings" | |
| 9 "time" | |
| 10 | |
| 11 "github.com/go-git/go-git/v5" | |
| 12 "github.com/go-git/go-git/v5/plumbing/object" | |
| 13 ) | |
| 14 | |
| 15 type Repo struct { | |
| 16 Name string | |
| 17 Description string | |
| 18 LastMod time.Time | |
| 19 gitRepo *git.Repository | |
| 20 } | |
| 21 | |
| 22 type Commit struct { | |
| 23 Hash string | |
| 24 Author string | |
| 25 Date string | |
| 26 Msg string | |
| 27 Added int | |
| 28 Removed int | |
| 29 } | |
| 30 | |
| 31 func OpenRepo(path string) (*Repo, error) { | |
| 32 gitRepo, err := git.PlainOpen(path) | |
| 33 if err != nil { | |
| 34 return nil, fmt.Errorf("open repo: %w", err) | |
| 35 } | |
| 36 | |
| 37 name := filepath.Base(path) | |
| 38 desc, _ := os.ReadFile(filepath.Join(path, "description")) | |
| 39 | |
| 40 head, err := gitRepo.Head() | |
| 41 if err != nil { | |
| 42 return nil, fmt.Errorf("get HEAD: %w", err) | |
| 43 } | |
| 44 | |
| 45 commit, err := gitRepo.CommitObject(head.Hash()) | |
| 46 if err != nil { | |
| 47 return nil, fmt.Errorf("get commit object: %w", err) | |
| 48 } | |
| 49 | |
| 50 return &Repo{ | |
| 51 Name: name, | |
| 52 Description: strings.TrimSpace(string(desc)), | |
| 53 LastMod: commit.Committer.When, | |
| 54 gitRepo: gitRepo, | |
| 55 }, nil | |
| 56 } | |
| 57 | |
| 58 func (r *Repo) GetCommits(maxCommits int) ([]Commit, error) { | |
| 59 iter, err := r.gitRepo.Log(&git.LogOptions{}) | |
| 60 if err != nil { | |
| 61 return nil, fmt.Errorf("get commit log: %w", err) | |
| 62 } | |
| 63 | |
| 64 var cs []Commit | |
| 65 err = iter.ForEach(func(c *object.Commit) error { | |
| 66 if len(cs) >= maxCommits { | |
| 67 return nil | |
| 68 } | |
| 69 | |
| 70 stats, err := c.Stats() | |
| 71 if err != nil { | |
| 72 return fmt.Errorf("get commit stats: %w", err) | |
| 73 } | |
| 74 | |
| 75 add, del := 0, 0 | |
| 76 for _, stat := range stats { | |
| 77 add += stat.Addition | |
| 78 del += stat.Deletion | |
| 79 } | |
| 80 | |
| 81 cs = append(cs, Commit{ | |
| 82 Hash: c.Hash.String()[:7], | |
| 83 Author: c.Author.Name, | |
| 84 Date: c.Author.When.Format("02 Jan 2006 15:04… | |
| 85 Msg: strings.Split(c.Message, "\n")[0], | |
| 86 Added: add, | |
| 87 Removed: del, | |
| 88 }) | |
| 89 | |
| 90 return nil | |
| 91 }) | |
| 92 | |
| 93 if err != nil { | |
| 94 return nil, fmt.Errorf("iterate commits: %w", err) | |
| 95 } | |
| 96 | |
| 97 return cs, nil | |
| 98 } | |
| 99 | |
| 100 func (r *Repo) GetFiles() ([]string, error) { | |
| 101 head, err := r.gitRepo.Head() | |
| 102 if err != nil { | |
| 103 return nil, fmt.Errorf("get HEAD: %w", err) | |
| 104 } | |
| 105 | |
| 106 commit, err := r.gitRepo.CommitObject(head.Hash()) | |
| 107 if err != nil { | |
| 108 return nil, fmt.Errorf("get commit object: %w", err) | |
| 109 } | |
| 110 | |
| 111 tree, err := commit.Tree() | |
| 112 if err != nil { | |
| 113 return nil, fmt.Errorf("get tree: %w", err) | |
| 114 } | |
| 115 | |
| 116 var fs []string | |
| 117 err = tree.Files().ForEach(func(f *object.File) error { | |
| 118 fs = append(fs, f.Name) | |
| 119 return nil | |
| 120 }) | |
| 121 if err != nil { | |
| 122 return nil, fmt.Errorf("iterate files: %w", err) | |
| 123 } | |
| 124 | |
| 125 sort.Strings(fs) | |
| 126 return fs, nil | |
| 127 } | |
| 128 | |
| 129 func (r *Repo) GetReadme() (string, error) { | |
| 130 names := []string{"README.md", "README.txt", "README"} | |
| 131 | |
| 132 head, err := r.gitRepo.Head() | |
| 133 if err != nil { | |
| 134 return "", fmt.Errorf("get HEAD: %w", err) | |
| 135 } | |
| 136 | |
| 137 commit, err := r.gitRepo.CommitObject(head.Hash()) | |
| 138 if err != nil { | |
| 139 return "", fmt.Errorf("get commit object: %w", err) | |
| 140 } | |
| 141 | |
| 142 tree, err := commit.Tree() | |
| 143 if err != nil { | |
| 144 return "", fmt.Errorf("get tree: %w", err) | |
| 145 } | |
| 146 | |
| 147 for _, name := range names { | |
| 148 file, err := tree.File(name) | |
| 149 if err != nil { | |
| 150 continue | |
| 151 } | |
| 152 | |
| 153 content, err := file.Contents() | |
| 154 if err != nil { | |
| 155 return "", fmt.Errorf("read file contents: %w", … | |
| 156 } | |
| 157 | |
| 158 return content, nil | |
| 159 } | |
| 160 | |
| 161 return "No README found!", nil | |
| 162 } |