Skip to content

Commit d552f42

Browse files
miguelvelezsagemini-code-assist[bot]JoeWang1127
authored
refactor(internal/librarianops): move parseRepoFlags to its own file and rename it to parseFlags (#3927)
Rename parseRepoFlags function to parseFlags and move to its own file in order to use it for upgrade and generate commands. For #3911. --------- Signed-off-by: miguel <miguelvelezsa@gmail.com> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Joe Wang <106995533+JoeWang1127@users.noreply.github.com>
1 parent 0d4a69f commit d552f42

File tree

3 files changed

+175
-18
lines changed

3 files changed

+175
-18
lines changed

internal/librarianops/flags.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package librarianops
16+
17+
import (
18+
"fmt"
19+
"path/filepath"
20+
21+
"github.com/urfave/cli/v3"
22+
)
23+
24+
// parseFlags parses the command line flags for librarianops commands.
25+
func parseFlags(cmd *cli.Command) (repoName, workDir string, verbose bool, err error) {
26+
workDir = cmd.String("C")
27+
verbose = cmd.Bool("v")
28+
if workDir != "" {
29+
// When -C is provided, infer repo name from directory basename.
30+
repoName = filepath.Base(workDir)
31+
} else {
32+
// When -C is not provided, require positional repo argument.
33+
if cmd.Args().Len() == 0 {
34+
return "", "", verbose, fmt.Errorf("usage: librarianops <command> <repo> or librarianops <command> -C <dir>")
35+
}
36+
repoName = cmd.Args().Get(0)
37+
}
38+
return repoName, workDir, verbose, nil
39+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package librarianops
16+
17+
import (
18+
"context"
19+
"testing"
20+
21+
"github.com/google/go-cmp/cmp"
22+
"github.com/urfave/cli/v3"
23+
)
24+
25+
func TestParseFlags(t *testing.T) {
26+
app := &cli.Command{
27+
Name: "librarianops",
28+
Commands: []*cli.Command{
29+
{
30+
Name: "test-command",
31+
Flags: []cli.Flag{
32+
&cli.StringFlag{Name: "C"},
33+
&cli.BoolFlag{Name: "v"},
34+
},
35+
},
36+
},
37+
}
38+
for _, test := range []struct {
39+
name string
40+
args []string
41+
wantRepoName string
42+
wantWorkDir string
43+
wantVerbose bool
44+
}{
45+
{
46+
name: "with -C flag",
47+
args: []string{"librarianops", "test-command", "-C", "/path/to/repo"},
48+
wantRepoName: "repo",
49+
wantWorkDir: "/path/to/repo",
50+
wantVerbose: false,
51+
},
52+
{
53+
name: "with positional argument",
54+
args: []string{"librarianops", "test-command", "repo-name"},
55+
wantRepoName: "repo-name",
56+
wantWorkDir: "",
57+
wantVerbose: false,
58+
},
59+
{
60+
name: "with -v flag",
61+
args: []string{"librarianops", "test-command", "-v", "repo-name"},
62+
wantRepoName: "repo-name",
63+
wantWorkDir: "",
64+
wantVerbose: true,
65+
},
66+
{
67+
name: "with -C and -v",
68+
args: []string{"librarianops", "test-command", "-C", "/path/to/repo", "-v"},
69+
wantRepoName: "repo",
70+
wantWorkDir: "/path/to/repo",
71+
wantVerbose: true,
72+
},
73+
} {
74+
t.Run(test.name, func(t *testing.T) {
75+
var (
76+
repoName, workDir string
77+
verbose bool
78+
err error
79+
)
80+
app.Commands[0].Action = func(ctx context.Context, cmd *cli.Command) error {
81+
repoName, workDir, verbose, err = parseFlags(cmd)
82+
return err
83+
}
84+
85+
if err := app.Run(t.Context(), test.args); err != nil {
86+
t.Fatalf("app.Run() error = %v, wantErr %v", err, false)
87+
}
88+
89+
if diff := cmp.Diff(test.wantRepoName, repoName); diff != "" {
90+
t.Errorf("mismatch (-want +got):\n%s", diff)
91+
}
92+
if diff := cmp.Diff(test.wantWorkDir, workDir); diff != "" {
93+
t.Errorf("mismatch (-want +got):\n%s", diff)
94+
}
95+
if diff := cmp.Diff(test.wantVerbose, verbose); diff != "" {
96+
t.Errorf("mismatch (-want +got):\n%s", diff)
97+
}
98+
})
99+
}
100+
}
101+
102+
func TestParseFlags_Error(t *testing.T) {
103+
app := &cli.Command{
104+
Name: "librarianops",
105+
Commands: []*cli.Command{
106+
{
107+
Name: "test-command",
108+
Flags: []cli.Flag{
109+
&cli.StringFlag{Name: "C"},
110+
&cli.BoolFlag{Name: "v"},
111+
},
112+
},
113+
},
114+
}
115+
for _, test := range []struct {
116+
name string
117+
args []string
118+
}{
119+
{
120+
name: "no arguments",
121+
args: []string{"librarianops", "test-command"},
122+
},
123+
} {
124+
t.Run(test.name, func(t *testing.T) {
125+
app.Commands[0].Action = func(ctx context.Context, cmd *cli.Command) error {
126+
_, _, _, err := parseFlags(cmd)
127+
return err
128+
}
129+
if err := app.Run(t.Context(), test.args); err == nil {
130+
t.Fatalf("app.Run() error = %v, wantErr %v", err, true)
131+
}
132+
})
133+
}
134+
}

internal/librarianops/generate.go

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,32 +66,16 @@ For each repository, librarianops will:
6666
},
6767
},
6868
Action: func(ctx context.Context, cmd *cli.Command) error {
69-
repoName, workDir, err := parseRepoFlags(cmd)
69+
repoName, workDir, verbose, err := parseFlags(cmd)
7070
if err != nil {
7171
return err
7272
}
73+
command.Verbose = verbose
7374
return runGenerate(ctx, repoName, workDir)
7475
},
7576
}
7677
}
7778

78-
func parseRepoFlags(cmd *cli.Command) (repoName, workDir string, err error) {
79-
workDir = cmd.String("C")
80-
command.Verbose = cmd.Bool("v")
81-
82-
if workDir != "" {
83-
// When -C is provided, infer repo name from directory basename.
84-
repoName = filepath.Base(workDir)
85-
} else {
86-
// When -C is not provided, require positional repo argument.
87-
if cmd.Args().Len() == 0 {
88-
return "", "", fmt.Errorf("usage: librarianops <command> <repo> or librarianops <command> -C <dir>")
89-
}
90-
repoName = cmd.Args().Get(0)
91-
}
92-
return repoName, workDir, nil
93-
}
94-
9579
func runGenerate(ctx context.Context, repoName, repoDir string) error {
9680
if !supportedRepositories[repoName] {
9781
return fmt.Errorf("repository %q not found in supported repositories list", repoName)

0 commit comments

Comments
 (0)