aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'cmd')
-rw-r--r--cmd/pom2mk/pom2mk.go65
-rw-r--r--cmd/sbox/sbox.go113
2 files changed, 116 insertions, 62 deletions
diff --git a/cmd/pom2mk/pom2mk.go b/cmd/pom2mk/pom2mk.go
index e6144a56..ac29a2a9 100644
--- a/cmd/pom2mk/pom2mk.go
+++ b/cmd/pom2mk/pom2mk.go
@@ -18,7 +18,6 @@ import (
"encoding/xml"
"flag"
"fmt"
- "io"
"io/ioutil"
"os"
"path/filepath"
@@ -84,6 +83,8 @@ func (d ExtraDeps) Set(v string) error {
var extraDeps = make(ExtraDeps)
+var useVersion string
+
type Dependency struct {
XMLName xml.Name `xml:"dependency"`
@@ -98,6 +99,7 @@ type Dependency struct {
type Pom struct {
XMLName xml.Name `xml:"http://maven.apache.org/POM/4.0.0 project"`
+ PomFile string `xml:"-"`
ArtifactFile string `xml:"-"`
GroupId string `xml:"groupId"`
@@ -105,7 +107,7 @@ type Pom struct {
Version string `xml:"version"`
Packaging string `xml:"packaging"`
- Dependencies []Dependency `xml:"dependencies>dependency"`
+ Dependencies []*Dependency `xml:"dependencies>dependency"`
}
func (p Pom) MkName() string {
@@ -125,6 +127,17 @@ func (p Pom) MkDeps() []string {
return ret
}
+func (p *Pom) FixDepTypes(modules map[string]*Pom) {
+ for _, d := range p.Dependencies {
+ if d.Type != "" {
+ continue
+ }
+ if depPom, ok := modules[d.ArtifactId]; ok {
+ d.Type = depPom.Packaging
+ }
+ }
+}
+
var mkTemplate = template.Must(template.New("mk").Parse(`
include $(CLEAR_VARS)
LOCAL_MODULE := {{.MkName}}
@@ -140,25 +153,30 @@ LOCAL_STATIC_ANDROID_LIBRARIES := \
include $(BUILD_PREBUILT)
`))
-func convert(filename string, out io.Writer) error {
+func parse(filename string) (*Pom, error) {
data, err := ioutil.ReadFile(filename)
if err != nil {
- return err
+ return nil, err
}
var pom Pom
err = xml.Unmarshal(data, &pom)
if err != nil {
- return err
+ return nil, err
+ }
+
+ if useVersion != "" && pom.Version != useVersion {
+ return nil, nil
}
if pom.Packaging == "" {
pom.Packaging = "jar"
}
+ pom.PomFile = filename
pom.ArtifactFile = strings.TrimSuffix(filename, ".pom") + "." + pom.Packaging
- return mkTemplate.Execute(out, pom)
+ return &pom, nil
}
func main() {
@@ -178,6 +196,9 @@ Usage: %s [--rewrite <regex>=<replace>] [--extra-deps <module>=<module>[,<module
Some Android.mk modules have transitive dependencies that must be specified when they are
depended upon (like android-support-v7-mediarouter requires android-support-v7-appcompat).
This may be specified multiple times to declare these dependencies.
+ -use-version <version>
+ If the maven directory contains multiple versions of artifacts and their pom files,
+ -use-version can be used to only write makefiles for a specific version of those artifacts.
<dir>
The directory to search for *.pom files under.
@@ -187,6 +208,7 @@ The makefile is written to stdout, to be put in the current directory (often as
flag.Var(&extraDeps, "extra-deps", "Extra dependencies needed when depending on a module")
flag.Var(&rewriteNames, "rewrite", "Regex(es) to rewrite artifact names")
+ flag.StringVar(&useVersion, "use-version", "", "Only read artifacts of a specific version")
flag.Parse()
if flag.NArg() != 1 {
@@ -240,14 +262,39 @@ The makefile is written to stdout, to be put in the current directory (often as
sort.Strings(filenames)
+ poms := []*Pom{}
+ modules := make(map[string]*Pom)
+ for _, filename := range filenames {
+ pom, err := parse(filename)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "Error converting", filename, err)
+ os.Exit(1)
+ }
+
+ if pom != nil {
+ poms = append(poms, pom)
+
+ if old, ok := modules[pom.ArtifactId]; ok {
+ fmt.Fprintln(os.Stderr, "Module", pom.ArtifactId, "defined twice:", old.PomFile, pom.PomFile)
+ os.Exit(1)
+ }
+
+ modules[pom.ArtifactId] = pom
+ }
+ }
+
+ for _, pom := range poms {
+ pom.FixDepTypes(modules)
+ }
+
fmt.Println("# Automatically generated with:")
fmt.Println("# pom2mk", strings.Join(proptools.ShellEscape(os.Args[1:]), " "))
fmt.Println("LOCAL_PATH := $(call my-dir)")
- for _, filename := range filenames {
- err := convert(filename, os.Stdout)
+ for _, pom := range poms {
+ err := mkTemplate.Execute(os.Stdout, pom)
if err != nil {
- fmt.Fprintln(os.Stderr, "Error converting", filename, err)
+ fmt.Fprintln(os.Stderr, "Error writing", pom.PomFile, pom.MkName(), err)
os.Exit(1)
}
}
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index e3e68c99..4b008eb8 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -15,6 +15,7 @@
package main
import (
+ "flag"
"fmt"
"io/ioutil"
"os"
@@ -24,7 +25,50 @@ import (
"strings"
)
+var (
+ sandboxesRoot string
+ rawCommand string
+ outputRoot string
+ keepOutDir bool
+ depfileOut string
+)
+
+func init() {
+ flag.StringVar(&sandboxesRoot, "sandbox-path", "",
+ "root of temp directory to put the sandbox into")
+ flag.StringVar(&rawCommand, "c", "",
+ "command to run")
+ flag.StringVar(&outputRoot, "output-root", "",
+ "root of directory to copy outputs into")
+ flag.BoolVar(&keepOutDir, "keep-out-dir", false,
+ "whether to keep the sandbox directory when done")
+
+ flag.StringVar(&depfileOut, "depfile-out", "",
+ "file path of the depfile to generate. This value will replace '__SBOX_DEPFILE__' in the command and will be treated as an output but won't be added to __SBOX_OUT_FILES__")
+}
+
+func usageViolation(violation string) {
+ if violation != "" {
+ fmt.Fprintf(os.Stderr, "Usage error: %s.\n\n", violation)
+ }
+
+ fmt.Fprintf(os.Stderr,
+ "Usage: sbox -c <commandToRun> --sandbox-path <sandboxPath> --output-root <outputRoot> [--depfile-out depFile] <outputFile> [<outputFile>...]\n"+
+ "\n"+
+ "Runs <commandToRun> and moves each <outputFile> out of <sandboxPath>\n"+
+ "and into <outputRoot>\n")
+
+ flag.PrintDefaults()
+
+ os.Exit(1)
+}
+
func main() {
+ flag.Usage = func() {
+ usageViolation("")
+ }
+ flag.Parse()
+
error := run()
if error != nil {
fmt.Fprintln(os.Stderr, error)
@@ -32,55 +76,9 @@ func main() {
}
}
-var usage = "Usage: sbox -c <commandToRun> --sandbox-path <sandboxPath> --output-root <outputRoot> [--depfile-out depFile] <outputFile> [<outputFile>...]\n" +
- "\n" +
- "Runs <commandToRun> and moves each <outputFile> out of <sandboxPath>\n" +
- "If any file in <outputFiles> is specified by absolute path, then <outputRoot> must be specified as well,\n" +
- "to enable sbox to compute the relative path within the sandbox of the specified output files"
-
-func usageError(violation string) error {
- return fmt.Errorf("Usage error: %s.\n\n%s", violation, usage)
-}
-
func run() error {
- // the contents of the __SBOX_OUT_FILES__ variable
- var outputsVarEntries []string
- // all outputs
- var allOutputs []string
-
- args := os.Args[1:]
-
- var rawCommand string
- var sandboxesRoot string
- removeTempDir := true
- var outputRoot string
- var depfile string
-
- for i := 0; i < len(args); i++ {
- arg := args[i]
- if arg == "--sandbox-path" {
- sandboxesRoot = args[i+1]
- i++
- } else if arg == "-c" {
- rawCommand = args[i+1]
- i++
- } else if arg == "--output-root" {
- outputRoot = args[i+1]
- i++
- } else if arg == "--keep-out-dir" {
- removeTempDir = false
- } else if arg == "--depfile-out" {
- depfile = args[i+1]
- i++
- } else {
- outputsVarEntries = append(outputsVarEntries, arg)
- }
- }
if rawCommand == "" {
- return usageError("-c <commandToRun> is required and must be non-empty")
- }
- if len(outputsVarEntries) == 0 {
- return usageError("at least one output file must be given")
+ usageViolation("-c <commandToRun> is required and must be non-empty")
}
if sandboxesRoot == "" {
// In practice, the value of sandboxesRoot will mostly likely be at a fixed location relative to OUT_DIR,
@@ -88,12 +86,21 @@ func run() error {
// the value of sandboxesRoot will most likely be at a fixed location relative to the sbox executable
// However, Soong also needs to be able to separately remove the sandbox directory on startup (if it has anything left in it)
// and by passing it as a parameter we don't need to duplicate its value
- return usageError("--sandbox-path <sandboxPath> is required and must be non-empty")
+ usageViolation("--sandbox-path <sandboxPath> is required and must be non-empty")
}
if len(outputRoot) == 0 {
- return usageError("--output-root <outputRoot> is required and must be non-empty")
+ usageViolation("--output-root <outputRoot> is required and must be non-empty")
}
+ // the contents of the __SBOX_OUT_FILES__ variable
+ outputsVarEntries := flag.Args()
+ if len(outputsVarEntries) == 0 {
+ usageViolation("at least one output file must be given")
+ }
+
+ // all outputs
+ var allOutputs []string
+
os.MkdirAll(sandboxesRoot, 0777)
tempDir, err := ioutil.TempDir(sandboxesRoot, "sbox")
@@ -110,8 +117,8 @@ func run() error {
allOutputs = append([]string(nil), outputsVarEntries...)
- if depfile != "" {
- sandboxedDepfile, err := filepath.Rel(outputRoot, depfile)
+ if depfileOut != "" {
+ sandboxedDepfile, err := filepath.Rel(outputRoot, depfileOut)
if err != nil {
return err
}
@@ -132,7 +139,7 @@ func run() error {
// then at the beginning of the next build, Soong will retry the cleanup
defer func() {
// in some cases we decline to remove the temp dir, to facilitate debugging
- if removeTempDir {
+ if !keepOutDir {
os.RemoveAll(tempDir)
}
}()
@@ -190,7 +197,7 @@ func run() error {
if len(outputErrors) > 0 {
// Keep the temporary output directory around in case a user wants to inspect it for debugging purposes.
// Soong will delete it later anyway.
- removeTempDir = false
+ keepOutDir = true
return fmt.Errorf("mismatch between declared and actual outputs in sbox command (%s):\n%v", commandDescription, outputErrors)
}
// the created files match the declared files; now move them