/
source.go
119 lines (98 loc) · 2.73 KB
/
source.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
package data
import (
"github.com/sirupsen/logrus"
"os"
"path"
"path/filepath"
"regexp"
"strings"
)
type SourceCacheManager struct {
RootPath string
doOnceCache map[string]bool
}
func NewSourceCacheManager(root string) SourceCacheManager {
return SourceCacheManager{
RootPath: root,
}
}
func (manager *SourceCacheManager) GetCacheDir(id string) string {
cacheDir := path.Join(manager.RootPath, ".cache", id)
return cacheDir
}
func (manager *SourceCacheManager) DoOnce(cacheKey string, task func() error) error {
if manager.doOnceCache == nil {
manager.doOnceCache = make(map[string]bool)
}
if _, exists := manager.doOnceCache[cacheKey]; !exists {
manager.doOnceCache[cacheKey] = true
return task()
}
return nil
}
func cleanUrl(s string) string {
var re = regexp.MustCompile("[^A-Za-z0-9\\.]")
return re.ReplaceAllString(s, `_`)
}
type Source interface {
GetPath(manager *SourceCacheManager) (string, error)
ToString() string
}
type EnvSource struct {
Dir string
}
func (source *EnvSource) GetPath(manager *SourceCacheManager) (string, error) {
return filepath.Abs(source.Dir)
}
func (source *EnvSource) ToString() string {
return "[local dir] FLEKSZIBLE_PATH=" + source.Dir
}
type LocalSource struct {
Dir string
}
func (source *LocalSource) GetPath(manager *SourceCacheManager) (string, error) {
return filepath.Abs(source.Dir)
}
func (source *LocalSource) ToString() string {
return "[local dir] dir=" + source.Dir
}
func LocalSourcesFromEnv() []Source {
sources := make([]Source, 0)
if os.Getenv("FLEKSZIBLE_PATH") != "" {
for _, path := range strings.Split(os.Getenv("FLEKSZIBLE_PATH"), ",") {
sources = append(sources, &EnvSource{Dir: path})
}
}
return sources
}
type RemoteSource struct {
Url string
CacheDir string
}
func (source *RemoteSource) ToString() string {
return "[remote] url=" + source.Url
}
type Downloader interface {
Download(url string, destinationDir string, rootPath string) error
}
var DownloaderPlugin Downloader = NodeDownloader{}
type NodeDownloader struct {
}
func (NodeDownloader) Download(url string, destinationDir string, rootPath string) error {
logrus.Warn("Downloader component has not been registered. Downloading remote resources are disabled.")
return nil
}
func (source *RemoteSource) EnsureDownloaded(manager *SourceCacheManager) error {
destinationDir := manager.GetCacheDir(cleanUrl(source.Url))
task := func() error {
return DownloaderPlugin.Download(source.Url, destinationDir, manager.RootPath)
}
return manager.DoOnce(destinationDir, task)
}
func (source *RemoteSource) GetPath(manager *SourceCacheManager) (string, error) {
err := source.EnsureDownloaded(manager)
if err != nil {
return "", err
}
return manager.GetCacheDir(cleanUrl(source.Url)), nil
}