Skip to content

Commit 44544ef

Browse files
author
Steve Salas
committed
feat: Converts TOML to JSON
1 parent f7437d7 commit 44544ef

File tree

7 files changed

+1058
-0
lines changed

7 files changed

+1058
-0
lines changed

cmd/toml2json/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
licenses
2+

cmd/toml2json/main.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"github.com/codedx/codedx-toml2json/pkg/console"
7+
"github.com/spf13/viper"
8+
"os"
9+
"path/filepath"
10+
)
11+
12+
const (
13+
/* flag.go uses exit code 2 for invalid command-line arguments */
14+
invalidCommandLineArgumentsExitCode = 3
15+
expectedTOMLFileExtensionExitCode = 4
16+
jsonConfigFileAlreadyExistsExitCode = 5
17+
cannotReadTOMLConfigExitCode = 6
18+
cannotWriteJSONConfigExitCode = 7
19+
)
20+
21+
func main() {
22+
23+
const tomlFilePathFlagName = "tomlFile"
24+
const jsonFilePathFlagName = "jsonFile"
25+
26+
tomlFilePathFlagValue := flag.String(tomlFilePathFlagName, "", "a path to the TOML file to convert to JSON")
27+
jsonFilePathFlagValue := flag.String(jsonFilePathFlagName, "", "a path to the JSON ouptut file")
28+
29+
flag.Parse()
30+
31+
tomlFilePath := console.ReadFileFlagValue(tomlFilePathFlagName, tomlFilePathFlagValue, true, invalidCommandLineArgumentsExitCode)
32+
jsonFilePath := console.ReadRequiredFlagStringValue(jsonFilePathFlagName, jsonFilePathFlagValue, invalidCommandLineArgumentsExitCode)
33+
34+
jsonExtension := filepath.Ext(jsonFilePath)
35+
if jsonExtension != ".json" {
36+
console.Fatalf(invalidCommandLineArgumentsExitCode, "JSON file must have '.json' extension. Extension '%s' is unsupported.", jsonExtension)
37+
}
38+
39+
tomlDirectory, tomlFilename := filepath.Split(tomlFilePath)
40+
tomlFilenameExt := filepath.Ext(tomlFilename)
41+
42+
if tomlFilenameExt != ".toml" {
43+
console.Fatalf(expectedTOMLFileExtensionExitCode, "Expected TOML file to have '.toml' file extension, found %s", tomlFilenameExt)
44+
}
45+
tomlFilenameNoExt := tomlFilename[0 : len(tomlFilename)-len(tomlFilenameExt)]
46+
47+
jsonSiblingPath := filepath.Join(tomlDirectory, fmt.Sprintf("%s.json", tomlFilenameNoExt))
48+
if _, err := os.Stat(jsonSiblingPath); !os.IsNotExist(err) {
49+
console.Fatalf(jsonConfigFileAlreadyExistsExitCode, "TOML to JSON conversion will not work because %s will block reading %s. Retry after either deleting the JSON file or specifying another path.", jsonSiblingPath, tomlFilePath)
50+
}
51+
52+
viper.SetConfigName(tomlFilenameNoExt)
53+
viper.SetConfigType("toml")
54+
viper.AddConfigPath(tomlDirectory)
55+
56+
if err := viper.ReadInConfig(); err != nil {
57+
console.Fatalf(cannotReadTOMLConfigExitCode, "Cannot read TOML configuration from %s: %s", tomlFilePath, err.Error())
58+
}
59+
60+
if err := viper.WriteConfigAs(jsonFilePath); err != nil {
61+
console.Fatalf(cannotWriteJSONConfigExitCode, "Cannot write JSON configuration to '%s': %s", jsonFilePath, err.Error())
62+
}
63+
}

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/codedx/codedx-toml2json
2+
3+
go 1.16
4+
5+
require github.com/spf13/viper v1.8.1

go.sum

Lines changed: 584 additions & 0 deletions
Large diffs are not rendered by default.

