-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: refactor for formatdataform cli ( beta )
- Loading branch information
0 parents
commit 2ca23db
Showing
11 changed files
with
767 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 @@ | ||
test/test_dataform/* |
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,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright © 2024 Ashish Alex ashish.alex10@gmail.com | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. |
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,114 @@ | ||
[sqlfluff] | ||
templater = placeholder | ||
dialect = bigquery | ||
output_line_length = 120 | ||
|
||
# EXCLUDED RULES | ||
# ============== | ||
# AL07 - Avoid table aliases in from clauses and join conditions. | ||
# ST06 - Select wildcards then simple targets before calculations and aggregates. | ||
# ST07 - Prefer specifying join keys instead of using USING. | ||
# AM03 - Ambiguous ordering directions for columns in order by clause. | ||
# ST04 - Dont mess up nested CASE statement | ||
# LT05 - Line is too long | ||
# AL05 - Tables should not be aliased if that alias is not used. | ||
exclude_rules = AL07, ST06, ST07, AM03, ST04, LT05, AL05 | ||
|
||
[sqlfluff:rules] | ||
allow_scalar = False | ||
|
||
[sqlfluff:indentation] | ||
tab_space_size = 2 | ||
indented_joins = False | ||
indented_using_on = True | ||
indented_then = False | ||
indented_on_contents = False | ||
allow_implicit_indents = True | ||
template_blocks_indent = True | ||
|
||
[sqlfluff:layout:type:where_clause] | ||
line_position = alone:strict | ||
|
||
[sqlfluff:layout:type:binary_operator] | ||
line_position = leading | ||
|
||
[sqlfluff:layout:type:comparison_operator] | ||
line_position = trailing | ||
|
||
[sqlfluff:layout:type:alias_expression] | ||
# We want non-default spacing _before_ the alias expressions. | ||
spacing_before = align | ||
align_within = select_clause | ||
align_scope = bracketed | ||
|
||
[sqlfluff:rules:capitalisation.keywords] | ||
# Keywords must be capitalised | ||
capitalisation_policy = upper | ||
|
||
[sqlfluff:rules:capitalisation.literals] | ||
# Null & Boolean Literals eg: NULL, TRUE, FALSE | ||
capitalisation_policy = upper | ||
|
||
[sqlfluff:rules:capitalisation.types] | ||
# Data Types eg: INT, STR | ||
extended_capitalisation_policy = upper | ||
|
||
[sqlfluff:rules:capitalisation.identifiers] | ||
# Unquoted identifiers | ||
extended_capitalisation_policy = upper | ||
unquoted_identifiers_policy=all | ||
|
||
[sqlfluff:rules:capitalisation.functions] | ||
# Function names | ||
capitalisation_policy = upper | ||
extended_capitalisation_policy = upper | ||
|
||
[sqlfluff:rules:ambiguous.join] | ||
# Fully qualify JOIN clause | ||
fully_qualify_join_types = inner | ||
|
||
[sqlfluff:rules:aliasing.length] | ||
# Minimum string length when creating an alias | ||
min_alias_length = 3 | ||
|
||
[sqlfluff:rules:aliasing.table] | ||
# Aliasing preference for tables, ie needs an AS | ||
aliasing = explicit | ||
|
||
[sqlfluff:rules:aliasing.column] | ||
# Aliasing preference for columns, ie needs an AS | ||
aliasing = explicit | ||
|
||
[sqlfluff:rules:layout.commas] | ||
# Leading or trailing commas | ||
line_position = leading | ||
|
||
[sqlfluff:layout:type:comma] | ||
line_position = leading | ||
|
||
|
||
[sqlfluff:rules:convention.select_trailing_comma] | ||
# No trailing comma at end of SELECT, ie before FROM (after last column name) | ||
select_clause_trailing_comma = forbid | ||
|
||
[sqlfluff:rules:ambiguous.column_references] | ||
# GROUP BY/ORDER BY column references (i.e. implicit by position or explicit by name) | ||
group_by_and_order_by_style = explicit | ||
|
||
[sqlfluff:rules:references.special_chars] | ||
# Special characters in identifiers | ||
unquoted_identifiers_policy = all | ||
quoted_identifiers_policy = all | ||
allow_space_in_identifier = False | ||
additional_allowed_characters = ["", $] | ||
|
||
[sqlfluff:rules:references.keywords] | ||
# Keywords should not be used as identifiers. | ||
unquoted_identifiers_policy = all | ||
quoted_identifiers_policy = none | ||
|
||
|
||
|
||
[sqlfluff:templater:placeholder] | ||
param_regex = \${ref\(\"\d*(?P<param_name>[\w]+)"\)\}|\${(?P<param_name>[^\s]+)} | ||
|
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,132 @@ | ||
/* | ||
Copyright © 2024 NAME HERE <EMAIL ADDRESS> | ||
*/ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"log/slog" | ||
"os" | ||
"path/filepath" | ||
"sync" | ||
|
||
"github.com/fatih/color" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// formatCmd represents the format command | ||
var formatCmd = &cobra.Command{ | ||
Use: "format", | ||
Short: "formats a file a directory depending on the next argument", | ||
Long: `formats a file a directory depending on the next argument | ||
To format a file: formatdataform format path/to/file.sqlx | ||
To format a directory: formatdataform format /dir/to/format | ||
`, | ||
Run: func(cmd *cobra.Command, args []string) { | ||
|
||
inplace, _ := cmd.Flags().GetBool("inplace") | ||
sqlfluffConfigPath := cmd.Flag("sqlfluff_config_path").Value.String() | ||
|
||
|
||
// make sure the .formatdataform directory exists if not create it | ||
os.Mkdir(".formatdataform", 0755) | ||
logFile, err := os.OpenFile(".formatdataform/formatdataform_logs.json", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) | ||
if err != nil { | ||
log.Fatalf("error opening file: %v", err) | ||
} | ||
defer logFile.Close() | ||
|
||
logger := slog.New(slog.NewJSONHandler(logFile, nil)) | ||
|
||
logger.Info("Formatting config", | ||
slog.String("sqlfluffConfigPath", sqlfluffConfigPath), | ||
slog.Bool("inplace", inplace), | ||
) | ||
|
||
|
||
green := color.New(color.FgGreen).SprintFunc() | ||
yellow := color.New(color.FgYellow).SprintFunc() | ||
red := color.New(color.FgRed).SprintFunc() | ||
|
||
if sqlfluffConfigPath == ""{ | ||
fmt.Printf(red("sqlfluff config file path is required \n")) | ||
return | ||
} | ||
|
||
if fileExists(sqlfluffConfigPath) == false { | ||
fmt.Printf(red("sqlfluff config file does not exist at: %v \n"), sqlfluffConfigPath) | ||
return | ||
} | ||
|
||
if fileExists(".formatdataform/sqlfluff_formatter.py") == false { | ||
fmt.Print(yellow("sqlfluff_formatter.py file does not exist at: ", ".formatdataform/sqlfluff_formatter.py. Run: ")) | ||
fmt.Printf("formatdataform setup \n") | ||
return | ||
} | ||
|
||
// If not file or directory path is supplied | ||
if len(args) == 0 { | ||
log.Fatalf(yellow(`No file or directory path supplied to command: `, red(` formatdataform format <path> | ||
^^^^^`))) | ||
return | ||
} | ||
|
||
// If more than one file or directory path is supplied | ||
// TODO: Add support for multiple files or directories | ||
if len(args) > 1 { | ||
color.Set(color.FgYellow) | ||
fmt.Printf("Only supports one file or directory path at a time, you passed %v \n", len(args)) | ||
color.Unset() | ||
return | ||
} | ||
|
||
fileOrDirPath := args[0] | ||
|
||
fileInfo, err := os.Stat(fileOrDirPath) | ||
if err != nil { | ||
log.Fatalf("Error opening file: %v", err) | ||
return | ||
} | ||
|
||
if fileInfo.IsDir() { | ||
fmt.Println("Directory to format: ", green(fileOrDirPath)) | ||
var sqlxFiles = findSqlxFiles(fileOrDirPath) // TODO: specify directory and depth to search for sql files here ? | ||
fmt.Println("Number of sqlx files found: ", green(len(*sqlxFiles))+"\n") | ||
|
||
if len(*sqlxFiles) == 0 { | ||
fmt.Println("No .sqlx files found in the directory: ", yellow(fileOrDirPath)) | ||
return | ||
} | ||
|
||
var wg sync.WaitGroup | ||
for i := 0; i < len(*sqlxFiles); i++ { | ||
wg.Add(1) | ||
go func(i int) { | ||
defer wg.Done() | ||
formatSqlxFile((*sqlxFiles)[i], inplace, sqlfluffConfigPath, logger) | ||
}(i) | ||
} | ||
wg.Wait() | ||
|
||
} else if !fileInfo.IsDir() { | ||
fmt.Println("File to format: ", green(fileOrDirPath)) | ||
if filepath.Ext(fileOrDirPath) != ".sqlx" { | ||
fmt.Printf(red("Only .sqlx files are supported for formatting \n")) | ||
return | ||
} | ||
formatSqlxFile(fileOrDirPath, inplace, sqlfluffConfigPath, logger) | ||
} else { | ||
cmd.Help() | ||
} | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(formatCmd) | ||
|
||
formatCmd.Flags().StringP("file", "f", "", "file to format") | ||
formatCmd.Flags().StringP("dir", "d", "", "directory to format") | ||
formatCmd.Flags().BoolP("inplace", "i", true, "format the file in place") | ||
|
||
} |
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,67 @@ | ||
/* | ||
Copyright © 2024 Ashish Alex ashish.alex10@gmail.com | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
*/ | ||
package cmd | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/spf13/cobra" | ||
) | ||
|
||
var sqlfluffConfigPath string | ||
|
||
|
||
|
||
// rootCmd represents the base command when called without any subcommands | ||
var rootCmd = &cobra.Command{ | ||
Use: "formatdataform", | ||
Short: "Format .sqlx files", | ||
Long: ``, | ||
// Uncomment the following line if your bare application | ||
// has an action associated with it: | ||
//TODO: might add version information here | ||
// Run: func(cmd *cobra.Command, args []string) { }, | ||
} | ||
|
||
// Execute adds all child commands to the root command and sets flags appropriately. | ||
// This is called by main.main(). It only needs to happen once to the rootCmd. | ||
func Execute() { | ||
err := rootCmd.Execute() | ||
if err != nil { | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func init() { | ||
// Here you will define your flags and configuration settings. | ||
// Cobra supports persistent flags, which, if defined here, | ||
// will be global for your application. | ||
|
||
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.formatdataform.yaml)") | ||
|
||
rootCmd.PersistentFlags().StringP("sqlfluff_config_path", "c", "", "Path to the sqlfluff config file") | ||
// Cobra also supports local flags, which will only run | ||
// when this action is called directly. | ||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") | ||
} | ||
|
||
|
Oops, something went wrong.