Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions pkg/runtime/golang/golang.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package golang
import (
"context"
"encoding/json"
"fmt"
"io"
"log/slog"
"os"
Expand Down Expand Up @@ -130,6 +131,20 @@ func (r *Runtime) Run(ctx context.Context, input *runtime.RunInput) (runtime.Wor
}, nil
}

func (r *Runtime) ValidateHandler(input *runtime.BuildInput) error {
if input.Handler != "" {
if info, err := os.Stat(input.Handler); err != nil || !info.IsDir() {
return fmt.Errorf("handler not found: %v", input.Handler)
}
}

_, err := fs.FindUp(input.Handler, "go.mod")
if err != nil {
return fmt.Errorf("handler not found: could not find go.mod for handler %v", input.Handler)
}
return nil
}

func (r *Runtime) ShouldRebuild(functionID string, file string) bool {
if !strings.HasSuffix(file, ".go") {
return false
Expand Down
2 changes: 1 addition & 1 deletion pkg/runtime/node/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (r *Runtime) Build(ctx context.Context, input *runtime.BuildInput) (*runtim

file, ok := r.getFile(input)
if !ok {
return nil, fmt.Errorf("Handler not found: %v", input.Handler)
return nil, fmt.Errorf("handler not found: %v", input.Handler)
}

isESM := true
Expand Down
28 changes: 21 additions & 7 deletions pkg/runtime/node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package node
import (
"context"
"encoding/json"
"fmt"
"io"
"log/slog"
"os"
Expand Down Expand Up @@ -242,22 +243,35 @@ func (r *Runtime) Match(runtime string) bool {
return strings.HasPrefix(runtime, "node")
}

func (r *Runtime) getFile(input *runtime.BuildInput) (string, bool) {
dir := filepath.Dir(input.Handler)
fileSplit := strings.Split(filepath.Base(input.Handler), ".")
func findHandlerFile(rootDir string, handler string) (string, bool) {
dir := filepath.Dir(handler)
fileSplit := strings.Split(filepath.Base(handler), ".")
base := strings.Join(fileSplit[:len(fileSplit)-1], ".")
for _, ext := range NODE_EXTENSIONS {
file := filepath.Join(dir, base+ext)
if !filepath.IsAbs(file) {
file = filepath.Join(path.ResolveRootDir(input.CfgPath), file)
}
file := filepath.Join(rootDir, dir, base+ext)
if _, err := os.Stat(file); err == nil {
return file, true
}
}
return "", false
}

func (r *Runtime) getFile(input *runtime.BuildInput) (string, bool) {
return findHandlerFile(path.ResolveRootDir(input.CfgPath), input.Handler)
}

func (r *Runtime) ValidateHandler(input *runtime.BuildInput) error {
rootDir := path.ResolveRootDir(input.CfgPath)
if input.Bundle != "" {
rootDir = input.Bundle
}
_, ok := findHandlerFile(rootDir, input.Handler)
if !ok {
return fmt.Errorf("handler not found: %v", input.Handler)
}
return nil
}

func (r *Runtime) ShouldRebuild(functionID string, file string) bool {
result, ok := r.results.Load(functionID)
if !ok {
Expand Down
28 changes: 20 additions & 8 deletions pkg/runtime/python/python.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,18 @@ func (r *PythonRuntime) Run(ctx context.Context, input *runtime.RunInput) (runti

}

func (r *PythonRuntime) ValidateHandler(input *runtime.BuildInput) error {
rootDir := path.ResolveRootDir(input.CfgPath)
if input.Bundle != "" {
rootDir = input.Bundle
}
_, err := findHandlerFile(rootDir, input.Handler)
if err != nil {
return fmt.Errorf("handler not found: %v", input.Handler)
}
return nil
}

func (r *PythonRuntime) ShouldRebuild(functionID string, file string) bool {
// Assume that the build is always stale. We could do a better job here but bc of how the build
// process actually works its not a slowdown as the real slow part is starting the python interpreter
Expand Down Expand Up @@ -382,25 +394,25 @@ func (r *PythonRuntime) CreateBuildAsset(ctx context.Context, input *runtime.Bui
}
}

func (r *PythonRuntime) getFile(input *runtime.BuildInput) (string, error) {
slog.Info("looking for python handler file", "handler", input.Handler)

dir := filepath.Dir(input.Handler)
base := strings.TrimSuffix(filepath.Base(input.Handler), filepath.Ext(input.Handler))
rootDir := path.ResolveRootDir(input.CfgPath)
func findHandlerFile(rootDir string, handler string) (string, error) {
dir := filepath.Dir(handler)
base := strings.TrimSuffix(filepath.Base(handler), filepath.Ext(handler))

// Look for .py file
pythonFile := filepath.Join(rootDir, dir, base+".py")
if _, err := os.Stat(pythonFile); err == nil {
return pythonFile, nil
}

// No Python file found for the handler
return "", fmt.Errorf("could not find Python file '%s.py' in directory '%s'",
base,
filepath.Join(rootDir, dir))
}

func (r *PythonRuntime) getFile(input *runtime.BuildInput) (string, error) {
slog.Info("looking for python handler file", "handler", input.Handler)
return findHandlerFile(path.ResolveRootDir(input.CfgPath), input.Handler)
}

func copyFile(src, dst string) error {
srcFile, err := os.Open(src)
if err != nil {
Expand Down
8 changes: 8 additions & 0 deletions pkg/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Runtime interface {
Build(ctx context.Context, input *BuildInput) (*BuildOutput, error)
Run(ctx context.Context, input *RunInput) (Worker, error)
ShouldRebuild(functionID string, path string) bool
ValidateHandler(input *BuildInput) error
}

type Worker interface {
Expand Down Expand Up @@ -100,6 +101,13 @@ func (c *Collection) Build(ctx context.Context, input *BuildInput) (*BuildOutput

if input.Bundle != "" {
out = input.Bundle
runtime, ok := c.Runtime(input.Runtime)
if !ok {
return nil, fmt.Errorf("runtime not found: %v", input.Runtime)
}
if err := runtime.ValidateHandler(input); err != nil {
return nil, err
}
result = &BuildOutput{
Handler: input.Handler,
Errors: []string{},
Expand Down
3 changes: 3 additions & 0 deletions pkg/runtime/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ func (m *mockRuntime) Run(ctx context.Context, input *runtime.RunInput) (runtime
func (m *mockRuntime) ShouldRebuild(functionID string, path string) bool {
return false
}
func (m *mockRuntime) ValidateHandler(input *runtime.BuildInput) error {
return nil
}

func TestBuildInputOut(t *testing.T) {
cfgPath := filepath.Join("/project", "sst.config.ts")
Expand Down
24 changes: 24 additions & 0 deletions pkg/runtime/rust/rust.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ func (r *Runtime) Build(ctx context.Context, input *runtime.BuildInput) (*runtim
var properties Properties
json.Unmarshal(input.Properties, &properties)

if err := r.ValidateHandler(input); err != nil {
return nil, err
}

// split handler into path and function name
parts := strings.Split(input.Handler, ".")
handler := strings.Join(parts[:len(parts)-1], ".")
Expand Down Expand Up @@ -194,6 +198,26 @@ func (r *Runtime) Run(ctx context.Context, input *runtime.RunInput) (runtime.Wor
}, nil
}

func (r *Runtime) ValidateHandler(input *runtime.BuildInput) error {
parts := strings.Split(input.Handler, ".")
handler := strings.Join(parts[:len(parts)-1], ".")

if handler != "" {
if info, err := os.Stat(handler); err != nil || !info.IsDir() {
return fmt.Errorf("handler not found: %v", input.Handler)
}
}

_, err := fs.FindUp(handler, "cargo.toml")
if err != nil {
_, err = fs.FindUp(handler, "Cargo.toml")
if err != nil {
return fmt.Errorf("handler not found: could not find Cargo.toml for handler %v", input.Handler)
}
}
return nil
}

func (r *Runtime) ShouldRebuild(functionID string, file string) bool {
// copied from go
if !strings.HasSuffix(file, ".rs") {
Expand Down
24 changes: 20 additions & 4 deletions pkg/runtime/worker/worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,18 +179,34 @@ func (w *Runtime) Match(runtime string) bool {
return runtime == "worker"
}

func (w *Runtime) getFile(input *runtime.BuildInput) (string, bool) {
dir := filepath.Dir(input.Handler)
base := strings.Split(filepath.Base(input.Handler), ".")[0]
func findHandlerFile(rootDir string, handler string) (string, bool) {
dir := filepath.Dir(handler)
base := strings.Split(filepath.Base(handler), ".")[0]
for _, ext := range node.NODE_EXTENSIONS {
file := filepath.Join(path.ResolveRootDir(input.CfgPath), dir, base+ext)
file := filepath.Join(rootDir, dir, base+ext)
if _, err := os.Stat(file); err == nil {
return file, true
}
}
return "", false
}

func (w *Runtime) getFile(input *runtime.BuildInput) (string, bool) {
return findHandlerFile(path.ResolveRootDir(input.CfgPath), input.Handler)
}

func (r *Runtime) ValidateHandler(input *runtime.BuildInput) error {
rootDir := path.ResolveRootDir(input.CfgPath)
if input.Bundle != "" {
rootDir = input.Bundle
}
_, ok := findHandlerFile(rootDir, input.Handler)
if !ok {
return fmt.Errorf("handler not found: %v", input.Handler)
}
return nil
}

func (r *Runtime) ShouldRebuild(functionID string, file string) bool {
r.lock.RLock()
result, ok := r.results[functionID]
Expand Down
9 changes: 9 additions & 0 deletions pkg/server/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package runtime

import (
"context"
"fmt"
"net/rpc"

"github.com/sst/sst/v3/pkg/bus"
Expand All @@ -24,6 +25,14 @@ func (r *Runtime) Build(input *runtime.BuildInput, output *runtime.BuildOutput)
}

func (r *Runtime) AddTarget(input *runtime.BuildInput, output *bool) error {
input.CfgPath = r.project.PathConfig()
rt, ok := r.project.Runtime.Runtime(input.Runtime)
if !ok {
return fmt.Errorf("runtime not found: %v", input.Runtime)
}
if err := rt.ValidateHandler(input); err != nil {
return err
}
bus.Publish(input)
*output = true
return nil
Expand Down
Loading