diff --git a/README.md b/README.md index 650658c..eb803c0 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,16 @@ Option | Description * ``: Direct JSON string input. * ``: The type name used to replace `null` type from json. +### Environments + +Environment | Description | Default +-------------------------------- | -------------------------------------------------------------------------------- | --------------- +`KIRKE_DEFAULT_ROOT_NAME` | Specified default used | `AutoGenerated` +`KIRKE_DEFAULT_NULL_AS` | Specified default used . | `interface{}` +`KIRKE_DEFAULT_OUTPUT_MODE` | Specified the default used output mode. Only `outline` and `inline` are valid. | `outline` +`KIRKE_DEFAULT_NO_PAGER` | When value "1", output doesn't use the pager. | `0` +`KIRKE_DEFAULT_WITH_POINTER` | When value "1", defines struct and array fields as pointers. | `0` + Examples -------- diff --git a/internal/commandline/help.txt b/internal/commandline/help.txt index 9518e6d..ab86baf 100644 --- a/internal/commandline/help.txt +++ b/internal/commandline/help.txt @@ -19,10 +19,21 @@ Options: --no-pager Does not use a pager even if the output size is larger than the terminal. (default: false) Arguments: - Used as the name of the root struct in the output. Automatically converted to camel case. - A file containing a JSON string. It will be read even if the extension is not .json. - Direct JSON string input. - The type name used to replace `null` type from json. + Used as the name of the root struct in the output. Automatically converted to camel case. + A file containing a JSON string. It will be read even if the extension is not .json. + Direct JSON string input. + The type name used to replace `null` type from json. + +Environments: + KIRKE_DEFAULT_ROOT_NAME Specified default used . (default: AutoGenerated) + KIRKE_DEFAULT_NULL_AS Specified default used . (default: interface{}) + KIRKE_DEFAULT_OUTPUT_MODE Specified the default used output mode. Only `outline` and `inline` are valid. (default: outline) + used if the `--inline` or `--outline` option is not specified. (invalid value will ignored) + KIRKE_DEFAULT_NO_PAGER When value "1", output doesn't use the pager. (default: 0) + used if the --with-pager option is not specified. + KIRKE_DEFAULT_WITH_POINTER When value "1", defines struct and array fields as pointers. (default: 0) + used if the `--with-pointer` option is not specified. valid in outline mode. + Examples: ex1) diff --git a/internal/commandline/mod.go b/internal/commandline/mod.go index 12ab3be..e0ba208 100644 --- a/internal/commandline/mod.go +++ b/internal/commandline/mod.go @@ -3,6 +3,8 @@ package commandline import ( _ "embed" "flag" + "fmt" + "os" ) //go:embed help.txt @@ -14,51 +16,77 @@ func OptParse(args []string) (int, *Option, error) { fs := flag.NewFlagSet("kirke", flag.ExitOnError) - nameOpt := fs.String("name", "AutoGenerated", "Specified root struct name.") - fs.StringVar(nameOpt, "n", "AutoGenerated", "Specified root struct name.") + // --name + var defaultName = os.Getenv("KIRKE_DEFAULT_ROOT_NAME") + if defaultName == "" { + defaultName = "AutoGenerated" + } + nameOpt := fs.String("name", defaultName, "Specified root struct name.") + fs.StringVar(nameOpt, "n", defaultName, "Specified root struct name.") + // --json jsonOpt := fs.String("json", "", "Specified json string.") fs.StringVar(jsonOpt, "j", "", "Specified json string.") + // --file filePathOpt := fs.String("file", "", "Specified json string source file.") fs.StringVar(filePathOpt, "f", "", "Specified json string source file.") - nullAsOpt := fs.String("null-as", "interface{}", "Specified type name used to replace nulls from json.") - fs.StringVar(nullAsOpt, "a", "interface{}", "Specified type name used to replace nulls from json.") + // --null-as + var defaultNullAs = os.Getenv("KIRKE_DEFAULT_NULL_AS") + if defaultNullAs == "" { + defaultNullAs = "interface{}" + } + nullAsOpt := fs.String("null-as", defaultNullAs, "Specified type name used to replace nulls from json.") + fs.StringVar(nullAsOpt, "a", defaultNullAs, "Specified type name used to replace nulls from json.") - helpFlagOpt := fs.Bool("help", false, "Show this message.") - fs.BoolVar(helpFlagOpt, "h", false, "Show this message.") + // --help + helpFlagOpt := fs.Bool("help", false, "Show help message.") + fs.BoolVar(helpFlagOpt, "h", false, "Show help message.") + // --version versionFlagOpt := fs.Bool("version", false, "Show version.") fs.BoolVar(versionFlagOpt, "v", false, "Show version.") + // --pipe forcePpipeFlagOpt := fs.Bool("pipe", false, "Receive a JSON string from a pipe.") fs.BoolVar(forcePpipeFlagOpt, "p", false, "Receive a JSON string from a pipe.") - noPagerFlagOpt := fs.Bool("no-pager", false, "Do not use a pager for output.") + // --no-pager + var defaultNoPager = os.Getenv("KIRKE_DEFAULT_NO_PAGER") == "1" + noPagerFlagOpt := fs.Bool("no-pager", defaultNoPager, "Do not use a pager for output.") + + // ouputmode --inline --outline + var defaultOutputMode = os.Getenv("KIRKE_DEFAULT_OUTPUT_MODE") inlineFlagOpt := fs.Bool("inline", false, "Create inline struct definition output.") outlineFlagOpt := fs.Bool("outline", false, "Create outline struct definition output.") - withPointerOpt := fs.Bool("with-pointer", false, "Make nested struct fields of pointer type.") + // with-pointer + var defaultWithPointer = os.Getenv("KIRKE_DEFAULT_WITH_POINTER") == "1" + withPointerOpt := fs.Bool("with-pointer", defaultWithPointer, "Make nested struct fields of pointer type.") + fs.Usage = func() { + fmt.Fprintln(os.Stderr, "\n\n"+helpMessage) + } err := fs.Parse(args) if err != nil { return optLength, nil, err } result := &Option{ - RootObjName: *nameOpt, - Json: *jsonOpt, - FilePath: *filePathOpt, - NullAs: *nullAsOpt, - WithPointerFlag: *withPointerOpt, - HelpFlag: *helpFlagOpt, - VersionFlag: *versionFlagOpt, - ForcePipeFlag: *forcePpipeFlagOpt, - NoPagerFlag: *noPagerFlagOpt, - InlineFlag: *inlineFlagOpt, - OutlineFlag: *outlineFlagOpt, - FlagSet: fs, + RootObjName: *nameOpt, + Json: *jsonOpt, + FilePath: *filePathOpt, + NullAs: *nullAsOpt, + WithPointerFlag: *withPointerOpt, + HelpFlag: *helpFlagOpt, + VersionFlag: *versionFlagOpt, + ForcePipeFlag: *forcePpipeFlagOpt, + NoPagerFlag: *noPagerFlagOpt, + InlineFlag: *inlineFlagOpt, + OutlineFlag: *outlineFlagOpt, + DefaultOutputMode: defaultOutputMode, + FlagSet: fs, } OverRideHelp(fs, result.NoPagerFlag) diff --git a/internal/commandline/mod_test.go b/internal/commandline/mod_test.go index 87fdba0..f63fd10 100644 --- a/internal/commandline/mod_test.go +++ b/internal/commandline/mod_test.go @@ -1,6 +1,7 @@ package commandline_test import ( + "os" "testing" "github.com/magicdrive/kirke/internal/commandline" @@ -51,7 +52,7 @@ func TestOptParse_NoArgs(t *testing.T) { ForcePipeFlag: false, NoPagerFlag: false, InlineFlag: false, - OutlineFlag: false, + OutlineFlag: true, } _, result, err := commandline.OptParse(args) @@ -97,3 +98,43 @@ func TestOptParse_WithFlags(t *testing.T) { // Compare only the relevant fields compareOptions(t, expected, result) } + +func TestOptParse_WithEnviroments(t *testing.T) { + + os.Setenv("KIRKE_DEFAULT_NULL_AS", "any") + os.Setenv("KIRKE_DEFAULT_WITH_POINTER", "1") + os.Setenv("KIRKE_DEFAULT_ROOT_NAME", "MyJsonStruct") + os.Setenv("KIRKE_DEFAULT_OUTPUT_MODE", "inline") + os.Setenv("KIRKE_DEFAULT_NO_PAGER", "1") + defer func() { + os.Unsetenv("KIRKE_DEFAULT_NULL_AS") + os.Unsetenv("KIRKE_DEFAULT_WITH_POINTER") + os.Unsetenv("KIRKE_DEFAULT_ROOT_NAME") + os.Unsetenv("KIRKE_DEFAULT_OUTPUT_MODE") + os.Unsetenv("KIRKE_DEFAULT_NO_PAGER") + }() + + args := []string{} + expected := &commandline.Option{ + RootObjName: "MyJsonStruct", + Json: "", + FilePath: "", + NullAs: "any", + WithPointerFlag: true, + HelpFlag: false, + VersionFlag: false, + ForcePipeFlag: false, + NoPagerFlag: true, + InlineFlag: false, + OutlineFlag: false, + DefaultOutputMode: "inline", + } + + _, result, err := commandline.OptParse(args) + if err != nil { + t.Fatalf("Expected no error, got %v", err) + } + + // Compare only the relevant fields + compareOptions(t, expected, result) +} diff --git a/internal/commandline/options.go b/internal/commandline/options.go index a8c061b..2cac716 100644 --- a/internal/commandline/options.go +++ b/internal/commandline/options.go @@ -14,19 +14,20 @@ const ( ) type Option struct { - RootObjName string - Json string - FilePath string - NullAs string - WithPointerFlag bool - HelpFlag bool - VersionFlag bool - ForcePipeFlag bool - NoPagerFlag bool - InlineFlag bool - OutlineFlag bool - FlagSet *flag.FlagSet - PipeReader PipeReader + RootObjName string + Json string + FilePath string + NullAs string + WithPointerFlag bool + HelpFlag bool + VersionFlag bool + ForcePipeFlag bool + NoPagerFlag bool + InlineFlag bool + OutlineFlag bool + DefaultOutputMode string + FlagSet *flag.FlagSet + PipeReader PipeReader } func (cr *Option) DecideJSONStr() (string, error) { @@ -91,11 +92,17 @@ func (cr *Option) DecideOutputMode() (int, error) { } else if cr.InlineFlag == false && cr.OutlineFlag == true { return OutputModeOutline, nil } else if cr.InlineFlag == false && cr.OutlineFlag == false { + if cr.DefaultOutputMode == "inline" { + return OutputModeInline, nil + } else if cr.DefaultOutputMode == "outline" { + return OutputModeOutline, nil + } return OutputModeOutline, nil } else if cr.InlineFlag == true && cr.OutlineFlag == true { return -1, fmt.Errorf("cannot enable --inline and --outline at the same time.") + } else { + return OutputModeOutline, nil } - return OutputModeOutline, nil } func isValidJSON(jsonStr string) bool { diff --git a/misc/sample.json b/misc/sample.json index b664309..95e2cd4 100644 --- a/misc/sample.json +++ b/misc/sample.json @@ -2,7 +2,7 @@ "id": 12345, "name": "Sample Data", "description": "This is a sample JSON data with a complex structure.", - "active": null, + "nullValue": null, "tags": [ "example", "json",