From 8950ca76ae1665ca247225f4b5b3a6262d9442b2 Mon Sep 17 00:00:00 2001 From: Dax Raad Date: Mon, 2 Sep 2024 13:18:43 -0400 Subject: [PATCH] add: handle adding unknown provider, pin version by default --- cmd/sst/main.go | 9 +++-- examples/aws-hono/package.json | 2 +- go.mod | 2 +- pkg/npm/npm.go | 4 +++ pkg/project/add.go | 6 ++-- pkg/project/install.go | 64 +++++++++++++--------------------- pkg/project/project.go | 6 ++++ platform/src/ast/add.ts | 3 +- 8 files changed, 49 insertions(+), 47 deletions(-) diff --git a/cmd/sst/main.go b/cmd/sst/main.go index 7d846a26e..df68cc93c 100644 --- a/cmd/sst/main.go +++ b/cmd/sst/main.go @@ -633,8 +633,11 @@ var root = &cli.Command{ return err } } - - err = p.Add(pkg) + entry, err := project.FindProvider(pkg, "latest") + if err != nil { + return util.NewReadableError(err, "Could not find provider "+pkg) + } + err = p.Add(entry.Name, entry.Version) if err != nil { return err } @@ -652,7 +655,7 @@ var root = &cli.Command{ return err } spin.Stop() - ui.Success(fmt.Sprintf("Added provider \"%s\"", pkg)) + ui.Success(fmt.Sprintf("Added provider \"%s\". You can create resources with `new %s.SomeResource()`", entry.Alias, entry.Alias)) return nil }, }, diff --git a/examples/aws-hono/package.json b/examples/aws-hono/package.json index 2b49be163..9ef06e685 100644 --- a/examples/aws-hono/package.json +++ b/examples/aws-hono/package.json @@ -13,6 +13,6 @@ "@aws-sdk/client-s3": "^3.552.0", "@aws-sdk/s3-request-presigner": "^3.552.0", "hono": "^4.1.3", - "sst": "latest" + "sst": "^3.0.83" } } diff --git a/go.mod b/go.mod index f2fd9845d..7be5a2331 100644 --- a/go.mod +++ b/go.mod @@ -76,7 +76,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 - github.com/aws/smithy-go v1.20.3 // indirect + github.com/aws/smithy-go v1.20.3 github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/charmbracelet/bubbles v0.18.0 diff --git a/pkg/npm/npm.go b/pkg/npm/npm.go index 850db85fa..e2ba33ed8 100644 --- a/pkg/npm/npm.go +++ b/pkg/npm/npm.go @@ -10,6 +10,10 @@ import ( type Package struct { Name string `json:"name"` Version string `json:"version"` + Pulumi struct { + Name string `json:"name"` + Version string `json:"version"` + } } func Get(name string, version string) (*Package, error) { diff --git a/pkg/project/add.go b/pkg/project/add.go index 235a32e88..4499027d4 100644 --- a/pkg/project/add.go +++ b/pkg/project/add.go @@ -8,10 +8,12 @@ import ( "github.com/sst/ion/pkg/global" ) -func (p *Project) Add(pkg string) error { +func (p *Project) Add(pkg string, version string) error { cmd := exec.Command(global.BunPath(), filepath.Join(p.PathPlatformDir(), "src/ast/add.ts"), p.PathConfig(), - pkg) + pkg, + version, + ) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() diff --git a/pkg/project/install.go b/pkg/project/install.go index 58e7b62df..e48321f7e 100644 --- a/pkg/project/install.go +++ b/pkg/project/install.go @@ -1,7 +1,6 @@ package project import ( - "bufio" "encoding/json" "errors" "fmt" @@ -10,8 +9,6 @@ import ( "os" "os/exec" "path/filepath" - "regexp" - "strings" "github.com/sst/ion/pkg/global" "github.com/sst/ion/pkg/npm" @@ -139,7 +136,7 @@ func (p *Project) writeTypes() error { file.WriteString(` interface Providers {` + "\n") file.WriteString(` providers?: {` + "\n") for _, entry := range p.lock { - file.WriteString(` "` + entry.Name + `"?: (_` + entry.Alias + `.ProviderArgs & { version?: string }) | boolean;` + "\n") + file.WriteString(` "` + entry.Name + `"?: (_` + entry.Alias + `.ProviderArgs & { version?: string }) | boolean | string;` + "\n") } file.WriteString(` }` + "\n") file.WriteString(` }` + "\n") @@ -165,29 +162,6 @@ func (p *Project) fetchDeps() error { if err != nil { return errors.New("failed to run bun install " + string(output)) } - for _, entry := range p.lock { - path := filepath.Join(p.PathPlatformDir(), "node_modules", entry.Package, "provider.js") - file, err := os.Open(path) - if err != nil { - return err - } - defer file.Close() - scanner := bufio.NewScanner(file) - pulumiTypePattern := regexp.MustCompile(`Provider\.__pulumiType = ['"]([^'"]+)['"]`) - for scanner.Scan() { - matches := pulumiTypePattern.FindStringSubmatch(scanner.Text()) - if len(matches) > 1 { - entry.Alias = strings.ReplaceAll(matches[1], "-", "") - break - } - } - if err := scanner.Err(); err != nil { - return err - } - if entry.Alias == "" { - return fmt.Errorf("failed to find __pulumiType for %s", entry.Package) - } - } return nil } @@ -225,19 +199,12 @@ func (p *Project) generateProviderLock() error { version = "latest" } wg.Go(func() error { - for _, prefix := range []string{"@sst-provider/", "@pulumi/", "@pulumiverse/", "@", ""} { - pkg, err := npm.Get(prefix+n, version.(string)) - if err != nil { - continue - } - results <- ProviderLockEntry{ - Name: n, - Package: pkg.Name, - Version: version.(string), - } - return nil + result, err := FindProvider(n, version.(string)) + if err != nil { + return err } - return fmt.Errorf("provider %s not found", n) + results <- *result + return nil }) } wg.Go(func() error { @@ -256,6 +223,25 @@ func (p *Project) generateProviderLock() error { return nil } +func FindProvider(name string, version string) (*ProviderLockEntry, error) { + for _, prefix := range []string{"@sst-provider/", "@pulumi/", "@pulumiverse/", "pulumi-", "@", ""} { + pkg, err := npm.Get(prefix+name, version) + if err != nil { + continue + } + if pkg.Pulumi.Name == "" { + continue + } + return &ProviderLockEntry{ + Name: name, + Package: pkg.Name, + Version: pkg.Version, + Alias: pkg.Pulumi.Name, + }, nil + } + return nil, fmt.Errorf("provider %s not found", name) +} + func (p *Project) writeProviderLock() error { lockPath := filepath.Join(p.PathPlatformDir(), "provider-lock.json") data, err := json.MarshalIndent(p.lock, "", " ") diff --git a/pkg/project/project.go b/pkg/project/project.go index aefc8214b..8af275e06 100644 --- a/pkg/project/project.go +++ b/pkg/project/project.go @@ -171,6 +171,12 @@ console.log("~j" + JSON.stringify(mod.app({ if argsBool, ok := args.(bool); ok && argsBool { proj.app.Providers[name] = make(map[string]interface{}) } + + if argsString, ok := args.(string); ok { + proj.app.Providers[name] = map[string]interface{}{ + "version": argsString, + } + } } if proj.app.Name == "" { diff --git a/platform/src/ast/add.ts b/platform/src/ast/add.ts index 593a84c3a..51520c15b 100644 --- a/platform/src/ast/add.ts +++ b/platform/src/ast/add.ts @@ -6,6 +6,7 @@ import prettier from "prettier"; const config = process.argv[2]; const pkg = process.argv[3]; +const version = process.argv[4]; const code = fs.readFileSync(config); @@ -61,7 +62,7 @@ if ( // Create a new property node for "foo: {}" const newProperty = ts.factory.createPropertyAssignment( ts.factory.createStringLiteral(pkg), - ts.factory.createTrue(), + ts.factory.createStringLiteral(version), ); providersProperty.initializer.properties.push(newProperty);