summaryrefslogtreecommitdiff
path: root/repo.go
diff options
context:
space:
mode:
Diffstat (limited to 'repo.go')
-rw-r--r--repo.go30
1 files changed, 29 insertions, 1 deletions
diff --git a/repo.go b/repo.go
index 0805913..8bb4a5d 100644
--- a/repo.go
+++ b/repo.go
@@ -14,8 +14,16 @@ import (
"tildegit.org/tjp/sliderule/logging"
)
+// Repository represents a git repository.
type Repository string
+// Open produces a git repository from a directory path.
+//
+// It will also try a few variations (dirpath.git, dirpath/.git) and use the first
+// path found to be a git repository.
+//
+// It returns nil if neither dirpath nor any of its variations are a valid git
+// repository.
func Open(dirpath string) *Repository {
check := []string{dirpath}
if !strings.HasSuffix(dirpath, ".git") {
@@ -38,6 +46,7 @@ func Open(dirpath string) *Repository {
return nil
}
+// Name is the repository name, defined by the directory path.
func (r *Repository) Name() string {
name := filepath.Base(string(*r))
if name == ".git" {
@@ -46,6 +55,7 @@ func (r *Repository) Name() string {
return strings.TrimSuffix(name, ".git")
}
+// NameBytes returns a byte slice of the repository name.
func (r *Repository) NameBytes() []byte {
return []byte(r.Name())
}
@@ -64,6 +74,7 @@ func (r *Repository) cmd(ctx context.Context, cmdname string, args ...string) (*
return result, err
}
+// Type returns the result of "git cat-file -t <hash>".
func (r *Repository) Type(ctx context.Context, hash string) (string, error) {
res, err := r.cmd(ctx, "cat-file", "-t", hash)
if err != nil {
@@ -76,6 +87,7 @@ func (r *Repository) Type(ctx context.Context, hash string) (string, error) {
return strings.Trim(res.out.String(), "\n"), nil
}
+// Refs returns a list of branch and tag references.
func (r *Repository) Refs(ctx context.Context) ([]Ref, error) {
res, err := r.cmd(ctx, "show-ref", "--head", "--heads", "--tags")
if err != nil {
@@ -101,6 +113,7 @@ func (r *Repository) Refs(ctx context.Context) ([]Ref, error) {
var badRevListOutput = errors.New("unexpected 'git rev-list' output")
+// Commits lists commits backwards from a given head.
func (r *Repository) Commits(ctx context.Context, head string, count int) ([]Commit, error) {
res, err := r.cmd(ctx, "rev-list",
"--format=%an%n%ae%n%aI%n%cn%n%ce%n%cI%n%P%n%B$$END$$",
@@ -176,6 +189,7 @@ func (r *Repository) Commits(ctx context.Context, head string, count int) ([]Com
return commits, nil
}
+// Commit gathers a single commit by a reference string.
func (r *Repository) Commit(ctx context.Context, ref string) (*Commit, error) {
commits, err := r.Commits(ctx, ref, 1)
if err != nil {
@@ -184,6 +198,7 @@ func (r *Repository) Commit(ctx context.Context, ref string) (*Commit, error) {
return &commits[0], nil
}
+// Diffstat produces a diffstat of two trees by their references.
func (r *Repository) Diffstat(ctx context.Context, fromref, toref string) (string, error) {
res, err := r.cmd(ctx, "diff-tree", "-r", "--stat", fromref, toref)
if err != nil {
@@ -195,6 +210,7 @@ func (r *Repository) Diffstat(ctx context.Context, fromref, toref string) (strin
return res.out.String(), nil
}
+// Diff produces a diff of two trees by their references.
func (r *Repository) Diff(ctx context.Context, fromref, toref string) (string, error) {
res, err := r.cmd(ctx, "diff-tree", "-r", "-p", "-u", fromref, toref)
if err != nil {
@@ -206,19 +222,27 @@ func (r *Repository) Diff(ctx context.Context, fromref, toref string) (string, e
return res.out.String(), nil
}
+// Readme represents a README file.
type Readme struct {
Filename string
RawContents string
}
+// GeminiEscapedContent produces the file contents with any ```-leading lines prefixed with a space.
func (r Readme) GeminiEscapedContents() string {
- return strings.ReplaceAll(r.RawContents, "\n```", "\n ```")
+ body := r.RawContents
+ if strings.HasPrefix(body, "```") {
+ body = " " + body
+ }
+ return strings.ReplaceAll(body, "\n```", "\n ```")
}
+// GopherEscapedContent produces the file formatted as gophermap with every line an info-message line.
func (r Readme) GopherEscapedContents(selector, host, port string) string {
return gopherRawtext(selector, host, port, r.RawContents)
}
+// Readme finds a README blob in the root path under a ref string.
func (r *Repository) Readme(ctx context.Context, ref string) (*Readme, error) {
dir, err := r.Tree(ctx, ref, "")
if err != nil {
@@ -248,6 +272,7 @@ func (r *Repository) Readme(ctx context.Context, ref string) (*Readme, error) {
return nil, nil
}
+// Description reads the "description" file from in the git repository.
func (r *Repository) Description() string {
f, err := os.Open(filepath.Join(string(*r), "description"))
if err != nil {
@@ -263,6 +288,7 @@ func (r *Repository) Description() string {
return strings.TrimRight(string(b), "\n")
}
+// Blob returns the contents of a blob at a given ref (commit) and path.
func (r *Repository) Blob(ctx context.Context, ref, path string) ([]byte, error) {
res, err := r.cmd(ctx, "cat-file", "blob", ref+":"+path)
switch {
@@ -277,6 +303,7 @@ func (r *Repository) Blob(ctx context.Context, ref, path string) ([]byte, error)
}
}
+// ObjectDescription represents an object within a git tree (directory).
type ObjectDescription struct {
Mode int
Type string
@@ -285,6 +312,7 @@ type ObjectDescription struct {
Path string
}
+// Tree lists the contents of a given directory (path) in a commit (ref).
func (r *Repository) Tree(ctx context.Context, ref, path string) ([]ObjectDescription, error) {
pattern := ref
if path != "" && path != "." {