-
Notifications
You must be signed in to change notification settings - Fork 207
/
feed.go
125 lines (105 loc) · 2.45 KB
/
feed.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package feed
import (
"fmt"
"net/url"
"strings"
"time"
"get.porter.sh/porter/pkg/context"
"github.com/Masterminds/semver/v3"
)
type MixinFeed struct {
*context.Context
// Index of mixin files
Index map[string]map[string]*MixinFileset
// Mixins present in the feed
Mixins []string
// Updated timestamp according to the atom xml feed
Updated *time.Time
}
func NewMixinFeed(cxt *context.Context) *MixinFeed {
return &MixinFeed{
Index: make(map[string]map[string]*MixinFileset),
Context: cxt,
}
}
func (feed *MixinFeed) Search(mixin string, version string) *MixinFileset {
versions, ok := feed.Index[mixin]
if !ok {
return nil
}
fileset, ok := versions[version]
if ok {
return fileset
}
// Return the highest version of the requested mixin according to semver, ignoring pre-releases
if version == "latest" {
var latestVersion *semver.Version
for version := range versions {
v, err := semver.NewVersion(version)
if err != nil {
continue
}
if v.Prerelease() != "" {
continue
}
if latestVersion == nil || v.GreaterThan(latestVersion) {
latestVersion = v
}
}
if latestVersion != nil {
return versions[latestVersion.Original()]
}
}
return nil
}
type MixinFileset struct {
Mixin string
Version string
Files []*MixinFile
}
func (f *MixinFileset) FindDownloadURL(os string, arch string) *url.URL {
match := fmt.Sprintf("%s-%s-%s", f.Mixin, os, arch)
for _, file := range f.Files {
if strings.Contains(file.URL.Path, match) {
return file.URL
}
}
return nil
}
func (f *MixinFileset) Updated() string {
return toAtomTimestamp(f.GetLastUpdated())
}
func (f *MixinFileset) GetLastUpdated() time.Time {
var max time.Time
for _, f := range f.Files {
if f.Updated.After(max) {
max = f.Updated
}
}
return max
}
type MixinFile struct {
File string
URL *url.URL
Updated time.Time
}
// MixinEntries is used to sort the entries in a mixin feed by when they were last updated
type MixinEntries []*MixinFileset
func (e MixinEntries) Len() int {
return len(e)
}
func (e MixinEntries) Swap(i, j int) {
e[i], e[j] = e[j], e[i]
}
func (e MixinEntries) Less(i, j int) bool {
// Sort by LastUpdated, Mixin, Version
entryI := e[i]
entryJ := e[j]
if entryI.GetLastUpdated().Equal(entryJ.GetLastUpdated()) {
if entryI.Mixin == entryJ.Mixin {
return entryI.Version < entryJ.Version
}
return entryI.Mixin < entryJ.Mixin
}
return entryI.GetLastUpdated().Before(entryJ.GetLastUpdated())
}