Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add dtm commit -m Command Implementation #1499

Merged
merged 1 commit into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions cmd/commit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package cmd

import (
"os"

"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/devstream-io/devstream/internal/log"
"github.com/devstream-io/devstream/internal/pkg/commit"
"github.com/devstream-io/devstream/internal/response"
)

// commitCmd represents the commit command
var commitCmd = &cobra.Command{
Use: "commit",
Short: "commit is used to execute git commit operations",
Long: `commit is used to execute git commit operations

e.g.

1. dtm commit -m "commit message"
`,
Run: func(cmd *cobra.Command, args []string) {
message := viper.GetString("message")
if message == "" {
log.Error("message is required")
os.Exit(1)
}
err := commit.Commit(message)
if err != nil {
log.Errorf("commit error: %v", err)
r := response.New(response.StatusError, response.MessageError, err.Error())
r.Print(OutputFormat)
} else {
r := response.New(response.StatusOK, response.MessageOK, "")
r.Print(OutputFormat)
}
},
}

func init() {
rootCmd.AddCommand(commitCmd)
commitCmd.Flags().StringP("message", "m", "", "commit message")
}
13 changes: 5 additions & 8 deletions cmd/patch.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
Expand Down Expand Up @@ -32,15 +29,15 @@ e.g.
log.Error("Incorrect number of arguments")
os.Exit(1)
}
err := patch.Patch(".", args[0])
err := patch.Patch(args[0])
if err != nil {
log.Error(err)
log.Errorf("patch error: %v", err)
r := response.New(response.StatusError, response.MessageError, err.Error())
r.Print(OutputFormat)
os.Exit(1)
} else {
r := response.New(response.StatusOK, response.MessageOK, "")
r.Print(OutputFormat)
}
r := response.New(response.StatusOK, response.MessageOK, "")
r.Print(OutputFormat)
},
}

Expand Down
3 changes: 0 additions & 3 deletions cmd/scaffold.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
/*
Copyright © 2023 NAME HERE <EMAIL ADDRESS>
*/
package cmd

