You've already forked android-go
mirror of
https://github.com/xlab/android-go.git
synced 2025-12-23 22:11:00 +02:00
Add "android-project" tool that replaces obsolete "android" util from SDK.
This commit is contained in:
20
cmd/android-project/LICENSE
Normal file
20
cmd/android-project/LICENSE
Normal file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
Copyright © 2017 Maxim Kupriianov <max@kc.vc>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the “Software”), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
2
cmd/android-project/Makefile
Normal file
2
cmd/android-project/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
all:
|
||||
go-bindata -pkg main templates/
|
||||
62
cmd/android-project/README.md
Normal file
62
cmd/android-project/README.md
Normal file
@@ -0,0 +1,62 @@
|
||||
## android-project
|
||||
|
||||
Android Project tool is a simple replacement for infamous `android` util from Android SDK, prior to Android SDK Tools [Revision 25.3.0 (March 2017) release](https://developer.android.com/studio/releases/sdk-tools.html) when they dropped that util abruptly. Realising their mistake later that March, they got it back, so it actually forwards the commands for `avd`, `target`, and `device` to the underlying layers properly, but still lacks of `android project update` capability.
|
||||
|
||||
I used `android project update` to simply create Ant build scripts for the projects with guarantees, that platform exists and is supported. So this tool does the same thing and it's the only feature implemented now.
|
||||
|
||||
### Installation
|
||||
|
||||
```
|
||||
go get github.com/xlab/android-go/cmd/android-project
|
||||
```
|
||||
|
||||
Also you must set `$ANDROID_HOME` to your Android SDK location, e.g.
|
||||
|
||||
```
|
||||
export ANDROID_HOME=/Users/xlab/Library/Android/sdk
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```
|
||||
Usage: android-project update [--sdk] [--target] --name --path
|
||||
|
||||
Updates an Android project (must already have an AndroidManifest.xml)
|
||||
```
|
||||
|
||||
[GolangExample](https://github.com/xlab/android-go/blob/master/example/android/Makefile)
|
||||
|
||||
```
|
||||
$ android-project update --target android-23 --name GolangExample --path .
|
||||
.
|
||||
├── Environment
|
||||
│ ├── [/Users/xlab/Library/Android/sdk] Android SDK location
|
||||
│ ├── [/Users/xlab/Library/Android/sdk/ndk-bundle] Android NDK location
|
||||
│ ├── [/Users/xlab/Library/Android/sdk/platforms] Android Platforms location
|
||||
│ └── [[android-23 android-N]] Android Platforms available
|
||||
├── Project
|
||||
│ ├── [GolangExample] Project name
|
||||
│ ├── [android-23] Project target
|
||||
│ └── [.] Project location
|
||||
└── Files updated
|
||||
├── build.xml
|
||||
├── local.properties
|
||||
├── project.properties
|
||||
└── proguard-project.txt
|
||||
```
|
||||
|
||||
As you can see, the effect of running this command is very similar to `android project update`. At least is used to be.
|
||||
|
||||
```
|
||||
$ android project update
|
||||
*************************************************************************
|
||||
The "android" command is deprecated.
|
||||
For manual SDK, AVD, and project management, please use Android Studio.
|
||||
For command-line tools, use tools/bin/sdkmanager and tools/bin/avdmanager
|
||||
*************************************************************************
|
||||
Invalid or unsupported command "project update"
|
||||
```
|
||||
|
||||
### License
|
||||
|
||||
MIT
|
||||
306
cmd/android-project/bindata.go
Normal file
306
cmd/android-project/bindata.go
Normal file
File diff suppressed because one or more lines are too long
152
cmd/android-project/main.go
Normal file
152
cmd/android-project/main.go
Normal file
@@ -0,0 +1,152 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/jawher/mow.cli"
|
||||
"github.com/xlab/closer"
|
||||
"github.com/xlab/treeprint"
|
||||
)
|
||||
|
||||
var app = cli.App("android-project", `Android project bootstrap tool for use instead of version that was removed from Android SDK (since Revision 25.3.0).
|
||||
See https://developer.android.com/studio/releases/sdk-tools.html`)
|
||||
|
||||
func init() {
|
||||
log.SetFlags(0)
|
||||
}
|
||||
|
||||
func main() {
|
||||
app.Command("update", "Updates an Android project (must already have an AndroidManifest.xml).", cmdUpdateFunc)
|
||||
app.Command("platforms", "Lists Android platforms supported within SDK.", cmdPlatformsFunc)
|
||||
|
||||
if err := app.Run(os.Args); err != nil {
|
||||
closer.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func cmdPlatformsFunc(c *cli.Cmd) {
|
||||
sdkDir := c.String(cli.StringOpt{
|
||||
Name: "sdk",
|
||||
Desc: "Android SDK location, can also be set using ANDROID_HOME env variable.",
|
||||
EnvVar: "ANDROID_HOME",
|
||||
HideValue: true,
|
||||
})
|
||||
c.Spec = "[--sdk]"
|
||||
c.Action = func() {
|
||||
defer closer.Close()
|
||||
|
||||
if len(*sdkDir) == 0 {
|
||||
closer.Fatalln("ANDROID_HOME environment variable not set (or --sdk flag not provided).")
|
||||
}
|
||||
_, platformsDir := learnPaths(*sdkDir)
|
||||
log.Println("Available Android platforms:")
|
||||
platforms := learnPlatforms(platformsDir)
|
||||
for _, platform := range platforms {
|
||||
log.Println("*", platform)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cmdUpdateFunc(c *cli.Cmd) {
|
||||
pathOpt := c.StringOpt("p path", "", "The project's directory.")
|
||||
nameOpt := c.StringOpt("n name", "", "Project name.")
|
||||
forceOpt := c.BoolOpt("f force", false, "Force generation, even if the target platform is not supported.")
|
||||
targetOpt := c.StringOpt("t target", "android-23", "Target ID to set for the project.")
|
||||
sdkDir := c.String(cli.StringOpt{
|
||||
Name: "sdk",
|
||||
Desc: "Android SDK location, can also be set using ANDROID_HOME env variable.",
|
||||
EnvVar: "ANDROID_HOME",
|
||||
HideValue: true,
|
||||
})
|
||||
c.Spec = "[--sdk] [--target] --name --path"
|
||||
c.Action = func() {
|
||||
defer closer.Close()
|
||||
|
||||
if len(*sdkDir) == 0 {
|
||||
closer.Fatalln("ANDROID_HOME environment variable not set (or --sdk flag not provided).")
|
||||
}
|
||||
tree := treeprint.New()
|
||||
closer.Bind(func() {
|
||||
log.Println(tree)
|
||||
})
|
||||
ndkDir, platformsDir := learnPaths(*sdkDir)
|
||||
|
||||
env := tree.AddBranch("Environment").
|
||||
AddMetaNode(*sdkDir, "Android SDK location").
|
||||
AddMetaNode(ndkDir, "Android NDK location").
|
||||
AddMetaNode(platformsDir, "Android Platforms location")
|
||||
platforms := learnPlatforms(platformsDir)
|
||||
env.AddMetaNode(platforms, "Android Platforms available")
|
||||
|
||||
ctx := &TemplateContext{
|
||||
ProjectName: *nameOpt,
|
||||
ProjectTarget: *targetOpt,
|
||||
|
||||
SDKDir: *sdkDir,
|
||||
}
|
||||
tree.AddBranch("Project").
|
||||
AddMetaNode(ctx.ProjectName, "Project name").
|
||||
AddMetaNode(ctx.ProjectTarget, "Project target").
|
||||
AddMetaNode(*pathOpt, "Project location")
|
||||
|
||||
manifestFileName := filepath.Join(*pathOpt, "AndroidManifest.xml")
|
||||
if _, err := os.Stat(manifestFileName); os.IsNotExist(err) {
|
||||
closer.Fatalln("AndroidManifest.xml not found in project location")
|
||||
}
|
||||
var platformSupported bool
|
||||
for _, platform := range platforms {
|
||||
if *targetOpt == platform {
|
||||
platformSupported = true
|
||||
}
|
||||
}
|
||||
if !platformSupported && !(*forceOpt) {
|
||||
closer.Fatalln("Platform", *targetOpt, "not supported within this SDK, build may fail. Use -f flag to override.")
|
||||
}
|
||||
|
||||
files := tree.AddBranch("Files updated")
|
||||
for _, tpl := range templates {
|
||||
fileName := filepath.Join(*pathOpt, tpl.TargetName())
|
||||
f, err := os.Create(fileName)
|
||||
if err != nil {
|
||||
closer.Fatalf("Failed to create file %s: %v", fileName, err)
|
||||
}
|
||||
if err := tpl.Render(ctx, f); err != nil {
|
||||
closer.Fatalf("Failed to render template %s: %v", tpl.Name(), err)
|
||||
}
|
||||
f.Close()
|
||||
files.AddNode(fileName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func learnPlatforms(platformsDir string) []string {
|
||||
var platforms []string
|
||||
filepath.Walk(platformsDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if path == platformsDir {
|
||||
return nil
|
||||
}
|
||||
platforms = append(platforms, filepath.Base(path))
|
||||
return filepath.SkipDir
|
||||
})
|
||||
return platforms
|
||||
}
|
||||
|
||||
func learnPaths(sdkDir string) (ndkDir, platformsDir string) {
|
||||
if _, err := os.Stat(sdkDir); err != nil {
|
||||
closer.Fatalln("Android SDK location is provided but not valid:", sdkDir)
|
||||
}
|
||||
ndkDir = filepath.Join(sdkDir, "ndk-bundle")
|
||||
if _, err := os.Stat(sdkDir); err != nil {
|
||||
closer.Fatalln("Android SDK location is provided but has no ndk-bundle:", ndkDir)
|
||||
}
|
||||
platformsDir = filepath.Join(sdkDir, "platforms")
|
||||
if _, err := os.Stat(sdkDir); err != nil {
|
||||
closer.Fatalln("Android SDK location is provided but has no platforms:", platformsDir)
|
||||
}
|
||||
return
|
||||
}
|
||||
64
cmd/android-project/templates.go
Normal file
64
cmd/android-project/templates.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
type TemplateContext struct {
|
||||
ProjectName string
|
||||
ProjectTarget string
|
||||
SDKDir string
|
||||
}
|
||||
|
||||
type Template interface {
|
||||
Name() string
|
||||
TargetName() string
|
||||
Render(ctx *TemplateContext, wr io.Writer) error
|
||||
}
|
||||
|
||||
var templates = []Template{
|
||||
&tpl{
|
||||
name: "build.xml.tpl",
|
||||
target: "build.xml",
|
||||
Template: template.Must(template.New("build.xml.tpl").
|
||||
Parse(string(MustAsset("templates/build.xml.tpl")))),
|
||||
},
|
||||
&tpl{
|
||||
name: "local.properties.tpl",
|
||||
target: "local.properties",
|
||||
Template: template.Must(template.New("local.properties.tpl").
|
||||
Parse(string(MustAsset("templates/local.properties.tpl")))),
|
||||
},
|
||||
&tpl{
|
||||
name: "project.properties.tpl",
|
||||
target: "project.properties",
|
||||
Template: template.Must(template.New("project.properties.tpl").
|
||||
Parse(string(MustAsset("templates/project.properties.tpl")))),
|
||||
},
|
||||
&tpl{
|
||||
name: "proguard-project.txt.tpl",
|
||||
target: "proguard-project.txt",
|
||||
Template: template.Must(template.New("proguard-project.txt.tpl").
|
||||
Parse(string(MustAsset("templates/proguard-project.txt.tpl")))),
|
||||
},
|
||||
}
|
||||
|
||||
type tpl struct {
|
||||
*template.Template
|
||||
|
||||
name string
|
||||
target string
|
||||
}
|
||||
|
||||
func (t *tpl) Name() string {
|
||||
return t.name
|
||||
}
|
||||
|
||||
func (t *tpl) TargetName() string {
|
||||
return t.target
|
||||
}
|
||||
|
||||
func (t *tpl) Render(ctx *TemplateContext, wr io.Writer) error {
|
||||
return t.Template.Execute(wr, ctx)
|
||||
}
|
||||
92
cmd/android-project/templates/build.xml.tpl
Normal file
92
cmd/android-project/templates/build.xml.tpl
Normal file
@@ -0,0 +1,92 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="{{.ProjectName}}" default="help">
|
||||
|
||||
<!-- The local.properties file is created and updated by the 'android' tool.
|
||||
It contains the path to the SDK. It should *NOT* be checked into
|
||||
Version Control Systems. -->
|
||||
<property file="local.properties" />
|
||||
|
||||
<!-- The ant.properties file can be created by you. It is only edited by the
|
||||
'android' tool to add properties to it.
|
||||
This is the place to change some Ant specific build properties.
|
||||
Here are some properties you may want to change/update:
|
||||
|
||||
source.dir
|
||||
The name of the source directory. Default is 'src'.
|
||||
out.dir
|
||||
The name of the output directory. Default is 'bin'.
|
||||
|
||||
For other overridable properties, look at the beginning of the rules
|
||||
files in the SDK, at tools/ant/build.xml
|
||||
|
||||
Properties related to the SDK location or the project target should
|
||||
be updated using the 'android' tool with the 'update' action.
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems.
|
||||
|
||||
-->
|
||||
<property file="ant.properties" />
|
||||
|
||||
<!-- if sdk.dir was not set from one of the property file, then
|
||||
get it from the ANDROID_HOME env var.
|
||||
This must be done before we load project.properties since
|
||||
the proguard config can use sdk.dir -->
|
||||
<property environment="env" />
|
||||
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
|
||||
<isset property="env.ANDROID_HOME" />
|
||||
</condition>
|
||||
|
||||
<!-- The project.properties file is created and updated by the 'android'
|
||||
tool, as well as ADT.
|
||||
|
||||
This contains project specific properties such as project target, and library
|
||||
dependencies. Lower level build properties are stored in ant.properties
|
||||
(or in .classpath for Eclipse projects).
|
||||
|
||||
This file is an integral part of the build system for your
|
||||
application and should be checked into Version Control Systems. -->
|
||||
<loadproperties srcFile="project.properties" />
|
||||
|
||||
<!-- quick check on sdk.dir -->
|
||||
<fail
|
||||
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
|
||||
unless="sdk.dir"
|
||||
/>
|
||||
|
||||
<!--
|
||||
Import per project custom build rules if present at the root of the project.
|
||||
This is the place to put custom intermediary targets such as:
|
||||
-pre-build
|
||||
-pre-compile
|
||||
-post-compile (This is typically used for code obfuscation.
|
||||
Compiled code location: ${out.classes.absolute.dir}
|
||||
If this is not done in place, override ${out.dex.input.absolute.dir})
|
||||
-post-package
|
||||
-post-build
|
||||
-pre-clean
|
||||
-->
|
||||
<import file="custom_rules.xml" optional="true" />
|
||||
|
||||
<!-- Import the actual build file.
|
||||
|
||||
To customize existing targets, there are two options:
|
||||
- Customize only one target:
|
||||
- copy/paste the target into this file, *before* the
|
||||
<import> task.
|
||||
- customize it to your needs.
|
||||
- Customize the whole content of build.xml
|
||||
- copy/paste the content of the rules files (minus the top node)
|
||||
into this file, replacing the <import> task.
|
||||
- customize to your needs.
|
||||
|
||||
***********************
|
||||
****** IMPORTANT ******
|
||||
***********************
|
||||
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
|
||||
in order to avoid having your file be overridden by tools such as "android update project"
|
||||
-->
|
||||
<!-- version-tag: 1 -->
|
||||
<import file="${sdk.dir}/tools/ant/build.xml" />
|
||||
|
||||
</project>
|
||||
10
cmd/android-project/templates/local.properties.tpl
Normal file
10
cmd/android-project/templates/local.properties.tpl
Normal file
@@ -0,0 +1,10 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must *NOT* be checked into Version Control Systems,
|
||||
# as it contains information specific to your local configuration.
|
||||
|
||||
# location of the SDK. This is only used by Ant
|
||||
# For customization when using a Version Control System, please read the
|
||||
# header note.
|
||||
sdk.dir={{.SDKDir}}
|
||||
20
cmd/android-project/templates/proguard-project.txt.tpl
Normal file
20
cmd/android-project/templates/proguard-project.txt.tpl
Normal file
@@ -0,0 +1,20 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
14
cmd/android-project/templates/project.properties.tpl
Normal file
14
cmd/android-project/templates/project.properties.tpl
Normal file
@@ -0,0 +1,14 @@
|
||||
# This file is automatically generated by Android Tools.
|
||||
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||
#
|
||||
# This file must be checked in Version Control Systems.
|
||||
#
|
||||
# To customize properties used by the Ant build system edit
|
||||
# "ant.properties", and override values to adapt the script to your
|
||||
# project structure.
|
||||
#
|
||||
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||
|
||||
# Project target.
|
||||
target={{.ProjectTarget}}
|
||||
Reference in New Issue
Block a user