Skip to content
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

Add labels option for single file #23

Merged
merged 11 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
153 changes: 87 additions & 66 deletions cmd/tgcom/main.go
Original file line number Diff line number Diff line change
@@ -1,66 +1,87 @@
package main

import (
"flag"
"fmt"
"strings"

"github.com/dyne/tgcom/internal/comment"
"github.com/dyne/tgcom/internal/file"
)

func main() {
fileFlag := flag.String("file", "", "The file to process")
lineFlag := flag.String("line", "", "The line number or range to modify (e.g., 4 or 10-20)")
actionFlag := flag.String("action", "", "can be comment, uncomment or toggle")
dryRunFlag := flag.Bool("dry-run", false, "Perform a dry run without modifying the files")

flag.Parse()

filename := *fileFlag
lineStr := *lineFlag
action := *actionFlag
dryRun := *dryRunFlag
var modFunc func(string, string) string

switch action {
case "comment":
modFunc = comment.Comment
case "uncomment":
modFunc = comment.Uncomment
case "toggle":
modFunc = comment.ToggleComments
case "":
// If no action provided, assume toggle
modFunc = comment.ToggleComments
default:
fmt.Println("Invalid action. Please provide 'comment', 'uncomment', or 'toggle'.")
flag.PrintDefaults()
return
}

if filename == "" {
fmt.Println("Please provide a filename to process.")
flag.PrintDefaults()
return
}

if strings.Contains(filename, ",") {
if err := file.ProcessMultipleFiles(filename, dryRun); err != nil {
fmt.Println("Error processing files:", err)
}
} else {
if strings.Contains(filename, ":") {
parts := strings.Split(filename, ":")
if len(parts) != 2 {
fmt.Println("Invalid syntax format. Use '<filename>:<lines>'")
return
}
filename = parts[0]
lineStr = parts[1]
}
if err := file.ProcessSingleFile(filename, lineStr, modFunc, dryRun); err != nil {
fmt.Println("Error processing file:", err)
}
}
}
package main

import (
"flag"
"fmt"
"strings"

"github.com/dyne/tgcom/internal/comment"
"github.com/dyne/tgcom/internal/file"
)

