Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99b87147 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Improve flags for compliance tools." into tm-dev

parents b5353a16 ccf94749
Loading
Loading
Loading
Loading
+27 −6
Original line number Diff line number Diff line
@@ -20,14 +20,20 @@ package {
blueprint_go_binary {
    name: "compliance_checkshare",
    srcs: ["cmd/checkshare/checkshare.go"],
    deps: ["compliance-module"],
    deps: [
        "compliance-module",
        "soong-response",
    ],
    testSrcs: ["cmd/checkshare/checkshare_test.go"],
}

blueprint_go_binary {
    name: "compliancenotice_bom",
    srcs: ["cmd/bom/bom.go"],
    deps: ["compliance-module"],
    deps: [
        "compliance-module",
        "soong-response",
    ],
    testSrcs: ["cmd/bom/bom_test.go"],
}

@@ -44,21 +50,30 @@ blueprint_go_binary {
blueprint_go_binary {
    name: "compliance_listshare",
    srcs: ["cmd/listshare/listshare.go"],
    deps: ["compliance-module"],
    deps: [
        "compliance-module",
        "soong-response",
    ],
    testSrcs: ["cmd/listshare/listshare_test.go"],
}

blueprint_go_binary {
    name: "compliance_dumpgraph",
    srcs: ["cmd/dumpgraph/dumpgraph.go"],
    deps: ["compliance-module"],
    deps: [
        "compliance-module",
        "soong-response",
    ],
    testSrcs: ["cmd/dumpgraph/dumpgraph_test.go"],
}

blueprint_go_binary {
    name: "compliance_dumpresolutions",
    srcs: ["cmd/dumpresolutions/dumpresolutions.go"],
    deps: ["compliance-module"],
    deps: [
        "compliance-module",
        "soong-response",
    ],
    testSrcs: ["cmd/dumpresolutions/dumpresolutions_test.go"],
}

@@ -68,6 +83,7 @@ blueprint_go_binary {
    deps: [
        "compliance-module",
        "blueprint-deptools",
        "soong-response",
    ],
    testSrcs: ["cmd/htmlnotice/htmlnotice_test.go"],
}
@@ -75,7 +91,10 @@ blueprint_go_binary {
blueprint_go_binary {
    name: "compliance_rtrace",
    srcs: ["cmd/rtrace/rtrace.go"],
    deps: ["compliance-module"],
    deps: [
        "compliance-module",
        "soong-response",
    ],
    testSrcs: ["cmd/rtrace/rtrace_test.go"],
}

@@ -85,6 +104,7 @@ blueprint_go_binary {
    deps: [
        "compliance-module",
        "blueprint-deptools",
        "soong-response",
    ],
    testSrcs: ["cmd/textnotice/textnotice_test.go"],
}
@@ -95,6 +115,7 @@ blueprint_go_binary {
    deps: [
        "compliance-module",
        "blueprint-deptools",
        "soong-response",
    ],
    testSrcs: ["cmd/xmlnotice/xmlnotice_test.go"],
}
+45 −23
Original line number Diff line number Diff line
@@ -24,13 +24,11 @@ import (
	"path/filepath"
	"strings"

	"android/soong/response"
	"android/soong/tools/compliance"
)

var (
	outputFile  = flag.String("o", "-", "Where to write the bill of materials. (default stdout)")
	stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")

	failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
	failNoLicenses    = fmt.Errorf("No licenses found")
)
@@ -55,22 +53,10 @@ func (ctx context) strip(installPath string) string {
	return installPath
}

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}

Outputs a bill of materials. i.e. the list of installed paths.

Options:
`, filepath.Base(os.Args[0]))
		flag.PrintDefaults()
	}
}

// newMultiString creates a flag that allows multiple values in an array.
func newMultiString(name, usage string) *multiString {
func newMultiString(flags *flag.FlagSet, name, usage string) *multiString {
	var f multiString
	flag.Var(&f, name, usage)
	flags.Var(&f, name, usage)
	return &f
}

@@ -81,16 +67,52 @@ 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()
	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 bill of materials. i.e. the list of installed paths.

Options:
`, filepath.Base(os.Args[0]))
		flags.PrintDefaults()
	}

	outputFile := flags.String("o", "-", "Where to write the bill of materials. (default stdout)")
	stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")

	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(*outputFile) == 0 {
		flag.Usage()
		flags.Usage()
		fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
		os.Exit(2)
	} else {
@@ -118,10 +140,10 @@ func main() {

	ctx := &context{ofile, os.Stderr, compliance.FS, *stripPrefix}

	err := billOfMaterials(ctx, flag.Args()...)
	err := billOfMaterials(ctx, flags.Args()...)
	if err != nil {
		if err == failNoneRequested {
			flag.Usage()
			flags.Usage()
		}
		fmt.Fprintf(os.Stderr, "%s\n", err.Error())
		os.Exit(1)
+86 −23
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
@@ -22,13 +23,51 @@ import (
	"os"
	"path/filepath"
	"sort"
	"strings"

	"android/soong/response"
	"android/soong/tools/compliance"
)

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, `Usage: %s file.meta_lic {file.meta_lic...}
var (
	failConflicts     = fmt.Errorf("conflicts")
	failNoneRequested = fmt.Errorf("\nNo metadata files requested")
	failNoLicenses    = fmt.Errorf("No licenses")
)

// byError orders conflicts by error string
type byError []compliance.SourceSharePrivacyConflict

func (l byError) Len() int           { return len(l) }
func (l byError) Swap(i, j int)      { l[i], l[j] = l[j], l[i] }
func (l byError) Less(i, j int) bool { return l[i].Error() < l[j].Error() }

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 {-o outfile} file.meta_lic {file.meta_lic...}

Reports on stderr any targets where policy says that the source both
must and must not be shared. The error report indicates the target, the
@@ -44,41 +83,65 @@ outputs "PASS" to stdout and exits with status 0.
If policy says any source must both be shared and not be shared,
outputs "FAIL" to stdout and exits with status 1.
`, filepath.Base(os.Args[0]))
		flags.PrintDefaults()
	}
}

