Skip to content

Commit

Permalink
Retouch env and options.
Browse files Browse the repository at this point in the history
  • Loading branch information
magicdrive committed Nov 2, 2024
1 parent 3194e47 commit ed7d95d
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 72 deletions.
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,27 +52,28 @@ Option | Description
`-a`, `--null-as <null-type-name>` | Specify the null-type name. Used to replace `null` type from json. | `interface{}`
`-j`, `--json <json-string>` | Specify the JSON string to be converted to a struct. |
`-p`, `--pipe` | Receive JSON from a pipe instead of a direct argument above all else. | `false`
`--with-pointer` | Define struct and array fields as pointers. | `false`
`--pointer` `<on|off>` | Define struct and array fields as pointers. | `off`
`--pager` `<pager-mode(auto|no)>` | Prevents usage of a pager even if output exceeds terminal size. (auto|no) | `auto`
`--outline` | Defines struct and array fields as outline struct. (default: true). | `true`
`--inline` | Defines struct and array fields as inline struct. (default: false) | `false`
`--no-pager` | Prevents usage of a pager even if output exceeds terminal size. | `false`

### Arguments

* `<root-name>`: Used as the name of the root struct in the output. Automatically converted to camel case.
* `<json-file>`: File containing JSON data. Can be read even if the extension is not `.json`.
* `<json-string>`: Direct JSON string input.
* `<null-type-name>`: The type name used to replace `null` type from json.
* `<pager-mode>`: Use a pager even if the output size is larger than the terminal. Only `auto` and `no` are valid.

### Environments

