-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathmain.go
139 lines (126 loc) · 4.68 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package main
import (
"embed"
"flag"
"fmt"
"github.com/pcasteran/terraform-graph-beautifier/cytoscape"
"github.com/pcasteran/terraform-graph-beautifier/graphviz"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"io/fs"
"os"
"path/filepath"
)
//go:embed templates/*
var templates embed.FS
const (
outputTypeCytoscapeJSON = "cyto-json"
outputTypeCytoscapeHTML = "cyto-html"
outputTypeGraphviz = "graphviz"
)
func getWorkingDir() string {
dir, err := os.Getwd()
if err != nil {
panic(err)
}
return filepath.Base(dir)
}
func main() {
// Prepare command line options.
inputFilePath := flag.String("input", "", "Path of the input Graphviz file to read, if not set 'stdin' is used")
outputType := flag.String("output-type", outputTypeCytoscapeHTML, fmt.Sprintf("Type of output, can be one the following : %s, %s, %s", outputTypeCytoscapeJSON, outputTypeCytoscapeHTML, outputTypeGraphviz))
outputFilePath := flag.String("output", "", "Path of the output file to write, if not set 'stdout' is used")
debug := flag.Bool("debug", false, "Print debugging information to stderr")
printVersion := flag.Bool("v", false, "Print command version and exit")
// Input reading options.
var excludePatterns arrayFlags
flag.Var(&excludePatterns, "exclude", "Pattern (regexp) of the resource to filter out (can be repeated multiple times)")
keepTfJunk := flag.Bool("keep-tf-junk", false, "Do not remove the \"junk\" nodes and edges generated by 'terraform graph' (default false)")
// Output writing options.
graphName := flag.String("graph-name", getWorkingDir(), "Name of the output graph, defaults to working directory name")
embedModules := flag.Bool("embed-modules", true, "Embed a module subgraph inside its parent if true; otherwise the two modules are drawn at the same level and an edge is drawn from the parent to the child")
cytoHTMLTemplatePath := flag.String("cyto-html-template", "", fmt.Sprintf("Path of the HTML template to use for Cytoscape.js rendering (output-type=\"%s\"), if not set a default one is used", outputTypeCytoscapeHTML))
// Parse command line arguments.
flag.Parse()
if *printVersion {
fmt.Printf("version: %s\ncommit: %s\nbuilt at: %s\nbuilt by: %s\n", version, commit, date, builtBy)
os.Exit(0)
}
// Configure logging.
// Default level for this example is info, unless debug flag is present.
zerolog.SetGlobalLevel(zerolog.InfoLevel)
if *debug {
zerolog.SetGlobalLevel(zerolog.DebugLevel)
}
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
// Load the graph from the specified input.
inputFile := os.Stdin
var err error
if *inputFilePath != "" {
// Read from the specified file.
inputFile, err = os.Open(*inputFilePath)
if err != nil {
log.Fatal().Err(err).Msg("Cannot open the file for reading")
}
defer func() {
if err := inputFile.Close(); err != nil {
log.Fatal().Err(err).Msg("Cannot close the file after reading")
}
}()
}
graph := graphviz.LoadGraph(inputFile, *keepTfJunk, excludePatterns)
// Write the result to the specified output.
outputFile := os.Stdout
if *outputFilePath != "" {
// Write to the specified file.
outputFile, err = os.Create(*outputFilePath)
if err != nil {
log.Fatal().Err(err).Msg("Cannot open the file for writing")
}
defer func() {
if err := outputFile.Close(); err != nil {
log.Fatal().Err(err).Msg("Cannot close the file after writing")
}
}()
}
switch *outputType {
case outputTypeCytoscapeJSON:
log.Debug().Msg("Output graph data to Cytoscape.js JSON format")
cytoscape.WriteGraphJSON(outputFile, graph, &cytoscape.RenderingOptions{
GraphName: *graphName,
EmbedModules: *embedModules,
})
case outputTypeCytoscapeHTML:
log.Debug().Msg("Output graph to HTML")
// Open HTML template file.
var template fs.File = nil
if *cytoHTMLTemplatePath != "" {
// Use the specified template file.
template, err = os.Open(*cytoHTMLTemplatePath)
} else {
// Use the default template file.
template, err = templates.Open("templates/index.gohtml")
}
if err != nil {
log.Fatal().Err(err).Msg("Cannot open the HTML template file for reading")
}
defer func() {
if err := template.Close(); err != nil {
log.Fatal().Err(err).Msg("Cannot close the file after reading")
}
}()
cytoscape.WriteGraphHTML(outputFile, graph, &cytoscape.RenderingOptions{
GraphName: *graphName,
EmbedModules: *embedModules,
HTMLTemplate: template,
})
case outputTypeGraphviz:
log.Debug().Msg("Output graph data to Graphviz Dot format")
graphviz.WriteGraph(outputFile, graph, &graphviz.RenderingOptions{
GraphName: *graphName,
EmbedModules: *embedModules,
})
default:
log.Fatal().Err(err).Msg(fmt.Sprintf("Invalid output type : %s", *outputType))
}
}