-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ce13f4c
commit 8d8a279
Showing
74 changed files
with
3,076 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Example 23 - Simple code to expose a CLI to web | ||
|
||
This simple CLI (built with Cobra) requests input for a file that's contents match a specific format structure: | ||
|
||
``` | ||
{ | ||
"title": "Workshop Title", | ||
"instructors": [ | ||
{ | ||
"name": "Instructor 1", | ||
"email": "instructor1@example.com" | ||
}, | ||
{ | ||
"name": "Instructor 2", | ||
"email": "instructor2@example.com" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
If the input file validates against this structure then the data is converted to YAML format and then printed out, otherwise the application will exit 1. | ||
|
||
## Usage | ||
|
||
To use this program, build with the following command: | ||
|
||
`$ go build -o cli .` | ||
|
||
This will create an executable file named `cli` in the current directory. You can then run the program with the `./cli` command and provide the `file` flag to print its contents: | ||
|
||
``` | ||
$ ./cli convert jsonToYaml --file <filename> | ||
``` | ||
|
||
Replace `<filename>` with the name of the file you want to read. An example file is available, `example.json`, with data within the expected structure and results in a successful execution and YAML output. | ||
|
||
If the file cannot be opened or read, an error message will be printed and the program will exit 1. | ||
|
||
## Generate man pages | ||
|
||
For UNIX: | ||
``` | ||
mkdir -p pages | ||
go run documentation/main.go | ||
``` | ||
|
||
## Testing |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
Copyright © 2023 NAME HERE <EMAIL ADDRESS> | ||
*/ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
|
||
"github.com/marianina8/example27/utils" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// convertCmd represents the convert command | ||
var convertCmd = &cobra.Command{ | ||
Use: "convert", | ||
Short: "Converts a JSON to YAML file", | ||
Run: func(cmd *cobra.Command, args []string) { | ||
// converts json to yaml by default | ||
file := cmd.Flag("file").Value.String() | ||
silence, _ := cmd.Flags().GetBool("silence") | ||
output := cmd.Flag("output").Value.String() | ||
|
||
if file == "" { | ||
fmt.Println("Please provide a JSON file to convert") | ||
return | ||
} | ||
yamlData, err := utils.J2Ytransform(file) | ||
if err != nil { | ||
fmt.Fprint(cmd.ErrOrStderr(), "Error converting JSON to YAML") | ||
os.Exit(1) | ||
} | ||
|
||
if !silence { | ||
fmt.Fprint(cmd.OutOrStdout(), string(yamlData)) | ||
} | ||
|
||
if output != "" { | ||
err = ioutil.WriteFile(output, yamlData, 0644) | ||
if err != nil { | ||
fmt.Fprintf(cmd.ErrOrStderr(), "Error writing YAML file: %v", err) | ||
os.Exit(1) | ||
} | ||
} | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(convertCmd) | ||
convertCmd.PersistentFlags().StringP("file", "f", "", "JSON file to convert") | ||
convertCmd.PersistentFlags().BoolP("silence", "s", false, "Silence the output") | ||
convertCmd.PersistentFlags().StringP("output", "o", "", "Output file name") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package cmd | ||
|
||
import ( | ||
"bytes" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/marianina8/example27/models" | ||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
func TestConvert(t *testing.T) { | ||
t.Run("Test successful convert", func(t *testing.T) { | ||
b := bytes.NewBufferString("") | ||
rootCmd.SetOut(b) | ||
rootCmd.SetArgs([]string{"convert", "-f", "../example.json"}) | ||
err := rootCmd.Execute() | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
actualBytes, err := io.ReadAll(b) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
filePath := filepath.Join("..", "example.yaml") | ||
expectedBytes, err := os.ReadFile(filePath) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
var workshop1, workshop2 models.Workshop | ||
yaml.Unmarshal(actualBytes, &workshop1) | ||
yaml.Unmarshal(expectedBytes, &workshop2) | ||
if !(workshop1.Title == workshop2.Title && | ||
workshop1.Instructors[0].Name == workshop2.Instructors[0].Name && | ||
workshop1.Instructors[0].Email == workshop2.Instructors[0].Email && | ||
workshop1.Instructors[1].Name == workshop2.Instructors[1].Name && | ||
workshop1.Instructors[1].Email == workshop2.Instructors[1].Email) { | ||
t.Fatalf("expected %v, got %v", workshop2, workshop1) | ||
} | ||
}) | ||
|
||
t.Run("Fail to convert", func(t *testing.T) { | ||
b := bytes.NewBufferString("") | ||
rootCmd.SetErr(b) | ||
rootCmd.SetArgs([]string{"convert", "--random"}) | ||
err := rootCmd.Execute() | ||
if err == nil { | ||
t.Fatalf("expected err (unknown flag) but got nil") | ||
} | ||
actualBytes, err := io.ReadAll(b) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if string(actualBytes) != "Error: unknown flag: --random\n" { | ||
t.Fatal(err) | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
Copyright © 2023 NAME HERE <EMAIL ADDRESS> | ||
*/ | ||
package cmd | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
|
||
"github.com/mum4k/termdash" | ||
"github.com/mum4k/termdash/align" | ||
"github.com/mum4k/termdash/cell" | ||
"github.com/mum4k/termdash/container" | ||
"github.com/mum4k/termdash/linestyle" | ||
"github.com/mum4k/termdash/terminal/tcell" | ||
"github.com/mum4k/termdash/terminal/terminalapi" | ||
"github.com/mum4k/termdash/widgets/button" | ||
"github.com/mum4k/termdash/widgets/text" | ||
"github.com/mum4k/termdash/widgets/textinput" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// dashboardCmd represents the dashboard command | ||
var dashboardCmd = &cobra.Command{ | ||
Use: "dashboard", | ||
Short: "An example dashboard", | ||
Run: func(cmd *cobra.Command, args []string) { | ||
terminalLayer, err := tcell.New(tcell.ColorMode(terminalapi.ColorMode256), tcell.ClearStyle(cell.ColorYellow, cell.ColorNavy)) | ||
if err != nil { | ||
fmt.Println(err) | ||
} | ||
defer terminalLayer.Close() | ||
value := make(chan string) | ||
rollingText, err := text.New(text.RollContent()) | ||
if err != nil { | ||
panic(err) | ||
} | ||
go rollText(rollingText, value) | ||
leftContainer := container.Left( | ||
container.Border(linestyle.Light), | ||
container.PlaceWidget(rollingText), | ||
) | ||
input, err := textinput.New( | ||
textinput.Label("Input: "), | ||
textinput.MaxWidthCells(20), | ||
textinput.PlaceHolder("Enter text here"), | ||
) | ||
if err != nil { | ||
panic(err) | ||
} | ||
submitButton, err := button.New("Submit", func() error { | ||
inputValue := input.ReadAndClear() | ||
if inputValue != "" { | ||
value <- inputValue | ||
} | ||
return nil | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
clearButton, err := button.New("Clear", func() error { | ||
rollingText.Reset() | ||
return nil | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
rightContainer := container.Right( | ||
container.SplitHorizontal( | ||
container.Top( | ||
container.Border(linestyle.Light), | ||
container.PlaceWidget(input), | ||
container.AlignVertical(align.VerticalBottom), | ||
container.MarginTop(3), | ||
container.MarginBottom(3), | ||
container.MarginRight(3), | ||
container.MarginLeft(3), | ||
), | ||
container.Bottom( | ||
container.SplitVertical( | ||
container.Left( | ||
container.Border(linestyle.Light), | ||
container.PlaceWidget(submitButton), | ||
container.AlignVertical(align.VerticalTop), | ||
), | ||
container.Right( | ||
container.Border(linestyle.Light), | ||
container.PlaceWidget(clearButton), | ||
container.AlignVertical(align.VerticalTop), | ||
), | ||
), | ||
), | ||
), | ||
) | ||
containerLayer, _ := container.New( | ||
terminalLayer, | ||
container.SplitVertical( | ||
leftContainer, | ||
rightContainer, | ||
container.SplitPercent(60), | ||
), | ||
) | ||
|
||
ctx, cancel := context.WithCancel(context.Background()) | ||
quitter := func(k *terminalapi.Keyboard) { | ||
if k.Key == 'q' || k.Key == 'Q' { | ||
cancel() | ||
} | ||
} | ||
if err := termdash.Run(ctx, terminalLayer, containerLayer, termdash.KeyboardSubscriber(quitter)); err != nil { | ||
panic(err) | ||
} | ||
|
||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(dashboardCmd) | ||
} | ||
|
||
func rollText(rollingText *text.Text, value <-chan string) { | ||
for { | ||
select { | ||
case v := <-value: | ||
err := rollingText.Write(v) | ||
if err != nil { | ||
panic(err) | ||
} | ||
default: | ||
// no value on the channel, continue without blocking | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
Copyright © 2023 NAME HERE <EMAIL ADDRESS> | ||
*/ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"log" | ||
"os" | ||
|
||
"github.com/marianina8/example27/utils" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// jsonToYamlCmd represents the jsonToYaml command | ||
var jsonToYamlCmd = &cobra.Command{ | ||
Use: "jsonToYaml", | ||
Short: "Converts json to yaml", | ||
Aliases: []string{"j2y"}, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
file := cmd.Flag("file").Value.String() | ||
silence, _ := cmd.Flags().GetBool("silence") | ||
output := cmd.Flag("output").Value.String() | ||
|
||
if file == "" { | ||
fmt.Println("Please provide a JSON file to convert") | ||
return | ||
} | ||
yamlData, err := utils.J2Ytransform(file) | ||
if err != nil { | ||
log.Fatalf("Error converting JSON to YAML: %v", err) | ||
os.Exit(1) | ||
} | ||
|
||
if !silence { | ||
fmt.Println(string(yamlData)) | ||
} | ||
|
||
if output != "" { | ||
err = ioutil.WriteFile(output, yamlData, 0644) | ||
if err != nil { | ||
log.Fatalf("Error writing YAML file: %v", err) | ||
os.Exit(1) | ||
} | ||
} | ||
}, | ||
} | ||
|
||
func init() { | ||
convertCmd.AddCommand(jsonToYamlCmd) | ||
} |
Oops, something went wrong.