github.com/Redstoneguy129/cli@v0.0.0-20230211220159-15dca4e91917/internal/functions/download/download.go (about) 1 package download 2 3 import ( 4 "bytes" 5 "context" 6 "errors" 7 "fmt" 8 "net/http" 9 "os" 10 "os/exec" 11 "path/filepath" 12 13 "github.com/Redstoneguy129/cli/internal/utils" 14 "github.com/spf13/afero" 15 ) 16 17 func Run(ctx context.Context, slug string, projectRefArg string, fsys afero.Fs) error { 18 // 1. Sanity checks. 19 projectRef := projectRefArg 20 var scriptDir *utils.DenoScriptDir 21 { 22 if len(projectRefArg) == 0 { 23 ref, err := utils.LoadProjectRef(fsys) 24 if err != nil { 25 return err 26 } 27 projectRef = ref 28 } else if !utils.ProjectRefPattern.MatchString(projectRefArg) { 29 return errors.New("Invalid project ref format. Must be like `abcdefghijklmnopqrst`.") 30 } 31 if err := utils.ValidateFunctionSlug(slug); err != nil { 32 return err 33 } 34 } 35 if err := utils.InstallOrUpgradeDeno(ctx, fsys); err != nil { 36 return err 37 } 38 39 var err error 40 scriptDir, err = utils.CopyDenoScripts(ctx, fsys) 41 if err != nil { 42 return err 43 } 44 45 // 2. Download Function. 46 { 47 fmt.Println("Downloading " + utils.Bold(slug)) 48 denoPath, err := utils.GetDenoPath() 49 if err != nil { 50 return err 51 } 52 53 resp, err := utils.GetSupabase().GetFunctionBodyWithResponse(ctx, projectRef, slug) 54 if err != nil { 55 return err 56 } 57 58 switch resp.StatusCode() { 59 case http.StatusNotFound: // Function doesn't exist 60 return errors.New("Function " + utils.Aqua(slug) + " does not exist on the Supabase project.") 61 case http.StatusOK: // Function exists 62 resBuf := bytes.NewReader(resp.Body) 63 64 extractScriptPath := scriptDir.ExtractPath 65 funcDir := filepath.Join(utils.FunctionsDir, slug) 66 var errBuf bytes.Buffer 67 args := []string{"run", "-A", extractScriptPath, funcDir} 68 cmd := exec.CommandContext(ctx, denoPath, args...) 69 cmd.Stdin = resBuf 70 cmd.Stdout = os.Stdout 71 cmd.Stderr = &errBuf 72 if err := cmd.Run(); err != nil { 73 return fmt.Errorf("Error downloading function: %w\n%v", err, errBuf.String()) 74 } 75 default: 76 return errors.New("Unexpected error downloading Function: " + string(resp.Body)) 77 } 78 } 79 80 fmt.Println("Downloaded Function " + utils.Aqua(slug) + " from project " + utils.Aqua(projectRef) + ".") 81 return nil 82 }