feat(main): add silent mode to suppress output messages
* implement --silent flag to control output verbosity * update error handling to restore stderr after silent mode * enhance progress reporting in PostgreSQL reader
This commit is contained in:
+8
-8
@@ -229,43 +229,43 @@ func readDatabase(dbType, filePath, connString, label string) (*models.Database,
|
||||
if filePath == "" {
|
||||
return nil, fmt.Errorf("%s: file path is required for DBML format", label)
|
||||
}
|
||||
reader = dbml.NewReader(&readers.ReaderOptions{FilePath: filePath})
|
||||
reader = dbml.NewReader(newReaderOptions(filePath, ""))
|
||||
|
||||
case "dctx":
|
||||
if filePath == "" {
|
||||
return nil, fmt.Errorf("%s: file path is required for DCTX format", label)
|
||||
}
|
||||
reader = dctx.NewReader(&readers.ReaderOptions{FilePath: filePath})
|
||||
reader = dctx.NewReader(newReaderOptions(filePath, ""))
|
||||
|
||||
case "drawdb":
|
||||
if filePath == "" {
|
||||
return nil, fmt.Errorf("%s: file path is required for DrawDB format", label)
|
||||
}
|
||||
reader = drawdb.NewReader(&readers.ReaderOptions{FilePath: filePath})
|
||||
reader = drawdb.NewReader(newReaderOptions(filePath, ""))
|
||||
|
||||
case "json":
|
||||
if filePath == "" {
|
||||
return nil, fmt.Errorf("%s: file path is required for JSON format", label)
|
||||
}
|
||||
reader = json.NewReader(&readers.ReaderOptions{FilePath: filePath})
|
||||
reader = json.NewReader(newReaderOptions(filePath, ""))
|
||||
|
||||
case "yaml":
|
||||
if filePath == "" {
|
||||
return nil, fmt.Errorf("%s: file path is required for YAML format", label)
|
||||
}
|
||||
reader = yaml.NewReader(&readers.ReaderOptions{FilePath: filePath})
|
||||
reader = yaml.NewReader(newReaderOptions(filePath, ""))
|
||||
|
||||
case "sqldir", "scripts", "scriptdir":
|
||||
if filePath == "" {
|
||||
return nil, fmt.Errorf("%s: file path is required for SQL directory format", label)
|
||||
}
|
||||
reader = sqldir.NewReader(&readers.ReaderOptions{FilePath: filePath})
|
||||
reader = sqldir.NewReader(newReaderOptions(filePath, ""))
|
||||
|
||||
case "pgsql", "postgres", "postgresql":
|
||||
if connString == "" {
|
||||
return nil, fmt.Errorf("%s: connection string is required for PostgreSQL format", label)
|
||||
}
|
||||
reader = pgsql.NewReader(&readers.ReaderOptions{ConnectionString: connString})
|
||||
reader = pgsql.NewReader(newReaderOptions("", connString))
|
||||
|
||||
case "sqlite", "sqlite3":
|
||||
// SQLite can use either file path or connection string
|
||||
@@ -276,7 +276,7 @@ func readDatabase(dbType, filePath, connString, label string) (*models.Database,
|
||||
if dbPath == "" {
|
||||
return nil, fmt.Errorf("%s: file path or connection string is required for SQLite format", label)
|
||||
}
|
||||
reader = sqlite.NewReader(&readers.ReaderOptions{FilePath: dbPath})
|
||||
reader = sqlite.NewReader(newReaderOptions(dbPath, ""))
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("%s: unsupported database format: %s", label, dbType)
|
||||
|
||||
+33
-2
@@ -6,9 +6,40 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
printVersionHeader(os.Args[1:])
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
args := os.Args[1:]
|
||||
isSilent := hasSilentFlag(args)
|
||||
if !isSilent {
|
||||
printVersionHeader(args)
|
||||
}
|
||||
|
||||
previousStderr := os.Stderr
|
||||
var nullOutput *os.File
|
||||
if isSilent {
|
||||
var err error
|
||||
nullOutput, err = os.OpenFile(os.DevNull, os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
fmt.Fprintln(previousStderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Stderr = nullOutput
|
||||
}
|
||||
|
||||
err := rootCmd.Execute()
|
||||
if nullOutput != nil {
|
||||
os.Stderr = previousStderr
|
||||
nullOutput.Close()
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func hasSilentFlag(args []string) bool {
|
||||
for _, arg := range args {
|
||||
if arg == "--silent" || arg == "--silent=true" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ func runMerge(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
// Step 1: Read target database
|
||||
fmt.Fprintf(os.Stderr, "[1/3] Reading target database...\n")
|
||||
fmt.Fprintf(os.Stderr, "[1/4] Reading target database...\n")
|
||||
fmt.Fprintf(os.Stderr, " Format: %s\n", mergeTargetType)
|
||||
if mergeTargetPath != "" {
|
||||
fmt.Fprintf(os.Stderr, " Path: %s\n", mergeTargetPath)
|
||||
@@ -195,7 +195,7 @@ func runMerge(cmd *cobra.Command, args []string) error {
|
||||
printDatabaseStats(targetDB)
|
||||
|
||||
// Step 2: Read source database(s)
|
||||
fmt.Fprintf(os.Stderr, "\n[2/3] Reading source database...\n")
|
||||
fmt.Fprintf(os.Stderr, "\n[2/4] Reading source database...\n")
|
||||
fmt.Fprintf(os.Stderr, " Format: %s\n", mergeSourceType)
|
||||
|
||||
var sourceDB *models.Database
|
||||
@@ -229,7 +229,7 @@ func runMerge(cmd *cobra.Command, args []string) error {
|
||||
printDatabaseStats(sourceDB)
|
||||
|
||||
// Step 3: Merge databases
|
||||
fmt.Fprintf(os.Stderr, "\n[3/3] Merging databases...\n")
|
||||
fmt.Fprintf(os.Stderr, "\n[3/4] Merging databases...\n")
|
||||
|
||||
opts := &merge.MergeOptions{
|
||||
SkipDomains: mergeSkipDomains,
|
||||
@@ -267,6 +267,9 @@ func runMerge(cmd *cobra.Command, args []string) error {
|
||||
if mergeOutputPath != "" {
|
||||
fmt.Fprintf(os.Stderr, " Path: %s\n", mergeOutputPath)
|
||||
}
|
||||
if mergeOutputConn != "" {
|
||||
fmt.Fprintf(os.Stderr, " Conn: %s\n", maskPassword(mergeOutputConn))
|
||||
}
|
||||
|
||||
err = writeDatabaseForMerge(mergeOutputType, mergeOutputPath, mergeOutputConn, targetDB, "Output", mergeFlattenSchema)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/readers"
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/writers"
|
||||
)
|
||||
@@ -11,6 +14,9 @@ func newReaderOptions(filePath, connString string) *readers.ReaderOptions {
|
||||
ConnectionString: connString,
|
||||
Prisma7: prisma7,
|
||||
StrictDirectives: strictDirectives,
|
||||
Progress: func(message string) {
|
||||
fmt.Fprintf(os.Stderr, " → %s\n", message)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ var (
|
||||
buildDate = "unknown"
|
||||
prisma7 bool
|
||||
noVersion bool
|
||||
silent bool
|
||||
strictDirectives bool
|
||||
)
|
||||
|
||||
@@ -73,6 +74,7 @@ func init() {
|
||||
rootCmd.AddCommand(reportCmd)
|
||||
rootCmd.PersistentFlags().BoolVar(&prisma7, "prisma7", false, "Use Prisma 7 generator conventions when reading/writing Prisma schemas")
|
||||
rootCmd.PersistentFlags().BoolVar(&noVersion, "no-version", false, "Suppress the RelSpec version header")
|
||||
rootCmd.PersistentFlags().BoolVar(&silent, "silent", false, "Suppress progress and status messages (errors are still shown)")
|
||||
rootCmd.PersistentFlags().BoolVar(&strictDirectives, "strict-directives", false, "Fail on unknown or untranslatable DBML dialect directives (@postgres:, @sqlite:, …)")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user