Improve flags for compliance tools.
Test: m droid dist reportmissinglicenses Change-Id: I4090dae3d5d33d1908d67dff31aeee92d2b261da
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -24,21 +25,19 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"android/soong/response"
|
||||
"android/soong/tools/compliance"
|
||||
)
|
||||
|
||||
var (
|
||||
sources = newMultiString("rtrace", "Projects or metadata files to trace back from. (required; multiple allowed)")
|
||||
stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
|
||||
|
||||
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
||||
failNoSources = fmt.Errorf("\nNo projects or metadata files to trace back from")
|
||||
failNoLicenses = fmt.Errorf("No licenses found")
|
||||
)
|
||||
|
||||
type context struct {
|
||||
sources []string
|
||||
stripPrefix []string
|
||||
sources []string
|
||||
stripPrefix []string
|
||||
}
|
||||
|
||||
func (ctx context) strip(installPath string) string {
|
||||
@@ -54,8 +53,44 @@ func (ctx context) strip(installPath string) string {
|
||||
return installPath
|
||||
}
|
||||
|
||||
func init() {
|
||||
flag.Usage = func() {
|
||||
// newMultiString creates a flag that allows multiple values in an array.
|
||||
func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
|
||||
var f multiString
|
||||
flags.Var(&f, name, usage)
|
||||
return &f
|
||||
}
|
||||
|
||||
// multiString implements the flag `Value` interface for multiple strings.
|
||||
type multiString []string
|
||||
|
||||
func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
|
||||
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
|
||||
|
||||
func main() {
|
||||
var expandedArgs []string
|
||||
for _, arg := range os.Args[1:] {
|
||||
if strings.HasPrefix(arg, "@") {
|
||||
f, err := os.Open(strings.TrimPrefix(arg, "@"))
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
respArgs, err := response.ReadRspFile(f)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
expandedArgs = append(expandedArgs, respArgs...)
|
||||
} else {
|
||||
expandedArgs = append(expandedArgs, arg)
|
||||
}
|
||||
}
|
||||
|
||||
flags := flag.NewFlagSet("flags", flag.ExitOnError)
|
||||
|
||||
flags.Usage = func() {
|
||||
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
|
||||
|
||||
Outputs a space-separated Target ActsOn Origin Condition tuple for each
|
||||
@@ -72,50 +107,75 @@ i.e. target:condition1:condition2 etc.
|
||||
|
||||
Options:
|
||||
`, filepath.Base(os.Args[0]))
|
||||
flag.PrintDefaults()
|
||||
flags.PrintDefaults()
|
||||
}
|
||||
}
|
||||
|
||||
// newMultiString creates a flag that allows multiple values in an array.
|
||||
func newMultiString(name, usage string) *multiString {
|
||||
var f multiString
|
||||
flag.Var(&f, name, usage)
|
||||
return &f
|
||||
}
|
||||
outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
|
||||
sources := newMultiString(flags, "rtrace", "Projects or metadata files to trace back from. (required; multiple allowed)")
|
||||
stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
|
||||
|
||||
// multiString implements the flag `Value` interface for multiple strings.
|
||||
type multiString []string
|
||||
|
||||
func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
|
||||
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
flags.Parse(expandedArgs)
|
||||
|
||||
// Must specify at least one root target.
|
||||
if flag.NArg() == 0 {
|
||||
flag.Usage()
|
||||
if flags.NArg() == 0 {
|
||||
flags.Usage()
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
if len(*sources) == 0 {
|
||||
flag.Usage()
|
||||
flags.Usage()
|
||||
fmt.Fprintf(os.Stderr, "\nMust specify at least 1 --rtrace source.\n")
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
ctx := &context{
|
||||
sources: *sources,
|
||||
stripPrefix: *stripPrefix,
|
||||
if len(*outputFile) == 0 {
|
||||
flags.Usage()
|
||||
fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
|
||||
os.Exit(2)
|
||||
} else {
|
||||
dir, err := filepath.Abs(filepath.Dir(*outputFile))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "cannot determine path to %q: %s\n", *outputFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fi, err := os.Stat(dir)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "cannot read directory %q of %q: %s\n", dir, *outputFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if !fi.IsDir() {
|
||||
fmt.Fprintf(os.Stderr, "parent %q of %q is not a directory\n", dir, *outputFile)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
_, err := traceRestricted(ctx, os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
|
||||
|
||||
var ofile io.Writer
|
||||
ofile = os.Stdout
|
||||
var obuf *bytes.Buffer
|
||||
if *outputFile != "-" {
|
||||
obuf = &bytes.Buffer{}
|
||||
ofile = obuf
|
||||
}
|
||||
|
||||
ctx := &context{
|
||||
sources: *sources,
|
||||
stripPrefix: *stripPrefix,
|
||||
}
|
||||
_, err := traceRestricted(ctx, ofile, os.Stderr, compliance.FS, flags.Args()...)
|
||||
if err != nil {
|
||||
if err == failNoneRequested {
|
||||
flag.Usage()
|
||||
flags.Usage()
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
if *outputFile != "-" {
|
||||
err := os.WriteFile(*outputFile, obuf.Bytes(), 0666)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "could not write output to %q from %q: %s\n", *outputFile, os.Getenv("PWD"), err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user