func (cmd *PluginInstall) Execute(c flags.FlagContext) { if !cmd.confirmWithUser( c, T("**Attention: Plugins are binaries written by potentially untrusted authors. Install and use plugins at your own risk.**\n\nDo you want to install the plugin {{.Plugin}}? (y or n)", map[string]interface{}{"Plugin": c.Args()[0]}), ) { cmd.ui.Failed(T("Plugin installation cancelled")) } fileDownloader := fileutils.NewDownloader(os.TempDir()) removeTmpFile := func() { err := fileDownloader.RemoveFile() if err != nil { cmd.ui.Say(T("Problem removing downloaded binary in temp directory: ") + err.Error()) } } defer removeTmpFile() deps := &plugin_installer.PluginInstallerContext{ Checksummer: cmd.checksum, GetPluginRepos: cmd.config.PluginRepos, FileDownloader: fileDownloader, PluginRepo: cmd.pluginRepo, RepoName: c.String("r"), Ui: cmd.ui, } installer := plugin_installer.NewPluginInstaller(deps) pluginSourceFilepath := installer.Install(c.Args()[0]) cmd.ui.Say(fmt.Sprintf(T("Installing plugin {{.PluginPath}}...", map[string]interface{}{"PluginPath": pluginSourceFilepath}))) _, pluginExecutableName := filepath.Split(pluginSourceFilepath) pluginDestinationFilepath := filepath.Join(cmd.pluginConfig.GetPluginPath(), pluginExecutableName) cmd.ensurePluginBinaryWithSameFileNameDoesNotAlreadyExist(pluginDestinationFilepath, pluginExecutableName) pluginMetadata := cmd.runBinaryAndObtainPluginMetadata(pluginSourceFilepath) cmd.ensurePluginIsSafeForInstallation(pluginMetadata, pluginDestinationFilepath, pluginSourceFilepath) cmd.installPlugin(pluginMetadata, pluginDestinationFilepath, pluginSourceFilepath) cmd.ui.Ok() cmd.ui.Say(fmt.Sprintf(T("Plugin {{.PluginName}} v{{.Version}} successfully installed.", map[string]interface{}{"PluginName": pluginMetadata.Name, "Version": fmt.Sprintf("%d.%d.%d", pluginMetadata.Version.Major, pluginMetadata.Version.Minor, pluginMetadata.Version.Build)}))) }
func (cmd *PluginInstall) Run(c *cli.Context) { downloader := fileutils.NewDownloader(os.TempDir()) removeTmpFile := func() { err := downloader.RemoveFile() if err != nil { cmd.ui.Say(T("Problem removing downloaded binary in temp directory: ") + err.Error()) } } defer removeTmpFile() pluginSourceFilepath := c.Args()[0] repoName := c.String("r") if repoName != "" { targetPluginName := strings.ToLower(c.Args()[0]) cmd.ui.Say(T("Looking up '{{.filePath}}' from repository '{{.repoName}}'", map[string]interface{}{"filePath": pluginSourceFilepath, "repoName": repoName})) repoModel, err := cmd.getRepoFromConfig(repoName) if err != nil { cmd.ui.Failed(err.Error() + "\n" + T("Tip: use 'add-plugin-repo' to register the repo")) } pluginList, repoAry := cmd.pluginRepo.GetPlugins([]models.PluginRepo{repoModel}) if len(repoAry) != 0 { cmd.ui.Failed(T("Error getting plugin metadata from repo: ") + repoAry[0]) } found := false sha1 := "" for _, plugin := range findRepoCaseInsensity(pluginList, repoName) { if strings.ToLower(plugin.Name) == targetPluginName { found = true pluginSourceFilepath, sha1 = cmd.downloadBinary(plugin, downloader) cmd.checksum.SetFilePath(pluginSourceFilepath) if !cmd.checksum.CheckSha1(sha1) { cmd.ui.Failed(T("Downloaded plugin binary's checksum does not match repo metadata")) } } } if !found { cmd.ui.Failed(pluginSourceFilepath + T(" is not available in repo '") + repoName + "'") } } else { if filepath.Dir(pluginSourceFilepath) == "." { pluginSourceFilepath = "./" + filepath.Clean(pluginSourceFilepath) } cmd.ui.Say("") if strings.HasPrefix(pluginSourceFilepath, "https://") || strings.HasPrefix(pluginSourceFilepath, "http://") || strings.HasPrefix(pluginSourceFilepath, "ftp://") || strings.HasPrefix(pluginSourceFilepath, "ftps://") { cmd.ui.Say(T("Attempting to download binary file from internet address...")) pluginSourceFilepath = cmd.tryDownloadPluginBinaryfromGivenPath(pluginSourceFilepath, downloader) } else if !cmd.ensureCandidatePluginBinaryExistsAtGivenPath(pluginSourceFilepath) { cmd.ui.Failed(T("File not found locally, make sure the file exists at given path ...")) } } cmd.ui.Say(fmt.Sprintf(T("Installing plugin {{.PluginPath}}...", map[string]interface{}{"PluginPath": pluginSourceFilepath}))) _, pluginExecutableName := filepath.Split(pluginSourceFilepath) pluginDestinationFilepath := filepath.Join(cmd.pluginConfig.GetPluginPath(), pluginExecutableName) cmd.ensurePluginBinaryWithSameFileNameDoesNotAlreadyExist(pluginDestinationFilepath, pluginExecutableName) pluginMetadata := cmd.runBinaryAndObtainPluginMetadata(pluginSourceFilepath) cmd.ensurePluginIsSafeForInstallation(pluginMetadata, pluginDestinationFilepath, pluginSourceFilepath) cmd.installPlugin(pluginMetadata, pluginDestinationFilepath, pluginSourceFilepath) cmd.ui.Ok() cmd.ui.Say(fmt.Sprintf(T("Plugin {{.PluginName}} v{{.Version}} successfully installed.", map[string]interface{}{"PluginName": pluginMetadata.Name, "Version": fmt.Sprintf("%d.%d.%d", pluginMetadata.Version.Major, pluginMetadata.Version.Minor, pluginMetadata.Version.Build)}))) }
. "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Downloader", func() { var ( downloader fileutils.Downloader tempDir string ) BeforeEach(func() { var err error tempDir, err = ioutil.TempDir("", "file-download-test") Expect(err).NotTo(HaveOccurred()) downloader = fileutils.NewDownloader(tempDir) }) AfterEach(func() { os.RemoveAll(tempDir) }) Describe("DownloadFile", func() { var server *ghttp.Server BeforeEach(func() { server = ghttp.NewServer() }) AfterEach(func() { server.Close()