Skip to content

Commit

Permalink
Code refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
alesr committed Mar 19, 2023
1 parent 7ed4429 commit 4077d95
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 142 deletions.
213 changes: 213 additions & 0 deletions internal/codetoprompt/codetoprompt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
package codetoprompt

import (
"errors"
"flag"
"fmt"
"io"
"os"
"path/filepath"
"strings"
)

const (
fileOverwritePrompt string = "The output file already exists. Do you want to overwrite it? (y/n)"
)

var (
dir string
outputPath string
exclude string
excludeBlankLines bool

errOutputFileAlreadyExists = errors.New("output file already exists")
)

type file struct {
name string
path string
content []byte
}

func parseFlags() {
flag.StringVar(&dir, "dir", "", "the root directory you want to load files from")
flag.StringVar(&outputPath, "out", "", "the filepath to the output file, if not provided, the output will be displayed in the terminal")
flag.StringVar(&exclude, "exclude", "", "exclude a directory or a file from the output file")
flag.BoolVar(&excludeBlankLines, "blanklines", true, "include blank lines in the output file")

flag.Parse()
}

func Run() error {
parseFlags()

if err := validateFlagsInput(); err != nil {
if !errors.Is(err, errOutputFileAlreadyExists) {
return fmt.Errorf("error validating flags: %w", err)
}

if !overwriteFile(outputPath) {
fmt.Println("Aborting...")
os.Exit(0)
}
}

ignoreList := strings.Split(exclude, ",")

if outputPath != "" {
// Adding the output file to the ignore list to avoid writing it to itself
ignoreList = append(ignoreList, outputPath)
}

files, err := loadFiles(dir, ignoreList)
if err != nil {
return fmt.Errorf("error loading files: %w", err)
}

if outputPath != "" {
fmt.Println("Writing files to output file...")
outputFile, err := createFile(outputPath)
if err != nil {
return fmt.Errorf("error creating output file: %w", err)
}

if err := writeFiles(files, outputFile, excludeBlankLines); err != nil {
return fmt.Errorf("error writing files: %w", err)
}
os.Exit(0)
}

for _, file := range files {
fmt.Println("Filename: ", file.name)
fmt.Println(string(file.content))
fmt.Println("---")
}
return nil
}

func validateFlagsInput() error {
if dir == "" {
return errors.New("root path not provided")
}

if outputPath != "" {
alreadyExists, err := fileAlreadyExists(outputPath)
if err != nil {
return fmt.Errorf("error checking if output file exists: %w", err)
}

if alreadyExists {
return errOutputFileAlreadyExists
}
}
return nil
}

func fileAlreadyExists(filePath string) (bool, error) {
if _, err := os.Stat(filePath); err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, fmt.Errorf("error checking if file exists: %w", err)
}
return true, nil
}

func overwriteFile(filePath string) bool {
if _, err := os.Stat(filePath); err == nil {
var input string
fmt.Println(fileOverwritePrompt)
fmt.Scanln(&input)

switch strings.ToLower(input) {
case "y", "yes":
return true
}
}
return false
}

func loadFiles(rootPath string, ignoreList []string) ([]file, error) {
var files []file

if err := filepath.Walk(rootPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("could not access path %q: %v", path, err)
}

if info.IsDir() {
for _, item := range ignoreList {
if info.Name() == item {
return filepath.SkipDir
}
}
}

if !info.IsDir() {
for _, item := range ignoreList {
if info.Name() == item {
return nil
}
}

content, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("could not read file %q: %v", path, err)
}

files = append(files, file{
name: info.Name(),
path: path,
content: content,
})
}
return nil
}); err != nil {
return nil, fmt.Errorf("could not walk the path %q: %v", rootPath, err)
}
return files, nil
}

func createFile(outputPath string) (*os.File, error) {
file, err := os.Create(outputPath)
if err != nil {
return nil, fmt.Errorf("could not create file: %w", err)
}
return file, nil
}

