-
-
Notifications
You must be signed in to change notification settings - Fork 47
Fix the suffix bug in Windows #16
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -11,6 +11,7 @@ import ( | |||||||||||||||||||
| "os/exec" | ||||||||||||||||||||
| "path/filepath" | ||||||||||||||||||||
| "regexp" | ||||||||||||||||||||
| "runtime" | ||||||||||||||||||||
| "text/tabwriter" | ||||||||||||||||||||
| "time" | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -24,13 +25,17 @@ const exercisesDir = "exercises" | |||||||||||||||||||
| // maxRuntime is the maximum time an exercise is allowed to run in watch mode. | ||||||||||||||||||||
| const maxRuntime = 5 * time.Second | ||||||||||||||||||||
|
|
||||||||||||||||||||
| var reStillGoing = regexp.MustCompile(`(?m)^\s*//\s+I\s+AM\s+STILL\s+GOING`) | ||||||||||||||||||||
| var reExercise = regexp.MustCompile(`^(?P<id>\d+)-(?P<name>.+)$`) | ||||||||||||||||||||
| var ( | ||||||||||||||||||||
| reStillGoing = regexp.MustCompile(`(?m)^\s*//\s+I\s+AM\s+STILL\s+GOING`) | ||||||||||||||||||||
| reExercise = regexp.MustCompile(`^(?P<id>\d+)-(?P<name>.+)$`) | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| var plain = color.New() | ||||||||||||||||||||
| var red = color.New(color.FgRed) | ||||||||||||||||||||
| var yellow = color.New(color.FgYellow) | ||||||||||||||||||||
| var green = color.New(color.FgGreen) | ||||||||||||||||||||
| var ( | ||||||||||||||||||||
| plain = color.New() | ||||||||||||||||||||
| red = color.New(color.FgRed) | ||||||||||||||||||||
| yellow = color.New(color.FgYellow) | ||||||||||||||||||||
| green = color.New(color.FgGreen) | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| var rootCmd = &cobra.Command{ | ||||||||||||||||||||
| Use: "gopherlings", | ||||||||||||||||||||
|
|
@@ -47,8 +52,10 @@ func init() { | |||||||||||||||||||
| func main() { | ||||||||||||||||||||
| err := rootCmd.Execute() | ||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||
| red.Fprintln(os.Stderr, err) | ||||||||||||||||||||
| os.Exit(1) | ||||||||||||||||||||
| _, err = red.Fprintln(os.Stderr, err) | ||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||
| os.Exit(1) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -62,13 +69,25 @@ func errExit(err error) { | |||||||||||||||||||
|
|
||||||||||||||||||||
| if errors.Is(err, ErrAllDone) { | ||||||||||||||||||||
| // Error: success ;) | ||||||||||||||||||||
| plain.Printf(goBuildSomething) | ||||||||||||||||||||
| _, err = plain.Printf(goBuildSomething) | ||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||
| os.Exit(1) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| os.Exit(0) | ||||||||||||||||||||
| } else if errors.Is(err, ErrNoExercisesDir) { | ||||||||||||||||||||
| red.Fprintln(os.Stderr, `No "exercises" directory.`) | ||||||||||||||||||||
| red.Fprintln(os.Stderr, "Please run this from the root of a Gopherlings repo checkout.") | ||||||||||||||||||||
| _, err = red.Fprintln(os.Stderr, `No "exercises" directory.`) | ||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||
| os.Exit(1) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| _, err = red.Fprintln(os.Stderr, "Please run this from the root of a Gopherlings repo checkout.") | ||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||
| os.Exit(1) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } else { | ||||||||||||||||||||
| red.Fprintln(os.Stderr, err) | ||||||||||||||||||||
| _, err = red.Fprintln(os.Stderr, err) | ||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||
| os.Exit(1) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| os.Exit(1) | ||||||||||||||||||||
|
|
@@ -344,45 +363,53 @@ func runPkg(ctx context.Context, pkgPath string) error { | |||||||||||||||||||
| // subprocess if the context is canceled. | ||||||||||||||||||||
|
|
||||||||||||||||||||
| plain.Println("Compiling", pkgPath) | ||||||||||||||||||||
| f, err := compilePkg(ctx, pkgPath) | ||||||||||||||||||||
| tmpPath, err := compilePkg(ctx, pkgPath) | ||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| defer os.Remove(f.Name()) | ||||||||||||||||||||
| defer os.Remove(tmpPath) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| plain.Println("Executing", pkgPath) | ||||||||||||||||||||
| plain.Println() | ||||||||||||||||||||
| return execFile(ctx, f) | ||||||||||||||||||||
| return execFile(ctx, tmpPath) | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| func compilePkg(ctx context.Context, pkg string) (*os.File, error) { | ||||||||||||||||||||
| func compilePkg(ctx context.Context, pkg string) (string, error) { | ||||||||||||||||||||
| name := filepath.Base(pkg) | ||||||||||||||||||||
| if runtime.GOOS == "windows" { | ||||||||||||||||||||
| name += ".exe" | ||||||||||||||||||||
| } | ||||||||||||||||||||
| f, err := os.CreateTemp("", name) | ||||||||||||||||||||
|
Comment on lines
+379
to
382
|
||||||||||||||||||||
| if runtime.GOOS == "windows" { | |
| name += ".exe" | |
| } | |
| f, err := os.CreateTemp("", name) | |
| pattern := name | |
| if runtime.GOOS == "windows" { | |
| pattern = name + "*.exe" | |
| } | |
| f, err := os.CreateTemp("", pattern) |
Copilot
AI
Mar 30, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The result of f.Close() is ignored. Since the file must be closed on Windows before it can be executed/overwritten reliably, handle the close error and clean up the temp file on failure.
| f.Close() | |
| if err := f.Close(); err != nil { | |
| // Best-effort cleanup if we fail to close the temp file. | |
| _ = os.Remove(tmpPath) | |
| return "", err | |
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,17 +1,17 @@ | ||
| module github.com/soypat/gopherlings | ||
|
|
||
| go 1.18 | ||
| go 1.26 | ||
|
|
||
| require ( | ||
| github.com/fatih/color v1.13.0 | ||
| github.com/fsnotify/fsnotify v1.5.4 | ||
| github.com/spf13/cobra v1.5.0 | ||
| github.com/fatih/color v1.19.0 | ||
| github.com/fsnotify/fsnotify v1.9.0 | ||
| github.com/spf13/cobra v1.10.2 | ||
|
Comment on lines
+3
to
+8
|
||
| ) | ||
|
|
||
| require ( | ||
| github.com/inconshreveable/mousetrap v1.0.0 // indirect | ||
| github.com/mattn/go-colorable v0.1.9 // indirect | ||
| github.com/mattn/go-isatty v0.0.14 // indirect | ||
| github.com/spf13/pflag v1.0.5 // indirect | ||
| golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect | ||
| github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||
| github.com/mattn/go-colorable v0.1.14 // indirect | ||
| github.com/mattn/go-isatty v0.0.20 // indirect | ||
| github.com/spf13/pflag v1.0.10 // indirect | ||
| golang.org/x/sys v0.42.0 // indirect | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,24 +1,22 @@ | ||
| github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= | ||
| github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= | ||
| github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= | ||
| github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= | ||
| github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= | ||
| github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= | ||
| github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | ||
| github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= | ||
| github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= | ||
| github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | ||
| github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= | ||
| github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= | ||
| github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= | ||
| github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= | ||
| github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= | ||
| github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= | ||
| github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= | ||
| github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= | ||
| github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= | ||
| github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= | ||
| github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= | ||
| github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= | ||
| github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= | ||
| github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= | ||
| github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= | ||
| github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= | ||
| github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | ||
| github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||
| golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
| golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
| golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
| golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= | ||
| golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
| github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= | ||
| github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= | ||
| github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||
| github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= | ||
| github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||
| go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= | ||
| golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= | ||
| golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= | ||
| golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= | ||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
| gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mainno longer exits with a non-zero status whenrootCmd.Execute()returns an error. After printing the error, the program falls through and returns exit code 0 unless printing fails, which will mask failures for callers/CI. Ensure the error path still callsos.Exit(1)(or returns an error tomain).