-
Notifications
You must be signed in to change notification settings - Fork 5
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
a95bd5c
commit 5195743
Showing
12 changed files
with
741 additions
and
0 deletions.
There are no files selected for viewing
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,15 @@ | ||
language: go | ||
|
||
go: | ||
- "1.11.x" | ||
|
||
env: | ||
- GO111MODULE=on GOLANGCI_LINT_VERSION=1.12.5 | ||
|
||
install: | ||
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $GOPATH/bin v${GOLANGCI_LINT_VERSION} | ||
- go mod vendor | ||
|
||
script: | ||
- go test -race ./... | ||
- golangci-lint run . |
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,68 @@ | ||
= Kroki CLI | ||
|
||
image:https://travis-ci.org/yuzutech/kroki-cli.svg?branch=master[Build Status,link=https://travis-ci.org/yuzutech/kroki-cli] | ||
|
||
A CLI for https://kroki.io. | ||
|
||
== Usage | ||
|
||
kroki convert hello.dot | ||
|
||
By default the diagram type will be inferred from the diagram file extension and the default output format will be `SVG`. | ||
|
||
Long format: | ||
|
||
kroki convert hello.dot --type dot --format svg | ||
|
||
The output format can also be inferred from the output file using the `--out-file` flag: | ||
|
||
kroki convert simple.er --out-file out.png | ||
|
||
Read from `stdin`: | ||
|
||
cat hello.dot | kroki convert - -t dot | ||
|
||
By default when reading from `stdin` using `-`, the result will be output to `stdout`. | ||
If you want to output to a file you can use `-o`: | ||
|
||
cat hello.dot | kroki convert - -t dot -o out.png | ||
|
||
Similarly, you can also output to `stdout` when reading from a file using the special value `-` with the `--out-file` flag: | ||
|
||
kroki convert simple.er --out-file - | ||
|
||
== Configuration | ||
|
||
To configure the endpoint, you can use a configuration file. | ||
The CLI will look for the following locations: | ||
|
||
* `/etc/kroki.yml` | ||
* `$HOME/kroki.yml` | ||
* `kroki.yml` | ||
|
||
You can also specify an alternate config file using the `--config` flag: | ||
|
||
kroki convert hello.dot --config config.yml | ||
|
||
The config file should contain the endpoint URL and the HTTP timeout. | ||
By default Kroki will use the demonstration server: https://demo.kroki.io and a timeout of 20 seconds. | ||
|
||
CAUTION: Please note that the demonstration server usage is restricted to reasonable, non-commercial use-cases. | ||
We provide no guarantee regarding uptime or latency. | ||
|
||
Example: | ||
|
||
.kroki.yml | ||
```yml | ||
endpoint: 'https://localhost:8000' | ||
timeout: 30s | ||
``` | ||
|
||
If you don't want to use a file you can also use the following environment variables: | ||
|
||
* `KROKI_ENDPOINT` | ||
* `KROKI_TIMEOUT` | ||
|
||
[] | ||
|
||
KROKI_ENDPOINT=https://localhost:8000 KROKI_TIMEOUT=1m kroki convert hello.dot |
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,33 @@ | ||
package cmd | ||
|
||
import "github.com/spf13/viper" | ||
|
||
func SetupConfig() { | ||
// Default values | ||
viper.SetDefault("endpoint", "https://demo.kroki.io") | ||
viper.SetDefault("timeout", "20s") | ||
|
||
// Config file name | ||
viper.SetConfigName("kroki") | ||
|
||
// Default config paths | ||
viper.AddConfigPath("/etc") | ||
viper.AddConfigPath("$HOME") | ||
viper.AddConfigPath(".") | ||
|
||
// Environment variables | ||
viper.SetEnvPrefix("kroki") | ||
err := viper.BindEnv("endpoint") | ||
if err != nil { | ||
exit(err) | ||
} | ||
err = viper.BindEnv("timeout") | ||
if err != nil { | ||
exit(err) | ||
} | ||
} | ||
|
||
|
||
func InitDefaultConfig() { | ||
viper.ReadInConfig() // ignore error | ||
} |
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,255 @@ | ||
package cmd | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"os" | ||
"path" | ||
"path/filepath" | ||
"strings" | ||
|
||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
"github.com/yuzutech/kroki-go" | ||
) | ||
|
||
func Convert(cmd *cobra.Command, args []string) { | ||
filePath := args[0] | ||
graphFormat, err := cmd.Flags().GetString("type") | ||
if err != nil { | ||
exit(err) | ||
} | ||
imageFormat, err := cmd.Flags().GetString("format") | ||
if err != nil { | ||
exit(err) | ||
} | ||
outFile, err := cmd.Flags().GetString("out-file") | ||
if err != nil { | ||
exit(err) | ||
} | ||
client := GetClient(cmd) | ||
if filePath == "-" { | ||
reader := bufio.NewReader(os.Stdin) | ||
ConvertFromReader(client, graphFormat, imageFormat, outFile, reader) | ||
} else { | ||
ConvertFromFile(client, filePath, graphFormat, imageFormat, outFile) | ||
} | ||
} | ||
|
||
func ConvertFromReader(client kroki.Client, diagramTypeRaw string, imageFormatRaw string, outFile string, reader io.Reader) { | ||
if diagramTypeRaw == "" { | ||
exit("diagram type must be specify using --type flag") | ||
} | ||
diagramType, err := GraphFormatFromValue(diagramTypeRaw) | ||
if err != nil { | ||
exit(err) | ||
} | ||
imageFormat, err := ResolveImageFormat(imageFormatRaw, outFile) | ||
if err != nil { | ||
exit(err) | ||
} | ||
text, err := GetTextFromReader(reader) | ||
if err != nil { | ||
exit(err) | ||
} | ||
result, err := client.FromString(text, diagramType, imageFormat) | ||
if err != nil { | ||
exit(err) | ||
} | ||
if outFile == "" || outFile == "-" { | ||
fmt.Println(result) | ||
} else { | ||
err = client.WriteToFile(outFile, result) | ||
if err != nil { | ||
exit(err) | ||
} | ||
} | ||
} | ||
|
||
func GetTextFromReader(reader io.Reader) (result string, err error) { | ||
input, err := ioutil.ReadAll(reader) | ||
return string(input), err | ||
} | ||
|
||
func ConvertFromFile(client kroki.Client, filePath string, graphFormatRaw string, imageFormatRaw string, outFile string) { | ||
graphFormat, err := ResolveGraphFormat(graphFormatRaw, filePath) | ||
if err != nil { | ||
exit(err) | ||
} | ||
imageFormat, err := ResolveImageFormat(imageFormatRaw, outFile) | ||
if err != nil { | ||
exit(err) | ||
} | ||
result, err := client.FromFile(filePath, graphFormat, imageFormat) | ||
if err != nil { | ||
exit(err) | ||
} | ||
if outFile == "-" { | ||
fmt.Println(result) | ||
} else { | ||
err = client.WriteToFile(ResolveOutputFilePath(outFile, filePath, imageFormat), result) | ||
if err != nil { | ||
exit(err) | ||
} | ||
} | ||
} | ||
|
||
func ResolveOutputFilePath(outFile string, filePath string, imageFormat kroki.ImageFormat) string { | ||
if outFile != "" { | ||
return outFile | ||
} | ||
fileExtension := path.Ext(filePath) | ||
return filePath[0:len(filePath)-len(fileExtension)] + "." + string(imageFormat) | ||
} | ||
|
||
func ResolveImageFormat(imageFormatRaw string, outFile string) (kroki.ImageFormat, error) { | ||
if imageFormatRaw == "" { | ||
if outFile == "" || outFile == "-" { | ||
return kroki.Svg, nil | ||
} | ||
return ImageFormatFromFile(outFile) | ||
} | ||
return ImageFormatFromValue(imageFormatRaw) | ||
} | ||
|
||
func ImageFormatFromValue(imageFormatRaw string) (kroki.ImageFormat, error) { | ||
value := strings.ToLower(imageFormatRaw) | ||
switch value { | ||
case "svg": | ||
return kroki.Svg, nil | ||
case "png": | ||
return kroki.ImageFormat("png"), nil | ||
case "jpeg": | ||
return kroki.ImageFormat("jpeg"), nil | ||
case "pdf": | ||
return kroki.ImageFormat("pdf"), nil | ||
default: | ||
return kroki.ImageFormat(""), errors.Errorf( | ||
"invalid image format %s.", | ||
value) | ||
} | ||
} | ||
|
||
func ImageFormatFromFile(filePath string) (kroki.ImageFormat, error) { | ||
fileExtension := filepath.Ext(filePath) | ||
value := strings.ToLower(fileExtension) | ||
switch value { | ||
case ".svg": | ||
return kroki.Svg, nil | ||
case ".png": | ||
return kroki.ImageFormat("png"), nil | ||
case ".jpeg", ".jpg": | ||
return kroki.ImageFormat("jpeg"), nil | ||
case ".pdf": | ||
return kroki.ImageFormat("pdf"), nil | ||
default: | ||
return kroki.ImageFormat(""), errors.Errorf( | ||
"invalid image format %s.", | ||
value) | ||
} | ||
} | ||
|
||
func ResolveGraphFormat(graphFormatRaw string, filePath string) (kroki.GraphFormat, error) { | ||
if graphFormatRaw == "" { | ||
return GraphFormatFromFile(filePath) | ||
} else { | ||
return GraphFormatFromValue(graphFormatRaw) | ||
} | ||
} | ||
|
||
func GraphFormatFromValue(value string) (kroki.GraphFormat, error) { | ||
value = strings.ToLower(value) | ||
switch value { | ||
case "dot", "graphviz": | ||
return kroki.Graphviz, nil | ||
case "plantuml": | ||
return kroki.Plantuml, nil | ||
case "nomnoml": | ||
return kroki.Nomnoml, nil | ||
case "blockdiag": | ||
return kroki.BlockDiag, nil | ||
case "mermaid": | ||
return kroki.Mermaid, nil | ||
case "svgbob": | ||
return kroki.Svgbob, nil | ||
case "umlet": | ||
return kroki.Umlet, nil | ||
case "c4plantuml": | ||
return kroki.C4plantuml, nil | ||
case "seqdiag": | ||
return kroki.SeqDiag, nil | ||
case "erd", "er": | ||
return kroki.GraphFormat("erd"), nil | ||
case "nwdiag": | ||
return kroki.GraphFormat("nwdiag"), nil | ||
case "actdiag": | ||
return kroki.GraphFormat("actdiag"), nil | ||
case "ditaa": | ||
return kroki.GraphFormat("ditaa"), nil | ||
default: | ||
return kroki.GraphFormat(""), errors.Errorf( | ||
"invalid graph format %s.", | ||
value) | ||
} | ||
} | ||
|
||
func GraphFormatFromFile(filePath string) (kroki.GraphFormat, error) { | ||
fileExtension := filepath.Ext(filePath) | ||
value := strings.ToLower(fileExtension) | ||
switch value { | ||
case ".dot", ".gv", ".graphviz": | ||
return kroki.Graphviz, nil | ||
case ".puml", ".plantuml": | ||
return kroki.Plantuml, nil | ||
case ".nomnoml": | ||
return kroki.Nomnoml, nil | ||
case ".blockdiag": | ||
return kroki.BlockDiag, nil | ||
case ".mermaid": | ||
return kroki.Mermaid, nil | ||
case ".svgbob": | ||
return kroki.Svgbob, nil | ||
case ".umlet": | ||
return kroki.Umlet, nil | ||
case ".c4puml", ".c4", ".c4plantuml": | ||
return kroki.C4plantuml, nil | ||
case ".seqdiag": | ||
return kroki.SeqDiag, nil | ||
case ".erd", ".er": | ||
return kroki.GraphFormat("erd"), nil | ||
case ".nwdiag": | ||
return kroki.GraphFormat("nwdiag"), nil | ||
case ".actdiag": | ||
return kroki.GraphFormat("actdiag"), nil | ||
case ".ditaa": | ||
return kroki.GraphFormat("ditaa"), nil | ||
default: | ||
return kroki.GraphFormat(""), errors.Errorf( | ||
"unable to infer the graph format from the file extension %s, please specify the diagram type using --type flag.", | ||
value) | ||
} | ||
} | ||
|
||
func GetClient(cmd *cobra.Command) kroki.Client { | ||
configFilePath, err := cmd.Flags().GetString("config") | ||
if err != nil { | ||
exit(err) | ||
} | ||
if configFilePath != "" { | ||
file, err := os.Open(configFilePath) | ||
if err != nil { | ||
exit(err) | ||
} | ||
err = viper.ReadConfig(file) | ||
if err != nil { | ||
exit(err) | ||
} | ||
} | ||
return kroki.New(kroki.Configuration{ | ||
URL: viper.GetString("endpoint"), | ||
Timeout: viper.GetDuration("timeout"), | ||
}) | ||
} |
Oops, something went wrong.