github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/cf/commands/buildpack/create_buildpack.go (about)

     1  package buildpack
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  
     7  	"code.cloudfoundry.org/cli/cf/flags"
     8  	. "code.cloudfoundry.org/cli/cf/i18n"
     9  
    10  	"code.cloudfoundry.org/cli/cf"
    11  	"code.cloudfoundry.org/cli/cf/api"
    12  	"code.cloudfoundry.org/cli/cf/commandregistry"
    13  	"code.cloudfoundry.org/cli/cf/errors"
    14  	"code.cloudfoundry.org/cli/cf/models"
    15  	"code.cloudfoundry.org/cli/cf/requirements"
    16  	"code.cloudfoundry.org/cli/cf/terminal"
    17  )
    18  
    19  type CreateBuildpack struct {
    20  	ui                terminal.UI
    21  	buildpackRepo     api.BuildpackRepository
    22  	buildpackBitsRepo api.BuildpackBitsRepository
    23  }
    24  
    25  func init() {
    26  	commandregistry.Register(&CreateBuildpack{})
    27  }
    28  
    29  func (cmd *CreateBuildpack) MetaData() commandregistry.CommandMetadata {
    30  	fs := make(map[string]flags.FlagSet)
    31  	fs["enable"] = &flags.BoolFlag{Name: "enable", Usage: T("Enable the buildpack to be used for staging")}
    32  	fs["disable"] = &flags.BoolFlag{Name: "disable", Usage: T("Disable the buildpack from being used for staging")}
    33  
    34  	return commandregistry.CommandMetadata{
    35  		Name:        "create-buildpack",
    36  		Description: T("Create a buildpack"),
    37  		Usage: []string{
    38  			T("CF_NAME create-buildpack BUILDPACK PATH POSITION [--enable|--disable]"),
    39  			T("\n\nTIP:\n"),
    40  			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."),
    41  		},
    42  		Flags:     fs,
    43  		TotalArgs: 3,
    44  	}
    45  }
    46  
    47  func (cmd *CreateBuildpack) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) ([]requirements.Requirement, error) {
    48  	if len(fc.Args()) != 3 {
    49  		cmd.ui.Failed(T("Incorrect Usage. Requires buildpack_name, path and position as arguments\n\n") + commandregistry.Commands.CommandUsage("create-buildpack"))
    50  		return nil, fmt.Errorf("Incorrect usage: %d arguments of %d required", len(fc.Args()), 3)
    51  	}
    52  
    53  	reqs := []requirements.Requirement{
    54  		requirementsFactory.NewLoginRequirement(),
    55  	}
    56  
    57  	return reqs, nil
    58  }
    59  
    60  func (cmd *CreateBuildpack) SetDependency(deps commandregistry.Dependency, pluginCall bool) commandregistry.Command {
    61  	cmd.ui = deps.UI
    62  	cmd.buildpackRepo = deps.RepoLocator.GetBuildpackRepository()
    63  	cmd.buildpackBitsRepo = deps.RepoLocator.GetBuildpackBitsRepository()
    64  	return cmd
    65  }
    66  
    67  func (cmd *CreateBuildpack) Execute(c flags.FlagContext) error {
    68  	buildpackName := c.Args()[0]
    69  
    70  	buildpackFile, buildpackFileName, err := cmd.buildpackBitsRepo.CreateBuildpackZipFile(c.Args()[1])
    71  	if err != nil {
    72  		cmd.ui.Warn(T("Failed to create a local temporary zip file for the buildpack"))
    73  		return err
    74  	}
    75  
    76  	cmd.ui.Say(T("Creating buildpack {{.BuildpackName}}...", map[string]interface{}{"BuildpackName": terminal.EntityNameColor(buildpackName)}))
    77  
    78  	buildpack, err := cmd.createBuildpack(buildpackName, c)
    79  
    80  	if err != nil {
    81  		if httpErr, ok := err.(errors.HTTPError); ok && httpErr.ErrorCode() == errors.BuildpackNameTaken {
    82  			cmd.ui.Ok()
    83  			cmd.ui.Warn(T("Buildpack {{.BuildpackName}} already exists", map[string]interface{}{"BuildpackName": buildpackName}))
    84  			cmd.ui.Say(T("TIP: use '{{.CfUpdateBuildpackCommand}}' to update this buildpack", map[string]interface{}{"CfUpdateBuildpackCommand": terminal.CommandColor(cf.Name + " " + "update-buildpack")}))
    85  		} else {
    86  			return err
    87  		}
    88  		return nil
    89  	}
    90  	cmd.ui.Ok()
    91  	cmd.ui.Say("")
    92  
    93  	cmd.ui.Say(T("Uploading buildpack {{.BuildpackName}}...", map[string]interface{}{"BuildpackName": terminal.EntityNameColor(buildpackName)}))
    94  
    95  	err = cmd.buildpackBitsRepo.UploadBuildpack(buildpack, buildpackFile, buildpackFileName)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	cmd.ui.Ok()
   101  	return nil
   102  }
   103  
   104  func (cmd CreateBuildpack) createBuildpack(buildpackName string, c flags.FlagContext) (buildpack models.Buildpack, apiErr error) {
   105  	position, err := strconv.Atoi(c.Args()[2])
   106  	if err != nil {
   107  		apiErr = fmt.Errorf(T("Error {{.ErrorDescription}} is being passed in as the argument for 'Position' but 'Position' requires an integer.  For more syntax help, see `cf create-buildpack -h`.", map[string]interface{}{"ErrorDescription": c.Args()[2]}))
   108  		return
   109  	}
   110  
   111  	enabled := c.Bool("enable")
   112  	disabled := c.Bool("disable")
   113  	if enabled && disabled {
   114  		apiErr = errors.New(T("Cannot specify both {{.Enabled}} and {{.Disabled}}.", map[string]interface{}{
   115  			"Enabled":  "enabled",
   116  			"Disabled": "disabled",
   117  		}))
   118  		return
   119  	}
   120  
   121  	var enableOption *bool
   122  	if enabled {
   123  		enableOption = &enabled
   124  	}
   125  	if disabled {
   126  		disabled = false
   127  		enableOption = &disabled
   128  	}
   129  
   130  	buildpack, apiErr = cmd.buildpackRepo.Create(buildpackName, &position, enableOption, nil)
   131  
   132  	return
   133  }