Skip to content

Commit 7dbde87

Browse files
authored
feat: add config pkg for commands (#12)
Signed-off-by: Gaius <[email protected]>
1 parent 7eac79a commit 7dbde87

File tree

10 files changed

+173
-47
lines changed

10 files changed

+173
-47
lines changed

cmd/modctl/build.go

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,14 @@ import (
2020
"context"
2121
"fmt"
2222

23+
"github.com/CloudNativeAI/modctl/pkg/config"
2324
"github.com/CloudNativeAI/modctl/pkg/oci"
2425

2526
"github.com/spf13/cobra"
2627
"github.com/spf13/viper"
2728
)
2829

29-
var buildOpts = buildOptions{}
30-
31-
type buildOptions struct {
32-
target string
33-
modelfile string
34-
}
30+
var buildConfig = config.NewBuild()
3531

3632
// buildCmd represents the modctl command for build.
3733
var buildCmd = &cobra.Command{
@@ -42,15 +38,19 @@ var buildCmd = &cobra.Command{
4238
SilenceUsage: true,
4339
FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
4440
RunE: func(cmd *cobra.Command, args []string) error {
41+
if err := buildConfig.Validate(); err != nil {
42+
return err
43+
}
44+
4545
return runBuild(context.Background(), args[0])
4646
},
4747
}
4848

4949
// init initializes build command.
5050
func init() {
5151
flags := buildCmd.Flags()
52-
flags.StringVarP(&buildOpts.target, "target", "t", "", "target model artifact name")
53-
flags.StringVarP(&buildOpts.modelfile, "modelfile", "f", "", "model file path")
52+
flags.StringVarP(&buildConfig.Target, "target", "t", "", "target model artifact name")
53+
flags.StringVarP(&buildConfig.Modelfile, "modelfile", "f", "", "model file path")
5454

5555
if err := viper.BindPFlags(flags); err != nil {
5656
panic(fmt.Errorf("bind cache list flags to viper: %w", err))
@@ -59,18 +59,10 @@ func init() {
5959

6060
// runBuild runs the build modctl.
6161
func runBuild(ctx context.Context, workDir string) error {
62-
if len(buildOpts.target) == 0 {
63-
return fmt.Errorf("target model artifact name is required")
64-
}
65-
66-
if len(buildOpts.modelfile) == 0 {
67-
buildOpts.modelfile = "Modelfile"
68-
}
69-
70-
if err := oci.Build(ctx, buildOpts.modelfile, workDir, buildOpts.target); err != nil {
62+
if err := oci.Build(ctx, buildConfig.Modelfile, workDir, buildConfig.Target); err != nil {
7163
return err
7264
}
7365

74-
fmt.Printf("Successfully built model artifact: %s\n", buildOpts.target)
66+
fmt.Printf("Successfully built model artifact: %s\n", buildConfig.Target)
7567
return nil
7668
}

cmd/modctl/cmd

-41.6 MB
Binary file not shown.

cmd/modctl/login.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ import (
2323
"os"
2424
"strings"
2525

26+
"github.com/CloudNativeAI/modctl/pkg/config"
2627
"github.com/CloudNativeAI/modctl/pkg/oci"
2728
"github.com/spf13/cobra"
2829
"github.com/spf13/viper"
2930
)
3031

31-
var loginOpts = loginOptions{}
32+
var loginConfig = config.NewLogin()
3233

3334
type loginOptions struct {
3435
username string
@@ -45,16 +46,20 @@ var loginCmd = &cobra.Command{
4546
SilenceUsage: true,
4647
FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
4748
RunE: func(cmd *cobra.Command, args []string) error {
49+
if err := loginConfig.Validate(); err != nil {
50+
return err
51+
}
52+
4853
return runLogin(context.Background(), args[0])
4954
},
5055
}
5156

5257
// init initializes login command.
5358
func init() {
5459
flags := loginCmd.Flags()
55-
flags.StringVarP(&loginOpts.username, "username", "u", "", "Username for login")
56-
flags.StringVarP(&loginOpts.password, "password", "p", "", "Password for login")
57-
flags.BoolVar(&loginOpts.passwordStdin, "password-stdin", false, "Take the password from stdin")
60+
flags.StringVarP(&loginConfig.Username, "username", "u", "", "Username for login")
61+
flags.StringVarP(&loginConfig.Password, "password", "p", "", "Password for login")
62+
flags.BoolVar(&loginConfig.PasswordStdin, "password-stdin", false, "Take the password from stdin")
5863

5964
if err := viper.BindPFlags(flags); err != nil {
6065
panic(fmt.Errorf("bind cache login flags to viper: %w", err))
@@ -63,26 +68,19 @@ func init() {
6368

6469
// runLogin runs the login modctl.
6570
func runLogin(ctx context.Context, registry string) error {
66-
if len(loginOpts.username) == 0 {
67-
return fmt.Errorf("missing username")
68-
}
6971
// read password from stdin if password-stdin is set
70-
if loginOpts.passwordStdin {
72+
if loginConfig.PasswordStdin {
7173
fmt.Print("Enter password: ")
7274
reader := bufio.NewReader(os.Stdin)
7375
password, err := reader.ReadString('\n')
7476
if err != nil {
7577
return err
7678
}
7779

78-
loginOpts.password = strings.TrimSpace(password)
79-
}
80-
81-
if len(loginOpts.password) == 0 {
82-
return fmt.Errorf("missing password")
80+
loginConfig.Password = strings.TrimSpace(password)
8381
}
8482

85-
if err := oci.Login(ctx, registry, loginOpts.username, loginOpts.password); err != nil {
83+
if err := oci.Login(ctx, registry, loginConfig.Username, loginConfig.Password); err != nil {
8684
return err
8785
}
8886

cmd/modctl/pull.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,13 @@ import (
2020
"context"
2121
"fmt"
2222

23+
"github.com/CloudNativeAI/modctl/pkg/config"
2324
"github.com/CloudNativeAI/modctl/pkg/oci"
2425
"github.com/spf13/cobra"
2526
"github.com/spf13/viper"
2627
)
2728

28-
var pullOpts = &pullOptions{}
29-
30-
type pullOptions struct {
31-
plainHTTP bool
32-
}
29+
var pullConfig = config.NewPull()
3330

3431
// pullCmd represents the modctl command for pull.
3532
var pullCmd = &cobra.Command{
@@ -47,7 +44,7 @@ var pullCmd = &cobra.Command{
4744
// init initializes pull command.
4845
func init() {
4946
flags := pullCmd.Flags()
50-
flags.BoolVarP(&pullOpts.plainHTTP, "plain-http", "p", false, "use plain HTTP instead of HTTPS")
47+
flags.BoolVarP(&pullConfig.PlainHTTP, "plain-http", "p", false, "use plain HTTP instead of HTTPS")
5148

5249
if err := viper.BindPFlags(flags); err != nil {
5350
panic(fmt.Errorf("bind cache pull flags to viper: %w", err))
@@ -61,7 +58,7 @@ func runPull(ctx context.Context, target string) error {
6158
}
6259

6360
opts := []oci.Option{}
64-
if pullOpts.plainHTTP {
61+
if pullConfig.PlainHTTP {
6562
opts = append(opts, oci.WithPlainHTTP())
6663
}
6764

cmd/modctl/push.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,13 @@ import (
2020
"context"
2121
"fmt"
2222

23+
"github.com/CloudNativeAI/modctl/pkg/config"
2324
"github.com/CloudNativeAI/modctl/pkg/oci"
2425
"github.com/spf13/cobra"
2526
"github.com/spf13/viper"
2627
)
2728

28-
var pushOpts = &pushOptions{}
29-
30-
type pushOptions struct {
31-
plainHTTP bool
32-
}
29+
var pushConfig = config.NewPull()
3330

3431
// pushCmd represents the modctl command for push.
3532
var pushCmd = &cobra.Command{
@@ -47,7 +44,7 @@ var pushCmd = &cobra.Command{
4744
// init initializes push command.
4845
func init() {
4946
flags := pushCmd.Flags()
50-
flags.BoolVarP(&pushOpts.plainHTTP, "plain-http", "p", false, "use plain HTTP instead of HTTPS")
47+
flags.BoolVarP(&pushConfig.PlainHTTP, "plain-http", "p", false, "use plain HTTP instead of HTTPS")
5148

5249
if err := viper.BindPFlags(flags); err != nil {
5350
panic(fmt.Errorf("bind cache push flags to viper: %w", err))
@@ -57,7 +54,7 @@ func init() {
5754
// runPush runs the push modctl.
5855
func runPush(ctx context.Context, target string) error {
5956
opts := []oci.Option{}
60-
if pushOpts.plainHTTP {
57+
if pushConfig.PlainHTTP {
6158
opts = append(opts, oci.WithPlainHTTP())
6259
}
6360

pkg/config/build.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2024 The CNAI Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package config
18+
19+
import "fmt"
20+
21+
type Build struct {
22+
Target string
23+
Modelfile string
24+
}
25+
26+
func NewBuild() *Build {
27+
return &Build{
28+
Target: "",
29+
Modelfile: "Modelfile",
30+
}
31+
}
32+
33+
func (b *Build) Validate() error {
34+
if len(b.Target) == 0 {
35+
return fmt.Errorf("target model artifact name is required")
36+
}
37+
38+
if len(b.Modelfile) == 0 {
39+
return fmt.Errorf("model file path is required")
40+
}
41+
42+
return nil
43+
}

pkg/config/login.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright 2024 The CNAI Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package config
18+
19+
import "fmt"
20+
21+
type Login struct {
22+
Username string
23+
Password string
24+
PasswordStdin bool
25+
}
26+
27+
func NewLogin() *Login {
28+
return &Login{
29+
Username: "",
30+
Password: "",
31+
PasswordStdin: false,
32+
}
33+
}
34+
35+
func (l *Login) Validate() error {
36+
if len(l.Username) == 0 {
37+
return fmt.Errorf("missing username")
38+
}
39+
40+
if len(l.Password) == 0 {
41+
return fmt.Errorf("missing password")
42+
}
43+
44+
return nil
45+
}

pkg/config/pull.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2024 The CNAI Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package config
18+
19+
type Pull struct {
20+
PlainHTTP bool
21+
}
22+
23+
func NewPull() *Pull {
24+
return &Pull{
25+
PlainHTTP: false,
26+
}
27+
}

pkg/config/push.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2024 The CNAI Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package config
18+
19+
type Push struct {
20+
PlainHTTP bool
21+
}
22+
23+
func NewPush() *Pull {
24+
return &Pull{
25+
PlainHTTP: false,
26+
}
27+
}

pkg/oci/processor/readme.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func NewReadmeProcessor() Processor {
3636
type readmeProcessor struct{}
3737

3838
func (p *readmeProcessor) Identify(_ context.Context, path string, info os.FileInfo) bool {
39-
return info.Name() == "README.md"
39+
return info.Name() == "README.md" || info.Name() == "README"
4040
}
4141

4242
func (p *readmeProcessor) Process(ctx context.Context, store storage.Storage, repo, path string, info os.FileInfo) (ocispec.Descriptor, error) {

0 commit comments

Comments
 (0)