Skip to content

Commit 2e15bcc

Browse files
committed
feat: add package manager
1 parent d960c2b commit 2e15bcc

File tree

10 files changed

+279
-83
lines changed

10 files changed

+279
-83
lines changed

cmd/misc_typescript.go

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,49 @@ import (
44
"bytes"
55

66
"github.com/pot-code/web-cli/internal/command"
7-
"github.com/pot-code/web-cli/internal/shell"
7+
"github.com/pot-code/web-cli/internal/pkm"
88
"github.com/pot-code/web-cli/internal/task"
99
"github.com/pot-code/web-cli/templates"
1010
"github.com/urfave/cli/v2"
1111
)
1212

1313
type AddTypescriptConfig struct {
14-
Target string `flag:"target" alias:"t" usage:"project target" validate:"required,oneof=node react"`
14+
Target string `flag:"target" alias:"t" usage:"project type" validate:"required,oneof=node react"`
15+
PackageManager string `flag:"pm" usage:"choose package manager" validate:"oneof=pnpm npm yarn"`
1516
}
1617

1718
var AddTypescriptCmd = command.NewCliCommand("typescript", "add typescript support",
18-
new(AddTypescriptConfig),
19+
&AddTypescriptConfig{
20+
PackageManager: "pnpm",
21+
},
1922
command.WithAlias([]string{"ts"}),
2023
).AddHandlers(
21-
new(AddTypescriptToNode),
22-
new(AddTypescriptToReact),
24+
new(AddTypescript),
2325
).BuildCommand()
2426

25-
type AddTypescriptToNode struct{}
27+
type AddTypescript struct {
28+
PackageManager string
29+
}
30+
31+
var _ command.CommandHandler = &AddTypescript{}
2632