var (
	failConflicts     = fmt.Errorf("conflicts")
	failNoneRequested = fmt.Errorf("\nNo metadata files requested")
	failNoLicenses    = fmt.Errorf("No licenses")
)

// byError orders conflicts by error string
type byError []compliance.SourceSharePrivacyConflict

func (l byError) Len() int           { return len(l) }
func (l byError) Swap(i, j int)      { l[i], l[j] = l[j], l[i] }
func (l byError) Less(i, j int) bool { return l[i].Error() < l[j].Error() }
	outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")

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(*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)
		}
	}

	var ofile io.Writer
	ofile = os.Stdout
	var obuf *bytes.Buffer
	if *outputFile != "-" {
		obuf = &bytes.Buffer{}
		ofile = obuf
	}

	err := checkShare(os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
	err := checkShare(ofile, os.Stderr, compliance.FS, flags.Args()...)
	if err != nil {
		if err != failConflicts {
			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)
}

@@ -92,7 +155,7 @@ func checkShare(stdout, stderr io.Writer, rootFS fs.FS, files ...string) error {
	// Read the license graph from the license metadata files (*.meta_lic).
	licenseGraph, err := compliance.ReadLicenseGraph(rootFS, stderr, files)
	if err != nil {
		return fmt.Errorf("Unable to read license metadata file(s) %q: %w\n", files, err)
		return fmt.Errorf("Unable to read license metadata file(s) %q from %q: %w\n", files, os.Getenv("PWD"), err)
	}
	if licenseGraph == nil {
		return failNoLicenses
+86 −26
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
@@ -24,14 +25,11 @@ import (
	"sort"
	"strings"

	"android/soong/response"
	"android/soong/tools/compliance"
)

var (
	graphViz        = flag.Bool("dot", false, "Whether to output graphviz (i.e. dot) format.")
	labelConditions = flag.Bool("label_conditions", false, "Whether to label target nodes with conditions.")
	stripPrefix     = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")

	failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
	failNoLicenses    = fmt.Errorf("No licenses found")
)
@@ -55,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 space-separated Target Dependency Annotations tuples for each
@@ -70,42 +104,68 @@ 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
}

// 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 }
	graphViz := flags.Bool("dot", false, "Whether to output graphviz (i.e. dot) format.")
	labelConditions := flags.Bool("label_conditions", false, "Whether to label target nodes with conditions.")
	outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
	stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")

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(*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)
		}
	}

	var ofile io.Writer
	ofile = os.Stdout
	var obuf *bytes.Buffer
	if *outputFile != "-" {
		obuf = &bytes.Buffer{}
		ofile = obuf
	}

	ctx := &context{*graphViz, *labelConditions, *stripPrefix}

	err := dumpGraph(ctx, os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
	err := dumpGraph(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)
}

+87 −27
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io"
@@ -24,15 +25,11 @@ import (
	"sort"
	"strings"

	"android/soong/response"
	"android/soong/tools/compliance"
)

var (
	conditions      = newMultiString("c", "License condition to resolve. (may be given multiple times)")
	graphViz        = flag.Bool("dot", false, "Whether to output graphviz (i.e. dot) format.")
	labelConditions = flag.Bool("label_conditions", false, "Whether to label target nodes with conditions.")
	stripPrefix     = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")

	failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
	failNoLicenses    = fmt.Errorf("No licenses found")
)
@@ -57,8 +54,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
@@ -75,32 +108,52 @@ 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
}

// 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 }
	conditions := newMultiString(flags, "c", "License condition to resolve. (may be given multiple times)")
	graphViz := flags.Bool("dot", false, "Whether to output graphviz (i.e. dot) format.")
	labelConditions := flags.Bool("label_conditions", false, "Whether to label target nodes with conditions.")
	outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
	stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")

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(*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)
		}
	}

	var ofile io.Writer
	ofile = os.Stdout
	var obuf *bytes.Buffer
	if *outputFile != "-" {
		obuf = &bytes.Buffer{}
		ofile = obuf
	}

	lcs := make([]compliance.LicenseCondition, 0, len(*conditions))
	for _, name := range *conditions {
		lcs = append(lcs, compliance.RecognizedConditionNames[name])
@@ -111,14 +164,21 @@ func main() {
		labelConditions: *labelConditions,
		stripPrefix:     *stripPrefix,
	}
	_, err := dumpResolutions(ctx, os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
	_, err := dumpResolutions(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)
}

Loading