func writeFiles(files []file, output io.WriteCloser, includeBlanklines bool) error {
defer output.Close()

if _, err := output.Write([]byte("---\n")); err != nil {
return fmt.Errorf("could not write opening code separator for file: %w", err)
}

for _, file := range files {
var strBulider strings.Builder

strBulider.WriteString("Filename: ")
strBulider.WriteString(file.name)
strBulider.WriteString("\n\n")

if includeBlanklines {
for _, line := range strings.Split(string(file.content), "\n") {
if line == "" {
continue
}
strBulider.WriteString(line)
strBulider.WriteString("\n")
}

} else {
strBulider.WriteString(string(file.content))
}

strBulider.WriteString("---\n")

if _, err := output.Write([]byte(strBulider.String())); err != nil {
return fmt.Errorf("could not write file %q: %v", file.name, err)
}
}
return nil
}
146 changes: 4 additions & 142 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,151 +1,13 @@
package main

import (
"flag"
"fmt"
"io"
"log"
"os"
"path/filepath"
"strings"
)

const defaultOutputFile string = "output.txt"

type file struct {
name string
path string
content []byte
}
"github.com/alesr/codetoprompt/internal/codetoprompt"
)

func main() {
rootPtr := flag.String("root", "", "the filepath to the root directory you want to load files from")
outputPtr := flag.String("output", defaultOutputFile, "the filepath to the output file")
includeBlanklines := flag.Bool("blanklines", false, "include blank lines in the output file")
expludeDirs := flag.String("excludedirs", "", "exclude a directory from the output file")

flag.Parse()

if rootPtr == nil || *rootPtr == "" {
log.Fatal("root flag is required")
}

var dirsToIgnore []string
if expludeDirs != nil && *expludeDirs != "" {
dirsToIgnore = strings.Split(*expludeDirs, ",")
}

var files []file

if *outputPtr != defaultOutputFile {
if _, err := os.Stat(*outputPtr); err == nil {
var input string
fmt.Println("The output file already exists. Do you want to overwrite it? (y/n)")
fmt.Scanln(&input)

switch strings.ToLower(input) {
case "y", "yes":
fmt.Println("Overwriting file...")
default:
fmt.Println("Exiting...")
os.Exit(0)
}
}
}

files, err := loadFiles(*rootPtr, dirsToIgnore)
if err != nil {
log.Fatalf("failed to load files: %s", err)
}

if len(files) == 0 {
fmt.Println("no files found")
os.Exit(0)
}

output, err := os.Create(*outputPtr)
if err != nil {
log.Fatalf("failed to create output file: %s", err)
}

if err := writeFiles(files, output, *includeBlanklines); err != nil {
log.Fatalf("failed to write files to output file: %s", err)
}

outputContent, err := os.ReadFile(*outputPtr)
if err != nil {
log.Fatalf("failed to read output file: %s", err)
}
fmt.Println(string(outputContent))
}

func loadFiles(root string, dirsToIgnore []string) ([]file, error) {
var files []file

if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
return fmt.Errorf("could not access path %q: %v", path, err)
}

if info.IsDir() {
for _, dir := range dirsToIgnore {
if info.Name() == dir {
return filepath.SkipDir
}
}
}

if !info.IsDir() {
content, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("could not read file %q: %v", path, err)
}

files = append(files, file{
name: info.Name(),
path: path,
content: content,
})
}
return nil
}); err != nil {
return nil, fmt.Errorf("could not walk the path %q: %v", root, err)
}
return files, nil
}

func writeFiles(files []file, output io.WriteCloser, includeBlanklines bool) error {
defer output.Close()

if _, err := output.Write([]byte("---\n")); err != nil {
return fmt.Errorf("could not write opening code separator for file: %w", err)
}

for _, file := range files {
var strBulider strings.Builder

strBulider.WriteString("Filename: ")
strBulider.WriteString(file.name)
strBulider.WriteString("\n\n")

if !includeBlanklines {
for _, line := range strings.Split(string(file.content), "\n") {
if line == "" {
continue
}
strBulider.WriteString(line)
strBulider.WriteString("\n")
}

} else {
strBulider.WriteString(string(file.content))
}

strBulider.WriteString("---\n")

if _, err := output.Write([]byte(strBulider.String())); err != nil {
return fmt.Errorf("could not write file %q: %v", file.name, err)
}
if err := codetoprompt.Run(); err != nil {
log.Fatalln(err)
}
return nil
}

0 comments on commit 4077d95

Please sign in to comment.