Environment | Description | Default
-------------------------------- | -------------------------------------------------------------------------------- | ---------------
`KIRKE_DEFAULT_ROOT_NAME` | Specified default used `<root-name>`. | `AutoGenerated`
`KIRKE_DEFAULT_NULL_AS` | Specified default used `<null-type-name>`. | `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. Changing the default behavior. | `0`
`KIRKE_DEFAULT_WITH_POINTER` | When value "1", defines struct and array fields as pointers. Changing the default behavior. | `0`
Environment | Description | Default
-------------------------------- | ----------------------------------------------------------------------------------- | ---------------
`KIRKE_DEFAULT_ROOT_NAME` | Specified default used `<root-name>`. | `AutoGenerated`
`KIRKE_DEFAULT_NULL_AS` | Specified default used `<null-type-name>`. | `interface{}`
`KIRKE_DEFAULT_OUTPUT_MODE` | Specified the default used output mode. Only `outline` and `inline` are valid. | `outline`
`KIRKE_DEFAULT_PAGER_MODE` | Specified default `<pager-mode>`. Only `auto` and `no` are valid.(default: "auto") | `auto`
`KIRKE_DEFAULT_POINTER_MODE` | Specified default `<pointer-mode>`. Only `on` and `off` are valid.(default: "off") | `off`

Examples
--------
Expand All @@ -81,7 +82,7 @@ Examples

Convert a JSON string to a struct without using a pager and with a specified root name:

kirke -j '{"key": "value"}' --no-pager --name MyStruct
kirke -j '{"key": "value"}' --pager no --name MyStruct

### Example 2: JSON from a file

Expand All @@ -93,19 +94,19 @@ Convert JSON data from a specified file to a struct with a specified root name:

Read JSON data from a pipe, use pointers for nested fields, and output as a struct:

echo '{"key": "value"}' | kirke --with-pointer
echo '{"key": "value"}' | kirke --pointer on

### Example 4: JSON input from a pipe force.

Read JSON data from a pipe, use pointers for nested fields, and output as a struct (-j option is ignored.):

echo '{"key": "value"}' | kirke --pipe --with-pointer -j '{"key2": "value2"}'
echo '{"key": "value"}' | kirke --pipe --pointer on -j '{"key2": "value2"}'

### Example 5: JSON null as `*string` in GO struct.

Read JSON data from a pipe, use pointers for nested fields, and output as a struct (-j option is ignored.):

echo '{"key": "value", "obj": {"num": 1} }' | kirke -a "*string"
echo '{"key": "value", "obj": {"address": null} }' | kirke -a "*string"

LICENCE
-----
Expand Down
4 changes: 2 additions & 2 deletions cmd/kirke/mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ func Excecute(version string) {
os.Exit(1)
}

result, err := core.Apply(jsonStr, opt.RootObjName, outputMode, opt.WithPointerFlag, opt.NullAs)
result, err := core.Apply(jsonStr, opt.RootObjName, outputMode, opt.PointerMode == "on", opt.NullAs)
if err != nil {
fmt.Fprintf(os.Stderr, "Error %v\n", err)
os.Exit(1)
}

commandline.GracefulPrintOut(result, opt.NoPagerFlag)
commandline.GracefulPrintOut(result, opt.PagerMode == "no")
}
21 changes: 11 additions & 10 deletions internal/commandline/help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,38 @@ Options:
-a, --null-as <null-type-name> Specify the null-type name. (default: interface{})
-j, --json <json-string> Specify the json string
-p, --pipe Receive JSON from a pipe instead of a direct argument above all else. (default: false)
--with-pointer Defines struct and array fields as pointers. Only valid for with --outline. (default: false)
--pointer <on|off> Defines struct and array fields as pointers. Only valid for with --outline. (default: off)
--pager <pager-mode> Use a pager even if the output size is larger than the terminal. (default: "auto")
--outline Specify output mode. Defines struct and array fields as outline struct. (default: true)
--inline Specify output mode. Defines struct and array fields as inline struct. (default: false)
--no-pager Does not use a pager even if the output size is larger than the terminal. (default: false)

Arguments:
<root-name> Used as the name of the root struct in the output. Automatically converted to camel case.
<json-file> A file containing a JSON string. It will be read even if the extension is not .json.
<json-string> Direct JSON string input.
<null-type-name> The type name used to replace `null` type from json.
<pager-mode> Use a pager even if the output size is larger than the terminal. Only `auto` and `no` are valid.



Environments:
KIRKE_DEFAULT_ROOT_NAME Specified default used <root-name>. (default: AutoGenerated)
KIRKE_DEFAULT_NULL_AS Specified default used <null-type-name>. (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.
Used if the `--inline` or `--outline` option is not specified. (invalid value will ignored)
KIRKE_DEFAULT_PAGER_MODE Specified default `<pager-mode>`. Only `auto` and `no` are valid.(default: "auto")
KIRKE_DEFAULT_POINTER_MODE Specified default `<pointer-mode>`. Only `on` and `off` are valid.(default: "off")


Examples:
ex1)
kirke -j '{"key": "value"}' --no-pager --name MyStruct
kirke -j '{"key": "value"}' --pager no --name MyStruct
ex2)
kirke -f ./path/to/example.json --name MyExample
ex3)
echo '{"key": "value"}' | kirke --pipe --with-pointer
echo '{"key": "value"}' | kirke --pipe --pointer on
ex4)
echo '{"key": "value"}' | kirke --pipe --with-pointer -j '{"key2": "value2"}'
echo '{"key": "value"}' | kirke --pipe --pointer on -j '{"key2": "value2"}'
ex5)
echo '{"key": "value", "obj": {"num": 1} }' | kirke -a "*string"

Expand Down
30 changes: 19 additions & 11 deletions internal/commandline/mod.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,30 @@ func OptParse(args []string) (int, *Option, error) {
forcePpipeFlagOpt := fs.Bool("pipe", false, "Receive a JSON string from a pipe.")
fs.BoolVar(forcePpipeFlagOpt, "p", false, "Receive a JSON string from a pipe.")

// --no-pager
var defaultNoPager = os.Getenv("KIRKE_DEFAULT_NO_PAGER") == "1"
noPagerFlagOpt := fs.Bool("no-pager", defaultNoPager, "Do not use a pager for output.")
// pagermode --pager auto|no
var defaultPagerMode = os.Getenv("KIRKE_DEFAULT_PAGER_MODE")
if !(defaultPagerMode == "no" || defaultPagerMode == "auto") {
defaultPagerMode = "auto"
}
var pagerMode PagerMode = PagerMode(defaultPagerMode)
fs.Var(&pagerMode, "pager", "Specifies whether to use a pager when necessary.")

// 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.")

// with-pointer
var defaultWithPointer = os.Getenv("KIRKE_DEFAULT_WITH_POINTER") == "1"
withPointerOpt := fs.Bool("with-pointer", defaultWithPointer, "Make nested struct fields of pointer type.")
// pointer mode --pointer on|off
var defaultPointerMode = os.Getenv("KIRKE_DEFAULT_POINTER_MODE")
if !(defaultPointerMode == "on" || defaultPointerMode == "off") {
defaultPointerMode = "off"
}
var pointerMode PointerMode = PointerMode(defaultPointerMode)
fs.Var(&pointerMode, "pointer", "Make nested struct fields of pointer type.")

fs.Usage = func() {
fmt.Fprintln(os.Stderr, "\n\n"+helpMessage)
fmt.Fprintln(os.Stderr, "\nHelpOption:")
fmt.Fprintln(os.Stderr, " kirke --help")
}
err := fs.Parse(args)
if err != nil {
Expand All @@ -78,20 +87,19 @@ func OptParse(args []string) (int, *Option, error) {
Json: *jsonOpt,
FilePath: *filePathOpt,
NullAs: *nullAsOpt,
WithPointerFlag: *withPointerOpt,
PointerMode: pointerMode.String(),
HelpFlag: *helpFlagOpt,
VersionFlag: *versionFlagOpt,
ForcePipeFlag: *forcePpipeFlagOpt,
NoPagerFlag: *noPagerFlagOpt,
PagerMode: pagerMode.String(),
InlineFlag: *inlineFlagOpt,
OutlineFlag: *outlineFlagOpt,
DefaultOutputMode: defaultOutputMode,
FlagSet: fs,
}
OverRideHelp(fs, result.NoPagerFlag)
OverRideHelp(fs, result.PagerMode == "no")

return optLength, result, nil

}

func OverRideHelp(fs *flag.FlagSet, noPagerFlag bool) *flag.FlagSet {
Expand Down
73 changes: 39 additions & 34 deletions internal/commandline/mod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ func compareOptions(t *testing.T, expected, result *commandline.Option) {
if expected.NullAs != result.NullAs {
t.Errorf("Expected NullAs %q, got %q", expected.NullAs, result.NullAs)
}
if expected.WithPointerFlag != result.WithPointerFlag {
t.Errorf("Expected WithPointerFlag %v, got %v", expected.WithPointerFlag, result.WithPointerFlag)
if expected.PointerMode != result.PointerMode {
t.Errorf("Expected PointerMode %v, got %v", expected.PointerMode, result.PointerMode)
}
if expected.HelpFlag != result.HelpFlag {
t.Errorf("Expected HelpFlag %v, got %v", expected.HelpFlag, result.HelpFlag)
Expand All @@ -34,25 +34,29 @@ func compareOptions(t *testing.T, expected, result *commandline.Option) {
if expected.ForcePipeFlag != result.ForcePipeFlag {
t.Errorf("Expected PipeFlag %v, got %v", expected.ForcePipeFlag, result.ForcePipeFlag)
}
if expected.NoPagerFlag != result.NoPagerFlag {
t.Errorf("Expected NoPagerFlag %v, got %v", expected.NoPagerFlag, result.NoPagerFlag)
if expected.PagerMode != result.PagerMode {
t.Errorf("Expected PagerMode %v, got %v", expected.PagerMode, result.PagerMode)
}
if expected.DefaultOutputMode != result.DefaultOutputMode {
t.Errorf("Expected DefaultOutputMode %v, got %v", expected.DefaultOutputMode, result.DefaultOutputMode)
}
}

func TestOptParse_NoArgs(t *testing.T) {
args := []string{}
expected := &commandline.Option{
RootObjName: "AutoGenerated",
Json: "",
FilePath: "",
NullAs: "interface{}",
WithPointerFlag: false,
HelpFlag: false,
VersionFlag: false,
ForcePipeFlag: false,
NoPagerFlag: false,
InlineFlag: false,
OutlineFlag: true,
RootObjName: "AutoGenerated",
Json: "",
FilePath: "",
NullAs: "interface{}",
PointerMode: "off",
HelpFlag: false,
VersionFlag: false,
ForcePipeFlag: false,
PagerMode: "auto",
InlineFlag: false,
OutlineFlag: true,
DefaultOutputMode: "",
}

_, result, err := commandline.OptParse(args)
Expand All @@ -70,24 +74,25 @@ func TestOptParse_WithFlags(t *testing.T) {
"-j", `{"key": "value"}`,
"-f", "input.json",
"-a", "any",
"--with-pointer",
"--pointer", "on",
"--help",
"--version",
"--pipe",
"--no-pager",
"--pager", "no",
}
expected := &commandline.Option{
RootObjName: "TestStruct",
Json: `{"key": "value"}`,
FilePath: "input.json",
NullAs: "any",
WithPointerFlag: true,
HelpFlag: true,
VersionFlag: true,
ForcePipeFlag: true,
NoPagerFlag: true,
InlineFlag: true,
OutlineFlag: true,
RootObjName: "TestStruct",
Json: `{"key": "value"}`,
FilePath: "input.json",
NullAs: "any",
PointerMode: "on",
HelpFlag: true,
VersionFlag: true,
ForcePipeFlag: true,
PagerMode: "no",
InlineFlag: true,
OutlineFlag: true,
DefaultOutputMode: "",
}

_, result, err := commandline.OptParse(args)
Expand All @@ -102,16 +107,16 @@ func TestOptParse_WithFlags(t *testing.T) {
func TestOptParse_WithEnviroments(t *testing.T) {

os.Setenv("KIRKE_DEFAULT_NULL_AS", "any")
os.Setenv("KIRKE_DEFAULT_WITH_POINTER", "1")
os.Setenv("KIRKE_DEFAULT_POINTER_MODE", "on")
os.Setenv("KIRKE_DEFAULT_ROOT_NAME", "MyJsonStruct")
os.Setenv("KIRKE_DEFAULT_OUTPUT_MODE", "inline")
os.Setenv("KIRKE_DEFAULT_NO_PAGER", "1")
os.Setenv("KIRKE_DEFAULT_PAGER_MODE", "no")
defer func() {
os.Unsetenv("KIRKE_DEFAULT_NULL_AS")
os.Unsetenv("KIRKE_DEFAULT_WITH_POINTER")
os.Unsetenv("KIRKE_DEFAULT_POINTER_MODE")
os.Unsetenv("KIRKE_DEFAULT_ROOT_NAME")
os.Unsetenv("KIRKE_DEFAULT_OUTPUT_MODE")
os.Unsetenv("KIRKE_DEFAULT_NO_PAGER")
os.Unsetenv("KIRKE_DEFAULT_PAGER_MODE")
}()

args := []string{}
Expand All @@ -120,11 +125,11 @@ func TestOptParse_WithEnviroments(t *testing.T) {
Json: "",
FilePath: "",
NullAs: "any",
WithPointerFlag: true,
PointerMode: "on",
HelpFlag: false,
VersionFlag: false,
ForcePipeFlag: false,
NoPagerFlag: true,
PagerMode: "no",
InlineFlag: false,
OutlineFlag: false,
DefaultOutputMode: "inline",
Expand Down
36 changes: 36 additions & 0 deletions internal/commandline/mode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package commandline

import (
"fmt"
"strings"
)

type PagerMode string

func (m *PagerMode) Set(value string) error {
switch strings.ToLower(value) {
case "auto", "no":
*m = PagerMode(value)
return nil
default:
return fmt.Errorf("invalid pager mode: %s. Allowed values are 'auto', 'no'", value)
}
}
func (m *PagerMode) String() string {
return string(*m)
}

type PointerMode string

func (m *PointerMode) Set(value string) error {
switch strings.ToLower(value) {
case "on", "off":
*m = PointerMode(value)
return nil
default:
return fmt.Errorf("invalid pointer mode: %s. Allowed values are 'on', 'off'", value)
}
}
func (m *PointerMode) String() string {
return string(*m)
}
9 changes: 7 additions & 2 deletions internal/commandline/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ type Option struct {
Json string
FilePath string
NullAs string
WithPointerFlag bool
PointerMode string
HelpFlag bool
VersionFlag bool
ForcePipeFlag bool
NoPagerFlag bool
PagerMode string
InlineFlag bool
OutlineFlag bool
DefaultOutputMode string
Expand Down Expand Up @@ -109,3 +109,8 @@ func isValidJSON(jsonStr string) bool {
var js json.RawMessage
return json.Unmarshal([]byte(jsonStr), &js) == nil
}

func isValidOption() error {
return nil

}

0 comments on commit ed7d95d

Please sign in to comment.