Skip to content
This repository has been archived by the owner on Nov 10, 2020. It is now read-only.

Commit

Permalink
use a nicer argparser
Browse files Browse the repository at this point in the history
  • Loading branch information
luludotdev committed May 26, 2019
1 parent f03c791 commit 1f70fba
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 75 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -39,3 +39,4 @@ release:
deps:
$(GOGET) github.com/bmatcuk/doublestar
$(GOGET) github.com/TomOnTime/utfutil
$(GOGET) github.com/ttacon/chalk
163 changes: 163 additions & 0 deletions src/flag.go
@@ -0,0 +1,163 @@
package main

import (
"flag"
"fmt"
"os"
"reflect"
"sort"
)

type betterFlag struct {
usage string
shortName string
longName string
description string
}

var (
usageRegistered = false
hasParsed = false

cliName string
cliLink string
cliExample string

flags []betterFlag
)

// RegisterStringFlag Registers a string flag
func RegisterStringFlag(reference *string, shortName string, longName string, description string) {
registerUsage()

defaultValue := *reference
flag.StringVar(reference, longName, *reference, description)
flag.StringVar(reference, shortName, *reference, description)

var usage string
if defaultValue != "" {
usage = "[string]"
} else {
usage = "string"
}

f := betterFlag{usage, shortName, longName, description}
flags = append(flags, f)
}

// RegisterBoolFlag Registers a boolean flag
func RegisterBoolFlag(reference *bool, shortName string, longName string, description string) {
registerUsage()

flag.BoolVar(reference, longName, *reference, description)
flag.BoolVar(reference, shortName, *reference, description)
usage := ""

f := betterFlag{usage, shortName, longName, description}
flags = append(flags, f)
}

// RegisterUintFlag Registers a uint flag
func RegisterUintFlag(reference *uint, shortName string, longName string, description string) {
registerUsage()

defaultValue := *reference
flag.UintVar(reference, longName, *reference, description)
flag.UintVar(reference, shortName, *reference, description)

var usage string
if defaultValue != 0 {
usage = "[uint]"
} else {
usage = "uint"
}

f := betterFlag{usage, shortName, longName, description}
flags = append(flags, f)
}

// SetDetails Set CLI details
func SetDetails(name string, link string) {
cliName = name
cliLink = link
}

// SetExample Set CLI example command
func SetExample(example string) {
cliExample = example
}

// ParseFlags Parses flags and returns extra args
func ParseFlags(args *[]string) {
if hasParsed == true {
return
}

hasParsed = true
flag.Parse()

flagArgs := flag.Args()
reflect.ValueOf(args).Elem().Set(reflect.ValueOf(flagArgs))
}

func registerUsage() {
if usageRegistered == true {
return
}

usageRegistered = true
flag.Usage = func() {
PrintUsage()
}

helpFlag := betterFlag{
shortName: "h",
longName: "help",
description: "Prints this help information."}
flags = append(flags, helpFlag)
}

// PrintUsage prints CLI flags usage
func PrintUsage() {
fmt.Println(cliName)
fmt.Println(cliLink)
fmt.Print("\n")

var (
maxShortName int
maxLongName int
)

for _, f := range flags {
if len(f.shortName) > maxShortName {
maxShortName = len(f.shortName)
}

combined := len(f.longName + " " + f.usage)
if combined > maxLongName {
maxLongName = combined
}
}

fmt.Println(" Flags:")
sort.Slice(flags, func(i, j int) bool {
return flags[i].shortName < flags[j].shortName
})

for _, f := range flags {
fmt.Printf(" -%-*v", maxShortName+1, f.shortName)
fmt.Printf("--%-*v", maxLongName+4, f.longName+" "+f.usage)
fmt.Println(f.description)
}

if cliExample != "" {
fmt.Println("\n Example:")
fmt.Printf(" %v\n", cliExample)
}
}

// PrintUsageAndExit prints CLI flags usage and exits
func PrintUsageAndExit() {
PrintUsage()
os.Exit(1)
}
17 changes: 17 additions & 0 deletions src/log.go
@@ -0,0 +1,17 @@
package main

import (
"fmt"
"os"

"github.com/ttacon/chalk"
)

func printError(msg string) {
fmt.Println(chalk.Red.Color("[ERROR]") + " " + msg)
os.Exit(1)
}

func printWarning(msg string) {
fmt.Println(chalk.Yellow.Color("[WARNING]") + " " + msg)
}
100 changes: 41 additions & 59 deletions src/main.go
@@ -1,76 +1,53 @@
package main

import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"

"github.com/bmatcuk/doublestar"
"github.com/ttacon/chalk"
)

var (
sha1ver string
sha1ver = "unknown"
gitTag string
)

func registerStringFlag(p *string, name string, alias string, def string, usage string) {
flag.StringVar(p, name, def, usage)
flag.StringVar(p, alias, def, usage+" (short)")
}
printVer bool
printHelp bool

