78
vendor/helm.sh/helm/v3/pkg/releaseutil/filter.go
vendored
Normal file
78
vendor/helm.sh/helm/v3/pkg/releaseutil/filter.go
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright The Helm Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package releaseutil // import "helm.sh/helm/v3/pkg/releaseutil"
|
||||
|
||||
import rspb "helm.sh/helm/v3/pkg/release"
|
||||
|
||||
// FilterFunc returns true if the release object satisfies
|
||||
// the predicate of the underlying filter func.
|
||||
type FilterFunc func(*rspb.Release) bool
|
||||
|
||||
// Check applies the FilterFunc to the release object.
|
||||
func (fn FilterFunc) Check(rls *rspb.Release) bool {
|
||||
if rls == nil {
|
||||
return false
|
||||
}
|
||||
return fn(rls)
|
||||
}
|
||||
|
||||
// Filter applies the filter(s) to the list of provided releases
|
||||
// returning the list that satisfies the filtering predicate.
|
||||
func (fn FilterFunc) Filter(rels []*rspb.Release) (rets []*rspb.Release) {
|
||||
for _, rel := range rels {
|
||||
if fn.Check(rel) {
|
||||
rets = append(rets, rel)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Any returns a FilterFunc that filters a list of releases
|
||||
// determined by the predicate 'f0 || f1 || ... || fn'.
|
||||
func Any(filters ...FilterFunc) FilterFunc {
|
||||
return func(rls *rspb.Release) bool {
|
||||
for _, filter := range filters {
|
||||
if filter(rls) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// All returns a FilterFunc that filters a list of releases
|
||||
// determined by the predicate 'f0 && f1 && ... && fn'.
|
||||
func All(filters ...FilterFunc) FilterFunc {
|
||||
return func(rls *rspb.Release) bool {
|
||||
for _, filter := range filters {
|
||||
if !filter(rls) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// StatusFilter filters a set of releases by status code.
|
||||
func StatusFilter(status rspb.Status) FilterFunc {
|
||||
return FilterFunc(func(rls *rspb.Release) bool {
|
||||
if rls == nil {
|
||||
return true
|
||||
}
|
||||
return rls.Info.Status == status
|
||||
})
|
||||
}
|
||||
156
vendor/helm.sh/helm/v3/pkg/releaseutil/kind_sorter.go
vendored
Normal file
156
vendor/helm.sh/helm/v3/pkg/releaseutil/kind_sorter.go
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
Copyright The Helm Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package releaseutil
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"helm.sh/helm/v3/pkg/release"
|
||||
)
|
||||
|
||||
// KindSortOrder is an ordering of Kinds.
|
||||
type KindSortOrder []string
|
||||
|
||||
// InstallOrder is the order in which manifests should be installed (by Kind).
|
||||
//
|
||||
// Those occurring earlier in the list get installed before those occurring later in the list.
|
||||
var InstallOrder KindSortOrder = []string{
|
||||
"Namespace",
|
||||
"NetworkPolicy",
|
||||
"ResourceQuota",
|
||||
"LimitRange",
|
||||
"PodSecurityPolicy",
|
||||
"PodDisruptionBudget",
|
||||
"ServiceAccount",
|
||||
"Secret",
|
||||
"SecretList",
|
||||
"ConfigMap",
|
||||
"StorageClass",
|
||||
"PersistentVolume",
|
||||
"PersistentVolumeClaim",
|
||||
"CustomResourceDefinition",
|
||||
"ClusterRole",
|
||||
"ClusterRoleList",
|
||||
"ClusterRoleBinding",
|
||||
"ClusterRoleBindingList",
|
||||
"Role",
|
||||
"RoleList",
|
||||
"RoleBinding",
|
||||
"RoleBindingList",
|
||||
"Service",
|
||||
"DaemonSet",
|
||||
"Pod",
|
||||
"ReplicationController",
|
||||
"ReplicaSet",
|
||||
"Deployment",
|
||||
"HorizontalPodAutoscaler",
|
||||
"StatefulSet",
|
||||
"Job",
|
||||
"CronJob",
|
||||
"Ingress",
|
||||
"APIService",
|
||||
}
|
||||
|
||||
// UninstallOrder is the order in which manifests should be uninstalled (by Kind).
|
||||
//
|
||||
// Those occurring earlier in the list get uninstalled before those occurring later in the list.
|
||||
var UninstallOrder KindSortOrder = []string{
|
||||
"APIService",
|
||||
"Ingress",
|
||||
"Service",
|
||||
"CronJob",
|
||||
"Job",
|
||||
"StatefulSet",
|
||||
"HorizontalPodAutoscaler",
|
||||
"Deployment",
|
||||
"ReplicaSet",
|
||||
"ReplicationController",
|
||||
"Pod",
|
||||
"DaemonSet",
|
||||
"RoleBindingList",
|
||||
"RoleBinding",
|
||||
"RoleList",
|
||||
"Role",
|
||||
"ClusterRoleBindingList",
|
||||
"ClusterRoleBinding",
|
||||
"ClusterRoleList",
|
||||
"ClusterRole",
|
||||
"CustomResourceDefinition",
|
||||
"PersistentVolumeClaim",
|
||||
"PersistentVolume",
|
||||
"StorageClass",
|
||||
"ConfigMap",
|
||||
"SecretList",
|
||||
"Secret",
|
||||
"ServiceAccount",
|
||||
"PodDisruptionBudget",
|
||||
"PodSecurityPolicy",
|
||||
"LimitRange",
|
||||
"ResourceQuota",
|
||||
"NetworkPolicy",
|
||||
"Namespace",
|
||||
}
|
||||
|
||||
// sort manifests by kind.
|
||||
//
|
||||
// Results are sorted by 'ordering', keeping order of items with equal kind/priority
|
||||
func sortManifestsByKind(manifests []Manifest, ordering KindSortOrder) []Manifest {
|
||||
sort.SliceStable(manifests, func(i, j int) bool {
|
||||
return lessByKind(manifests[i], manifests[j], manifests[i].Head.Kind, manifests[j].Head.Kind, ordering)
|
||||
})
|
||||
|
||||
return manifests
|
||||
}
|
||||
|
||||
// sort hooks by kind, using an out-of-place sort to preserve the input parameters.
|
||||
//
|
||||
// Results are sorted by 'ordering', keeping order of items with equal kind/priority
|
||||
func sortHooksByKind(hooks []*release.Hook, ordering KindSortOrder) []*release.Hook {
|
||||
h := hooks
|
||||
sort.SliceStable(h, func(i, j int) bool {
|
||||
return lessByKind(h[i], h[j], h[i].Kind, h[j].Kind, ordering)
|
||||
})
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func lessByKind(a interface{}, b interface{}, kindA string, kindB string, o KindSortOrder) bool {
|
||||
ordering := make(map[string]int, len(o))
|
||||
for v, k := range o {
|
||||
ordering[k] = v
|
||||
}
|
||||
|
||||
first, aok := ordering[kindA]
|
||||
second, bok := ordering[kindB]
|
||||
|
||||
if !aok && !bok {
|
||||
// if both are unknown then sort alphabetically by kind, keep original order if same kind
|
||||
if kindA != kindB {
|
||||
return kindA < kindB
|
||||
}
|
||||
return first < second
|
||||
}
|
||||
// unknown kind is last
|
||||
if !aok {
|
||||
return false
|
||||
}
|
||||
if !bok {
|
||||
return true
|
||||
}
|
||||
// sort different kinds, keep original order if same priority
|
||||
return first < second
|
||||
}
|
||||
72
vendor/helm.sh/helm/v3/pkg/releaseutil/manifest.go
vendored
Normal file
72
vendor/helm.sh/helm/v3/pkg/releaseutil/manifest.go
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
Copyright The Helm Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package releaseutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SimpleHead defines what the structure of the head of a manifest file
|
||||
type SimpleHead struct {
|
||||
Version string `json:"apiVersion"`
|
||||
Kind string `json:"kind,omitempty"`
|
||||
Metadata *struct {
|
||||
Name string `json:"name"`
|
||||
Annotations map[string]string `json:"annotations"`
|
||||
} `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
var sep = regexp.MustCompile("(?:^|\\s*\n)---\\s*")
|
||||
|
||||
// SplitManifests takes a string of manifest and returns a map contains individual manifests
|
||||
func SplitManifests(bigFile string) map[string]string {
|
||||
// Basically, we're quickly splitting a stream of YAML documents into an
|
||||
// array of YAML docs. The file name is just a place holder, but should be
|
||||
// integer-sortable so that manifests get output in the same order as the
|
||||
// input (see `BySplitManifestsOrder`).
|
||||
tpl := "manifest-%d"
|
||||
res := map[string]string{}
|
||||
// Making sure that any extra whitespace in YAML stream doesn't interfere in splitting documents correctly.
|
||||
bigFileTmp := strings.TrimSpace(bigFile)
|
||||
docs := sep.Split(bigFileTmp, -1)
|
||||
var count int
|
||||
for _, d := range docs {
|
||||
if d == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
d = strings.TrimSpace(d)
|
||||
res[fmt.Sprintf(tpl, count)] = d
|
||||
count = count + 1
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// BySplitManifestsOrder sorts by in-file manifest order, as provided in function `SplitManifests`
|
||||
type BySplitManifestsOrder []string
|
||||
|
||||
func (a BySplitManifestsOrder) Len() int { return len(a) }
|
||||
func (a BySplitManifestsOrder) Less(i, j int) bool {
|
||||
// Split `manifest-%d`
|
||||
anum, _ := strconv.ParseInt(a[i][len("manifest-"):], 10, 0)
|
||||
bnum, _ := strconv.ParseInt(a[j][len("manifest-"):], 10, 0)
|
||||
return anum < bnum
|
||||
}
|
||||
func (a BySplitManifestsOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
233
vendor/helm.sh/helm/v3/pkg/releaseutil/manifest_sorter.go
vendored
Normal file
233
vendor/helm.sh/helm/v3/pkg/releaseutil/manifest_sorter.go
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
Copyright The Helm Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package releaseutil
|
||||
|
||||
import (
|
||||
"log"
|
||||
"path"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"helm.sh/helm/v3/pkg/chartutil"
|
||||
"helm.sh/helm/v3/pkg/release"
|
||||
)
|
||||
|
||||
// Manifest represents a manifest file, which has a name and some content.
|
||||
type Manifest struct {
|
||||
Name string
|
||||
Content string
|
||||
Head *SimpleHead
|
||||
}
|
||||
|
||||
// manifestFile represents a file that contains a manifest.
|
||||
type manifestFile struct {
|
||||
entries map[string]string
|
||||
path string
|
||||
apis chartutil.VersionSet
|
||||
}
|
||||
|
||||
// result is an intermediate structure used during sorting.
|
||||
type result struct {
|
||||
hooks []*release.Hook
|
||||
generic []Manifest
|
||||
}
|
||||
|
||||
// TODO: Refactor this out. It's here because naming conventions were not followed through.
|
||||
// So fix the Test hook names and then remove this.
|
||||
var events = map[string]release.HookEvent{
|
||||
release.HookPreInstall.String(): release.HookPreInstall,
|
||||
release.HookPostInstall.String(): release.HookPostInstall,
|
||||
release.HookPreDelete.String(): release.HookPreDelete,
|
||||
release.HookPostDelete.String(): release.HookPostDelete,
|
||||
release.HookPreUpgrade.String(): release.HookPreUpgrade,
|
||||
release.HookPostUpgrade.String(): release.HookPostUpgrade,
|
||||
release.HookPreRollback.String(): release.HookPreRollback,
|
||||
release.HookPostRollback.String(): release.HookPostRollback,
|
||||
release.HookTest.String(): release.HookTest,
|
||||
// Support test-success for backward compatibility with Helm 2 tests
|
||||
"test-success": release.HookTest,
|
||||
}
|
||||
|
||||
// SortManifests takes a map of filename/YAML contents, splits the file
|
||||
// by manifest entries, and sorts the entries into hook types.
|
||||
//
|
||||
// The resulting hooks struct will be populated with all of the generated hooks.
|
||||
// Any file that does not declare one of the hook types will be placed in the
|
||||
// 'generic' bucket.
|
||||
//
|
||||
// Files that do not parse into the expected format are simply placed into a map and
|
||||
// returned.
|
||||
func SortManifests(files map[string]string, apis chartutil.VersionSet, ordering KindSortOrder) ([]*release.Hook, []Manifest, error) {
|
||||
result := &result{}
|
||||
|
||||
var sortedFilePaths []string
|
||||
for filePath := range files {
|
||||
sortedFilePaths = append(sortedFilePaths, filePath)
|
||||
}
|
||||
sort.Strings(sortedFilePaths)
|
||||
|
||||
for _, filePath := range sortedFilePaths {
|
||||
content := files[filePath]
|
||||
|
||||
// Skip partials. We could return these as a separate map, but there doesn't
|
||||
// seem to be any need for that at this time.
|
||||
if strings.HasPrefix(path.Base(filePath), "_") {
|
||||
continue
|
||||
}
|
||||
// Skip empty files and log this.
|
||||
if strings.TrimSpace(content) == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
manifestFile := &manifestFile{
|
||||
entries: SplitManifests(content),
|
||||
path: filePath,
|
||||
apis: apis,
|
||||
}
|
||||
|
||||
if err := manifestFile.sort(result); err != nil {
|
||||
return result.hooks, result.generic, err
|
||||
}
|
||||
}
|
||||
|
||||
return sortHooksByKind(result.hooks, ordering), sortManifestsByKind(result.generic, ordering), nil
|
||||
}
|
||||
|
||||
// sort takes a manifestFile object which may contain multiple resource definition
|
||||
// entries and sorts each entry by hook types, and saves the resulting hooks and
|
||||
// generic manifests (or non-hooks) to the result struct.
|
||||
//
|
||||
// To determine hook type, it looks for a YAML structure like this:
|
||||
//
|
||||
// kind: SomeKind
|
||||
// apiVersion: v1
|
||||
// metadata:
|
||||
// annotations:
|
||||
// helm.sh/hook: pre-install
|
||||
//
|
||||
// To determine the policy to delete the hook, it looks for a YAML structure like this:
|
||||
//
|
||||
// kind: SomeKind
|
||||
// apiVersion: v1
|
||||
// metadata:
|
||||
// annotations:
|
||||
// helm.sh/hook-delete-policy: hook-succeeded
|
||||
func (file *manifestFile) sort(result *result) error {
|
||||
// Go through manifests in order found in file (function `SplitManifests` creates integer-sortable keys)
|
||||
var sortedEntryKeys []string
|
||||
for entryKey := range file.entries {
|
||||
sortedEntryKeys = append(sortedEntryKeys, entryKey)
|
||||
}
|
||||
sort.Sort(BySplitManifestsOrder(sortedEntryKeys))
|
||||
|
||||
for _, entryKey := range sortedEntryKeys {
|
||||
m := file.entries[entryKey]
|
||||
|
||||
var entry SimpleHead
|
||||
if err := yaml.Unmarshal([]byte(m), &entry); err != nil {
|
||||
return errors.Wrapf(err, "YAML parse error on %s", file.path)
|
||||
}
|
||||
|
||||
if !hasAnyAnnotation(entry) {
|
||||
result.generic = append(result.generic, Manifest{
|
||||
Name: file.path,
|
||||
Content: m,
|
||||
Head: &entry,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
hookTypes, ok := entry.Metadata.Annotations[release.HookAnnotation]
|
||||
if !ok {
|
||||
result.generic = append(result.generic, Manifest{
|
||||
Name: file.path,
|
||||
Content: m,
|
||||
Head: &entry,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
hw := calculateHookWeight(entry)
|
||||
|
||||
h := &release.Hook{
|
||||
Name: entry.Metadata.Name,
|
||||
Kind: entry.Kind,
|
||||
Path: file.path,
|
||||
Manifest: m,
|
||||
Events: []release.HookEvent{},
|
||||
Weight: hw,
|
||||
DeletePolicies: []release.HookDeletePolicy{},
|
||||
}
|
||||
|
||||
isUnknownHook := false
|
||||
for _, hookType := range strings.Split(hookTypes, ",") {
|
||||
hookType = strings.ToLower(strings.TrimSpace(hookType))
|
||||
e, ok := events[hookType]
|
||||
if !ok {
|
||||
isUnknownHook = true
|
||||
break
|
||||
}
|
||||
h.Events = append(h.Events, e)
|
||||
}
|
||||
|
||||
if isUnknownHook {
|
||||
log.Printf("info: skipping unknown hook: %q", hookTypes)
|
||||
continue
|
||||
}
|
||||
|
||||
result.hooks = append(result.hooks, h)
|
||||
|
||||
operateAnnotationValues(entry, release.HookDeleteAnnotation, func(value string) {
|
||||
h.DeletePolicies = append(h.DeletePolicies, release.HookDeletePolicy(value))
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// hasAnyAnnotation returns true if the given entry has any annotations at all.
|
||||
func hasAnyAnnotation(entry SimpleHead) bool {
|
||||
return entry.Metadata != nil &&
|
||||
entry.Metadata.Annotations != nil &&
|
||||
len(entry.Metadata.Annotations) != 0
|
||||
}
|
||||
|
||||
// calculateHookWeight finds the weight in the hook weight annotation.
|
||||
//
|
||||
// If no weight is found, the assigned weight is 0
|
||||
func calculateHookWeight(entry SimpleHead) int {
|
||||
hws := entry.Metadata.Annotations[release.HookWeightAnnotation]
|
||||
hw, err := strconv.Atoi(hws)
|
||||
if err != nil {
|
||||
hw = 0
|
||||
}
|
||||
return hw
|
||||
}
|
||||
|
||||
// operateAnnotationValues finds the given annotation and runs the operate function with the value of that annotation
|
||||
func operateAnnotationValues(entry SimpleHead, annotation string, operate func(p string)) {
|
||||
if dps, ok := entry.Metadata.Annotations[annotation]; ok {
|
||||
for _, dp := range strings.Split(dps, ",") {
|
||||
dp = strings.ToLower(strings.TrimSpace(dp))
|
||||
operate(dp)
|
||||
}
|
||||
}
|
||||
}
|
||||
78
vendor/helm.sh/helm/v3/pkg/releaseutil/sorter.go
vendored
Normal file
78
vendor/helm.sh/helm/v3/pkg/releaseutil/sorter.go
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright The Helm Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package releaseutil // import "helm.sh/helm/v3/pkg/releaseutil"
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
rspb "helm.sh/helm/v3/pkg/release"
|
||||
)
|
||||
|
||||
type list []*rspb.Release
|
||||
|
||||
func (s list) Len() int { return len(s) }
|
||||
func (s list) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
|
||||
// ByName sorts releases by name
|
||||
type ByName struct{ list }
|
||||
|
||||
// Less compares to releases
|
||||
func (s ByName) Less(i, j int) bool { return s.list[i].Name < s.list[j].Name }
|
||||
|
||||
// ByDate sorts releases by date
|
||||
type ByDate struct{ list }
|
||||
|
||||
// Less compares to releases
|
||||
func (s ByDate) Less(i, j int) bool {
|
||||
ti := s.list[i].Info.LastDeployed.Unix()
|
||||
tj := s.list[j].Info.LastDeployed.Unix()
|
||||
return ti < tj
|
||||
}
|
||||
|
||||
// ByRevision sorts releases by revision number
|
||||
type ByRevision struct{ list }
|
||||
|
||||
// Less compares to releases
|
||||
func (s ByRevision) Less(i, j int) bool {
|
||||
return s.list[i].Version < s.list[j].Version
|
||||
}
|
||||
|
||||
// Reverse reverses the list of releases sorted by the sort func.
|
||||
func Reverse(list []*rspb.Release, sortFn func([]*rspb.Release)) {
|
||||
sortFn(list)
|
||||
for i, j := 0, len(list)-1; i < j; i, j = i+1, j-1 {
|
||||
list[i], list[j] = list[j], list[i]
|
||||
}
|
||||
}
|
||||
|
||||
// SortByName returns the list of releases sorted
|
||||
// in lexicographical order.
|
||||
func SortByName(list []*rspb.Release) {
|
||||
sort.Sort(ByName{list})
|
||||
}
|
||||
|
||||
// SortByDate returns the list of releases sorted by a
|
||||
// release's last deployed time (in seconds).
|
||||
func SortByDate(list []*rspb.Release) {
|
||||
sort.Sort(ByDate{list})
|
||||
}
|
||||
|
||||
// SortByRevision returns the list of releases sorted by a
|
||||
// release's revision number (release.Version).
|
||||
func SortByRevision(list []*rspb.Release) {
|
||||
sort.Sort(ByRevision{list})
|
||||
}
|
||||
Reference in New Issue
Block a user