Skip to content

Commit 4436f07

Browse files
authored
feat(cli): implement yomo run --production to skip compile step (#1093)
1 parent f829616 commit 4436f07

File tree

9 files changed

+68
-78
lines changed

9 files changed

+68
-78
lines changed

cli/cli.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,16 @@ func loadOptionsFromViper(v *viper.Viper, opts *serverless.Options) {
6464
opts.Runtime = v.GetString("runtime")
6565
}
6666

67+
// parseFileArg parses the filename from command line arguments or uses default files if none provided.
68+
// It updates the given serverless.Options with the filename and validates it via checkOptions.
69+
// Returns nil if a valid filename is found, otherwise continues trying default files.
6770
func parseFileArg(args []string, opts *serverless.Options, defaultFiles ...string) error {
71+
// parse filename from args, like `yomo run app.go`
6872
if len(args) >= 1 && args[0] != "" {
6973
opts.Filename = args[0]
7074
return checkOptions(opts)
7175
}
76+
// if no filename is provided, use the default files
7277
for _, f := range defaultFiles {
7378
opts.Filename = f
7479
err := checkOptions(opts)

cli/run.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,14 @@ var runCmd = &cobra.Command{
6767
return
6868
}
6969

70-
if err := s.Build(true); err != nil {
71-
log.FailureStatusEvent(os.Stdout, "%s", err.Error())
72-
os.Exit(127)
70+
// if has `--production` flag, skip s.Build() process
71+
isProduction := opts.Production
72+
log.InfoStatusEvent(os.Stdout, "production mode is %v", opts.Production)
73+
if !isProduction {
74+
if err := s.Build(true); err != nil {
75+
log.FailureStatusEvent(os.Stdout, "%s", err.Error())
76+
os.Exit(127)
77+
}
7378
}
7479

7580
log.InfoStatusEvent(
@@ -93,6 +98,7 @@ func init() {
9398
runCmd.Flags().StringVarP(&opts.ModFile, "modfile", "m", "", "custom go.mod")
9499
runCmd.Flags().StringVarP(&opts.Credential, "credential", "d", "", "client credential payload, eg: `token:dBbBiRE7`")
95100
runCmd.Flags().StringVarP(&opts.Runtime, "runtime", "r", "", "serverless runtime type")
101+
runCmd.Flags().BoolVarP(&opts.Production, "production", "p", false, "run in production mode, skip the build process")
96102

97103
viper.BindPFlags(viper.RunViper, runCmd.Flags())
98104
}

cli/serverless/nodejs/runtime.go

Lines changed: 33 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,11 @@ func (w *NodejsWrapper) WorkDir() string {
8989

9090
// Build defines how to build the serverless llm function.
9191
func (w *NodejsWrapper) Build(env []string) error {
92-
// 1. generate .wrapper.ts file
93-
dstPath := filepath.Join(w.workDir, wrapperTS)
92+
// 1. generate ./src/.wrapper.ts file
93+
dstPath := filepath.Join(w.workDir, "src/", wrapperTS)
94+
// remove the old one
9495
_ = os.Remove(dstPath)
95-
96+
// create new one
9697
if err := w.genWrapperTS(w.functionName, dstPath); err != nil {
9798
return err
9899
}
@@ -137,80 +138,44 @@ func (w *NodejsWrapper) Build(env []string) error {
137138
return err
138139
}
139140

140-
// 4. copy files other than .ts file from src/ to dist/src/ because tsc do not do that
141-
srcDir := filepath.Join(w.workDir, "src")
142-
dstDir := filepath.Join(w.workDir, "dist/src")
143-
if err := os.MkdirAll(dstDir, 0755); err != nil {
144-
return err
145-
}
146-
// copy all files from src/ to dist/
147-
err = filepath.Walk(srcDir, func(path string, info os.FileInfo, err error) error {
148-
if err != nil {
149-
return err
150-
}
151-
if path == srcDir {
152-
return nil
153-
}
154-
155-
// Get relative path to maintain directory structure
156-
relPath, err := filepath.Rel(srcDir, path)
157-
if err != nil {
158-
return fmt.Errorf("failed to get relative path: %v", err)
159-
}
160-
161-
if filepath.Ext(path) == ".ts" {
162-
return nil
163-
}
141+
// 4. copy src/app.ts to dist/app.ts
142+
baseFileName := filepath.Base(w.entryTSFile)
143+
srcEntryPath := w.entryTSFile
144+
dstEntryPath := filepath.Join(w.outputDir, baseFileName)
164145

165-
// Create destination path with same structure
166-
dstPath := filepath.Join(dstDir, relPath)
146+
data, err := os.ReadFile(srcEntryPath)
147+
if err != nil {
148+
return fmt.Errorf("failed to read file %s: %v", srcEntryPath, err)
149+
}
167150

168-
// Check if the destination directory exists
169-
dstDir := filepath.Dir(dstPath)
170-
if _, err := os.Stat(dstDir); os.IsNotExist(err) {
171-
return fmt.Errorf("destination directory %s does not exist", dstDir)
172-
}
151+
if err := os.WriteFile(dstEntryPath, data, 0644); err != nil {
152+
return fmt.Errorf("failed to write file %s: %v", dstEntryPath, err)
153+
}
173154

174-
// Copy the file to ./dist/src/
175-
if info.IsDir() {
176-
return os.MkdirAll(dstPath, info.Mode())
177-
} else {
178-
// Read the source file
179-
data, err := os.ReadFile(path)
180-
if err != nil {
181-
return fmt.Errorf("failed to read file %s: %v", path, err)
182-
}
183-
184-
// Write to the destination file
185-
if err := os.WriteFile(dstPath, data, info.Mode()); err != nil {
186-
return fmt.Errorf("failed to write file %s: %v", dstPath, err)
187-
}
188-
189-
log.InfoStatusEvent(os.Stdout, "copied %s to %s\n", path, dstPath)
190-
return nil
191-
}
192-
})
155+
// log.InfoStatusEvent(os.Stdout, "Copied %s to %s", srcEntryPath, dstEntryPath)
193156

194157
return err
195158
}
196159

197160
// Run runs the serverless function
198161
func (w *NodejsWrapper) Run(env []string) error {
162+
// ./dist/.wrapper.js
163+
entryJSFile := filepath.Join(w.outputDir, wrapperJS)
199164
// try to run with bunjs
200165
// first, check if bun is installed
201166
bunPath, err := exec.LookPath("bun")
202167
if err == nil {
203168
// bun is installed, run the wrapper with bun
204-
// get the version of tsgo/tsc
169+
// get the version of bun
205170
var bunVersion string
206171
if v, err := checkVersion("bun"); err != nil {
207172
return err
208173
} else {
209174
bunVersion = v
210175
}
211-
log.InfoStatusEvent(os.Stdout, "Runtime is Bun (Version %s)", bunVersion)
176+
log.InfoStatusEvent(os.Stdout, "Runtime is Bun (Version %s), %s", bunVersion, entryJSFile)
212177

213-
cmd := exec.Command(bunPath, wrapperTS)
178+
cmd := exec.Command(bunPath, "run", entryJSFile)
214179
cmd.Dir = w.workDir
215180
cmd.Stdout = os.Stdout
216181
cmd.Stderr = os.Stderr
@@ -220,18 +185,27 @@ func (w *NodejsWrapper) Run(env []string) error {
220185
}
221186

222187
// if bun is not found, fallback to nodejs
223-
cmd := exec.Command(w.nodePath, filepath.Join(w.outputDir, wrapperJS))
188+
cmd := exec.Command(w.nodePath, entryJSFile)
224189
cmd.Dir = w.workDir
225190
cmd.Stdout = os.Stdout
226191
cmd.Stderr = os.Stderr
227192
cmd.Env = env
228193

194+
var nodeVersion string
195+
if v, err := checkVersion("node"); err != nil {
196+
return err
197+
} else {
198+
nodeVersion = v
199+
}
200+
201+
log.InfoStatusEvent(os.Stdout, "Runtime is Node.js (Version %s), %s, %s", nodeVersion, w.nodePath, entryJSFile)
202+
229203
return cmd.Run()
230204
}
231205

232206
func (w *NodejsWrapper) genWrapperTS(functionName, dstPath string) error {
233-
baseFilename := "./src/" + filepath.Base(w.fileName)
234-
entryTS := baseFilename + ".ts"
207+
baseFilename := "./" + filepath.Base(w.fileName)
208+
entryTS := "./dist/" + baseFilename + ".ts"
235209

236210
data := struct {
237211
WorkDir string

cli/serverless/nodejs/serverless.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ func (s *nodejsServerless) Setup(opts *serverless.Options) error {
4343
"module": "commonjs",
4444
"forceConsistentCasingInFileNames": true,
4545
"strict": true,
46-
"outDir": "dist",
46+
"outDir": "./dist",
47+
"rootDir": "./src",
4748
"skipLibCheck": true
4849
},
49-
"include": ["src/**/*", ".wrapper.ts"],
50+
"include": ["src/**/*", "src/.wrapper.ts"],
5051
"exclude": ["node_modules"]
5152
}`
5253
if err := os.WriteFile(tsconfigPath, []byte(tsconfigContent), 0644); err != nil {

cli/serverless/options.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ type Options struct {
1414
Credential string
1515
// Runtime specifies the serverless runtime environment type
1616
Runtime string
17+
// Production indicates whether to run in production mode
18+
Production bool
1719
}

cli/serverless/serverless.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ func LoadEnvFile(envDir string) error {
5656
return nil
5757
}
5858

59-
// Create returns a new serverless instance with options.
59+
// Create returns a new serverless instance with options
6060
func Create(opts *Options) (Serverless, error) {
61+
// TODO: need refactor to infer serverless runtime from `--runtime` flag or `RUNTIME` env,
62+
// instead of inferring from file extension here.
6163
ext := filepath.Ext(opts.Filename)
6264

6365
driversMu.RLock()

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.23.0
44

55
require (
66
cloud.google.com/go/vertexai v0.13.4
7-
github.com/anthropics/anthropic-sdk-go v1.2.0
7+
github.com/anthropics/anthropic-sdk-go v1.2.1
88
github.com/briandowns/spinner v1.23.2
99
github.com/caarlos0/env/v6 v6.10.1
1010
github.com/fatih/color v1.18.0
@@ -17,7 +17,7 @@ require (
1717
github.com/matoous/go-nanoid/v2 v2.1.0
1818
github.com/quic-go/quic-go v0.52.0
1919
github.com/robfig/cron/v3 v3.0.1
20-
github.com/sashabaranov/go-openai v1.40.0
20+
github.com/sashabaranov/go-openai v1.40.1
2121
github.com/shirou/gopsutil/v3 v3.24.5
2222
github.com/spf13/cobra v1.9.1
2323
github.com/spf13/pflag v1.0.6

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D
2727
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
2828
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2929
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
30-
github.com/anthropics/anthropic-sdk-go v1.2.0 h1:RQzJUqaROewrPTl7Rl4hId/TqmjFvfnkmhHJ6pP1yJ8=
31-
github.com/anthropics/anthropic-sdk-go v1.2.0/go.mod h1:AapDW22irxK2PSumZiQXYUFvsdQgkwIWlpESweWZI/c=
30+
github.com/anthropics/anthropic-sdk-go v1.2.1 h1:zwRsDe3+KEJNDwKdbtum4P3UsQ9Uc8y/WmBE+V2WElk=
31+
github.com/anthropics/anthropic-sdk-go v1.2.1/go.mod h1:AapDW22irxK2PSumZiQXYUFvsdQgkwIWlpESweWZI/c=
3232
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
3333
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
3434
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -184,8 +184,8 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
184184
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
185185
github.com/sagikazarmark/locafero v0.9.0 h1:GbgQGNtTrEmddYDSAH9QLRyfAHY12md+8YFTqyMTC9k=
186186
github.com/sagikazarmark/locafero v0.9.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk=
187-
github.com/sashabaranov/go-openai v1.40.0 h1:Peg9Iag5mUJtPW00aYatlsn97YML0iNULiLNe74iPrU=
188-
github.com/sashabaranov/go-openai v1.40.0/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
187+
github.com/sashabaranov/go-openai v1.40.1 h1:bJ08Iwct5mHBVkuvG6FEcb9MDTfsXdTYPGjYLRdeTEU=
188+
github.com/sashabaranov/go-openai v1.40.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
189189
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
190190
github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
191191
github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=

pkg/wrapper/wrapper.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ type SFNWrapper interface {
2626
Run(env []string) error
2727
}
2828

29-
// BuildAndRun builds and runs the serverless function.
30-
func BuildAndRun(name, zipperAddr, credential string, wrapper SFNWrapper, env []string) error {
31-
if err := wrapper.Build(env); err != nil {
32-
return err
33-
}
34-
return Run(name, zipperAddr, credential, wrapper, env)
35-
}
29+
// // BuildAndRun builds and runs the serverless function.
30+
// func BuildAndRun(name, zipperAddr, credential string, wrapper SFNWrapper, env []string) error {
31+
// if err := wrapper.Build(env); err != nil {
32+
// return err
33+
// }
34+
// return Run(name, zipperAddr, credential, wrapper, env)
35+
// }
3636

3737
// Run runs the serverless function.
3838
func Run(name, zipperAddr, credential string, wrapper SFNWrapper, env []string) error {

0 commit comments

Comments
 (0)