-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement half of the CLI #8
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,34 +24,30 @@ var ( | |
disallowAdditionalProperties bool | ||
overwrite bool | ||
allowEmpty bool | ||
requireAll bool | ||
outputStdOut bool | ||
output string | ||
input string | ||
|
||
errReturned error | ||
) | ||
|
||
// rootCmd is the base command for terraschema | ||
var rootCmd = &cobra.Command{ | ||
Use: "terraschema", | ||
Short: "Generate JSON schema from HCL Variable Blocks in a Terraform/OpenTofu module", | ||
Long: `TODO: Long description`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
path, err := filepath.Abs(input) // absolute path | ||
if err != nil { | ||
fmt.Printf("could not get absolute path: %v\n", err) | ||
os.Exit(1) | ||
} | ||
output, err := jsonschema.CreateSchema(path, false) | ||
if err != nil { | ||
fmt.Printf("error creating schema: %v\n", err) | ||
os.Exit(1) | ||
} | ||
jsonOutput, err := json.MarshalIndent(output, "", " ") | ||
if err != nil { | ||
fmt.Printf("error marshalling schema: %v\n", err) | ||
Use: "terraschema", | ||
Example: "terraschema -i /path/to/module -o /path/to/schema.json", | ||
Short: "Generate JSON schema from HCL Variable Blocks in a Terraform/OpenTofu module", | ||
Long: "TerraSchema is a CLI tool which scans Terraform configuration ('.tf') " + | ||
"files, parses a list of variables along with their type and validation rules, and converts " + | ||
"them to a schema which complies with JSON Schema Draft-07.\nThe default behaviour is to scan " + | ||
"the current directory and output a schema file called 'schema.json' in the same location. " + | ||
"\nFor more information see https://github.com/HewlettPackard/terraschema.", | ||
Run: runCommand, | ||
PostRun: func(cmd *cobra.Command, args []string) { | ||
if errReturned != nil { | ||
fmt.Printf("error: %v\n", errReturned) | ||
os.Exit(1) | ||
} | ||
|
||
fmt.Println(string(jsonOutput)) | ||
}, | ||
} | ||
|
||
|
@@ -61,18 +57,72 @@ func Execute() error { | |
|
||
func init() { | ||
// TODO: implement | ||
rootCmd.Flags().BoolVar(&overwrite, "overwrite", false, "overwrite existing schema file") | ||
rootCmd.Flags().BoolVar(&overwrite, "overwrite", false, "allow overwriting an existing file") | ||
// TODO: implement | ||
rootCmd.Flags().BoolVar(&outputStdOut, "stdout", false, | ||
"output schema content to stdout instead of a file and disable error output", | ||
"output JSON Schema content to stdout instead of a file and disable error output", | ||
) | ||
// TODO: implement | ||
|
||
rootCmd.Flags().BoolVar(&disallowAdditionalProperties, "disallow-additional-properties", false, | ||
"set additionalProperties to false in the generated schema and in nested objects", | ||
"set additionalProperties to false in the JSON Schema and in nested objects", | ||
) | ||
|
||
rootCmd.Flags().BoolVar(&allowEmpty, "allow-empty", false, | ||
"allow an empty JSON Schema if no variables are found", | ||
) | ||
|
||
rootCmd.Flags().BoolVar(&requireAll, "require-all", false, | ||
"set all variables to be 'required' in the JSON Schema, even if a default value is specified", | ||
) | ||
|
||
rootCmd.Flags().StringVarP(&input, "input", "i", ".", | ||
"input folder containing a Terraform module", | ||
) | ||
|
||
// TODO: implement | ||
rootCmd.Flags().BoolVar(&allowEmpty, "allow-empty", false, "allow empty schema if no variables are found, otherwise error") | ||
rootCmd.Flags().StringVarP(&input, "input", "i", ".", "input folder containing .tf files") | ||
// TODO: implement | ||
rootCmd.Flags().StringVarP(&output, "output", "o", "schema.json", "output file path for schema") | ||
rootCmd.Flags().StringVarP(&output, "output", "o", "schema.json", | ||
"output path for the JSON Schema file", | ||
) | ||
} | ||
|
||
func runCommand(cmd *cobra.Command, args []string) { | ||
path, err := filepath.Abs(input) // absolute path | ||
if err != nil { | ||
errReturned = fmt.Errorf("could not get absolute path for %q: %w", input, err) | ||
|
||
return | ||
} | ||
|
||
folder, err := os.Stat(path) | ||
if err != nil { | ||
errReturned = fmt.Errorf("could not access directory %q: %w", path, err) | ||
|
||
return | ||
} | ||
|
||
if !folder.IsDir() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fwiw this works if input is a sym link to a directory (due to using Stat). |
||
errReturned = fmt.Errorf("input %q is not a directory", path) | ||
|
||
return | ||
} | ||
|
||
output, err := jsonschema.CreateSchema(path, jsonschema.CreateSchemaOptions{ | ||
RequireAll: requireAll, | ||
AllowAdditionalProperties: !disallowAdditionalProperties, | ||
AllowEmpty: allowEmpty, | ||
}) | ||
if err != nil { | ||
errReturned = fmt.Errorf("error creating schema: %w", err) | ||
|
||
return | ||
} | ||
|
||
jsonOutput, err := json.MarshalIndent(output, "", " ") | ||
if err != nil { | ||
errReturned = fmt.Errorf("error marshalling schema: %w", err) | ||
|
||
return | ||
} | ||
|
||
fmt.Println(string(jsonOutput)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is going to stdout (good default behaviour), so "-o" flag not implemented? (Or did I miss something?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implemented in the PR after this |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,10 +32,14 @@ func TestCreateSchema(t *testing.T) { | |
expected, err := os.ReadFile(filepath.Join(schemaPath, name, "schema.json")) | ||
require.NoError(t, err) | ||
|
||
result, err := CreateSchema(filepath.Join(tfPath, name), false) | ||
result, err := CreateSchema(filepath.Join(tfPath, name), CreateSchemaOptions{ | ||
RequireAll: false, | ||
AllowAdditionalProperties: true, | ||
AllowEmpty: true, | ||
}) | ||
require.NoError(t, err) | ||
|
||
var expectedMap map[string]interface{} | ||
var expectedMap map[string]any | ||
err = json.Unmarshal(expected, &expectedMap) | ||
require.NoError(t, err) | ||
|
||
|
@@ -283,7 +287,7 @@ func TestSampleInput(t *testing.T) { | |
|
||
input, err := os.ReadFile(tc.filePath) | ||
require.NoError(t, err) | ||
var m interface{} | ||
var m any | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious - this change is just a style thing? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes |
||
err = json.Unmarshal(input, &m) | ||
require.NoError(t, err) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arguably outputting to stdout by default is the UNIX way. But ultimately a judgement call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather not here because you'll want a file output in all cases, and it complicates error logging a lot. (Splitting stderr and stdout doesnt feel like the Go way to me personally)