Mirror of https://git.jolheiser.com/ugit
at cue 3.1 kB view raw
1package git 2 3import ( 4 "errors" 5 "io/fs" 6 "os" 7 "path/filepath" 8 "sort" 9 10 "github.com/dustin/go-humanize" 11 "github.com/go-git/go-git/v5" 12 "github.com/go-git/go-git/v5/plumbing" 13 "github.com/go-git/go-git/v5/plumbing/object" 14) 15 16// EnsureRepo ensures that the repo exists in the given directory 17func EnsureRepo(dir string, repo string) error { 18 exists, err := PathExists(dir) 19 if err != nil { 20 return err 21 } 22 if !exists { 23 err = os.MkdirAll(dir, os.ModeDir|os.FileMode(0o700)) 24 if err != nil { 25 return err 26 } 27 } 28 rp := filepath.Join(dir, repo) 29 exists, err = PathExists(rp) 30 if err != nil { 31 return err 32 } 33 if !exists { 34 _, err := git.PlainInit(rp, true) 35 if err != nil { 36 return err 37 } 38 } 39 return nil 40} 41 42// PathExists checks if a path exists and returns true if it does 43func PathExists(path string) (bool, error) { 44 _, err := os.Stat(path) 45 if err == nil { 46 return true, nil 47 } 48 if errors.Is(err, fs.ErrNotExist) { 49 return false, nil 50 } 51 return true, err 52} 53 54// Tree returns the git tree at a given ref/rev 55func (r Repo) Tree(ref string) (*object.Tree, error) { 56 g, err := r.Git() 57 if err != nil { 58 return nil, err 59 } 60 61 hash, err := g.ResolveRevision(plumbing.Revision(ref)) 62 if err != nil { 63 return nil, err 64 } 65 66 c, err := g.CommitObject(*hash) 67 if err != nil { 68 return nil, err 69 } 70 71 return c.Tree() 72} 73 74// FileInfo is the information for a file in a tree 75type FileInfo struct { 76 Path string 77 IsDir bool 78 Mode string 79 Size string 80} 81 82// Name returns the last part of the FileInfo.Path 83func (f FileInfo) Name() string { 84 return filepath.Base(f.Path) 85} 86 87// Dir returns the given dirpath in the given ref as a slice of FileInfo 88// Sorted alphabetically, dirs first 89func (r Repo) Dir(ref, path string) ([]FileInfo, error) { 90 t, err := r.Tree(ref) 91 if err != nil { 92 return nil, err 93 } 94 if path != "" { 95 t, err = t.Tree(path) 96 if err != nil { 97 return nil, err 98 } 99 } 100 101 fis := make([]FileInfo, 0, len(t.Entries)) 102 for _, entry := range t.Entries { 103 fm, err := entry.Mode.ToOSFileMode() 104 if err != nil { 105 return nil, err 106 } 107 size, err := t.Size(entry.Name) 108 if err != nil { 109 return nil, err 110 } 111 fis = append(fis, FileInfo{ 112 Path: filepath.Join(path, entry.Name), 113 IsDir: fm.IsDir(), 114 Mode: fm.String(), 115 Size: humanize.Bytes(uint64(size)), 116 }) 117 } 118 sort.Slice(fis, func(i, j int) bool { 119 fi1 := fis[i] 120 fi2 := fis[j] 121 if fi1.IsDir != fi2.IsDir { 122 return fi1.IsDir 123 } 124 return fi1.Name() < fi2.Name() 125 }) 126 127 return fis, nil 128} 129 130// GetCommitFromRef returns the commit object for a given ref 131func (r Repo) GetCommitFromRef(ref string) (*object.Commit, error) { 132 g, err := r.Git() 133 if err != nil { 134 return nil, err 135 } 136 137 hash, err := g.ResolveRevision(plumbing.Revision(ref)) 138 if err != nil { 139 return nil, err 140 } 141 142 return g.CommitObject(*hash) 143} 144 145// FileContent returns the content of a file in the git tree at a given ref/rev 146func (r Repo) FileContent(ref, file string) (string, error) { 147 t, err := r.Tree(ref) 148 if err != nil { 149 return "", err 150 } 151 152 f, err := t.File(file) 153 if err != nil { 154 return "", err 155 } 156 157 content, err := f.Contents() 158 if err != nil { 159 return "", err 160 } 161 162 return content, nil 163}