commit 1
This commit is contained in:
commit
6859e01192
6
.devcontainer/Dockerfile
Normal file
6
.devcontainer/Dockerfile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
FROM mcr.microsoft.com/devcontainers/go:1-1.21-bullseye
|
||||||
|
|
||||||
|
# Install Magefile from GitHub release
|
||||||
|
ARG MAGE_VERSION=1.15.0
|
||||||
|
|
||||||
|
RUN wget -q https://github.com/magefile/mage/releases/download/v${MAGE_VERSION}/mage_${MAGE_VERSION}_Linux-64bit.tar.gz -O - | tar -xz -C /usr/local/bin
|
24
.devcontainer/devcontainer.json
Normal file
24
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||||
|
// README at: https://github.com/devcontainers/templates/tree/main/src/go
|
||||||
|
{
|
||||||
|
"name": "Go",
|
||||||
|
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||||
|
//"features": {},
|
||||||
|
|
||||||
|
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||||
|
// "forwardPorts": [],
|
||||||
|
|
||||||
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
|
// "postCreateCommand": "go version",
|
||||||
|
|
||||||
|
// Configure tool-specific properties.
|
||||||
|
// "customizations": {},
|
||||||
|
|
||||||
|
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||||
|
// "remoteUser": "root"
|
||||||
|
}
|
19
git/cmd.go
Normal file
19
git/cmd.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import "os/exec"
|
||||||
|
|
||||||
|
// Execute runs a git command and returns the stdout
|
||||||
|
func (g *Git) Execute(args ...string) (string, error) {
|
||||||
|
|
||||||
|
cmd := exec.Command("git", args...)
|
||||||
|
if g.WorkingDir != "" {
|
||||||
|
cmd.Dir = g.WorkingDir
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run and return stdout
|
||||||
|
out, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return string(out), nil
|
||||||
|
}
|
28
git/cmd_test.go
Normal file
28
git/cmd_test.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestExecute runs a unit test with testify for git.Execute
|
||||||
|
func TestExecute(t *testing.T) {
|
||||||
|
require := require.New(t)
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
// Create a new git
|
||||||
|
git := NewGit(&NewGitInput{
|
||||||
|
Executable: "git",
|
||||||
|
})
|
||||||
|
|
||||||
|
// Run the command
|
||||||
|
out, err := git.Execute("version")
|
||||||
|
|
||||||
|
// Assert that the command ran successfully
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
// Assert that the output contains 'git version'
|
||||||
|
assert.Contains(out, "git version")
|
||||||
|
}
|
36
git/commit.go
Normal file
36
git/commit.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import "strconv"
|
||||||
|
|
||||||
|
// GetHash returns the commit hash for the current HEAD
|
||||||
|
func (g *Git) GetHash() (string, error) {
|
||||||
|
|
||||||
|
out, err := g.Execute("rev-parse", "HEAD")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCommitRemote returns the commit hash for the current HEAD on the remote
|
||||||
|
func (g *Git) GetCommitRemote() (string, error) {
|
||||||
|
|
||||||
|
out, err := g.Execute("ls-remote", "origin", "HEAD")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCommitsAhead returns the number of commits ahead of main
|
||||||
|
func (g *Git) GetCommitsAhead() (int, error) {
|
||||||
|
|
||||||
|
out, err := g.Execute("rev-list", "--count", "HEAD", "^"+g.MainBranch)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return strconv.Atoi(out)
|
||||||
|
}
|
36
git/git.go
Normal file
36
git/git.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
type Git struct {
|
||||||
|
// Executable is the path to the git executable
|
||||||
|
Executable string
|
||||||
|
// WorkingDir is the path to the working directory
|
||||||
|
WorkingDir string
|
||||||
|
// MainBranch is the name of the main branch
|
||||||
|
MainBranch string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGitInput is the input type for NewGit
|
||||||
|
type NewGitInput struct {
|
||||||
|
// Executable is the path to the git executable
|
||||||
|
Executable string
|
||||||
|
// WorkingDir is the path to the working directory
|
||||||
|
WorkingDir *string
|
||||||
|
// MainBranch is the name of the main branch
|
||||||
|
MainBranch string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGit creates a new Git
|
||||||
|
func NewGit(input *NewGitInput) *Git {
|
||||||
|
git := &Git{
|
||||||
|
Executable: input.Executable,
|
||||||
|
}
|
||||||
|
|
||||||
|
if git.Executable == "" {
|
||||||
|
git.Executable = "git"
|
||||||
|
}
|
||||||
|
if git.MainBranch == "" {
|
||||||
|
git.MainBranch = "main"
|
||||||
|
}
|
||||||
|
|
||||||
|
return git
|
||||||
|
}
|
23
git/pull.go
Normal file
23
git/pull.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
// Pull pulls the latest changes from the remote
|
||||||
|
func (g *Git) Pull() error {
|
||||||
|
|
||||||
|
_, err := g.Execute("pull")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PullMain pulls the latest changes from the remote main branch
|
||||||
|
func (g *Git) PullMain() error {
|
||||||
|
|
||||||
|
_, err := g.Execute("pull", "origin", g.MainBranch)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
72
git/squash.go
Normal file
72
git/squash.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SquashInput contains the input for Squash
|
||||||
|
type SquashInput struct {
|
||||||
|
Message *string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Squash squashes everything every commit ahead of main into one commit
|
||||||
|
func (g *Git) Squash(input SquashInput) error {
|
||||||
|
|
||||||
|
// Get the current commit hash
|
||||||
|
hash, err := g.GetHash()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the commit hash on the remote
|
||||||
|
remote, err := g.GetCommitRemote()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the hashes are the same, there's nothing to squash
|
||||||
|
if hash == remote {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the number of commits ahead of main
|
||||||
|
commits, err := g.GetCommitsAhead()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
message := ""
|
||||||
|
|
||||||
|
if input.Message != nil {
|
||||||
|
message = *input.Message
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Get array of commit messages
|
||||||
|
out, err := g.Execute("log", "--pretty=format:%s", "-n", strconv.Itoa(commits))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
messages := strings.Split(out, "\n")
|
||||||
|
|
||||||
|
// Add `-` to each message
|
||||||
|
for i, m := range messages {
|
||||||
|
messages[i] = "- " + m
|
||||||
|
}
|
||||||
|
|
||||||
|
// Join the messages
|
||||||
|
message = strings.Join(messages, "\n")
|
||||||
|
|
||||||
|
// Add header comment
|
||||||
|
message = "# Squashed " + strconv.Itoa(commits) + " commits\n\n" + message
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Squash the current commit into the previous commits
|
||||||
|
_, err = g.Execute("rebase", "-i", hash+"~"+strconv.Itoa(commits), "-x", "git commit --amend -m \""+message+"\" ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
11
go.mod
Normal file
11
go.mod
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
module gitea.layla.gg/layla/gsquash
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/magefile/mage v1.15.0 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/stretchr/testify v1.8.4 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
)
|
11
go.sum
Normal file
11
go.sum
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg=
|
||||||
|
github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
22
magefile.go
Normal file
22
magefile.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//go:build mage
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/magefile/mage/sh"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Build builds the binary
|
||||||
|
func Build() error {
|
||||||
|
return sh.RunV("go", "build", "-o", "gsquash", "main.go")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Install installs the binary
|
||||||
|
func Install() error {
|
||||||
|
return sh.RunV("go", "install")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test runs the tests
|
||||||
|
func Test() error {
|
||||||
|
return sh.RunV("go", "test", "./...")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user