示例#1
0
func Unzip(call []string) error {

	flagSet := uggo.NewFlagSetDefault("unzip", "[options] file.zip [list]", VERSION)
	destDir := "."
	flagSet.StringVar(&destDir, "d", destDir, "destination directory")
	test := false
	flagSet.BoolVar(&test, "t", test, "test archive data")

	err := flagSet.Parse(call[1:])
	if err != nil {
		return err
	}
	if flagSet.ProcessHelpOrVersion() {
		return nil
	}
	args := flagSet.Args()
	if len(args) < 1 {
		return errors.New("No zip filename given")
	}
	zipname := args[0]
	files := args[1:]
	if test {
		err = TestItems(zipname, files)
		if err != nil {
			return err
		}
	} else {
		err = UnzipItems(zipname, destDir, files)
		if err != nil {
			return err
		}
	}
	return nil
}
示例#2
0
func Rm(call []string) error {
	options := RmOptions{}
	flagSet := uggo.NewFlagSetDefault("rm", "[options] [files...]", VERSION)
	flagSet.BoolVar(&options.IsRecursive, "r", false, "Recurse into directories")

	e := flagSet.Parse(call[1:])
	if e != nil {
		return e
	}
	if flagSet.ProcessHelpOrVersion() {
		return nil
	}
	for _, fileGlob := range flagSet.Args() {
		files, err := filepath.Glob(fileGlob)
		if err != nil {
			return err
		}
		for _, file := range files {
			e := delete(file, options.IsRecursive)
			if e != nil {
				return e
			}
		}
	}

	return nil
}
示例#3
0
func Gunzip(call []string) error {
	options := GunzipOptions{}
	flagSet := uggo.NewFlagSetDefault("gunzip", "[options] file.gz [list]", VERSION)
	flagSet.AliasedBoolVar(&options.IsTest, []string{"t", "test"}, false, "test archive data")
	flagSet.AliasedBoolVar(&options.IsKeep, []string{"k", "keep"}, false, "keep gzip file")

	err := flagSet.Parse(call[1:])
	if err != nil {
		return err
	}
	if flagSet.ProcessHelpOrVersion() {
		return nil
	}
	args := flagSet.Args()
	//TODO STDIN support
	if len(args) < 1 {
		return errors.New("No gzip filename given")
	}
	if options.IsTest {
		err = TestGzipItems(args)
		if err != nil {
			return err
		}
	} else {
		err = GunzipItems(args, options)
		if err != nil {
			return err
		}
	}
	return nil
}
示例#4
0
func Which(call []string) error {
	options := WhichOptions{}
	flagSet := uggo.NewFlagSetDefault("which", "[-a] args", VERSION)
	flagSet.BoolVar(&options.all, "a", false, "Print all matching executables in PATH, not just the first.")

	err := flagSet.Parse(call[1:])
	if err != nil {
		println("Error parsing flags")
		return err
	}
	if flagSet.ProcessHelpOrVersion() {
		return nil
	}

	args := flagSet.Args()
	path := os.Getenv("PATH")
	if runtime.GOOS == "windows" {
		path = ".;" + path
	}
	pl := filepath.SplitList(path)
	for _, arg := range args {
		checkPathParts(arg, pl, options)
		/*
			if err != nil {
				return err
			}*/
	}
	return nil
}
示例#5
0
// ParseFlags parses commandline options.
func (tr *SomeTr) ParseFlags(call []string, errWriter io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("tr", "[OPTION]... SET1 [SET2]", someutils.VERSION)
	flagSet.SetOutput(errWriter)
	flagSet.AliasedBoolVar(&tr.IsDelete, []string{"d", "delete"}, false, "Delete characters in SET1, do not translate")
	flagSet.AliasedBoolVar(&tr.IsSqueeze, []string{"s", "squeeze-repeats"}, false, "replace each input sequence of a repeated character that is listed in SET1 with a single occurence of that character")
	//Don't get the Complement thing. Just don't understand it right now.
	flagSet.AliasedBoolVar(&tr.IsComplement, []string{"c", "complement"}, false, "use the complement of SET1")
	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	sets := flagSet.Args()
	if len(sets) > 0 {
		tr.set1 = sets[0]
	} else {
		return errors.New("Not enough args supplied"), 1
	}
	if len(sets) > 1 {
		tr.set2 = sets[1]
	} else if !tr.IsDelete {
		return errors.New("Not enough args supplied"), 1
	}
	err = tr.Preprocess()
	if err != nil {
		return err, 1
	}
	return nil, 0
}
示例#6
0
// ParseFlags parses flags from a commandline []string
func (grep *SomeGrep) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("grep", "[options] PATTERN [files...]", someutils.VERSION)
	flagSet.SetOutput(errPipe)
	flagSet.AliasedBoolVar(&grep.IsPerl, []string{"P", "perl-regexp"}, false, "Perl-style regex")
	flagSet.AliasedBoolVar(&grep.IsExtended, []string{"E", "extended-regexp"}, true, "Extended regex (default)")
	flagSet.AliasedBoolVar(&grep.IsIgnoreCase, []string{"i", "ignore-case"}, false, "ignore case")
	flagSet.AliasedBoolVar(&grep.IsPrintFilename, []string{"H", "with-filename"}, true, "print the file name for each match")
	flagSet.AliasedBoolVar(&grep.IsPrintLineNumber, []string{"n", "line-number"}, false, "print the line number for each match")
	flagSet.AliasedBoolVar(&grep.IsInvertMatch, []string{"v", "invert-match"}, false, "invert match")
	// disable for now
	//	flagSet.AliasedBoolVar(&grep.IsRecurse, []string{"r", "recurse"}, false, "recurse into subdirectories")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	args := flagSet.Args()
	if len(args) < 1 {
		flagSet.Usage()
		return errors.New("Not enough args"), 1
	}
	grep.pattern = args[0]

	if len(args) > 1 {
		grep.globs = args[1:]
	} else {
		grep.globs = []string{}
	}

	return nil, 0
}
示例#7
0
func Ln(call []string) error {
	options := LnOptions{}
	flagSet := uggo.NewFlagSetDefault("ln", "[options] TARGET LINK_NAME", VERSION)
	flagSet.BoolVar(&options.IsSymbolic, "s", false, "Symbolic")
	flagSet.BoolVar(&options.IsForce, "f", false, "Force")

	e := flagSet.Parse(call[1:])
	if e != nil {
		println("Error parsing flags")
		return e
	}
	if flagSet.ProcessHelpOrVersion() {
		return nil
	}

	args := flagSet.Args()
	if len(args) < 2 {
		flagSet.Usage()
		return errors.New("Not enough args!")
	}
	target := args[0]
	linkName := args[1]
	return makeLink(target, linkName, options)

}
示例#8
0
func Grep(call []string) error {

	options := GrepOptions{}
	flagSet := uggo.NewFlagSetDefault("grep", "[options] PATTERN [files...]", VERSION)
	flagSet.AliasedBoolVar(&options.IsPerl, []string{"P", "perl-regexp"}, false, "Perl-style regex")
	flagSet.AliasedBoolVar(&options.IsExtended, []string{"E", "extended-regexp"}, true, "Extended regex (default)")
	flagSet.AliasedBoolVar(&options.IsIgnoreCase, []string{"i", "ignore-case"}, false, "ignore case")
	flagSet.AliasedBoolVar(&options.IsPrintFilename, []string{"H", "with-filename"}, true, "print the file name for each match")
	flagSet.AliasedBoolVar(&options.IsPrintLineNumber, []string{"n", "line-number"}, false, "print the line number for each match")
	flagSet.AliasedBoolVar(&options.IsInvertMatch, []string{"v", "invert-match"}, false, "invert match")
	// disable for now
	//	flagSet.AliasedBoolVar(&options.IsRecurse, []string{"r", "recurse"}, false, "recurse into subdirectories")

	err := flagSet.Parse(call[1:])
	if err != nil {
		flagSet.Usage()
		return err
	}
	if flagSet.ProcessHelpOrVersion() {
		return nil
	}
	args := flagSet.Args()
	if len(args) < 1 {
		flagSet.Usage()
		return errors.New("Not enough args")
	}
	pattern := args[0]
	reg, err := compile(pattern, options)
	if err != nil {
		return err
	}

	globs := []string{}
	if len(args) > 1 {
		globs = args[1:]
		files := []string{}
		for _, glob := range globs {
			results, err := filepath.Glob(glob)
			if err != nil {
				return err
			}
			if len(results) < 1 { //no match
				return errors.New("grep: cannot access " + glob + ": No such file or directory")
			}
			files = append(files, results...)
		}
		return grep(reg, files, options)
	} else {
		if uggo.IsPipingStdin() {
			//check STDIN
			return grepReader(os.Stdin, "", reg, options)
		} else {
			//NOT piping.
			return errors.New("Not enough args")
		}
	}
}
示例#9
0
// ParseFlags parses flags from a commandline []string
func (pwd *SomePwd) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("pwd", "", someutils.VERSION)
	flagSet.SetOutput(errPipe)

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	return nil, 0
}
示例#10
0
// ParseFlags parses flags from a commandline []string
func (dirname *SomeDirname) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("dirname", "[options] NAME...", someutils.VERSION)
	flagSet.SetOutput(errPipe)

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	dirname.Filenames = flagSet.Args()
	return nil, 0
}
示例#11
0
// ParseFlags parses flags from a commandline []string
func (tee *SomeTee) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("tee", "[OPTION]... [FILE]...", someutils.VERSION)
	flagSet.SetOutput(errPipe)
	flagSet.AliasedBoolVar(&tee.isAppend, []string{"a", "append"}, false, "Append instead of overwrite")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}

	tee.args = flagSet.Args()
	return nil, 0
}
示例#12
0
// ParseFlags parses flags from a commandline []string
func (which *SomeWhich) ParseFlags(call []string, errWriter io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("which", "[options] [args...]", someutils.VERSION)
	flagSet.SetOutput(errWriter)

	flagSet.BoolVar(&which.all, "a", false, "Print all matching executables in PATH, not just the first.")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}

	which.args = flagSet.Args()
	return nil, 0
}
示例#13
0
// ParseFlags parses flags from a commandline []string
func (rm *SomeRm) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("rm", "[options] [files...]", someutils.VERSION)
	flagSet.SetOutput(errPipe)

	flagSet.BoolVar(&rm.IsRecursive, "r", false, "Recurse into directories")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}

	rm.fileGlobs = flagSet.Args()
	return nil, 0
}
示例#14
0
// ParseFlags parses flags from a commandline []string
func (head *SomeHead) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("head", "[options] [args...]", someutils.VERSION)
	flagSet.SetOutput(errPipe)

	flagSet.AliasedIntVar(&head.lines, []string{"n", "lines"}, 10, "number of lines to print")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	//could be nil
	head.Filenames = flagSet.Args()
	return nil, 0
}
示例#15
0
// ParseFlags parses flags from a commandline []string
func (touch *SomeTouch) ParseFlags(call []string, errWriter io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("touch", "[options] [files...]", someutils.VERSION)
	flagSet.SetOutput(errWriter)

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}

	args := flagSet.Args()
	if len(args) < 1 {
		return errors.New("Not enough args given"), 1
	}
	touch.args = args
	return nil, 0
}
示例#16
0
// ParseFlags parses flags from a commandline []string
func (tail *SomeTail) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("tail", "[options] [args...]", someutils.VERSION)
	flagSet.SetOutput(errPipe)

	flagSet.AliasedIntVar(&tail.Lines, []string{"n", "lines"}, 10, "number of lines to print")
	flagSet.AliasedFloat64Var(&tail.SleepInterval, []string{"s", "sleep"}, 1.0, "how long to sleep")
	//TODO!
	//flagSet.AliasedStringVar(&options.Follow, []string{"f", "follow"}, "", "follow (name|descriptor). Default is by descriptor (unsupported so far!!)")
	flagSet.BoolVar(&tail.FollowByName, "F", false, "follow by name")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	tail.Filenames = flagSet.Args()
	return nil, 0
}
示例#17
0
// ParseFlags parses flags from a commandline []string
func (z *SomeZip) ParseFlags(call []string, errWriter io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("zip", "[options] [files...]", someutils.VERSION)
	flagSet.SetOutput(errWriter)

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	args := flagSet.Args()
	if len(args) < 2 {
		flagSet.Usage()
		return errors.New("Not enough args given"), 1
	}
	z.zipFilename = args[0]
	z.items = args[1:]
	return nil, 0
}
示例#18
0
// ParseFlags parses flags from a commandline []string
func (wc *SomeWc) ParseFlags(call []string, errWriter io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("wc", "[OPTION]... [FILE]...", someutils.VERSION)
	flagSet.SetOutput(errWriter)

	// TODO add flags here
	flagSet.AliasedBoolVar(&wc.IsLines, []string{"l", "lines"}, false, "Count lines")
	flagSet.AliasedBoolVar(&wc.IsWords, []string{"w", "words"}, false, "Count words")
	//	flagSet.AliasedBoolVar(&wc.IsChars, []string{"m", "chars"}, false, "Count characters")
	flagSet.AliasedBoolVar(&wc.IsBytes, []string{"c", "bytes"}, false, "Count bytes")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}

	wc.args = flagSet.Args()
	return nil, 0
}
示例#19
0
func Pwd(call []string) error {

	flagSet := uggo.NewFlagSetDefault("pwd", "", VERSION)

	err := flagSet.Parse(call[1:])
	if err != nil {
		return err
	}
	if flagSet.ProcessHelpOrVersion() {
		return nil
	}
	wd, err := os.Getwd()
	if err != nil {
		return err
	}
	println(wd)
	return nil
}
示例#20
0
// ParseFlags parses flags from a commandline []string
func (basename *SomeBasename) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("basename", "", someutils.VERSION)
	flagSet.SetOutput(errPipe)
	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	if len(flagSet.Args()) < 1 {
		return errors.New("Missing operand"), 1
	}
	if len(flagSet.Args()) > 1 {
		basename.RelativeTo = flagSet.Args()[0]
		basename.InputPath = flagSet.Args()[1]
	} else {
		basename.InputPath = flagSet.Args()[0]
	}
	return nil, 1
}
示例#21
0
func (cat *SomeCat) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("cat", "[options] [files...]", someutils.VERSION)
	flagSet.SetOutput(errPipe)
	flagSet.AliasedBoolVar(&cat.IsShowEnds, []string{"E", "show-ends"}, false, "display $ at end of each line")
	flagSet.AliasedBoolVar(&cat.IsNumber, []string{"n", "number"}, false, "number all output lines")
	flagSet.AliasedBoolVar(&cat.IsSqueezeBlank, []string{"s", "squeeze-blank"}, false, "squeeze repeated empty output lines")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}

	if len(flagSet.Args()) > 0 {
		cat.FileNames = flagSet.Args()
	}
	// else it's coming from STDIN
	return nil, 0
}
示例#22
0
// ParseFlags parses flags from a commandline []string
func (ls *SomeLs) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("ls", "[options] [dirs...]", someutils.VERSION)
	flagSet.SetOutput(errPipe)

	flagSet.BoolVar(&ls.LongList, "l", false, "Long, detailed listing")
	flagSet.AliasedBoolVar(&ls.Recursive, []string{"R", "recursive"}, false, "Recurse into directories")
	flagSet.AliasedBoolVar(&ls.Human, []string{"h", "human-readable"}, false, "Output sizes in a human readable format")
	flagSet.AliasedBoolVar(&ls.AllFiles, []string{"a", "all"}, false, "Show all files (including dotfiles)")
	flagSet.BoolVar(&ls.OnePerLine, "1", false, "One entry per line")
	flagSet.AliasedBoolVar(&ls.Stdin, []string{"z", "stdin"}, false, "Read from stdin")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	//fmt.Fprintf(errPipe, "ls args: %+v\n", flagSet.Args())
	ls.globs = flagSet.Args()
	return nil, 0
}
示例#23
0
// ParseFlags parses flags from a commandline []string
func (gz *SomeGzip) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("gzip", "[options] [files...]", someutils.VERSION)
	flagSet.SetOutput(errPipe)

	flagSet.AliasedBoolVar(&gz.IsKeep, []string{"k", "keep"}, false, "keep gzip file")
	flagSet.AliasedBoolVar(&gz.IsStdout, []string{"c", "stdout", "to-stdout"}, false, "pipe output to standard out. Keep source file.")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	args := flagSet.Args()
	//TODO STDIN support
	if len(args) < 1 {
		flagSet.Usage()
		return errors.New("Not enough args given"), 1
	}
	gz.Filenames = args
	return nil, 0
}
示例#24
0
// ParseFlags parses flags from a commandline []string
func (cd *SomeCd) ParseFlags(call []string, errPipe io.Writer) error {
	flagSet := uggo.NewFlagSetDefault("cd", "[options] [args...]", VERSION)
	flagSet.SetOutput(errPipe)

	// TODO add flags here

	err := flagSet.Parse(call[1:])
	if err != nil {
		fmt.Fprintf(errPipe, "Flag error:  %v\n\n", err.Error())
		flagSet.Usage()
		return err
	}

	if flagSet.ProcessHelpOrVersion() {
		return nil
	}

	// TODO: validate and process flagSet.Args()
	return nil
}
示例#25
0
func mv(call []string) error {
	flagSet := uggo.NewFlagSetDefault("mv", "[options] [src...] [dest]", VERSION)

	err := flagSet.Parse(call[1:])
	if err != nil {
		fmt.Fprintf(os.Stderr, "Flag error:  %v\n\n", err.Error())
		flagSet.Usage()
		return err
	}
	if flagSet.ProcessHelpOrVersion() {
		return nil
	}
	args := flagSet.Args()

	if len(args) < 2 {
		fmt.Fprintf(os.Stderr, "Error: not enough arguments\n\n")
		flagSet.Usage()
		return errors.New("Not enough arguments")
	}

	srcGlobs := args[0 : len(args)-1]
	dest := args[len(args)-1]
	for _, srcGlob := range srcGlobs {
		srces, err := filepath.Glob(srcGlob)
		if err != nil {
			return err
		}
		if len(srces) < 1 {
			return errors.New(fmt.Sprintf("Source glob '%s' does not match any files\n", srcGlob))
		}

		for _, src := range srces {
			err = moveFile(src, dest)
			if err != nil {
				fmt.Fprintf(os.Stderr, "Error %v\n", err)
				return err
			}
		}
	}
	return nil
}
示例#26
0
// ParseFlags parses flags from a commandline []string
func (unzip *SomeUnzip) ParseFlags(call []string, errWriter io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("unzip", "[options] file.zip [list...]", someutils.VERSION)
	flagSet.SetOutput(errWriter)
	destDir := "."
	flagSet.StringVar(&unzip.destDir, "d", destDir, "destination directory")
	test := false
	flagSet.BoolVar(&unzip.isTest, "t", test, "test archive data")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	args := flagSet.Args()
	if len(args) < 1 {
		return errors.New("No zip filename given"), 1
	}
	unzip.zipname = args[0]
	unzip.files = args[1:]

	return nil, 0
}
示例#27
0
func Zip(call []string) error {
	flagSet := uggo.NewFlagSetDefault("zip", "[options] [files...]", VERSION)
	err := flagSet.Parse(call[1:])
	if err != nil {
		flagSet.Usage()
		return err
	}
	if flagSet.ProcessHelpOrVersion() {
		return nil
	}
	args := flagSet.Args()
	if len(args) < 2 {
		flagSet.Usage()
		return errors.New("Not enough args given")
	}
	err = ZipItems(args[0], args[1:])
	if err != nil {
		return err
	}
	return nil
}
示例#28
0
// ParseFlags parses flags from a commandline []string
func (cp *SomeCp) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("cp", "[options] [src...] [dest]", someutils.VERSION)
	flagSet.AliasedBoolVar(&cp.IsRecursive, []string{"R", "r", "recursive"}, false, "Recurse into directories")
	flagSet.SetOutput(errPipe)

	// TODO add flags here
	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}
	args := flagSet.Args()
	if len(args) < 2 {
		flagSet.Usage()
		return errors.New("Not enough args"), 1
	}

	cp.SrcGlobs = args[0 : len(args)-1]
	cp.Dest = args[len(args)-1]

	return nil, 0
}
示例#29
0
// ParseFlags parses flags from a commandline []string
func (xargs *SomeXargs) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("xargs", "[options] [args...]", someutils.VERSION)
	flagSet.SetOutput(errPipe)
	// TODO multiple processes at once ?
	flagSet.AliasedIntVar(&xargs.maxProcesses, []string{"P", "max-procs"}, 1, "Maximum processes")
	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}

	args := flagSet.Args()
	if len(args) < 1 {
		return errors.New("No command specified"), 1
	}
	if !someutils.Exists(args[0]) {
		return errors.New("Command does not exist."), 1
	}
	xargs.utilFactory = someutils.GetCliPipableFactory(args[0])
	xargs.utilArgs = args
	return nil, 0
}
示例#30
0
// ParseFlags parses flags from a commandline []string
func (t *SomeTar) ParseFlags(call []string, errPipe io.Writer) (error, int) {
	flagSet := uggo.NewFlagSetDefault("tar", "[option...] [FILE...]", someutils.VERSION)
	flagSet.SetOutput(errPipe)
	flagSet.AliasedBoolVar(&t.IsCreate, []string{"c", "create"}, false, "create a new archive")
	flagSet.AliasedBoolVar(&t.IsAppend, []string{"r", "append"}, false, "append files to the end of an archive")
	flagSet.AliasedBoolVar(&t.IsList, []string{"t", "list"}, false, "list the contents of an archive")
	flagSet.AliasedBoolVar(&t.IsExtract, []string{"x", "extract", "get"}, false, "extract files from an archive")
	flagSet.AliasedBoolVar(&t.IsVerbose, []string{"v", "verbose"}, false, "verbosely list files processed")
	flagSet.AliasedStringVar(&t.ArchiveFilename, []string{"f", "file"}, "", "use given archive file or device")

	err, code := flagSet.ParsePlus(call[1:])
	if err != nil {
		return err, code
	}

	if countTrue(t.IsCreate, t.IsAppend, t.IsList, t.IsExtract) != 1 {
		return errors.New("You must use *one* of -c, -t, -x, -r (create, list, extract or append), plus -f"), 1
	}
	t.args = flagSet.Args()

	return nil, 0
}