178 lines
4.6 KiB
Go
178 lines
4.6 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"os"
|
||
|
|
||
|
"multini/output"
|
||
|
"multini/types"
|
||
|
|
||
|
"github.com/juju/gnuflag"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
ArgInplace bool
|
||
|
ArgGet bool
|
||
|
ArgSet bool
|
||
|
ArgAdd bool
|
||
|
ArgDel bool
|
||
|
ArgChk bool
|
||
|
ArgVerbose bool
|
||
|
ArgVersion bool
|
||
|
ArgWindows bool
|
||
|
ArgUnix bool
|
||
|
ArgHelp bool
|
||
|
ArgExisting bool
|
||
|
ArgOutput string
|
||
|
|
||
|
ArgFile string
|
||
|
ArgFileIsSet bool = false
|
||
|
ArgSection string
|
||
|
ArgSectionIsSet bool = false
|
||
|
ArgKey string
|
||
|
ArgKeyIsSet bool = false
|
||
|
ArgValue string
|
||
|
ArgValueIsSet bool = false
|
||
|
)
|
||
|
|
||
|
func printHelp() {
|
||
|
output.Println("A utility for manipulating ini files with duplicate keys")
|
||
|
output.Println("")
|
||
|
output.Println("Usage: multini [OPTION]... [ACTION] config_file [section] [param] [value]")
|
||
|
output.Println("Actions:")
|
||
|
output.Println(" -g, --get get values for a given combination of parameters.")
|
||
|
output.Println(" -s, --set set values for a given combination of parameters.")
|
||
|
output.Println(" -a, --add add values for a given combination of parameters.")
|
||
|
output.Println(" -d, --del delete the given combination of parameters.")
|
||
|
output.Println(" -c, --chk display parsing errors for the specified file.")
|
||
|
output.Println("")
|
||
|
output.Println("Options:")
|
||
|
output.Println(" -e, --existing For --set and --del, fail if item is missing.")
|
||
|
output.Println(" -i, --inplace Lock and write files in place.")
|
||
|
output.Println(" This is not atomic but has less restrictions")
|
||
|
output.Println(" than the default replacement method.")
|
||
|
output.Println(" -o, --output FILE Write output to FILE instead. '-' means stdout")
|
||
|
// output.Println(" -v, --verbose Indicate on stderr if changes were made")
|
||
|
output.Println(" -u, --unix Use LF as end of line")
|
||
|
output.Println(" -w, --windows Use CRLF as end of line")
|
||
|
output.Println(" -h, --help Write this help to stdout")
|
||
|
output.Println(" --version Write version to stdout")
|
||
|
}
|
||
|
|
||
|
func printVersion() {
|
||
|
output.Println("multini ", Version)
|
||
|
}
|
||
|
|
||
|
func init() {
|
||
|
gnuflag.BoolVar(&ArgGet, "get", false, "")
|
||
|
gnuflag.BoolVar(&ArgGet, "g", false, "")
|
||
|
gnuflag.BoolVar(&ArgAdd, "add", false, "")
|
||
|
gnuflag.BoolVar(&ArgAdd, "a", false, "")
|
||
|
gnuflag.BoolVar(&ArgSet, "set", false, "")
|
||
|
gnuflag.BoolVar(&ArgSet, "s", false, "")
|
||
|
gnuflag.BoolVar(&ArgDel, "del", false, "")
|
||
|
gnuflag.BoolVar(&ArgDel, "d", false, "")
|
||
|
gnuflag.BoolVar(&ArgChk, "chk", false, "")
|
||
|
gnuflag.BoolVar(&ArgChk, "c", false, "")
|
||
|
gnuflag.BoolVar(&ArgDel, "inplace", false, "")
|
||
|
gnuflag.BoolVar(&ArgDel, "i", false, "")
|
||
|
gnuflag.BoolVar(&ArgUnix, "unix", false, "")
|
||
|
gnuflag.BoolVar(&ArgUnix, "u", false, "")
|
||
|
gnuflag.BoolVar(&ArgWindows, "windows", false, "")
|
||
|
gnuflag.BoolVar(&ArgWindows, "w", false, "")
|
||
|
gnuflag.BoolVar(&ArgExisting, "existing", false, "")
|
||
|
gnuflag.BoolVar(&ArgExisting, "e", false, "")
|
||
|
gnuflag.BoolVar(&ArgVerbose, "verbose", false, "")
|
||
|
gnuflag.BoolVar(&ArgVerbose, "v", false, "")
|
||
|
gnuflag.StringVar(&ArgOutput, "output", "", "")
|
||
|
gnuflag.StringVar(&ArgOutput, "o", "", "")
|
||
|
gnuflag.BoolVar(&ArgVersion, "version", false, "")
|
||
|
gnuflag.BoolVar(&ArgHelp, "help", false, "")
|
||
|
gnuflag.BoolVar(&ArgHelp, "h", false, "")
|
||
|
}
|
||
|
|
||
|
func parseArgs() error {
|
||
|
gnuflag.Parse(true)
|
||
|
|
||
|
// info
|
||
|
switch {
|
||
|
case ArgHelp:
|
||
|
printHelp()
|
||
|
os.Exit(EXIT_SUCCESS)
|
||
|
case ArgVersion:
|
||
|
printVersion()
|
||
|
os.Exit(EXIT_SUCCESS)
|
||
|
}
|
||
|
|
||
|
// File EOF
|
||
|
switch {
|
||
|
case ArgWindows:
|
||
|
types.SetEndOfLineWindows()
|
||
|
case ArgUnix:
|
||
|
types.SetEndOfLineUnix()
|
||
|
default:
|
||
|
types.SetEndOfLineNative()
|
||
|
}
|
||
|
|
||
|
// Output settings
|
||
|
output.SetEndOfLineNative()
|
||
|
output.SetVerbose(ArgVerbose)
|
||
|
|
||
|
// Positional Args
|
||
|
for i := 0; i < 4 && i < gnuflag.NArg(); i++ {
|
||
|
switch i {
|
||
|
case 0:
|
||
|
ArgFile = gnuflag.Arg(0)
|
||
|
ArgFileIsSet = true
|
||
|
case 1:
|
||
|
ArgSection = gnuflag.Arg(1)
|
||
|
ArgSectionIsSet = true
|
||
|
case 2:
|
||
|
ArgKey = gnuflag.Arg(2)
|
||
|
ArgKeyIsSet = true
|
||
|
case 3:
|
||
|
ArgValue = gnuflag.Arg(3)
|
||
|
ArgValueIsSet = true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if !ArgFileIsSet {
|
||
|
return errors.New("Config_file not specified")
|
||
|
}
|
||
|
|
||
|
// Mode
|
||
|
actionCounter := 0
|
||
|
if ArgChk {
|
||
|
actionCounter++
|
||
|
}
|
||
|
if ArgDel {
|
||
|
actionCounter++
|
||
|
if !ArgSectionIsSet {
|
||
|
return errors.New("Section not specified")
|
||
|
}
|
||
|
}
|
||
|
if ArgGet {
|
||
|
actionCounter++
|
||
|
}
|
||
|
if ArgSet {
|
||
|
actionCounter++
|
||
|
if !ArgSectionIsSet {
|
||
|
return errors.New("Section not specified")
|
||
|
}
|
||
|
}
|
||
|
if ArgAdd {
|
||
|
actionCounter++
|
||
|
if !ArgSectionIsSet {
|
||
|
return errors.New("Section not specified")
|
||
|
}
|
||
|
}
|
||
|
switch actionCounter {
|
||
|
case 0:
|
||
|
return errors.New("Action not set")
|
||
|
case 1:
|
||
|
return nil
|
||
|
default:
|
||
|
return errors.New("Only one action can be used at the same time")
|
||
|
}
|
||
|
}
|