github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/cf/commands/buildpack/update_buildpack.go (about) 1 package buildpack 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 8 "code.cloudfoundry.org/cli/cf/api" 9 "code.cloudfoundry.org/cli/cf/commandregistry" 10 "code.cloudfoundry.org/cli/cf/flags" 11 . "code.cloudfoundry.org/cli/cf/i18n" 12 "code.cloudfoundry.org/cli/cf/requirements" 13 "code.cloudfoundry.org/cli/cf/terminal" 14 ) 15 16 type UpdateBuildpack struct { 17 ui terminal.UI 18 buildpackRepo api.BuildpackRepository 19 buildpackBitsRepo api.BuildpackBitsRepository 20 buildpackReq requirements.BuildpackRequirement 21 } 22 23 func init() { 24 commandregistry.Register(&UpdateBuildpack{}) 25 } 26 27 func (cmd *UpdateBuildpack) MetaData() commandregistry.CommandMetadata { 28 fs := make(map[string]flags.FlagSet) 29 fs["i"] = &flags.IntFlag{ShortName: "i", Usage: T("The order in which the buildpacks are checked during buildpack auto-detection")} 30 fs["s"] = &flags.StringFlag{ShortName: "s", Usage: T("Specify stack to disambiguate buildpacks with the same name")} 31 fs["p"] = &flags.StringFlag{ShortName: "p", Usage: T("Path to directory or zip file")} 32 fs["enable"] = &flags.BoolFlag{Name: "enable", Usage: T("Enable the buildpack to be used for staging")} 33 fs["disable"] = &flags.BoolFlag{Name: "disable", Usage: T("Disable the buildpack from being used for staging")} 34 fs["lock"] = &flags.BoolFlag{Name: "lock", Usage: T("Lock the buildpack to prevent updates")} 35 fs["unlock"] = &flags.BoolFlag{Name: "unlock", Usage: T("Unlock the buildpack to enable updates")} 36 37 return commandregistry.CommandMetadata{ 38 Name: "update-buildpack", 39 Description: T("Update a buildpack"), 40 Usage: []string{ 41 T("CF_NAME update-buildpack BUILDPACK [-p PATH] [-i POSITION] [-s STACK] [--enable|--disable] [--lock|--unlock]"), 42 T("\n\nTIP:\n"), 43 T(" 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."), 44 }, 45 Flags: fs, 46 } 47 } 48 49 func (cmd *UpdateBuildpack) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) ([]requirements.Requirement, error) { 50 if len(fc.Args()) != 1 { 51 cmd.ui.Failed(T("Incorrect Usage. Requires an argument\n\n") + commandregistry.Commands.CommandUsage("update-buildpack")) 52 return nil, fmt.Errorf("Incorrect usage: %d arguments of %d required", len(fc.Args()), 1) 53 } 54 55 loginReq := requirementsFactory.NewLoginRequirement() 56 cmd.buildpackReq = requirementsFactory.NewBuildpackRequirement(fc.Args()[0], fc.String("s")) 57 58 reqs := []requirements.Requirement{ 59 loginReq, 60 cmd.buildpackReq, 61 } 62 63 return reqs, nil 64 } 65 66 func (cmd *UpdateBuildpack) SetDependency(deps commandregistry.Dependency, pluginCall bool) commandregistry.Command { 67 cmd.ui = deps.UI 68 cmd.buildpackRepo = deps.RepoLocator.GetBuildpackRepository() 69 cmd.buildpackBitsRepo = deps.RepoLocator.GetBuildpackBitsRepository() 70 return cmd 71 } 72 73 func (cmd *UpdateBuildpack) Execute(c flags.FlagContext) error { 74 buildpack := cmd.buildpackReq.GetBuildpack() 75 76 cmd.ui.Say(T("Updating buildpack {{.BuildpackName}} with stack {{.BuildpackStack}}...", map[string]interface{}{"BuildpackName": terminal.EntityNameColor(buildpack.Name), "BuildpackStack": terminal.EntityNameColor(buildpack.Stack)})) 77 78 updateBuildpack := false 79 80 if c.IsSet("i") { 81 position := c.Int("i") 82 83 buildpack.Position = &position 84 updateBuildpack = true 85 } 86 87 enabled := c.Bool("enable") 88 disabled := c.Bool("disable") 89 if enabled && disabled { 90 return errors.New(T("Cannot specify both {{.Enabled}} and {{.Disabled}}.", map[string]interface{}{ 91 "Enabled": "enabled", 92 "Disabled": "disabled", 93 })) 94 } 95 96 if enabled { 97 buildpack.Enabled = &enabled 98 updateBuildpack = true 99 } 100 if disabled { 101 disabled = false 102 buildpack.Enabled = &disabled 103 updateBuildpack = true 104 } 105 106 lock := c.Bool("lock") 107 unlock := c.Bool("unlock") 108 if lock && unlock { 109 return errors.New(T("Cannot specify both lock and unlock options.")) 110 } 111 112 path := c.String("p") 113 114 if path != "" && (lock || unlock) { 115 return errors.New(T("Cannot specify buildpack bits and lock/unlock.")) 116 } 117 118 if lock { 119 buildpack.Locked = &lock 120 updateBuildpack = true 121 } 122 if unlock { 123 unlock = false 124 buildpack.Locked = &unlock 125 updateBuildpack = true 126 } 127 var ( 128 buildpackFile *os.File 129 buildpackFileName string 130 err error 131 ) 132 if path != "" { 133 buildpackFile, buildpackFileName, err = cmd.buildpackBitsRepo.CreateBuildpackZipFile(path) 134 if err != nil { 135 cmd.ui.Warn(T("Failed to create a local temporary zip file for the buildpack")) 136 return err 137 } 138 } 139 140 if updateBuildpack { 141 newBuildpack, err := cmd.buildpackRepo.Update(buildpack) 142 if err != nil { 143 return errors.New(T("Error updating buildpack {{.Name}}\n{{.Error}}", map[string]interface{}{ 144 "Name": terminal.EntityNameColor(buildpack.Name), 145 "Error": err.Error(), 146 })) 147 } 148 buildpack = newBuildpack 149 } 150 151 if path != "" { 152 err := cmd.buildpackBitsRepo.UploadBuildpack(buildpack, buildpackFile, buildpackFileName) 153 if err != nil { 154 return errors.New(T("Error uploading buildpack {{.Name}}\n{{.Error}}", map[string]interface{}{ 155 "Name": terminal.EntityNameColor(buildpack.Name), 156 "Error": err.Error(), 157 })) 158 } 159 } 160 cmd.ui.Ok() 161 return nil 162 }