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

supabase / cli / 20128715106

11 Dec 2025 09:43AM UTC coverage: 56.046% (-0.2%) from 56.237%
20128715106

Pull #4606

github

web-flow
Merge e5bcc615b into f513dbecb
Pull Request #4606: refactor(cli): replace IDE flags with interactive mode in init

12 of 44 new or added lines in 4 files covered. (27.27%)

13 existing lines in 3 files now uncovered.

6813 of 12156 relevant lines covered (56.05%)

6.29 hits per line

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

68.18
/internal/functions/new/new.go
1
package new
2

3
import (
4
        "context"
5
        _ "embed"
6
        "fmt"
7
        "html/template"
8
        "os"
9
        "path/filepath"
10

11
        "github.com/go-errors/errors"
12
        "github.com/spf13/afero"
13
        "github.com/supabase/cli/internal/functions/deploy"
14
        _init "github.com/supabase/cli/internal/init"
15
        "github.com/supabase/cli/internal/utils"
16
        "github.com/supabase/cli/internal/utils/flags"
17
)
18

19
var (
20
        //go:embed templates/index.ts
21
        indexEmbed string
22
        //go:embed templates/deno.json
23
        denoEmbed string
24
        //go:embed templates/.npmrc
25
        npmrcEmbed string
26
        //go:embed templates/config.toml
27
        configEmbed string
28

29
        indexTemplate  = template.Must(template.New("index").Parse(indexEmbed))
30
        configTemplate = template.Must(template.New("config").Parse(configEmbed))
31
)
32

33
type indexConfig struct {
34
        URL   string
35
        Token string
36
}
37

38
func Run(ctx context.Context, slug string, fsys afero.Fs) error {
4✔
39
        // 1. Sanity checks.
4✔
40
        if err := utils.ValidateFunctionSlug(slug); err != nil {
5✔
41
                return err
1✔
42
        }
1✔
43
        // Check if this is the first function being created
44
        existingSlugs, err := deploy.GetFunctionSlugs(fsys)
3✔
45
        if err != nil {
3✔
NEW
46
                fmt.Fprintln(utils.GetDebugLogger(), err)
×
NEW
47
        }
×
48
        isFirstFunction := len(existingSlugs) == 0
3✔
49

3✔
50
        // 2. Create new function.
3✔
51
        funcDir := filepath.Join(utils.FunctionsDir, slug)
3✔
52
        if err := utils.MkdirIfNotExistFS(fsys, funcDir); err != nil {
4✔
53
                return err
1✔
54
        }
1✔
55
        // Load config if available
56
        if err := flags.LoadConfig(fsys); err != nil {
2✔
57
                fmt.Fprintln(utils.GetDebugLogger(), err)
×
58
        }
×
59
        if err := createEntrypointFile(slug, fsys); err != nil {
3✔
60
                return err
1✔
61
        }
1✔
62
        if err := appendConfigFile(slug, fsys); err != nil {
1✔
63
                return err
×
64
        }
×
65
        // 3. Create optional files
66
        if err := afero.WriteFile(fsys, filepath.Join(funcDir, "deno.json"), []byte(denoEmbed), 0644); err != nil {
1✔
67
                return errors.Errorf("failed to create deno.json config: %w", err)
×
68
        }
×
69
        if err := afero.WriteFile(fsys, filepath.Join(funcDir, ".npmrc"), []byte(npmrcEmbed), 0644); err != nil {
1✔
70
                return errors.Errorf("failed to create .npmrc config: %w", err)
×
71
        }
×
72
        fmt.Println("Created new Function at " + utils.Bold(funcDir))
1✔
73

1✔
74
        if isFirstFunction {
2✔
75
                if err := _init.PromptForIDESettings(ctx, fsys); err != nil {
1✔
76
                        return err
×
77
                }
×
78
        }
79
        return nil
1✔
80
}
81

82
func createEntrypointFile(slug string, fsys afero.Fs) error {
2✔
83
        entrypointPath := filepath.Join(utils.FunctionsDir, slug, "index.ts")
2✔
84
        f, err := fsys.OpenFile(entrypointPath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0644)
2✔
85
        if err != nil {
3✔
86
                return errors.Errorf("failed to create entrypoint: %w", err)
1✔
87
        }
1✔
88
        defer f.Close()
1✔
89
        if err := indexTemplate.Option("missingkey=error").Execute(f, indexConfig{
1✔
90
                URL:   utils.GetApiUrl("/functions/v1/" + slug),
1✔
91
                Token: utils.Config.Auth.AnonKey.Value,
1✔
92
        }); err != nil {
1✔
93
                return errors.Errorf("failed to write entrypoint: %w", err)
×
94
        }
×
95
        return nil
1✔
96
}
97

98
func appendConfigFile(slug string, fsys afero.Fs) error {
1✔
99
        if _, exists := utils.Config.Functions[slug]; exists {
1✔
100
                fmt.Fprintf(os.Stderr, "[functions.%s] is already declared in %s\n", slug, utils.Bold(utils.ConfigPath))
×
101
                return nil
×
102
        }
×
103
        f, err := fsys.OpenFile(utils.ConfigPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
1✔
104
        if err != nil {
1✔
105
                return errors.Errorf("failed to append config: %w", err)
×
106
        }
×
107
        defer f.Close()
1✔
108
        if err := configTemplate.Option("missingkey=error").Execute(f, slug); err != nil {
1✔
109
                return errors.Errorf("failed to append template: %w", err)
×
110
        }
×
111
        return nil
1✔
112
}
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