swupd-inspector: use Cobra library for CLI

Signed-off-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
This commit is contained in:
Caio Marcelo de Oliveira Filho
2018-06-11 15:32:22 -07:00
committed by tmarcu
parent d11431e46d
commit edf50352ca
6 changed files with 123 additions and 132 deletions
+2 -8
View File
@@ -14,13 +14,8 @@ import (
// TODO: Support reading text files.
func runCat(cacheDir string, args []string) {
if len(args) != 2 {
usage()
os.Exit(2)
}
base, version := parseURL(args[0])
func runCat(cacheDir, url, arg string) {
base, version := parseURL(url)
stateDir := filepath.Join(cacheDir, convertContentBaseToDirname(base))
state, err := client.NewState(stateDir, base)
if err != nil {
@@ -32,7 +27,6 @@ func runCat(cacheDir string, args []string) {
log.Fatalf("ERROR: %s", err)
}
arg := args[1]
switch {
case arg == "Manifest.MoM", arg == "Manifest.full":
path, err := state.GetFile(version, arg)
+1 -1
View File
@@ -7,7 +7,7 @@ import (
"path/filepath"
)
func runClean(cacheDir string, args []string) {
func runClean(cacheDir string) {
fis, err := ioutil.ReadDir(cacheDir)
if err != nil {
log.Fatalf("ERROR: %s", err)
+19 -34
View File
@@ -1,7 +1,6 @@
package main
import (
"flag"
"fmt"
"log"
"path/filepath"
@@ -20,38 +19,24 @@ var (
RESET = "\x1b[0m"
)
func runDiff(cacheDir string, args []string) {
var (
noColor bool
strict bool
)
type diffFlags struct {
noColor bool
strict bool
}
flagSet := flag.NewFlagSet("diff", flag.ExitOnError)
flagSet.BoolVar(&noColor, "no-color", false, "use no colors")
flagSet.BoolVar(&strict, "strict", false, "also compare version numbers")
flagSet.Usage = usage
err := flagSet.Parse(args)
if err != nil {
log.Fatalf("ERROR: %s", err)
}
if len(flagSet.Args()) != 2 {
usage()
return
}
if noColor {
func runDiff(cacheDir string, flags *diffFlags, urlA, urlB string) {
if flags.noColor {
RED = ""
GREEN = ""
RESET = ""
}
baseA, versionA := parseURL(flagSet.Arg(0))
baseB, versionB := parseURL(flagSet.Arg(1))
baseA, versionA := parseURL(urlA)
baseB, versionB := parseURL(urlB)
var stateA, stateB *client.State
stateDirA := filepath.Join(cacheDir, convertContentBaseToDirname(baseA))
stateA, err = client.NewState(stateDirA, baseA)
stateA, err := client.NewState(stateDirA, baseA)
if err != nil {
log.Fatalf("ERROR: %s", err)
}
@@ -122,7 +107,7 @@ func runDiff(cacheDir string, args []string) {
fmt.Printf("%s+%s%s %s%s\n", RED, a.Type, a.Status, a.Name, RESET)
} else {
fmt.Printf(" %s%s %s", a.Type, a.Status, a.Name)
if strict && a.Version != b.Version {
if flags.strict && a.Version != b.Version {
fmt.Printf(" (VERSION: %s-%d%s / %s+%d%s)", RED, a.Version, RESET, GREEN, b.Version, RESET)
}
if a.Hash != b.Hash {
@@ -140,7 +125,7 @@ func runDiff(cacheDir string, args []string) {
})
fmt.Println()
flags := func(f *swupd.File) string {
flagString := func(f *swupd.File) string {
result, err := f.GetFlagString()
if err != nil {
result = "...."
@@ -202,16 +187,16 @@ func runDiff(cacheDir string, args []string) {
walkFiles(mA.Files, mB.Files, func(a, b *swupd.File) {
switch {
case a == nil:
fmt.Printf("%s+%s %s%s\n", GREEN, flags(b), b.Name, RESET)
fmt.Printf("%s+%s %s%s\n", GREEN, flagString(b), b.Name, RESET)
case b == nil:
fmt.Printf("%s-%s %s%s\n", RED, flags(a), a.Name, RESET)
fmt.Printf("%s-%s %s%s\n", RED, flagString(a), a.Name, RESET)
default:
if flags(a) != flags(b) {
fmt.Printf("%s-%s %s%s\n", RED, flags(a), a.Name, RESET)
fmt.Printf("%s+%s %s%s\n", GREEN, flags(b), b.Name, RESET)
} else if a.Rename != b.Rename || a.Hash != b.Hash || (strict && a.Version != b.Version) {
fmt.Printf(" %s %s", flags(a), a.Name)
if strict && a.Version != b.Version {
if flagString(a) != flagString(b) {
fmt.Printf("%s-%s %s%s\n", RED, flagString(a), a.Name, RESET)
fmt.Printf("%s+%s %s%s\n", GREEN, flagString(b), b.Name, RESET)
} else if a.Rename != b.Rename || a.Hash != b.Hash || (flags.strict && a.Version != b.Version) {
fmt.Printf(" %s %s", flagString(a), a.Name)
if flags.strict && a.Version != b.Version {
fmt.Printf(" (VERSION: %s-%d%s / %s+%d%s)", RED, a.Version, RESET, GREEN, b.Version, RESET)
}
if a.Rename != b.Rename {
+2 -8
View File
@@ -12,13 +12,8 @@ import (
"github.com/clearlinux/mixer-tools/swupd"
)
func runGet(cacheDir string, args []string) {
if len(args) != 2 {
usage()
os.Exit(2)
}
base, version := parseURL(args[0])
func runGet(cacheDir, url, arg string) {
base, version := parseURL(url)
stateDir := filepath.Join(cacheDir, convertContentBaseToDirname(base))
state, err := client.NewState(stateDir, base)
if err != nil {
@@ -30,7 +25,6 @@ func runGet(cacheDir string, args []string) {
log.Fatalf("ERROR: %s", err)
}
arg := args[1]
switch {
case arg == "Manifest.MoM", arg == "Manifest.full":
+5 -12
View File
@@ -3,7 +3,6 @@ package main
import (
"fmt"
"log"
"os"
"path/filepath"
"github.com/clearlinux/mixer-tools/internal/client"
@@ -12,21 +11,15 @@ import (
// TODO: Consider a --unique flag that would not print consecutive versions that have the same hash.
func runLog(cacheDir string, args []string) {
if len(args) != 2 {
usage()
os.Exit(2)
}
base, version := parseURL(args[0])
func runLog(cacheDir, url, filename string) {
base, version := parseURL(url)
stateDir := filepath.Join(cacheDir, convertContentBaseToDirname(base))
state, err := client.NewState(stateDir, base)
if err != nil {
log.Fatalf("ERROR: %s", err)
}
arg := args[1]
if arg == "" || arg[0] != '/' {
if filename == "" || filename[0] != '/' {
// TODO: Support Manifest.* files too, but showing the diff of the files?
log.Fatalf("Second argument to 'log' must be an absolute path")
}
@@ -44,7 +37,7 @@ func runLog(cacheDir string, args []string) {
var found *swupd.File
visit := func(bundle, file *swupd.File) bool {
if file.Name == arg && file.Present() {
if file.Name == filename && file.Present() {
found = file
lastBundle = bundle.Name
return true
@@ -95,7 +88,7 @@ func runLog(cacheDir string, args []string) {
}
if lastBundle == "" {
log.Fatalf("ERROR: file %s not found in version %s", arg, version)
log.Fatalf("ERROR: file %s not found in version %s", filename, version)
}
}
+94 -69
View File
@@ -2,13 +2,14 @@ package main
import (
"bufio"
"fmt"
"log"
"os"
"os/user"
"path/filepath"
"strconv"
"strings"
"github.com/spf13/cobra"
)
// TODO: Flag to set cacheDir.
@@ -17,58 +18,9 @@ import (
// TODO: Take into account deleted files, right now 'get' fails trying to download 0000...0.tar.
func usage() {
fmt.Printf(`swupd-inspector analyzes swupd content
Commands:
cat URL Manifest.NAME
Print the contents of the given Manifest.
get URL Manifest.NAME
Download the contents of the given Manifest.
get URL FILENAME
Search for the FILENAME and download the corresponding fullfile.
The FILENAME must be an absolute path.
get URL HASH
Download the fullfile corresponding to the hash.
diff [--strict] [--no-color] URL1 URL2
Compare two versions of swupd content. The filenames and flags
will be compared, recursing to the bundles. Use --strict to
also compare the version numbers of the files. Use --no-color
to not emit escape codes in the output.
log URL FILENAME
Show FILENAME version and its previous versions.
clean
Clean up any cached content.
The program will cache everything downloaded, and can keep content from
different sources. The cache directory is $HOME/.cache/swupd-inspector.
The URLs must refer to a specific version like
https://download.clearlinux.org/update/20520. Absolute local paths can
also be used instead of URLs.
It is possible to refer to content by aliases. The alias 'clear' works
by default, so clear/20520 refer to the same as the URL above. Other
aliases can be defined in $HOME/.config/swupd-inspector/aliases in the
format ALIAS=URL per line.
`)
}
func main() {
log.SetFlags(0)
if len(os.Args) < 2 {
usage()
os.Exit(2)
}
user, err := user.Current()
if err != nil {
log.Fatal(err)
@@ -83,26 +35,99 @@ func main() {
log.Fatalf("couldn't create cache directory: %s", err)
}
cmd := os.Args[1]
args := os.Args[2:]
switch cmd {
case "help", "-h", "--help":
usage()
os.Exit(0)
case "diff":
runDiff(cacheDir, args)
case "get":
runGet(cacheDir, args)
case "cat":
runCat(cacheDir, args)
case "log":
runLog(cacheDir, args)
case "clean":
runClean(cacheDir, args)
default:
usage()
os.Exit(2)
rootCmd := &cobra.Command{
Use: "swupd-inspector",
Short: "Inspect and download swupd content",
Long: `Inspect and download swupd content
The program will cache everything downloaded, and can keep content from
different sources. The cache directory is $HOME/.cache/swupd-inspector.
The URLs must refer to a specific version like
https://download.clearlinux.org/update/20520. Absolute local paths can
also be used instead of URLs.
It is possible to refer to content by aliases. The alias 'clear' works
by default, so clear/20520 refer to the same as the URL above. Other
aliases can be defined in $HOME/.config/swupd-inspector/aliases in the
format ALIAS=URL per line.
`,
}
diffFlags := &diffFlags{}
diffCmd := &cobra.Command{
Use: "diff [flags] URL1 URL2",
Short: "Compare two versions of swupd content",
Long: `Compare two versions of swupd content.
The filenames and flags will be compared, recursing to the
bundles. Use --strict to also compare the version numbers of the
files. Use --no-color to not emit escape codes in the output.
`,
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
runDiff(cacheDir, diffFlags, args[0], args[1])
},
}
diffCmd.Flags().BoolVar(&diffFlags.noColor, "no-color", false, "disable colored output")
diffCmd.Flags().BoolVar(&diffFlags.strict, "strict", false, "compare version numbers of files")
rootCmd.AddCommand(diffCmd)
getCmd := &cobra.Command{
Use: "get [flags] URL (FILENAME|HASH|Manifest.NAME)",
Short: "Download content from a swupd repository",
Long: `Download content from a swupd repository.
Different types of content can be downloaded:
swupd-inspector get URL Manifest.NAME
Download the contents of the given Manifest.
swupd-inspector get URL FILENAME
Search for the FILENAME and download the corresponding fullfile.
The FILENAME must be an absolute path.
swupd-inspector get URL HASH
Download the fullfile corresponding to the hash.
`,
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
runGet(cacheDir, args[0], args[1])
},
}
rootCmd.AddCommand(getCmd)
cleanCmd := &cobra.Command{
Use: "clean",
Short: "Clean up any cached content",
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
runClean(cacheDir)
},
}
rootCmd.AddCommand(cleanCmd)
catCmd := &cobra.Command{
Use: "cat [flags] URL Manifest.NAME",
Short: "Print the contents of a Manifest",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
runCat(cacheDir, args[0], args[1])
},
}
rootCmd.AddCommand(catCmd)
logCmd := &cobra.Command{
Use: "log [flags] URL FILENAME",
Short: "Print FILENAME version and all previous versions",
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
runLog(cacheDir, args[0], args[1])
},
}
rootCmd.AddCommand(logCmd)
_ = rootCmd.Execute()
}
var aliases = map[string]string{