github.com/GGP1/kure@v0.8.4/commands/file/mv/mv.go (about)

     1  package mv
     2  
     3  import (
     4  	"fmt"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/GGP1/kure/auth"
     9  	cmdutil "github.com/GGP1/kure/commands"
    10  	"github.com/GGP1/kure/db/file"
    11  
    12  	"github.com/pkg/errors"
    13  	"github.com/spf13/cobra"
    14  	bolt "go.etcd.io/bbolt"
    15  )
    16  
    17  const example = `
    18  * Move a file
    19  kure file mv oldFile newFile
    20  
    21  * Move a directory
    22  kure file mv oldDir/ newDir/
    23  
    24  * Move a file into a directory
    25  kure file mv oldDir/test.txt newDir/`
    26  
    27  // NewCmd returns a new command.
    28  func NewCmd(db *bolt.DB) *cobra.Command {
    29  	return &cobra.Command{
    30  		Use:   "mv <src> <dst>",
    31  		Short: "Move a file or directory",
    32  		Long: `Move a file or directory.
    33  
    34  In case any of the paths contains spaces within it, it must be enclosed by double quotes.`,
    35  		Args: func(cmd *cobra.Command, args []string) error {
    36  			if len(args) != 2 {
    37  				return errors.Errorf("accepts 2 arg(s), received %d", len(args))
    38  			}
    39  
    40  			oldName := cmdutil.NormalizeName(args[0], true)
    41  			if err := cmdutil.Exists(db, oldName, cmdutil.File); err == nil {
    42  				return errors.Errorf("there's no file nor directory named %q", strings.TrimSuffix(oldName, "/"))
    43  			}
    44  			return nil
    45  		},
    46  		Example: example,
    47  		PreRunE: auth.Login(db),
    48  		RunE:    runMv(db),
    49  	}
    50  }
    51  
    52  func runMv(db *bolt.DB) cmdutil.RunEFunc {
    53  	return func(cmd *cobra.Command, args []string) error {
    54  		oldName := args[0]
    55  		newName := args[1]
    56  		if oldName == "" || newName == "" {
    57  			return errors.New("invalid format, use: kure file mv <oldName> <newName>")
    58  		}
    59  
    60  		oldName = cmdutil.NormalizeName(oldName, true)
    61  		newName = cmdutil.NormalizeName(newName, true)
    62  		oldNameIsDir := strings.HasSuffix(oldName, "/")
    63  		newNameIsDir := strings.HasSuffix(newName, "/")
    64  
    65  		if oldNameIsDir {
    66  			if !newNameIsDir {
    67  				return errors.New("cannot move a directory into a file")
    68  			}
    69  			return mvDir(db, oldName, newName)
    70  		}
    71  
    72  		// Move file into directory
    73  		if !oldNameIsDir && newNameIsDir {
    74  			newName += filepath.Base(oldName)
    75  		}
    76  
    77  		if filepath.Ext(newName) == "" {
    78  			newName += filepath.Ext(oldName)
    79  		}
    80  
    81  		if err := cmdutil.Exists(db, newName, cmdutil.File); err != nil {
    82  			return err
    83  		}
    84  
    85  		if err := file.Rename(db, oldName, newName); err != nil {
    86  			return err
    87  		}
    88  
    89  		fmt.Printf("\n%q moved to %q\n", oldName, newName)
    90  		return nil
    91  	}
    92  }
    93  
    94  func mvDir(db *bolt.DB, oldName, newName string) error {
    95  	names, err := file.ListNames(db)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	fmt.Printf("Moving %q directory into %q...\n", strings.TrimSuffix(oldName, "/"), strings.TrimSuffix(newName, "/"))
   101  
   102  	for _, name := range names {
   103  		if strings.HasPrefix(name, oldName) {
   104  			if err := file.Rename(db, name, newName+strings.TrimPrefix(name, oldName)); err != nil {
   105  				return err
   106  			}
   107  		}
   108  	}
   109  
   110  	return nil
   111  }