import (
Expand Down
29 changes: 29 additions & 0 deletions internal/pkg/commit/commit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package commit

import (
"fmt"
"os/exec"
"strings"

"github.com/devstream-io/devstream/internal/log"
)

// Commit is used to execute git commit operations
func Commit(message string) error {
// Check if the git command exists
gitPath, err := exec.LookPath("git")
if err != nil {
return fmt.Errorf("git command not found: %w", err)
}

cmd := exec.Command(gitPath, "commit", "-m", message)
output, err := cmd.CombinedOutput()
outputStr := strings.TrimSpace(string(output))

if err != nil {
return fmt.Errorf("git commit failed: %w\nOutput: %s", err, outputStr)
}

log.Infof("Successfully committed the file")
return nil
}
77 changes: 77 additions & 0 deletions internal/pkg/commit/commit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package commit_test

import (
"os"
"os/exec"
"path/filepath"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

. "github.com/devstream-io/devstream/internal/pkg/commit"
)

var _ = Describe("Commit", func() {
var testRepoDir string

BeforeEach(func() {
// 1. Create a temporary directory
var err error
testRepoDir, err = os.MkdirTemp("", "test-repo-*")
Expect(err).NotTo(HaveOccurred())

// 2. Change the working directory to the temporary directory
err = os.Chdir(testRepoDir)
Expect(err).NotTo(HaveOccurred())

// 3. Initialize a git repository
cmd := exec.Command("git", "init")
err = cmd.Run()
Expect(err).NotTo(HaveOccurred())

// 4. Create a file and write some content to it
file, err := os.Create(filepath.Join(testRepoDir, "test.txt"))
Expect(err).NotTo(HaveOccurred())

_, err = file.WriteString("Test content")
Expect(err).NotTo(HaveOccurred())
file.Close()

// 5. Add the file to the git index
cmd = exec.Command("git", "add", "test.txt")
err = cmd.Run()
Expect(err).NotTo(HaveOccurred())
})

AfterEach(func() {
err := os.RemoveAll(testRepoDir)
Expect(err).NotTo(HaveOccurred())
})

It("should create a new commit with the given message", func() {
message := "Test commit"
err := Commit(message)
Expect(err).NotTo(HaveOccurred())

cmd := exec.Command("git", "log", "--oneline")
output, err := cmd.CombinedOutput()
Expect(err).NotTo(HaveOccurred())

Expect(string(output)).To(ContainSubstring(message))
})

It("should return an error when git is not installed", func() {
origGitPath, err := exec.LookPath("git")
Expect(err).NotTo(HaveOccurred())

err = os.Setenv("PATH", "")
Expect(err).NotTo(HaveOccurred())
defer func() {
err = os.Setenv("PATH", origGitPath)
Expect(err).NotTo(HaveOccurred())
}()

err = Commit("Test commit")
Expect(err).To(HaveOccurred())
})
})
18 changes: 7 additions & 11 deletions internal/pkg/patch/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"

Expand All @@ -20,24 +19,23 @@ const (
type ProcessOption string

// Patch calls the patch command to apply a diff file to an original
func Patch(workDir, patchFile string) error {
func Patch(patchFile string) error {
log.Infof("Patching file: %s", patchFile)

// Fix patch file if it mixed tab and space indentation
err := fixPatchFile(workDir, patchFile)
err := fixPatchFile(patchFile)
if err != nil {
return fmt.Errorf("patch file fix failed: %w", err)
}

// Check if the patch command exists and is executable
err = checkPatchCommand()
// Check if the patch command exists
patchPath, err := exec.LookPath("patch")
if err != nil {
return fmt.Errorf("patch command check failed: %w", err)
return fmt.Errorf("patch command not found: %w", err)
}

// Use the patch tool to apply the patch
cmd := exec.Command("patch", "-i", patchFile, "-t", "-p0")
cmd.Dir = workDir
cmd := exec.Command(patchPath, "-i", patchFile, "-t", "-p0")
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("patch command failed: %w\nOutput: %s", err, string(output))
Expand Down Expand Up @@ -73,10 +71,9 @@ func checkPatchCommand() error {
// The original file path is contained in the patch file, so we can use the fix the patch file by using the original file.
// If the original file uses tab indentation, we replace all spaces with tabs in the patch file.
// If the original file uses space indentation, we replace all tabs with spaces in the patch file.
func fixPatchFile(workDir, patchFile string) error {
func fixPatchFile(patchFile string) error {
// Read the original file path from the patch file
originalFilePath, err := extractOriginalFilePathFromPatchFile(patchFile)
originalFilePath = filepath.Join(workDir, originalFilePath)

if err != nil {
return fmt.Errorf("failed to extract original file path from patch string: %w", err)
Expand Down Expand Up @@ -118,7 +115,6 @@ func fixPatchFile(workDir, patchFile string) error {
}

return nil

}

// ExtractOriginalFilePathFromPatchString extracts the original file path from a patch string
Expand Down
14 changes: 10 additions & 4 deletions internal/pkg/patch/patch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@ var _ = Describe("Patcher", func() {
)

BeforeEach(func() {
// 1. Create a temporary directory
var err error
tempDir, err = os.MkdirTemp("", "patcher-tests")
Expect(err).NotTo(HaveOccurred())

// 2. Change the working directory to the temporary directory
err = os.Chdir(tempDir)
Expect(err).NotTo(HaveOccurred())

// 3. Create the original file and the patch file
originalFile, err = os.CreateTemp(tempDir, "original-*")
Expect(err).NotTo(HaveOccurred())

Expand Down Expand Up @@ -63,7 +69,7 @@ This is the original file.
err = os.WriteFile(patchFile.Name(), []byte(patchContent), 0644)
Expect(err).NotTo(HaveOccurred())

err = Patch(tempDir, patchFile.Name())
err = Patch(patchFile.Name())
Expect(err).NotTo(HaveOccurred())

patchedContent, err := os.ReadFile(originalFile.Name())
Expand Down Expand Up @@ -93,7 +99,7 @@ This is the original file.
err = os.WriteFile(patchFile.Name(), []byte(invalidPatchContent), 0644)
Expect(err).NotTo(HaveOccurred())

err = Patch(tempDir, patchFile.Name())
err = Patch(patchFile.Name())
Expect(err).To(HaveOccurred())
Expect(strings.Contains(err.Error(), "patch command failed")).To(BeTrue())
})
Expand All @@ -118,7 +124,7 @@ This is the original file.
err = os.WriteFile(patchFile.Name(), []byte(patchContent), 0644)
Expect(err).NotTo(HaveOccurred())

err = Patch(tempDir, patchFile.Name())
err = Patch(patchFile.Name())
Expect(err).NotTo(HaveOccurred())

patchedContent, err := os.ReadFile(originalFile.Name())
Expand Down Expand Up @@ -146,7 +152,7 @@ This is the original file.
err = os.WriteFile(patchFile.Name(), []byte(patchContent), 0644)
Expect(err).NotTo(HaveOccurred())

err = Patch(tempDir, patchFile.Name())
err = Patch(patchFile.Name())
Expect(err).NotTo(HaveOccurred())

patchedContent, err := os.ReadFile(originalFile.Name())
Expand Down