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.
110 lines
3.4 KiB
Go
110 lines
3.4 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" || commitFile == "PUBLISH.trigger.mkd" {
|
|
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
|
|
|
|
repoPath, gitIsBare, err := detectGitPath(hookPath)
|
|
check(err)
|
|
git.IsBare = gitIsBare
|
|
|
|
if hookContext == "PostReceive" {
|
|
revs := strings.Fields(hookStdinput)
|
|
git.PreviousCommit = revs[0]
|
|
git.LastCommit = revs[1]
|
|
git.Branch = revs[2]
|
|
} else {
|
|
o, err := exec.Command(gexe, "-C", repoPath, "rev-parse", "HEAD").Output()
|
|
check(err)
|
|
git.LastCommit = stringifyOutput(o)
|
|
o, err = exec.Command(gexe, "-C", repoPath, "rev-parse", "HEAD^").Output()
|
|
check(err)
|
|
git.PreviousCommit = stringifyOutput(o)
|
|
o, err = exec.Command(gexe, "-C", repoPath, "branch", "-a", "--contains", "HEAD").Output()
|
|
check(err)
|
|
git.Branch = strings.Replace(stringifyOutput(o), "* ", "", 1)
|
|
}
|
|
|
|
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.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
|
|
}
|