-
Notifications
You must be signed in to change notification settings - Fork 187
/
create_conversion_graph.go
114 lines (94 loc) · 3.18 KB
/
create_conversion_graph.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
/*
* Copyright (c) Microsoft Corporation.
* Licensed under the MIT license.
*/
package pipeline
import (
"context"
"fmt"
"os"
"path/filepath"
"github.com/Azure/azure-service-operator/v2/internal/set"
"github.com/pkg/errors"
"github.com/Azure/azure-service-operator/v2/tools/generator/internal/astmodel"
"github.com/Azure/azure-service-operator/v2/tools/generator/internal/codegen/storage"
"github.com/Azure/azure-service-operator/v2/tools/generator/internal/config"
)
// CreateConversionGraphStageId is the unique identifier for this stage
const CreateConversionGraphStageId = "createConversionGraph"
// CreateConversionGraph walks the set of available types and creates a graph of conversions that will be used to
// convert resources to/from the designated storage (or hub) version
func CreateConversionGraph(
configuration *config.Configuration,
generatorPrefix string,
) *Stage {
stage := NewStage(
CreateConversionGraphStageId,
"Create the graph of conversions between versions of each resource group",
func(ctx context.Context, state *State) (*State, error) {
// Collect all distinct references
allNames := astmodel.NewInternalTypeNameSet()
for _, def := range state.Definitions() {
if def.Name().IsARMType() {
// ARM types don't participate in the conversion graph
continue
}
allNames.Add(def.Name())
}
builder := storage.NewConversionGraphBuilder(
configuration.ObjectModelConfiguration, generatorPrefix)
builder.AddAll(allNames)
graph, err := builder.Build()
if err != nil {
// Shouldn't have any non-local references, if we do, abort
return nil, errors.Wrapf(err, "creating conversion graph")
}
return state.WithConversionGraph(graph), nil
})
stage.AddDiagnostic(exportConversionGraph)
stage.RequiresPrerequisiteStages(CreateStorageTypesStageID)
return stage
}
func exportConversionGraph(settings *DebugSettings, index int, state *State) error {
graph := state.ConversionGraph()
if graph == nil {
return errors.New("no conversion graph available")
}
// Create our output folder
outputFolder := settings.CreateFileName(fmt.Sprintf("conversion-graph-%d", index))
err := os.Mkdir(outputFolder, 0o700)
if err != nil {
return errors.Wrapf(err, "creating output folder for conversion graph diagnostic")
}
done := set.Make[string]()
for name, def := range state.Definitions() {
if name.IsARMType() {
// ARM types don't participate in the conversion graph
continue
}
_, isResource := astmodel.AsResourceType(def.Type())
_, isObject := astmodel.AsObjectType(def.Type())
if !isResource && !isObject {
// Not a resource or object, so not a type we're interested in
continue
}
if !settings.MatchesGroup(name.InternalPackageReference()) {
// Not a group/version we're interested in
continue
}
grp := name.InternalPackageReference().Group()
name := name.Name()
key := fmt.Sprintf("%s-%s.gv", grp, name)
if done.Contains(key) {
// We've already exported this graph
continue
}
done.Add(key)
filename := filepath.Join(outputFolder, key)
err := graph.SaveTo(grp, name, filename)
if err != nil {
return errors.Wrapf(err, "writing conversion graph for %s", name)
}
}
return nil
}