You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.6 KiB
Go

package giq
import (
"bytes"
"fmt"
"math/rand"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
)
func stringifyOutput(s []byte) string {
return strings.TrimSpace(string(s))
}
func (g *Sysgit) Whoami() string {
return "I am Sysgit!"
}
func (g *Sysgit) AddBareWorktree(gitRepoPath, gitIndexPath, gitWorktree, gexe string) {
tmpRepoPath := filepath.Join(os.TempDir(), gitWorktree)
if _, err := os.Stat(tmpRepoPath); err == nil {
err := os.RemoveAll(tmpRepoPath)
check(err)
}
err := os.MkdirAll(tmpRepoPath, 0755)
check(err)
gitAddWorktree := exec.Command(gexe, "-C", gitRepoPath, "worktree", "add", "--detach", tmpRepoPath)
gitAddWorktree.Env = os.Environ()
gitAddWorktree.Env = append(gitAddWorktree.Env, fmt.Sprintf("GIT_INDEX_FILE=%s%s", gitRepoPath, gitIndexPath))
err = gitAddWorktree.Run()
check(err)
}
func (g *Sysgit) RemoveBareWorktree(gitRepoPath, gitIndexPath, gitWorktree, gexe string) {
gitRemoveWorktree := exec.Command(gexe, "-C", gitRepoPath, "worktree", "remove", gitWorktree)
gitRemoveWorktree.Env = os.Environ()
gitRemoveWorktree.Env = append(gitRemoveWorktree.Env, fmt.Sprintf("GIT_INDEX_FILE=%s%s", gitRepoPath, gitIndexPath))
gitRemoveWorktree.Run()
}
func isPublished(gitRepoPath, gitIndexPath, prevCommit, lastCommit string) bool {
var sout bytes.Buffer
//var serr bytes.Buffer
commits := exec.Command("git", "-C", gitRepoPath, "rev-list", fmt.Sprintf("%s..%s", prevCommit, lastCommit))
commits.Env = os.Environ()
commits.Env = append(commits.Env, fmt.Sprintf("GIT_INDEX_FILE=%s%s", gitRepoPath, gitIndexPath))
commits.Stdout = &sout
//commits.Stderr = &serr
err := commits.Run()
check(err)
for _, commit := range strings.Fields(sout.String()) {
committedFiles, err := exec.Command("git", "-C", gitRepoPath, "diff-tree", "--no-commit-id", "--name-only", commit).Output()
check(err)
for _, commitFile := range strings.Fields(string(committedFiles)) {
if commitFile == "PUBLISH.trigger.md" {
return true
}
}
commitMessages, err := exec.Command("git", "-C", gitRepoPath, "show", "-s", "--format=%B", commit).Output()
check(err)
if strings.Contains(string(commitMessages), "!publish!") {
return true
}
}
return false
}
func (g *Sysgit) GitStruct(hookPath, hookContext, hookStdinput, gexe string) Git {
var git Git
repositoryPath, err := exec.Command(gexe, "-C", hookPath, "rev-parse", "--git-dir").Output()
check(err)
repoPath := stringifyOutput(repositoryPath)
gitBareOutput, err := exec.Command(gexe, "-C", repoPath, "rev-parse", "--is-bare-repository").Output()
check(err)
gitBare := stringifyOutput(gitBareOutput)
if gitBare == "true" {
git.IsBare = true
} else {
git.IsBare = false
repoPath = strings.Replace(stringifyOutput(repositoryPath), ".git", "", 1)
check(err)
}
gitLastCommit, err := exec.Command(gexe, "-C", repoPath, "rev-parse", "HEAD").Output()
check(err)
gitPreviousCommit, err := exec.Command(gexe, "-C", repoPath, "rev-parse", "HEAD^").Output()
check(err)
gitBranch, err := exec.Command(gexe, "-C", repoPath, "branch", "-a", "--contains", "HEAD").Output()
check(err)
rand.Seed(time.Now().UnixNano())
git.Worktree = fmt.Sprintf("sandpoints_repo_%06d", rand.Intn(100001))
git.TmpRepoPath = filepath.Join(os.TempDir(), git.Worktree)
git.RepoPath = repoPath
git.LastCommit = stringifyOutput(gitLastCommit)
git.PreviousCommit = stringifyOutput(gitPreviousCommit)
git.Branch = strings.Replace(stringifyOutput(gitBranch), "* ", "", 1)
git.IndexPath = filepath.Join("/", ".git", "index")
if git.IsBare {
git.IndexPath = filepath.Join("/", "index")
}
git.Publish = isPublished(git.RepoPath, git.IndexPath, git.PreviousCommit, git.LastCommit)
return git
}