Skip to content

Commit 856d6a6

Browse files
committed
refactor: move UI layer code to main.go
1 parent cba0aa0 commit 856d6a6

File tree

2 files changed

+93
-98
lines changed

2 files changed

+93
-98
lines changed

main.go

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,100 @@ package main
44

55
import (
66
"os"
7+
"os/user"
8+
"runtime"
79

10+
"github.com/pkg/errors"
11+
"github.com/vim-volt/volt/config"
12+
"github.com/vim-volt/volt/lockjson"
813
"github.com/vim-volt/volt/logger"
914
"github.com/vim-volt/volt/subcmd"
1015
)
1116

1217
func main() {
13-
err := subcmd.Run(os.Args, subcmd.DefaultRunner)
18+
code, msg := run(os.Args)
19+
if code != 0 {
20+
logger.Error(msg)
21+
os.Exit(code)
22+
}
23+
}
24+
25+
func run(args []string) (int, string) {
26+
if os.Getenv("VOLT_DEBUG") != "" {
27+
logger.SetLevel(logger.DebugLevel)
28+
}
29+
30+
if len(args) <= 1 {
31+
args = append(args, "help")
32+
}
33+
subCmd := args[1]
34+
args = args[2:]
35+
36+
// Expand subcommand alias
37+
subCmd, args, err := expandAlias(subCmd, args)
1438
if err != nil {
15-
logger.Error(err.Msg)
16-
os.Exit(err.Code)
39+
return 1, err.Error()
40+
}
41+
42+
c := subcmd.LookUpCmd(subCmd)
43+
if c == nil {
44+
return 3, "Unknown command '" + subCmd + "'"
45+
}
46+
47+
// Disallow executing the commands which may modify files in root priviledge
48+
if c.ProhibitRootExecution(args) {
49+
err := detectPriviledgedUser()
50+
if err != nil {
51+
return 4, err.Error()
52+
}
53+
}
54+
55+
lockJSON, err := lockjson.Read()
56+
if err != nil {
57+
return 20, errors.Wrap(err, "failed to read lock.json").Error()
58+
}
59+
60+
cfg, err := config.Read()
61+
if err != nil {
62+
return 30, errors.Wrap(err, "failed to read config.toml").Error()
63+
}
64+
65+
result := c.Run(&subcmd.CmdContext{
66+
Args: args,
67+
LockJSON: lockJSON,
68+
Config: cfg,
69+
})
70+
return result.Code, result.Msg
71+
}
72+
73+
func expandAlias(subCmd string, args []string) (string, []string, error) {
74+
cfg, err := config.Read()
75+
if err != nil {
76+
return "", nil, errors.Wrap(err, "could not read config.toml")
77+
}
78+
if newArgs, exists := cfg.Alias[subCmd]; exists && len(newArgs) > 0 {
79+
subCmd = newArgs[0]
80+
args = append(newArgs[1:], args...)
81+
}
82+
return subCmd, args, nil
83+
}
84+
85+
// On Windows, this function always returns nil.
86+
// Because if even administrator user creates a file, the file can be
87+
// overwritten by normal user.
88+
// On Linux, if current user's uid == 0, returns non-nil error.
89+
func detectPriviledgedUser() error {
90+
if runtime.GOOS == "windows" {
91+
return nil
92+
}
93+
u, err := user.Current()
94+
if err != nil {
95+
return errors.Wrap(err, "cannot get current user")
96+
}
97+
if u.Uid == "0" {
98+
return errors.New(
99+
"cannot run this sub command with root priviledge. " +
100+
"Please run as normal user")
17101
}
102+
return nil
18103
}

subcmd/cmd.go

Lines changed: 5 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,18 @@ package subcmd
22

33
import (
44
"flag"
5-
"os"
6-
"os/user"
7-
"runtime"
8-
9-
"github.com/pkg/errors"
105

116
"github.com/vim-volt/volt/config"
127
"github.com/vim-volt/volt/lockjson"
13-
"github.com/vim-volt/volt/logger"
148
)
159

