Skip to content

Commit 882246b

Browse files
committed
Use MANPATH and fix linter
1 parent c9f34e6 commit 882246b

26 files changed

+520
-134
lines changed

.github/workflows/unit_test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
- "macos-latest"
2020
go:
2121
- "1"
22+
- "1.25"
2223
- "1.24"
2324
fail-fast: false
2425
runs-on: ${{ matrix.os }}

.golangci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
version: "2"
22
run:
3-
go: "1.20"
3+
go: "1.24"
44
linters:
55
default: none
66
enable:

cmd/bug_report.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func newBugReportCmd() *cobra.Command {
2626
type openBrowserFunc func(string) bool
2727

2828
// bugReport opens the default browser to start a bug report which will include useful system information.
29-
func bugReport(cmd *cobra.Command, _ []string, openBrowser openBrowserFunc) int { //nolint
29+
func bugReport(cmd *cobra.Command, _ []string, openBrowser openBrowserFunc) int {
3030
var buf bytes.Buffer
3131

3232
const (

cmd/bug_report_linux.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
package cmd
44

55
import (
6+
"context"
67
"os/exec"
78
)
89

910
func openBrowser(targetURL string) bool {
10-
return exec.Command("xdg-open", targetURL).Start() == nil
11+
return exec.CommandContext(context.Background(), "xdg-open", targetURL).Start() == nil
1112
}

cmd/check.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,9 @@ func printUpdatablePkgInfo(pkgs []goutil.Package) {
147147
for _, v := range pkgs {
148148
p += v.Name + " "
149149
}
150+
const indentSpaces = 11
150151
fmt.Println("")
151152
print.Info("If you want to update binaries, run the following command.\n" +
152-
strings.Repeat(" ", 11) +
153+
strings.Repeat(" ", indentSpaces) +
153154
"$ gup update " + p)
154155
}

cmd/check_test.go

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//nolint:paralleltest,errcheck,gosec
12
package cmd
23

34
import (
@@ -70,6 +71,68 @@ func Test_check(t *testing.T) {
7071
}
7172
}
7273

74+
func Test_CheckOption(t *testing.T) {
75+
type args struct {
76+
cmd *cobra.Command
77+
args []string
78+
}
79+
tests := []struct {
80+
name string
81+
args args
82+
want int
83+
stderr []string
84+
}{
85+
{
86+
name: "parser --jobs argument error",
87+
args: args{
88+
cmd: &cobra.Command{},
89+
args: []string{},
90+
},
91+
want: 1,
92+
stderr: []string{
93+
"gup:ERROR: can not parse command line argument (--jobs): flag accessed but not defined: jobs",
94+
"",
95+
},
96+
},
97+
}
98+
for _, tt := range tests {
99+
t.Run(tt.name, func(t *testing.T) {
100+
OsExit = func(code int) {}
101+
defer func() {
102+
OsExit = os.Exit
103+
}()
104+
105+
orgStdout := print.Stdout
106+
orgStderr := print.Stderr
107+
pr, pw, err := os.Pipe()
108+
if err != nil {
109+
t.Fatal(err)
110+
}
111+
print.Stdout = pw
112+
print.Stderr = pw
113+
114+
if got := check(tt.args.cmd, tt.args.args); got != tt.want {
115+
t.Errorf("check() = %v, want %v", got, tt.want)
116+
}
117+
pw.Close()
118+
print.Stdout = orgStdout
119+
print.Stderr = orgStderr
120+
121+
buf := bytes.Buffer{}
122+
_, err = io.Copy(&buf, pr)
123+
if err != nil {
124+
t.Error(err)
125+
}
126+
defer pr.Close()
127+
got := strings.Split(buf.String(), "\n")
128+
129+
if diff := cmp.Diff(tt.stderr, got); diff != "" {
130+
t.Errorf("value is mismatch (-want +got):\n%s", diff)
131+
}
132+
})
133+
}
134+
}
135+
73136
func Test_check_not_use_go_cmd(t *testing.T) {
74137
t.Run("Not found go command", func(t *testing.T) {
75138
t.Setenv("PATH", "")
@@ -99,7 +162,7 @@ func Test_check_not_use_go_cmd(t *testing.T) {
99162
got := strings.Split(buf.String(), "\n")
100163

101164
want := []string{}
102-
if runtime.GOOS == "windows" {
165+
if runtime.GOOS == goosWindows {
103166
want = append(want, `gup:ERROR: you didn't install golang: exec: "go": executable file not found in %PATH%`)
104167
want = append(want, "")
105168
} else {
@@ -114,7 +177,6 @@ func Test_check_not_use_go_cmd(t *testing.T) {
114177

115178
func Test_check_gobin_is_empty(t *testing.T) {
116179
type args struct {
117-
cmd *cobra.Command
118180
args []string
119181
}
120182
tests := []struct {
@@ -136,7 +198,7 @@ func Test_check_gobin_is_empty(t *testing.T) {
136198
},
137199
}
138200

139-
if runtime.GOOS == "windows" {
201+
if runtime.GOOS == goosWindows {
140202
tests = append(tests, struct {
141203
name string
142204
gobin string

cmd/export_test.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//nolint:paralleltest
12
package cmd
23

34
import (
@@ -66,7 +67,9 @@ func Test_export_not_use_go_cmd(t *testing.T) {
6667
if got := export(&cobra.Command{}, []string{}); got != 1 {
6768
t.Errorf("export() = %v, want %v", got, 1)
6869
}
69-
pw.Close()
70+
if err := pw.Close(); err != nil {
71+
t.Fatal(err)
72+
}
7073
print.Stdout = orgStdout
7174
print.Stderr = orgStderr
7275

@@ -75,11 +78,13 @@ func Test_export_not_use_go_cmd(t *testing.T) {
7578
if err != nil {
7679
t.Error(err)
7780
}
78-
defer pr.Close()
81+
defer func() {
82+
_ = pr.Close()
83+
}()
7984
got := strings.Split(buf.String(), "\n")
8085

8186
want := []string{}
82-
if runtime.GOOS == "windows" {
87+
if runtime.GOOS == goosWindows {
8388
want = append(want, `gup:ERROR: you didn't install golang: exec: "go": executable file not found in %PATH%`)
8489
want = append(want, "")
8590
} else {
@@ -119,10 +124,10 @@ func Test_export(t *testing.T) {
119124
},
120125
}
121126

122-
if runtime.GOOS == "windows" {
127+
if runtime.GOOS == goosWindows {
123128
tests = append(tests, struct {
124129
name string
125-
args []string
130+
args []string
126131
gobin string
127132
want int
128133
stderr []string
@@ -139,7 +144,7 @@ func Test_export(t *testing.T) {
139144
} else {
140145
tests = append(tests, struct {
141146
name string
142-
args []string
147+
args []string
143148
gobin string
144149
want int
145150
stderr []string
@@ -179,7 +184,9 @@ func Test_export(t *testing.T) {
179184
if got := export(newExportCmd(), tt.args); got != tt.want {
180185
t.Errorf("export() = %v, want %v", got, tt.want)
181186
}
182-
pw.Close()
187+
if err := pw.Close(); err != nil {
188+
t.Fatal(err)
189+
}
183190
print.Stdout = orgStdout
184191
print.Stderr = orgStderr
185192

@@ -188,7 +195,9 @@ func Test_export(t *testing.T) {
188195
if err != nil {
189196
t.Error(err)
190197
}
191-
defer pr.Close()
198+
defer func() {
199+
_ = pr.Close()
200+
}()
192201
got := strings.Split(buf.String(), "\n")
193202

194203
if tt.name != "can not make .config directory" {

cmd/list.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func newListCmd() *cobra.Command {
2323
}
2424
}
2525

26-
func list(cmd *cobra.Command, args []string) int {
26+
func list(_ *cobra.Command, _ []string) int {
2727
if err := goutil.CanUseGoCmd(); err != nil {
2828
print.Err(fmt.Errorf("%s: %w", "you didn't install golang", err))
2929
return 1
@@ -54,7 +54,7 @@ func printPackageList(pkgs []goutil.Package) {
5454
}
5555

5656
for _, v := range pkgs {
57-
fmt.Fprintf(print.Stdout, "%"+strconv.Itoa(max)+"s: %s%s\n",
57+
_, _ = fmt.Fprintf(print.Stdout, "%"+strconv.Itoa(max)+"s: %s%s\n",
5858
v.Name,
5959
v.ImportPath,
6060
color.GreenString("@"+v.Version.Current))

cmd/list_test.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ func Test_list_not_found_go_command(t *testing.T) {
3030
if got := list(&cobra.Command{}, []string{}); got != 1 {
3131
t.Errorf("list() = %v, want %v", got, 1)
3232
}
33-
pw.Close()
33+
if err := pw.Close(); err != nil {
34+
t.Fatal(err)
35+
}
3436
print.Stdout = orgStdout
3537
print.Stderr = orgStderr
3638

@@ -39,11 +41,13 @@ func Test_list_not_found_go_command(t *testing.T) {
3941
if err != nil {
4042
t.Error(err)
4143
}
42-
defer pr.Close()
44+
defer func() {
45+
_ = pr.Close()
46+
}()
4347
got := strings.Split(buf.String(), "\n")
4448

4549
want := []string{}
46-
if runtime.GOOS == "windows" {
50+
if runtime.GOOS == goosWindows {
4751
want = append(want, `gup:ERROR: you didn't install golang: exec: "go": executable file not found in %PATH%`)
4852
want = append(want, "")
4953
} else {
@@ -79,7 +83,7 @@ func Test_list_gobin_is_empty(t *testing.T) {
7983
},
8084
},
8185
}
82-
if runtime.GOOS == "windows" {
86+
if runtime.GOOS == goosWindows {
8387
tests = append(tests, struct {
8488
name string
8589
gobin string
@@ -115,7 +119,7 @@ func Test_list_gobin_is_empty(t *testing.T) {
115119
})
116120
}
117121

118-
if err := os.Mkdir(filepath.Join("testdata", "empty_dir"), 0755); err != nil {
122+
if err := os.Mkdir(filepath.Join("testdata", "empty_dir"), 0o755); err != nil { //nolint:gosec
119123
t.Fatal(err)
120124
}
121125

@@ -135,7 +139,9 @@ func Test_list_gobin_is_empty(t *testing.T) {
135139
if got := list(tt.args.cmd, tt.args.args); got != tt.want {
136140
t.Errorf("list() = %v, want %v", got, tt.want)
137141
}
138-
pw.Close()
142+
if err := pw.Close(); err != nil {
143+
t.Fatal(err)
144+
}
139145
print.Stdout = orgStdout
140146
print.Stderr = orgStderr
141147

@@ -144,7 +150,9 @@ func Test_list_gobin_is_empty(t *testing.T) {
144150
if err != nil {
145151
t.Error(err)
146152
}
147-
defer pr.Close()
153+
defer func() {
154+
_ = pr.Close()
155+
}()
148156
got := strings.Split(buf.String(), "\n")
149157

150158
if diff := cmp.Diff(tt.stderr, got); diff != "" {

cmd/man.go

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,44 @@ func newManCmd() *cobra.Command {
2929
return cmd
3030
}
3131

32-
func man(cmd *cobra.Command, args []string) int { //nolint
33-
if err := generateManpages(filepath.Join("/", "usr", "share", "man", "man1")); err != nil {
34-
print.Err(fmt.Errorf("%s: %w", "can not generate man-pages", err))
35-
return 1
32+
func man(_ *cobra.Command, _ []string) int {
33+
for _, dst := range manPaths(os.Getenv("MANPATH")) {
34+
if err := generateManpages(dst); err != nil {
35+
print.Err(fmt.Errorf("can not generate man-pages in %s: %w", dst, err))
36+
return 1
37+
}
3638
}
3739
return 0
3840
}
3941

42+
// manPaths normalizes MANPATH entries into man1 directories.
43+
// Empty or invalid MANPATH falls back to /usr/share/man/man1.
44+
func manPaths(manpathEnv string) []string {
45+
defaultPath := filepath.Join("/", "usr", "share", "man", "man1")
46+
if manpathEnv == "" {
47+
return []string{defaultPath}
48+
}
49+
50+
paths := make([]string, 0)
51+
for _, p := range strings.Split(manpathEnv, ":") {
52+
p = filepath.Clean(strings.TrimSpace(p))
53+
if p == "" || p == "." {
54+
continue
55+
}
56+
57+
if filepath.Base(p) != "man1" {
58+
p = filepath.Join(p, "man1")
59+
}
60+
paths = append(paths, p)
61+
}
62+
63+
if len(paths) == 0 {
64+
return []string{defaultPath}
65+
}
66+
67+
return paths
68+
}
69+
4070
func generateManpages(dst string) error {
4171
now := time.Now()
4272
header := &doc.GenManHeader{

0 commit comments

Comments
 (0)