Repository: j178/leetgo (language: python)

Issue:
[Feature] If the local test run fails, it should return a non-zero return value
### Verification steps

- [X]  我已经在 [Issue Tracker](https://github.com/j178/leetgo/issues) 中找过我要提出的请求 I have searched on the [Issue Tracker](https://github.com/j178/leetgo/issues) for a related feature request. 

### Description

<img width="675" alt="image" src="https://github.com/j178/leetgo/assets/34479567/63c323ad-584c-43bf-9789-1cc917c1a9dd">
In this case, the return value of "echo "$?"" should be 127


Discussion / hints:

Fix patch:
diff --git a/cmd/root.go b/cmd/root.go
index 24675e7b..e66a705d 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -1,6 +1,7 @@
 package cmd
 
 import (
+	"errors"
 	"fmt"
 	"os"
 	"runtime"
@@ -40,9 +41,19 @@ var rootCmd = &cobra.Command{
 	SilenceUsage:  true,
 }
 
+type exitCode int
+
+func (e exitCode) Error() string {
+	return fmt.Sprintf("exit code %d", e)
+}
+
 func Execute() {
 	err := rootCmd.Execute()
 	if err != nil {
+		var e exitCode
+		if errors.As(err, &e) {
+			os.Exit(int(e))
+		}
 		log.Fatal(err)
 	}
 }
diff --git a/cmd/submit.go b/cmd/submit.go
index 6facaf5f..e2668faf 100644
--- a/cmd/submit.go
+++ b/cmd/submit.go
@@ -43,16 +43,19 @@ leetgo submit w330/
 		}
 		limiter := newLimiter(user)
 
+		var hasFailedCase bool
 		for _, q := range qs {
 			log.Info("submitting solution", "question", q.TitleSlug, "user", user.Whoami(c))
 			result, err := submitSolution(cmd, q, c, gen, limiter)
 			if err != nil {
+				hasFailedCase = true
 				log.Error("failed to submit solution", "err", err)
 				continue
 			}
 			cmd.Print(result.Display(qs[0]))
 
 			if !result.Accepted() {
+				hasFailedCase = true
 				added, _ := appendToTestCases(q, result)
 				if added {
 					log.Info("added failed case to testcases.txt")
@@ -60,6 +63,10 @@ leetgo submit w330/
 			}
 		}
 
+		if hasFailedCase {
+			return exitCode(1)
+		}
+
 		return nil
 	},
 }


Test patch:
diff --git a/cmd/test.go b/cmd/test.go
index 6d7ea445..bdf585bc 100644
--- a/cmd/test.go
+++ b/cmd/test.go
@@ -87,8 +87,13 @@ leetgo test w330/`,
 		testLimiter := newLimiter(user)
 		submitLimiter := newLimiter(user)
 
+		var hasFailedCase bool
 		for _, q := range qs {
-			localPassed, remotePassed := true, true
+			var (
+				localPassed    = true
+				remotePassed   = true
+				submitAccepted = true
+			)
 			if runLocally {
 				log.Info("running test locally", "question", q.TitleSlug)
 				localPassed, err = lang.RunLocalTest(q, targetCase)
@@ -112,11 +117,12 @@ leetgo test w330/`,
 				log.Info("submitting solution", "user", user.Whoami(c))
 				result, err := submitSolution(cmd, q, c, gen, submitLimiter)
 				if err != nil {
+					submitAccepted = false
 					log.Error("failed to submit solution", "err", err)
 				} else {
 					cmd.Print(result.Display(q))
-
 					if !result.Accepted() {
+						submitAccepted = false
 						added, _ := appendToTestCases(q, result)
 						if added {
 							log.Info("added failed case to testcases.txt")
@@ -124,6 +130,14 @@ leetgo test w330/`,
 					}
 				}
 			}
+
+			if !localPassed || !remotePassed || !submitAccepted {
+				hasFailedCase = true
+			}
+		}
+
+		if hasFailedCase {
+			return exitCode(1)
 		}
 		return nil
 	},