tooling/templatize/cmd/generate/options.go (95 lines of code) (raw):

// Copyright 2025 Microsoft Corporation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package generate import ( "fmt" "io" "io/fs" "os" "path/filepath" "github.com/spf13/cobra" "github.com/Azure/ARO-Tools/pkg/config" options "github.com/Azure/ARO-HCP/tooling/templatize/cmd" ) func DefaultGenerationOptions() *RawGenerationOptions { return &RawGenerationOptions{ RolloutOptions: options.DefaultRolloutOptions(), } } func BindGenerationOptions(opts *RawGenerationOptions, cmd *cobra.Command) error { err := options.BindRolloutOptions(opts.RolloutOptions, cmd) if err != nil { return fmt.Errorf("failed to bind raw options: %w", err) } cmd.Flags().StringVar(&opts.Input, "input", opts.Input, "input file path") cmd.Flags().StringVar(&opts.Output, "output", opts.Output, "output file path") for _, flag := range []string{"config-file", "input", "output"} { if err := cmd.MarkFlagFilename(flag); err != nil { return fmt.Errorf("failed to mark flag %q as a file: %w", flag, err) } } return nil } // RawGenerationOptions holds input values. type RawGenerationOptions struct { RolloutOptions *options.RawRolloutOptions Input string Output string } // validatedGenerationOptions is a private wrapper that enforces a call of Validate() before Complete() can be invoked. type validatedGenerationOptions struct { *RawGenerationOptions *options.ValidatedRolloutOptions } type ValidatedGenerationOptions struct { // Embed a private pointer that cannot be instantiated outside of this package. *validatedGenerationOptions } // completedGenerationOptions is a private wrapper that enforces a call of Complete() before config generation can be invoked. type completedGenerationOptions struct { *options.RolloutOptions InputFS fs.FS InputFile string OutputFile io.Writer } type GenerationOptions struct { // Embed a private pointer that cannot be instantiated outside of this package. *completedGenerationOptions } func (o *RawGenerationOptions) Validate() (*ValidatedGenerationOptions, error) { validatedRolloutOptions, err := o.RolloutOptions.Validate() if err != nil { return nil, fmt.Errorf("validation failed for raw options: %w", err) } if _, err := os.Stat(o.Input); os.IsNotExist(err) { return nil, fmt.Errorf("input file %s does not exist", o.Input) } return &ValidatedGenerationOptions{ validatedGenerationOptions: &validatedGenerationOptions{ RawGenerationOptions: o, ValidatedRolloutOptions: validatedRolloutOptions, }, }, nil } func (o *ValidatedGenerationOptions) Complete() (*GenerationOptions, error) { completed, err := o.ValidatedRolloutOptions.Complete() if err != nil { return nil, err } inputFile := filepath.Base(o.Input) if err := os.MkdirAll(filepath.Dir(o.Output), os.ModePerm); err != nil { return nil, fmt.Errorf("failed to create output directory %s: %w", o.Output, err) } outputFile, err := os.Create(o.Output) if err != nil { return nil, fmt.Errorf("failed to create output file %s: %w", o.Input, err) } return &GenerationOptions{ completedGenerationOptions: &completedGenerationOptions{ RolloutOptions: completed, InputFS: os.DirFS(filepath.Dir(o.Input)), InputFile: inputFile, OutputFile: outputFile, }, }, nil } func (opts *GenerationOptions) ExecuteTemplate() error { content, err := fs.ReadFile(opts.InputFS, opts.InputFile) if err != nil { return err } return config.PreprocessContentIntoWriter(content, opts.Config, opts.OutputFile) }