func registerBoolFlag(p *bool, name string, alias string, def bool, usage string) {
flag.BoolVar(p, name, def, usage)
flag.BoolVar(p, alias, def, usage+" (alias of -"+name+")")
}
concurrency uint = 5
output = ""
glob = ""
allDirs = false
keepFiles = false
dryRun = false
quiet = false

func registerIntFlag(p *int, name string, alias string, def int, usage string) {
flag.IntVar(p, name, def, usage)
flag.IntVar(p, alias, def, usage+" (alias of -"+name+")")
}
args []string
)

func main() {
var (
printVersion bool
concurrency int
output string
glob string
allDirs bool
keepFiles bool
dryRun bool
quiet bool
)

registerBoolFlag(&printVersion, "version", "v", false, "print version information")
registerIntFlag(&concurrency, "concurrency", "c", 5, "max number of jobs allowed to run at a time")
registerBoolFlag(&allDirs, "all-dirs", "a", false, "run on all subfolders of given directory")
registerStringFlag(&glob, "glob", "g", "", "run a glob match in a given directory")
registerBoolFlag(&keepFiles, "keep-orig", "k", false, "do not delete original JSON files")
registerStringFlag(&output, "output", "o", "", "save converted hashes and errors to file")
registerBoolFlag(&dryRun, "dry-run", "d", false, "don't modify filesystem, only log output")
registerBoolFlag(&quiet, "quiet", "q", false, "don't print to stdout")
SetDetails("Songe Converter "+gitTag, "https://github.com/lolPants/songe-converter")
SetExample("./songe-converter -g '**/info.json' ./CustomSongs")

RegisterBoolFlag(&printVer, "v", "version", "Print version information.")
RegisterUintFlag(&concurrency, "c", "concurrency", "Max number of jobs allowed to run at a time.")
RegisterStringFlag(&output, "o", "output", "Save converted hashes and errors to file.")
RegisterStringFlag(&glob, "g", "glob", "Use a glob to match directories.")
RegisterBoolFlag(&allDirs, "a", "all-dirs", "Run on all subfolders of given directory.")
RegisterBoolFlag(&keepFiles, "k", "keep-original", "Do not delete original JSON files")
RegisterBoolFlag(&dryRun, "d", "dry-run", "Do not modify filesystem, only log output.")
RegisterBoolFlag(&quiet, "q", "quiet", "Do not print to stdout.")
ParseFlags(&args)

if len(os.Args[1:]) == 0 {
if gitTag == "" {
fmt.Println("songe converter")
} else {
fmt.Println("songe converter " + gitTag)
}

fmt.Print("https://github.com/lolPants/songe-converter\n\nflags:\n")
flag.PrintDefaults()
PrintUsageAndExit()
return
}

flag.Parse()

if printVersion == true {
if sha1ver == "" {
sha1ver = "unknown"
}

if printVer == true {
if gitTag != "" {
fmt.Println(gitTag)
}
Expand All @@ -79,25 +56,30 @@ func main() {
return
}

if printHelp == true {
PrintUsageAndExit()
return
}

if concurrency < 1 {
fatalStr("--concurrency cannot be less than 1")
printError(chalk.Bold.TextStyle("--concurrency") + " cannot be less than 1!")
}

if allDirs == true && glob != "" {
fatalStr("--all-dirs and --glob cannot be used together!")
printError(chalk.Bold.TextStyle("--all-dirs") + " and " +
chalk.Bold.TextStyle("--glob") + " cannot be used together!")
}

dirs := make([]string, 0)
if allDirs == true || glob != "" {
var dir string

args := flag.Args()
if len(args) > 0 && args[0] != "" {
dir = args[0]
} else {
cwd, err := os.Getwd()
if err != nil {
fatal(err)
printError(err.Error())
}

dir = cwd
Expand All @@ -106,7 +88,7 @@ func main() {
if allDirs == true {
fileInfo, err := ioutil.ReadDir(dir)
if err != nil {
fatalStr("Could not list subdirectories of \"" + dir + "\"")
printError("Could not list subdirectories of \"" + dir + "\"")
}

for _, file := range fileInfo {
Expand All @@ -120,20 +102,20 @@ func main() {

paths, err := doublestar.Glob(pattern)
if err != nil {
fatalStr("Error matching glob path!")
printError("Error matching glob path!")
}

dirs = paths
}
} else {
dirs = flag.Args()
dirs = args
}

flags := CommandFlags{keepFiles, dryRun, quiet}
c := make(chan Result, len(dirs))

if flags.dryRun && !flags.quiet {
log.Print("WARNING: Performing a dry run!")
printWarning("Performing a dry run!")
}

sem := make(chan bool, concurrency)
Expand All @@ -159,7 +141,7 @@ func main() {
f, err := os.OpenFile(output, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
f.Close()
fatal(err)
printError(err.Error())
}

defer f.Close()
Expand Down
16 changes: 0 additions & 16 deletions src/panic.go

This file was deleted.

0 comments on commit 1f70fba

Please sign in to comment.