From 4b9b7b3421b5b9dee4ceed015258b049fe8087c1 Mon Sep 17 00:00:00 2001 From: Qiao Han Date: Tue, 11 Feb 2025 20:53:03 +0800 Subject: [PATCH] fix: fail on static directories --- cmd/functions.go | 15 +++++++++------ internal/functions/deploy/upload.go | 5 +++-- internal/functions/deploy/upload_test.go | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/cmd/functions.go b/cmd/functions.go index 7713f1f14..4904d0c13 100644 --- a/cmd/functions.go +++ b/cmd/functions.go @@ -54,8 +54,8 @@ var ( useApi bool useDocker bool - noVerifyJWT = new(bool) useLegacyBundle bool + noVerifyJWT = new(bool) importMapPath string functionsDeployCmd = &cobra.Command{ @@ -67,6 +67,9 @@ var ( if !cmd.Flags().Changed("no-verify-jwt") { noVerifyJWT = nil } + if useApi { + useDocker = false + } return deploy.Run(cmd.Context(), args, useDocker, noVerifyJWT, importMapPath, afero.NewOsFs()) }, } @@ -126,14 +129,14 @@ func init() { functionsListCmd.Flags().StringVar(&flags.ProjectRef, "project-ref", "", "Project ref of the Supabase project.") functionsDeleteCmd.Flags().StringVar(&flags.ProjectRef, "project-ref", "", "Project ref of the Supabase project.") deployFlags := functionsDeployCmd.Flags() - deployFlags.BoolVar(&useApi, "use-api", true, "Use Management API to bundle functions.") - deployFlags.BoolVar(&useDocker, "use-docker", false, "Use Docker to bundle functions.") - functionsDeployCmd.MarkFlagsMutuallyExclusive("use-api", "use-docker") + deployFlags.BoolVar(&useApi, "use-api", false, "Use Management API to bundle functions.") + deployFlags.BoolVar(&useDocker, "use-docker", true, "Use Docker to bundle functions.") + deployFlags.BoolVar(&useLegacyBundle, "legacy-bundle", false, "Use legacy bundling mechanism.") + functionsDeployCmd.MarkFlagsMutuallyExclusive("use-api", "use-docker", "legacy-bundle") + cobra.CheckErr(deployFlags.MarkHidden("legacy-bundle")) deployFlags.BoolVar(noVerifyJWT, "no-verify-jwt", false, "Disable JWT verification for the Function.") deployFlags.StringVar(&flags.ProjectRef, "project-ref", "", "Project ref of the Supabase project.") - deployFlags.BoolVar(&useLegacyBundle, "legacy-bundle", false, "Use legacy bundling mechanism.") deployFlags.StringVar(&importMapPath, "import-map", "", "Path to import map file.") - cobra.CheckErr(deployFlags.MarkHidden("legacy-bundle")) functionsServeCmd.Flags().BoolVar(noVerifyJWT, "no-verify-jwt", false, "Disable JWT verification for the Function.") functionsServeCmd.Flags().StringVar(&envFilePath, "env-file", "", "Path to an env file to be populated to the Function environment.") functionsServeCmd.Flags().StringVar(&importMapPath, "import-map", "", "Path to import map file.") diff --git a/internal/functions/deploy/upload.go b/internal/functions/deploy/upload.go index f70bb0f6f..e9a425b88 100644 --- a/internal/functions/deploy/upload.go +++ b/internal/functions/deploy/upload.go @@ -79,6 +79,8 @@ func upload(ctx context.Context, param api.V1DeployAFunctionParams, meta api.Fun defer w.Close() defer form.Close() if err := writeForm(form, meta, fsys); err != nil { + // Since we are streaming files to the POST request body, any errors + // should be propagated to the request context to cancel the upload. cancel(err) } }() @@ -111,8 +113,7 @@ func writeForm(form *multipart.Writer, meta api.FunctionDeployMetadata, fsys afe if fi, err := f.Stat(); err != nil { return errors.Errorf("failed to stat file: %w", err) } else if fi.IsDir() { - fmt.Fprintln(os.Stderr, "Skipping directory:", srcPath) - return nil + return errors.New("file path is a directory: " + srcPath) } fmt.Fprintln(os.Stderr, "Uploading asset:", srcPath) r := io.TeeReader(f, w) diff --git a/internal/functions/deploy/upload_test.go b/internal/functions/deploy/upload_test.go index 79431ecef..cbd549459 100644 --- a/internal/functions/deploy/upload_test.go +++ b/internal/functions/deploy/upload_test.go @@ -120,6 +120,20 @@ func TestWriteForm(t *testing.T) { // Check error assert.ErrorIs(t, err, os.ErrNotExist) }) + + t.Run("throws error on directory path", func(t *testing.T) { + var buf bytes.Buffer + form := multipart.NewWriter(&buf) + require.NoError(t, form.SetBoundary("test")) + // Setup in-memory fs + fsys := afero.NewMemMapFs() + // Run test + err := writeForm(form, api.FunctionDeployMetadata{ + StaticPatterns: cast.Ptr([]string{"testdata"}), + }, fsys) + // Check error + assert.ErrorContains(t, err, "file path is a directory:") + }) } func TestDeployAll(t *testing.T) {