[from now] 2014/08/26 23:15:08

diff --git a/cmd/copybackup/copybackup.go b/cmd/copybackup/copybackup.go
index a9bbd98..cf92872 100644
--- a/cmd/copybackup/copybackup.go
+++ b/cmd/copybackup/copybackup.go
@@ -13,18 +13,20 @@ import (
 )

 type Options struct {
-	Generation int    `short:"g" long:"generation" description:"バックアップする世代。"`
-	BackupDst  string `short:"b" long:"backup" description:"" `
-	Sleep      int    `short:"s" long:"sleep" description:"バックアップ間隔。 (秒 [デフォルト 5分])"`
+	Generation int    `short:"g" long:"generation" description:"バックアップする世代。 (デフォルト [5])" default:"5"`
+	BackupDst  string `short:"b" long:"backup" description:"バックアップを保存する先。 (デフォルト [_old])" default:"_old"`
+	Sleep      int    `short:"s" long:"sleep" description:"バックアップ間隔。 (秒 [デフォルト 5分])" default:"60*5"`
+	Csv        string `short:"c" long:"csv" description:"設定ファイルから読み込み。(csvファイル)"`
 }

 func main() {
 	core.Logger, _ = log.NewLogger(os.Stdout, log.TIME_FORMAT_SEC, log.LOG_FORMAT_POWERFUL, log.LogLevel_Debug)

-	var root string
 	var e error
 	var wg sync.WaitGroup

+	cg := &cb.CopyGroup{}
+
 	opts := &Options{}
 	parser := flags.NewParser(opts, flags.Default)
 	args, e := parser.Parse()
@@ -35,22 +37,30 @@ func main() {
 		os.Exit(0)
 	}

-	root = args[0]
-
-	files, e := ioutil.ReadDir(root)
-	core.FailOnError(e)
-
-	for _, f := range files {
-		if !f.IsDir() {
-			src := filepath.Join(root, f.Name())
-			dst, e := cb.MakeDstPath(src, "_old")
+	for _, arg := range args {
+		if f, _ := os.Stat(arg); f.IsDir() {
+			files, e := ioutil.ReadDir(arg)
 			core.FailOnError(e)
+			for _, f := range files {
+				if !f.IsDir() {
+					cg = cb.NewCopyGroup(filepath.Join(arg, f.Name()), opts.BackupDst, opts.Generation, opts.Sleep)
+					wg.Add(1)
+					go func() {
+						defer wg.Done()
+						cg.Backup()
+					}()
+				}
+			}
+
+		} else {
+			cg = cb.NewCopyGroup(arg, opts.BackupDst, opts.Generation, opts.Sleep)
 			wg.Add(1)
-			go func(src, dst string) {
+			go func() {
 				defer wg.Done()
-				cb.Backup(src, dst)
-			}(src, dst)
+				cg.Backup()
+			}()
 		}
-		wg.Wait()
 	}
+	wg.Wait()
+
 }
diff --git a/copybackup.go b/copybackup.go
index ce6ea3c..5e6fcb1 100644
--- a/copybackup.go
+++ b/copybackup.go
@@ -1,6 +1,7 @@
 package copybackup

 import ( // {{{
+	"fmt"
 	"io"
 	"os"
 	"path/filepath"
@@ -10,39 +11,51 @@ import ( // {{{
 	core "github.com/yukimemi/gocore"
 ) // }}}

-type Options struct {
-	path       string
+type CopyGroup struct { // {{{
+	src        string
+	dst        string
+	bkpath     string
 	generation int
-	backup     string
 	sleep      int
-}
+} // }}}

-func NewOptions(path string, generation int, backup string, sleep int) *Options {
-	return &Options{path, generation, backup, sleep}
-}
+func makeDstPath(src, bkpath string) (string, error) { // {{{
+	var dst string

-func MakeDstPath(path, bkpath string) (string, error) {
-	_, e := os.Stat(path)
-	parent, base := filepath.Split(path)
+	f, e := os.Stat(src)
+	if e == nil && f.IsDir() {
+		// core.Logger.Warnf("%s is Directory !", src)
+		return "", fmt.Errorf("%s is Directory !", src)
+	}
+	parent, base := filepath.Split(src)
 	ext := filepath.Ext(base)
 	basename := strings.TrimSuffix(base, ext)
 	now := time.Now()
-	dst := filepath.Join(parent, bkpath, basename+"_"+now.Format("20060102_150405")+ext)
+	if filepath.IsAbs(bkpath) {
+		dst = filepath.Join(bkpath, basename+"_"+now.Format("20060102-150405")+ext)
+	} else {
+		dst = filepath.Join(parent, bkpath, basename+"_"+now.Format("20060102-150405")+ext)
+	}

 	return dst, e
-}
+} // }}}

-func Backup(src, dst string) {
+func NewCopyGroup(src, bkpath string, generation, sleep int) *CopyGroup { // {{{
+	dst, e := makeDstPath(src, bkpath)
+	core.FailOnError(e)
+	return &CopyGroup{src, dst, bkpath, generation, sleep}
+} // }}}
+
+func (cg *CopyGroup) Backup() error { // {{{
 	var e error
-	dstParent := filepath.Dir(dst)
+	dstParent := filepath.Dir(cg.dst)
 	e = os.MkdirAll(dstParent, os.ModePerm)
 	core.FailOnError(e)
-	core.Logger.Infof("%s -> %s", src, dst)
-	e = cp(dst, src)
-	core.FailOnError(e)
-}
+	core.Logger.Infof("%s -> %s", cg.src, cg.dst)
+	return cp(cg.dst, cg.src)
+} // }}}

-func cp(dst, src string) error {
+func cp(dst, src string) error { // {{{
 	// https://gist.github.com/elazarl/5507969
 	s, err := os.Open(src)
 	if err != nil {
@@ -60,4 +73,4 @@ func cp(dst, src string) error {
 		return err
 	}
 	return d.Close()
-}
+} // }}}
diff --git a/copybackup_test.go b/copybackup_test.go
index d508cd5..364a0c6 100644
--- a/copybackup_test.go
+++ b/copybackup_test.go
@@ -2,15 +2,44 @@ package copybackup

 import (
 	"os"
-	"reflect"
+	"regexp"
 	"testing"
+
+	"github.com/umisama/golog"
+	core "github.com/yukimemi/gocore"
 )

-func TestGetFileList(t *testing.T) {
-	path, _ := os.Getwd()
-	files, _ := GetFileList(path)
-	expected := []string{"/Users/yukimemi/.ghq/bitbucket.org/yukimemi/go/copybackup/copybackup.go", "/Users/yukimemi/.ghq/bitbucket.org/yukimemi/go/copybackup/copybackup_test.go", "/Users/yukimemi/.ghq/bitbucket.org/yukimemi/go/copybackup/export_test.go"}
-	if !reflect.DeepEqual(files, expected) {
-		t.Errorf("expected = [%s] but files = [%s]", expected, files)
+func TestMakeDstPath1(t *testing.T) { // {{{
+	core.Logger, _ = log.NewLogger(os.Stdout, log.TIME_FORMAT_SEC, log.LOG_FORMAT_POWERFUL, log.LogLevel_Debug)
+	src := "/tmp/"
+	bkpath := "_old"
+
+	expected := "^/tmp/_old/test_[0-9]{8}-[0-9]{6}$"
+	dst, e := makeDstPath(src, bkpath)
+	if e != nil {
+		t.Error(e)
+	}
+
+	if m, e := regexp.MatchString(expected, dst); m && e == nil {
+	} else {
+		t.Errorf("expected = [%s] but dst is = [%s]", expected, dst)
+	}
+} // }}}
+
+func TestMakeDstPath2(t *testing.T) { // {{{
+	core.Logger, _ = log.NewLogger(os.Stdout, log.TIME_FORMAT_SEC, log.LOG_FORMAT_POWERFUL, log.LogLevel_Debug)
+	src := "/tmp"
+	bkpath := "/Users/yukimemi/backup"
+
+	expected := "^/Users/yukimemi/backup/test_[0-9]{8}-[0-9]{6}$"
+	dst, e := makeDstPath(src, bkpath)
+	if e != nil {
+		t.Error(e)
+	}
+
+	if m, e := regexp.MatchString(expected, dst); m && e == nil {
+		core.Logger.Infof("dst := [%s]", dst)
+	} else {
+		t.Errorf("expected = [%s] but dst is = [%s]", expected, dst)
 	}
-}
+} // }}}
diff --git a/export_test.go b/export_test.go
index 4155667..b98de5c 100644
--- a/export_test.go
+++ b/export_test.go
@@ -1,3 +1 @@
 package copybackup
-
-var GetFileList = getFileList