diff --git a/README.md b/README.md index 0a60a832..ff25f7d4 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ However, she no longer has the time to work on it so I am its new maintainer. Use `drive help` for further reference. $ drive version + $ drive help cmd e.g drive help push $ drive init [path] $ drive pull [-r -no-prompt path1 path2 path3 ...] # pulls from remotes $ drive pull [-r -no-prompt -hidden path] # pulls even hidden paths from remote diff --git a/about.go b/about.go index 3e93878a..a7ec7e14 100644 --- a/about.go +++ b/about.go @@ -34,8 +34,8 @@ func (g *Commands) Quota() (err error) { freeBytes := about.QuotaBytesTotal - about.QuotaBytesUsed fmt.Printf( - "Account type: %s\nBytes Used: %20d (%s)\n"+ - "Bytes Free: %20d (%s)\nTotal Bytes: %20d (%s)\n", + "Account type:\t%s\nBytes Used:\t%-20d (%s)\n"+ + "Bytes Free:\t%-20d (%s)\nTotal Bytes:\t%-20d (%s)\n", about.QuotaType, about.QuotaBytesUsed, prettyBytes(about.QuotaBytesUsed), freeBytes, prettyBytes(freeBytes), diff --git a/cmd/drive/main.go b/cmd/drive/main.go index a555d727..ffbd0fb2 100644 --- a/cmd/drive/main.go +++ b/cmd/drive/main.go @@ -31,25 +31,8 @@ import ( ) var context *config.Context - -var Version = "0.0.4a" var DefaultMaxProcs = runtime.NumCPU() -const ( - descInit = "inits a directory and authenticates user" - descPull = "pulls remote changes from google drive" - descPush = "push local changes to google drive" - descDiff = "compares a local file with remote" - descEmptyTrash = "cleans out your trash" - descList = "lists the contents of remote path" - descQuota = "prints out the space information" - descPublish = "publishes a file and prints its publicly available url" - descTrash = "moves the file to trash" - descUntrash = "restores the file from trash" - descUnpublish = "revokes public access to a file" - descVersion = "prints the version" -) - func main() { maxProcs, err := strconv.ParseInt(os.Getenv("GOMAXPROCS"), 10, 0) if err != nil || maxProcs < 1 { @@ -57,21 +40,38 @@ func main() { } runtime.GOMAXPROCS(int(maxProcs)) - command.On("diff", descDiff, &diffCmd{}, []string{}) - command.On("init", descInit, &initCmd{}, []string{}) - command.On("list", descList, &listCmd{}, []string{}) - command.On("pull", descPull, &pullCmd{}, []string{}) - command.On("push", descPush, &pushCmd{}, []string{}) - command.On("pub", descPublish, &publishCmd{}, []string{}) - command.On("emptytrash", descEmptyTrash, &emptyTrashCmd{}, []string{}) - command.On("quota", descQuota, "aCmd{}, []string{}) - command.On("trash", descTrash, &trashCmd{}, []string{}) - command.On("untrash", descUntrash, &untrashCmd{}, []string{}) - command.On("unpub", descUnpublish, &unpublishCmd{}, []string{}) - command.On("version", descVersion, &versionCmd{}, []string{}) + command.On("diff", drive.DescDiff, &diffCmd{}, []string{}) + command.On("init", drive.DescInit, &initCmd{}, []string{}) + command.On("list", drive.DescList, &listCmd{}, []string{}) + command.On("pull", drive.DescPull, &pullCmd{}, []string{}) + command.On("push", drive.DescPush, &pushCmd{}, []string{}) + command.On("pub", drive.DescPublish, &publishCmd{}, []string{}) + command.On("emptytrash", drive.DescEmptyTrash, &emptyTrashCmd{}, []string{}) + command.On("help", drive.DescHelp, &helpCmd{}, []string{}) + command.On("quota", drive.DescQuota, "aCmd{}, []string{}) + command.On("trash", drive.DescTrash, &trashCmd{}, []string{}) + command.On("untrash", drive.DescUntrash, &untrashCmd{}, []string{}) + command.On("unpub", drive.DescUnpublish, &unpublishCmd{}, []string{}) + command.On("version", drive.Version, &versionCmd{}, []string{}) command.ParseAndRun() } +type helpCmd struct { + args []string +} + +func (cmd *helpCmd) Flags(fs *flag.FlagSet) *flag.FlagSet { + return fs +} + +func (cmd *helpCmd) Run(args []string) { + if len(args) < 1 { + exitWithError(fmt.Errorf("help for more usage")) + } + drive.ShowDescription(args[0]) + exitWithError(nil) +} + type versionCmd struct{} func (cmd *versionCmd) Flags(fs *flag.FlagSet) *flag.FlagSet { @@ -79,7 +79,7 @@ func (cmd *versionCmd) Flags(fs *flag.FlagSet) *flag.FlagSet { } func (cmd *versionCmd) Run(args []string) { - fmt.Printf("drive version %s\n", Version) + fmt.Printf("drive version %s\n", drive.Version) exitWithError(nil) } diff --git a/help.go b/help.go new file mode 100644 index 00000000..95569490 --- /dev/null +++ b/help.go @@ -0,0 +1,72 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package drive + +import ( + "fmt" +) + +var Version = "0.0.4b" + +const ( + DescInit = "inits a directory and authenticates user" + DescPull = "pulls remote changes from google drive" + DescPush = "push local changes to google drive" + DescDiff = "compares a local file with remote" + DescEmptyTrash = "cleans out your trash" + DescHelp = "Get help for a topic" + DescList = "lists the contents of remote path" + DescQuota = "prints out the space information" + DescPublish = "publishes a file and prints its publicly available url" + DescTrash = "moves the file to trash" + DescUntrash = "restores the file from trash" + DescUnpublish = "revokes public access to a file" + DescVersion = "prints the version" +) + +var shortToCmd = map[string][]string{ + "diff": []string{DescDiff, "Accepts multiple paths for comparison"}, + "emptytrash": []string{DescEmptyTrash}, + "init": []string{DescInit, "This is where you drive credentials will be placed"}, + "pull": []string{DescPull, "Accepts multiple paths"}, + "push": []string{ + DescPush, "Accepts multiple paths", "Push comes in a couple of flavors", + "\t* Ordinary push: `drive push path1 path2 path3`", + "\t* Mounted push: `drive push -m path1 [path2 path3] drive_context_path`", + }, + "list": []string{DescList, "Accepts multiple paths"}, + "quota": []string{DescQuota}, + "trash": []string{DescTrash, "Accepts multiple paths"}, + "untrash": []string{DescUntrash, "Accepts multiple paths"}, + "pub": []string{DescPublish, "Accepts multiple paths"}, + "unpub": []string{DescUnpublish, "Accepts multiple paths"}, + "version": []string{DescVersion, fmt.Sprintf("current version is: %s", Version)}, +} + +func ShowDescription(topic string) { + help, ok := shortToCmd[topic] + if !ok { + fmt.Printf("Unkown command '%s' type `drive help` for usage\n", topic) + } else { + description, documentation := help[0], help[1:] + fmt.Printf("Name\n\t%s - %s\n", topic, description) + if len(documentation) >= 1 { + fmt.Println("Description") + for _, line := range documentation { + fmt.Printf("\t%s\n", line) + } + } + } +} diff --git a/list.go b/list.go index b022a549..18e558f9 100644 --- a/list.go +++ b/list.go @@ -21,6 +21,10 @@ import ( "strings" ) +const ( + DriveAbsRootPath = "My Drive" +) + var BytesPerKB = float64(1024) type byteDescription func(b int64) string @@ -139,7 +143,7 @@ func (f *File) pretty(opt attribute) { fmt.Printf("%-10s ", f.UserPermission.Role) } fPath := fmt.Sprintf("%s/%s", opt.parent, f.Name) - fmt.Printf("%-10s %-6s %s", prettyBytes(f.Size), fPath, f.ModTime) + fmt.Printf("%-10s\t%-60s\t\t%-20s", prettyBytes(f.Size), fPath, f.ModTime) fmt.Println() } @@ -161,7 +165,7 @@ func (g *Commands) breadthFirst(parentId, parent, child string, depth int, inTra expr = fmt.Sprintf("'%s' in parents and trashed=false", parentId) } headPath := "" - if parent != "" { + if parent != "" && parent != DriveAbsRootPath { headPath = parent } if child != "" { diff --git a/pull.go b/pull.go index b8babf56..fc7fca98 100644 --- a/pull.go +++ b/pull.go @@ -116,11 +116,14 @@ func (g *Commands) localAdd(wg *sync.WaitGroup, change *Change, exports []string // make parent's dir if not exists destAbsDir := g.context.AbsPathOf(change.Parent) - os.MkdirAll(destAbsDir, os.ModeDir|0755) - if err != nil { - return + if destAbsDir != destAbsPath { + err = os.MkdirAll(destAbsDir, os.ModeDir|0755) + if err != nil { + return err + } } + if change.Src.IsDir { return os.Mkdir(destAbsPath, os.ModeDir|0755) }