-
Notifications
You must be signed in to change notification settings - Fork 9
/
service.go
131 lines (112 loc) · 3.72 KB
/
service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2022 Namespace Labs Inc; All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
package create
import (
"context"
"path/filepath"
"strings"
"github.com/iancoleman/strcase"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"namespacelabs.dev/foundation/internal/cli/fncobra"
"namespacelabs.dev/foundation/internal/console/tui"
"namespacelabs.dev/foundation/internal/fnfs"
"namespacelabs.dev/foundation/internal/frontend/scaffold"
"namespacelabs.dev/foundation/schema"
"namespacelabs.dev/foundation/std/cfg"
)
const serviceSuffix = "service"
func newServiceCmd(runCommand func(ctx context.Context, args []string) error) *cobra.Command {
var (
targetPkg targetPkg
env cfg.Context
fmwkFlag string
name string
httpBackendPkg string
)
return fncobra.
Cmd(&cobra.Command{
Use: "service [path/to/package]",
Short: "Creates a service.",
}).
WithFlags(func(flags *pflag.FlagSet) {
flags.StringVar(&name, "name", "", "Service name.")
flags.StringVar(&httpBackendPkg, "with_http_backend", "", "Package name of the API backend server.")
}).
With(parseTargetPkgWithDeps(&targetPkg, "service")...).
With(
fncobra.HardcodeEnv(&env, "dev"),
withFramework(&fmwkFlag)).
Do(func(ctx context.Context) error {
fmwk, err := selectFramework(ctx, "Which framework would you like to use?", fmwkFlag)
if err != nil {
return err
}
if fmwk == nil {
return context.Canceled
}
if *fmwk == schema.Framework_GO {
if err := runGoInitCmdIfNeeded(ctx, targetPkg.Root, runCommand); err != nil {
return err
}
}
isNameUsed := *fmwk == schema.Framework_WEB
if !isNameUsed {
if name == "" {
name, err = tui.Ask(ctx, "How would you like to name your service?",
"A service's name should not contain private information, as it is used in various debugging references.\n\nIf a service exposes internet-facing handlers, then the service's name may also be part of public-facing endpoints.",
serviceName(targetPkg.Location))
if err != nil {
return err
}
}
if name == "" {
return context.Canceled
}
} else {
name = ""
}
if *fmwk == schema.Framework_GO {
protoOpts := scaffold.GenProtoServiceOpts{Name: name, Framework: *fmwk}
if err := scaffold.CreateProtoScaffold(ctx, targetPkg.Root.ReadWriteFS(), targetPkg.Location, protoOpts); err != nil {
return err
}
}
cueOpts := scaffold.GenServiceOpts{
ExportedServiceName: name,
Framework: *fmwk,
HttpBackendPkg: httpBackendPkg,
}
if err := scaffold.CreateServiceScaffold(ctx, targetPkg.Root.ReadWriteFS(), targetPkg.Location, cueOpts); err != nil {
return err
}
switch *fmwk {
case schema.Framework_GO:
goOpts := scaffold.GenGoServiceOpts{Name: name}
if err := scaffold.CreateGoServiceScaffold(ctx, targetPkg.Root.ReadWriteFS(), targetPkg.Location, goOpts); err != nil {
return err
}
case schema.Framework_WEB:
webOpts := scaffold.GenWebServiceOpts{}
if err := scaffold.CreateWebServiceScaffold(ctx, targetPkg.Root.ReadWriteFS(), targetPkg.Location, webOpts); err != nil {
return err
}
}
return codegenNode(ctx, targetPkg.Root, env, targetPkg.Location)
})
}
func serviceName(loc fnfs.Location) string {
var name string
base := filepath.Base(loc.RelPath)
dir := filepath.Dir(loc.RelPath)
if base != serviceSuffix {
name = strcase.ToCamel(base)
} else if dir != serviceSuffix {
name = strcase.ToCamel(dir)
}
if name != "" && !strings.HasSuffix(strings.ToLower(name), serviceSuffix) {
return name + strcase.ToCamel(serviceSuffix)
}
return name
}