Skip to content

Commit ddfdd9d

Browse files
committed
Don't parse roots if we're printing marker help
This avoids loading roots if we're just printing marker help, saving some time when `-w` is used.
1 parent 4278655 commit ddfdd9d

File tree

2 files changed

+76
-32
lines changed

2 files changed

+76
-32
lines changed

cmd/controller-gen/main.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -157,20 +157,22 @@ func main() {
157157
}
158158

159159
func runGenerators(c *cobra.Command, rawOptions []string, whichLevel int) error {
160-
rt, err := genall.FromOptions(optionsRegistry, rawOptions)
161-
if err != nil {
162-
return err
163-
}
164-
165160
if whichLevel > 0 {
166-
reg := &markers.Registry{}
167-
if err := rt.Generators.RegisterMarkers(reg); err != nil {
161+
// just grab a registry so we don't lag while trying to load roots
162+
// (like we'd do if we just constructed the full runtime).
163+
reg, err := genall.RegistryFromOptions(optionsRegistry, rawOptions)
164+
if err != nil {
168165
return err
169166
}
170167

171168
return helpForLevels(c.OutOrStdout(), c.OutOrStderr(), whichLevel, reg, help.SortByCategory)
172169
}
173170

171+
rt, err := genall.FromOptions(optionsRegistry, rawOptions)
172+
if err != nil {
173+
return err
174+
}
175+
174176
if hadErrs := rt.Run(); hadErrs {
175177
return fmt.Errorf("not all generators ran successfully")
176178
}

pkg/genall/options.go

Lines changed: 67 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,21 @@ func RegisterOptionsMarkers(into *markers.Registry) error {
4545
return nil
4646
}
4747

48+
// RegistryFromOptions produces just the marker registry that would be used by FromOptions, without
49+
// attempting to produce a full Runtime. This can be useful if you want to display help without
50+
// trying to load roots.
51+
func RegistryFromOptions(optionsRegistry *markers.Registry, options []string) (*markers.Registry, error) {
52+
protoRt, err := protoFromOptions(optionsRegistry, options)
53+
if err != nil {
54+
return nil, err
55+
}
56+
reg := &markers.Registry{}
57+
if err := protoRt.Generators.RegisterMarkers(reg); err != nil {
58+
return nil, err
59+
}
60+
return reg, nil
61+
}
62+
4863
// FromOptions parses the options from markers stored in the given registry out into a runtime.
4964
// The markers in the registry must be either
5065
//
@@ -57,6 +72,40 @@ func RegisterOptionsMarkers(into *markers.Registry) error {
5772
// further modified. Not default generators are used if none are specified -- you can check
5873
// the output and rerun for that.
5974
func FromOptions(optionsRegistry *markers.Registry, options []string) (*Runtime, error) {
75+
76+
protoRt, err := protoFromOptions(optionsRegistry, options)
77+
if err != nil {
78+
return nil, err
79+
}
80+
81+
// make the runtime
82+
genRuntime, err := protoRt.Generators.ForRoots(protoRt.Paths...)
83+
if err != nil {
84+
return nil, err
85+
}
86+
87+
// attempt to figure out what the user wants without a lot of verbose specificity:
88+
// if the user specifies a default rule, assume that they probably want to fall back
89+
// to that. Otherwise, assume that they just wanted to customize one option from the
90+
// set, and leave the rest in the standard configuration.
91+
if protoRt.OutputRules.Default != nil {
92+
genRuntime.OutputRules = protoRt.OutputRules
93+
return genRuntime, nil
94+
}
95+
96+
outRules := DirectoryPerGenerator("config", protoRt.GeneratorsByName)
97+
for gen, rule := range protoRt.OutputRules.ByGenerator {
98+
outRules.ByGenerator[gen] = rule
99+
}
100+
101+
genRuntime.OutputRules = outRules
102+
return genRuntime, nil
103+
}
104+
105+
// protoFromOptions returns a proto-Runtime from the given options registry and
106+
// options set. This can then be used to construct an actual Runtime. See the
107+
// FromOptions function for more details about how the options work.
108+
func protoFromOptions(optionsRegistry *markers.Registry, options []string) (protoRuntime, error) {
60109
var gens Generators
61110
rules := OutputRules{
62111
ByGenerator: make(map[Generator]OutputRule),
@@ -74,12 +123,12 @@ func FromOptions(optionsRegistry *markers.Registry, options []string) (*Runtime,
74123
}
75124
defn := optionsRegistry.Lookup(rawOpt, markers.DescribesPackage)
76125
if defn == nil {
77-
return nil, fmt.Errorf("unknown option %q", rawOpt[1:])
126+
return protoRuntime{}, fmt.Errorf("unknown option %q", rawOpt[1:])
78127
}
79128

80129
val, err := defn.Parse(rawOpt)
81130
if err != nil {
82-
return nil, fmt.Errorf("unable to parse option %q: %v", rawOpt[1:], err)
131+
return protoRuntime{}, fmt.Errorf("unable to parse option %q: %v", rawOpt[1:], err)
83132
}
84133

85134
switch val := val.(type) {
@@ -99,42 +148,35 @@ func FromOptions(optionsRegistry *markers.Registry, options []string) (*Runtime,
99148
case InputPaths:
100149
paths = append(paths, val...)
101150
default:
102-
return nil, fmt.Errorf("unknown option marker %q", defn.Name)
151+
return protoRuntime{}, fmt.Errorf("unknown option marker %q", defn.Name)
103152
}
104153
}
105154

106155
// actually associate the rules now that we know the generators
107156
for genName, outputRule := range outputByGen {
108157
gen, knownGen := gensByName[genName]
109158
if !knownGen {
110-
return nil, fmt.Errorf("non-invoked generator %q", genName)
159+
return protoRuntime{}, fmt.Errorf("non-invoked generator %q", genName)
111160
}
112161

113162
rules.ByGenerator[gen] = outputRule
114163
}
115164

116-
// make the runtime
117-
genRuntime, err := Generators(gens).ForRoots(paths...)
118-
if err != nil {
119-
return nil, err
120-
}
121-
122-
// attempt to figure out what the user wants without a lot of verbose specificity:
123-
// if the user specifies a default rule, assume that they probably want to fall back
124-
// to that. Otherwise, assume that they just wanted to customize one option from the
125-
// set, and leave the rest in the standard configuration.
126-
if rules.Default != nil {
127-
genRuntime.OutputRules = rules
128-
return genRuntime, nil
129-
}
130-
131-
outRules := DirectoryPerGenerator("config", gensByName)
132-
for gen, rule := range rules.ByGenerator {
133-
outRules.ByGenerator[gen] = rule
134-
}
165+
return protoRuntime{
166+
Paths: paths,
167+
Generators: Generators(gens),
168+
OutputRules: rules,
169+
GeneratorsByName: gensByName,
170+
}, nil
171+
}
135172

136-
genRuntime.OutputRules = outRules
137-
return genRuntime, nil
173+
// protoRuntime represents the raw pieces needed to compose a runtime, as
174+
// parsed from some options.
175+
type protoRuntime struct {
176+
Paths []string
177+
Generators Generators
178+
OutputRules OutputRules
179+
GeneratorsByName map[string]Generator
138180
}
139181

140182
// splitOutputRuleOption splits a marker name of "output:rule:gen" or "output:rule"

0 commit comments

Comments
 (0)