diff options
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/pom2mk/pom2mk.go | 65 | ||||
-rw-r--r-- | cmd/sbox/sbox.go | 113 |
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 |