55namespace Flow \Bridge \Symfony \PostgreSqlBundle \Command ;
66
77use function Flow \Filesystem \DSL \{native_local_filesystem , path };
8- use function Flow \PostgreSql \DSL \sql_format ;
9- use function Flow \Types \DSL \type_string ;
8+ use function Flow \PostgreSql \DSL \{sql_deparse_options , sql_format };
9+ use function Flow \Types \DSL \{type_boolean , type_integer , type_string };
10+ use Flow \Bridge \Symfony \PostgreSqlBundle \Sql \SqlFileFinder ;
1011use Flow \Filesystem \Local \NativeLocalFilesystem ;
11- use Flow \Filesystem \ Path as FsPath ;
12+ use Flow \PostgreSql \ DeparseOptions ;
1213use Symfony \Component \Console \Attribute \AsCommand ;
1314use Symfony \Component \Console \Command \Command ;
1415use Symfony \Component \Console \Input \{InputArgument , InputInterface , InputOption };
@@ -31,28 +32,35 @@ protected function configure() : void
3132 ->addArgument ('sql ' , InputArgument::OPTIONAL , 'Raw SQL string to format. Ignored when --path is used. ' )
3233 ->addOption ('path ' , 'p ' , InputOption::VALUE_REQUIRED , 'Path, directory or glob pattern (only files with .sql extension are processed) ' )
3334 ->addOption ('write ' , 'w ' , InputOption::VALUE_NONE , 'Write formatted SQL back to source files instead of printing to stdout ' )
34- ->addOption ('check ' , null , InputOption::VALUE_NONE , 'Exit with non-zero status when any input is not already formatted (does not modify files) ' );
35+ ->addOption ('check ' , null , InputOption::VALUE_NONE , 'Exit with non-zero status when any input is not already formatted (does not modify files) ' )
36+ ->addOption ('indent-size ' , null , InputOption::VALUE_REQUIRED , 'Number of spaces used for indentation ' , 4 )
37+ ->addOption ('max-line-length ' , null , InputOption::VALUE_REQUIRED , 'Maximum line length before wrapping ' , 80 )
38+ ->addOption ('no-pretty-print ' , null , InputOption::VALUE_NONE , 'Disable pretty-printing (output single-line SQL) ' )
39+ ->addOption ('commas-start-of-line ' , null , InputOption::VALUE_NONE , 'Place commas at the start of the line instead of the end ' )
40+ ->addOption ('trailing-newline ' , null , InputOption::VALUE_NONE , 'Append a trailing newline to formatted SQL ' );
3541 }
3642
3743 protected function execute (InputInterface $ input , OutputInterface $ output ) : int
3844 {
3945 $ pathOption = $ input ->getOption ('path ' );
4046 $ sqlArgument = $ input ->getArgument ('sql ' );
41- $ write = ( bool ) $ input ->getOption ('write ' );
42- $ check = ( bool ) $ input ->getOption ('check ' );
47+ $ write = type_boolean ()-> cast ( $ input ->getOption ('write ' ) );
48+ $ check = type_boolean ()-> cast ( $ input ->getOption ('check ' ) );
4349
4450 if ($ pathOption === null && $ sqlArgument === null ) {
4551 $ output ->writeln ('<error>Either a SQL string argument or --path option must be provided.</error> ' );
4652
4753 return Command::FAILURE ;
4854 }
4955
56+ $ options = $ this ->buildDeparseOptions ($ input );
57+
5058 if ($ pathOption !== null ) {
51- return $ this ->formatPath (type_string ()->assert ($ pathOption ), $ write , $ check , $ output );
59+ return $ this ->formatPath (type_string ()->assert ($ pathOption ), $ write , $ check , $ output, $ options );
5260 }
5361
5462 $ sql = type_string ()->assert ($ sqlArgument );
55- $ formatted = sql_format ($ sql );
63+ $ formatted = sql_format ($ sql, $ options );
5664
5765 if ($ check ) {
5866 if (\trim ($ formatted ) !== \trim ($ sql )) {
@@ -71,37 +79,19 @@ protected function execute(InputInterface $input, OutputInterface $output) : int
7179 return Command::SUCCESS ;
7280 }
7381
74- /**
75- * @return list<FsPath>
76- */
77- private function collectSqlFiles (FsPath $ path ) : array
82+ private function buildDeparseOptions (InputInterface $ input ) : DeparseOptions
7883 {
79- $ status = $ this ->filesystem ->status ($ path );
80-
81- if ($ status !== null && $ status ->isDirectory ()) {
82- $ path = path (\rtrim ($ path ->path (), '/ ' ) . '/**/*.sql ' , $ path ->options ());
83- }
84-
85- $ files = [];
86-
87- foreach ($ this ->filesystem ->list ($ path ) as $ file ) {
88- if (!$ file ->isFile ()) {
89- continue ;
90- }
91-
92- if ($ file ->path ->extension () !== 'sql ' ) {
93- continue ;
94- }
95-
96- $ files [] = $ file ->path ;
97- }
98-
99- return $ files ;
84+ return sql_deparse_options ()
85+ ->indentSize (type_integer ()->cast ($ input ->getOption ('indent-size ' )))
86+ ->maxLineLength (type_integer ()->cast ($ input ->getOption ('max-line-length ' )))
87+ ->prettyPrint (!type_boolean ()->cast ($ input ->getOption ('no-pretty-print ' )))
88+ ->commasStartOfLine (type_boolean ()->cast ($ input ->getOption ('commas-start-of-line ' )))
89+ ->trailingNewline (type_boolean ()->cast ($ input ->getOption ('trailing-newline ' )));
10090 }
10191
102- private function formatPath (string $ pathString , bool $ write , bool $ check , OutputInterface $ output ) : int
92+ private function formatPath (string $ pathString , bool $ write , bool $ check , OutputInterface $ output, DeparseOptions $ options ) : int
10393 {
104- $ files = $ this -> collectSqlFiles (path ($ pathString ));
94+ $ files = ( new SqlFileFinder ( native_local_filesystem ()))-> find (path ($ pathString ));
10595
10696 if ($ files === []) {
10797 $ output ->writeln (\sprintf ('<comment>No .sql files found at: %s</comment> ' , $ pathString ));
@@ -116,7 +106,7 @@ private function formatPath(string $pathString, bool $write, bool $check, Output
116106 $ original = $ this ->filesystem ->readFrom ($ file )->content ();
117107
118108 try {
119- $ formatted = sql_format ($ original );
109+ $ formatted = sql_format ($ original, $ options );
120110 } catch (\Throwable $ e ) {
121111 $ output ->writeln (\sprintf ('<error>Failed to format %s: %s</error> ' , $ file ->path (), $ e ->getMessage ()));
122112
0 commit comments