27-
var _ command.CommandHandler = &AddTypescriptToNode{}
33+
func (at *AddTypescript) Handle(c *cli.Context, cfg interface{}) error {
34+
config := cfg.(*AddTypescriptConfig)
2835

29-
func (arc *AddTypescriptToNode) Cond(c *cli.Context) bool {
30-
return c.String("target") == "node"
36+
at.PackageManager = config.PackageManager
37+
38+
if config.Target == "node" {
39+
return at.node().Run()
40+
}
41+
if config.Target == "react" {
42+
return at.react().Run()
43+
}
44+
return nil
3145
}
3246

33-
func (arc *AddTypescriptToNode) Handle(c *cli.Context, cfg interface{}) error {
47+
func (at *AddTypescript) node() task.Task {
48+
pm := pkm.NewPackageManager(at.PackageManager)
49+
3450
return task.NewParallelExecutor(
3551
[]task.Task{
3652
&task.FileGenerator{
@@ -41,30 +57,26 @@ func (arc *AddTypescriptToNode) Handle(c *cli.Context, cfg interface{}) error {
4157
Name: "tsconfig.json",
4258
Data: bytes.NewBufferString(templates.NodeTsConfig()),
4359
},
44-
shell.YarnAddDev(
45-
"typescript",
46-
"eslint",
47-
"@typescript-eslint/eslint-plugin",
48-
"eslint-plugin-prettier",
49-
"@typescript-eslint/parser",
50-
"eslint-config-prettier",
51-
"eslint-plugin-import",
52-
"prettier",
53-
"prettier-eslint",
60+
pm.InstallDev(
61+
[]string{
62+
"typescript",
63+
"eslint",
64+
"@typescript-eslint/eslint-plugin",
65+
"eslint-plugin-prettier",
66+
"@typescript-eslint/parser",
67+
"eslint-config-prettier",
68+
"eslint-plugin-import",
69+
"prettier",
70+
"prettier-eslint",
71+
},
5472
),
5573
},
56-
).Run()
74+
)
5775
}
5876

59-
type AddTypescriptToReact struct{}
60-
61-
var _ command.CommandHandler = &AddTypescriptToReact{}
62-
63-
func (arc *AddTypescriptToReact) Cond(c *cli.Context) bool {
64-
return c.String("target") == "react"
65-
}
77+
func (at *AddTypescript) react() task.Task {
78+
pm := pkm.NewPackageManager(at.PackageManager)
6679

67-
func (arc *AddTypescriptToReact) Handle(c *cli.Context, cfg interface{}) error {
6880
return task.NewParallelExecutor(
6981
[]task.Task{
7082
&task.FileGenerator{
@@ -75,23 +87,25 @@ func (arc *AddTypescriptToReact) Handle(c *cli.Context, cfg interface{}) error {
7587
Name: "tsconfig.json",
7688
Data: bytes.NewBufferString(templates.ReactTsConfig()),
7789
},
78-
shell.YarnAddDev(
79-
"@types/react",
80-
"@typescript-eslint/eslint-plugin",
81-
"@typescript-eslint/parser",
82-
"eslint",
83-
"eslint-config-airbnb",
84-
"eslint-config-prettier",
85-
"eslint-import-resolver-typescript",
86-
"eslint-plugin-import",
87-
"eslint-plugin-jsx-a11y",
88-
"eslint-plugin-prettier",
89-
"eslint-plugin-react",
90-
"eslint-plugin-react-hooks",
91-
"prettier",
92-
"prettier-eslint",
93-
"typescript",
90+
pm.InstallDev(
91+
[]string{
92+
"@types/react",
93+
"@typescript-eslint/eslint-plugin",
94+
"@typescript-eslint/parser",
95+
"eslint",
96+
"eslint-config-airbnb",
97+
"eslint-config-prettier",
98+
"eslint-import-resolver-typescript",
99+
"eslint-plugin-import",
100+
"eslint-plugin-jsx-a11y",
101+
"eslint-plugin-prettier",
102+
"eslint-plugin-react",
103+
"eslint-plugin-react-hooks",
104+
"prettier",
105+
"prettier-eslint",
106+
"typescript",
107+
},
94108
),
95109
},
96-
).Run()
110+
)
97111
}

cmd/react_init.go

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,66 @@ package cmd
22

33
import (
44
"github.com/pot-code/web-cli/internal/command"
5+
"github.com/pot-code/web-cli/internal/pkm"
56
"github.com/pot-code/web-cli/internal/shell"
67
"github.com/pot-code/web-cli/internal/task"
8+
"github.com/pot-code/web-cli/internal/util"
9+
log "github.com/sirupsen/logrus"
710
"github.com/urfave/cli/v2"
811
)
912

1013
type ReactInitConfig struct {
11-
GenType string `flag:"type" alias:"t" usage:"project type" validate:"oneof=vanilla next"`
12-
ProjectName string `arg:"0" alias:"project_name" validate:"required,var"`
14+
GenType string `flag:"type" alias:"t" usage:"project type" validate:"oneof=vanilla nextjs"`
15+
PackageManager string `flag:"pm" usage:"choose package manager" validate:"oneof=pnpm npm yarn"`
16+
ProjectName string `arg:"0" alias:"project_name" validate:"required,var"`
1317
}
1418

1519
var ReactInitCmd = command.NewCliCommand("init", "create react project",
1620
&ReactInitConfig{
17-
GenType: "vanilla",
21+
GenType: "vanilla",
22+
PackageManager: "pnpm",
1823
},
1924
command.WithArgUsage("project_name"),
2025
).AddHandlers(
21-
new(VanillaTemplate),
22-
new(NextJsTemplate),
26+
new(InitReact),
2327
).BuildCommand()
2428

25-
type VanillaTemplate struct{}
26-
27-
var _ command.CommandHandler = &VanillaTemplate{}
28-
29-
func (grf *VanillaTemplate) Cond(c *cli.Context) bool {
30-
return c.String("type") == "vanilla"
29+
type InitReact struct {
30+
ProjectName string
31+
PackageManager string
3132
}
3233

33-
func (grf *VanillaTemplate) Handle(c *cli.Context, cfg interface{}) error {
34+
func (ir *InitReact) Handle(c *cli.Context, cfg interface{}) error {
3435
config := cfg.(*ReactInitConfig)
36+
gt := config.GenType
3537

36-
return task.NewSequentialExecutor(
37-
[]task.Task{
38-
shell.GitClone("https://github.com/pot-code/react-boilerplate.git", config.ProjectName),
39-
shell.GitDeleteHistory(config.ProjectName),
40-
},
41-
).Run()
42-
}
43-
44-
type NextJsTemplate struct{}
38+
ir.ProjectName = config.ProjectName
39+
ir.PackageManager = config.PackageManager
4540

46-
var _ command.CommandHandler = &NextJsTemplate{}
41+
if util.Exists(ir.ProjectName) {
42+
log.Infof("folder '%s' already exists", ir.ProjectName)
43+
return nil
44+
}
4745

48-
func (gnf *NextJsTemplate) Cond(c *cli.Context) bool {
49-
return c.String("type") == "next"
46+
if gt == "vanilla" {
47+
return ir.vanilla().Run()
48+
}
49+
if gt == "nextjs" {
50+
return ir.nextjs().Run()
51+
}
52+
return nil
5053
}
5154

52-
func (gnf *NextJsTemplate) Handle(c *cli.Context, cfg interface{}) error {
53-
config := cfg.(*ReactInitConfig)
55+
func (ir *InitReact) nextjs() task.Task {
56+
pm := pkm.NewPackageManager(ir.PackageManager)
57+
return pm.Create("next-app", ir.ProjectName, []string{"--typescript"})
58+
}
5459

55-
return shell.YarnCreate("next-app", "--ts", config.ProjectName).Run()
60+
func (ir *InitReact) vanilla() task.Task {
61+
return task.NewSequentialExecutor(
62+
[]task.Task{
63+
shell.GitClone("https://github.com/pot-code/react-boilerplate.git", ir.ProjectName),
64+
shell.GitDeleteHistory(ir.ProjectName),
65+
},
66+
)
5667
}

cmd/root.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ var RootCmd = &cli.App{
1818
Version: AppVersion,
1919
Flags: []cli.Flag{
2020
&cli.BoolFlag{
21-
Name: "debug",
22-
Aliases: []string{"D"},
23-
Usage: "enable debugging",
21+
Name: "verbose",
22+
Aliases: []string{"vv"},
23+
Usage: "verbose mode",
2424
Value: false,
2525
DefaultText: "false",
2626
},
2727
},
2828
Before: func(c *cli.Context) error {
29-
if c.Bool("debug") {
29+
if c.Bool("verbose") {
3030
log.SetLevel(log.DebugLevel)
3131
}
3232
return nil

internal/command/extract.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func (efv *extractFlagsVisitor) visitString(f *configField) {
5555
Name: flag,
5656
}
5757

58-
if f.hasDefault() {
58+
if f.hasDefaultValue() {
5959
cf.Value = f.value.String()
6060
}
6161

@@ -89,7 +89,7 @@ func (efv *extractFlagsVisitor) visitBoolean(f *configField) {
8989
Name: flag,
9090
}
9191

92-
if f.hasDefault() {
92+
if f.hasDefaultValue() {
9393
cf.Value = f.value.Bool()
9494
}
9595

@@ -123,7 +123,7 @@ func (efv *extractFlagsVisitor) visitInt(f *configField) {
123123
Name: flag,
124124
}
125125

126-
if f.hasDefault() {
126+
if f.hasDefaultValue() {
127127
cf.Value = int(f.value.Int())
128128
}
129129

internal/command/field.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func (f *configField) hasTag() bool {
4343
return f.meta.Tag != ""
4444
}
4545

46-
func (f *configField) hasDefault() bool {
46+
func (f *configField) hasDefaultValue() bool {
4747
return !f.value.IsZero()
4848
}
4949

internal/pkm/create.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package pkm
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/pot-code/web-cli/internal/task"
7+
)
8+
9+
type PackageManager interface {
10+
Create(template, name string, flags []string) *task.ShellCommand
11+
Install(name []string) *task.ShellCommand
12+
InstallDev(name []string) *task.ShellCommand
13+
Uninstall(name []string) *task.ShellCommand
14+
}
15+
16+
func NewPackageManager(bin string) PackageManager {
17+
switch bin {
18+
case "pnpm":
19+
return newPnpm(bin)
20+
case "npm":
21+
return newNpm(bin)
22+
case "yarn":
23+
return newYarn(bin)
24+
}
25+
panic(fmt.Sprintf("unknown package manager '%s'", bin))
26+
}

internal/pkm/npm.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package pkm
2+
3+
import "github.com/pot-code/web-cli/internal/task"
4+
5+
type npm struct {
6+
bin string
7+
}
8+
9+
func newNpm(bin string) *npm {
10+
return &npm{bin: bin}
11+
}
12+
13+
func (n *npm) Create(template, name string, flags []string) *task.ShellCommand {
14+
bin := "npx"
15+
args := []string{template}
16+
args = append(args, flags...)
17+
args = append(args, name)
18+
return &task.ShellCommand{
19+
Bin: bin,
20+
Args: args,
21+
}
22+
}
23+
24+
func (n *npm) Install(name []string) *task.ShellCommand {
25+
args := []string{"install"}
26+
args = append(args, name...)
27+
return &task.ShellCommand{
28+
Bin: n.bin,
29+
Args: args,
30+
}
31+
}
32+
33+
func (n *npm) InstallDev(name []string) *task.ShellCommand {
34+
args := []string{"install", "-D"}
35+
args = append(args, name...)
36+
return &task.ShellCommand{
37+
Bin: n.bin,
38+
Args: args,
39+
}
40+
}
41+
42+
func (n *npm) Uninstall(name []string) *task.ShellCommand {
43+
args := []string{"rm"}
44+
args = append(args, name...)
45+
return &task.ShellCommand{
46+
Bin: n.bin,
47+
Args: args,
48+
}
49+
}

0 commit comments

Comments
 (0)