github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/command/v6/create_buildpack_command.go (about) 1 package v6 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "strings" 8 "time" 9 10 "code.cloudfoundry.org/cli/actor/actionerror" 11 "code.cloudfoundry.org/cli/actor/sharedaction" 12 "code.cloudfoundry.org/cli/actor/v2action" 13 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 14 "code.cloudfoundry.org/cli/command" 15 "code.cloudfoundry.org/cli/command/flag" 16 "code.cloudfoundry.org/cli/command/translatableerror" 17 "code.cloudfoundry.org/cli/command/v6/shared" 18 "code.cloudfoundry.org/cli/util/download" 19 ) 20 21 //go:generate counterfeiter . Downloader 22 23 type Downloader interface { 24 Download(string) (string, error) 25 } 26 27 //go:generate counterfeiter . CreateBuildpackActor 28 29 type CreateBuildpackActor interface { 30 CreateBuildpack(name string, position int, enabled bool) (v2action.Buildpack, v2action.Warnings, error) 31 UploadBuildpack(GUID string, path string, progBar v2action.SimpleProgressBar) (v2action.Warnings, error) 32 PrepareBuildpackBits(inputPath string, tmpDirPath string, downloader v2action.Downloader) (string, error) 33 } 34 35 type CreateBuildpackCommand struct { 36 RequiredArgs flag.CreateBuildpackArgs `positional-args:"yes"` 37 Disable bool `long:"disable" description:"Disable the buildpack from being used for staging"` 38 Enable bool `long:"enable" description:"Enable the buildpack to be used for staging"` 39 usage interface{} `usage:"CF_NAME create-buildpack BUILDPACK PATH POSITION [--enable|--disable]\n\nTIP:\n Path should be a zip file, a url to a zip file, or a local directory. Position is a positive integer, sets priority, and is sorted from lowest to highest."` 40 relatedCommands interface{} `related_commands:"buildpacks, push"` 41 42 UI command.UI 43 Actor CreateBuildpackActor 44 ProgressBar v2action.SimpleProgressBar 45 SharedActor command.SharedActor 46 Config command.Config 47 } 48 49 func (cmd *CreateBuildpackCommand) Setup(config command.Config, ui command.UI) error { 50 cmd.UI = ui 51 cmd.Config = config 52 cmd.SharedActor = sharedaction.NewActor(config) 53 54 ccClient, uaaClient, err := shared.GetNewClientsAndConnectToCF(config, ui) 55 if err != nil { 56 return err 57 } 58 cmd.Actor = v2action.NewActor(ccClient, uaaClient, config) 59 cmd.ProgressBar = v2action.NewProgressBar() 60 61 return nil 62 } 63 64 func (cmd *CreateBuildpackCommand) Execute(args []string) error { 65 if cmd.Enable && cmd.Disable { 66 return translatableerror.ArgumentCombinationError{ 67 Args: []string{"--enable", "--disable"}, 68 } 69 } 70 71 err := cmd.SharedActor.CheckTarget(false, false) 72 if err != nil { 73 return err 74 } 75 76 user, err := cmd.Config.CurrentUser() 77 if err != nil { 78 return err 79 } 80 81 cmd.UI.DisplayTextWithFlavor("Creating buildpack {{.Buildpack}} as {{.Username}}...", map[string]interface{}{ 82 "Buildpack": cmd.RequiredArgs.Buildpack, 83 "Username": user.Name, 84 }) 85 86 downloader := download.NewDownloader(time.Second * 30) 87 tmpDirPath, err := ioutil.TempDir("", "buildpack-dir-") 88 if err != nil { 89 return err 90 } 91 defer os.RemoveAll(tmpDirPath) 92 93 pathToBuildpackBits, err := cmd.Actor.PrepareBuildpackBits(string(cmd.RequiredArgs.Path), tmpDirPath, downloader) 94 if err != nil { 95 return err 96 } 97 98 buildpack, warnings, err := cmd.Actor.CreateBuildpack(cmd.RequiredArgs.Buildpack, cmd.RequiredArgs.Position, !cmd.Disable) 99 cmd.UI.DisplayWarnings(warnings) 100 101 if err != nil { 102 return cmd.displayIfKnownBuildpackError(err) 103 } 104 105 cmd.UI.DisplayOK() 106 107 cmd.UI.DisplayTextWithFlavor("Uploading buildpack {{.Buildpack}} as {{.Username}}...", map[string]interface{}{ 108 "Buildpack": cmd.RequiredArgs.Buildpack, 109 "Username": user.Name, 110 }) 111 112 uploadWarnings, err := cmd.Actor.UploadBuildpack(buildpack.GUID, pathToBuildpackBits, cmd.ProgressBar) 113 if _, ok := err.(ccerror.InvalidAuthTokenError); ok { 114 cmd.UI.DisplayWarnings([]string{"Failed to upload buildpack due to auth token expiration, retrying..."}) 115 uploadWarnings, err = cmd.Actor.UploadBuildpack(buildpack.GUID, pathToBuildpackBits, cmd.ProgressBar) 116 } 117 cmd.UI.DisplayWarnings(uploadWarnings) 118 if err != nil { 119 cmd.UI.DisplayNewline() 120 cmd.UI.DisplayNewline() 121 if _, ok := err.(actionerror.BuildpackAlreadyExistsForStackError); ok { 122 cmd.displayNameAndStackCollisionError(err) 123 return nil 124 } else if httpErr, ok := err.(download.RawHTTPStatusError); ok { 125 return translatableerror.HTTPStatusError{Status: httpErr.Status} 126 } 127 return err 128 } 129 130 cmd.UI.DisplayNewline() 131 cmd.UI.DisplayText("Done uploading") 132 cmd.UI.DisplayOK() 133 134 return nil 135 } 136 137 func (cmd CreateBuildpackCommand) displayNameAndStackCollisionError(err error) { 138 cmd.UI.DisplayWarning(err.Error()) 139 cmd.UI.DisplayTextWithFlavor("TIP: use '{{.CfUpdateBuildpackCommand}}' to update this buildpack", 140 map[string]interface{}{ 141 "CfUpdateBuildpackCommand": cmd.Config.BinaryName() + " update-buildpack", 142 }) 143 } 144 145 func (cmd CreateBuildpackCommand) displayIfKnownBuildpackError(err error) error { 146 if _, ok := err.(actionerror.BuildpackInvalidError); ok { 147 if strings.Index(err.Error(), "stack unique") != -1 { 148 cmd.displayAlreadyExistingBuildpackWithoutStack(err) 149 return nil 150 } else if strings.Index(err.Error(), "can only contain alphanumeric characters") != -1 { 151 cmd.displayInvalidBuildpackName(err) 152 return nil 153 } 154 } else if _, ok := err.(actionerror.BuildpackNameTakenError); ok { 155 cmd.displayAlreadyExistingBuildpack(err) 156 return nil 157 } 158 return err 159 } 160 161 func (cmd CreateBuildpackCommand) displayInvalidBuildpackName(err error) { 162 cmd.UI.DisplayNewline() 163 cmd.UI.DisplayWarning(err.Error()) 164 } 165 166 func (cmd CreateBuildpackCommand) displayAlreadyExistingBuildpackWithoutStack(err error) { 167 cmd.UI.DisplayNewline() 168 cmd.UI.DisplayWarning(fmt.Sprintf("Buildpack %s already exists without a stack", cmd.RequiredArgs.Buildpack)) 169 cmd.UI.DisplayTextWithFlavor("TIP: use '{{.CfBuildpacksCommand}}' and '{{.CfDeleteBuildpackCommand}}' to delete buildpack {{.BuildpackName}} without a stack", 170 map[string]interface{}{ 171 "CfBuildpacksCommand": cmd.Config.BinaryName() + " buildpacks", 172 "CfDeleteBuildpackCommand": cmd.Config.BinaryName() + " delete-buildpack", 173 "BuildpackName": cmd.RequiredArgs.Buildpack, 174 }) 175 } 176 177 func (cmd CreateBuildpackCommand) displayAlreadyExistingBuildpack(err error) { 178 cmd.UI.DisplayNewline() 179 cmd.UI.DisplayWarning(err.Error()) 180 cmd.UI.DisplayTextWithFlavor("TIP: use '{{.CfUpdateBuildpackCommand}}' to update this buildpack", 181 map[string]interface{}{ 182 "CfUpdateBuildpackCommand": cmd.Config.BinaryName() + " update-buildpack", 183 }) 184 }