func main() {
fileFlag := flag.String("file", "", "The file to process")
lineFlag := flag.String("line", "", "The line number or range to modify (e.g., 4 or 10-20)")
startLabelFlag := flag.String("start-label", "", "The start label for a section")
endLabelFlag := flag.String("end-label", "", "The end label for a section")
actionFlag := flag.String("action", "", "can be comment, uncomment or toggle")
dryRunFlag := flag.Bool("dry-run", false, "Perform a dry run without modifying the files")

flag.Parse()

filename := *fileFlag
lineStr := *lineFlag
startLabel := *startLabelFlag
endLabel := *endLabelFlag
action := *actionFlag
dryRun := *dryRunFlag
var modFunc func(string, string) string

switch action {
case "comment":
modFunc = comment.Comment
case "uncomment":
modFunc = comment.Uncomment
case "toggle":
modFunc = comment.ToggleComments
case "":
// If no action provided, assume toggle
modFunc = comment.ToggleComments
default:
fmt.Println("Invalid action. Please provide 'comment', 'uncomment', or 'toggle'.")
flag.PrintDefaults()
return
}

if filename == "" {
fmt.Println("Please provide a filename to process.")
flag.PrintDefaults()
return
}

if startLabel == "" && endLabel != "" {
fmt.Println("Error: 'startLabel' is required when 'endLabel' is provided.")
return
} else if startLabel != "" && endLabel == "" {
fmt.Println("Error: 'endLabel' is required when 'startLabel' is provided.")
return
}

if startLabel != "" && lineStr != "" {
fmt.Println("Error: only line OR label flags are allowed not both")
}

if startLabel != "" && lineStr != "" {
fmt.Println("Error: Specify either line number/range OR label, not both.")
return
}

if strings.Contains(filename, ",") {
if err := file.ProcessMultipleFiles(filename, dryRun); err != nil {
fmt.Println("Error processing files:", err)
}
} else {
if strings.Contains(filename, ":") {
parts := strings.Split(filename, ":")
if len(parts) != 2 {
fmt.Println("Invalid syntax format. Use '<filename>:<lines>'")
return
}
filename = parts[0]
lineStr = parts[1]
}
if err := file.ProcessSingleFile(filename, lineStr, startLabel, endLabel, modFunc, dryRun); err != nil {
fmt.Println("Error processing file:", err)
}
}
}
4 changes: 2 additions & 2 deletions internal/comment/comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ func Uncomment(line string, commentChars string) string {
trimmedLine := strings.TrimSpace(line)
if strings.HasPrefix(trimmedLine, commentChars) {
// Check for both `//` and `// ` prefixes.
if strings.HasPrefix(trimmedLine, commentChars + " ") {
return strings.Replace(line, commentChars + " ", "", 1)
if strings.HasPrefix(trimmedLine, commentChars+" ") {
return strings.Replace(line, commentChars+" ", "", 1)
}
return strings.Replace(line, commentChars, "", 1)
}
Expand Down
80 changes: 58 additions & 22 deletions internal/file/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

// ProcessFile processes a single file.
func ProcessFile(filename string, lineNum [2]int, commentChars string, modFunc func(string, string) string, dryRun bool) error {
func ProcessFile(filename string, lineNum [2]int, startLabel, endLabel string, commentChars string, modFunc func(string, string) string, dryRun bool) error {
inputFile, err := os.Open(filename)
if err != nil {
return err
Expand All @@ -24,7 +24,7 @@ func ProcessFile(filename string, lineNum [2]int, commentChars string, modFunc f

if dryRun {
// Perform a dry run: print the changes instead of writing them
return printChanges(inputFile, lineNum, commentChars, modFunc)
return printChanges(inputFile, lineNum, startLabel, endLabel, commentChars, modFunc)
}

// Create a backup of the original file
Expand All @@ -49,7 +49,7 @@ func ProcessFile(filename string, lineNum [2]int, commentChars string, modFunc f
return err
}

err = writeChanges(inputFile, tmpFile, lineNum, commentChars, modFunc)
err = writeChanges(inputFile, tmpFile, lineNum, startLabel, endLabel, commentChars, modFunc)
if err != nil {
restoreBackup(filename, backupFilename)
tmpFile.Close()
Expand Down Expand Up @@ -82,55 +82,88 @@ func ProcessFile(filename string, lineNum [2]int, commentChars string, modFunc f
return nil
}

func writeChanges(inputFile *os.File, outputFile *os.File, lineNum [2]int, commentChars string, modFunc func(string, string) string) error {
func writeChanges(inputFile *os.File, outputFile *os.File, lineNum [2]int, startLabel, endLabel string, commentChars string, modFunc func(string, string) string) error {
scanner := bufio.NewScanner(inputFile)
writer := bufio.NewWriter(outputFile)
currentLine := 1
inSection := false
var err error

for scanner.Scan() {
lineContent := scanner.Text()
if lineNum[0] <= currentLine && currentLine <= lineNum[1] {
lineContent = modFunc(lineContent, commentChars)

// Determine if we are processing based on line numbers or labels
if startLabel != "" && endLabel != "" {
if strings.Contains(lineContent, startLabel) {
inSection = true
}
if inSection {
lineContent = modFunc(lineContent, commentChars)
}
if strings.Contains(lineContent, endLabel) {
inSection = false
}
} else {
if lineNum[0] <= currentLine && currentLine <= lineNum[1] {
lineContent = modFunc(lineContent, commentChars)
}
}

if _, err := writer.WriteString(lineContent + "\n"); err != nil {
if _, err = writer.WriteString(lineContent + "\n"); err != nil {
return err
}

currentLine++
}

if lineNum[1] > currentLine {
if lineNum[1] > currentLine && startLabel == "" && endLabel == "" {
return errors.New("line number is out of range")
}

if err := scanner.Err(); err != nil {
if err = scanner.Err(); err != nil {
return err
}

return writer.Flush()
}

func printChanges(inputFile *os.File, lineNum [2]int, commentChars string, modFunc func(string, string) string) error {
func printChanges(inputFile *os.File, lineNum [2]int, startLabel, endLabel, commentChars string, modFunc func(string, string) string) error {
scanner := bufio.NewScanner(inputFile)
currentLine := 1
inSection := false

for scanner.Scan() {
lineContent := scanner.Text()
if lineNum[0] <= currentLine && currentLine <= lineNum[1] {
modified := modFunc(lineContent, commentChars)
fmt.Printf("%d: %s -> %s\n", currentLine, lineContent, modified)

// Determine if we are processing based on line numbers or labels
if startLabel != "" && endLabel != "" {
if strings.Contains(lineContent, startLabel) {
inSection = true
}
if inSection {
modified := modFunc(lineContent, commentChars)
fmt.Printf("%d: %s -> %s\n", currentLine, lineContent, modified)
}
if strings.Contains(lineContent, endLabel) {
inSection = false
}
} else {
if lineNum[0] <= currentLine && currentLine <= lineNum[1] {
modified := modFunc(lineContent, commentChars)
fmt.Printf("%d: %s -> %s\n", currentLine, lineContent, modified)
}
}

currentLine++
}

if lineNum[1] > currentLine {
if lineNum[1] > currentLine && startLabel == "" && endLabel == "" {
return errors.New("line number is out of range")
}

return scanner.Err()
}

func createBackup(filename, backupFilename string) error {
inputFile, err := os.Open(filename)
if err != nil {
Expand Down Expand Up @@ -160,19 +193,22 @@ func restoreBackup(filename, backupFilename string) {
}

// ProcessSingleFile processes a single file specified by filename.
func ProcessSingleFile(filename string, lineStr string, modFunc func(string, string) string, dryRun bool) error {
startLine, endLine, err := extractLines(lineStr)
func ProcessSingleFile(filename string, lineStr, startLabel, endLabel string, modFunc func(string, string) string, dryRun bool) error {
commentChars, err := selectCommentChars(filename)
if err != nil {
return err
}
lineNum := [2]int{startLine, endLine}

commentChars, err := selectCommentChars(filename)
if err != nil {
return err
var lineNum [2]int
if startLabel == "" && endLabel == "" {
startLine, endLine, err := extractLines(lineStr)
if err != nil {
return err
}
lineNum = [2]int{startLine, endLine}
}

return ProcessFile(filename, lineNum, commentChars, modFunc, dryRun)
return ProcessFile(filename, lineNum, startLabel, endLabel, commentChars, modFunc, dryRun)
}

// ProcessMultipleFiles processes multiple files specified by comma-separated filenames.
Expand Down Expand Up @@ -208,7 +244,7 @@ func processFileWithLines(fileInfo string, dryRun bool) error {
return err
}

return ProcessFile(file, lineNum, commentChars, comment.ToggleComments, dryRun)
return ProcessFile(file, lineNum, "", "", commentChars, comment.ToggleComments, dryRun)
}

func extractLines(lineStr string) (startLine, endLine int, err error) {
Expand Down
Loading