diff --git a/cmd/commit.go b/cmd/commit.go new file mode 100644 index 000000000..e959dd067 --- /dev/null +++ b/cmd/commit.go @@ -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") +} diff --git a/cmd/patch.go b/cmd/patch.go index 6172acd84..0083ac163 100644 --- a/cmd/patch.go +++ b/cmd/patch.go @@ -1,6 +1,3 @@ -/* -Copyright © 2023 NAME HERE -*/ package cmd import ( @@ -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) }, } diff --git a/cmd/scaffold.go b/cmd/scaffold.go index db44ebd32..462ebe2e9 100644 --- a/cmd/scaffold.go +++ b/cmd/scaffold.go @@ -1,6 +1,3 @@ -/* -Copyright © 2023 NAME HERE -*/ package cmd import ( diff --git a/internal/pkg/commit/commit.go b/internal/pkg/commit/commit.go new file mode 100644 index 000000000..5462ae20e --- /dev/null +++ b/internal/pkg/commit/commit.go @@ -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 +} diff --git a/internal/pkg/commit/commit_test.go b/internal/pkg/commit/commit_test.go new file mode 100644 index 000000000..9419be114 --- /dev/null +++ b/internal/pkg/commit/commit_test.go @@ -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()) + }) +}) diff --git a/internal/pkg/patch/patch.go b/internal/pkg/patch/patch.go index 7d8c1d562..2823d13aa 100644 --- a/internal/pkg/patch/patch.go +++ b/internal/pkg/patch/patch.go @@ -5,7 +5,6 @@ import ( "fmt" "os" "os/exec" - "path/filepath" "regexp" "strings" @@ -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)) @@ -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) @@ -118,7 +115,6 @@ func fixPatchFile(workDir, patchFile string) error { } return nil - } // ExtractOriginalFilePathFromPatchString extracts the original file path from a patch string diff --git a/internal/pkg/patch/patch_test.go b/internal/pkg/patch/patch_test.go index 498abd72d..bd581972b 100644 --- a/internal/pkg/patch/patch_test.go +++ b/internal/pkg/patch/patch_test.go @@ -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()) @@ -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()) @@ -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()) }) @@ -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()) @@ -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())