diff --git a/.gitignore b/.gitignore index 20e1d72..73731f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -.go-version \ No newline at end of file +.go-version diff --git a/args.go b/args.go index 5298add..5eae1f5 100644 --- a/args.go +++ b/args.go @@ -9,9 +9,11 @@ const ( ) type Args struct { - Files []string - Delim string - Pad int + Files []string + Delim string + Pad int + OutputFile string + ForceOverwrite bool } var Delims = []string{",", ";"} @@ -32,21 +34,21 @@ func (args *Args) ValidateAll() error { func (args *Args) validateFiles() error { if len(args.Files) < 1 { - return fmt.Errorf(ERROR_NO_FILENAME) + return fmt.Errorf("%s", ERROR_NO_FILENAME) } return nil } func (args *Args) validateDelim() error { if !contains(Delims, args.Delim) { - return fmt.Errorf("Error: delimiter should be one of %+q, but got %q", Delims, args.Delim) + return fmt.Errorf("error: delimiter should be one of %+q, but got %q", Delims, args.Delim) } return nil } func (args *Args) validatePad() error { if args.Pad < 0 { - return fmt.Errorf("Error: padding should be positive integer, but got %d", args.Pad) + return fmt.Errorf("error: padding should be positive integer, but got %d", args.Pad) } return nil } diff --git a/args_test.go b/args_test.go index a182bdb..23a9d72 100644 --- a/args_test.go +++ b/args_test.go @@ -14,7 +14,7 @@ func TestArgs(t *testing.T) { } err := args.ValidateAll() if err != nil { - t.Errorf(err.Error()) + t.Error(err.Error()) t.Errorf("Input Args: %+v\n", args) } }) @@ -27,7 +27,7 @@ func TestArgs(t *testing.T) { } err := args.ValidateAll() if err != nil { - t.Errorf(err.Error()) + t.Error(err.Error()) t.Errorf("Input Args: %+v\n", args) } }) diff --git a/convert.go b/convert.go index c89acfa..095a10c 100644 --- a/convert.go +++ b/convert.go @@ -2,6 +2,7 @@ package main import ( "encoding/csv" + "errors" "fmt" "os" "strings" @@ -19,8 +20,18 @@ func ConvertAll(args *Args) error { if err != nil { return err } - // print markdown - fmt.Println(md) + if args.OutputFile == "" { + fmt.Println(md) + } else { + _, err := os.Stat(args.OutputFile) + if errors.Is(err, os.ErrNotExist) || args.ForceOverwrite { + os.WriteFile(args.OutputFile, []byte(md), 0644) + } else { + fmt.Printf( + "skip writing output, file exists: %s\n", args.OutputFile, + ) + } + } } return nil } @@ -74,9 +85,7 @@ func ArrayToMd(records [][]string, args *Args) (string, error) { md := []string{} md = append(md, rows[0]) // header md = append(md, horiz) // horizontal devider - for _, v := range rows[1:] { - md = append(md, v) - } + md = append(md, rows[1:]...) return strings.Join(md, "\n"), nil } @@ -99,7 +108,7 @@ func padCells(records [][]string, colSizes []int) ([][]string, error) { fmt.Println(v) fmt.Println(colSizes[j]) fmt.Println(utf8.RuneCountInString(v)) - return nil, fmt.Errorf("Internal error: column size is bigger than max.") + return nil, fmt.Errorf("internal error: column size is bigger than max") } } } diff --git a/convert_test.go b/convert_test.go index 122de5b..70a357e 100644 --- a/convert_test.go +++ b/convert_test.go @@ -22,7 +22,7 @@ func TestConvert(t *testing.T) { md, err := Convert(testFile, args) if err != nil { - t.Errorf(err.Error()) + t.Error(err.Error()) } if md != expected { @@ -43,7 +43,7 @@ func TestConvert(t *testing.T) { md, err := Convert(testFile, args) if err != nil { - t.Errorf(err.Error()) + t.Error(err.Error()) } if md != expected { @@ -64,7 +64,7 @@ func TestConvert(t *testing.T) { md, err := Convert(testFile, args) if err != nil { - t.Errorf(err.Error()) + t.Error(err.Error()) } if md != expected { @@ -85,7 +85,7 @@ func TestConvert(t *testing.T) { md, err := Convert(testFile, args) if err != nil { - t.Errorf(err.Error()) + t.Error(err.Error()) } if md != expected { diff --git a/main.go b/main.go index d9c3822..6c7e985 100644 --- a/main.go +++ b/main.go @@ -30,6 +30,20 @@ func main() { Usage: "CSV delimiter, expected values: ',', ';'.", Destination: &args.Delim, }, + &cli.StringFlag{ + Name: "output", + Aliases: []string{"o"}, + Value: "", + Usage: "Write output to file, not overwriting existing file by default", + Destination: &args.OutputFile, + }, + &cli.BoolFlag{ + Name: "force", + Aliases: []string{"f"}, + Value: false, + Usage: "Force overwrite, if output file already exists", + Destination: &args.ForceOverwrite, + }, }, Action: func(c *cli.Context) error { args.Files = c.Args().Slice()