Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to use stdout #63

Merged
merged 2 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (a analyzer) GetTables(db database.Connector, selectedSchemas []string) ([]
return util.Map2(selectedTables, func(value string) database.TableDetail {
res, err := database.ParseTableName(value, selectedSchemas)
if err != nil {
logrus.Error("Could not parse table name", value)
logrus.Error("Could not parse table name ", value)
}

return res
Expand Down Expand Up @@ -165,7 +165,7 @@ func (a analyzer) GetTables(db database.Connector, selectedSchemas []string) ([]
return util.Map2(surveyResult, func(value string) database.TableDetail {
res, err := database.ParseTableName(value, selectedSchemas)
if err != nil {
logrus.Error("Could not parse table name", value)
logrus.Error("Could not parse table name ", value)
}

return res
Expand Down
11 changes: 9 additions & 2 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (after version 0.0.5).

## [0.12.0] - 2024-0
### Added
- new `--outputMode` option ([PR #63](https://github.com/KarnerTh/mermerd/pull/63))

### Changed
- go 1.23 is now used

## [0.11.0] - 2024-06-16
### Added
- new `--ignoreTables` option ([PR #59](https://github.com/KarnerTh/mermerd/pull/59))

### Changed
- go 1.22 is now used

### Fixed

## [0.10.0] - 2023-11-21
### Added
- Support relationship labels ([PR #50](https://github.com/KarnerTh/mermerd/pull/50))
Expand Down Expand Up @@ -155,6 +160,8 @@ by `--showDescriptions enumValues` (for details see [PR #32](https://github.com/
### Added
- Initial release of mermerd

[0.12.0]: https://github.com/KarnerTh/mermerd/releases/tag/v0.12.0

[0.11.0]: https://github.com/KarnerTh/mermerd/releases/tag/v0.11.0

[0.10.0]: https://github.com/KarnerTh/mermerd/releases/tag/v0.10.0
Expand Down
60 changes: 42 additions & 18 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"io"
"os"

"github.com/fatih/color"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
Expand All @@ -24,14 +23,18 @@ var rootCmd = &cobra.Command{
Short: "Create Mermaid ERD diagrams from existing tables",
Long: "Create Mermaid ERD diagrams from existing tables",
Run: func(cmd *cobra.Command, args []string) {
presentation.ShowIntro()
config := config.NewConfig()
conf := config.NewConfig()
if runConfig != "" {
presentation.ShowInfo(conf, fmt.Sprintf("Using run configuration (from %s)", runConfig))
}

presentation.ShowIntro(conf)
connectorFactory := database.NewConnectorFactory()
questioner := analyzer.NewQuestioner()
analyzer := analyzer.NewAnalyzer(config, connectorFactory, questioner)
diagram := diagram.NewDiagram(config)
analyzer := analyzer.NewAnalyzer(conf, connectorFactory, questioner)
diagram := diagram.NewDiagram(conf)

if !config.Debug() {
if !conf.Debug() {
logrus.SetOutput(io.Discard)
}

Expand All @@ -42,14 +45,33 @@ var rootCmd = &cobra.Command{
os.Exit(1)
}

err = diagram.Create(result)
var wr io.Writer
if conf.OutputMode() == config.File {
f, err := os.Create(conf.OutputFileName())
defer f.Close()
if err != nil {
logrus.Error(err)
presentation.ShowError()
os.Exit(1)
}

wr = f
} else if conf.OutputMode() == config.Stdout {
wr = os.Stdout
} else {
logrus.Errorf("Output mode %s not suppported", conf.OutputMode())
presentation.ShowError()
os.Exit(1)
}

err = diagram.Create(wr, result)
if err != nil {
logrus.Error(err)
presentation.ShowError()
os.Exit(1)
}

presentation.ShowSuccess(config.OutputFileName())
presentation.ShowSuccess(conf, conf.OutputFileName())
},
}

Expand All @@ -76,24 +98,27 @@ func init() {
rootCmd.Flags().StringP(config.SchemaKey, "s", "", "schema that should be used")
rootCmd.Flags().StringP(config.OutputFileNameKey, "o", "result.mmd", "output file name")
rootCmd.Flags().String(config.SchemaPrefixSeparator, ".", "the separator that should be used between schema and table name")
var outputMode = config.File
rootCmd.Flags().Var(&outputMode, config.OutputMode, `output mode (file, stdout)`)
rootCmd.Flags().StringSlice(config.ShowDescriptionsKey, []string{""}, "show 'notNull', 'enumValues' and/or 'columnComments' in the description column")
rootCmd.Flags().StringSlice(config.SelectedTablesKey, []string{""}, "tables to include")

bindFlagToViper(config.ShowAllConstraintsKey)
bindFlagToViper(config.UseAllTablesKey)
bindFlagToViper(config.IgnoreTables)
bindFlagToViper(config.UseAllSchemasKey)
bindFlagToViper(config.ConnectionStringKey)
bindFlagToViper(config.DebugKey)
bindFlagToViper(config.OmitConstraintLabelsKey)
bindFlagToViper(config.OmitAttributeKeysKey)
bindFlagToViper(config.EncloseWithMermaidBackticksKey)
bindFlagToViper(config.ConnectionStringKey)
bindFlagToViper(config.SchemaKey)
bindFlagToViper(config.IgnoreTables)
bindFlagToViper(config.OmitAttributeKeysKey)
bindFlagToViper(config.OmitConstraintLabelsKey)
bindFlagToViper(config.OutputFileNameKey)
bindFlagToViper(config.OutputMode)
bindFlagToViper(config.SchemaKey)
bindFlagToViper(config.SchemaPrefixSeparator)
bindFlagToViper(config.SelectedTablesKey)
bindFlagToViper(config.ShowAllConstraintsKey)
bindFlagToViper(config.ShowDescriptionsKey)
bindFlagToViper(config.ShowSchemaPrefix)
bindFlagToViper(config.SchemaPrefixSeparator)
bindFlagToViper(config.UseAllSchemasKey)
bindFlagToViper(config.UseAllTablesKey)
}

func bindFlagToViper(key string) {
Expand All @@ -102,7 +127,6 @@ func bindFlagToViper(key string) {

func initConfig() {
if runConfig != "" {
color.Blue(fmt.Sprintf("Using run configuration (from %s)", runConfig))
viper.SetConfigFile(runConfig)
} else {
home, err := os.UserHomeDir()
Expand Down
50 changes: 28 additions & 22 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,47 @@ package config
import "github.com/spf13/viper"

const (
ShowAllConstraintsKey = "showAllConstraints"
UseAllTablesKey = "useAllTables"
IgnoreTables = "ignoreTables"
SelectedTablesKey = "selectedTables"
SchemaKey = "schema"
ConnectionStringKey = "connectionString"
ConnectionStringSuggestionsKey = "connectionStringSuggestions"
OutputFileNameKey = "outputFileName"
EncloseWithMermaidBackticksKey = "encloseWithMermaidBackticks"
DebugKey = "debug"
OmitConstraintLabelsKey = "omitConstraintLabels"
EncloseWithMermaidBackticksKey = "encloseWithMermaidBackticks"
IgnoreTables = "ignoreTables"
OmitAttributeKeysKey = "omitAttributeKeys"
OmitConstraintLabelsKey = "omitConstraintLabels"
OutputFileNameKey = "outputFileName"
OutputMode = "outputMode"
RelationshipLabelsKey = "relationshipLabels"
SchemaKey = "schema"
SchemaPrefixSeparator = "schemaPrefixSeparator"
SelectedTablesKey = "selectedTables"
ShowAllConstraintsKey = "showAllConstraints"
ShowDescriptionsKey = "showDescriptions"
UseAllSchemasKey = "useAllSchemas"
ShowSchemaPrefix = "showSchemaPrefix"
SchemaPrefixSeparator = "schemaPrefixSeparator"
RelationshipLabelsKey = "relationshipLabels"
UseAllSchemasKey = "useAllSchemas"
UseAllTablesKey = "useAllTables"
)

type config struct{}

type MermerdConfig interface {
ShowAllConstraints() bool
UseAllTables() bool
IgnoreTables() []string
Schemas() []string
ConnectionString() string
OutputFileName() string
ConnectionStringSuggestions() []string
SelectedTables() []string
EncloseWithMermaidBackticks() bool
Debug() bool
OmitConstraintLabels() bool
EncloseWithMermaidBackticks() bool
IgnoreTables() []string
OmitAttributeKeys() bool
OmitConstraintLabels() bool
OutputFileName() string
OutputMode() OutputModeType
RelationshipLabels() []RelationshipLabel
SchemaPrefixSeparator() string
Schemas() []string
SelectedTables() []string
ShowAllConstraints() bool
ShowDescriptions() []string
UseAllSchemas() bool
ShowSchemaPrefix() bool
SchemaPrefixSeparator() string
RelationshipLabels() []RelationshipLabel
UseAllSchemas() bool
UseAllTables() bool
}

func NewConfig() MermerdConfig {
Expand Down Expand Up @@ -116,3 +118,7 @@ func (c config) ShowSchemaPrefix() bool {
func (c config) SchemaPrefixSeparator() string {
return viper.GetString(SchemaPrefixSeparator)
}

func (c config) OutputMode() OutputModeType {
return OutputModeType(viper.GetString(OutputMode))
}
28 changes: 28 additions & 0 deletions config/output_mode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package config

import "errors"

type OutputModeType string

const (
File OutputModeType = "file"
Stdout OutputModeType = "stdout"
)

func (o *OutputModeType) String() string {
return string(*o)
}

func (o *OutputModeType) Set(v string) error {
switch v {
case "file", "stdout":
*o = OutputModeType(v)
return nil
}

return errors.New(`must be one of "file" or "stdout"`)
}

func (o *OutputModeType) Type() string {
return "OutputModeType"
}
16 changes: 4 additions & 12 deletions diagram/diagram.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package diagram

import (
_ "embed"
"os"
"io"
"text/template"

"github.com/sirupsen/logrus"
Expand All @@ -19,22 +19,14 @@ type diagram struct {
}

type Diagram interface {
Create(result *database.Result) error
Create(wr io.Writer, result *database.Result) error
}

func NewDiagram(config config.MermerdConfig) Diagram {
return diagram{config}
}

func (d diagram) Create(result *database.Result) error {
f, err := os.Create(d.config.OutputFileName())
if err != nil {
logrus.Error("Could not create output file", " | ", err)
return err
}

defer f.Close()

func (d diagram) Create(wr io.Writer, result *database.Result) error {
tmpl, err := template.New("erd_template").Parse(erdTemplate)
if err != nil {
logrus.Error("Could not load template file", " | ", err)
Expand Down Expand Up @@ -74,7 +66,7 @@ func (d diagram) Create(result *database.Result) error {
Constraints: constraints,
}

if err = tmpl.Execute(f, diagramData); err != nil {
if err = tmpl.Execute(wr, diagramData); err != nil {
logrus.Error("Could not create diagram", " | ", err)
return err
}
Expand Down
5 changes: 3 additions & 2 deletions exampleRunConfig.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ schema:
# Define what tables should be used
#useAllTables: true
selectedTables:
- article
- label
- public.article
- public.label

# Additional flags
showAllConstraints: true
Expand All @@ -20,6 +20,7 @@ encloseWithMermaidBackticks: false
debug: false
omitConstraintLabels: false
omitAttributeKeys: false
outputMode: stdout
showDescriptions:
- enumValues
- columnComments
Expand Down
4 changes: 1 addition & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ module github.com/KarnerTh/mermerd
go 1.23

// https://github.com/microsoft/mssql-docker/issues/895#issuecomment-2327988940
godebug (
x509negativeserial=1
)
godebug x509negativeserial=1

require (
github.com/AlecAivazis/survey/v2 v2.3.7
Expand Down
Loading