• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / cli / 13774747273

10 Mar 2025 09:04PM UTC coverage: 57.683% (-0.04%) from 57.727%
13774747273

Pull #3279

github

web-flow
Merge 8e053712e into e1ae7274d
Pull Request #3279: fix: append to empty request array

0 of 1 new or added line in 1 file covered. (0.0%)

8 existing lines in 2 files now uncovered.

7846 of 13602 relevant lines covered (57.68%)

198.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

19.81
/pkg/function/batch.go
1
package function
2

3
import (
4
        "bytes"
5
        "context"
6
        "fmt"
7
        "net/url"
8
        "os"
9
        "path/filepath"
10
        "strings"
11

12
        "github.com/cenkalti/backoff/v4"
13
        "github.com/docker/go-units"
14
        "github.com/go-errors/errors"
15
        "github.com/supabase/cli/pkg/api"
16
        "github.com/supabase/cli/pkg/config"
17
)
18

19
const (
20
        eszipContentType = "application/vnd.denoland.eszip"
21
        maxRetries       = 3
22
)
23

24
func (s *EdgeRuntimeAPI) UpsertFunctions(ctx context.Context, functionConfig config.FunctionConfig, filter ...func(string) bool) error {
4✔
25
        var result []api.FunctionResponse
4✔
26
        if resp, err := s.client.V1ListAllFunctionsWithResponse(ctx, s.project); err != nil {
5✔
27
                return errors.Errorf("failed to list functions: %w", err)
1✔
28
        } else if resp.JSON200 == nil {
5✔
29
                return errors.Errorf("unexpected status %d: %s", resp.StatusCode(), string(resp.Body))
1✔
30
        } else {
3✔
31
                result = *resp.JSON200
2✔
32
        }
2✔
33
        exists := make(map[string]struct{}, len(result))
2✔
34
        for _, f := range result {
3✔
35
                exists[f.Slug] = struct{}{}
1✔
36
        }
1✔
37
        toUpdate := map[string]api.BulkUpdateFunctionBody{}
2✔
38
OUTER:
2✔
39
        for slug, function := range functionConfig {
4✔
40
                if !function.Enabled {
4✔
41
                        fmt.Fprintln(os.Stderr, "Skipped deploying Function:", slug)
2✔
42
                        continue
2✔
43
                }
44
                for _, keep := range filter {
×
45
                        if !keep(slug) {
×
46
                                continue OUTER
×
47
                        }
48
                }
49
                var body bytes.Buffer
×
50
                if err := s.eszip.Bundle(ctx, function.Entrypoint, function.ImportMap, function.StaticFiles, &body); err != nil {
×
51
                        return err
×
52
                }
×
53
                // Update if function already exists
54
                upsert := func() error {
×
55
                        if _, ok := exists[slug]; ok {
×
56
                                resp, err := s.client.V1UpdateAFunctionWithBodyWithResponse(ctx, s.project, slug, &api.V1UpdateAFunctionParams{
×
57
                                        VerifyJwt:      &function.VerifyJWT,
×
58
                                        ImportMapPath:  toFileURL(function.ImportMap),
×
59
                                        EntrypointPath: toFileURL(function.Entrypoint),
×
60
                                }, eszipContentType, bytes.NewReader(body.Bytes()))
×
61
                                if err != nil {
×
62
                                        return errors.Errorf("failed to update function: %w", err)
×
63
                                } else if resp.JSON200 == nil {
×
64
                                        return errors.Errorf("unexpected status %d: %s", resp.StatusCode(), string(resp.Body))
×
65
                                }
×
66
                                toUpdate[slug] = api.BulkUpdateFunctionBody{
×
67
                                        Id:             resp.JSON200.Id,
×
68
                                        Name:           resp.JSON200.Name,
×
69
                                        Slug:           resp.JSON200.Slug,
×
70
                                        Version:        resp.JSON200.Version,
×
71
                                        EntrypointPath: resp.JSON200.EntrypointPath,
×
72
                                        ImportMap:      resp.JSON200.ImportMap,
×
73
                                        ImportMapPath:  resp.JSON200.ImportMapPath,
×
74
                                        VerifyJwt:      resp.JSON200.VerifyJwt,
×
75
                                        Status:         api.BulkUpdateFunctionBodyStatus(resp.JSON200.Status),
×
76
                                        CreatedAt:      &resp.JSON200.CreatedAt,
×
77
                                }
×
78
                        } else {
×
79
                                resp, err := s.client.V1CreateAFunctionWithBodyWithResponse(ctx, s.project, &api.V1CreateAFunctionParams{
×
80
                                        Slug:           &slug,
×
81
                                        Name:           &slug,
×
82
                                        VerifyJwt:      &function.VerifyJWT,
×
83
                                        ImportMapPath:  toFileURL(function.ImportMap),
×
84
                                        EntrypointPath: toFileURL(function.Entrypoint),
×
85
                                }, eszipContentType, bytes.NewReader(body.Bytes()))
×
86
                                if err != nil {
×
87
                                        return errors.Errorf("failed to create function: %w", err)
×
88
                                } else if resp.JSON201 == nil {
×
89
                                        return errors.Errorf("unexpected status %d: %s", resp.StatusCode(), string(resp.Body))
×
90
                                }
×
91
                                toUpdate[slug] = api.BulkUpdateFunctionBody{
×
92
                                        Id:             resp.JSON201.Id,
×
93
                                        Name:           resp.JSON201.Name,
×
94
                                        Slug:           resp.JSON201.Slug,
×
95
                                        Version:        resp.JSON201.Version,
×
96
                                        EntrypointPath: resp.JSON201.EntrypointPath,
×
97
                                        ImportMap:      resp.JSON201.ImportMap,
×
98
                                        ImportMapPath:  resp.JSON201.ImportMapPath,
×
99
                                        VerifyJwt:      resp.JSON201.VerifyJwt,
×
100
                                        Status:         api.BulkUpdateFunctionBodyStatus(resp.JSON201.Status),
×
101
                                        CreatedAt:      &resp.JSON201.CreatedAt,
×
102
                                }
×
103
                        }
104
                        return nil
×
105
                }
106
                functionSize := units.HumanSize(float64(body.Len()))
×
107
                fmt.Fprintf(os.Stderr, "Deploying Function: %s (script size: %s)\n", slug, functionSize)
×
108
                policy := backoff.WithContext(backoff.WithMaxRetries(backoff.NewExponentialBackOff(), maxRetries), ctx)
×
109
                if err := backoff.Retry(upsert, policy); err != nil {
×
110
                        return err
×
111
                }
×
112
        }
113
        if len(toUpdate) > 1 {
2✔
NEW
114
                var body []api.BulkUpdateFunctionBody
×
115
                for _, b := range toUpdate {
×
116
                        body = append(body, b)
×
117
                }
×
118
                if resp, err := s.client.V1BulkUpdateFunctionsWithResponse(ctx, s.project, body); err != nil {
×
119
                        return errors.Errorf("failed to bulk update: %w", err)
×
120
                } else if resp.JSON200 == nil {
×
121
                        return errors.Errorf("unexpected bulk update status %d: %s", resp.StatusCode(), string(resp.Body))
×
122
                }
×
123
        }
124
        return nil
2✔
125
}
126

127
func toFileURL(hostPath string) *string {
×
128
        absHostPath, err := filepath.Abs(hostPath)
×
129
        if err != nil {
×
130
                return nil
×
131
        }
×
132
        // Convert to unix path because edge runtime only supports linux
133
        parsed := url.URL{Scheme: "file", Path: toUnixPath(absHostPath)}
×
134
        result := parsed.String()
×
135
        return &result
×
136
}
137

138
func toUnixPath(absHostPath string) string {
×
139
        prefix := filepath.VolumeName(absHostPath)
×
140
        unixPath := filepath.ToSlash(absHostPath)
×
141
        return strings.TrimPrefix(unixPath, prefix)
×
142
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc