Skip to content

Commit

Permalink
feat: Improve file/dir path options
Browse files Browse the repository at this point in the history
Checks for permissions
Checks for its existence
Checks for the file/dir type
  • Loading branch information
caffeine-addictt committed Apr 15, 2024
1 parent b7a13bc commit 63427be
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 28 deletions.
12 changes: 6 additions & 6 deletions src/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ var cacheListCommand = &cobra.Command{
Aliases: []string{"ls"},
Args: cobra.MaximumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
Debug("Opening cache file at " + cacheFile)
file, err := os.Open(cacheFile)
Debug("Opening cache file at " + cacheFile.String())
file, err := os.Open(cacheFile.String())
if err != nil {
fmt.Println("Failed to open cache file")
Debug(err.Error())
Expand Down Expand Up @@ -74,8 +74,8 @@ var cacheRemoveCommand = &cobra.Command{
os.Exit(1)
}

Debug("Opening cache file at " + cacheFile)
file, err := os.Open(cacheFile)
Debug("Opening cache file at " + cacheFile.String())
file, err := os.Open(cacheFile.String())
if err != nil {
fmt.Println("Failed to open cache file")
Debug(err.Error())
Expand Down Expand Up @@ -171,8 +171,8 @@ var cacheClearCommand = &cobra.Command{
Aliases: []string{"wipe", "clr"},
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
Debug("Creating/Truncating cache file at " + cacheFile)
file, err := os.OpenFile(cacheFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
Debug("Creating/Truncating cache file at " + cacheFile.String())
file, err := os.OpenFile(cacheFile.String(), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
if err != nil {
fmt.Println("Failed to clear the cache at " + cacheFile)
Debug(err.Error())
Expand Down
6 changes: 3 additions & 3 deletions src/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var deleteCommand = &cobra.Command{
Short: "Delete videos from the source directory",
Args: cobra.ExactArgs(1),
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
filenames, err := utils.ReadDirectory(workingDir, 0)
filenames, err := utils.ReadDirectory(workingDir.String(), 0)
if err != nil {
fmt.Println("Failed to read source directory:", err.Error())
os.Exit(1)
Expand All @@ -47,7 +47,7 @@ var deleteCommand = &cobra.Command{
},
Run: func(cmd *cobra.Command, args []string) {
Info("Reading source directory")
filenames, err := utils.ReadDirectory(workingDir, 0)
filenames, err := utils.ReadDirectory(workingDir.String(), 0)
if err != nil {
fmt.Println("Failed to read source directory:", err.Error())
os.Exit(1)
Expand Down Expand Up @@ -92,7 +92,7 @@ var deleteCommand = &cobra.Command{

// Delete files
for _, filename := range filenames {
fileFullPath := filepath.Join(workingDir, filename)
fileFullPath := filepath.Join(workingDir.String(), filename)
if err := os.Remove(fileFullPath); err != nil {
fmt.Printf("Failed to delete %s: %s", filename, err.Error())
os.Exit(1)
Expand Down
16 changes: 8 additions & 8 deletions src/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type Similarity map[string]int8

// Command stuff
var getFlags struct {
inputFile string
inputFile utils.FilePathFlag
strategy utils.StrategyEnum
maxConcurrency int
}
Expand All @@ -40,7 +40,7 @@ var getCommand = &cobra.Command{
}

// Validate working directory exists and is writable
dirPath, err := utils.ValidateDirectory(workingDir)
dirPath, err := utils.ValidateDirectory(workingDir.String())
if err != nil {
fmt.Printf("Failed to validate working directory: %#v\n", workingDir)
Debug(err.Error())
Expand All @@ -64,13 +64,13 @@ var getCommand = &cobra.Command{
// Fetch URLs from file
if getFlags.inputFile != "" {
Debug("-f was passed, reading url(s) from file")
file, err := os.Open(getFlags.inputFile)
file, err := os.Open(getFlags.inputFile.String())
if err != nil {
fmt.Printf("Failed to read file at %s\n", getFlags.inputFile)
Debug(err.Error())
os.Exit(1)
}
Debug("Closing file at " + getFlags.inputFile)
Debug("Closing file at " + getFlags.inputFile.String())
defer file.Close()

// Read URLs from file, line by line
Expand All @@ -91,14 +91,14 @@ var getCommand = &cobra.Command{
}
argSet[scanner.Text()] = struct{}{}
}
Info("Read " + fmt.Sprint(len(args)-preURLCount) + " url(s) from " + getFlags.inputFile)
Info("Read " + fmt.Sprint(len(args)-preURLCount) + " url(s) from " + getFlags.inputFile.String())
}
Debug("Valid URL(s): " + fmt.Sprint(argSet))
Debug("Non URL(s): " + fmt.Sprint(nonURLSet))

// Open cache file
Debug("Opening cache file at " + cacheFile)
file, err := os.OpenFile(cacheFile, os.O_RDWR|os.O_APPEND, 0o600)
Debug("Opening cache file at " + cacheFile.String())
file, err := os.OpenFile(cacheFile.String(), os.O_RDWR|os.O_APPEND, 0o600)
if err != nil {
fmt.Println("Failed to open cache file at " + cacheFile)
Debug(err.Error())
Expand Down Expand Up @@ -352,7 +352,7 @@ func init() {
rootCommand.AddCommand(getCommand)
getCommand.Flags().IntVarP(&getFlags.maxConcurrency, "max-concurrency", "m", 10, "Maximum number of concurrent downloads [0 = unlimited] (default is 10)")

getCommand.Flags().StringVarP(&getFlags.inputFile, "file", "f", "", "Path to the input file containing the url(s)")
getCommand.Flags().VarP(&getFlags.inputFile, "file", "f", "Path to the input file containing the url(s)")
if err := getCommand.MarkFlagFilename("file"); err != nil {
fmt.Println("Failed to mark flag -f as filename in get command")
Debug(err.Error())
Expand Down
2 changes: 1 addition & 1 deletion src/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var listCommand = &cobra.Command{
considerReject := len(listFlags.rejectExt) > 0

Info("Reading directory...")
filenames, err := utils.ReadDirectory(workingDir, listFlags.count)
filenames, err := utils.ReadDirectory(workingDir.String(), listFlags.count)
if err != nil {
fmt.Println("Failed to read directory")
Debug(err.Error())
Expand Down
16 changes: 8 additions & 8 deletions src/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ var (
home string

// Flags
cfgFile string
cacheFile string
cfgFile utils.FilePathFlag
cacheFile utils.FilePathFlag
verbose bool
debug bool

// Working Directory
workingDir string
workingDir utils.DirPathFlag
)

// Root command
Expand Down Expand Up @@ -52,14 +52,14 @@ func init() {
func init() {
cobra.OnInitialize(initConfig)

rootCommand.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file (default is $HOME/.video-manager)")
rootCommand.PersistentFlags().VarP(&cfgFile, "config", "c", "config file (default is $HOME/.video-manager)")
if err := rootCommand.MarkPersistentFlagFilename("config"); err != nil {
fmt.Println("Failed to mark flag -c as filename in root command")
Debug(err.Error())
os.Exit(1)
}

rootCommand.PersistentFlags().StringVarP(&cacheFile, "cache", "C", "", "cache file (default is $HOME/.video-manager_history)")
rootCommand.PersistentFlags().VarP(&cacheFile, "cache", "C", "cache file (default is $HOME/.video-manager_history)")
if err := rootCommand.MarkPersistentFlagFilename("cache"); err != nil {
fmt.Println("Failed to mark flag -C as filename in root command")
Debug(err.Error())
Expand All @@ -77,7 +77,7 @@ func init() {
rootCommand.PersistentFlags().BoolVarP(&debug, "debug", "d", false, "Debug output")

// Working directory
rootCommand.PersistentFlags().StringVarP(&workingDir, "dir", "w", "~/Videos", "Working directory (default is ~/Videos)")
rootCommand.PersistentFlags().VarP(&workingDir, "dir", "w", "Working directory (default is ~/Videos)")
if err := rootCommand.MarkPersistentFlagDirname("dir"); err != nil {
fmt.Println("Failed to mark flag -w as dirname in root command")
Debug(err.Error())
Expand All @@ -99,8 +99,8 @@ func initConfig() {

if cfgFile != "" {
// Reading provided configuration file
viper.SetConfigFile(cfgFile)
Debug("-c supplied at " + cfgFile)
viper.SetConfigFile(cfgFile.String())
Debug("-c supplied at " + cfgFile.String())
} else {
// Reading configuration file from either pwd or $HOME
viper.AddConfigPath(".")
Expand Down
94 changes: 92 additions & 2 deletions src/utils/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,98 @@ import (
"github.com/pkg/errors"
)

func ValidateDirectory(dir string) (string, error) {
dirPath, err := homedir.Expand(dir)
// Path Flag
type PathFlag string

func (e *PathFlag) String() string {
return string(*e)
}

func (e *PathFlag) Set(value string) error {
if _, err := os.Stat(filepath.Clean(value)); err != nil {
return errors.New("must be a valid path")
}

*e = PathFlag(value)
return nil
}

func (e *PathFlag) Type() string {
return "<path>"
}

// File Path Flag
type FilePathFlag string

func (e *FilePathFlag) String() string {
return string(*e)
}

func (e *FilePathFlag) Set(value string) error {
filePath, err := ValidateFile(value)
if err != nil {
return err
}

*e = FilePathFlag(filePath)
return nil
}

func (e *FilePathFlag) Type() string {
return "<path>"
}

// Directory Path Flag
type DirPathFlag string

func (e *DirPathFlag) String() string {
return string(*e)
}

func (e *DirPathFlag) Set(value string) error {
dirPath, err := ValidateDirectory(value)
if err != nil {
return err
}

*e = DirPathFlag(dirPath)
return nil
}

func (e *DirPathFlag) Type() string {
return "<path>"
}

// Functions
func ValidateFile(path string) (string, error) {
filePath, err := homedir.Expand(path)
if err != nil {
return "", err
}

info, err := os.Stat(filePath)
if os.IsNotExist(err) {
return "", errors.Wrapf(err, "File does not exist: %v\n", filePath)
}
if err != nil {
return "", errors.Wrapf(err, "File error: %v\n", filePath)
}

if info.IsDir() {
return "", errors.Errorf("%#v is a directory\n", filePath)
}

// Check for read/write permissions
mode := info.Mode()
if mode.Perm()&0o666 == 0 {
return "", errors.Errorf("%#v has no read/write permissions\n", filePath)
}

return filePath, nil
}

func ValidateDirectory(path string) (string, error) {
dirPath, err := homedir.Expand(path)
if err != nil {
return "", errors.WithStack(err)
}
Expand Down

0 comments on commit 63427be

Please sign in to comment.