Skip to content

Commit

Permalink
Check file file can't be processed
Browse files Browse the repository at this point in the history
  • Loading branch information
taylormonacelli committed Jul 30, 2024
1 parent a16ffb1 commit 736091a
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 17 deletions.
20 changes: 19 additions & 1 deletion cmd/watchDir.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmd

import (
"os"

"github.com/gkwa/littlewill/watcher"
"github.com/spf13/cobra"
)
Expand All @@ -21,7 +23,23 @@ Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
Run: func(cmd *cobra.Command, args []string) {
watcher.RunWatcher(cmd, args, patterns, filterType, linkTransforms)
if len(args) == 0 {
err := cmd.Usage()
if err != nil {
cmd.PrintErrf("Error: %v\n", err)
}
cmd.PrintErrln("Error: directory path is required")
os.Exit(1)
}

dir := args[0]
watcher.RunWatcher(
cmd.Context(),
dir,
patterns,
filterType,
linkTransforms,
)
},
}

Expand Down
59 changes: 59 additions & 0 deletions file/type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package file

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

type File struct {
Path string
}

func (f File) IsSymlink() (bool, error) {
fileInfo, err := os.Lstat(f.Path)
if err != nil {
return false, err
}
return fileInfo.Mode()&os.ModeSymlink != 0, nil
}

func (f File) FileType() string {
// Get file info without following symlinks
info, err := os.Lstat(f.Path)
if err != nil {
return "Error: Unable to get file info"
}

// Check if it's a symlink
if info.Mode()&os.ModeSymlink != 0 {
// If it's a symlink, we can optionally get the target
target, err := os.Readlink(f.Path)
if err != nil {
return "Symlink (unable to read target)"
}
return fmt.Sprintf("Symlink to %s", target)
}

// If it's not a symlink, proceed with file type detection
if info.IsDir() {
return "Directory"
}

ext := strings.ToLower(filepath.Ext(f.Path))
switch ext {
case ".txt":
return "Text File"
case ".go":
return "Go Source File"
case ".jpg", ".jpeg":
return "JPEG Image"
case ".png":
return "PNG Image"
case ".pdf":
return "PDF Document"
default:
return "Unknown File Type"
}
}
104 changes: 104 additions & 0 deletions file/type_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package file

import (
"os"
"path/filepath"
"strings"
"testing"
)

func TestFileType(t *testing.T) {
// Create a temporary directory for our test files
tmpDir, err := os.MkdirTemp("", "filetest")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
defer os.RemoveAll(tmpDir)

// Test cases
tests := []struct {
name string
setup func() (string, error)
expected string
}{
{
name: "Text File",
setup: func() (string, error) {
path := filepath.Join(tmpDir, "test.txt")
err := os.WriteFile(path, []byte("test"), 0o644)
return path, err
},
expected: "Text File",
},
{
name: "Go Source File",
setup: func() (string, error) {
path := filepath.Join(tmpDir, "test.go")
err := os.WriteFile(path, []byte("package main"), 0o644)
return path, err
},
expected: "Go Source File",
},
{
name: "JPEG Image",
setup: func() (string, error) {
path := filepath.Join(tmpDir, "test.jpg")
err := os.WriteFile(path, []byte("fake jpg"), 0o644)
return path, err
},
expected: "JPEG Image",
},
{
name: "Directory",
setup: func() (string, error) {
path := filepath.Join(tmpDir, "testdir")
err := os.Mkdir(path, 0o755)
return path, err
},
expected: "Directory",
},
{
name: "Symlink",
setup: func() (string, error) {
target := filepath.Join(tmpDir, "target.txt")
err := os.WriteFile(target, []byte("target"), 0o644)
if err != nil {
return "", err
}
link := filepath.Join(tmpDir, "symlink")
err = os.Symlink(target, link)
return link, err
},
expected: "Symlink to ", // We'll check if it starts with this
},
{
name: "Unknown File Type",
setup: func() (string, error) {
path := filepath.Join(tmpDir, "test.xyz")
err := os.WriteFile(path, []byte("unknown"), 0o644)
return path, err
},
expected: "Unknown File Type",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
path, err := tt.setup()
if err != nil {
t.Fatalf("Setup failed: %v", err)
}

file := File{Path: path}
result := file.FileType()

if tt.name == "Symlink" {
if !strings.HasPrefix(result, tt.expected) {
t.Errorf("FileType() = %v, want prefix %v", result, tt.expected)
}
} else if result != tt.expected {
t.Errorf("FileType() = %v, want %v", result, tt.expected)
}
})
}
}
42 changes: 26 additions & 16 deletions watcher/watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,42 +10,52 @@ import (

"github.com/fsnotify/fsnotify"
"github.com/gkwa/littlewill/core"
"github.com/gkwa/littlewill/file"
"github.com/go-logr/logr"
"github.com/spf13/cobra"
)

var ignoredEvents = []fsnotify.Op{
fsnotify.Chmod,
fsnotify.Remove,
fsnotify.Rename,
}

type EventHandler func(event fsnotify.Event, path string)

func RunWatcher(cmd *cobra.Command, args []string, patterns []string, filterType string, linkTransforms []func(io.Reader, io.Writer) error) {
logger := logr.FromContextOrDiscard(cmd.Context())

if len(args) == 0 {
err := cmd.Usage()
if err != nil {
cmd.PrintErrf("Error: %v\n", err)
}
cmd.PrintErrln("Error: directory path is required")
os.Exit(1)
}
func RunWatcher(
ctx context.Context,
dirToWatch string,
patterns []string,
filterType string,
linkTransforms []func(io.Reader, io.Writer) error,
) {
logger := logr.FromContextOrDiscard(ctx)

dirToWatch := args[0]
ctx := cmd.Context()
handler := func(event fsnotify.Event, path string) {
time.Sleep(100 * time.Millisecond)
fmt.Printf("Event: %s, File: %s\n", event.Op, path)
err := core.ProcessFile(logger, path, linkTransforms...)

f := file.File{Path: path}

isSymlink, err := f.IsSymlink()
if err != nil {
logger.Error(err, "Failed to check if path is symlink", "path", path)
}
logger.V(1).Info("file type check", "path", path, "type", f.FileType())

if isSymlink {
logger.V(1).Info("skipping symlink", "path", path)
return
}

err = core.ProcessFile(logger, path, linkTransforms...)
if err != nil {
logger.Error(err, "Failed to process file", "path", path)
}
}
err := Run(ctx, dirToWatch, patterns, filterType, handler)
if err != nil {
cmd.PrintErrf("Error: %v\n", err)
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
}
Expand Down

0 comments on commit 736091a

Please sign in to comment.