1610
var cmdMap = make(map[string]Cmd)
1711

12+
// LookUpCmd looks up subcommand by name.
13+
func LookUpCmd(cmd string) Cmd {
14+
return cmdMap[cmd]
15+
}
16+
1817
// Cmd represents volt's subcommand interface.
1918
// All subcommands must implement this.
2019
type Cmd interface {
@@ -30,10 +29,6 @@ type CmdContext struct {
3029
Config *config.Config
3130
}
3231

33-
// RunnerFunc invokes c with args.
34-
// On unit testing, a mock function was given.
35-
type RunnerFunc func(c Cmd, cmdctx *CmdContext) *Error
36-
3732
// Error is a command error.
3833
// It also has a exit code.
3934
type Error struct {
@@ -44,88 +39,3 @@ type Error struct {
4439
func (e *Error) Error() string {
4540
return e.Msg
4641
}
47-
48-
// DefaultRunner simply runs command with args
49-
func DefaultRunner(c Cmd, cmdctx *CmdContext) *Error {
50-
return c.Run(cmdctx)
51-
}
52-
53-
// Run is invoked by main(), each argument means 'volt {subcmd} {args}'.
54-
func Run(args []string, cont RunnerFunc) *Error {
55-
if os.Getenv("VOLT_DEBUG") != "" {
56-
logger.SetLevel(logger.DebugLevel)
57-
}
58-
59-
if len(args) <= 1 {
60-
args = append(args, "help")
61-
}
62-
subCmd := args[1]
63-
args = args[2:]
64-
65-
// Expand subcommand alias
66-
subCmd, args, err := expandAlias(subCmd, args)
67-
if err != nil {
68-
return &Error{Code: 1, Msg: err.Error()}
69-
}
70-
71-
c, exists := cmdMap[subCmd]
72-
if !exists {
73-
return &Error{Code: 3, Msg: "Unknown command '" + subCmd + "'"}
74-
}
75-
76-
// Disallow executing the commands which may modify files in root priviledge
77-
if c.ProhibitRootExecution(args) {
78-
err := detectPriviledgedUser()
79-
if err != nil {
80-
return &Error{Code: 4, Msg: err.Error()}
81-
}
82-
}
83-
84-
lockJSON, err := lockjson.Read()
85-
if err != nil {
86-
return &Error{Code: 20, Msg: errors.Wrap(err, "failed to read lock.json").Error()}
87-
}
88-
89-
cfg, err := config.Read()
90-
if err != nil {
91-
return &Error{Code: 30, Msg: errors.Wrap(err, "failed to read config.toml").Error()}
92-
}
93-
94-
return cont(c, &CmdContext{
95-
Args: args,
96-
LockJSON: lockJSON,
97-
Config: cfg,
98-
})
99-
}
100-
101-
func expandAlias(subCmd string, args []string) (string, []string, error) {
102-
cfg, err := config.Read()
103-
if err != nil {
104-
return "", nil, errors.Wrap(err, "could not read config.toml")
105-
}
106-
if newArgs, exists := cfg.Alias[subCmd]; exists && len(newArgs) > 0 {
107-
subCmd = newArgs[0]
108-
args = append(newArgs[1:], args...)
109-
}
110-
return subCmd, args, nil
111-
}
112-
113-
// On Windows, this function always returns nil.
114-
// Because if even administrator user creates a file, the file can be
115-
// overwritten by normal user.
116-
// On Linux, if current user's uid == 0, returns non-nil error.
117-
func detectPriviledgedUser() error {
118-
if runtime.GOOS == "windows" {
119-
return nil
120-
}
121-
u, err := user.Current()
122-
if err != nil {
123-
return errors.Wrap(err, "cannot get current user")
124-
}
125-
if u.Uid == "0" {
126-
return errors.New(
127-
"cannot run this sub command with root priviledge. " +
128-
"Please run as normal user")
129-
}
130-
return nil
131-
}

0 commit comments

Comments
 (0)