Skip to content

Commit be9dafc

Browse files
sh0rezDuologic
authored andcommitted
feat(api): Loader.List
Introduces `Loader.List(path, opts)` which returns all environments that could possibly be found at path. This can be used to prompt the user for the correct inline environment, while the actual Load does not need to be concerned with this
1 parent c15952a commit be9dafc

File tree

3 files changed

+91
-23
lines changed

3 files changed

+91
-23
lines changed

pkg/tanka/inline.go

+64-21
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,7 @@ import (
1818
type InlineLoader struct{}
1919

2020
func (i *InlineLoader) Load(path string, opts JsonnetOpts) (*v1alpha1.Environment, error) {
21-
raw, err := EvalJsonnet(path, opts)
22-
if err != nil {
23-
return nil, err
24-
}
25-
26-
var data interface{}
27-
if err := json.Unmarshal([]byte(raw), &data); err != nil {
28-
return nil, err
29-
}
30-
31-
envs, err := extractEnvs(data)
21+
envs, err := inlineEval(path, opts)
3222
if err != nil {
3323
return nil, err
3424
}
@@ -45,38 +35,91 @@ func (i *InlineLoader) Load(path string, opts JsonnetOpts) (*v1alpha1.Environmen
4535
return nil, fmt.Errorf("Found no environments in '%s'", path)
4636
}
4737

48-
root, err := jpath.FindRoot(path)
38+
// TODO: Re-serializing the entire env here. This is horribly inefficient
39+
envData, err := json.Marshal(envs[0])
4940
if err != nil {
5041
return nil, err
5142
}
5243

53-
file, err := jpath.Entrypoint(path)
44+
env, err := inlineParse(path, envData)
5445
if err != nil {
5546
return nil, err
5647
}
5748

58-
namespace, err := filepath.Rel(root, file)
49+
return env, nil
50+
}
51+
52+
func (i *InlineLoader) Peek(path string, opts JsonnetOpts) (*v1alpha1.Environment, error) {
53+
opts.EvalScript = EnvsOnlyEvalScript
54+
return i.Load(path, opts)
55+
}
56+
57+
func (i *InlineLoader) List(path string, opts JsonnetOpts) ([]*v1alpha1.Environment, error) {
58+
opts.EvalScript = EnvsOnlyEvalScript
59+
list, err := inlineEval(path, opts)
5960
if err != nil {
6061
return nil, err
6162
}
6263

63-
// TODO: Re-serializing the entire env here. This is horribly inefficient
64-
envData, err := json.Marshal(envs[0])
64+
envs := make([]*v1alpha1.Environment, 0, len(list))
65+
for _, raw := range list {
66+
data, err := json.Marshal(raw)
67+
if err != nil {
68+
return nil, err
69+
}
70+
71+
env, err := inlineParse(path, data)
72+
if err != nil {
73+
return nil, err
74+
}
75+
76+
envs = append(envs, env)
77+
}
78+
79+
return envs, nil
80+
}
81+
82+
func inlineEval(path string, opts JsonnetOpts) (manifest.List, error) {
83+
raw, err := EvalJsonnet(path, opts)
6584
if err != nil {
6685
return nil, err
6786
}
6887

69-
env, err := spec.Parse(envData, namespace)
88+
var data interface{}
89+
if err := json.Unmarshal([]byte(raw), &data); err != nil {
90+
return nil, err
91+
}
92+
93+
envs, err := extractEnvs(data)
7094
if err != nil {
7195
return nil, err
7296
}
7397

74-
return env, nil
98+
return envs, nil
7599
}
76100

77-
func (i *InlineLoader) Peek(path string, opts JsonnetOpts) (*v1alpha1.Environment, error) {
78-
opts.EvalScript = EnvsOnlyEvalScript
79-
return i.Load(path, opts)
101+
func inlineParse(path string, data []byte) (*v1alpha1.Environment, error) {
102+
root, err := jpath.FindRoot(path)
103+
if err != nil {
104+
return nil, err
105+
}
106+
107+
file, err := jpath.Entrypoint(path)
108+
if err != nil {
109+
return nil, err
110+
}
111+
112+
namespace, err := filepath.Rel(root, file)
113+
if err != nil {
114+
return nil, err
115+
}
116+
117+
env, err := spec.Parse(data, namespace)
118+
if err != nil {
119+
return nil, err
120+
}
121+
122+
return env, nil
80123
}
81124

82125
// extractEnvs filters out any Environment manifests

pkg/tanka/load.go

+17-1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ func Peek(path string, opts JsonnetOpts) (*v1alpha1.Environment, error) {
6868
return loader.Peek(path, opts)
6969
}
7070

71+
// List finds metadata of all environments at path that could possibly be
72+
// loaded. List can be used to deal with multiple inline environments, by first
73+
// listing them, choosing the right one and then only loading that one
74+
func List(path string, opts JsonnetOpts) ([]*v1alpha1.Environment, error) {
75+
loader, err := DetectLoader(path)
76+
if err != nil {
77+
return nil, err
78+
}
79+
80+
return loader.List(path, opts)
81+
}
82+
7183
// DetectLoader detects whether the environment is inline or static and picks
7284
// the approriate loader
7385
func DetectLoader(path string) (Loader, error) {
@@ -89,11 +101,15 @@ func DetectLoader(path string) (Loader, error) {
89101

90102
// Loader is an abstraction over the process of loading Environments
91103
type Loader interface {
92-
// Load the environment with path
104+
// Load a single environment at path
93105
Load(path string, opts JsonnetOpts) (*v1alpha1.Environment, error)
94106

95107
// Peek only loads metadata and omits the actual resources
96108
Peek(path string, opts JsonnetOpts) (*v1alpha1.Environment, error)
109+
110+
// List returns metadata of all possible environments at path that can be
111+
// loaded
112+
List(path string, opts JsonnetOpts) ([]*v1alpha1.Environment, error)
97113
}
98114

99115
type LoadResult struct {

pkg/tanka/static.go

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
type StaticLoader struct{}
1414

1515
func (s StaticLoader) Load(path string, opts JsonnetOpts) (*v1alpha1.Environment, error) {
16-
config, err := Peek(path, opts)
16+
config, err := s.Peek(path, opts)
1717
if err != nil {
1818
return nil, err
1919
}
@@ -39,6 +39,15 @@ func (s StaticLoader) Peek(path string, opts JsonnetOpts) (*v1alpha1.Environment
3939
return config, nil
4040
}
4141

42+
func (s StaticLoader) List(path string, opts JsonnetOpts) ([]*v1alpha1.Environment, error) {
43+
env, err := s.Peek(path, opts)
44+
if err != nil {
45+
return nil, err
46+
}
47+
48+
return []*v1alpha1.Environment{env}, nil
49+
}
50+
4251
// parseStaticSpec parses the `spec.json` of the environment and returns a
4352
// *kubernetes.Kubernetes from it
4453
func parseStaticSpec(path string) (*v1alpha1.Environment, error) {

0 commit comments

Comments
 (0)