pluginApi.go 4.7 KB
Newer Older
1 2 3
package client

import (
yJunS's avatar
yJunS 已提交
4
	"crypto/tls"
5 6 7 8 9
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
yJunS's avatar
yJunS 已提交
10
	"strings"
11 12
)

LinuxSuRen's avatar
LinuxSuRen 已提交
13
// PluginAPI represetns a plugin API
14 15 16 17
type PluginAPI struct {
	dependencyMap map[string]string
}

LinuxSuRen's avatar
LinuxSuRen 已提交
18
// PluginDependency represents a plugin dependency
19 20 21 22 23 24 25 26
type PluginDependency struct {
	Name     string `json:"name"`
	Implied  bool   `json:"implied"`
	Optional bool   `json:"optional"`
	Title    string `json:"title"`
	Version  string `json:"version"`
}

LinuxSuRen's avatar
LinuxSuRen 已提交
27
// PluginInfo hold the info of a plugin
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
type PluginInfo struct {
	BuildDate         string             `json:"buildDate"`
	Dependencies      []PluginDependency `json:"dependencies"`
	Excerpt           string             `json:"excerpt"`
	FirstRelease      string             `json:"firstRelease"`
	Gav               string             `json:"gav"`
	Name              string             `json:"name"`
	PreviousTimestamp string             `json:"previousTimestamp"`
	PreviousVersion   string             `json:"previousVersion"`
	ReleaseTimestamp  string             `json:"releaseTimestamp"`
	RequireCore       string             `json:"RequireCore"`
	Title             string             `json:"title"`
	URL               string             `json:"url"`
	Version           string             `json:"version"`

	Stats PluginInfoStats
}

LinuxSuRen's avatar
LinuxSuRen 已提交
46
// PluginInfoStats is the plugin info stats
47 48 49 50 51 52 53 54 55
type PluginInfoStats struct {
	CurrentInstalls                   int
	Installations                     []PluginInstallationInfo
	InstallationsPerVersion           []PluginInstallationInfo
	InstallationsPercentage           []PluginInstallationInfo
	InstallationsPercentagePerVersion []PluginInstallationInfo
	Trend                             int
}

LinuxSuRen's avatar
LinuxSuRen 已提交
56
// PluginInstallationInfo represents the plugin installation info
57 58 59 60 61 62 63
type PluginInstallationInfo struct {
	Timestamp  int64
	Total      int
	Version    string
	Percentage float64
}

LinuxSuRen's avatar
LinuxSuRen 已提交
64 65 66
// ShowTrend show the trend of plugins
func (d *PluginAPI) ShowTrend(name string) {
	if plugin, err := d.getPlugin(name); err == nil {
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
		data := []float64{}
		installations := plugin.Stats.Installations
		offset, count := 0, 10
		if len(installations) > count {
			offset = len(installations) - count
		}
		for _, installation := range installations[offset:] {
			data = append(data, float64(installation.Total))
		}

		min, max := 0.0, 0.0
		for _, item := range data {
			if item < min {
				min = item
			} else if item > max {
				max = item
			}
		}

		unit := (max - min) / 100
		for _, num := range data {
			total := (int)(num / unit)
			if total == 0 {
				total = 1
			}
			arr := make([]int, total)
LinuxSuRen's avatar
LinuxSuRen 已提交
93
			for range arr {
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
				fmt.Print("*")
			}
			fmt.Println("", num)
		}
	} else {
		log.Fatal(err)
	}
}

// DownloadPlugins will download those plugins from update center
func (d *PluginAPI) DownloadPlugins(names []string) {
	d.dependencyMap = make(map[string]string)
	fmt.Println("Start to collect plugin dependencies...")
	plugins := make([]PluginInfo, 0)
	for _, name := range names {
yJunS's avatar
yJunS 已提交
109
		plugins = append(plugins, d.collectDependencies(strings.ToLower(name))...)
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
	}

	fmt.Printf("Ready to download plugins, total: %d.\n", len(plugins))
	for i, plugin := range plugins {
		fmt.Printf("Start to download plugin %s, version: %s, number: %d\n",
			plugin.Name, plugin.Version, i)

		d.download(plugin.URL, plugin.Name)
	}
}

func (d *PluginAPI) download(url string, name string) {
	if resp, err := http.Get(url); err != nil {
		fmt.Println(err)
	} else {
		defer resp.Body.Close()
		if body, err := ioutil.ReadAll(resp.Body); err != nil {
			fmt.Println(err)
		} else {
			if err = ioutil.WriteFile(fmt.Sprintf("%s.hpi", name), body, 0644); err != nil {
				fmt.Println(err)
			}
		}
	}
}

func (d *PluginAPI) getPlugin(name string) (plugin *PluginInfo, err error) {
yJunS's avatar
yJunS 已提交
137 138 139 140 141 142 143
	var cli = http.Client{}
	cli.Transport = &http.Transport{
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	}
	resp, err := cli.Get("https://plugins.jenkins.io/api/plugin/" + name)
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
	if err != nil {
		return plugin, err
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)

	plugin = &PluginInfo{}
	err = json.Unmarshal(body, plugin)
	if err != nil {
		log.Println("error when unmarshal:", string(body))
	}
	return
}

func (d *PluginAPI) collectDependencies(pluginName string) (plugins []PluginInfo) {
	plugin, err := d.getPlugin(pluginName)
	if err != nil {
		log.Println("can't get the plugin by name:", pluginName)
		panic(err)
	}

	plugins = make([]PluginInfo, 0)
	plugins = append(plugins, *plugin)

	for _, dependency := range plugin.Dependencies {
		if dependency.Optional {
			continue
		}
		if _, ok := d.dependencyMap[dependency.Name]; !ok {
			d.dependencyMap[dependency.Name] = dependency.Version

			plugins = append(plugins, d.collectDependencies(dependency.Name)...)
		}
	}
	return
}