-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathcatalog.go
More file actions
79 lines (68 loc) · 1.99 KB
/
Copy pathcatalog.go
File metadata and controls
79 lines (68 loc) · 1.99 KB
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
package catalog
//go:generate go run ../../scripts/generate_catalog_types v2.0.0
import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"github.com/arm/topo/internal/fetch"
)
type Project = ProjectElement
var (
majorCatalogVersion = majorVersion(CatalogSchemaVersion)
defaultURL = "https://artifacts.tools.arm.com/devx-topo-project-catalog/" + majorCatalogVersion + "/catalog/"
DefaultCatalogURL = defaultURL + "catalog.json"
)
func majorVersion(version string) string {
major, _, _ := strings.Cut(version, ".")
return major
}
func ListProjectsFromURL(ctx context.Context, url string) ([]Project, error) {
data, err := fetchProjectsJSON(ctx, url)
if err != nil {
return nil, fmt.Errorf("failed to fetch projects: %w", err)
}
return parseProjects(data)
}
func parseProjects(b []byte) ([]Project, error) {
catalogVersion, versionErr := unmarshalCatalogVersion(b)
schemaVersionMajor := majorVersion(CatalogSchemaVersion)
if majorVersion(catalogVersion) != schemaVersionMajor {
return nil, fmt.Errorf(
"failed to parse catalog: requested catalog version %q is incompatible with supported schema version %q: %w",
catalogVersion,
CatalogSchemaVersion,
versionErr,
)
}
catalog, err := UnmarshalCatalogDocument(b)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal catalog: %w", err)
}
return catalog.Projects, nil
}
func unmarshalCatalogVersion(b []byte) (string, error) {
var header struct {
Version string `json:"version"`
}
if err := json.Unmarshal(b, &header); err != nil {
return "", err
}
return header.Version, nil
}
func fetchProjectsJSON(ctx context.Context, url string) ([]byte, error) {
const filePrefix = "file://"
if path, found := strings.CutPrefix(url, filePrefix); found {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read projects: %w", err)
}
return data, nil
}
data, err := fetch.Get(ctx, url)
if err != nil {
return nil, fmt.Errorf("failed to fetch project: %w", err)
}
return data, nil
}