pkg/assert/common.go

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// Package assert provides functions to compare actual and expected test values.
2+
package assert
3+
4+
import (
5+
"io/ioutil"
6+
"os"
7+
"runtime/debug"
8+
"strings"
9+
"testing"
10+
)
11+
12+
// IntsAreEqual compares an expected int value and an actual int value for equality.
13+
func IntsAreEqual(t *testing.T, expected int, actual int) {
14+
if expected != actual {
15+
debug.PrintStack()
16+
t.Fatalf("Expected: %d; Actual: %d", expected, actual)
17+
}
18+
}
19+
20+
// Int32sAreEqual compares an expected int32 value and an actual int32 value for equality.
21+
func Int32sAreEqual(t *testing.T, expected int32, actual int32) {
22+
if expected != actual {
23+
debug.PrintStack()
24+
t.Fatalf("Expected: %d; Actual: %d", expected, actual)
25+
}
26+
}
27+
28+
// Int64sAreEqual compares an expected int64 value and an actual int64 value for equality.
29+
func Int64sAreEqual(t *testing.T, expected int64, actual int64) {
30+
if expected != actual {
31+
debug.PrintStack()
32+
t.Fatalf("Expected: %d; Actual: %d", expected, actual)
33+
}
34+
}
35+
36+
// StringPrefix compares an expected string value and an actual string value for a prefix match.
37+
func StringPrefix(t *testing.T, expectedPrefix string, actual string) {
38+
if expectedPrefix == "" {
39+
t.FailNow() // invalid usage -> strings.HasPrefix will return true for empty string
40+
}
41+
42+
if !strings.HasPrefix(actual, expectedPrefix) {
43+
debug.PrintStack()
44+
t.Fatalf("Actual does not start with expected: Expected: %s; Actual: %s", expectedPrefix, actual)
45+
}
46+
}
47+
48+
// StringContains compares an expected string and an actual string value for a substring.
49+
func StringContains(t *testing.T, expectedContains string, actual string) {
50+
if !strings.Contains(actual, expectedContains) {
51+
debug.PrintStack()
52+
t.Fatalf("Actual does not contain expected:\nExpected: %s\nActual: %s", expectedContains, actual)
53+
}
54+
}
55+
56+
// StringNotContains compares an expected string and an actual string value for a missing substring.
57+
func StringNotContains(t *testing.T, expectedNotContains string, actual string) {
58+
if strings.Contains(actual, expectedNotContains) {
59+
debug.PrintStack()
60+
t.Fatalf("Actual contains expected: Expected: %s; Actual: %s", expectedNotContains, actual)
61+
}
62+
}
63+
64+
// StringsAreEqual compares an expected string value and an actual string value for equality.
65+
func StringsAreEqual(t *testing.T, expected string, actual string) {
66+
if expected != actual {
67+
debug.PrintStack()
68+
69+
if len(expected) <= 250 {
70+
t.Fatalf("\nExpected: %s;\nActual: %s\n",
71+
expected,
72+
actual)
73+
} else {
74+
t.Fatalf("\nExpected: %s;\nActual: %s\nExpected File: %s\nActual File: %s\nDiff Cmd: gvimdiff '%[3]s' '%[4]s'",
75+
expected,
76+
actual,
77+
saveString(expected, "expected-"),
78+
saveString(actual, "actual-"))
79+
}
80+
}
81+
}
82+
83+
// EmptyString compares an actual string value and the empty string for equality.
84+
func EmptyString(t *testing.T, actual string) {
85+
if actual != "" {
86+
debug.PrintStack()
87+
t.Fatalf("Expected empty string: Actual: %s", actual)
88+
}
89+
}
90+
91+
// NotNil compares an interface and nil for equality.
92+
func NotNil(t *testing.T, actual interface{}) {
93+
if actual == nil {
94+
debug.PrintStack()
95+
t.Fatal("Expected non-nil")
96+
}
97+
}
98+
99+
// Nil compares an interface and nil for inequality.
100+
func Nil(t *testing.T, actual interface{}) {
101+
if actual != nil {
102+
debug.PrintStack()
103+
t.Fatal("Expected nil")
104+
}
105+
}
106+
107+
// NilError compares an error and nil.
108+
func NilError(t *testing.T, err error) {
109+
if err != nil {
110+
debug.PrintStack()
111+
t.Fatalf("Expected nil error, found: %s", err.Error())
112+
}
113+
}
114+
115+
// False compares a bool value to false.
116+
func False(t *testing.T, actual bool) {
117+
if actual {
118+
debug.PrintStack()
119+
t.Fatalf("Expected false: Actual: %t", actual)
120+
}
121+
}
122+
123+
// True compares a bool value to false.
124+
func True(t *testing.T, actual bool) {
125+
if !actual {
126+
debug.PrintStack()
127+
t.Fatalf("Expected true: Actual: %t", actual)
128+
}
129+
}
130+
131+
func saveString(str string, prefix string) string {
132+
f, _ := ioutil.TempFile(os.TempDir(), prefix)
133+
_, _ = f.WriteString(str)
134+
_ = f.Close()
135+
return f.Name()
136+
}

0 commit comments

Comments
 (0)