package main
import (
"flag"
"fmt"
"logc/git"
"logc/output"
"logc/parser"
"logc/search"
"os"
"os/exec"
"strings"
)
// !TODO: Add above and clean mode --clean also have the search function include the code
// + I'd like to be able to --tag=devman --search=outputCSV --format=json --clean
// + --include-ext adds the file extention maybe a --headers that logs the CSV/JSON headers
// + --tag logs all tags --tag="DEVMAN,TODO" includes both
// + --headers="File,Line" only includes file and line
// + Description: might to something like this to add a custom header
// + hello
func main() {
list := flag.Bool("list", false, "List all headers")
headers := flag.String("headers", "", "Search Headers")
query := flag.String("query", "", "Search Body")
// clean := flag.Bool("clean", false, "Remove Comments")
format := flag.String("format", "", "Output format (text/json/csv/html)")
gitBool := flag.Bool("git", false, "Enable HTML to Git")
template := flag.String("template", "", "Git Template")
theme := flag.String("theme", "dracula", "Code Highlighting Theme")
outputPath := flag.String("output", "./", "HTML Output Directory")
address := flag.String("address", ":80", "HTTP Address to listen on")
serve := flag.Bool("serve", false, "Start Git Server")
// Preprocess to extract the positional argument
var root string
args := os.Args[1:] // Skip the program name
for i, arg := range args {
if !strings.HasPrefix(arg, "-") {
root = arg
// Remove the positional argument so `flag.Parse` can handle the rest
args = append(args[:i], args[i+1:]...)
break
}
}
if root == "" {
root = "." // Default to the current directory
}
// Parse the remaining flags
flag.CommandLine.Parse(args)
// Validate the root directory
if _, err := os.Stat(root); os.IsNotExist(err) {
fmt.Println("Directory does not exist:", root)
os.Exit(1)
}
if *gitBool {
if *serve {
git.ServeHTML(root, *template, *theme, *address, *outputPath, *headers, *query)
} else {
git.ConvertRepo(root, *outputPath, *theme, *template, *headers, *query)
}
return
}
comments := []parser.Comment{}
paths := parser.LoadPaths(root)
for _, v := range paths {
comments = append(comments, parser.File(v)...)
}
if *list {
fmt.Println(strings.Join(output.GetHeaders(comments), ","))
return
}
// Filter comments based on search term
filteredComments := search.Text(comments, *headers, *query)
// Skip TUI if `-format` flag is present
if *format != "" {
switch strings.ToLower(*format) {
case "json":
output.JSON(filteredComments)
case "csv":
output.CSV(filteredComments)
case "html":
fmt.Println(output.HTML(filteredComments))
default:
output.Text(filteredComments)
}
return
} else {
content := output.FormatText(filteredComments, 90)
editor := os.Getenv("EDITOR")
if editor == "" {
editor = "less"
}
// !ISSUE: Fix this
// if editor == "less" {
// content = output.HighlightText(content)
// }
tmpFile, err := os.CreateTemp("", "highlighted_text_*.txt")
if err != nil {
return
}
defer os.Remove(tmpFile.Name()) // Clean up after use
// Write content to the temporary file
if _, err := tmpFile.WriteString(content); err != nil {
return
}
tmpFile.Close()
// Construct the shell command
// Execute the command in a shell
cmd := exec.Command(editor, tmpFile.Name())
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
// Run and handle errors
if err := cmd.Run(); err != nil {
fmt.Fprintf(os.Stderr, "Error opening editor: %v\n", err)
os.Exit(1)
}
}
}