Merge "Improve flags for compliance tools."
This commit is contained in:
@@ -20,14 +20,20 @@ package {
|
|||||||
blueprint_go_binary {
|
blueprint_go_binary {
|
||||||
name: "compliance_checkshare",
|
name: "compliance_checkshare",
|
||||||
srcs: ["cmd/checkshare/checkshare.go"],
|
srcs: ["cmd/checkshare/checkshare.go"],
|
||||||
deps: ["compliance-module"],
|
deps: [
|
||||||
|
"compliance-module",
|
||||||
|
"soong-response",
|
||||||
|
],
|
||||||
testSrcs: ["cmd/checkshare/checkshare_test.go"],
|
testSrcs: ["cmd/checkshare/checkshare_test.go"],
|
||||||
}
|
}
|
||||||
|
|
||||||
blueprint_go_binary {
|
blueprint_go_binary {
|
||||||
name: "compliancenotice_bom",
|
name: "compliancenotice_bom",
|
||||||
srcs: ["cmd/bom/bom.go"],
|
srcs: ["cmd/bom/bom.go"],
|
||||||
deps: ["compliance-module"],
|
deps: [
|
||||||
|
"compliance-module",
|
||||||
|
"soong-response",
|
||||||
|
],
|
||||||
testSrcs: ["cmd/bom/bom_test.go"],
|
testSrcs: ["cmd/bom/bom_test.go"],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,21 +50,30 @@ blueprint_go_binary {
|
|||||||
blueprint_go_binary {
|
blueprint_go_binary {
|
||||||
name: "compliance_listshare",
|
name: "compliance_listshare",
|
||||||
srcs: ["cmd/listshare/listshare.go"],
|
srcs: ["cmd/listshare/listshare.go"],
|
||||||
deps: ["compliance-module"],
|
deps: [
|
||||||
|
"compliance-module",
|
||||||
|
"soong-response",
|
||||||
|
],
|
||||||
testSrcs: ["cmd/listshare/listshare_test.go"],
|
testSrcs: ["cmd/listshare/listshare_test.go"],
|
||||||
}
|
}
|
||||||
|
|
||||||
blueprint_go_binary {
|
blueprint_go_binary {
|
||||||
name: "compliance_dumpgraph",
|
name: "compliance_dumpgraph",
|
||||||
srcs: ["cmd/dumpgraph/dumpgraph.go"],
|
srcs: ["cmd/dumpgraph/dumpgraph.go"],
|
||||||
deps: ["compliance-module"],
|
deps: [
|
||||||
|
"compliance-module",
|
||||||
|
"soong-response",
|
||||||
|
],
|
||||||
testSrcs: ["cmd/dumpgraph/dumpgraph_test.go"],
|
testSrcs: ["cmd/dumpgraph/dumpgraph_test.go"],
|
||||||
}
|
}
|
||||||
|
|
||||||
blueprint_go_binary {
|
blueprint_go_binary {
|
||||||
name: "compliance_dumpresolutions",
|
name: "compliance_dumpresolutions",
|
||||||
srcs: ["cmd/dumpresolutions/dumpresolutions.go"],
|
srcs: ["cmd/dumpresolutions/dumpresolutions.go"],
|
||||||
deps: ["compliance-module"],
|
deps: [
|
||||||
|
"compliance-module",
|
||||||
|
"soong-response",
|
||||||
|
],
|
||||||
testSrcs: ["cmd/dumpresolutions/dumpresolutions_test.go"],
|
testSrcs: ["cmd/dumpresolutions/dumpresolutions_test.go"],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +83,7 @@ blueprint_go_binary {
|
|||||||
deps: [
|
deps: [
|
||||||
"compliance-module",
|
"compliance-module",
|
||||||
"blueprint-deptools",
|
"blueprint-deptools",
|
||||||
|
"soong-response",
|
||||||
],
|
],
|
||||||
testSrcs: ["cmd/htmlnotice/htmlnotice_test.go"],
|
testSrcs: ["cmd/htmlnotice/htmlnotice_test.go"],
|
||||||
}
|
}
|
||||||
@@ -75,7 +91,10 @@ blueprint_go_binary {
|
|||||||
blueprint_go_binary {
|
blueprint_go_binary {
|
||||||
name: "compliance_rtrace",
|
name: "compliance_rtrace",
|
||||||
srcs: ["cmd/rtrace/rtrace.go"],
|
srcs: ["cmd/rtrace/rtrace.go"],
|
||||||
deps: ["compliance-module"],
|
deps: [
|
||||||
|
"compliance-module",
|
||||||
|
"soong-response",
|
||||||
|
],
|
||||||
testSrcs: ["cmd/rtrace/rtrace_test.go"],
|
testSrcs: ["cmd/rtrace/rtrace_test.go"],
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,6 +104,7 @@ blueprint_go_binary {
|
|||||||
deps: [
|
deps: [
|
||||||
"compliance-module",
|
"compliance-module",
|
||||||
"blueprint-deptools",
|
"blueprint-deptools",
|
||||||
|
"soong-response",
|
||||||
],
|
],
|
||||||
testSrcs: ["cmd/textnotice/textnotice_test.go"],
|
testSrcs: ["cmd/textnotice/textnotice_test.go"],
|
||||||
}
|
}
|
||||||
@@ -95,6 +115,7 @@ blueprint_go_binary {
|
|||||||
deps: [
|
deps: [
|
||||||
"compliance-module",
|
"compliance-module",
|
||||||
"blueprint-deptools",
|
"blueprint-deptools",
|
||||||
|
"soong-response",
|
||||||
],
|
],
|
||||||
testSrcs: ["cmd/xmlnotice/xmlnotice_test.go"],
|
testSrcs: ["cmd/xmlnotice/xmlnotice_test.go"],
|
||||||
}
|
}
|
||||||
|
@@ -24,13 +24,11 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/response"
|
||||||
"android/soong/tools/compliance"
|
"android/soong/tools/compliance"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
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")
|
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
||||||
failNoLicenses = fmt.Errorf("No licenses found")
|
failNoLicenses = fmt.Errorf("No licenses found")
|
||||||
)
|
)
|
||||||
@@ -55,22 +53,10 @@ func (ctx context) strip(installPath string) string {
|
|||||||
return installPath
|
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.
|
// 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
|
var f multiString
|
||||||
flag.Var(&f, name, usage)
|
flags.Var(&f, name, usage)
|
||||||
return &f
|
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 (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
|
||||||
|
|
||||||
func main() {
|
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.
|
// Must specify at least one root target.
|
||||||
if flag.NArg() == 0 {
|
if flags.NArg() == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(*outputFile) == 0 {
|
if len(*outputFile) == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
|
fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
} else {
|
} else {
|
||||||
@@ -118,10 +140,10 @@ func main() {
|
|||||||
|
|
||||||
ctx := &context{ofile, os.Stderr, compliance.FS, *stripPrefix}
|
ctx := &context{ofile, os.Stderr, compliance.FS, *stripPrefix}
|
||||||
|
|
||||||
err := billOfMaterials(ctx, flag.Args()...)
|
err := billOfMaterials(ctx, flags.Args()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == failNoneRequested {
|
if err == failNoneRequested {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -22,31 +23,12 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/response"
|
||||||
"android/soong/tools/compliance"
|
"android/soong/tools/compliance"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.Usage = func() {
|
|
||||||
fmt.Fprintf(os.Stderr, `Usage: %s 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
|
|
||||||
license condition that has a source privacy policy, and the license
|
|
||||||
condition that has a source sharing policy.
|
|
||||||
|
|
||||||
Any given target may appear multiple times with different combinations
|
|
||||||
of conflicting license conditions.
|
|
||||||
|
|
||||||
If all the source code that policy says must be shared may be shared,
|
|
||||||
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]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
failConflicts = fmt.Errorf("conflicts")
|
failConflicts = fmt.Errorf("conflicts")
|
||||||
failNoneRequested = fmt.Errorf("\nNo metadata files requested")
|
failNoneRequested = fmt.Errorf("\nNo metadata files requested")
|
||||||
@@ -61,24 +43,105 @@ 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 (l byError) Less(i, j int) bool { return l[i].Error() < l[j].Error() }
|
||||||
|
|
||||||
func main() {
|
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 {-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
|
||||||
|
license condition that has a source privacy policy, and the license
|
||||||
|
condition that has a source sharing policy.
|
||||||
|
|
||||||
|
Any given target may appear multiple times with different combinations
|
||||||
|
of conflicting license conditions.
|
||||||
|
|
||||||
|
If all the source code that policy says must be shared may be shared,
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
|
||||||
|
|
||||||
|
flags.Parse(expandedArgs)
|
||||||
|
|
||||||
// Must specify at least one root target.
|
// Must specify at least one root target.
|
||||||
if flag.NArg() == 0 {
|
if flags.NArg() == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := checkShare(os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
|
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(ofile, os.Stderr, compliance.FS, flags.Args()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != failConflicts {
|
if err != failConflicts {
|
||||||
if err == failNoneRequested {
|
if err == failNoneRequested {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
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)
|
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).
|
// Read the license graph from the license metadata files (*.meta_lic).
|
||||||
licenseGraph, err := compliance.ReadLicenseGraph(rootFS, stderr, files)
|
licenseGraph, err := compliance.ReadLicenseGraph(rootFS, stderr, files)
|
||||||
if err != nil {
|
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 {
|
if licenseGraph == nil {
|
||||||
return failNoLicenses
|
return failNoLicenses
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -24,14 +25,11 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/response"
|
||||||
"android/soong/tools/compliance"
|
"android/soong/tools/compliance"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
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")
|
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
||||||
failNoLicenses = fmt.Errorf("No licenses found")
|
failNoLicenses = fmt.Errorf("No licenses found")
|
||||||
)
|
)
|
||||||
@@ -55,8 +53,44 @@ func (ctx context) strip(installPath string) string {
|
|||||||
return installPath
|
return installPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
// newMultiString creates a flag that allows multiple values in an array.
|
||||||
flag.Usage = func() {
|
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...}
|
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
|
||||||
|
|
||||||
Outputs space-separated Target Dependency Annotations tuples for each
|
Outputs space-separated Target Dependency Annotations tuples for each
|
||||||
@@ -70,42 +104,68 @@ target:condition1:condition2 etc.
|
|||||||
|
|
||||||
Options:
|
Options:
|
||||||
`, filepath.Base(os.Args[0]))
|
`, filepath.Base(os.Args[0]))
|
||||||
flag.PrintDefaults()
|
flags.PrintDefaults()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// newMultiString creates a flag that allows multiple values in an array.
|
graphViz := flags.Bool("dot", false, "Whether to output graphviz (i.e. dot) format.")
|
||||||
func newMultiString(name, usage string) *multiString {
|
labelConditions := flags.Bool("label_conditions", false, "Whether to label target nodes with conditions.")
|
||||||
var f multiString
|
outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
|
||||||
flag.Var(&f, name, usage)
|
stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
|
||||||
return &f
|
|
||||||
}
|
|
||||||
|
|
||||||
// multiString implements the flag `Value` interface for multiple strings.
|
flags.Parse(expandedArgs)
|
||||||
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()
|
|
||||||
|
|
||||||
// Must specify at least one root target.
|
// Must specify at least one root target.
|
||||||
if flag.NArg() == 0 {
|
if flags.NArg() == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
os.Exit(2)
|
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}
|
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 != nil {
|
||||||
if err == failNoneRequested {
|
if err == failNoneRequested {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
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)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -24,15 +25,11 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/response"
|
||||||
"android/soong/tools/compliance"
|
"android/soong/tools/compliance"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
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")
|
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
||||||
failNoLicenses = fmt.Errorf("No licenses found")
|
failNoLicenses = fmt.Errorf("No licenses found")
|
||||||
)
|
)
|
||||||
@@ -57,8 +54,44 @@ func (ctx context) strip(installPath string) string {
|
|||||||
return installPath
|
return installPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
// newMultiString creates a flag that allows multiple values in an array.
|
||||||
flag.Usage = func() {
|
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...}
|
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
|
||||||
|
|
||||||
Outputs a space-separated Target ActsOn Origin Condition tuple for each
|
Outputs a space-separated Target ActsOn Origin Condition tuple for each
|
||||||
@@ -75,32 +108,52 @@ i.e. target:condition1:condition2 etc.
|
|||||||
|
|
||||||
Options:
|
Options:
|
||||||
`, filepath.Base(os.Args[0]))
|
`, filepath.Base(os.Args[0]))
|
||||||
flag.PrintDefaults()
|
flags.PrintDefaults()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// newMultiString creates a flag that allows multiple values in an array.
|
conditions := newMultiString(flags, "c", "License condition to resolve. (may be given multiple times)")
|
||||||
func newMultiString(name, usage string) *multiString {
|
graphViz := flags.Bool("dot", false, "Whether to output graphviz (i.e. dot) format.")
|
||||||
var f multiString
|
labelConditions := flags.Bool("label_conditions", false, "Whether to label target nodes with conditions.")
|
||||||
flag.Var(&f, name, usage)
|
outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
|
||||||
return &f
|
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.
|
flags.Parse(expandedArgs)
|
||||||
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()
|
|
||||||
|
|
||||||
// Must specify at least one root target.
|
// Must specify at least one root target.
|
||||||
if flag.NArg() == 0 {
|
if flags.NArg() == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
os.Exit(2)
|
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))
|
lcs := make([]compliance.LicenseCondition, 0, len(*conditions))
|
||||||
for _, name := range *conditions {
|
for _, name := range *conditions {
|
||||||
lcs = append(lcs, compliance.RecognizedConditionNames[name])
|
lcs = append(lcs, compliance.RecognizedConditionNames[name])
|
||||||
@@ -111,14 +164,21 @@ func main() {
|
|||||||
labelConditions: *labelConditions,
|
labelConditions: *labelConditions,
|
||||||
stripPrefix: *stripPrefix,
|
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 != nil {
|
||||||
if err == failNoneRequested {
|
if err == failNoneRequested {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
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)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,19 +26,13 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/response"
|
||||||
"android/soong/tools/compliance"
|
"android/soong/tools/compliance"
|
||||||
|
|
||||||
"github.com/google/blueprint/deptools"
|
"github.com/google/blueprint/deptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
outputFile = flag.String("o", "-", "Where to write the NOTICE text file. (default stdout)")
|
|
||||||
depsFile = flag.String("d", "", "Where to write the deps file")
|
|
||||||
includeTOC = flag.Bool("toc", true, "Whether to include a table of contents.")
|
|
||||||
product = flag.String("product", "", "The name of the product for which the notice is generated.")
|
|
||||||
stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
|
|
||||||
title = flag.String("title", "", "The title of the notice file.")
|
|
||||||
|
|
||||||
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
||||||
failNoLicenses = fmt.Errorf("No licenses found")
|
failNoLicenses = fmt.Errorf("No licenses found")
|
||||||
)
|
)
|
||||||
@@ -70,23 +64,10 @@ func (ctx context) strip(installPath string) string {
|
|||||||
return installPath
|
return installPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.Usage = func() {
|
|
||||||
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
|
|
||||||
|
|
||||||
Outputs an html NOTICE.html or gzipped NOTICE.html.gz file if the -o filename
|
|
||||||
ends with ".gz".
|
|
||||||
|
|
||||||
Options:
|
|
||||||
`, filepath.Base(os.Args[0]))
|
|
||||||
flag.PrintDefaults()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// newMultiString creates a flag that allows multiple values in an array.
|
// 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
|
var f multiString
|
||||||
flag.Var(&f, name, usage)
|
flags.Var(&f, name, usage)
|
||||||
return &f
|
return &f
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,16 +78,57 @@ func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
|
|||||||
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
|
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
|
||||||
|
|
||||||
func main() {
|
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 an html NOTICE.html or gzipped NOTICE.html.gz file if the -o filename
|
||||||
|
ends with ".gz".
|
||||||
|
|
||||||
|
Options:
|
||||||
|
`, filepath.Base(os.Args[0]))
|
||||||
|
flags.PrintDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
|
outputFile := flags.String("o", "-", "Where to write the NOTICE text file. (default stdout)")
|
||||||
|
depsFile := flags.String("d", "", "Where to write the deps file")
|
||||||
|
includeTOC := flags.Bool("toc", true, "Whether to include a table of contents.")
|
||||||
|
product := flags.String("product", "", "The name of the product for which the notice is generated.")
|
||||||
|
stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
|
||||||
|
title := flags.String("title", "", "The title of the notice file.")
|
||||||
|
|
||||||
|
flags.Parse(expandedArgs)
|
||||||
|
|
||||||
// Must specify at least one root target.
|
// Must specify at least one root target.
|
||||||
if flag.NArg() == 0 {
|
if flags.NArg() == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(*outputFile) == 0 {
|
if len(*outputFile) == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
|
fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
} else {
|
} else {
|
||||||
@@ -143,10 +165,10 @@ func main() {
|
|||||||
|
|
||||||
ctx := &context{ofile, os.Stderr, compliance.FS, *includeTOC, *product, *stripPrefix, *title, &deps}
|
ctx := &context{ofile, os.Stderr, compliance.FS, *includeTOC, *product, *stripPrefix, *title, &deps}
|
||||||
|
|
||||||
err := htmlNotice(ctx, flag.Args()...)
|
err := htmlNotice(ctx, flags.Args()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == failNoneRequested {
|
if err == failNoneRequested {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -24,12 +25,41 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/response"
|
||||||
"android/soong/tools/compliance"
|
"android/soong/tools/compliance"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
var (
|
||||||
flag.Usage = func() {
|
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
||||||
fmt.Fprintf(os.Stderr, `Usage: %s file.meta_lic {file.meta_lic...}
|
failNoLicenses = fmt.Errorf("No licenses found")
|
||||||
|
)
|
||||||
|
|
||||||
|
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...}
|
||||||
|
|
||||||
Outputs a csv file with 1 project per line in the first field followed
|
Outputs a csv file with 1 project per line in the first field followed
|
||||||
by target:condition pairs describing why the project must be shared.
|
by target:condition pairs describing why the project must be shared.
|
||||||
@@ -39,30 +69,61 @@ Soong module or Make target, and the license condition is either
|
|||||||
restricted (e.g. GPL) or reciprocal (e.g. MPL).
|
restricted (e.g. GPL) or reciprocal (e.g. MPL).
|
||||||
`, filepath.Base(os.Args[0]))
|
`, filepath.Base(os.Args[0]))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
outputFile := flags.String("o", "-", "Where to write the list of projects to share. (default stdout)")
|
||||||
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
|
||||||
failNoLicenses = fmt.Errorf("No licenses found")
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
flags.Parse(expandedArgs)
|
||||||
flag.Parse()
|
|
||||||
|
|
||||||
// Must specify at least one root target.
|
// Must specify at least one root target.
|
||||||
if flag.NArg() == 0 {
|
if flags.NArg() == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := listShare(os.Stdout, os.Stderr, compliance.FS, flag.Args()...)
|
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 := listShare(ofile, os.Stderr, compliance.FS, flags.Args()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == failNoneRequested {
|
if err == failNoneRequested {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
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)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +137,7 @@ func listShare(stdout, stderr io.Writer, rootFS fs.FS, files ...string) error {
|
|||||||
// Read the license graph from the license metadata files (*.meta_lic).
|
// Read the license graph from the license metadata files (*.meta_lic).
|
||||||
licenseGraph, err := compliance.ReadLicenseGraph(rootFS, stderr, files)
|
licenseGraph, err := compliance.ReadLicenseGraph(rootFS, stderr, files)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Unable to read license metadata file(s) %q: %v\n", files, err)
|
return fmt.Errorf("Unable to read license metadata file(s) %q from %q: %v\n", files, os.Getenv("PWD"), err)
|
||||||
}
|
}
|
||||||
if licenseGraph == nil {
|
if licenseGraph == nil {
|
||||||
return failNoLicenses
|
return failNoLicenses
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -24,21 +25,19 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/response"
|
||||||
"android/soong/tools/compliance"
|
"android/soong/tools/compliance"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
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")
|
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
||||||
failNoSources = fmt.Errorf("\nNo projects or metadata files to trace back from")
|
failNoSources = fmt.Errorf("\nNo projects or metadata files to trace back from")
|
||||||
failNoLicenses = fmt.Errorf("No licenses found")
|
failNoLicenses = fmt.Errorf("No licenses found")
|
||||||
)
|
)
|
||||||
|
|
||||||
type context struct {
|
type context struct {
|
||||||
sources []string
|
sources []string
|
||||||
stripPrefix []string
|
stripPrefix []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ctx context) strip(installPath string) string {
|
func (ctx context) strip(installPath string) string {
|
||||||
@@ -54,8 +53,44 @@ func (ctx context) strip(installPath string) string {
|
|||||||
return installPath
|
return installPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
// newMultiString creates a flag that allows multiple values in an array.
|
||||||
flag.Usage = func() {
|
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...}
|
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
|
||||||
|
|
||||||
Outputs a space-separated Target ActsOn Origin Condition tuple for each
|
Outputs a space-separated Target ActsOn Origin Condition tuple for each
|
||||||
@@ -72,50 +107,75 @@ i.e. target:condition1:condition2 etc.
|
|||||||
|
|
||||||
Options:
|
Options:
|
||||||
`, filepath.Base(os.Args[0]))
|
`, filepath.Base(os.Args[0]))
|
||||||
flag.PrintDefaults()
|
flags.PrintDefaults()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// newMultiString creates a flag that allows multiple values in an array.
|
outputFile := flags.String("o", "-", "Where to write the output. (default stdout)")
|
||||||
func newMultiString(name, usage string) *multiString {
|
sources := newMultiString(flags, "rtrace", "Projects or metadata files to trace back from. (required; multiple allowed)")
|
||||||
var f multiString
|
stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
|
||||||
flag.Var(&f, name, usage)
|
|
||||||
return &f
|
|
||||||
}
|
|
||||||
|
|
||||||
// multiString implements the flag `Value` interface for multiple strings.
|
flags.Parse(expandedArgs)
|
||||||
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()
|
|
||||||
|
|
||||||
// Must specify at least one root target.
|
// Must specify at least one root target.
|
||||||
if flag.NArg() == 0 {
|
if flags.NArg() == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(*sources) == 0 {
|
if len(*sources) == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
fmt.Fprintf(os.Stderr, "\nMust specify at least 1 --rtrace source.\n")
|
fmt.Fprintf(os.Stderr, "\nMust specify at least 1 --rtrace source.\n")
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := &context{
|
if len(*outputFile) == 0 {
|
||||||
sources: *sources,
|
flags.Usage()
|
||||||
stripPrefix: *stripPrefix,
|
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 != nil {
|
||||||
if err == failNoneRequested {
|
if err == failNoneRequested {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
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)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,9 +39,6 @@ type context struct {
|
|||||||
rootFS fs.FS
|
rootFS fs.FS
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var expandedArgs []string
|
var expandedArgs []string
|
||||||
for _, arg := range os.Args[1:] {
|
for _, arg := range os.Args[1:] {
|
||||||
|
@@ -25,18 +25,13 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/response"
|
||||||
"android/soong/tools/compliance"
|
"android/soong/tools/compliance"
|
||||||
|
|
||||||
"github.com/google/blueprint/deptools"
|
"github.com/google/blueprint/deptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
outputFile = flag.String("o", "-", "Where to write the NOTICE text file. (default stdout)")
|
|
||||||
depsFile = flag.String("d", "", "Where to write the deps file")
|
|
||||||
product = flag.String("product", "", "The name of the product for which the notice is generated.")
|
|
||||||
stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
|
|
||||||
title = flag.String("title", "", "The title of the notice file.")
|
|
||||||
|
|
||||||
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
||||||
failNoLicenses = fmt.Errorf("No licenses found")
|
failNoLicenses = fmt.Errorf("No licenses found")
|
||||||
)
|
)
|
||||||
@@ -67,22 +62,10 @@ func (ctx context) strip(installPath string) string {
|
|||||||
return installPath
|
return installPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.Usage = func() {
|
|
||||||
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
|
|
||||||
|
|
||||||
Outputs a text NOTICE file.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
`, filepath.Base(os.Args[0]))
|
|
||||||
flag.PrintDefaults()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// newMultiString creates a flag that allows multiple values in an array.
|
// 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
|
var f multiString
|
||||||
flag.Var(&f, name, usage)
|
flags.Var(&f, name, usage)
|
||||||
return &f
|
return &f
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,16 +76,55 @@ func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
|
|||||||
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
|
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
|
||||||
|
|
||||||
func main() {
|
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 text NOTICE file.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
`, filepath.Base(os.Args[0]))
|
||||||
|
flags.PrintDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
|
outputFile := flags.String("o", "-", "Where to write the NOTICE text file. (default stdout)")
|
||||||
|
depsFile := flags.String("d", "", "Where to write the deps file")
|
||||||
|
product := flags.String("product", "", "The name of the product for which the notice is generated.")
|
||||||
|
stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
|
||||||
|
title := flags.String("title", "", "The title of the notice file.")
|
||||||
|
|
||||||
|
flags.Parse(expandedArgs)
|
||||||
|
|
||||||
// Must specify at least one root target.
|
// Must specify at least one root target.
|
||||||
if flag.NArg() == 0 {
|
if flags.NArg() == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(*outputFile) == 0 {
|
if len(*outputFile) == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
|
fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
} else {
|
} else {
|
||||||
@@ -139,10 +161,10 @@ func main() {
|
|||||||
|
|
||||||
ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, *title, &deps}
|
ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, *title, &deps}
|
||||||
|
|
||||||
err := textNotice(ctx, flag.Args()...)
|
err := textNotice(ctx, flags.Args()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == failNoneRequested {
|
if err == failNoneRequested {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
@@ -26,18 +26,13 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"android/soong/response"
|
||||||
"android/soong/tools/compliance"
|
"android/soong/tools/compliance"
|
||||||
|
|
||||||
"github.com/google/blueprint/deptools"
|
"github.com/google/blueprint/deptools"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
outputFile = flag.String("o", "-", "Where to write the NOTICE xml or xml.gz file. (default stdout)")
|
|
||||||
depsFile = flag.String("d", "", "Where to write the deps file")
|
|
||||||
product = flag.String("product", "", "The name of the product for which the notice is generated.")
|
|
||||||
stripPrefix = newMultiString("strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
|
|
||||||
title = flag.String("title", "", "The title of the notice file.")
|
|
||||||
|
|
||||||
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
failNoneRequested = fmt.Errorf("\nNo license metadata files requested")
|
||||||
failNoLicenses = fmt.Errorf("No licenses found")
|
failNoLicenses = fmt.Errorf("No licenses found")
|
||||||
)
|
)
|
||||||
@@ -68,23 +63,10 @@ func (ctx context) strip(installPath string) string {
|
|||||||
return installPath
|
return installPath
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
flag.Usage = func() {
|
|
||||||
fmt.Fprintf(os.Stderr, `Usage: %s {options} file.meta_lic {file.meta_lic...}
|
|
||||||
|
|
||||||
Outputs an xml NOTICE.xml or gzipped NOTICE.xml.gz file if the -o filename ends
|
|
||||||
with ".gz".
|
|
||||||
|
|
||||||
Options:
|
|
||||||
`, filepath.Base(os.Args[0]))
|
|
||||||
flag.PrintDefaults()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// newMultiString creates a flag that allows multiple values in an array.
|
// 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
|
var f multiString
|
||||||
flag.Var(&f, name, usage)
|
flags.Var(&f, name, usage)
|
||||||
return &f
|
return &f
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,16 +77,56 @@ func (ms *multiString) String() string { return strings.Join(*ms, ", ") }
|
|||||||
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
|
func (ms *multiString) Set(s string) error { *ms = append(*ms, s); return nil }
|
||||||
|
|
||||||
func main() {
|
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 an xml NOTICE.xml or gzipped NOTICE.xml.gz file if the -o filename ends
|
||||||
|
with ".gz".
|
||||||
|
|
||||||
|
Options:
|
||||||
|
`, filepath.Base(os.Args[0]))
|
||||||
|
flags.PrintDefaults()
|
||||||
|
}
|
||||||
|
|
||||||
|
outputFile := flags.String("o", "-", "Where to write the NOTICE xml or xml.gz file. (default stdout)")
|
||||||
|
depsFile := flags.String("d", "", "Where to write the deps file")
|
||||||
|
product := flags.String("product", "", "The name of the product for which the notice is generated.")
|
||||||
|
stripPrefix := newMultiString(flags, "strip_prefix", "Prefix to remove from paths. i.e. path to root (multiple allowed)")
|
||||||
|
title := flags.String("title", "", "The title of the notice file.")
|
||||||
|
|
||||||
|
flags.Parse(expandedArgs)
|
||||||
|
|
||||||
// Must specify at least one root target.
|
// Must specify at least one root target.
|
||||||
if flag.NArg() == 0 {
|
if flags.NArg() == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(*outputFile) == 0 {
|
if len(*outputFile) == 0 {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
|
fmt.Fprintf(os.Stderr, "must specify file for -o; use - for stdout\n")
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
} else {
|
} else {
|
||||||
@@ -141,10 +163,10 @@ func main() {
|
|||||||
|
|
||||||
ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, *title, &deps}
|
ctx := &context{ofile, os.Stderr, compliance.FS, *product, *stripPrefix, *title, &deps}
|
||||||
|
|
||||||
err := xmlNotice(ctx, flag.Args()...)
|
err := xmlNotice(ctx, flags.Args()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == failNoneRequested {
|
if err == failNoneRequested {
|
||||||
flag.Usage()
|
flags.Usage()
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
fmt.Fprintf(os.Stderr, "%s\n", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
Reference in New Issue
Block a user