github.com/rainforestapp/rainforest-cli@v2.12.0+incompatible/mobile_upload.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "strconv" 8 "strings" 9 10 "github.com/rainforestapp/rainforest-cli/rainforest" 11 "github.com/urfave/cli" 12 ) 13 14 // mobileUploadAPI is part of the API connected to mobile uploads 15 type mobileUploadAPI interface { 16 GetPresignedPOST(fileExt string, siteID int, environmentID int, appSlot int) (*rainforest.RFPresignedPostData, error) 17 UploadToS3(postData *rainforest.RFPresignedPostData, filePath string) error 18 UpdateURL(siteID int, environmentID int, appSlot int, newURL string) error 19 } 20 21 // uploadMobileApp takes a path to a mobile app file and uploads it to S3 then sets 22 // the site-id specified's URL to the magic url 23 func uploadMobileApp(api mobileUploadAPI, filePath string, siteID int, environmentID int, appSlot int) error { 24 25 presignedPostData, err := api.GetPresignedPOST(filepath.Ext(filePath), siteID, environmentID, appSlot) 26 if err != nil { 27 return err 28 } 29 30 err = api.UploadToS3(presignedPostData, filePath) 31 if err != nil { 32 return err 33 } 34 35 err = api.UpdateURL(siteID, environmentID, appSlot, presignedPostData.RainforestURL) 36 if err != nil { 37 return err 38 } 39 40 return nil 41 } 42 43 func isAllowedExtension(extension string) bool { 44 switch extension { 45 case ".apk", ".ipa", ".zip", ".gz", ".tar.gz": 46 return true 47 } 48 return false 49 } 50 51 const allowedExtensionsPretty = ".apk, .ipa, .zip, .gz, .tar.gz" 52 53 // mobileAppUpload is a wrapper around uploadMobileApp to function with mobile-upload cli command 54 func mobileAppUpload(c cliContext, api mobileUploadAPI) error { 55 // Get the filepath from the arg 56 filePath := c.Args().First() 57 if filePath == "" { 58 return cli.NewExitError("Mobile app file path not specified", 1) 59 } 60 61 // verify extension 62 fileExt := strings.ToLower(filepath.Ext(filePath)) 63 if !isAllowedExtension(fileExt) { 64 return cli.NewExitError(fmt.Sprintf("Invalid file extension. - %v. Allowed Extensions: %v", fileExt, allowedExtensionsPretty), 1) 65 } 66 67 siteIDString := c.String("site-id") 68 if siteIDString == "" { 69 return cli.NewExitError("site-id flag required", 1) 70 } 71 siteID, err := strconv.Atoi(siteIDString) 72 if err != nil { 73 return cli.NewExitError("site-id must be an integer", 1) 74 } 75 76 envIDstring := c.String("environment-id") 77 if envIDstring == "" { 78 return cli.NewExitError("environment-id flag required", 1) 79 } 80 environmentID, err := strconv.Atoi(envIDstring) 81 if err != nil { 82 return cli.NewExitError("environment-id must be an integer", 1) 83 } 84 85 appSlot := 1 // Default to 1, optional param 86 appSlotString := c.String("app-slot") 87 if appSlotString != "" { 88 appSlot, err = strconv.Atoi(appSlotString) 89 if err != nil || appSlot < 1 || appSlot > 100 { 90 return cli.NewExitError("app-slot must be an integer (1 to 100)", 1) 91 } 92 } 93 94 // Open app and return early with an error if we fail 95 f, err := os.Open(filePath) 96 if err != nil { 97 return cli.NewExitError(err.Error(), 1) 98 } 99 defer f.Close() 100 101 err = uploadMobileApp(api, filePath, siteID, environmentID, appSlot) 102 if err != nil { 103 return cli.NewExitError(err.Error(), 1) 104 } 105 106 return nil 107 }