Skip to content

Commit e112755

Browse files
authored
feat: #148 adding go script and makefile commands (#202)
1 parent cd8f79a commit e112755

File tree

2 files changed

+174
-1
lines changed

2 files changed

+174
-1
lines changed

Makefile

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.PHONY: code_gen format go_lint go_lint_fix go_mod_tidy lint sqlc sql_lint sql_lint_fix vendor
1+
.PHONY: code_gen format go_lint go_lint_fix go_mod_tidy lint sqlc sql_lint sql_lint_fix vendor sql_whitespace_dry_run sql_whitespace_fix
22

33
code_gen: go_mod_tidy sqlc
44

@@ -27,3 +27,9 @@ sql_lint_fix:
2727
vendor:
2828
go mod vendor
2929

30+
sql_whitespace_dry_run:
31+
go run ./scripts/acceptance_test_sql_linter/main.go
32+
33+
sql_whitespace_fix:
34+
go run ./scripts/acceptance_test_sql_linter/main.go --fix
35+
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"os"
7+
"path/filepath"
8+
"strings"
9+
10+
"github.com/spf13/cobra"
11+
)
12+
13+
var (
14+
dirPath string
15+
fixMode bool
16+
)
17+
18+
func main() {
19+
var rootCmd = &cobra.Command{
20+
Use: "replace-spaces",
21+
Short: "Replace tabs with spaces in SQL strings within files",
22+
Long: `This tool replaces tab characters with four spaces in SQL strings across files in a specified directory.`,
23+
Run: func(cmd *cobra.Command, args []string) {
24+
replaceSpaces()
25+
},
26+
}
27+
28+
rootCmd.Flags().StringVarP(&dirPath, "dir", "d", "./internal/migration_acceptance_tests", "Directory path containing files to process")
29+
rootCmd.Flags().BoolVar(&fixMode, "fix", false, "Apply changes (without this flag, only shows what would change)")
30+
31+
if err := rootCmd.Execute(); err != nil {
32+
fmt.Println(err)
33+
os.Exit(1)
34+
}
35+
}
36+
37+
func replaceSpaces() {
38+
files, err := os.ReadDir(dirPath)
39+
if err != nil {
40+
fmt.Printf("Error reading directory: %v\n", err)
41+
return
42+
}
43+
44+
if !fixMode {
45+
fmt.Println("Running in dry-run mode. Use --fix to apply changes.")
46+
}
47+
48+
for _, file := range files {
49+
if file.IsDir() {
50+
continue
51+
}
52+
53+
filePath := filepath.Join(dirPath, file.Name())
54+
needsChanges, err := checkFileNeedsChanges(filePath)
55+
56+
if err != nil {
57+
fmt.Printf("Error checking file %s: %v\n", filePath, err)
58+
continue
59+
}
60+
61+
if needsChanges {
62+
if fixMode {
63+
if err := processFile(filePath); err != nil {
64+
fmt.Printf("Error processing file %s: %v\n", filePath, err)
65+
} else {
66+
fmt.Printf("Updated file: %s\n", filePath)
67+
}
68+
} else {
69+
fmt.Printf("Would update file: %s\n", filePath)
70+
}
71+
}
72+
}
73+
}
74+
75+
// Check if the file would need changes without modifying it
76+
func checkFileNeedsChanges(filePath string) (bool, error) {
77+
srcFile, err := os.Open(filePath)
78+
if err != nil {
79+
return false, fmt.Errorf("failed to open source file: %w", err)
80+
}
81+
defer srcFile.Close()
82+
83+
scanner := bufio.NewScanner(srcFile)
84+
inSQLString := false
85+
needsChanges := false
86+
87+
for scanner.Scan() {
88+
line := scanner.Text()
89+
90+
if inSQLString && !strings.Contains(line, "`") && strings.Contains(line, "\t") {
91+
// Found a line that needs changes
92+
needsChanges = true
93+
break
94+
}
95+
96+
// Toggle SQL string flag if line contains backtick
97+
if strings.Contains(line, "`") {
98+
inSQLString = !inSQLString
99+
}
100+
}
101+
102+
if err := scanner.Err(); err != nil {
103+
return false, fmt.Errorf("error reading source file: %w", err)
104+
}
105+
106+
return needsChanges, nil
107+
}
108+
109+
func processFile(filePath string) error {
110+
// Create a temporary file
111+
tempFile, err := os.CreateTemp(filepath.Dir(filePath), "temp_*")
112+
if err != nil {
113+
return fmt.Errorf("failed to create temp file: %w", err)
114+
}
115+
tempFilePath := tempFile.Name()
116+
defer os.Remove(tempFilePath) // Clean up in case of failure
117+
118+
// Open source file for reading
119+
srcFile, err := os.Open(filePath)
120+
if err != nil {
121+
tempFile.Close()
122+
return fmt.Errorf("failed to open source file: %w", err)
123+
}
124+
defer srcFile.Close()
125+
126+
// Process the file
127+
inSQLString := false
128+
scanner := bufio.NewScanner(srcFile)
129+
writer := bufio.NewWriter(tempFile)
130+
131+
for scanner.Scan() {
132+
line := scanner.Text()
133+
134+
if inSQLString && !strings.Contains(line, "`") {
135+
// Replace tabs with spaces in SQL strings
136+
newLine := strings.ReplaceAll(line, "\t", " ")
137+
_, err = writer.WriteString(newLine + "\n")
138+
} else {
139+
_, err = writer.WriteString(line + "\n")
140+
}
141+
142+
if err != nil {
143+
tempFile.Close()
144+
return fmt.Errorf("failed to write to temp file: %w", err)
145+
}
146+
147+
// Toggle SQL string flag if line contains backtick
148+
if strings.Contains(line, "`") {
149+
inSQLString = !inSQLString
150+
}
151+
}
152+
153+
if err := scanner.Err(); err != nil {
154+
tempFile.Close()
155+
return fmt.Errorf("error reading source file: %w", err)
156+
}
157+
158+
// Ensure all buffered data is written
159+
if err := writer.Flush(); err != nil {
160+
tempFile.Close()
161+
return fmt.Errorf("failed to flush buffer: %w", err)
162+
}
163+
tempFile.Close()
164+
165+
// Replace the original file with the temporary file
166+
return os.Rename(tempFilePath, filePath)
167+
}

0 commit comments

Comments
 (0)