Skip to content

feat: #148 adding go script and makefile commands #202

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: code_gen format go_lint go_lint_fix go_mod_tidy lint sqlc sql_lint sql_lint_fix vendor
.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

code_gen: go_mod_tidy sqlc

Expand Down Expand Up @@ -27,3 +27,9 @@ sql_lint_fix:
vendor:
go mod vendor

sql_whitespace_dry_run:
go run ./scripts/acceptance_test_sql_linter/main.go

sql_whitespace_fix:
go run ./scripts/acceptance_test_sql_linter/main.go --fix

167 changes: 167 additions & 0 deletions scripts/acceptance_test_sql_linter/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
package main

import (
"bufio"
"fmt"
"os"
"path/filepath"
"strings"

"github.com/spf13/cobra"
)

var (
dirPath string
fixMode bool
)

func main() {
var rootCmd = &cobra.Command{
Use: "replace-spaces",
Short: "Replace tabs with spaces in SQL strings within files",
Long: `This tool replaces tab characters with four spaces in SQL strings across files in a specified directory.`,
Run: func(cmd *cobra.Command, args []string) {
replaceSpaces()
},
}

rootCmd.Flags().StringVarP(&dirPath, "dir", "d", "./internal/migration_acceptance_tests", "Directory path containing files to process")
rootCmd.Flags().BoolVar(&fixMode, "fix", false, "Apply changes (without this flag, only shows what would change)")

if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

func replaceSpaces() {
files, err := os.ReadDir(dirPath)
if err != nil {
fmt.Printf("Error reading directory: %v\n", err)
return
}

if !fixMode {
fmt.Println("Running in dry-run mode. Use --fix to apply changes.")
}

for _, file := range files {
if file.IsDir() {
continue
}

filePath := filepath.Join(dirPath, file.Name())
needsChanges, err := checkFileNeedsChanges(filePath)

if err != nil {
fmt.Printf("Error checking file %s: %v\n", filePath, err)
continue
}

if needsChanges {
if fixMode {
if err := processFile(filePath); err != nil {
fmt.Printf("Error processing file %s: %v\n", filePath, err)
} else {
fmt.Printf("Updated file: %s\n", filePath)
}
} else {
fmt.Printf("Would update file: %s\n", filePath)
}
}
}
}

// Check if the file would need changes without modifying it
func checkFileNeedsChanges(filePath string) (bool, error) {
srcFile, err := os.Open(filePath)
if err != nil {
return false, fmt.Errorf("failed to open source file: %w", err)
}
defer srcFile.Close()

scanner := bufio.NewScanner(srcFile)
inSQLString := false
needsChanges := false

for scanner.Scan() {
line := scanner.Text()

if inSQLString && !strings.Contains(line, "`") && strings.Contains(line, "\t") {
// Found a line that needs changes
needsChanges = true
break
}

// Toggle SQL string flag if line contains backtick
if strings.Contains(line, "`") {
inSQLString = !inSQLString
}
}

if err := scanner.Err(); err != nil {
return false, fmt.Errorf("error reading source file: %w", err)
}

return needsChanges, nil
}

func processFile(filePath string) error {
// Create a temporary file
tempFile, err := os.CreateTemp(filepath.Dir(filePath), "temp_*")
if err != nil {
return fmt.Errorf("failed to create temp file: %w", err)
}
tempFilePath := tempFile.Name()
defer os.Remove(tempFilePath) // Clean up in case of failure

// Open source file for reading
srcFile, err := os.Open(filePath)
if err != nil {
tempFile.Close()
return fmt.Errorf("failed to open source file: %w", err)
}
defer srcFile.Close()

// Process the file
inSQLString := false
scanner := bufio.NewScanner(srcFile)
writer := bufio.NewWriter(tempFile)

for scanner.Scan() {
line := scanner.Text()

if inSQLString && !strings.Contains(line, "`") {
// Replace tabs with spaces in SQL strings
newLine := strings.ReplaceAll(line, "\t", " ")
_, err = writer.WriteString(newLine + "\n")
} else {
_, err = writer.WriteString(line + "\n")
}

if err != nil {
tempFile.Close()
return fmt.Errorf("failed to write to temp file: %w", err)
}

// Toggle SQL string flag if line contains backtick
if strings.Contains(line, "`") {
inSQLString = !inSQLString
}
}

if err := scanner.Err(); err != nil {
tempFile.Close()
return fmt.Errorf("error reading source file: %w", err)
}

// Ensure all buffered data is written
if err := writer.Flush(); err != nil {
tempFile.Close()
return fmt.Errorf("failed to flush buffer: %w", err)
}
tempFile.Close()

// Replace the original file with the temporary file
return os.Rename(tempFilePath, filePath)
}