Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c0c3b769f2 | |||
| fae39dd2e5 | |||
| 3ad1ed7dbc | |||
| ae823e6c4e | |||
| 9056e5a2dc | |||
| a972d1ef62 | |||
| 6f58d4c474 | |||
| 6404780186 | |||
| 5d99e50c4a | |||
| aaeb630eb1 | |||
| 3760616639 | |||
| 026dce563b | |||
| 83601dca2f | |||
| 7a27ee4f69 | |||
| 05aeaf1bd2 | |||
| cc13413007 | |||
| b138867b78 | |||
| a1195cefd5 | |||
| b83c3b3684 | |||
| 5502ddaf0d | |||
| 39e6765e64 | |||
| 47e20da631 | |||
| bb7b47b063 | |||
| a2618dcde5 | |||
| 9fdb126715 | |||
| b2a81c09ec | |||
| 04fa5d3feb | |||
| d73108cc13 | |||
| 93efe71080 | |||
| 697c8f129c | |||
| c12f7fef76 | |||
| cde238de94 | |||
| ec83d481fa | |||
| 1f12fdbeea | |||
| 6fa16b615b | |||
| e5c90badba | |||
| be6c6ba976 | |||
| 7f3be98199 | |||
| 0e498db735 | |||
| 7203b740fd | |||
| 97aab900da | |||
| dddb2837dd | |||
| 1637937664 | |||
| 03144eb160 | |||
| 53210710ba | |||
| e7a972df77 | |||
| cb2f396e33 | |||
| 2940d05209 | |||
| 2377aa7ac2 | |||
| dce3b7ed6c | |||
| 5bda4df7fa | |||
| 1a8e36ccd3 | |||
| 14816c7c81 | |||
| 940439866e | |||
| d364f46baa | |||
| 2b53c98cf5 | |||
| 36d07d7a15 | |||
| 458e479681 | |||
| c3ce2f8a07 | |||
| 893356abcd | |||
| 22645d9158 | |||
| 76dd8613ca | |||
| 5917d4ef0b | |||
| 90053eb9df | |||
| 540929c6a0 | |||
| 3ff32092a3 | |||
| 55d7cf3865 | |||
| ac4ac935f6 | |||
| d83d49d83b | |||
| e36158a0da | |||
| 5cc14b8031 | |||
| 17906735df | |||
| 3a6e898b12 | |||
| 0cc3df3747 | |||
| 2bc842a2b3 | |||
| 1c6f640026 | |||
| 6daad829cc | |||
| 7d926822ed | |||
| d4dcbb13fc | |||
| f396712f59 | |||
| d97250f968 | |||
| e7e8e95242 | |||
| d518a655a8 | |||
| b6a5844027 | |||
| 9d9abea157 | |||
| ee1165ea33 | |||
| 2704ee54cf | |||
| ad01d28351 | |||
| a215c1cf30 | |||
| cadea2f6c3 | |||
| e13e15d3e9 | |||
| 6ef2f67ae8 | |||
| 765c4ee9f6 | |||
| a4103d8dc8 | |||
| 8e0f021cad | |||
| 002ab85f76 | |||
| 4a0f69a3f0 | |||
| 8a2e96d995 | |||
| 13dbd2f5d4 | |||
| bcf3f8611a |
@@ -0,0 +1 @@
|
|||||||
|
bin/templates/project/assets/www/cordova.js
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
root: true
|
||||||
|
extends: semistandard
|
||||||
|
rules:
|
||||||
|
indent:
|
||||||
|
- error
|
||||||
|
- 4
|
||||||
|
camelcase: off
|
||||||
|
padded-blocks: off
|
||||||
|
operator-linebreak: off
|
||||||
|
no-throw-literal: off
|
||||||
@@ -1,11 +1,21 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
|
.gradle
|
||||||
|
.metadata
|
||||||
|
Thumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*.class
|
||||||
|
*.jar
|
||||||
default.properties
|
default.properties
|
||||||
gen
|
gen
|
||||||
assets/www/cordova.js
|
assets/www/cordova.js
|
||||||
local.properties
|
local.properties
|
||||||
proguard.cfg
|
proguard.cfg
|
||||||
proguard.cfg
|
|
||||||
proguard-project.txt
|
proguard-project.txt
|
||||||
|
example
|
||||||
|
/coverage
|
||||||
/framework/lib
|
/framework/lib
|
||||||
/framework/build
|
/framework/build
|
||||||
/framework/bin
|
/framework/bin
|
||||||
@@ -15,30 +25,23 @@ proguard-project.txt
|
|||||||
/framework/libs
|
/framework/libs
|
||||||
/framework/javadoc-public
|
/framework/javadoc-public
|
||||||
/framework/javadoc-private
|
/framework/javadoc-private
|
||||||
/test/libs
|
/test/.externalNativeBuild
|
||||||
example
|
/test/build.gradle
|
||||||
/test/bin
|
|
||||||
/test/assets/www/.tmp*
|
|
||||||
/test/assets/www/cordova.js
|
|
||||||
/test/gradle
|
/test/gradle
|
||||||
/test/gradlew
|
/test/gradlew
|
||||||
/test/gradlew.bat
|
/test/gradlew.bat
|
||||||
|
/test/assets/www/.tmp*
|
||||||
|
/test/assets/www/cordova.js
|
||||||
|
/test/bin
|
||||||
/test/build
|
/test/build
|
||||||
.gradle
|
/test/captures
|
||||||
|
/test/libs
|
||||||
tmp/**
|
tmp/**
|
||||||
.metadata
|
|
||||||
tmp/**/*
|
tmp/**/*
|
||||||
Thumbs.db
|
|
||||||
Desktop.ini
|
|
||||||
*.tmp
|
|
||||||
*.bak
|
|
||||||
*.swp
|
|
||||||
*.class
|
|
||||||
*.jar
|
|
||||||
!/spec/fixtures/org.test.plugins.dummyplugin/src/android/TestLib.jar
|
!/spec/fixtures/org.test.plugins.dummyplugin/src/android/TestLib.jar
|
||||||
# IntelliJ IDEA files
|
# IntelliJ IDEA files
|
||||||
|
**/.idea/**/*
|
||||||
*.iml
|
*.iml
|
||||||
.idea
|
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
node_modules/jshint
|
node_modules/jshint
|
||||||
node_modules/promise-matchers
|
node_modules/promise-matchers
|
||||||
@@ -130,4 +133,3 @@ node_modules/wordwrap/
|
|||||||
node_modules/yargs/
|
node_modules/yargs/
|
||||||
node_modules/jasmine-core/
|
node_modules/jasmine-core/
|
||||||
node_modules/fs.realpath/
|
node_modules/fs.realpath/
|
||||||
/coverage
|
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
bin/node_modules/*
|
|
||||||
bin/templates/project/*
|
|
||||||
spec/fixtures/*
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"node": true
|
|
||||||
, "bitwise": true
|
|
||||||
, "undef": true
|
|
||||||
, "trailing": true
|
|
||||||
, "quotmark": true
|
|
||||||
, "indent": 4
|
|
||||||
, "unused": "vars"
|
|
||||||
, "latedef": "nofunc"
|
|
||||||
}
|
|
||||||
@@ -2,21 +2,27 @@ language: android
|
|||||||
sudo: false
|
sudo: false
|
||||||
jdk:
|
jdk:
|
||||||
- oraclejdk8
|
- oraclejdk8
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- ANDROID_TOOLS=${ANDROID_HOME}/tools
|
||||||
before_install:
|
before_install:
|
||||||
- nvm install 6
|
- nvm install 6
|
||||||
|
# ensure at least gradle 3.3 is in place.
|
||||||
|
- wget http://services.gradle.org/distributions/gradle-3.3-bin.zip
|
||||||
|
- unzip gradle-3.3-bin.zip
|
||||||
|
- export GRADLE_HOME=$PWD/gradle-3.3
|
||||||
|
- export PATH=${GRADLE_HOME}/bin:${ANDROID_HOME}:${ANDROID_HOME}/emulator:${ANDROID_TOOLS}:${ANDROID_TOOLS}/bin:${ANDROID_HOME}/platform-tools:$PATH
|
||||||
- node --version
|
- node --version
|
||||||
- gradle --version
|
- gradle --version
|
||||||
install:
|
- echo y | android --silent update sdk --no-ui --all --filter platform-tools,tools,build-tools-26.0.2,android-26,android-25,extra-google-m2repository,extra-android-m2repository
|
||||||
- npm install
|
|
||||||
- npm install -g codecov
|
|
||||||
- echo y | android update sdk -u --filter android-22,android-23,android-24,android-25
|
|
||||||
android:
|
android:
|
||||||
components:
|
components:
|
||||||
- tools
|
- tools
|
||||||
- tools
|
install:
|
||||||
|
- npm install
|
||||||
|
- npm install -g codecov
|
||||||
script:
|
script:
|
||||||
- npm run jshint
|
- npm test
|
||||||
- npm run cover
|
- npm run cover
|
||||||
- npm run test-build
|
|
||||||
after_script:
|
after_script:
|
||||||
- codecov
|
- codecov
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ at the core, applications written with web technology: HTML, CSS and JavaScript.
|
|||||||
|
|
||||||
## Requires
|
## Requires
|
||||||
|
|
||||||
- Java JDK 1.6 or greater
|
- Java JDK 1.8 or greater
|
||||||
- Android SDK [http://developer.android.com](http://developer.android.com)
|
- Android SDK [http://developer.android.com](http://developer.android.com)
|
||||||
|
|
||||||
|
|
||||||
@@ -62,3 +62,9 @@ These commands live in a generated Cordova Android project. Any interactions wit
|
|||||||
|
|
||||||
1. Create a project
|
1. Create a project
|
||||||
2. Import it via "Non-Android Studio Project"
|
2. Import it via "Non-Android Studio Project"
|
||||||
|
|
||||||
|
## Running the Native Tests
|
||||||
|
|
||||||
|
The `test/` directory in this project contains an Android test project that can
|
||||||
|
be used to run different kinds of native tests. Check out the
|
||||||
|
[README contained therein](test/README.md) for more details!
|
||||||
|
|||||||
@@ -20,6 +20,34 @@
|
|||||||
-->
|
-->
|
||||||
## Release Notes for Cordova (Android) ##
|
## Release Notes for Cordova (Android) ##
|
||||||
|
|
||||||
|
### 6.4.0 (Nov 06, 2017)
|
||||||
|
* [CB-13289](https://issues.apache.org/jira/browse/CB-13289) Fixing build problems with Studio Three, but keeping **Windows** Gradle fix for now, will be deprecated
|
||||||
|
* [CB-13289](https://issues.apache.org/jira/browse/CB-13289) Fix test to work with new Google **Android** Gradle DSL
|
||||||
|
* :CB-13501 : update appveyor node versions to support node 8
|
||||||
|
* [CB-13499](https://issues.apache.org/jira/browse/CB-13499) Remove duplicate "setting" in error strings
|
||||||
|
* Include missing values for task.name when 'cdvBuildMultipleApks' option is true, 'task.name' can have 'validateSigningArmv7Release' or 'validateSigningX86Release' values too.
|
||||||
|
* [CB-13406](https://issues.apache.org/jira/browse/CB-13406) Fixed AVD API level comparison when choosing sub-par API level match. Added tests for the best_image method.
|
||||||
|
* [CB-13404](https://issues.apache.org/jira/browse/CB-13404) add **Android**-versions to bundledDependencies. Ignore best emulator selection when parsed AVD information does not include API level in the target
|
||||||
|
* [CB-12895](https://issues.apache.org/jira/browse/CB-12895) : eslint ignoring cordova.js
|
||||||
|
* [CB-12895](https://issues.apache.org/jira/browse/CB-12895) Temporarily disabling eslint since cordova-js does not have eslint yet.
|
||||||
|
|
||||||
|
### 6.3.0 (Sep 25, 2017)
|
||||||
|
* [CB-6936](https://issues.apache.org/jira/browse/CB-6936) fix crash when calling methods on a destroyed webview
|
||||||
|
* [CB-12981](https://issues.apache.org/jira/browse/CB-12981) handle SDK 26.0.2 slightly different AVD list output for **Android** 8+ AVDs. Would cause "cannot read property replace of undefined" errors when trying to deploy an **Android** 8 emulator.
|
||||||
|
* Updated maven repo to include most recent lib versions
|
||||||
|
* [CB-13177](https://issues.apache.org/jira/browse/CB-13177) Updating to API Level 26
|
||||||
|
* Revert [CB-12015](https://issues.apache.org/jira/browse/CB-12015) initial-scale values less than 1.0 are ignored on **Android**
|
||||||
|
* [CB-12730](https://issues.apache.org/jira/browse/CB-12730) The Cordova Compatibility Plugin is now integrated into cordova-android
|
||||||
|
* [CB-12453](https://issues.apache.org/jira/browse/CB-12453) Remove unnecessary double quotes from .bat files which are the causes of crash if project path contains spaces
|
||||||
|
* [CB-13031](https://issues.apache.org/jira/browse/CB-13031) Fix bug with case-sensitivity of **Android**-packageName
|
||||||
|
* [CB-10916](https://issues.apache.org/jira/browse/CB-10916) Support display name for **Android**
|
||||||
|
* [CB-12423](https://issues.apache.org/jira/browse/CB-12423) make explicit JDK 1.8 or greater is needed in the `README`, we require 1.8 for compilation, but do not have 1.8 Java features yet
|
||||||
|
* [CB-13006](https://issues.apache.org/jira/browse/CB-13006) removed create and update end-to-end tests, and instead added more unit test coverage. tweaked code coverage invocation so that we get coverage details on the create.js module. slight changes to the create.js module so that it is slightly easier to test.
|
||||||
|
* [CB-12950](https://issues.apache.org/jira/browse/CB-12950) lots of tweaks for end-to-end test runs, especially on CI: - rename npm tasks to reflect what they do (npm run unit-tests, npm run e2e-tests). main `npm test` runs linter, unit tests and e2e tests now. - locked jasmine down to ~2.6.0. - consolidate gitignores. - updated travis to run `npm test`. add **Android** sdk installation to appveyor ci run.align **Android** dpendencies across travis and appveyor. have appveyor install gradle. force gradle to version 3.4.1 in appveyor, as that seems to be the only version choco has. explicitly invoke sdkmanager to move license accepting process along.
|
||||||
|
* [CB-12605](https://issues.apache.org/jira/browse/CB-12605) In **Windows** get **Android** studio path from the registry
|
||||||
|
* [CB-12762](https://issues.apache.org/jira/browse/CB-12762) : pointed `package.json` repo items to github mirrors instead of apache repos site
|
||||||
|
* [CB-12617](https://issues.apache.org/jira/browse/CB-12617) : removed node0.x support for platforms and added engineStrict
|
||||||
|
|
||||||
### 6.2.3 (May 2, 2017)
|
### 6.2.3 (May 2, 2017)
|
||||||
* [CB-12640](https://issues.apache.org/jira/browse/CB-12640) better handling of unrecognized Android SDK commands on **Windows**.
|
* [CB-12640](https://issues.apache.org/jira/browse/CB-12640) better handling of unrecognized Android SDK commands on **Windows**.
|
||||||
* [CB-12640](https://issues.apache.org/jira/browse/CB-12640) flipped avd parsing logic so that it always tries to use avdmanager to retrieve avds first, then falls back to android command if avdmanager cannot be found (and errors with ENOENT). updated tests - and added explicit tests to ensure to shell out to singular forms of sub-commands when executing `android`
|
* [CB-12640](https://issues.apache.org/jira/browse/CB-12640) flipped avd parsing logic so that it always tries to use avdmanager to retrieve avds first, then falls back to android command if avdmanager cannot be found (and errors with ENOENT). updated tests - and added explicit tests to ensure to shell out to singular forms of sub-commands when executing `android`
|
||||||
|
|||||||
@@ -1,20 +1,38 @@
|
|||||||
|
image:
|
||||||
|
- Previous Visual Studio 2015
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
ANDROID_HOME: "C:\\android"
|
||||||
matrix:
|
matrix:
|
||||||
- nodejs_version: "0.10"
|
|
||||||
- nodejs_version: "0.12"
|
|
||||||
- nodejs_version: "4"
|
- nodejs_version: "4"
|
||||||
- nodejs_version: "6"
|
- nodejs_version: "6"
|
||||||
|
- nodejs_version: "8"
|
||||||
|
|
||||||
|
init:
|
||||||
|
- mkdir "%ANDROID_HOME%
|
||||||
|
- cd "%ANDROID_HOME%"
|
||||||
|
- appveyor DownloadFile "https://dl.google.com/android/repository/tools_r25.2.3-windows.zip"
|
||||||
|
- 7z x "tools_r25.2.3-windows.zip" > nul
|
||||||
|
- cd "C:\projects\cordova-android"
|
||||||
|
|
||||||
install:
|
install:
|
||||||
# - cinst android-sdk
|
- choco install gradle -version 3.4.1
|
||||||
# - echo y | android update sdk -u --filter android-22,android-23
|
- gradle -version
|
||||||
|
- echo y | "%ANDROID_HOME%\tools\android.bat" --silent update sdk --no-ui --all --filter platform-tools,tools,build-tools-26.0.2,android-26,android-25,extra-google-m2repository,extra-android-m2repository
|
||||||
|
# on windows we need to accept sublicenses for the new tooling, wee. 30 is an arbitrary number,
|
||||||
|
# but should be the maximum number of licenses we explicitly need to type "Y ENTER" for.
|
||||||
|
# also, the sdkmanager in all its glory leaks a bit of output to stderr, and powershell
|
||||||
|
# and appveyor interpret that as errors, and blows up. so, when piping in our "Y ENTER"
|
||||||
|
# responses, we invoke cmd so we can redirect stderr to stdout, and tell it to --update itself.
|
||||||
|
- ps: for($i=0;$i -lt 30;$i++) { $response += "y`n"}; $response | cmd /c 'C:\android\tools\bin\sdkmanager.bat 2>&1' --update
|
||||||
- ps: Install-Product node $env:nodejs_version
|
- ps: Install-Product node $env:nodejs_version
|
||||||
- npm install
|
- npm install
|
||||||
|
# below is a workaround on using gradle installed via choco on appveyor
|
||||||
|
- set path=C:\ProgramData\chocolatey\lib\gradle\tools\gradle-3.4.1\bin;%path%
|
||||||
|
|
||||||
build: off
|
build: off
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- node --version
|
- node --version
|
||||||
- npm --version
|
- npm --version
|
||||||
- npm run test
|
- npm test
|
||||||
# - npm run test-build
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
SET script_path="%~dp0android_sdk_version"
|
SET script_path="%~dp0android_sdk_version"
|
||||||
IF EXIST %script_path% (
|
IF EXIST %script_path% (
|
||||||
node "%script_path%" %*
|
node %script_path% %*
|
||||||
) ELSE (
|
) ELSE (
|
||||||
ECHO.
|
ECHO.
|
||||||
ECHO ERROR: Could not find 'android_sdk_version' script in 'bin' folder, aborting...>&2
|
ECHO ERROR: Could not find 'android_sdk_version' script in 'bin' folder, aborting...>&2
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
SET script_path="%~dp0check_reqs"
|
SET script_path="%~dp0check_reqs"
|
||||||
IF EXIST %script_path% (
|
IF EXIST %script_path% (
|
||||||
node "%script_path%" %*
|
node %script_path% %*
|
||||||
) ELSE (
|
) ELSE (
|
||||||
ECHO.
|
ECHO.
|
||||||
ECHO ERROR: Could not find 'check_reqs' script in 'bin' folder, aborting...>&2
|
ECHO ERROR: Could not find 'check_reqs' script in 'bin' folder, aborting...>&2
|
||||||
|
|||||||
@@ -19,30 +19,42 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var shell = require('shelljs'),
|
var shell = require('shelljs');
|
||||||
Q = require('q'),
|
var Q = require('q');
|
||||||
path = require('path'),
|
var path = require('path');
|
||||||
fs = require('fs'),
|
var fs = require('fs');
|
||||||
check_reqs = require('./../templates/cordova/lib/check_reqs'),
|
var check_reqs = require('./../templates/cordova/lib/check_reqs');
|
||||||
ROOT = path.join(__dirname, '..', '..');
|
var ROOT = path.join(__dirname, '..', '..');
|
||||||
|
|
||||||
var MIN_SDK_VERSION = 16;
|
var MIN_SDK_VERSION = 16;
|
||||||
|
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
var AndroidManifest = require('../templates/cordova/lib/AndroidManifest');
|
var AndroidManifest = require('../templates/cordova/lib/AndroidManifest');
|
||||||
|
|
||||||
function setShellFatal(value, func) {
|
// Export all helper functions, and make sure internally within this module, we
|
||||||
|
// reference these methods via the `exports` object - this helps with testing
|
||||||
|
// (since we can then mock and control behaviour of all of these functions)
|
||||||
|
exports.validatePackageName = validatePackageName;
|
||||||
|
exports.validateProjectName = validateProjectName;
|
||||||
|
exports.setShellFatal = setShellFatal;
|
||||||
|
exports.copyJsAndLibrary = copyJsAndLibrary;
|
||||||
|
exports.copyScripts = copyScripts;
|
||||||
|
exports.copyBuildRules = copyBuildRules;
|
||||||
|
exports.writeProjectProperties = writeProjectProperties;
|
||||||
|
exports.prepBuildFiles = prepBuildFiles;
|
||||||
|
|
||||||
|
function setShellFatal (value, func) {
|
||||||
var oldVal = shell.config.fatal;
|
var oldVal = shell.config.fatal;
|
||||||
shell.config.fatal = value;
|
shell.config.fatal = value;
|
||||||
func();
|
func();
|
||||||
shell.config.fatal = oldVal;
|
shell.config.fatal = oldVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFrameworkDir(projectPath, shared) {
|
function getFrameworkDir (projectPath, shared) {
|
||||||
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
|
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyJsAndLibrary(projectPath, shared, projectName) {
|
function copyJsAndLibrary (projectPath, shared, projectName) {
|
||||||
var nestedCordovaLibPath = getFrameworkDir(projectPath, false);
|
var nestedCordovaLibPath = getFrameworkDir(projectPath, false);
|
||||||
var srcCordovaJsPath = path.join(ROOT, 'bin', 'templates', 'project', 'assets', 'www', 'cordova.js');
|
var srcCordovaJsPath = path.join(ROOT, 'bin', 'templates', 'project', 'assets', 'www', 'cordova.js');
|
||||||
shell.cp('-f', srcCordovaJsPath, path.join(projectPath, 'assets', 'www', 'cordova.js'));
|
shell.cp('-f', srcCordovaJsPath, path.join(projectPath, 'assets', 'www', 'cordova.js'));
|
||||||
@@ -57,8 +69,8 @@ function copyJsAndLibrary(projectPath, shared, projectName) {
|
|||||||
shell.cp('-rf', path.join(ROOT, 'cordova-js-src'), path.join(projectPath, 'platform_www'));
|
shell.cp('-rf', path.join(ROOT, 'cordova-js-src'), path.join(projectPath, 'platform_www'));
|
||||||
|
|
||||||
// Don't fail if there are no old jars.
|
// Don't fail if there are no old jars.
|
||||||
setShellFatal(false, function() {
|
exports.setShellFatal(false, function () {
|
||||||
shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function(oldJar) {
|
shell.ls(path.join(projectPath, 'libs', 'cordova-*.jar')).forEach(function (oldJar) {
|
||||||
console.log('Deleting ' + oldJar);
|
console.log('Deleting ' + oldJar);
|
||||||
shell.rm('-f', oldJar);
|
shell.rm('-f', oldJar);
|
||||||
});
|
});
|
||||||
@@ -90,7 +102,7 @@ function copyJsAndLibrary(projectPath, shared, projectName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractSubProjectPaths(data) {
|
function extractSubProjectPaths (data) {
|
||||||
var ret = {};
|
var ret = {};
|
||||||
var r = /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg;
|
var r = /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg;
|
||||||
var m;
|
var m;
|
||||||
@@ -100,7 +112,7 @@ function extractSubProjectPaths(data) {
|
|||||||
return Object.keys(ret);
|
return Object.keys(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeProjectProperties(projectPath, target_api) {
|
function writeProjectProperties (projectPath, target_api) {
|
||||||
var dstPath = path.join(projectPath, 'project.properties');
|
var dstPath = path.join(projectPath, 'project.properties');
|
||||||
var templatePath = path.join(ROOT, 'bin', 'templates', 'project', 'project.properties');
|
var templatePath = path.join(ROOT, 'bin', 'templates', 'project', 'project.properties');
|
||||||
var srcPath = fs.existsSync(dstPath) ? dstPath : templatePath;
|
var srcPath = fs.existsSync(dstPath) ? dstPath : templatePath;
|
||||||
@@ -108,11 +120,10 @@ function writeProjectProperties(projectPath, target_api) {
|
|||||||
var data = fs.readFileSync(srcPath, 'utf8');
|
var data = fs.readFileSync(srcPath, 'utf8');
|
||||||
data = data.replace(/^target=.*/m, 'target=' + target_api);
|
data = data.replace(/^target=.*/m, 'target=' + target_api);
|
||||||
var subProjects = extractSubProjectPaths(data);
|
var subProjects = extractSubProjectPaths(data);
|
||||||
subProjects = subProjects.filter(function(p) {
|
subProjects = subProjects.filter(function (p) {
|
||||||
return !(/^CordovaLib$/m.exec(p) ||
|
return !(/^CordovaLib$/m.exec(p) ||
|
||||||
/[\\\/]cordova-android[\\\/]framework$/m.exec(p) ||
|
/[\\/]cordova-android[\\/]framework$/m.exec(p) ||
|
||||||
/^(\.\.[\\\/])+framework$/m.exec(p)
|
/^(\.\.[\\/])+framework$/m.exec(p));
|
||||||
);
|
|
||||||
});
|
});
|
||||||
subProjects.unshift('CordovaLib');
|
subProjects.unshift('CordovaLib');
|
||||||
data = data.replace(/^\s*android\.library\.reference\.\d+=.*\n/mg, '');
|
data = data.replace(/^\s*android\.library\.reference\.\d+=.*\n/mg, '');
|
||||||
@@ -120,24 +131,24 @@ function writeProjectProperties(projectPath, target_api) {
|
|||||||
data += '\n';
|
data += '\n';
|
||||||
}
|
}
|
||||||
for (var i = 0; i < subProjects.length; ++i) {
|
for (var i = 0; i < subProjects.length; ++i) {
|
||||||
data += 'android.library.reference.' + (i+1) + '=' + subProjects[i] + '\n';
|
data += 'android.library.reference.' + (i + 1) + '=' + subProjects[i] + '\n';
|
||||||
}
|
}
|
||||||
fs.writeFileSync(dstPath, data);
|
fs.writeFileSync(dstPath, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepBuildFiles(projectPath) {
|
function prepBuildFiles (projectPath) {
|
||||||
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
|
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
|
||||||
buildModule.getBuilder('gradle').prepBuildFiles();
|
buildModule.getBuilder('gradle').prepBuildFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyBuildRules(projectPath) {
|
function copyBuildRules (projectPath) {
|
||||||
var srcDir = path.join(ROOT, 'bin', 'templates', 'project');
|
var srcDir = path.join(ROOT, 'bin', 'templates', 'project');
|
||||||
|
|
||||||
shell.cp('-f', path.join(srcDir, 'build.gradle'), projectPath);
|
shell.cp('-f', path.join(srcDir, 'build.gradle'), projectPath);
|
||||||
shell.cp('-f', path.join(srcDir, 'wrapper.gradle'), projectPath);
|
shell.cp('-f', path.join(srcDir, 'wrapper.gradle'), projectPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyScripts(projectPath) {
|
function copyScripts (projectPath) {
|
||||||
var bin = path.join(ROOT, 'bin');
|
var bin = path.join(ROOT, 'bin');
|
||||||
var srcScriptsDir = path.join(bin, 'templates', 'cordova');
|
var srcScriptsDir = path.join(bin, 'templates', 'cordova');
|
||||||
var destScriptsDir = path.join(projectPath, 'cordova');
|
var destScriptsDir = path.join(projectPath, 'cordova');
|
||||||
@@ -164,17 +175,18 @@ function copyScripts(projectPath) {
|
|||||||
* Returns a promise, fulfilled if the package name is acceptable; rejected
|
* Returns a promise, fulfilled if the package name is acceptable; rejected
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
function validatePackageName(package_name) {
|
function validatePackageName (package_name) {
|
||||||
//Make the package conform to Java package types
|
// Make the package conform to Java package types
|
||||||
//http://developer.android.com/guide/topics/manifest/manifest-element.html#package
|
// http://developer.android.com/guide/topics/manifest/manifest-element.html#package
|
||||||
//Enforce underscore limitation
|
// Enforce underscore limitation
|
||||||
var msg = 'Error validating package name. ';
|
var msg = 'Error validating package name. ';
|
||||||
|
|
||||||
if (!/^[a-zA-Z][a-zA-Z0-9_]+(\.[a-zA-Z][a-zA-Z0-9_]*)+$/.test(package_name)) {
|
if (!/^[a-zA-Z][a-zA-Z0-9_]+(\.[a-zA-Z][a-zA-Z0-9_]*)+$/.test(package_name)) {
|
||||||
return Q.reject(new CordovaError(msg + 'Package name must look like: com.company.Name'));
|
return Q.reject(new CordovaError(msg + 'Package name must look like: com.company.Name'));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Class is a reserved word
|
// Class is a reserved word
|
||||||
if(/\b[Cc]lass\b/.test(package_name)) {
|
if (/\b[Cc]lass\b/.test(package_name)) {
|
||||||
return Q.reject(new CordovaError(msg + '"class" is a reserved word'));
|
return Q.reject(new CordovaError(msg + '"class" is a reserved word'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,19 +198,19 @@ function validatePackageName(package_name) {
|
|||||||
* Returns a promise, fulfilled if the project name is acceptable; rejected
|
* Returns a promise, fulfilled if the project name is acceptable; rejected
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
function validateProjectName(project_name) {
|
function validateProjectName (project_name) {
|
||||||
var msg = 'Error validating project name. ';
|
var msg = 'Error validating project name. ';
|
||||||
//Make sure there's something there
|
// Make sure there's something there
|
||||||
if (project_name === '') {
|
if (project_name === '') {
|
||||||
return Q.reject(new CordovaError(msg + 'Project name cannot be empty'));
|
return Q.reject(new CordovaError(msg + 'Project name cannot be empty'));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Enforce stupid name error
|
// Enforce stupid name error
|
||||||
if (project_name === 'CordovaActivity') {
|
if (project_name === 'CordovaActivity') {
|
||||||
return Q.reject(new CordovaError(msg + 'Project name cannot be CordovaActivity'));
|
return Q.reject(new CordovaError(msg + 'Project name cannot be CordovaActivity'));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Classes in Java don't begin with numbers
|
// Classes in Java don't begin with numbers
|
||||||
if (/^[0-9]/.test(project_name)) {
|
if (/^[0-9]/.test(project_name)) {
|
||||||
return Q.reject(new CordovaError(msg + 'Project name must not begin with a number'));
|
return Q.reject(new CordovaError(msg + 'Project name must not begin with a number'));
|
||||||
}
|
}
|
||||||
@@ -224,83 +236,83 @@ function validateProjectName(project_name) {
|
|||||||
*
|
*
|
||||||
* @return {Promise<String>} Directory where application has been created
|
* @return {Promise<String>} Directory where application has been created
|
||||||
*/
|
*/
|
||||||
exports.create = function(project_path, config, options, events) {
|
exports.create = function (project_path, config, options, events) {
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
// Set default values for path, package and name
|
// Set default values for path, package and name
|
||||||
project_path = path.relative(process.cwd(), (project_path || 'CordovaExample'));
|
project_path = path.relative(process.cwd(), (project_path || 'CordovaExample'));
|
||||||
// Check if project already exists
|
// Check if project already exists
|
||||||
if(fs.existsSync(project_path)) {
|
if (fs.existsSync(project_path)) {
|
||||||
return Q.reject(new CordovaError('Project already exists! Delete and recreate'));
|
return Q.reject(new CordovaError('Project already exists! Delete and recreate'));
|
||||||
}
|
}
|
||||||
|
|
||||||
var package_name = config.packageName() || 'my.cordova.project';
|
var package_name = config.android_packageName() || config.packageName() || 'my.cordova.project';
|
||||||
var project_name = config.name() ?
|
var project_name = config.name() ?
|
||||||
config.name().replace(/[^\w.]/g,'_') : 'CordovaExample';
|
config.name().replace(/[^\w.]/g, '_') : 'CordovaExample';
|
||||||
|
|
||||||
var safe_activity_name = config.android_activityName() || options.activityName || 'MainActivity';
|
var safe_activity_name = config.android_activityName() || options.activityName || 'MainActivity';
|
||||||
var target_api = check_reqs.get_target();
|
var target_api = check_reqs.get_target();
|
||||||
|
|
||||||
//Make the package conform to Java package types
|
// Make the package conform to Java package types
|
||||||
return validatePackageName(package_name)
|
return exports.validatePackageName(package_name)
|
||||||
.then(function() {
|
.then(function () {
|
||||||
validateProjectName(project_name);
|
exports.validateProjectName(project_name);
|
||||||
}).then(function() {
|
}).then(function () {
|
||||||
// Log the given values for the project
|
// Log the given values for the project
|
||||||
events.emit('log', 'Creating Cordova project for the Android platform:');
|
events.emit('log', 'Creating Cordova project for the Android platform:');
|
||||||
events.emit('log', '\tPath: ' + project_path);
|
events.emit('log', '\tPath: ' + project_path);
|
||||||
events.emit('log', '\tPackage: ' + package_name);
|
events.emit('log', '\tPackage: ' + package_name);
|
||||||
events.emit('log', '\tName: ' + project_name);
|
events.emit('log', '\tName: ' + project_name);
|
||||||
events.emit('log', '\tActivity: ' + safe_activity_name);
|
events.emit('log', '\tActivity: ' + safe_activity_name);
|
||||||
events.emit('log', '\tAndroid target: ' + target_api);
|
events.emit('log', '\tAndroid target: ' + target_api);
|
||||||
|
|
||||||
events.emit('verbose', 'Copying android template project to ' + project_path);
|
events.emit('verbose', 'Copying android template project to ' + project_path);
|
||||||
|
|
||||||
setShellFatal(true, function() {
|
exports.setShellFatal(true, function () {
|
||||||
var project_template_dir = options.customTemplate || path.join(ROOT, 'bin', 'templates', 'project');
|
var project_template_dir = options.customTemplate || path.join(ROOT, 'bin', 'templates', 'project');
|
||||||
// copy project template
|
// copy project template
|
||||||
shell.cp('-r', path.join(project_template_dir, 'assets'), project_path);
|
shell.cp('-r', path.join(project_template_dir, 'assets'), project_path);
|
||||||
shell.cp('-r', path.join(project_template_dir, 'res'), project_path);
|
shell.cp('-r', path.join(project_template_dir, 'res'), project_path);
|
||||||
shell.cp(path.join(project_template_dir, 'gitignore'), path.join(project_path, '.gitignore'));
|
shell.cp(path.join(project_template_dir, 'gitignore'), path.join(project_path, '.gitignore'));
|
||||||
|
|
||||||
// Manually create directories that would be empty within the template (since git doesn't track directories).
|
// Manually create directories that would be empty within the template (since git doesn't track directories).
|
||||||
shell.mkdir(path.join(project_path, 'libs'));
|
shell.mkdir(path.join(project_path, 'libs'));
|
||||||
|
|
||||||
// copy cordova.js, cordova.jar
|
// copy cordova.js, cordova.jar
|
||||||
copyJsAndLibrary(project_path, options.link, safe_activity_name);
|
exports.copyJsAndLibrary(project_path, options.link, safe_activity_name);
|
||||||
|
|
||||||
// interpolate the activity name and package
|
// interpolate the activity name and package
|
||||||
var packagePath = package_name.replace(/\./g, path.sep);
|
var packagePath = package_name.replace(/\./g, path.sep);
|
||||||
var activity_dir = path.join(project_path, 'src', packagePath);
|
var activity_dir = path.join(project_path, 'src', packagePath);
|
||||||
var activity_path = path.join(activity_dir, safe_activity_name + '.java');
|
var activity_path = path.join(activity_dir, safe_activity_name + '.java');
|
||||||
shell.mkdir('-p', activity_dir);
|
shell.mkdir('-p', activity_dir);
|
||||||
shell.cp('-f', path.join(project_template_dir, 'Activity.java'), activity_path);
|
shell.cp('-f', path.join(project_template_dir, 'Activity.java'), activity_path);
|
||||||
shell.sed('-i', /__ACTIVITY__/, safe_activity_name, activity_path);
|
shell.sed('-i', /__ACTIVITY__/, safe_activity_name, activity_path);
|
||||||
shell.sed('-i', /__NAME__/, project_name, path.join(project_path, 'res', 'values', 'strings.xml'));
|
shell.sed('-i', /__NAME__/, project_name, path.join(project_path, 'res', 'values', 'strings.xml'));
|
||||||
shell.sed('-i', /__ID__/, package_name, activity_path);
|
shell.sed('-i', /__ID__/, package_name, activity_path);
|
||||||
|
|
||||||
var manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
|
var manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
|
||||||
manifest.setPackageId(package_name)
|
manifest.setPackageId(package_name)
|
||||||
.setTargetSdkVersion(target_api.split('-')[1])
|
.setTargetSdkVersion(target_api.split('-')[1])
|
||||||
.getActivity().setName(safe_activity_name);
|
.getActivity().setName(safe_activity_name);
|
||||||
|
|
||||||
var manifest_path = path.join(project_path, 'AndroidManifest.xml');
|
var manifest_path = path.join(project_path, 'AndroidManifest.xml');
|
||||||
manifest.write(manifest_path);
|
manifest.write(manifest_path);
|
||||||
|
|
||||||
copyScripts(project_path);
|
exports.copyScripts(project_path);
|
||||||
copyBuildRules(project_path);
|
exports.copyBuildRules(project_path);
|
||||||
});
|
});
|
||||||
// Link it to local android install.
|
// Link it to local android install.
|
||||||
writeProjectProperties(project_path, target_api);
|
exports.writeProjectProperties(project_path, target_api);
|
||||||
prepBuildFiles(project_path);
|
exports.prepBuildFiles(project_path);
|
||||||
events.emit('log', generateDoneMessage('create', options.link));
|
events.emit('log', generateDoneMessage('create', options.link));
|
||||||
}).thenResolve(project_path);
|
}).thenResolve(project_path);
|
||||||
};
|
};
|
||||||
|
|
||||||
function generateDoneMessage(type, link) {
|
function generateDoneMessage (type, link) {
|
||||||
var pkg = require('../../package');
|
var pkg = require('../../package');
|
||||||
var msg = 'Android project ' + (type == 'update' ? 'updated ' : 'created ') + 'with ' + pkg.name + '@' + pkg.version;
|
var msg = 'Android project ' + (type === 'update' ? 'updated ' : 'created ') + 'with ' + pkg.name + '@' + pkg.version;
|
||||||
if (link) {
|
if (link) {
|
||||||
msg += ' and has a linked CordovaLib';
|
msg += ' and has a linked CordovaLib';
|
||||||
}
|
}
|
||||||
@@ -308,34 +320,29 @@ function generateDoneMessage(type, link) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns a promise.
|
// Returns a promise.
|
||||||
exports.update = function(projectPath, options, events) {
|
exports.update = function (projectPath, options, events) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
return Q()
|
return Q()
|
||||||
.then(function() {
|
.then(function () {
|
||||||
|
|
||||||
var manifest = new AndroidManifest(path.join(projectPath, 'AndroidManifest.xml'));
|
var manifest = new AndroidManifest(path.join(projectPath, 'AndroidManifest.xml'));
|
||||||
|
|
||||||
if (Number(manifest.getMinSdkVersion()) < MIN_SDK_VERSION) {
|
if (Number(manifest.getMinSdkVersion()) < MIN_SDK_VERSION) {
|
||||||
events.emit('verbose', 'Updating minSdkVersion to ' + MIN_SDK_VERSION + ' in AndroidManifest.xml');
|
events.emit('verbose', 'Updating minSdkVersion to ' + MIN_SDK_VERSION + ' in AndroidManifest.xml');
|
||||||
manifest.setMinSdkVersion(MIN_SDK_VERSION);
|
manifest.setMinSdkVersion(MIN_SDK_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
manifest.setDebuggable(false).write();
|
manifest.setDebuggable(false).write();
|
||||||
|
|
||||||
var projectName = manifest.getActivity().getName();
|
var projectName = manifest.getActivity().getName();
|
||||||
var target_api = check_reqs.get_target();
|
var target_api = check_reqs.get_target();
|
||||||
|
|
||||||
copyJsAndLibrary(projectPath, options.link, projectName);
|
exports.copyJsAndLibrary(projectPath, options.link, projectName);
|
||||||
copyScripts(projectPath);
|
exports.copyScripts(projectPath);
|
||||||
copyBuildRules(projectPath);
|
exports.copyBuildRules(projectPath);
|
||||||
writeProjectProperties(projectPath, target_api);
|
exports.writeProjectProperties(projectPath, target_api);
|
||||||
prepBuildFiles(projectPath);
|
exports.prepBuildFiles(projectPath);
|
||||||
events.emit('log', generateDoneMessage('update', options.link));
|
events.emit('log', generateDoneMessage('update', options.link));
|
||||||
}).thenResolve(projectPath);
|
}).thenResolve(projectPath);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// For testing
|
|
||||||
exports.validatePackageName = validatePackageName;
|
|
||||||
exports.validateProjectName = validateProjectName;
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
{
|
|
||||||
"node": true
|
|
||||||
, "bitwise": true
|
|
||||||
, "undef": true
|
|
||||||
, "trailing": true
|
|
||||||
, "quotmark": true
|
|
||||||
, "indent": 4
|
|
||||||
, "unused": "vars"
|
|
||||||
, "latedef": "nofunc"
|
|
||||||
}
|
|
||||||
@@ -29,8 +29,7 @@ var selfEvents = require('cordova-common').events;
|
|||||||
|
|
||||||
var PLATFORM = 'android';
|
var PLATFORM = 'android';
|
||||||
|
|
||||||
|
function setupEvents (externalEventEmitter) {
|
||||||
function setupEvents(externalEventEmitter) {
|
|
||||||
if (externalEventEmitter) {
|
if (externalEventEmitter) {
|
||||||
// This will make the platform internal events visible outside
|
// This will make the platform internal events visible outside
|
||||||
selfEvents.forwardEventsTo(externalEventEmitter);
|
selfEvents.forwardEventsTo(externalEventEmitter);
|
||||||
@@ -43,7 +42,6 @@ function setupEvents(externalEventEmitter) {
|
|||||||
return selfEvents;
|
return selfEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class, that acts as abstraction over particular platform. Encapsulates the
|
* Class, that acts as abstraction over particular platform. Encapsulates the
|
||||||
* platform's properties and methods.
|
* platform's properties and methods.
|
||||||
@@ -55,7 +53,7 @@ function setupEvents(externalEventEmitter) {
|
|||||||
*
|
*
|
||||||
* * platform: String that defines a platform name.
|
* * platform: String that defines a platform name.
|
||||||
*/
|
*/
|
||||||
function Api(platform, platformRootDir, events) {
|
function Api (platform, platformRootDir, events) {
|
||||||
this.platform = PLATFORM;
|
this.platform = PLATFORM;
|
||||||
this.root = path.resolve(__dirname, '..');
|
this.root = path.resolve(__dirname, '..');
|
||||||
|
|
||||||
@@ -79,14 +77,14 @@ function Api(platform, platformRootDir, events) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// XXX Override some locations for Android Studio projects
|
// XXX Override some locations for Android Studio projects
|
||||||
if(AndroidStudio.isAndroidStudioProject(self.root) === true) {
|
if (AndroidStudio.isAndroidStudioProject(self.root) === true) {
|
||||||
selfEvents.emit('log', 'Android Studio project detected');
|
selfEvents.emit('log', 'Android Studio project detected');
|
||||||
this.android_studio = true;
|
this.android_studio = true;
|
||||||
this.locations.configXml = path.join(self.root, 'app/src/main/res/xml/config.xml');
|
this.locations.configXml = path.join(self.root, 'app/src/main/res/xml/config.xml');
|
||||||
this.locations.strings = path.join(self.root, 'app/src/main/res/xml/strings.xml');
|
this.locations.strings = path.join(self.root, 'app/src/main/res/xml/strings.xml');
|
||||||
this.locations.manifest = path.join(self.root, 'app/src/main/AndroidManifest.xml');
|
this.locations.manifest = path.join(self.root, 'app/src/main/AndroidManifest.xml');
|
||||||
this.locations.www = path.join(self.root, 'app/src/main/assets/www');
|
this.locations.www = path.join(self.root, 'app/src/main/assets/www');
|
||||||
this.locations.res = path.join(self.root, 'app/src/main/res');
|
this.locations.res = path.join(self.root, 'app/src/main/res');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,16 +110,13 @@ Api.createPlatform = function (destination, config, options, events) {
|
|||||||
events = setupEvents(events);
|
events = setupEvents(events);
|
||||||
var result;
|
var result;
|
||||||
try {
|
try {
|
||||||
result = require('../../lib/create')
|
result = require('../../lib/create').create(destination, config, options, events).then(function (destination) {
|
||||||
.create(destination, config, options, events)
|
|
||||||
.then(function (destination) {
|
|
||||||
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
||||||
return new PlatformApi(PLATFORM, destination, events);
|
return new PlatformApi(PLATFORM, destination, events);
|
||||||
});
|
});
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
events.emit('error', 'createPlatform is not callable from the android project API.');
|
||||||
events.emit('error','createPlatform is not callable from the android project API.');
|
throw (e);
|
||||||
throw(e);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -146,16 +141,13 @@ Api.updatePlatform = function (destination, options, events) {
|
|||||||
events = setupEvents(events);
|
events = setupEvents(events);
|
||||||
var result;
|
var result;
|
||||||
try {
|
try {
|
||||||
result = require('../../lib/create')
|
result = require('../../lib/create').update(destination, options, events).then(function (destination) {
|
||||||
.update(destination, options, events)
|
|
||||||
.then(function (destination) {
|
|
||||||
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
||||||
return new PlatformApi('android', destination, events);
|
return new PlatformApi('android', destination, events);
|
||||||
});
|
});
|
||||||
}
|
} catch (e) {
|
||||||
catch (e) {
|
events.emit('error', 'updatePlatform is not callable from the android project API, you will need to do this manually.');
|
||||||
events.emit('error','updatePlatform is not callable from the android project API, you will need to do this manually.');
|
throw (e);
|
||||||
throw(e);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -226,40 +218,36 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
|
|||||||
installOptions.variables.PACKAGE_NAME = project.getPackageName();
|
installOptions.variables.PACKAGE_NAME = project.getPackageName();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.android_studio === true) {
|
if (this.android_studio === true) {
|
||||||
installOptions.android_studio = true;
|
installOptions.android_studio = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Q()
|
return Q().then(function () {
|
||||||
.then(function () {
|
// CB-11964: Do a clean when installing the plugin code to get around
|
||||||
//CB-11964: Do a clean when installing the plugin code to get around
|
// the Gradle bug introduced by the Android Gradle Plugin Version 2.2
|
||||||
//the Gradle bug introduced by the Android Gradle Plugin Version 2.2
|
// TODO: Delete when the next version of Android Gradle plugin comes out
|
||||||
//TODO: Delete when the next version of Android Gradle plugin comes out
|
|
||||||
|
|
||||||
// Since clean doesn't just clean the build, it also wipes out www, we need
|
// Since clean doesn't just clean the build, it also wipes out www, we need
|
||||||
// to pass additional options.
|
// to pass additional options.
|
||||||
|
|
||||||
// Do some basic argument parsing
|
// Do some basic argument parsing
|
||||||
var opts = {};
|
var opts = {};
|
||||||
|
|
||||||
// Skip cleaning prepared files when not invoking via cordova CLI.
|
// Skip cleaning prepared files when not invoking via cordova CLI.
|
||||||
opts.noPrepare = true;
|
opts.noPrepare = true;
|
||||||
|
|
||||||
if(!AndroidStudio.isAndroidStudioProject(self.root) && !project.isClean()) {
|
if (!AndroidStudio.isAndroidStudioProject(self.root) && !project.isClean()) {
|
||||||
return self.clean(opts);
|
return self.clean(opts);
|
||||||
}
|
}
|
||||||
})
|
}).then(function () {
|
||||||
.then(function () {
|
return PluginManager.get(self.platform, self.locations, project).addPlugin(plugin, installOptions);
|
||||||
return PluginManager.get(self.platform, self.locations, project)
|
}).then(function () {
|
||||||
.addPlugin(plugin, installOptions);
|
if (plugin.getFrameworks(this.platform).length === 0) return;
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
if (plugin.getFrameworks(this.platform).length === 0) return;
|
|
||||||
|
|
||||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||||
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
require('./lib/builders/builders').getBuilder('gradle').prepBuildFiles();
|
||||||
}.bind(this))
|
}.bind(this))
|
||||||
// CB-11022 Return truthy value to prevent running prepare after
|
// CB-11022 Return truthy value to prevent running prepare after
|
||||||
.thenResolve(true);
|
.thenResolve(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -279,9 +267,9 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
|
|||||||
Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
||||||
var project = AndroidProject.getProjectFile(this.root);
|
var project = AndroidProject.getProjectFile(this.root);
|
||||||
|
|
||||||
if(uninstallOptions && uninstallOptions.usePlatformWww === true && this.android_studio === true) {
|
if (uninstallOptions && uninstallOptions.usePlatformWww === true && this.android_studio === true) {
|
||||||
uninstallOptions.usePlatformWww = false;
|
uninstallOptions.usePlatformWww = false;
|
||||||
uninstallOptions.android_studio = true;
|
uninstallOptions.android_studio = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PluginManager.get(this.platform, this.locations, project)
|
return PluginManager.get(this.platform, this.locations, project)
|
||||||
@@ -343,11 +331,9 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
|||||||
*/
|
*/
|
||||||
Api.prototype.build = function (buildOptions) {
|
Api.prototype.build = function (buildOptions) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return require('./lib/check_reqs').run()
|
return require('./lib/check_reqs').run().then(function () {
|
||||||
.then(function () {
|
|
||||||
return require('./lib/build').run.call(self, buildOptions);
|
return require('./lib/build').run.call(self, buildOptions);
|
||||||
})
|
}).then(function (buildResults) {
|
||||||
.then(function (buildResults) {
|
|
||||||
// Cast build result to array of build artifacts
|
// Cast build result to array of build artifacts
|
||||||
return buildResults.apkPaths.map(function (apkPath) {
|
return buildResults.apkPaths.map(function (apkPath) {
|
||||||
return {
|
return {
|
||||||
@@ -372,10 +358,9 @@ Api.prototype.build = function (buildOptions) {
|
|||||||
* @return {Promise} A promise either fulfilled if package was built and ran
|
* @return {Promise} A promise either fulfilled if package was built and ran
|
||||||
* successfully, or rejected with CordovaError.
|
* successfully, or rejected with CordovaError.
|
||||||
*/
|
*/
|
||||||
Api.prototype.run = function(runOptions) {
|
Api.prototype.run = function (runOptions) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return require('./lib/check_reqs').run()
|
return require('./lib/check_reqs').run().then(function () {
|
||||||
.then(function () {
|
|
||||||
return require('./lib/run').run.call(self, runOptions);
|
return require('./lib/run').run.call(self, runOptions);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -387,19 +372,15 @@ Api.prototype.run = function(runOptions) {
|
|||||||
* @return {Promise} Return a promise either fulfilled, or rejected with
|
* @return {Promise} Return a promise either fulfilled, or rejected with
|
||||||
* CordovaError.
|
* CordovaError.
|
||||||
*/
|
*/
|
||||||
Api.prototype.clean = function(cleanOptions) {
|
Api.prototype.clean = function (cleanOptions) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return require('./lib/check_reqs').run()
|
return require('./lib/check_reqs').run().then(function () {
|
||||||
.then(function () {
|
return require('./lib/build').runClean.call(self, cleanOptions);
|
||||||
return require('./lib/build').runClean.call(self, cleanOptions);
|
}).then(function () {
|
||||||
})
|
return require('./lib/prepare').clean.call(self, cleanOptions);
|
||||||
.then(function () {
|
});
|
||||||
return require('./lib/prepare').clean.call(self, cleanOptions);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a requirements check for current platform. Each platform defines its
|
* Performs a requirements check for current platform. Each platform defines its
|
||||||
* own set of requirements, which should be resolved before platform can be
|
* own set of requirements, which should be resolved before platform can be
|
||||||
@@ -408,7 +389,7 @@ Api.prototype.clean = function(cleanOptions) {
|
|||||||
* @return {Promise<Requirement[]>} Promise, resolved with set of Requirement
|
* @return {Promise<Requirement[]>} Promise, resolved with set of Requirement
|
||||||
* objects for current platform.
|
* objects for current platform.
|
||||||
*/
|
*/
|
||||||
Api.prototype.requirements = function() {
|
Api.prototype.requirements = function () {
|
||||||
return require('./lib/check_reqs').check_all();
|
return require('./lib/check_reqs').check_all();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -25,11 +25,11 @@ var CordovaError = require('cordova-common').CordovaError;
|
|||||||
|
|
||||||
var Adb = {};
|
var Adb = {};
|
||||||
|
|
||||||
function isDevice(line) {
|
function isDevice (line) {
|
||||||
return line.match(/\w+\tdevice/) && !line.match(/emulator/);
|
return line.match(/\w+\tdevice/) && !line.match(/emulator/);
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEmulator(line) {
|
function isEmulator (line) {
|
||||||
return line.match(/device/) && line.match(/emulator/);
|
return line.match(/device/) && line.match(/emulator/);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,8 +44,7 @@ function isEmulator(line) {
|
|||||||
* devices/emulators
|
* devices/emulators
|
||||||
*/
|
*/
|
||||||
Adb.devices = function (opts) {
|
Adb.devices = function (opts) {
|
||||||
return spawn('adb', ['devices'], {cwd: os.tmpdir()})
|
return spawn('adb', ['devices'], {cwd: os.tmpdir()}).then(function (output) {
|
||||||
.then(function(output) {
|
|
||||||
return output.split('\n').filter(function (line) {
|
return output.split('\n').filter(function (line) {
|
||||||
// Filter out either real devices or emulators, depending on options
|
// Filter out either real devices or emulators, depending on options
|
||||||
return (line && opts && opts.emulators) ? isEmulator(line) : isDevice(line);
|
return (line && opts && opts.emulators) ? isEmulator(line) : isDevice(line);
|
||||||
@@ -59,8 +58,7 @@ Adb.install = function (target, packagePath, opts) {
|
|||||||
events.emit('verbose', 'Installing apk ' + packagePath + ' on target ' + target + '...');
|
events.emit('verbose', 'Installing apk ' + packagePath + ' on target ' + target + '...');
|
||||||
var args = ['-s', target, 'install'];
|
var args = ['-s', target, 'install'];
|
||||||
if (opts && opts.replace) args.push('-r');
|
if (opts && opts.replace) args.push('-r');
|
||||||
return spawn('adb', args.concat(packagePath), {cwd: os.tmpdir()})
|
return spawn('adb', args.concat(packagePath), {cwd: os.tmpdir()}).then(function (output) {
|
||||||
.then(function(output) {
|
|
||||||
// 'adb install' seems to always returns no error, even if installation fails
|
// 'adb install' seems to always returns no error, even if installation fails
|
||||||
// so we catching output to detect installation failure
|
// so we catching output to detect installation failure
|
||||||
if (output.match(/Failure/)) {
|
if (output.match(/Failure/)) {
|
||||||
@@ -86,8 +84,7 @@ Adb.shell = function (target, shellCommand) {
|
|||||||
events.emit('verbose', 'Running adb shell command "' + shellCommand + '" on target ' + target + '...');
|
events.emit('verbose', 'Running adb shell command "' + shellCommand + '" on target ' + target + '...');
|
||||||
var args = ['-s', target, 'shell'];
|
var args = ['-s', target, 'shell'];
|
||||||
shellCommand = shellCommand.split(/\s+/);
|
shellCommand = shellCommand.split(/\s+/);
|
||||||
return spawn('adb', args.concat(shellCommand), {cwd: os.tmpdir()})
|
return spawn('adb', args.concat(shellCommand), {cwd: os.tmpdir()}).catch(function (output) {
|
||||||
.catch(function (output) {
|
|
||||||
return Q.reject(new CordovaError('Failed to execute shell command "' +
|
return Q.reject(new CordovaError('Failed to execute shell command "' +
|
||||||
shellCommand + '"" on device: ' + output));
|
shellCommand + '"" on device: ' + output));
|
||||||
});
|
});
|
||||||
@@ -95,8 +92,7 @@ Adb.shell = function (target, shellCommand) {
|
|||||||
|
|
||||||
Adb.start = function (target, activityName) {
|
Adb.start = function (target, activityName) {
|
||||||
events.emit('verbose', 'Starting application "' + activityName + '" on target ' + target + '...');
|
events.emit('verbose', 'Starting application "' + activityName + '" on target ' + target + '...');
|
||||||
return Adb.shell(target, 'am start -W -a android.intent.action.MAIN -n' + activityName)
|
return Adb.shell(target, 'am start -W -a android.intent.action.MAIN -n' + activityName).catch(function (output) {
|
||||||
.catch(function (output) {
|
|
||||||
return Q.reject(new CordovaError('Failed to start application "' +
|
return Q.reject(new CordovaError('Failed to start application "' +
|
||||||
activityName + '"" on device: ' + output));
|
activityName + '"" on device: ' + output));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,12 +19,12 @@
|
|||||||
|
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var et = require('elementtree');
|
var et = require('elementtree');
|
||||||
var xml= require('cordova-common').xmlHelpers;
|
var xml = require('cordova-common').xmlHelpers;
|
||||||
|
|
||||||
var DEFAULT_ORIENTATION = 'default';
|
var DEFAULT_ORIENTATION = 'default';
|
||||||
|
|
||||||
/** Wraps an AndroidManifest file */
|
/** Wraps an AndroidManifest file */
|
||||||
function AndroidManifest(path) {
|
function AndroidManifest (path) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
this.doc = xml.parseElementtreeSync(path);
|
this.doc = xml.parseElementtreeSync(path);
|
||||||
if (this.doc.getroot().tag !== 'manifest') {
|
if (this.doc.getroot().tag !== 'manifest') {
|
||||||
@@ -32,38 +32,38 @@ function AndroidManifest(path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidManifest.prototype.getVersionName = function() {
|
AndroidManifest.prototype.getVersionName = function () {
|
||||||
return this.doc.getroot().attrib['android:versionName'];
|
return this.doc.getroot().attrib['android:versionName'];
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidManifest.prototype.setVersionName = function(versionName) {
|
AndroidManifest.prototype.setVersionName = function (versionName) {
|
||||||
this.doc.getroot().attrib['android:versionName'] = versionName;
|
this.doc.getroot().attrib['android:versionName'] = versionName;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidManifest.prototype.getVersionCode = function() {
|
AndroidManifest.prototype.getVersionCode = function () {
|
||||||
return this.doc.getroot().attrib['android:versionCode'];
|
return this.doc.getroot().attrib['android:versionCode'];
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidManifest.prototype.setVersionCode = function(versionCode) {
|
AndroidManifest.prototype.setVersionCode = function (versionCode) {
|
||||||
this.doc.getroot().attrib['android:versionCode'] = versionCode;
|
this.doc.getroot().attrib['android:versionCode'] = versionCode;
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidManifest.prototype.getPackageId = function() {
|
AndroidManifest.prototype.getPackageId = function () {
|
||||||
/*jshint -W069 */
|
/* jshint -W069 */
|
||||||
return this.doc.getroot().attrib['package'];
|
return this.doc.getroot().attrib['package'];
|
||||||
/*jshint +W069 */
|
/* jshint +W069 */
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidManifest.prototype.setPackageId = function(pkgId) {
|
AndroidManifest.prototype.setPackageId = function (pkgId) {
|
||||||
/*jshint -W069 */
|
/* jshint -W069 */
|
||||||
this.doc.getroot().attrib['package'] = pkgId;
|
this.doc.getroot().attrib['package'] = pkgId;
|
||||||
/*jshint +W069 */
|
/* jshint +W069 */
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidManifest.prototype.getActivity = function() {
|
AndroidManifest.prototype.getActivity = function () {
|
||||||
var activity = this.doc.getroot().find('./application/activity');
|
var activity = this.doc.getroot().find('./application/activity');
|
||||||
return {
|
return {
|
||||||
getName: function () {
|
getName: function () {
|
||||||
@@ -102,17 +102,16 @@ AndroidManifest.prototype.getActivity = function() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion']
|
['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion'].forEach(function (sdkPrefName) {
|
||||||
.forEach(function(sdkPrefName) {
|
|
||||||
// Copy variable reference to avoid closure issues
|
// Copy variable reference to avoid closure issues
|
||||||
var prefName = sdkPrefName;
|
var prefName = sdkPrefName;
|
||||||
|
|
||||||
AndroidManifest.prototype['get' + capitalize(prefName)] = function() {
|
AndroidManifest.prototype['get' + capitalize(prefName)] = function () {
|
||||||
var usesSdk = this.doc.getroot().find('./uses-sdk');
|
var usesSdk = this.doc.getroot().find('./uses-sdk');
|
||||||
return usesSdk && usesSdk.attrib['android:' + prefName];
|
return usesSdk && usesSdk.attrib['android:' + prefName];
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidManifest.prototype['set' + capitalize(prefName)] = function(prefValue) {
|
AndroidManifest.prototype['set' + capitalize(prefName)] = function (prefValue) {
|
||||||
var usesSdk = this.doc.getroot().find('./uses-sdk');
|
var usesSdk = this.doc.getroot().find('./uses-sdk');
|
||||||
|
|
||||||
if (!usesSdk && prefValue) { // if there is no required uses-sdk element, we should create it first
|
if (!usesSdk && prefValue) { // if there is no required uses-sdk element, we should create it first
|
||||||
@@ -128,11 +127,11 @@ AndroidManifest.prototype.getActivity = function() {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
AndroidManifest.prototype.getDebuggable = function() {
|
AndroidManifest.prototype.getDebuggable = function () {
|
||||||
return this.doc.getroot().find('./application').attrib['android:debuggable'] === 'true';
|
return this.doc.getroot().find('./application').attrib['android:debuggable'] === 'true';
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidManifest.prototype.setDebuggable = function(value) {
|
AndroidManifest.prototype.setDebuggable = function (value) {
|
||||||
var application = this.doc.getroot().find('./application');
|
var application = this.doc.getroot().find('./application');
|
||||||
if (value) {
|
if (value) {
|
||||||
application.attrib['android:debuggable'] = 'true';
|
application.attrib['android:debuggable'] = 'true';
|
||||||
@@ -150,7 +149,7 @@ AndroidManifest.prototype.setDebuggable = function(value) {
|
|||||||
* @param {String} [destPath] File to write manifest to. If omitted,
|
* @param {String} [destPath] File to write manifest to. If omitted,
|
||||||
* manifest will be written to file it has been read from.
|
* manifest will be written to file it has been read from.
|
||||||
*/
|
*/
|
||||||
AndroidManifest.prototype.write = function(destPath) {
|
AndroidManifest.prototype.write = function (destPath) {
|
||||||
fs.writeFileSync(destPath || this.path, this.doc.write({indent: 4}), 'utf-8');
|
fs.writeFileSync(destPath || this.path, this.doc.write({indent: 4}), 'utf-8');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,16 +26,15 @@ var pluginHandlers = require('./pluginHandlers');
|
|||||||
|
|
||||||
var projectFileCache = {};
|
var projectFileCache = {};
|
||||||
|
|
||||||
function addToPropertyList(projectProperties, key, value) {
|
function addToPropertyList (projectProperties, key, value) {
|
||||||
var i = 1;
|
var i = 1;
|
||||||
while (projectProperties.get(key + '.' + i))
|
while (projectProperties.get(key + '.' + i)) { i++; }
|
||||||
i++;
|
|
||||||
|
|
||||||
projectProperties.set(key + '.' + i, value);
|
projectProperties.set(key + '.' + i, value);
|
||||||
projectProperties.dirty = true;
|
projectProperties.dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeFromPropertyList(projectProperties, key, value) {
|
function removeFromPropertyList (projectProperties, key, value) {
|
||||||
var i = 1;
|
var i = 1;
|
||||||
var currentValue;
|
var currentValue;
|
||||||
while ((currentValue = projectProperties.get(key + '.' + i))) {
|
while ((currentValue = projectProperties.get(key + '.' + i))) {
|
||||||
@@ -54,18 +53,18 @@ function removeFromPropertyList(projectProperties, key, value) {
|
|||||||
|
|
||||||
function getRelativeLibraryPath (parentDir, subDir) {
|
function getRelativeLibraryPath (parentDir, subDir) {
|
||||||
var libraryPath = path.relative(parentDir, subDir);
|
var libraryPath = path.relative(parentDir, subDir);
|
||||||
return (path.sep == '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath;
|
return (path.sep === '\\') ? libraryPath.replace(/\\/g, '/') : libraryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
function AndroidProject(projectDir) {
|
function AndroidProject (projectDir) {
|
||||||
this._propertiesEditors = {};
|
this._propertiesEditors = {};
|
||||||
this._subProjectDirs = {};
|
this._subProjectDirs = {};
|
||||||
this._dirty = false;
|
this._dirty = false;
|
||||||
this.projectDir = projectDir;
|
this.projectDir = projectDir;
|
||||||
this.platformWww = path.join(this.projectDir, 'platform_www');
|
this.platformWww = path.join(this.projectDir, 'platform_www');
|
||||||
this.www = path.join(this.projectDir, 'assets/www');
|
this.www = path.join(this.projectDir, 'assets/www');
|
||||||
if(AndroidStudio.isAndroidStudioProject(projectDir) === true) {
|
if (AndroidStudio.isAndroidStudioProject(projectDir) === true) {
|
||||||
this.www = path.join(this.projectDir, 'app/src/main/assets/www');
|
this.www = path.join(this.projectDir, 'app/src/main/assets/www');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,15 +91,15 @@ AndroidProject.purgeCache = function (projectDir) {
|
|||||||
*
|
*
|
||||||
* @return {String} The name of the package
|
* @return {String} The name of the package
|
||||||
*/
|
*/
|
||||||
AndroidProject.prototype.getPackageName = function() {
|
AndroidProject.prototype.getPackageName = function () {
|
||||||
var manifestPath = path.join(this.projectDir, 'AndroidManifest.xml');
|
var manifestPath = path.join(this.projectDir, 'AndroidManifest.xml');
|
||||||
if(AndroidStudio.isAndroidStudioProject(this.projectDir) === true) {
|
if (AndroidStudio.isAndroidStudioProject(this.projectDir) === true) {
|
||||||
manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml');
|
manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml');
|
||||||
}
|
}
|
||||||
return new AndroidManifest(manifestPath).getPackageId();
|
return new AndroidManifest(manifestPath).getPackageId();
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidProject.prototype.getCustomSubprojectRelativeDir = function(plugin_id, src) {
|
AndroidProject.prototype.getCustomSubprojectRelativeDir = function (plugin_id, src) {
|
||||||
// All custom subprojects are prefixed with the last portion of the package id.
|
// All custom subprojects are prefixed with the last portion of the package id.
|
||||||
// This is to avoid collisions when opening multiple projects in Eclipse that have subprojects with the same name.
|
// This is to avoid collisions when opening multiple projects in Eclipse that have subprojects with the same name.
|
||||||
var packageName = this.getPackageName();
|
var packageName = this.getPackageName();
|
||||||
@@ -110,7 +109,7 @@ AndroidProject.prototype.getCustomSubprojectRelativeDir = function(plugin_id, sr
|
|||||||
return subRelativeDir;
|
return subRelativeDir;
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidProject.prototype.addSubProject = function(parentDir, subDir) {
|
AndroidProject.prototype.addSubProject = function (parentDir, subDir) {
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
var subProjectFile = path.resolve(subDir, 'project.properties');
|
var subProjectFile = path.resolve(subDir, 'project.properties');
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
@@ -126,7 +125,7 @@ AndroidProject.prototype.addSubProject = function(parentDir, subDir) {
|
|||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidProject.prototype.removeSubProject = function(parentDir, subDir) {
|
AndroidProject.prototype.removeSubProject = function (parentDir, subDir) {
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
removeFromPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir));
|
removeFromPropertyList(parentProperties, 'android.library.reference', getRelativeLibraryPath(parentDir, subDir));
|
||||||
@@ -134,35 +133,35 @@ AndroidProject.prototype.removeSubProject = function(parentDir, subDir) {
|
|||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidProject.prototype.addGradleReference = function(parentDir, subDir) {
|
AndroidProject.prototype.addGradleReference = function (parentDir, subDir) {
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
addToPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
|
addToPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
|
||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidProject.prototype.removeGradleReference = function(parentDir, subDir) {
|
AndroidProject.prototype.removeGradleReference = function (parentDir, subDir) {
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
removeFromPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
|
removeFromPropertyList(parentProperties, 'cordova.gradle.include', getRelativeLibraryPath(parentDir, subDir));
|
||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidProject.prototype.addSystemLibrary = function(parentDir, value) {
|
AndroidProject.prototype.addSystemLibrary = function (parentDir, value) {
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
addToPropertyList(parentProperties, 'cordova.system.library', value);
|
addToPropertyList(parentProperties, 'cordova.system.library', value);
|
||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidProject.prototype.removeSystemLibrary = function(parentDir, value) {
|
AndroidProject.prototype.removeSystemLibrary = function (parentDir, value) {
|
||||||
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
var parentProjectFile = path.resolve(parentDir, 'project.properties');
|
||||||
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
var parentProperties = this._getPropertiesFile(parentProjectFile);
|
||||||
removeFromPropertyList(parentProperties, 'cordova.system.library', value);
|
removeFromPropertyList(parentProperties, 'cordova.system.library', value);
|
||||||
this._dirty = true;
|
this._dirty = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
AndroidProject.prototype.write = function() {
|
AndroidProject.prototype.write = function () {
|
||||||
if (!this._dirty) {
|
if (!this._dirty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -201,9 +200,9 @@ AndroidProject.prototype.getUninstaller = function (type) {
|
|||||||
* This checks if an Android project is clean or has old build artifacts
|
* This checks if an Android project is clean or has old build artifacts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
AndroidProject.prototype.isClean = function() {
|
AndroidProject.prototype.isClean = function () {
|
||||||
var build_path = path.join(this.projectDir, 'build');
|
var build_path = path.join(this.projectDir, 'build');
|
||||||
//If the build directory doesn't exist, it's clean
|
// If the build directory doesn't exist, it's clean
|
||||||
return !(fs.existsSync(build_path));
|
return !(fs.existsSync(build_path));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
* @param {String} root Root folder of the project
|
* @param {String} root Root folder of the project
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*jshint esnext: false */
|
/* jshint esnext: false */
|
||||||
|
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
|
|
||||||
module.exports.isAndroidStudioProject = function isAndroidStudioProject(root) {
|
module.exports.isAndroidStudioProject = function isAndroidStudioProject (root) {
|
||||||
var eclipseFiles = ['AndroidManifest.xml', 'libs', 'res', 'project.properties', 'platform_www'];
|
var eclipseFiles = ['AndroidManifest.xml', 'libs', 'res', 'project.properties', 'platform_www'];
|
||||||
var androidStudioFiles = ['app', 'gradle', 'app/src/main/res'];
|
var androidStudioFiles = ['app', 'gradle', 'app/src/main/res'];
|
||||||
|
|
||||||
@@ -18,21 +18,21 @@ module.exports.isAndroidStudioProject = function isAndroidStudioProject(root) {
|
|||||||
var isEclipse = false;
|
var isEclipse = false;
|
||||||
var isAS = true;
|
var isAS = true;
|
||||||
|
|
||||||
if(!fs.existsSync(root)) {
|
if (!fs.existsSync(root)) {
|
||||||
throw new CordovaError('AndroidStudio.js:inAndroidStudioProject root does not exist: ' + root);
|
throw new CordovaError('AndroidStudio.js:inAndroidStudioProject root does not exist: ' + root);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if any of the following exists, then we are not an ASProj
|
// if any of the following exists, then we are not an ASProj
|
||||||
eclipseFiles.forEach(function(file) {
|
eclipseFiles.forEach(function (file) {
|
||||||
if(fs.existsSync(path.join(root, file))) {
|
if (fs.existsSync(path.join(root, file))) {
|
||||||
isEclipse = true;
|
isEclipse = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// if it is NOT an eclipse project, check that all required files exist
|
// if it is NOT an eclipse project, check that all required files exist
|
||||||
if(!isEclipse) {
|
if (!isEclipse) {
|
||||||
androidStudioFiles.forEach(function(file){
|
androidStudioFiles.forEach(function (file) {
|
||||||
if(!fs.existsSync(path.join(root, file))) {
|
if (!fs.existsSync(path.join(root, file))) {
|
||||||
console.log('missing file :: ' + file);
|
console.log('missing file :: ' + file);
|
||||||
isAS = false;
|
isAS = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Q = require('q'),
|
var Q = require('q');
|
||||||
superspawn = require('cordova-common').superspawn;
|
var superspawn = require('cordova-common').superspawn;
|
||||||
|
|
||||||
var suffix_number_regex = /(\d+)$/;
|
var suffix_number_regex = /(\d+)$/;
|
||||||
// Used for sorting Android targets, example strings to sort:
|
// Used for sorting Android targets, example strings to sort:
|
||||||
@@ -29,7 +29,7 @@ var suffix_number_regex = /(\d+)$/;
|
|||||||
// The idea is to sort based on largest "suffix" number - meaning the bigger
|
// The idea is to sort based on largest "suffix" number - meaning the bigger
|
||||||
// the number at the end, the more recent the target, the closer to the
|
// the number at the end, the more recent the target, the closer to the
|
||||||
// start of the array.
|
// start of the array.
|
||||||
function sort_by_largest_numerical_suffix(a, b) {
|
function sort_by_largest_numerical_suffix (a, b) {
|
||||||
var suffix_a = a.match(suffix_number_regex);
|
var suffix_a = a.match(suffix_number_regex);
|
||||||
var suffix_b = b.match(suffix_number_regex);
|
var suffix_b = b.match(suffix_number_regex);
|
||||||
if (suffix_a && suffix_b) {
|
if (suffix_a && suffix_b) {
|
||||||
@@ -43,9 +43,8 @@ function sort_by_largest_numerical_suffix(a, b) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.print_newest_available_sdk_target = function() {
|
module.exports.print_newest_available_sdk_target = function () {
|
||||||
return module.exports.list_targets()
|
return module.exports.list_targets().then(function (targets) {
|
||||||
.then(function(targets) {
|
|
||||||
targets.sort(sort_by_largest_numerical_suffix);
|
targets.sort(sort_by_largest_numerical_suffix);
|
||||||
console.log(targets[0]);
|
console.log(targets[0]);
|
||||||
});
|
});
|
||||||
@@ -66,38 +65,34 @@ module.exports.version_string_to_api_level = {
|
|||||||
'7.1.1': 25
|
'7.1.1': 25
|
||||||
};
|
};
|
||||||
|
|
||||||
function parse_targets(output) {
|
function parse_targets (output) {
|
||||||
var target_out = output.split('\n');
|
var target_out = output.split('\n');
|
||||||
var targets = [];
|
var targets = [];
|
||||||
for (var i = target_out.length - 1; i >= 0; i--) {
|
for (var i = target_out.length - 1; i >= 0; i--) {
|
||||||
if(target_out[i].match(/id:/)) { // if "id:" is in the line...
|
if (target_out[i].match(/id:/)) { // if "id:" is in the line...
|
||||||
targets.push(target_out[i].match(/"(.+)"/)[1]); //.. match whatever is in quotes.
|
targets.push(target_out[i].match(/"(.+)"/)[1]); // .. match whatever is in quotes.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.list_targets_with_android = function() {
|
module.exports.list_targets_with_android = function () {
|
||||||
return superspawn.spawn('android', ['list', 'target'])
|
return superspawn.spawn('android', ['list', 'target']).then(parse_targets);
|
||||||
.then(parse_targets);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.list_targets_with_avdmanager = function() {
|
module.exports.list_targets_with_avdmanager = function () {
|
||||||
return superspawn.spawn('avdmanager', ['list', 'target'])
|
return superspawn.spawn('avdmanager', ['list', 'target']).then(parse_targets);
|
||||||
.then(parse_targets);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.list_targets = function() {
|
module.exports.list_targets = function () {
|
||||||
return module.exports.list_targets_with_avdmanager()
|
return module.exports.list_targets_with_avdmanager().catch(function (err) {
|
||||||
.catch(function(err) {
|
|
||||||
// If there's an error, like avdmanager could not be found, we can try
|
// If there's an error, like avdmanager could not be found, we can try
|
||||||
// as a last resort, to run `android`, in case this is a super old
|
// as a last resort, to run `android`, in case this is a super old
|
||||||
// SDK installation.
|
// SDK installation.
|
||||||
if (err && (err.code == 'ENOENT' || (err.stderr && err.stderr.match(/not recognized/)))) {
|
if (err && (err.code === 'ENOENT' || (err.stderr && err.stderr.match(/not recognized/)))) {
|
||||||
return module.exports.list_targets_with_android();
|
return module.exports.list_targets_with_android();
|
||||||
} else throw err;
|
} else throw err;
|
||||||
})
|
}).then(function (targets) {
|
||||||
.then(function(targets) {
|
|
||||||
if (targets.length === 0) {
|
if (targets.length === 0) {
|
||||||
return Q.reject(new Error('No android targets (SDKs) installed!'));
|
return Q.reject(new Error('No android targets (SDKs) installed!'));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Q = require('q'),
|
var Q = require('q');
|
||||||
path = require('path'),
|
var path = require('path');
|
||||||
fs = require('fs'),
|
var fs = require('fs');
|
||||||
nopt = require('nopt');
|
var nopt = require('nopt');
|
||||||
|
|
||||||
var Adb = require('./Adb');
|
var Adb = require('./Adb');
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ var events = require('cordova-common').events;
|
|||||||
var spawn = require('cordova-common').superspawn.spawn;
|
var spawn = require('cordova-common').superspawn.spawn;
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
|
|
||||||
function parseOpts(options, resolvedTarget, projectRoot) {
|
function parseOpts (options, resolvedTarget, projectRoot) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
options.argv = nopt({
|
options.argv = nopt({
|
||||||
gradle: Boolean,
|
gradle: Boolean,
|
||||||
@@ -55,16 +55,13 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
|||||||
extraArgs: []
|
extraArgs: []
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options.argv.ant || options.argv.gradle)
|
if (options.argv.ant || options.argv.gradle) { ret.buildMethod = options.argv.ant ? 'ant' : 'gradle'; }
|
||||||
ret.buildMethod = options.argv.ant ? 'ant' : 'gradle';
|
|
||||||
|
|
||||||
if (options.nobuild) ret.buildMethod = 'none';
|
if (options.nobuild) ret.buildMethod = 'none';
|
||||||
|
|
||||||
if (options.argv.versionCode)
|
if (options.argv.versionCode) { ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode); }
|
||||||
ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode);
|
|
||||||
|
|
||||||
if (options.argv.minSdkVersion)
|
if (options.argv.minSdkVersion) { ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion); }
|
||||||
ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion);
|
|
||||||
|
|
||||||
if (options.argv.gradleArg) {
|
if (options.argv.gradleArg) {
|
||||||
ret.extraArgs = ret.extraArgs.concat(options.argv.gradleArg);
|
ret.extraArgs = ret.extraArgs.concat(options.argv.gradleArg);
|
||||||
@@ -72,12 +69,10 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
|||||||
|
|
||||||
var packageArgs = {};
|
var packageArgs = {};
|
||||||
|
|
||||||
if (options.argv.keystore)
|
if (options.argv.keystore) { packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore)); }
|
||||||
packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore));
|
|
||||||
|
|
||||||
['alias','storePassword','password','keystoreType'].forEach(function (flagName) {
|
['alias', 'storePassword', 'password', 'keystoreType'].forEach(function (flagName) {
|
||||||
if (options.argv[flagName])
|
if (options.argv[flagName]) { packageArgs[flagName] = options.argv[flagName]; }
|
||||||
packageArgs[flagName] = options.argv[flagName];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var buildConfig = options.buildConfig;
|
var buildConfig = options.buildConfig;
|
||||||
@@ -88,20 +83,20 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
|||||||
if (!fs.existsSync(buildConfig)) {
|
if (!fs.existsSync(buildConfig)) {
|
||||||
throw new Error('Specified build config file does not exist: ' + buildConfig);
|
throw new Error('Specified build config file does not exist: ' + buildConfig);
|
||||||
}
|
}
|
||||||
events.emit('log', 'Reading build config file: '+ path.resolve(buildConfig));
|
events.emit('log', 'Reading build config file: ' + path.resolve(buildConfig));
|
||||||
var buildjson = fs.readFileSync(buildConfig, 'utf8');
|
var buildjson = fs.readFileSync(buildConfig, 'utf8');
|
||||||
var config = JSON.parse(buildjson.replace(/^\ufeff/, '')); // Remove BOM
|
var config = JSON.parse(buildjson.replace(/^\ufeff/, '')); // Remove BOM
|
||||||
if (config.android && config.android[ret.buildType]) {
|
if (config.android && config.android[ret.buildType]) {
|
||||||
var androidInfo = config.android[ret.buildType];
|
var androidInfo = config.android[ret.buildType];
|
||||||
if(androidInfo.keystore && !packageArgs.keystore) {
|
if (androidInfo.keystore && !packageArgs.keystore) {
|
||||||
if(androidInfo.keystore.substr(0,1) === '~') {
|
if (androidInfo.keystore.substr(0, 1) === '~') {
|
||||||
androidInfo.keystore = process.env.HOME + androidInfo.keystore.substr(1);
|
androidInfo.keystore = process.env.HOME + androidInfo.keystore.substr(1);
|
||||||
}
|
}
|
||||||
packageArgs.keystore = path.resolve(path.dirname(buildConfig), androidInfo.keystore);
|
packageArgs.keystore = path.resolve(path.dirname(buildConfig), androidInfo.keystore);
|
||||||
events.emit('log', 'Reading the keystore from: ' + packageArgs.keystore);
|
events.emit('log', 'Reading the keystore from: ' + packageArgs.keystore);
|
||||||
}
|
}
|
||||||
|
|
||||||
['alias', 'storePassword', 'password','keystoreType'].forEach(function (key){
|
['alias', 'storePassword', 'password', 'keystoreType'].forEach(function (key) {
|
||||||
packageArgs[key] = packageArgs[key] || androidInfo[key];
|
packageArgs[key] = packageArgs[key] || androidInfo[key];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -112,8 +107,8 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
|||||||
packageArgs.password, packageArgs.keystoreType);
|
packageArgs.password, packageArgs.keystoreType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ret.packageInfo) {
|
if (!ret.packageInfo) {
|
||||||
if(Object.keys(packageArgs).length > 0) {
|
if (Object.keys(packageArgs).length > 0) {
|
||||||
events.emit('warn', '\'keystore\' and \'alias\' need to be specified to generate a signed archive.');
|
events.emit('warn', '\'keystore\' and \'alias\' need to be specified to generate a signed archive.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,11 +120,10 @@ function parseOpts(options, resolvedTarget, projectRoot) {
|
|||||||
* Builds the project with the specifed options
|
* Builds the project with the specifed options
|
||||||
* Returns a promise.
|
* Returns a promise.
|
||||||
*/
|
*/
|
||||||
module.exports.runClean = function(options) {
|
module.exports.runClean = function (options) {
|
||||||
var opts = parseOpts(options, null, this.root);
|
var opts = parseOpts(options, null, this.root);
|
||||||
var builder = builders.getBuilder(opts.buildMethod);
|
var builder = builders.getBuilder(opts.buildMethod);
|
||||||
return builder.prepEnv(opts)
|
return builder.prepEnv(opts).then(function () {
|
||||||
.then(function() {
|
|
||||||
return builder.clean(opts);
|
return builder.clean(opts);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -146,17 +140,15 @@ module.exports.runClean = function(options) {
|
|||||||
* @return {Promise<Object>} Promise, resolved with built packages
|
* @return {Promise<Object>} Promise, resolved with built packages
|
||||||
* information.
|
* information.
|
||||||
*/
|
*/
|
||||||
module.exports.run = function(options, optResolvedTarget) {
|
module.exports.run = function (options, optResolvedTarget) {
|
||||||
var opts = parseOpts(options, optResolvedTarget, this.root);
|
var opts = parseOpts(options, optResolvedTarget, this.root);
|
||||||
var builder = builders.getBuilder(opts.buildMethod);
|
var builder = builders.getBuilder(opts.buildMethod);
|
||||||
return builder.prepEnv(opts)
|
return builder.prepEnv(opts).then(function () {
|
||||||
.then(function() {
|
|
||||||
if (opts.prepEnv) {
|
if (opts.prepEnv) {
|
||||||
events.emit('verbose', 'Build file successfully prepared.');
|
events.emit('verbose', 'Build file successfully prepared.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return builder.build(opts)
|
return builder.build(opts).then(function () {
|
||||||
.then(function() {
|
|
||||||
var apkPaths = builder.findOutputApks(opts.buildType, opts.arch);
|
var apkPaths = builder.findOutputApks(opts.buildType, opts.arch);
|
||||||
events.emit('log', 'Built the following apk(s): \n\t' + apkPaths.join('\n\t'));
|
events.emit('log', 'Built the following apk(s): \n\t' + apkPaths.join('\n\t'));
|
||||||
return {
|
return {
|
||||||
@@ -172,38 +164,31 @@ module.exports.run = function(options, optResolvedTarget) {
|
|||||||
* Detects the architecture of a device/emulator
|
* Detects the architecture of a device/emulator
|
||||||
* Returns "arm" or "x86".
|
* Returns "arm" or "x86".
|
||||||
*/
|
*/
|
||||||
module.exports.detectArchitecture = function(target) {
|
module.exports.detectArchitecture = function (target) {
|
||||||
function helper() {
|
function helper () {
|
||||||
return Adb.shell(target, 'cat /proc/cpuinfo')
|
return Adb.shell(target, 'cat /proc/cpuinfo').then(function (output) {
|
||||||
.then(function(output) {
|
|
||||||
return /intel/i.exec(output) ? 'x86' : 'arm';
|
return /intel/i.exec(output) ? 'x86' : 'arm';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// It sometimes happens (at least on OS X), that this command will hang forever.
|
// It sometimes happens (at least on OS X), that this command will hang forever.
|
||||||
// To fix it, either unplug & replug device, or restart adb server.
|
// To fix it, either unplug & replug device, or restart adb server.
|
||||||
return helper()
|
return helper().timeout(1000, new CordovaError('Device communication timed out. Try unplugging & replugging the device.')).then(null, function (err) {
|
||||||
.timeout(1000, new CordovaError('Device communication timed out. Try unplugging & replugging the device.'))
|
|
||||||
.then(null, function(err) {
|
|
||||||
if (/timed out/.exec('' + err)) {
|
if (/timed out/.exec('' + err)) {
|
||||||
// adb kill-server doesn't seem to do the trick.
|
// adb kill-server doesn't seem to do the trick.
|
||||||
// Could probably find a x-platform version of killall, but I'm not actually
|
// Could probably find a x-platform version of killall, but I'm not actually
|
||||||
// sure that this scenario even happens on non-OSX machines.
|
// sure that this scenario even happens on non-OSX machines.
|
||||||
events.emit('verbose', 'adb timed out while detecting device/emulator architecture. Killing adb and trying again.');
|
events.emit('verbose', 'adb timed out while detecting device/emulator architecture. Killing adb and trying again.');
|
||||||
return spawn('killall', ['adb'])
|
return spawn('killall', ['adb']).then(function () {
|
||||||
.then(function() {
|
return helper().then(null, function () {
|
||||||
return helper()
|
|
||||||
.then(null, function() {
|
|
||||||
// The double kill is sadly often necessary, at least on mac.
|
// The double kill is sadly often necessary, at least on mac.
|
||||||
events.emit('warn', 'adb timed out a second time while detecting device/emulator architecture. Killing adb and trying again.');
|
events.emit('warn', 'adb timed out a second time while detecting device/emulator architecture. Killing adb and trying again.');
|
||||||
return spawn('killall', ['adb'])
|
return spawn('killall', ['adb']).then(function () {
|
||||||
.then(function() {
|
return helper().then(null, function () {
|
||||||
return helper()
|
|
||||||
.then(null, function() {
|
|
||||||
return Q.reject(new CordovaError('adb timed out a third time while detecting device/emulator architecture. Try unplugging & replugging the device.'));
|
return Q.reject(new CordovaError('adb timed out a third time while detecting device/emulator architecture. Try unplugging & replugging the device.'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}, function() {
|
}, function () {
|
||||||
// For non-killall OS's.
|
// For non-killall OS's.
|
||||||
return Q.reject(err);
|
return Q.reject(err);
|
||||||
});
|
});
|
||||||
@@ -212,10 +197,10 @@ module.exports.detectArchitecture = function(target) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.findBestApkForArchitecture = function(buildResults, arch) {
|
module.exports.findBestApkForArchitecture = function (buildResults, arch) {
|
||||||
var paths = buildResults.apkPaths.filter(function(p) {
|
var paths = buildResults.apkPaths.filter(function (p) {
|
||||||
var apkName = path.basename(p);
|
var apkName = path.basename(p);
|
||||||
if (buildResults.buildType == 'debug') {
|
if (buildResults.buildType === 'debug') {
|
||||||
return /-debug/.exec(apkName);
|
return /-debug/.exec(apkName);
|
||||||
}
|
}
|
||||||
return !/-debug/.exec(apkName);
|
return !/-debug/.exec(apkName);
|
||||||
@@ -235,7 +220,7 @@ module.exports.findBestApkForArchitecture = function(buildResults, arch) {
|
|||||||
throw new Error('Could not find apk architecture: ' + arch + ' build-type: ' + buildResults.buildType);
|
throw new Error('Could not find apk architecture: ' + arch + ' build-type: ' + buildResults.buildType);
|
||||||
};
|
};
|
||||||
|
|
||||||
function PackageInfo(keystore, alias, storePassword, password, keystoreType) {
|
function PackageInfo (keystore, alias, storePassword, password, keystoreType) {
|
||||||
this.keystore = {
|
this.keystore = {
|
||||||
'name': 'key.store',
|
'name': 'key.store',
|
||||||
'value': keystore
|
'value': keystore
|
||||||
@@ -265,10 +250,10 @@ function PackageInfo(keystore, alias, storePassword, password, keystoreType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PackageInfo.prototype = {
|
PackageInfo.prototype = {
|
||||||
toProperties: function() {
|
toProperties: function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
var result = '';
|
var result = '';
|
||||||
Object.keys(self).forEach(function(key) {
|
Object.keys(self).forEach(function (key) {
|
||||||
result += self[key].name;
|
result += self[key].name;
|
||||||
result += '=';
|
result += '=';
|
||||||
result += self[key].value.replace(/\\/g, '\\\\');
|
result += self[key].value.replace(/\\/g, '\\\\');
|
||||||
@@ -278,7 +263,7 @@ PackageInfo.prototype = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.help = function() {
|
module.exports.help = function () {
|
||||||
console.log('Usage: ' + path.relative(process.cwd(), path.join('../build')) + ' [flags] [Signed APK flags]');
|
console.log('Usage: ' + path.relative(process.cwd(), path.join('../build')) + ' [flags] [Signed APK flags]');
|
||||||
console.log('Flags:');
|
console.log('Flags:');
|
||||||
console.log(' \'--debug\': will build project in debug mode (default)');
|
console.log(' \'--debug\': will build project in debug mode (default)');
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
specific language governing permissions and limitations
|
specific language governing permissions and limitations
|
||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
/* eslint no-unused-vars: 0 */
|
||||||
|
|
||||||
var Q = require('q');
|
var Q = require('q');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
@@ -42,30 +43,29 @@ function AntBuilder (projectRoot) {
|
|||||||
|
|
||||||
util.inherits(AntBuilder, GenericBuilder);
|
util.inherits(AntBuilder, GenericBuilder);
|
||||||
|
|
||||||
AntBuilder.prototype.getArgs = function(cmd, opts) {
|
AntBuilder.prototype.getArgs = function (cmd, opts) {
|
||||||
var args = [cmd, '-f', path.join(this.root, 'build.xml')];
|
var args = [cmd, '-f', path.join(this.root, 'build.xml')];
|
||||||
// custom_rules.xml is required for incremental builds.
|
// custom_rules.xml is required for incremental builds.
|
||||||
if (hasCustomRules(this.root)) {
|
if (hasCustomRules(this.root)) {
|
||||||
args.push('-Dout.dir=ant-build', '-Dgen.absolute.dir=ant-gen');
|
args.push('-Dout.dir=ant-build', '-Dgen.absolute.dir=ant-gen');
|
||||||
}
|
}
|
||||||
if(opts.packageInfo) {
|
if (opts.packageInfo) {
|
||||||
args.push('-propertyfile=' + path.join(this.root, opts.buildType + SIGNING_PROPERTIES));
|
args.push('-propertyfile=' + path.join(this.root, opts.buildType + SIGNING_PROPERTIES));
|
||||||
}
|
}
|
||||||
return args;
|
return args;
|
||||||
};
|
};
|
||||||
|
|
||||||
AntBuilder.prototype.prepEnv = function(opts) {
|
AntBuilder.prototype.prepEnv = function (opts) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return check_reqs.check_ant()
|
return check_reqs.check_ant().then(function () {
|
||||||
.then(function() {
|
|
||||||
// Copy in build.xml on each build so that:
|
// Copy in build.xml on each build so that:
|
||||||
// A) we don't require the Android SDK at project creation time, and
|
// A) we don't require the Android SDK at project creation time, and
|
||||||
// B) we always use the SDK's latest version of it.
|
// B) we always use the SDK's latest version of it.
|
||||||
/*jshint -W069 */
|
/* jshint -W069 */
|
||||||
var sdkDir = process.env['ANDROID_HOME'];
|
var sdkDir = process.env['ANDROID_HOME'];
|
||||||
/*jshint +W069 */
|
/* jshint +W069 */
|
||||||
var buildTemplate = fs.readFileSync(path.join(sdkDir, 'tools', 'lib', 'build.template'), 'utf8');
|
var buildTemplate = fs.readFileSync(path.join(sdkDir, 'tools', 'lib', 'build.template'), 'utf8');
|
||||||
function writeBuildXml(projectPath) {
|
function writeBuildXml (projectPath) {
|
||||||
var newData = buildTemplate.replace('PROJECT_NAME', self.extractRealProjectNameFromManifest());
|
var newData = buildTemplate.replace('PROJECT_NAME', self.extractRealProjectNameFromManifest());
|
||||||
fs.writeFileSync(path.join(projectPath, 'build.xml'), newData);
|
fs.writeFileSync(path.join(projectPath, 'build.xml'), newData);
|
||||||
if (!fs.existsSync(path.join(projectPath, 'local.properties'))) {
|
if (!fs.existsSync(path.join(projectPath, 'local.properties'))) {
|
||||||
@@ -86,7 +86,7 @@ AntBuilder.prototype.prepEnv = function(opts) {
|
|||||||
var propertiesFilePath = path.join(self.root, propertiesFile);
|
var propertiesFilePath = path.join(self.root, propertiesFile);
|
||||||
if (opts.packageInfo) {
|
if (opts.packageInfo) {
|
||||||
fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties());
|
fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties());
|
||||||
} else if(isAutoGenerated(propertiesFilePath)) {
|
} else if (isAutoGenerated(propertiesFilePath)) {
|
||||||
shell.rm('-f', propertiesFilePath);
|
shell.rm('-f', propertiesFilePath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -96,7 +96,7 @@ AntBuilder.prototype.prepEnv = function(opts) {
|
|||||||
* Builds the project with ant.
|
* Builds the project with ant.
|
||||||
* Returns a promise.
|
* Returns a promise.
|
||||||
*/
|
*/
|
||||||
AntBuilder.prototype.build = function(opts) {
|
AntBuilder.prototype.build = function (opts) {
|
||||||
// Without our custom_rules.xml, we need to clean before building.
|
// Without our custom_rules.xml, we need to clean before building.
|
||||||
var ret = Q();
|
var ret = Q();
|
||||||
if (!hasCustomRules(this.root)) {
|
if (!hasCustomRules(this.root)) {
|
||||||
@@ -104,11 +104,10 @@ AntBuilder.prototype.build = function(opts) {
|
|||||||
ret = this.clean(opts);
|
ret = this.clean(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts);
|
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
|
||||||
return check_reqs.check_ant()
|
return check_reqs.check_ant().then(function () {
|
||||||
.then(function() {
|
|
||||||
return spawn('ant', args, {stdio: 'pipe'});
|
return spawn('ant', args, {stdio: 'pipe'});
|
||||||
}).progress(function (stdio){
|
}).progress(function (stdio) {
|
||||||
if (stdio.stderr) {
|
if (stdio.stderr) {
|
||||||
process.stderr.write(stdio.stderr);
|
process.stderr.write(stdio.stderr);
|
||||||
} else {
|
} else {
|
||||||
@@ -116,7 +115,7 @@ AntBuilder.prototype.build = function(opts) {
|
|||||||
}
|
}
|
||||||
}).catch(function (error) {
|
}).catch(function (error) {
|
||||||
if (error.toString().indexOf('Unable to resolve project target') >= 0) {
|
if (error.toString().indexOf('Unable to resolve project target') >= 0) {
|
||||||
return check_reqs.check_android_target(error).then(function() {
|
return check_reqs.check_android_target(error).then(function () {
|
||||||
// If due to some odd reason - check_android_target succeeds
|
// If due to some odd reason - check_android_target succeeds
|
||||||
// we should still fail here.
|
// we should still fail here.
|
||||||
return Q.reject(error);
|
return Q.reject(error);
|
||||||
@@ -126,19 +125,17 @@ AntBuilder.prototype.build = function(opts) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
AntBuilder.prototype.clean = function(opts) {
|
AntBuilder.prototype.clean = function (opts) {
|
||||||
var args = this.getArgs('clean', opts);
|
var args = this.getArgs('clean', opts);
|
||||||
var self = this;
|
var self = this;
|
||||||
return check_reqs.check_ant()
|
return check_reqs.check_ant().then(function () {
|
||||||
.then(function() {
|
|
||||||
return spawn('ant', args, {stdio: 'inherit'});
|
return spawn('ant', args, {stdio: 'inherit'});
|
||||||
})
|
}).then(function () {
|
||||||
.then(function () {
|
|
||||||
shell.rm('-rf', path.join(self.root, 'out'));
|
shell.rm('-rf', path.join(self.root, 'out'));
|
||||||
|
|
||||||
['debug', 'release'].forEach(function(config) {
|
['debug', 'release'].forEach(function (config) {
|
||||||
var propertiesFilePath = path.join(self.root, config + SIGNING_PROPERTIES);
|
var propertiesFilePath = path.join(self.root, config + SIGNING_PROPERTIES);
|
||||||
if(isAutoGenerated(propertiesFilePath)){
|
if (isAutoGenerated(propertiesFilePath)) {
|
||||||
shell.rm('-f', propertiesFilePath);
|
shell.rm('-f', propertiesFilePath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -147,10 +144,10 @@ AntBuilder.prototype.clean = function(opts) {
|
|||||||
|
|
||||||
module.exports = AntBuilder;
|
module.exports = AntBuilder;
|
||||||
|
|
||||||
function hasCustomRules(projectRoot) {
|
function hasCustomRules (projectRoot) {
|
||||||
return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
|
return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAutoGenerated(file) {
|
function isAutoGenerated (file) {
|
||||||
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
specific language governing permissions and limitations
|
specific language governing permissions and limitations
|
||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
/* eslint no-self-assign: 0 */
|
||||||
|
/* eslint no-unused-vars: 0 */
|
||||||
|
|
||||||
var Q = require('q');
|
var Q = require('q');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
@@ -32,35 +34,33 @@ function GenericBuilder (projectDir) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasCustomRules(projectRoot) {
|
function hasCustomRules (projectRoot) {
|
||||||
return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
|
return fs.existsSync(path.join(projectRoot, 'custom_rules.xml'));
|
||||||
}
|
}
|
||||||
|
|
||||||
GenericBuilder.prototype.prepEnv = function() {
|
GenericBuilder.prototype.prepEnv = function () {
|
||||||
return Q();
|
return Q();
|
||||||
};
|
};
|
||||||
|
|
||||||
GenericBuilder.prototype.build = function() {
|
GenericBuilder.prototype.build = function () {
|
||||||
events.emit('log', 'Skipping build...');
|
events.emit('log', 'Skipping build...');
|
||||||
return Q(null);
|
return Q(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
GenericBuilder.prototype.clean = function() {
|
GenericBuilder.prototype.clean = function () {
|
||||||
return Q();
|
return Q();
|
||||||
};
|
};
|
||||||
|
|
||||||
GenericBuilder.prototype.findOutputApks = function(build_type, arch) {
|
GenericBuilder.prototype.findOutputApks = function (build_type, arch) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return Object.keys(this.binDirs)
|
return Object.keys(this.binDirs).reduce(function (result, builderName) {
|
||||||
.reduce(function (result, builderName) {
|
|
||||||
var binDir = self.binDirs[builderName];
|
var binDir = self.binDirs[builderName];
|
||||||
return result.concat(findOutputApksHelper(binDir, build_type, builderName === 'ant' ? null : arch));
|
return result.concat(findOutputApksHelper(binDir, build_type, builderName === 'ant' ? null : arch));
|
||||||
}, [])
|
}, []).sort(apkSorter);
|
||||||
.sort(apkSorter);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GenericBuilder.prototype.readProjectProperties = function () {
|
GenericBuilder.prototype.readProjectProperties = function () {
|
||||||
function findAllUniq(data, r) {
|
function findAllUniq (data, r) {
|
||||||
var s = {};
|
var s = {};
|
||||||
var m;
|
var m;
|
||||||
while ((m = r.exec(data))) {
|
while ((m = r.exec(data))) {
|
||||||
@@ -85,14 +85,22 @@ GenericBuilder.prototype.extractRealProjectNameFromManifest = function () {
|
|||||||
throw new CordovaError('Could not find package name in ' + manifestPath);
|
throw new CordovaError('Could not find package name in ' + manifestPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
var packageName=m[1];
|
var packageName = m[1];
|
||||||
var lastDotIndex = packageName.lastIndexOf('.');
|
var lastDotIndex = packageName.lastIndexOf('.');
|
||||||
return packageName.substring(lastDotIndex + 1);
|
return packageName.substring(lastDotIndex + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = GenericBuilder;
|
module.exports = GenericBuilder;
|
||||||
|
|
||||||
function apkSorter(fileA, fileB) {
|
function apkSorter (fileA, fileB) {
|
||||||
|
// De-prioritize arch specific builds
|
||||||
|
var archSpecificRE = /-x86|-arm/;
|
||||||
|
if (archSpecificRE.exec(fileA)) {
|
||||||
|
return 1;
|
||||||
|
} else if (archSpecificRE.exec(fileB)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// De-prioritize unsigned builds
|
// De-prioritize unsigned builds
|
||||||
var unsignedRE = /-unsigned/;
|
var unsignedRE = /-unsigned/;
|
||||||
if (unsignedRE.exec(fileA)) {
|
if (unsignedRE.exec(fileA)) {
|
||||||
@@ -101,16 +109,22 @@ function apkSorter(fileA, fileB) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var timeDiff = fs.statSync(fileA).mtime - fs.statSync(fileB).mtime;
|
var timeDiff = fs.statSync(fileB).mtime - fs.statSync(fileA).mtime;
|
||||||
return timeDiff === 0 ? fileA.length - fileB.length : timeDiff;
|
return timeDiff === 0 ? fileA.length - fileB.length : timeDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
function findOutputApksHelper(dir, build_type, arch) {
|
function findOutputApksHelper (dir, build_type, arch) {
|
||||||
var shellSilent = shell.config.silent;
|
var shellSilent = shell.config.silent;
|
||||||
shell.config.silent = true;
|
shell.config.silent = true;
|
||||||
|
|
||||||
var ret = shell.ls(path.join(dir, '*.apk'))
|
// list directory recursively
|
||||||
.filter(function(candidate) {
|
var ret = shell.ls('-R', dir).map(function (file) {
|
||||||
|
// ls does not include base directory
|
||||||
|
return path.join(dir, file);
|
||||||
|
}).filter(function (file) {
|
||||||
|
// find all APKs
|
||||||
|
return file.match(/\.apk?$/i);
|
||||||
|
}).filter(function (candidate) {
|
||||||
var apkName = path.basename(candidate);
|
var apkName = path.basename(candidate);
|
||||||
// Need to choose between release and debug .apk.
|
// Need to choose between release and debug .apk.
|
||||||
if (build_type === 'debug') {
|
if (build_type === 'debug') {
|
||||||
@@ -120,8 +134,7 @@ function findOutputApksHelper(dir, build_type, arch) {
|
|||||||
return /-release/.exec(apkName) && !/-unaligned/.exec(apkName);
|
return /-release/.exec(apkName) && !/-unaligned/.exec(apkName);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
})
|
}).sort(apkSorter);
|
||||||
.sort(apkSorter);
|
|
||||||
|
|
||||||
shellSilent = shellSilent;
|
shellSilent = shellSilent;
|
||||||
|
|
||||||
@@ -131,15 +144,15 @@ function findOutputApksHelper(dir, build_type, arch) {
|
|||||||
// Assume arch-specific build if newest apk has -x86 or -arm.
|
// Assume arch-specific build if newest apk has -x86 or -arm.
|
||||||
var archSpecific = !!/-x86|-arm/.exec(path.basename(ret[0]));
|
var archSpecific = !!/-x86|-arm/.exec(path.basename(ret[0]));
|
||||||
// And show only arch-specific ones (or non-arch-specific)
|
// And show only arch-specific ones (or non-arch-specific)
|
||||||
ret = ret.filter(function(p) {
|
ret = ret.filter(function (p) {
|
||||||
/*jshint -W018 */
|
/* jshint -W018 */
|
||||||
return !!/-x86|-arm/.exec(path.basename(p)) == archSpecific;
|
return !!/-x86|-arm/.exec(path.basename(p)) === archSpecific;
|
||||||
/*jshint +W018 */
|
/* jshint +W018 */
|
||||||
});
|
});
|
||||||
|
|
||||||
if (archSpecific && ret.length > 1 && arch) {
|
if (archSpecific && ret.length > 1 && arch) {
|
||||||
ret = ret.filter(function(p) {
|
ret = ret.filter(function (p) {
|
||||||
return path.basename(p).indexOf('-' + arch) != -1;
|
return path.basename(p).indexOf('-' + arch) !== -1;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ var fs = require('fs');
|
|||||||
var util = require('util');
|
var util = require('util');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var shell = require('shelljs');
|
var shell = require('shelljs');
|
||||||
var spawn = require('cordova-common').superspawn.spawn;
|
var superspawn = require('cordova-common').superspawn;
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
var check_reqs = require('../check_reqs');
|
var check_reqs = require('../check_reqs');
|
||||||
|
|
||||||
@@ -37,15 +37,15 @@ var TEMPLATE =
|
|||||||
function GradleBuilder (projectRoot) {
|
function GradleBuilder (projectRoot) {
|
||||||
GenericBuilder.call(this, projectRoot);
|
GenericBuilder.call(this, projectRoot);
|
||||||
|
|
||||||
this.binDirs = {gradle: this.binDirs.gradle};
|
this.binDirs = { gradle: this.binDirs.gradle };
|
||||||
}
|
}
|
||||||
|
|
||||||
util.inherits(GradleBuilder, GenericBuilder);
|
util.inherits(GradleBuilder, GenericBuilder);
|
||||||
|
|
||||||
GradleBuilder.prototype.getArgs = function(cmd, opts) {
|
GradleBuilder.prototype.getArgs = function (cmd, opts) {
|
||||||
if (cmd == 'release') {
|
if (cmd === 'release') {
|
||||||
cmd = 'cdvBuildRelease';
|
cmd = 'cdvBuildRelease';
|
||||||
} else if (cmd == 'debug') {
|
} else if (cmd === 'debug') {
|
||||||
cmd = 'cdvBuildDebug';
|
cmd = 'cdvBuildDebug';
|
||||||
}
|
}
|
||||||
var args = [cmd, '-b', path.join(this.root, 'build.gradle')];
|
var args = [cmd, '-b', path.join(this.root, 'build.gradle')];
|
||||||
@@ -69,46 +69,47 @@ GradleBuilder.prototype.getArgs = function(cmd, opts) {
|
|||||||
* This returns a promise
|
* This returns a promise
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GradleBuilder.prototype.runGradleWrapper = function(gradle_cmd) {
|
GradleBuilder.prototype.runGradleWrapper = function (gradle_cmd, gradle_file) {
|
||||||
var gradlePath = path.join(this.root, 'gradlew');
|
var gradlePath = path.join(this.root, 'gradlew');
|
||||||
var wrapperGradle = path.join(this.root, 'wrapper.gradle');
|
gradle_file = path.join(this.root, (gradle_file || 'wrapper.gradle'));
|
||||||
if(fs.existsSync(gradlePath)) {
|
if (fs.existsSync(gradlePath)) {
|
||||||
//Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
|
// Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
|
||||||
} else {
|
} else {
|
||||||
return spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', wrapperGradle], {stdio: 'inherit'});
|
return superspawn.spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', gradle_file], { stdio: 'pipe' })
|
||||||
|
.progress(function (stdio) {
|
||||||
|
suppressJavaOptionsInfo(stdio);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Makes the project buildable, minus the gradle wrapper.
|
// Makes the project buildable, minus the gradle wrapper.
|
||||||
GradleBuilder.prototype.prepBuildFiles = function() {
|
GradleBuilder.prototype.prepBuildFiles = function () {
|
||||||
// Update the version of build.gradle in each dependent library.
|
// Update the version of build.gradle in each dependent library.
|
||||||
var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle');
|
var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle');
|
||||||
var propertiesObj = this.readProjectProperties();
|
var propertiesObj = this.readProjectProperties();
|
||||||
var subProjects = propertiesObj.libs;
|
var subProjects = propertiesObj.libs;
|
||||||
var checkAndCopy = function(subProject, root) {
|
var checkAndCopy = function (subProject, root) {
|
||||||
var subProjectGradle = path.join(root, subProject, 'build.gradle');
|
var subProjectGradle = path.join(root, subProject, 'build.gradle');
|
||||||
// This is the future-proof way of checking if a file exists
|
// This is the future-proof way of checking if a file exists
|
||||||
// This must be synchronous to satisfy a Travis test
|
// This must be synchronous to satisfy a Travis test
|
||||||
try {
|
try {
|
||||||
fs.accessSync(subProjectGradle, fs.F_OK);
|
fs.accessSync(subProjectGradle, fs.F_OK);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
shell.cp('-f', pluginBuildGradle, subProjectGradle);
|
shell.cp('-f', pluginBuildGradle, subProjectGradle);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
for (var i = 0; i < subProjects.length; ++i) {
|
for (var i = 0; i < subProjects.length; ++i) {
|
||||||
if (subProjects[i] !== 'CordovaLib') {
|
if (subProjects[i] !== 'CordovaLib') {
|
||||||
checkAndCopy(subProjects[i], this.root);
|
checkAndCopy(subProjects[i], this.root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var name = this.extractRealProjectNameFromManifest();
|
var name = this.extractRealProjectNameFromManifest();
|
||||||
//Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
|
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
|
||||||
var settingsGradlePaths = subProjects.map(function(p){
|
var settingsGradlePaths = subProjects.map(function (p) {
|
||||||
var realDir=p.replace(/[/\\]/g, ':');
|
var realDir = p.replace(/[/\\]/g, ':');
|
||||||
var libName=realDir.replace(name+'-','');
|
var libName = realDir.replace(name + '-', '');
|
||||||
var str='include ":'+libName+'"\n';
|
var str = 'include ":' + libName + '"\n';
|
||||||
if(realDir.indexOf(name+'-')!==-1)
|
if (realDir.indexOf(name + '-') !== -1) { str += 'project(":' + libName + '").projectDir = new File("' + p + '")\n'; }
|
||||||
str+='project(":'+libName+'").projectDir = new File("'+p+'")\n';
|
|
||||||
return str;
|
return str;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -120,22 +121,19 @@ GradleBuilder.prototype.prepBuildFiles = function() {
|
|||||||
var buildGradle = fs.readFileSync(path.join(this.root, 'build.gradle'), 'utf8');
|
var buildGradle = fs.readFileSync(path.join(this.root, 'build.gradle'), 'utf8');
|
||||||
var depsList = '';
|
var depsList = '';
|
||||||
var root = this.root;
|
var root = this.root;
|
||||||
var insertExclude = function(p) {
|
var insertExclude = function (p) {
|
||||||
var gradlePath = path.join(root, p, 'build.gradle');
|
var gradlePath = path.join(root, p, 'build.gradle');
|
||||||
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
|
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
|
||||||
if(projectGradleFile.indexOf('CordovaLib') != -1) {
|
if (projectGradleFile.indexOf('CordovaLib') !== -1) {
|
||||||
depsList += '{\n exclude module:("CordovaLib")\n }\n';
|
depsList += '{\n exclude module:("CordovaLib")\n }\n';
|
||||||
}
|
} else {
|
||||||
else {
|
depsList += '\n';
|
||||||
depsList +='\n';
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
subProjects.forEach(function(p) {
|
subProjects.forEach(function (p) {
|
||||||
console.log('Subproject Path: ' + p);
|
console.log('Subproject Path: ' + p);
|
||||||
var libName=p.replace(/[/\\]/g, ':').replace(name+'-','');
|
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
|
||||||
depsList += ' debugCompile(project(path: "' + libName + '", configuration: "debug"))';
|
depsList += ' implementation(project(path: "' + libName + '"))';
|
||||||
insertExclude(p);
|
|
||||||
depsList += ' releaseCompile(project(path: "' + libName + '", configuration: "release"))';
|
|
||||||
insertExclude(p);
|
insertExclude(p);
|
||||||
});
|
});
|
||||||
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
|
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
|
||||||
@@ -143,7 +141,7 @@ GradleBuilder.prototype.prepBuildFiles = function() {
|
|||||||
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
|
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
|
||||||
[/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+']
|
[/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+']
|
||||||
];
|
];
|
||||||
propertiesObj.systemLibs.forEach(function(p) {
|
propertiesObj.systemLibs.forEach(function (p) {
|
||||||
var mavenRef;
|
var mavenRef;
|
||||||
// It's already in gradle form if it has two ':'s
|
// It's already in gradle form if it has two ':'s
|
||||||
if (/:.*:/.exec(p)) {
|
if (/:.*:/.exec(p)) {
|
||||||
@@ -164,21 +162,20 @@ GradleBuilder.prototype.prepBuildFiles = function() {
|
|||||||
});
|
});
|
||||||
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2');
|
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2');
|
||||||
var includeList = '';
|
var includeList = '';
|
||||||
propertiesObj.gradleIncludes.forEach(function(includePath) {
|
propertiesObj.gradleIncludes.forEach(function (includePath) {
|
||||||
includeList += 'apply from: "' + includePath + '"\n';
|
includeList += 'apply from: "' + includePath + '"\n';
|
||||||
});
|
});
|
||||||
buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2');
|
buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2');
|
||||||
fs.writeFileSync(path.join(this.root, 'build.gradle'), buildGradle);
|
fs.writeFileSync(path.join(this.root, 'build.gradle'), buildGradle);
|
||||||
};
|
};
|
||||||
|
|
||||||
GradleBuilder.prototype.prepEnv = function(opts) {
|
GradleBuilder.prototype.prepEnv = function (opts) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return check_reqs.check_gradle()
|
return check_reqs.check_gradle().then(function (gradlePath) {
|
||||||
.then(function(gradlePath) {
|
|
||||||
return self.runGradleWrapper(gradlePath);
|
return self.runGradleWrapper(gradlePath);
|
||||||
}).then(function() {
|
}).then(function () {
|
||||||
return self.prepBuildFiles();
|
return self.prepBuildFiles();
|
||||||
}).then(function() {
|
}).then(function () {
|
||||||
// We now copy the gradle out of the framework
|
// We now copy the gradle out of the framework
|
||||||
// This is a dirty patch to get the build working
|
// This is a dirty patch to get the build working
|
||||||
/*
|
/*
|
||||||
@@ -198,12 +195,12 @@ GradleBuilder.prototype.prepEnv = function(opts) {
|
|||||||
// If it's not set, do nothing, assuming that we're using a future version of gradle that we don't want to mess with.
|
// If it's not set, do nothing, assuming that we're using a future version of gradle that we don't want to mess with.
|
||||||
// For some reason, using ^ and $ don't work. This does the job, though.
|
// For some reason, using ^ and $ don't work. This does the job, though.
|
||||||
var distributionUrlRegex = /distributionUrl.*zip/;
|
var distributionUrlRegex = /distributionUrl.*zip/;
|
||||||
/*jshint -W069 */
|
/* jshint -W069 */
|
||||||
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-3.3-all.zip';
|
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.1-all.zip';
|
||||||
/*jshint +W069 */
|
/* jshint +W069 */
|
||||||
var gradleWrapperPropertiesPath = path.join(self.root, 'gradle', 'wrapper', 'gradle-wrapper.properties');
|
var gradleWrapperPropertiesPath = path.join(self.root, 'gradle', 'wrapper', 'gradle-wrapper.properties');
|
||||||
shell.chmod('u+w', gradleWrapperPropertiesPath);
|
shell.chmod('u+w', gradleWrapperPropertiesPath);
|
||||||
shell.sed('-i', distributionUrlRegex, 'distributionUrl='+distributionUrl, gradleWrapperPropertiesPath);
|
shell.sed('-i', distributionUrlRegex, 'distributionUrl=' + distributionUrl, gradleWrapperPropertiesPath);
|
||||||
|
|
||||||
var propertiesFile = opts.buildType + SIGNING_PROPERTIES;
|
var propertiesFile = opts.buildType + SIGNING_PROPERTIES;
|
||||||
var propertiesFilePath = path.join(self.root, propertiesFile);
|
var propertiesFilePath = path.join(self.root, propertiesFile);
|
||||||
@@ -219,53 +216,37 @@ GradleBuilder.prototype.prepEnv = function(opts) {
|
|||||||
* Builds the project with gradle.
|
* Builds the project with gradle.
|
||||||
* Returns a promise.
|
* Returns a promise.
|
||||||
*/
|
*/
|
||||||
GradleBuilder.prototype.build = function(opts) {
|
GradleBuilder.prototype.build = function (opts) {
|
||||||
var wrapper = path.join(this.root, 'gradlew');
|
var wrapper = path.join(this.root, 'gradlew');
|
||||||
var args = this.getArgs(opts.buildType == 'debug' ? 'debug' : 'release', opts);
|
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
|
||||||
|
|
||||||
return spawn(wrapper, args, {stdio: 'pipe'})
|
return superspawn.spawn(wrapper, args, { stdio: 'pipe' })
|
||||||
.progress(function (stdio){
|
.progress(function (stdio) {
|
||||||
if (stdio.stderr) {
|
suppressJavaOptionsInfo(stdio);
|
||||||
/*
|
}).catch(function (error) {
|
||||||
* Workaround for the issue with Java printing some unwanted information to
|
if (error.toString().indexOf('failed to find target with hash string') >= 0) {
|
||||||
* stderr instead of stdout.
|
return check_reqs.check_android_target(error).then(function () {
|
||||||
* This function suppresses 'Picked up _JAVA_OPTIONS' message from being
|
// If due to some odd reason - check_android_target succeeds
|
||||||
* printed to stderr. See https://issues.apache.org/jira/browse/CB-9971 for
|
// we should still fail here.
|
||||||
* explanation.
|
return Q.reject(error);
|
||||||
*/
|
});
|
||||||
var suppressThisLine = /^Picked up _JAVA_OPTIONS: /i.test(stdio.stderr.toString());
|
|
||||||
if (suppressThisLine) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
process.stderr.write(stdio.stderr);
|
return Q.reject(error);
|
||||||
} else {
|
});
|
||||||
process.stdout.write(stdio.stdout);
|
|
||||||
}
|
|
||||||
}).catch(function (error) {
|
|
||||||
if (error.toString().indexOf('failed to find target with hash string') >= 0) {
|
|
||||||
return check_reqs.check_android_target(error).then(function() {
|
|
||||||
// If due to some odd reason - check_android_target succeeds
|
|
||||||
// we should still fail here.
|
|
||||||
return Q.reject(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Q.reject(error);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
GradleBuilder.prototype.clean = function(opts) {
|
GradleBuilder.prototype.clean = function (opts) {
|
||||||
var builder = this;
|
var builder = this;
|
||||||
var wrapper = path.join(this.root, 'gradlew');
|
var wrapper = path.join(this.root, 'gradlew');
|
||||||
var args = builder.getArgs('clean', opts);
|
var args = builder.getArgs('clean', opts);
|
||||||
return Q().then(function() {
|
return Q().then(function () {
|
||||||
return spawn(wrapper, args, {stdio: 'inherit'});
|
return superspawn.spawn(wrapper, args, { stdio: 'inherit' });
|
||||||
})
|
}).then(function () {
|
||||||
.then(function () {
|
|
||||||
shell.rm('-rf', path.join(builder.root, 'out'));
|
shell.rm('-rf', path.join(builder.root, 'out'));
|
||||||
|
|
||||||
['debug', 'release'].forEach(function(config) {
|
['debug', 'release'].forEach(function (config) {
|
||||||
var propertiesFilePath = path.join(builder.root, config + SIGNING_PROPERTIES);
|
var propertiesFilePath = path.join(builder.root, config + SIGNING_PROPERTIES);
|
||||||
if(isAutoGenerated(propertiesFilePath)){
|
if (isAutoGenerated(propertiesFilePath)) {
|
||||||
shell.rm('-f', propertiesFilePath);
|
shell.rm('-f', propertiesFilePath);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -274,6 +255,25 @@ GradleBuilder.prototype.clean = function(opts) {
|
|||||||
|
|
||||||
module.exports = GradleBuilder;
|
module.exports = GradleBuilder;
|
||||||
|
|
||||||
function isAutoGenerated(file) {
|
function suppressJavaOptionsInfo (stdio) {
|
||||||
|
if (stdio.stderr) {
|
||||||
|
/*
|
||||||
|
* Workaround for the issue with Java printing some unwanted information to
|
||||||
|
* stderr instead of stdout.
|
||||||
|
* This function suppresses 'Picked up _JAVA_OPTIONS' message from being
|
||||||
|
* printed to stderr. See https://issues.apache.org/jira/browse/CB-9971 for
|
||||||
|
* explanation.
|
||||||
|
*/
|
||||||
|
var suppressThisLine = /^Picked up _JAVA_OPTIONS: /i.test(stdio.stderr.toString());
|
||||||
|
if (suppressThisLine) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
process.stderr.write(stdio.stderr);
|
||||||
|
} else {
|
||||||
|
process.stdout.write(stdio.stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAutoGenerated (file) {
|
||||||
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,7 @@ var knownBuilders = {
|
|||||||
* @return {Builder} A builder instance for specified build type.
|
* @return {Builder} A builder instance for specified build type.
|
||||||
*/
|
*/
|
||||||
module.exports.getBuilder = function (builderType, projectRoot) {
|
module.exports.getBuilder = function (builderType, projectRoot) {
|
||||||
if (!knownBuilders[builderType])
|
if (!knownBuilders[builderType]) { throw new CordovaError('Builder ' + builderType + ' is not supported.'); }
|
||||||
throw new CordovaError('Builder ' + builderType + ' is not supported.');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var Builder = require('./' + knownBuilders[builderType]);
|
var Builder = require('./' + knownBuilders[builderType]);
|
||||||
|
|||||||
@@ -21,19 +21,19 @@
|
|||||||
|
|
||||||
/* jshint sub:true */
|
/* jshint sub:true */
|
||||||
|
|
||||||
var shelljs = require('shelljs'),
|
var shelljs = require('shelljs');
|
||||||
child_process = require('child_process'),
|
var child_process = require('child_process');
|
||||||
Q = require('q'),
|
var Q = require('q');
|
||||||
path = require('path'),
|
var path = require('path');
|
||||||
fs = require('fs'),
|
var fs = require('fs');
|
||||||
os = require('os'),
|
var os = require('os');
|
||||||
REPO_ROOT = path.join(__dirname, '..', '..', '..', '..'),
|
var REPO_ROOT = path.join(__dirname, '..', '..', '..', '..');
|
||||||
PROJECT_ROOT = path.join(__dirname, '..', '..');
|
var PROJECT_ROOT = path.join(__dirname, '..', '..');
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
var superspawn = require('cordova-common').superspawn;
|
var superspawn = require('cordova-common').superspawn;
|
||||||
var android_sdk = require('./android_sdk');
|
var android_sdk = require('./android_sdk');
|
||||||
|
|
||||||
function forgivingWhichSync(cmd) {
|
function forgivingWhichSync (cmd) {
|
||||||
try {
|
try {
|
||||||
return fs.realpathSync(shelljs.which(cmd));
|
return fs.realpathSync(shelljs.which(cmd));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -41,9 +41,9 @@ function forgivingWhichSync(cmd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryCommand(cmd, errMsg, catchStderr) {
|
function tryCommand (cmd, errMsg, catchStderr) {
|
||||||
var d = Q.defer();
|
var d = Q.defer();
|
||||||
child_process.exec(cmd, function(err, stdout, stderr) {
|
child_process.exec(cmd, function (err, stdout, stderr) {
|
||||||
if (err) d.reject(new CordovaError(errMsg));
|
if (err) d.reject(new CordovaError(errMsg));
|
||||||
// Sometimes it is necessary to return an stderr instead of stdout in case of success, since
|
// Sometimes it is necessary to return an stderr instead of stdout in case of success, since
|
||||||
// some commands prints theirs output to stderr instead of stdout. 'javac' is the example
|
// some commands prints theirs output to stderr instead of stdout. 'javac' is the example
|
||||||
@@ -52,18 +52,18 @@ function tryCommand(cmd, errMsg, catchStderr) {
|
|||||||
return d.promise;
|
return d.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.isWindows = function() {
|
module.exports.isWindows = function () {
|
||||||
return (os.platform() == 'win32');
|
return (os.platform() === 'win32');
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.isDarwin = function() {
|
module.exports.isDarwin = function () {
|
||||||
return (os.platform() == 'darwin');
|
return (os.platform() === 'darwin');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get valid target from framework/project.properties if run from this repo
|
// Get valid target from framework/project.properties if run from this repo
|
||||||
// Otherwise get target from project.properties file within a generated cordova-android project
|
// Otherwise get target from project.properties file within a generated cordova-android project
|
||||||
module.exports.get_target = function() {
|
module.exports.get_target = function () {
|
||||||
function extractFromFile(filePath) {
|
function extractFromFile (filePath) {
|
||||||
var target = shelljs.grep(/\btarget=/, filePath);
|
var target = shelljs.grep(/\btarget=/, filePath);
|
||||||
if (!target) {
|
if (!target) {
|
||||||
throw new Error('Could not find android target within: ' + filePath);
|
throw new Error('Could not find android target within: ' + filePath);
|
||||||
@@ -83,77 +83,82 @@ module.exports.get_target = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise. Called only by build and clean commands.
|
// Returns a promise. Called only by build and clean commands.
|
||||||
module.exports.check_ant = function() {
|
module.exports.check_ant = function () {
|
||||||
return superspawn.spawn('ant', ['-version'])
|
return superspawn.spawn('ant', ['-version']).then(function (output) {
|
||||||
.then(function(output) {
|
|
||||||
// Parse Ant version from command output
|
// Parse Ant version from command output
|
||||||
return /version ((?:\d+\.)+(?:\d+))/i.exec(output)[1];
|
return /version ((?:\d+\.)+(?:\d+))/i.exec(output)[1];
|
||||||
}).catch(function(err) {
|
}).catch(function (err) {
|
||||||
throw new CordovaError('Failed to run `ant -version`. Make sure you have `ant` on your $PATH.');
|
if (err) {
|
||||||
|
throw new CordovaError('Failed to run `ant -version`. Make sure you have `ant` on your $PATH.');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.get_gradle_wrapper = function() {
|
module.exports.get_gradle_wrapper = function () {
|
||||||
var androidStudioPath;
|
var androidStudioPath;
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var foundStudio = false;
|
var foundStudio = false;
|
||||||
var program_dir;
|
var program_dir;
|
||||||
if (module.exports.isDarwin()) {
|
// OK, This hack only works on Windows, not on Mac OS or Linux. We will be deleting this eventually!
|
||||||
program_dir = fs.readdirSync('/Applications');
|
if (module.exports.isWindows()) {
|
||||||
while (i < program_dir.length && !foundStudio) {
|
|
||||||
if (program_dir[i].startsWith('Android Studio')) {
|
var result = child_process.spawnSync(path.join(__dirname, 'getASPath.bat'));
|
||||||
//TODO: Check for a specific Android Studio version, make sure it's not Canary
|
// console.log('result.stdout =' + result.stdout.toString());
|
||||||
androidStudioPath = path.join('/Applications', program_dir[i], 'Contents', 'gradle');
|
// console.log('result.stderr =' + result.stderr.toString());
|
||||||
foundStudio = true;
|
|
||||||
} else { ++i; }
|
if (result.stderr.toString().length > 0) {
|
||||||
}
|
var androidPath = path.join(process.env['ProgramFiles'], 'Android') + '/';
|
||||||
} else if (module.exports.isWindows()) {
|
if (fs.existsSync(androidPath)) {
|
||||||
var androidPath = path.join(process.env['ProgramFiles'], 'Android') + '/';
|
program_dir = fs.readdirSync(androidPath);
|
||||||
if (fs.existsSync(androidPath)) {
|
while (i < program_dir.length && !foundStudio) {
|
||||||
program_dir = fs.readdirSync(androidPath);
|
if (program_dir[i].startsWith('Android Studio')) {
|
||||||
while (i < program_dir.length && !foundStudio) {
|
foundStudio = true;
|
||||||
if (program_dir[i].startsWith('Android Studio')) {
|
androidStudioPath = path.join(process.env['ProgramFiles'], 'Android', program_dir[i], 'gradle');
|
||||||
foundStudio = true;
|
} else { ++i; }
|
||||||
androidStudioPath = path.join(process.env['ProgramFiles'], 'Android', program_dir[i], 'gradle');
|
}
|
||||||
} else { ++i; }
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// console.log('got android studio path from registry');
|
||||||
|
// remove the (os independent) new line char at the end of stdout
|
||||||
|
// add gradle to match the above.
|
||||||
|
androidStudioPath = path.join(result.stdout.toString().split('\r\n')[0], 'gradle');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
|
if (androidStudioPath !== null && fs.existsSync(androidStudioPath)) {
|
||||||
var dirs = fs.readdirSync(androidStudioPath);
|
var dirs = fs.readdirSync(androidStudioPath);
|
||||||
if(dirs[0].split('-')[0] == 'gradle') {
|
if (dirs[0].split('-')[0] === 'gradle') {
|
||||||
return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
|
return path.join(androidStudioPath, dirs[0], 'bin', 'gradle');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//OK, let's try to check for Gradle!
|
// OK, let's try to check for Gradle!
|
||||||
return forgivingWhichSync('gradle');
|
return forgivingWhichSync('gradle');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise. Called only by build and clean commands.
|
// Returns a promise. Called only by build and clean commands.
|
||||||
module.exports.check_gradle = function() {
|
module.exports.check_gradle = function () {
|
||||||
var sdkDir = process.env['ANDROID_HOME'];
|
var sdkDir = process.env['ANDROID_HOME'];
|
||||||
var d = Q.defer();
|
var d = Q.defer();
|
||||||
if (!sdkDir)
|
if (!sdkDir) {
|
||||||
return Q.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' +
|
return Q.reject(new CordovaError('Could not find gradle wrapper within Android SDK. Could not find Android SDK directory.\n' +
|
||||||
'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.'));
|
'Might need to install Android SDK or set up \'ANDROID_HOME\' env variable.'));
|
||||||
|
}
|
||||||
|
|
||||||
var gradlePath = module.exports.get_gradle_wrapper();
|
var gradlePath = module.exports.get_gradle_wrapper();
|
||||||
if (gradlePath.length !== 0)
|
if (gradlePath.length !== 0) { d.resolve(gradlePath); } else {
|
||||||
d.resolve(gradlePath);
|
|
||||||
else
|
|
||||||
d.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' +
|
d.reject(new CordovaError('Could not find an installed version of Gradle either in Android Studio,\n' +
|
||||||
'or on your system to install the gradle wrapper. Please include gradle \n' +
|
'or on your system to install the gradle wrapper. Please include gradle \n' +
|
||||||
'in your path, or install Android Studio'));
|
'in your path, or install Android Studio'));
|
||||||
|
}
|
||||||
return d.promise;
|
return d.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise.
|
// Returns a promise.
|
||||||
module.exports.check_java = function() {
|
module.exports.check_java = function () {
|
||||||
var javacPath = forgivingWhichSync('javac');
|
var javacPath = forgivingWhichSync('javac');
|
||||||
var hasJavaHome = !!process.env['JAVA_HOME'];
|
var hasJavaHome = !!process.env['JAVA_HOME'];
|
||||||
return Q().then(function() {
|
return Q().then(function () {
|
||||||
if (hasJavaHome) {
|
if (hasJavaHome) {
|
||||||
// Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
|
// Windows java installer doesn't add javac to PATH, nor set JAVA_HOME (ugh).
|
||||||
if (!javacPath) {
|
if (!javacPath) {
|
||||||
@@ -163,13 +168,14 @@ module.exports.check_java = function() {
|
|||||||
if (javacPath) {
|
if (javacPath) {
|
||||||
// OS X has a command for finding JAVA_HOME.
|
// OS X has a command for finding JAVA_HOME.
|
||||||
var find_java = '/usr/libexec/java_home';
|
var find_java = '/usr/libexec/java_home';
|
||||||
var default_java_error_msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting setting it manually.';
|
var default_java_error_msg = 'Failed to find \'JAVA_HOME\' environment variable. Try setting it manually.';
|
||||||
if (fs.existsSync(find_java)) {
|
if (fs.existsSync(find_java)) {
|
||||||
return superspawn.spawn(find_java)
|
return superspawn.spawn(find_java).then(function (stdout) {
|
||||||
.then(function(stdout) {
|
|
||||||
process.env['JAVA_HOME'] = stdout.trim();
|
process.env['JAVA_HOME'] = stdout.trim();
|
||||||
}).catch(function(err) {
|
}).catch(function (err) {
|
||||||
throw new CordovaError(default_java_error_msg);
|
if (err) {
|
||||||
|
throw new CordovaError(default_java_error_msg);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// See if we can derive it from javac's location.
|
// See if we can derive it from javac's location.
|
||||||
@@ -200,7 +206,7 @@ module.exports.check_java = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).then(function() {
|
}).then(function () {
|
||||||
var msg =
|
var msg =
|
||||||
'Failed to run "javac -version", make sure that you have a JDK installed.\n' +
|
'Failed to run "javac -version", make sure that you have a JDK installed.\n' +
|
||||||
'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n';
|
'You can get it from: http://www.oracle.com/technetwork/java/javase/downloads.\n';
|
||||||
@@ -209,9 +215,8 @@ module.exports.check_java = function() {
|
|||||||
}
|
}
|
||||||
// We use tryCommand with catchStderr = true, because
|
// We use tryCommand with catchStderr = true, because
|
||||||
// javac writes version info to stderr instead of stdout
|
// javac writes version info to stderr instead of stdout
|
||||||
return tryCommand('javac -version', msg, true)
|
return tryCommand('javac -version', msg, true).then(function (output) {
|
||||||
.then(function (output) {
|
// Let's check for at least Java 8, and keep it future proof so we can support Java 10
|
||||||
//Let's check for at least Java 8, and keep it future proof so we can support Java 10
|
|
||||||
var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output);
|
var match = /javac ((?:1\.)(?:[8-9]\.)(?:\d+))|((?:1\.)(?:[1-9]\d+\.)(?:\d+))/i.exec(output);
|
||||||
return match && match[1];
|
return match && match[1];
|
||||||
});
|
});
|
||||||
@@ -219,13 +224,13 @@ module.exports.check_java = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise.
|
// Returns a promise.
|
||||||
module.exports.check_android = function() {
|
module.exports.check_android = function () {
|
||||||
return Q().then(function() {
|
return Q().then(function () {
|
||||||
var androidCmdPath = forgivingWhichSync('android');
|
var androidCmdPath = forgivingWhichSync('android');
|
||||||
var adbInPath = forgivingWhichSync('adb');
|
var adbInPath = forgivingWhichSync('adb');
|
||||||
var avdmanagerInPath = forgivingWhichSync('avdmanager');
|
var avdmanagerInPath = forgivingWhichSync('avdmanager');
|
||||||
var hasAndroidHome = !!process.env['ANDROID_HOME'] && fs.existsSync(process.env['ANDROID_HOME']);
|
var hasAndroidHome = !!process.env['ANDROID_HOME'] && fs.existsSync(process.env['ANDROID_HOME']);
|
||||||
function maybeSetAndroidHome(value) {
|
function maybeSetAndroidHome (value) {
|
||||||
if (!hasAndroidHome && fs.existsSync(value)) {
|
if (!hasAndroidHome && fs.existsSync(value)) {
|
||||||
hasAndroidHome = true;
|
hasAndroidHome = true;
|
||||||
process.env['ANDROID_HOME'] = value;
|
process.env['ANDROID_HOME'] = value;
|
||||||
@@ -265,10 +270,10 @@ module.exports.check_android = function() {
|
|||||||
if (androidCmdPath) {
|
if (androidCmdPath) {
|
||||||
parentDir = path.dirname(androidCmdPath);
|
parentDir = path.dirname(androidCmdPath);
|
||||||
grandParentDir = path.dirname(parentDir);
|
grandParentDir = path.dirname(parentDir);
|
||||||
if (path.basename(parentDir) == 'tools' || fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
|
if (path.basename(parentDir) === 'tools' || fs.existsSync(path.join(grandParentDir, 'tools', 'android'))) {
|
||||||
maybeSetAndroidHome(grandParentDir);
|
maybeSetAndroidHome(grandParentDir);
|
||||||
} else {
|
} else {
|
||||||
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
|
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
|
||||||
'Detected \'android\' command at ' + parentDir + ' but no \'tools\' directory found near.\n' +
|
'Detected \'android\' command at ' + parentDir + ' but no \'tools\' directory found near.\n' +
|
||||||
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools directory.');
|
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools directory.');
|
||||||
}
|
}
|
||||||
@@ -276,10 +281,10 @@ module.exports.check_android = function() {
|
|||||||
if (adbInPath) {
|
if (adbInPath) {
|
||||||
parentDir = path.dirname(adbInPath);
|
parentDir = path.dirname(adbInPath);
|
||||||
grandParentDir = path.dirname(parentDir);
|
grandParentDir = path.dirname(parentDir);
|
||||||
if (path.basename(parentDir) == 'platform-tools') {
|
if (path.basename(parentDir) === 'platform-tools') {
|
||||||
maybeSetAndroidHome(grandParentDir);
|
maybeSetAndroidHome(grandParentDir);
|
||||||
} else {
|
} else {
|
||||||
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
|
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
|
||||||
'Detected \'adb\' command at ' + parentDir + ' but no \'platform-tools\' directory found near.\n' +
|
'Detected \'adb\' command at ' + parentDir + ' but no \'platform-tools\' directory found near.\n' +
|
||||||
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'platform-tools directory.');
|
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'platform-tools directory.');
|
||||||
}
|
}
|
||||||
@@ -287,17 +292,17 @@ module.exports.check_android = function() {
|
|||||||
if (avdmanagerInPath) {
|
if (avdmanagerInPath) {
|
||||||
parentDir = path.dirname(avdmanagerInPath);
|
parentDir = path.dirname(avdmanagerInPath);
|
||||||
grandParentDir = path.dirname(parentDir);
|
grandParentDir = path.dirname(parentDir);
|
||||||
if (path.basename(parentDir) == 'bin' && path.basename(grandParentDir) == 'tools') {
|
if (path.basename(parentDir) === 'bin' && path.basename(grandParentDir) === 'tools') {
|
||||||
maybeSetAndroidHome(path.dirname(grandParentDir));
|
maybeSetAndroidHome(path.dirname(grandParentDir));
|
||||||
} else {
|
} else {
|
||||||
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
|
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
|
||||||
'Detected \'avdmanager\' command at ' + parentDir + ' but no \'tools' + path.sep + 'bin\' directory found near.\n' +
|
'Detected \'avdmanager\' command at ' + parentDir + ' but no \'tools' + path.sep + 'bin\' directory found near.\n' +
|
||||||
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools' + path.sep + 'bin directory.');
|
'Try reinstall Android SDK or update your PATH to include valid path to SDK' + path.sep + 'tools' + path.sep + 'bin directory.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!process.env['ANDROID_HOME']) {
|
if (!process.env['ANDROID_HOME']) {
|
||||||
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting setting it manually.\n' +
|
throw new CordovaError('Failed to find \'ANDROID_HOME\' environment variable. Try setting it manually.\n' +
|
||||||
'Failed to find \'android\' command in your \'PATH\'. Try update your \'PATH\' to include path to valid SDK directory.');
|
'Failed to find \'android\' command in your \'PATH\'. Try update your \'PATH\' to include path to valid SDK directory.');
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(process.env['ANDROID_HOME'])) {
|
if (!fs.existsSync(process.env['ANDROID_HOME'])) {
|
||||||
@@ -330,20 +335,19 @@ module.exports.getAbsoluteAndroidCmd = function () {
|
|||||||
return cmd.replace(/(\s)/g, '\\$1');
|
return cmd.replace(/(\s)/g, '\\$1');
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.check_android_target = function(originalError) {
|
module.exports.check_android_target = function (originalError) {
|
||||||
// valid_target can look like:
|
// valid_target can look like:
|
||||||
// android-19
|
// android-19
|
||||||
// android-L
|
// android-L
|
||||||
// Google Inc.:Google APIs:20
|
// Google Inc.:Google APIs:20
|
||||||
// Google Inc.:Glass Development Kit Preview:20
|
// Google Inc.:Glass Development Kit Preview:20
|
||||||
var desired_api_level = module.exports.get_target();
|
var desired_api_level = module.exports.get_target();
|
||||||
return android_sdk.list_targets()
|
return android_sdk.list_targets().then(function (targets) {
|
||||||
.then(function(targets) {
|
|
||||||
if (targets.indexOf(desired_api_level) >= 0) {
|
if (targets.indexOf(desired_api_level) >= 0) {
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
var androidCmd = module.exports.getAbsoluteAndroidCmd();
|
var androidCmd = module.exports.getAbsoluteAndroidCmd();
|
||||||
var msg = 'Please install Android target / API level: "' + desired_api_level + '".\n\n' +
|
var msg = 'Please install Android target / API level: "' + desired_api_level + '".\n\n' +
|
||||||
'Hint: Open the SDK manager by running: ' + androidCmd + '\n' +
|
'Hint: Open the SDK manager by running: ' + androidCmd + '\n' +
|
||||||
'You will require:\n' +
|
'You will require:\n' +
|
||||||
'1. "SDK Platform" for API level ' + desired_api_level + '\n' +
|
'1. "SDK Platform" for API level ' + desired_api_level + '\n' +
|
||||||
@@ -357,23 +361,21 @@ module.exports.check_android_target = function(originalError) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise.
|
// Returns a promise.
|
||||||
module.exports.run = function() {
|
module.exports.run = function () {
|
||||||
return Q.all([this.check_java(), this.check_android()])
|
return Q.all([this.check_java(), this.check_android()]).then(function (values) {
|
||||||
.then(function(values) {
|
console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']);
|
||||||
console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']);
|
console.log('JAVA_HOME=' + process.env['JAVA_HOME']);
|
||||||
console.log('JAVA_HOME=' + process.env['JAVA_HOME']);
|
|
||||||
|
|
||||||
if (!values[0]) {
|
if (!values[0]) {
|
||||||
throw new CordovaError('Requirements check failed for JDK 1.8 or greater');
|
throw new CordovaError('Requirements check failed for JDK 1.8 or greater');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!values[1]) {
|
if (!values[1]) {
|
||||||
throw new CordovaError('Requirements check failed for Android SDK');
|
throw new CordovaError('Requirements check failed for Android SDK');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object thar represents one of requirements for current platform.
|
* Object thar represents one of requirements for current platform.
|
||||||
* @param {String} id The unique identifier for this requirements.
|
* @param {String} id The unique identifier for this requirements.
|
||||||
@@ -387,7 +389,7 @@ var Requirement = function (id, name, version, installed) {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.installed = installed || false;
|
this.installed = installed || false;
|
||||||
this.metadata = {
|
this.metadata = {
|
||||||
version: version,
|
version: version
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -397,7 +399,7 @@ var Requirement = function (id, name, version, installed) {
|
|||||||
*
|
*
|
||||||
* @return Promise<Requirement[]> Array of requirements. Due to implementation, promise is always fulfilled.
|
* @return Promise<Requirement[]> Array of requirements. Due to implementation, promise is always fulfilled.
|
||||||
*/
|
*/
|
||||||
module.exports.check_all = function() {
|
module.exports.check_all = function () {
|
||||||
|
|
||||||
var requirements = [
|
var requirements = [
|
||||||
new Requirement('java', 'Java JDK'),
|
new Requirement('java', 'Java JDK'),
|
||||||
@@ -417,15 +419,13 @@ module.exports.check_all = function() {
|
|||||||
return checkFns.reduce(function (promise, checkFn, idx) {
|
return checkFns.reduce(function (promise, checkFn, idx) {
|
||||||
// Update each requirement with results
|
// Update each requirement with results
|
||||||
var requirement = requirements[idx];
|
var requirement = requirements[idx];
|
||||||
return promise.then(checkFn)
|
return promise.then(checkFn).then(function (version) {
|
||||||
.then(function (version) {
|
|
||||||
requirement.installed = true;
|
requirement.installed = true;
|
||||||
requirement.metadata.version = version;
|
requirement.metadata.version = version;
|
||||||
}, function (err) {
|
}, function (err) {
|
||||||
requirement.metadata.reason = err instanceof Error ? err.message : err;
|
requirement.metadata.reason = err instanceof Error ? err.message : err;
|
||||||
});
|
});
|
||||||
}, Q())
|
}, Q()).then(function () {
|
||||||
.then(function () {
|
|
||||||
// When chain is completed, return requirements array to upstream API
|
// When chain is completed, return requirements array to upstream API
|
||||||
return requirements;
|
return requirements;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,8 +19,8 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var Q = require('q'),
|
var Q = require('q');
|
||||||
build = require('./build');
|
var build = require('./build');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var Adb = require('./Adb');
|
var Adb = require('./Adb');
|
||||||
var AndroidManifest = require('./AndroidManifest');
|
var AndroidManifest = require('./AndroidManifest');
|
||||||
@@ -32,18 +32,16 @@ var events = require('cordova-common').events;
|
|||||||
* Returns a promise for the list of the device ID's found
|
* Returns a promise for the list of the device ID's found
|
||||||
* @param lookHarder When true, try restarting adb if no devices are found.
|
* @param lookHarder When true, try restarting adb if no devices are found.
|
||||||
*/
|
*/
|
||||||
module.exports.list = function(lookHarder) {
|
module.exports.list = function (lookHarder) {
|
||||||
return Adb.devices()
|
return Adb.devices().then(function (list) {
|
||||||
.then(function(list) {
|
|
||||||
if (list.length === 0 && lookHarder) {
|
if (list.length === 0 && lookHarder) {
|
||||||
// adb kill-server doesn't seem to do the trick.
|
// adb kill-server doesn't seem to do the trick.
|
||||||
// Could probably find a x-platform version of killall, but I'm not actually
|
// Could probably find a x-platform version of killall, but I'm not actually
|
||||||
// sure that this scenario even happens on non-OSX machines.
|
// sure that this scenario even happens on non-OSX machines.
|
||||||
return spawn('killall', ['adb'])
|
return spawn('killall', ['adb']).then(function () {
|
||||||
.then(function() {
|
|
||||||
events.emit('verbose', 'Restarting adb to see if more devices are detected.');
|
events.emit('verbose', 'Restarting adb to see if more devices are detected.');
|
||||||
return Adb.devices();
|
return Adb.devices();
|
||||||
}, function() {
|
}, function () {
|
||||||
// For non-killall OS's.
|
// For non-killall OS's.
|
||||||
return list;
|
return list;
|
||||||
});
|
});
|
||||||
@@ -52,9 +50,8 @@ module.exports.list = function(lookHarder) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.resolveTarget = function(target) {
|
module.exports.resolveTarget = function (target) {
|
||||||
return this.list(true)
|
return this.list(true).then(function (device_list) {
|
||||||
.then(function(device_list) {
|
|
||||||
if (!device_list || !device_list.length) {
|
if (!device_list || !device_list.length) {
|
||||||
return Q.reject(new CordovaError('Failed to deploy to device, no devices found.'));
|
return Q.reject(new CordovaError('Failed to deploy to device, no devices found.'));
|
||||||
}
|
}
|
||||||
@@ -65,8 +62,7 @@ module.exports.resolveTarget = function(target) {
|
|||||||
return Q.reject('ERROR: Unable to find target \'' + target + '\'.');
|
return Q.reject('ERROR: Unable to find target \'' + target + '\'.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return build.detectArchitecture(target)
|
return build.detectArchitecture(target).then(function (arch) {
|
||||||
.then(function(arch) {
|
|
||||||
return { target: target, arch: arch, isEmulator: false };
|
return { target: target, arch: arch, isEmulator: false };
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -77,13 +73,13 @@ module.exports.resolveTarget = function(target) {
|
|||||||
* and launches it.
|
* and launches it.
|
||||||
* Returns a promise.
|
* Returns a promise.
|
||||||
*/
|
*/
|
||||||
module.exports.install = function(target, buildResults) {
|
module.exports.install = function (target, buildResults) {
|
||||||
return Q().then(function() {
|
return Q().then(function () {
|
||||||
if (target && typeof target == 'object') {
|
if (target && typeof target === 'object') {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
return module.exports.resolveTarget(target);
|
return module.exports.resolveTarget(target);
|
||||||
}).then(function(resolvedTarget) {
|
}).then(function (resolvedTarget) {
|
||||||
var apk_path = build.findBestApkForArchitecture(buildResults, resolvedTarget.arch);
|
var apk_path = build.findBestApkForArchitecture(buildResults, resolvedTarget.arch);
|
||||||
var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml'));
|
var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml'));
|
||||||
var pkgName = manifest.getPackageId();
|
var pkgName = manifest.getPackageId();
|
||||||
@@ -91,29 +87,25 @@ module.exports.install = function(target, buildResults) {
|
|||||||
events.emit('log', 'Using apk: ' + apk_path);
|
events.emit('log', 'Using apk: ' + apk_path);
|
||||||
events.emit('log', 'Package name: ' + pkgName);
|
events.emit('log', 'Package name: ' + pkgName);
|
||||||
|
|
||||||
return Adb.install(resolvedTarget.target, apk_path, {replace: true})
|
return Adb.install(resolvedTarget.target, apk_path, {replace: true}).catch(function (error) {
|
||||||
.catch(function (error) {
|
|
||||||
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
||||||
// is already installed on device was signed w/different certificate
|
// is already installed on device was signed w/different certificate
|
||||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString()))
|
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) { throw error; }
|
||||||
throw error;
|
|
||||||
|
|
||||||
events.emit('warn', 'Uninstalling app from device and reinstalling it again because the ' +
|
events.emit('warn', 'Uninstalling app from device and reinstalling it again because the ' +
|
||||||
'installed app already signed with different key');
|
'installed app already signed with different key');
|
||||||
|
|
||||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||||
// or the app doesn't installed at all, so no error catching needed.
|
// or the app doesn't installed at all, so no error catching needed.
|
||||||
return Adb.uninstall(resolvedTarget.target, pkgName)
|
return Adb.uninstall(resolvedTarget.target, pkgName).then(function () {
|
||||||
.then(function() {
|
|
||||||
return Adb.install(resolvedTarget.target, apk_path, {replace: true});
|
return Adb.install(resolvedTarget.target, apk_path, {replace: true});
|
||||||
});
|
});
|
||||||
})
|
}).then(function () {
|
||||||
.then(function() {
|
// unlock screen
|
||||||
//unlock screen
|
|
||||||
return Adb.shell(resolvedTarget.target, 'input keyevent 82');
|
return Adb.shell(resolvedTarget.target, 'input keyevent 82');
|
||||||
}).then(function() {
|
}).then(function () {
|
||||||
return Adb.start(resolvedTarget.target, launchName);
|
return Adb.start(resolvedTarget.target, launchName);
|
||||||
}).then(function() {
|
}).then(function () {
|
||||||
events.emit('log', 'LAUNCH SUCCESS');
|
events.emit('log', 'LAUNCH SUCCESS');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,8 +21,9 @@
|
|||||||
|
|
||||||
/* jshint sub:true */
|
/* jshint sub:true */
|
||||||
|
|
||||||
var retry = require('./retry');
|
var android_versions = require('android-versions');
|
||||||
var build = require('./build');
|
var retry = require('./retry');
|
||||||
|
var build = require('./build');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var Adb = require('./Adb');
|
var Adb = require('./Adb');
|
||||||
var AndroidManifest = require('./AndroidManifest');
|
var AndroidManifest = require('./AndroidManifest');
|
||||||
@@ -33,20 +34,20 @@ var shelljs = require('shelljs');
|
|||||||
var android_sdk = require('./android_sdk');
|
var android_sdk = require('./android_sdk');
|
||||||
var check_reqs = require('./check_reqs');
|
var check_reqs = require('./check_reqs');
|
||||||
|
|
||||||
var Q = require('q');
|
var Q = require('q');
|
||||||
var os = require('os');
|
var os = require('os');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var child_process = require('child_process');
|
var child_process = require('child_process');
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
var ONE_SECOND = 1000; // in milliseconds
|
var ONE_SECOND = 1000; // in milliseconds
|
||||||
var ONE_MINUTE = 60 * ONE_SECOND; // in milliseconds
|
var ONE_MINUTE = 60 * ONE_SECOND; // in milliseconds
|
||||||
var INSTALL_COMMAND_TIMEOUT = 5 * ONE_MINUTE; // in milliseconds
|
var INSTALL_COMMAND_TIMEOUT = 5 * ONE_MINUTE; // in milliseconds
|
||||||
var NUM_INSTALL_RETRIES = 3;
|
var NUM_INSTALL_RETRIES = 3;
|
||||||
var CHECK_BOOTED_INTERVAL = 3 * ONE_SECOND; // in milliseconds
|
var CHECK_BOOTED_INTERVAL = 3 * ONE_SECOND; // in milliseconds
|
||||||
var EXEC_KILL_SIGNAL = 'SIGKILL';
|
var EXEC_KILL_SIGNAL = 'SIGKILL';
|
||||||
|
|
||||||
function forgivingWhichSync(cmd) {
|
function forgivingWhichSync (cmd) {
|
||||||
try {
|
try {
|
||||||
return fs.realpathSync(shelljs.which(cmd));
|
return fs.realpathSync(shelljs.which(cmd));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -55,8 +56,7 @@ function forgivingWhichSync(cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports.list_images_using_avdmanager = function () {
|
module.exports.list_images_using_avdmanager = function () {
|
||||||
return superspawn.spawn('avdmanager', ['list', 'avd'])
|
return superspawn.spawn('avdmanager', ['list', 'avd']).then(function (output) {
|
||||||
.then(function(output) {
|
|
||||||
var response = output.split('\n');
|
var response = output.split('\n');
|
||||||
var emulator_list = [];
|
var emulator_list = [];
|
||||||
for (var i = 1; i < response.length; i++) {
|
for (var i = 1; i < response.length; i++) {
|
||||||
@@ -108,16 +108,15 @@ module.exports.list_images_using_avdmanager = function () {
|
|||||||
/* To just return a list of names use this
|
/* To just return a list of names use this
|
||||||
if (response[i].match(/Name:\s/)) {
|
if (response[i].match(/Name:\s/)) {
|
||||||
emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
|
emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
|
||||||
}*/
|
} */
|
||||||
|
|
||||||
}
|
}
|
||||||
return emulator_list;
|
return emulator_list;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.list_images_using_android = function() {
|
module.exports.list_images_using_android = function () {
|
||||||
return superspawn.spawn('android', ['list', 'avd'])
|
return superspawn.spawn('android', ['list', 'avd']).then(function (output) {
|
||||||
.then(function(output) {
|
|
||||||
var response = output.split('\n');
|
var response = output.split('\n');
|
||||||
var emulator_list = [];
|
var emulator_list = [];
|
||||||
for (var i = 1; i < response.length; i++) {
|
for (var i = 1; i < response.length; i++) {
|
||||||
@@ -152,7 +151,7 @@ module.exports.list_images_using_android = function() {
|
|||||||
/* To just return a list of names use this
|
/* To just return a list of names use this
|
||||||
if (response[i].match(/Name:\s/)) {
|
if (response[i].match(/Name:\s/)) {
|
||||||
emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
|
emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
|
||||||
}*/
|
} */
|
||||||
|
|
||||||
}
|
}
|
||||||
return emulator_list;
|
return emulator_list;
|
||||||
@@ -170,16 +169,30 @@ module.exports.list_images_using_android = function() {
|
|||||||
skin : <skin>
|
skin : <skin>
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
module.exports.list_images = function() {
|
module.exports.list_images = function () {
|
||||||
if (forgivingWhichSync('avdmanager')) {
|
return Q.fcall(function () {
|
||||||
return module.exports.list_images_using_avdmanager();
|
if (forgivingWhichSync('avdmanager')) {
|
||||||
} else if (forgivingWhichSync('android')) {
|
return module.exports.list_images_using_avdmanager();
|
||||||
return module.exports.list_images_using_android();
|
} else if (forgivingWhichSync('android')) {
|
||||||
} else {
|
return module.exports.list_images_using_android();
|
||||||
return Q().then(function() {
|
} else {
|
||||||
throw new CordovaError('Could not find either `android` or `avdmanager` on your $PATH! Are you sure the Android SDK is installed and available?');
|
return Q().then(function () {
|
||||||
|
throw new CordovaError('Could not find either `android` or `avdmanager` on your $PATH! Are you sure the Android SDK is installed and available?');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).then(function (avds) {
|
||||||
|
// In case we're missing the Android OS version string from the target description, add it.
|
||||||
|
return avds.map(function (avd) {
|
||||||
|
if (avd.target && avd.target.indexOf('Android API') > -1 && avd.target.indexOf('API level') < 0) {
|
||||||
|
var api_level = avd.target.match(/\d+/);
|
||||||
|
if (api_level) {
|
||||||
|
var level = android_versions.get(api_level);
|
||||||
|
avd.target = 'Android ' + level.semver + ' (API level ' + api_level + ')';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return avd;
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -187,20 +200,19 @@ module.exports.list_images = function() {
|
|||||||
* or undefined if no avds exist.
|
* or undefined if no avds exist.
|
||||||
* Returns a promise.
|
* Returns a promise.
|
||||||
*/
|
*/
|
||||||
module.exports.best_image = function() {
|
module.exports.best_image = function () {
|
||||||
return this.list_images()
|
return this.list_images().then(function (images) {
|
||||||
.then(function(images) {
|
|
||||||
// Just return undefined if there is no images
|
// Just return undefined if there is no images
|
||||||
if (images.length === 0) return;
|
if (images.length === 0) return;
|
||||||
|
|
||||||
var closest = 9999;
|
var closest = 9999;
|
||||||
var best = images[0];
|
var best = images[0];
|
||||||
var project_target = check_reqs.get_target().replace('android-', '');
|
var project_target = parseInt(check_reqs.get_target().replace('android-', ''));
|
||||||
for (var i in images) {
|
for (var i in images) {
|
||||||
var target = images[i].target;
|
var target = images[i].target;
|
||||||
if(target) {
|
if (target && target.indexOf('API level') > -1) {
|
||||||
var num = target.split('(API level ')[1].replace(')', '');
|
var num = parseInt(target.split('(API level ')[1].replace(')', ''));
|
||||||
if (num == project_target) {
|
if (num === project_target) {
|
||||||
return images[i];
|
return images[i];
|
||||||
} else if (project_target - num < closest && project_target > num) {
|
} else if (project_target - num < closest && project_target > num) {
|
||||||
closest = project_target - num;
|
closest = project_target - num;
|
||||||
@@ -213,19 +225,18 @@ module.exports.best_image = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise.
|
// Returns a promise.
|
||||||
module.exports.list_started = function() {
|
module.exports.list_started = function () {
|
||||||
return Adb.devices({emulators: true});
|
return Adb.devices({emulators: true});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns a promise.
|
// Returns a promise.
|
||||||
// TODO: we should remove this, there's a more robust method under android_sdk.js
|
// TODO: we should remove this, there's a more robust method under android_sdk.js
|
||||||
module.exports.list_targets = function() {
|
module.exports.list_targets = function () {
|
||||||
return superspawn.spawn('android', ['list', 'targets'], {cwd: os.tmpdir()})
|
return superspawn.spawn('android', ['list', 'targets'], {cwd: os.tmpdir()}).then(function (output) {
|
||||||
.then(function(output) {
|
|
||||||
var target_out = output.split('\n');
|
var target_out = output.split('\n');
|
||||||
var targets = [];
|
var targets = [];
|
||||||
for (var i = target_out.length; i >= 0; i--) {
|
for (var i = target_out.length; i >= 0; i--) {
|
||||||
if(target_out[i].match(/id:/)) {
|
if (target_out[i].match(/id:/)) {
|
||||||
targets.push(targets[i].split(' ')[1]);
|
targets.push(targets[i].split(' ')[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,9 +251,8 @@ module.exports.list_targets = function() {
|
|||||||
module.exports.get_available_port = function () {
|
module.exports.get_available_port = function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
return self.list_started()
|
return self.list_started().then(function (emulators) {
|
||||||
.then(function (emulators) {
|
for (var p = 5584; p >= 5554; p -= 2) {
|
||||||
for (var p = 5584; p >= 5554; p-=2) {
|
|
||||||
if (emulators.indexOf('emulator-' + p) === -1) {
|
if (emulators.indexOf('emulator-' + p) === -1) {
|
||||||
events.emit('verbose', 'Found available port: ' + p);
|
events.emit('verbose', 'Found available port: ' + p);
|
||||||
return p;
|
return p;
|
||||||
@@ -262,14 +272,13 @@ module.exports.get_available_port = function () {
|
|||||||
*
|
*
|
||||||
* Returns a promise.
|
* Returns a promise.
|
||||||
*/
|
*/
|
||||||
module.exports.start = function(emulator_ID, boot_timeout) {
|
module.exports.start = function (emulator_ID, boot_timeout) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
return Q().then(function() {
|
return Q().then(function () {
|
||||||
if (emulator_ID) return Q(emulator_ID);
|
if (emulator_ID) return Q(emulator_ID);
|
||||||
|
|
||||||
return self.best_image()
|
return self.best_image().then(function (best) {
|
||||||
.then(function(best) {
|
|
||||||
if (best && best.name) {
|
if (best && best.name) {
|
||||||
events.emit('warn', 'No emulator specified, defaulting to ' + best.name);
|
events.emit('warn', 'No emulator specified, defaulting to ' + best.name);
|
||||||
return best.name;
|
return best.name;
|
||||||
@@ -281,9 +290,8 @@ module.exports.start = function(emulator_ID, boot_timeout) {
|
|||||||
'2. Create an AVD by running: ' + androidCmd + ' avd\n' +
|
'2. Create an AVD by running: ' + androidCmd + ' avd\n' +
|
||||||
'HINT: For a faster emulator, use an Intel System Image and install the HAXM device driver\n'));
|
'HINT: For a faster emulator, use an Intel System Image and install the HAXM device driver\n'));
|
||||||
});
|
});
|
||||||
}).then(function(emulatorId) {
|
}).then(function (emulatorId) {
|
||||||
return self.get_available_port()
|
return self.get_available_port().then(function (port) {
|
||||||
.then(function (port) {
|
|
||||||
// Figure out the directory the emulator binary runs in, and set the cwd to that directory.
|
// Figure out the directory the emulator binary runs in, and set the cwd to that directory.
|
||||||
// Workaround for https://code.google.com/p/android/issues/detail?id=235461
|
// Workaround for https://code.google.com/p/android/issues/detail?id=235461
|
||||||
var emulator_dir = path.dirname(shelljs.which('emulator'));
|
var emulator_dir = path.dirname(shelljs.which('emulator'));
|
||||||
@@ -297,20 +305,17 @@ module.exports.start = function(emulator_ID, boot_timeout) {
|
|||||||
events.emit('log', 'Waiting for emulator to start...');
|
events.emit('log', 'Waiting for emulator to start...');
|
||||||
return self.wait_for_emulator(port);
|
return self.wait_for_emulator(port);
|
||||||
});
|
});
|
||||||
}).then(function(emulatorId) {
|
}).then(function (emulatorId) {
|
||||||
if (!emulatorId)
|
if (!emulatorId) { return Q.reject(new CordovaError('Failed to start emulator')); }
|
||||||
return Q.reject(new CordovaError('Failed to start emulator'));
|
|
||||||
|
|
||||||
//wait for emulator to boot up
|
// wait for emulator to boot up
|
||||||
process.stdout.write('Waiting for emulator to boot (this may take a while)...');
|
process.stdout.write('Waiting for emulator to boot (this may take a while)...');
|
||||||
return self.wait_for_boot(emulatorId, boot_timeout)
|
return self.wait_for_boot(emulatorId, boot_timeout).then(function (success) {
|
||||||
.then(function(success) {
|
|
||||||
if (success) {
|
if (success) {
|
||||||
events.emit('log','BOOT COMPLETE');
|
events.emit('log', 'BOOT COMPLETE');
|
||||||
//unlock screen
|
// unlock screen
|
||||||
return Adb.shell(emulatorId, 'input keyevent 82')
|
return Adb.shell(emulatorId, 'input keyevent 82').then(function () {
|
||||||
.then(function() {
|
// return the new emulator id for the started emulators
|
||||||
//return the new emulator id for the started emulators
|
|
||||||
return emulatorId;
|
return emulatorId;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -325,20 +330,19 @@ module.exports.start = function(emulator_ID, boot_timeout) {
|
|||||||
* Waits for an emulator to boot on a given port.
|
* Waits for an emulator to boot on a given port.
|
||||||
* Returns this emulator's ID in a promise.
|
* Returns this emulator's ID in a promise.
|
||||||
*/
|
*/
|
||||||
module.exports.wait_for_emulator = function(port) {
|
module.exports.wait_for_emulator = function (port) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return Q().then(function() {
|
return Q().then(function () {
|
||||||
var emulator_id = 'emulator-' + port;
|
var emulator_id = 'emulator-' + port;
|
||||||
return Adb.shell(emulator_id, 'getprop dev.bootcomplete')
|
return Adb.shell(emulator_id, 'getprop dev.bootcomplete').then(function (output) {
|
||||||
.then(function (output) {
|
|
||||||
if (output.indexOf('1') >= 0) {
|
if (output.indexOf('1') >= 0) {
|
||||||
return emulator_id;
|
return emulator_id;
|
||||||
}
|
}
|
||||||
return self.wait_for_emulator(port);
|
return self.wait_for_emulator(port);
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
if (error && error.message &&
|
if ((error && error.message &&
|
||||||
(error.message.indexOf('not found') > -1) ||
|
(error.message.indexOf('not found') > -1)) ||
|
||||||
error.message.indexOf('device offline') > -1) {
|
(error.message.indexOf('device offline') > -1)) {
|
||||||
// emulator not yet started, continue waiting
|
// emulator not yet started, continue waiting
|
||||||
return self.wait_for_emulator(port);
|
return self.wait_for_emulator(port);
|
||||||
} else {
|
} else {
|
||||||
@@ -346,7 +350,7 @@ module.exports.wait_for_emulator = function(port) {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -354,10 +358,9 @@ module.exports.wait_for_emulator = function(port) {
|
|||||||
* promise that resolves to a boolean indicating success. Not specifying a
|
* promise that resolves to a boolean indicating success. Not specifying a
|
||||||
* time_remaining or passing a negative value will cause it to wait forever
|
* time_remaining or passing a negative value will cause it to wait forever
|
||||||
*/
|
*/
|
||||||
module.exports.wait_for_boot = function(emulator_id, time_remaining) {
|
module.exports.wait_for_boot = function (emulator_id, time_remaining) {
|
||||||
var self = this;
|
var self = this;
|
||||||
return Adb.shell(emulator_id, 'ps')
|
return Adb.shell(emulator_id, 'ps').then(function (output) {
|
||||||
.then(function(output) {
|
|
||||||
if (output.match(/android\.process\.acore/)) {
|
if (output.match(/android\.process\.acore/)) {
|
||||||
return true;
|
return true;
|
||||||
} else if (time_remaining === 0) {
|
} else if (time_remaining === 0) {
|
||||||
@@ -366,7 +369,7 @@ module.exports.wait_for_boot = function(emulator_id, time_remaining) {
|
|||||||
process.stdout.write('.');
|
process.stdout.write('.');
|
||||||
|
|
||||||
// Check at regular intervals
|
// Check at regular intervals
|
||||||
return Q.delay(time_remaining < CHECK_BOOTED_INTERVAL ? time_remaining : CHECK_BOOTED_INTERVAL).then(function() {
|
return Q.delay(time_remaining < CHECK_BOOTED_INTERVAL ? time_remaining : CHECK_BOOTED_INTERVAL).then(function () {
|
||||||
var updated_time = time_remaining >= 0 ? Math.max(time_remaining - CHECK_BOOTED_INTERVAL, 0) : time_remaining;
|
var updated_time = time_remaining >= 0 ? Math.max(time_remaining - CHECK_BOOTED_INTERVAL, 0) : time_remaining;
|
||||||
return self.wait_for_boot(emulator_id, updated_time);
|
return self.wait_for_boot(emulator_id, updated_time);
|
||||||
});
|
});
|
||||||
@@ -379,11 +382,10 @@ module.exports.wait_for_boot = function(emulator_id, time_remaining) {
|
|||||||
* TODO : Enter the stdin input required to complete the creation of an avd.
|
* TODO : Enter the stdin input required to complete the creation of an avd.
|
||||||
* Returns a promise.
|
* Returns a promise.
|
||||||
*/
|
*/
|
||||||
module.exports.create_image = function(name, target) {
|
module.exports.create_image = function (name, target) {
|
||||||
console.log('Creating new avd named ' + name);
|
console.log('Creating new avd named ' + name);
|
||||||
if (target) {
|
if (target) {
|
||||||
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', target])
|
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', target]).then(null, function (error) {
|
||||||
.then(null, function(error) {
|
|
||||||
console.error('ERROR : Failed to create emulator image : ');
|
console.error('ERROR : Failed to create emulator image : ');
|
||||||
console.error(' Do you have the latest android targets including ' + target + '?');
|
console.error(' Do you have the latest android targets including ' + target + '?');
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@@ -391,22 +393,20 @@ module.exports.create_image = function(name, target) {
|
|||||||
} else {
|
} else {
|
||||||
console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
|
console.log('WARNING : Project target not found, creating avd with a different target but the project may fail to install.');
|
||||||
// TODO: there's a more robust method for finding targets in android_sdk.js
|
// TODO: there's a more robust method for finding targets in android_sdk.js
|
||||||
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', this.list_targets()[0]])
|
return superspawn.spawn('android', ['create', 'avd', '--name', name, '--target', this.list_targets()[0]]).then(function () {
|
||||||
.then(function() {
|
|
||||||
// TODO: This seems like another error case, even though it always happens.
|
// TODO: This seems like another error case, even though it always happens.
|
||||||
console.error('ERROR : Unable to create an avd emulator, no targets found.');
|
console.error('ERROR : Unable to create an avd emulator, no targets found.');
|
||||||
console.error('Ensure you have targets available by running the "android" command');
|
console.error('Ensure you have targets available by running the "android" command');
|
||||||
return Q.reject();
|
return Q.reject();
|
||||||
}, function(error) {
|
}, function (error) {
|
||||||
console.error('ERROR : Failed to create emulator image : ');
|
console.error('ERROR : Failed to create emulator image : ');
|
||||||
console.error(error);
|
console.error(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.resolveTarget = function(target) {
|
module.exports.resolveTarget = function (target) {
|
||||||
return this.list_started()
|
return this.list_started().then(function (emulator_list) {
|
||||||
.then(function(emulator_list) {
|
|
||||||
if (emulator_list.length < 1) {
|
if (emulator_list.length < 1) {
|
||||||
return Q.reject('No running Android emulators found, please start an emulator before deploying your project.');
|
return Q.reject('No running Android emulators found, please start an emulator before deploying your project.');
|
||||||
}
|
}
|
||||||
@@ -417,9 +417,8 @@ module.exports.resolveTarget = function(target) {
|
|||||||
return Q.reject('Unable to find target \'' + target + '\'. Failed to deploy to emulator.');
|
return Q.reject('Unable to find target \'' + target + '\'. Failed to deploy to emulator.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return build.detectArchitecture(target)
|
return build.detectArchitecture(target).then(function (arch) {
|
||||||
.then(function(arch) {
|
return {target: target, arch: arch, isEmulator: true};
|
||||||
return {target:target, arch:arch, isEmulator:true};
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -430,7 +429,7 @@ module.exports.resolveTarget = function(target) {
|
|||||||
* If no started emulators are found, error out.
|
* If no started emulators are found, error out.
|
||||||
* Returns a promise.
|
* Returns a promise.
|
||||||
*/
|
*/
|
||||||
module.exports.install = function(givenTarget, buildResults) {
|
module.exports.install = function (givenTarget, buildResults) {
|
||||||
|
|
||||||
var target;
|
var target;
|
||||||
var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml'));
|
var manifest = new AndroidManifest(path.join(__dirname, '../../AndroidManifest.xml'));
|
||||||
@@ -438,7 +437,7 @@ module.exports.install = function(givenTarget, buildResults) {
|
|||||||
|
|
||||||
// resolve the target emulator
|
// resolve the target emulator
|
||||||
return Q().then(function () {
|
return Q().then(function () {
|
||||||
if (givenTarget && typeof givenTarget == 'object') {
|
if (givenTarget && typeof givenTarget === 'object') {
|
||||||
return givenTarget;
|
return givenTarget;
|
||||||
} else {
|
} else {
|
||||||
return module.exports.resolveTarget(givenTarget);
|
return module.exports.resolveTarget(givenTarget);
|
||||||
@@ -452,13 +451,12 @@ module.exports.install = function(givenTarget, buildResults) {
|
|||||||
}).then(function () {
|
}).then(function () {
|
||||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||||
// or the app doesn't installed at all, so no error catching needed.
|
// or the app doesn't installed at all, so no error catching needed.
|
||||||
return Q.when()
|
return Q.when().then(function () {
|
||||||
.then(function() {
|
|
||||||
|
|
||||||
var apk_path = build.findBestApkForArchitecture(buildResults, target.arch);
|
var apk_path = build.findBestApkForArchitecture(buildResults, target.arch);
|
||||||
var execOptions = {
|
var execOptions = {
|
||||||
cwd: os.tmpdir(),
|
cwd: os.tmpdir(),
|
||||||
timeout: INSTALL_COMMAND_TIMEOUT, // in milliseconds
|
timeout: INSTALL_COMMAND_TIMEOUT, // in milliseconds
|
||||||
killSignal: EXEC_KILL_SIGNAL
|
killSignal: EXEC_KILL_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -469,12 +467,12 @@ module.exports.install = function(givenTarget, buildResults) {
|
|||||||
// A special function to call adb install in specific environment w/ specific options.
|
// A special function to call adb install in specific environment w/ specific options.
|
||||||
// Introduced as a part of fix for http://issues.apache.org/jira/browse/CB-9119
|
// Introduced as a part of fix for http://issues.apache.org/jira/browse/CB-9119
|
||||||
// to workaround sporadic emulator hangs
|
// to workaround sporadic emulator hangs
|
||||||
function adbInstallWithOptions(target, apk, opts) {
|
function adbInstallWithOptions (target, apk, opts) {
|
||||||
events.emit('verbose', 'Installing apk ' + apk + ' on ' + target + '...');
|
events.emit('verbose', 'Installing apk ' + apk + ' on ' + target + '...');
|
||||||
|
|
||||||
var command = 'adb -s ' + target + ' install -r "' + apk + '"';
|
var command = 'adb -s ' + target + ' install -r "' + apk + '"';
|
||||||
return Q.promise(function (resolve, reject) {
|
return Q.promise(function (resolve, reject) {
|
||||||
child_process.exec(command, opts, function(err, stdout, stderr) {
|
child_process.exec(command, opts, function (err, stdout, stderr) {
|
||||||
if (err) reject(new CordovaError('Error executing "' + command + '": ' + stderr));
|
if (err) reject(new CordovaError('Error executing "' + command + '": ' + stderr));
|
||||||
// adb does not return an error code even if installation fails. Instead it puts a specific
|
// adb does not return an error code even if installation fails. Instead it puts a specific
|
||||||
// message to stdout, so we have to use RegExp matching to detect installation failure.
|
// message to stdout, so we have to use RegExp matching to detect installation failure.
|
||||||
@@ -494,27 +492,23 @@ module.exports.install = function(givenTarget, buildResults) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function installPromise () {
|
function installPromise () {
|
||||||
return adbInstallWithOptions(target.target, apk_path, execOptions)
|
return adbInstallWithOptions(target.target, apk_path, execOptions).catch(function (error) {
|
||||||
.catch(function (error) {
|
|
||||||
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
||||||
// is already installed on device was signed w/different certificate
|
// is already installed on device was signed w/different certificate
|
||||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString()))
|
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) { throw error; }
|
||||||
throw error;
|
|
||||||
|
|
||||||
events.emit('warn', 'Uninstalling app from device and reinstalling it because the ' +
|
events.emit('warn', 'Uninstalling app from device and reinstalling it because the ' +
|
||||||
'currently installed app was signed with different key');
|
'currently installed app was signed with different key');
|
||||||
|
|
||||||
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
// This promise is always resolved, even if 'adb uninstall' fails to uninstall app
|
||||||
// or the app doesn't installed at all, so no error catching needed.
|
// or the app doesn't installed at all, so no error catching needed.
|
||||||
return Adb.uninstall(target.target, pkgName)
|
return Adb.uninstall(target.target, pkgName).then(function () {
|
||||||
.then(function() {
|
|
||||||
return adbInstallWithOptions(target.target, apk_path, execOptions);
|
return adbInstallWithOptions(target.target, apk_path, execOptions);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise)
|
return retry.retryPromise(NUM_INSTALL_RETRIES, installPromise).then(function (output) {
|
||||||
.then(function (output) {
|
|
||||||
events.emit('log', 'INSTALL SUCCESS');
|
events.emit('log', 'INSTALL SUCCESS');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
for /f "tokens=2*" %%a in ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Android Studio" /v Path') do set "ASPath=%%~b"
|
||||||
|
ECHO %ASPath%
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
SET script_path="%~dp0install-device"
|
SET script_path="%~dp0install-device"
|
||||||
IF EXIST %script_path% (
|
IF EXIST %script_path% (
|
||||||
node "%script_path%" %*
|
node %script_path% %*
|
||||||
) ELSE (
|
) ELSE (
|
||||||
ECHO.
|
ECHO.
|
||||||
ECHO ERROR: Could not find 'install-device' script in 'cordova\lib' folder, aborting...>&2
|
ECHO ERROR: Could not find 'install-device' script in 'cordova\lib' folder, aborting...>&2
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
SET script_path="%~dp0install-emulator"
|
SET script_path="%~dp0install-emulator"
|
||||||
IF EXIST %script_path% (
|
IF EXIST %script_path% (
|
||||||
node "%script_path%" %*
|
node %script_path% %*
|
||||||
) ELSE (
|
) ELSE (
|
||||||
ECHO.
|
ECHO.
|
||||||
ECHO ERROR: Could not find 'install-emulator' script in 'cordova\lib' folder, aborting...>&2
|
ECHO ERROR: Could not find 'install-emulator' script in 'cordova\lib' folder, aborting...>&2
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
SET script_path="%~dp0list-devices"
|
SET script_path="%~dp0list-devices"
|
||||||
IF EXIST %script_path% (
|
IF EXIST %script_path% (
|
||||||
node "%script_path%" %*
|
node %script_path% %*
|
||||||
) ELSE (
|
) ELSE (
|
||||||
ECHO.
|
ECHO.
|
||||||
ECHO ERROR: Could not find 'list-devices' script in 'cordova\lib' folder, aborting...>&2
|
ECHO ERROR: Could not find 'list-devices' script in 'cordova\lib' folder, aborting...>&2
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
SET script_path="%~dp0list-emulator-images"
|
SET script_path="%~dp0list-emulator-images"
|
||||||
IF EXIST %script_path% (
|
IF EXIST %script_path% (
|
||||||
node "%script_path%" %*
|
node %script_path% %*
|
||||||
) ELSE (
|
) ELSE (
|
||||||
ECHO.
|
ECHO.
|
||||||
ECHO ERROR: Could not find 'list-emulator-images' script in 'cordova\lib' folder, aborting...>&2
|
ECHO ERROR: Could not find 'list-emulator-images' script in 'cordova\lib' folder, aborting...>&2
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
SET script_path="%~dp0list-started-emulators"
|
SET script_path="%~dp0list-started-emulators"
|
||||||
IF EXIST %script_path% (
|
IF EXIST %script_path% (
|
||||||
node "%script_path%" %*
|
node %script_path% %*
|
||||||
) ELSE (
|
) ELSE (
|
||||||
ECHO.
|
ECHO.
|
||||||
ECHO ERROR: Could not find 'list-started-emulators' script in 'cordova\lib' folder, aborting...>&2
|
ECHO ERROR: Could not find 'list-started-emulators' script in 'cordova\lib' folder, aborting...>&2
|
||||||
|
|||||||
@@ -19,28 +19,28 @@
|
|||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var path = require('path'),
|
var path = require('path');
|
||||||
os = require('os'),
|
var os = require('os');
|
||||||
Q = require('q'),
|
var Q = require('q');
|
||||||
child_process = require('child_process'),
|
var child_process = require('child_process');
|
||||||
ROOT = path.join(__dirname, '..', '..');
|
var ROOT = path.join(__dirname, '..', '..');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Starts running logcat in the shell.
|
* Starts running logcat in the shell.
|
||||||
* Returns a promise.
|
* Returns a promise.
|
||||||
*/
|
*/
|
||||||
module.exports.run = function() {
|
module.exports.run = function () {
|
||||||
var d = Q.defer();
|
var d = Q.defer();
|
||||||
var adb = child_process.spawn('adb', ['logcat'], {cwd: os.tmpdir()});
|
var adb = child_process.spawn('adb', ['logcat'], {cwd: os.tmpdir()});
|
||||||
|
|
||||||
adb.stdout.on('data', function(data) {
|
adb.stdout.on('data', function (data) {
|
||||||
var lines = data ? data.toString().split('\n') : [];
|
var lines = data ? data.toString().split('\n') : [];
|
||||||
var out = lines.filter(function(x) { return x.indexOf('nativeGetEnabledTags') < 0; });
|
var out = lines.filter(function (x) { return x.indexOf('nativeGetEnabledTags') < 0; });
|
||||||
console.log(out.join('\n'));
|
console.log(out.join('\n'));
|
||||||
});
|
});
|
||||||
|
|
||||||
adb.stderr.on('data', console.error);
|
adb.stderr.on('data', console.error);
|
||||||
adb.on('close', function(code) {
|
adb.on('close', function (code) {
|
||||||
if (code > 0) {
|
if (code > 0) {
|
||||||
d.reject('Failed to run logcat command.');
|
d.reject('Failed to run logcat command.');
|
||||||
} else d.resolve();
|
} else d.resolve();
|
||||||
@@ -49,7 +49,7 @@ module.exports.run = function() {
|
|||||||
return d.promise;
|
return d.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.help = function() {
|
module.exports.help = function () {
|
||||||
console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'log')));
|
console.log('Usage: ' + path.relative(process.cwd(), path.join(ROOT, 'cordova', 'log')));
|
||||||
console.log('Gives the logcat output on the command line.');
|
console.log('Gives the logcat output on the command line.');
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
|
|||||||
@@ -20,8 +20,10 @@
|
|||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven {
|
||||||
|
url "https://maven.google.com"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch the Android Gradle plugin version requirement depending on the
|
// Switch the Android Gradle plugin version requirement depending on the
|
||||||
|
|||||||
@@ -26,15 +26,15 @@ var events = require('cordova-common').events;
|
|||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
|
|
||||||
var handlers = {
|
var handlers = {
|
||||||
'source-file':{
|
'source-file': {
|
||||||
install:function(obj, plugin, project, options) {
|
install: function (obj, plugin, project, options) {
|
||||||
if (!obj.src) throw new CordovaError(generateAttributeError('src', 'source-file', plugin.id));
|
if (!obj.src) throw new CordovaError(generateAttributeError('src', 'source-file', plugin.id));
|
||||||
if (!obj.targetDir) throw new CordovaError(generateAttributeError('target-dir', 'source-file', plugin.id));
|
if (!obj.targetDir) throw new CordovaError(generateAttributeError('target-dir', 'source-file', plugin.id));
|
||||||
|
|
||||||
var dest = path.join(obj.targetDir, path.basename(obj.src));
|
var dest = path.join(obj.targetDir, path.basename(obj.src));
|
||||||
|
|
||||||
if(options && options.android_studio === true) {
|
if (options && options.android_studio === true) {
|
||||||
dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src));
|
dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options && options.force) {
|
if (options && options.force) {
|
||||||
@@ -43,42 +43,42 @@ var handlers = {
|
|||||||
copyNewFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
|
copyNewFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
uninstall:function(obj, plugin, project, options) {
|
uninstall: function (obj, plugin, project, options) {
|
||||||
var dest = path.join(obj.targetDir, path.basename(obj.src));
|
var dest = path.join(obj.targetDir, path.basename(obj.src));
|
||||||
|
|
||||||
if(options && options.android_studio === true) {
|
if (options && options.android_studio === true) {
|
||||||
dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src));
|
dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src));
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteJava(project.projectDir, dest);
|
deleteJava(project.projectDir, dest);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'lib-file':{
|
'lib-file': {
|
||||||
install:function(obj, plugin, project, options) {
|
install: function (obj, plugin, project, options) {
|
||||||
var dest = path.join('libs', path.basename(obj.src));
|
var dest = path.join('libs', path.basename(obj.src));
|
||||||
if(options && options.android_studio === true) {
|
if (options && options.android_studio === true) {
|
||||||
dest = path.join('app/libs', path.basename(obj.src));
|
dest = path.join('app/libs', path.basename(obj.src));
|
||||||
}
|
}
|
||||||
copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
|
copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
|
||||||
},
|
},
|
||||||
uninstall:function(obj, plugin, project, options) {
|
uninstall: function (obj, plugin, project, options) {
|
||||||
var dest = path.join('libs', path.basename(obj.src));
|
var dest = path.join('libs', path.basename(obj.src));
|
||||||
if(options && options.android_studio === true) {
|
if (options && options.android_studio === true) {
|
||||||
dest = path.join('app/libs', path.basename(obj.src));
|
dest = path.join('app/libs', path.basename(obj.src));
|
||||||
}
|
}
|
||||||
removeFile(project.projectDir, dest);
|
removeFile(project.projectDir, dest);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'resource-file':{
|
'resource-file': {
|
||||||
install:function(obj, plugin, project, options) {
|
install: function (obj, plugin, project, options) {
|
||||||
copyFile(plugin.dir, obj.src, project.projectDir, path.normalize(obj.target), !!(options && options.link));
|
copyFile(plugin.dir, obj.src, project.projectDir, path.normalize(obj.target), !!(options && options.link));
|
||||||
},
|
},
|
||||||
uninstall:function(obj, plugin, project, options) {
|
uninstall: function (obj, plugin, project, options) {
|
||||||
removeFile(project.projectDir, path.normalize(obj.target));
|
removeFile(project.projectDir, path.normalize(obj.target));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'framework': {
|
'framework': {
|
||||||
install:function(obj, plugin, project, options) {
|
install: function (obj, plugin, project, options) {
|
||||||
var src = obj.src;
|
var src = obj.src;
|
||||||
if (!src) throw new CordovaError(generateAttributeError('src', 'framework', plugin.id));
|
if (!src) throw new CordovaError(generateAttributeError('src', 'framework', plugin.id));
|
||||||
|
|
||||||
@@ -95,15 +95,15 @@ var handlers = {
|
|||||||
subDir = src;
|
subDir = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.type == 'gradleReference') {
|
if (obj.type === 'gradleReference') {
|
||||||
project.addGradleReference(parentDir, subDir);
|
project.addGradleReference(parentDir, subDir);
|
||||||
} else if (obj.type == 'sys') {
|
} else if (obj.type === 'sys') {
|
||||||
project.addSystemLibrary(parentDir, subDir);
|
project.addSystemLibrary(parentDir, subDir);
|
||||||
} else {
|
} else {
|
||||||
project.addSubProject(parentDir, subDir);
|
project.addSubProject(parentDir, subDir);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
uninstall:function(obj, plugin, project, options) {
|
uninstall: function (obj, plugin, project, options) {
|
||||||
var src = obj.src;
|
var src = obj.src;
|
||||||
if (!src) throw new CordovaError(generateAttributeError('src', 'framework', plugin.id));
|
if (!src) throw new CordovaError(generateAttributeError('src', 'framework', plugin.id));
|
||||||
|
|
||||||
@@ -125,17 +125,17 @@ var handlers = {
|
|||||||
subDir = src;
|
subDir = src;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.type == 'gradleReference') {
|
if (obj.type === 'gradleReference') {
|
||||||
project.removeGradleReference(parentDir, subDir);
|
project.removeGradleReference(parentDir, subDir);
|
||||||
} else if (obj.type == 'sys') {
|
} else if (obj.type === 'sys') {
|
||||||
project.removeSystemLibrary(parentDir, subDir);
|
project.removeSystemLibrary(parentDir, subDir);
|
||||||
} else {
|
} else {
|
||||||
project.removeSubProject(parentDir, subDir);
|
project.removeSubProject(parentDir, subDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
asset:{
|
asset: {
|
||||||
install:function(obj, plugin, project, options) {
|
install: function (obj, plugin, project, options) {
|
||||||
if (!obj.src) {
|
if (!obj.src) {
|
||||||
throw new CordovaError(generateAttributeError('src', 'asset', plugin.id));
|
throw new CordovaError(generateAttributeError('src', 'asset', plugin.id));
|
||||||
}
|
}
|
||||||
@@ -149,7 +149,7 @@ var handlers = {
|
|||||||
copyFile(plugin.dir, obj.src, project.platformWww, obj.target);
|
copyFile(plugin.dir, obj.src, project.platformWww, obj.target);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
uninstall:function(obj, plugin, project, options) {
|
uninstall: function (obj, plugin, project, options) {
|
||||||
var target = obj.target || obj.src;
|
var target = obj.target || obj.src;
|
||||||
|
|
||||||
if (!target) throw new CordovaError(generateAttributeError('target', 'asset', plugin.id));
|
if (!target) throw new CordovaError(generateAttributeError('target', 'asset', plugin.id));
|
||||||
@@ -167,7 +167,7 @@ var handlers = {
|
|||||||
install: function (obj, plugin, project, options) {
|
install: function (obj, plugin, project, options) {
|
||||||
// Copy the plugin's files into the www directory.
|
// Copy the plugin's files into the www directory.
|
||||||
var moduleSource = path.resolve(plugin.dir, obj.src);
|
var moduleSource = path.resolve(plugin.dir, obj.src);
|
||||||
var moduleName = plugin.id + '.' + (obj.name || path.basename(obj.src, path.extname (obj.src)));
|
var moduleName = plugin.id + '.' + (obj.name || path.basename(obj.src, path.extname(obj.src)));
|
||||||
|
|
||||||
// Read in the file, prepend the cordova.define, and write it back out.
|
// Read in the file, prepend the cordova.define, and write it back out.
|
||||||
var scriptContent = fs.readFileSync(moduleSource, 'utf-8').replace(/^\ufeff/, ''); // Window BOM
|
var scriptContent = fs.readFileSync(moduleSource, 'utf-8').replace(/^\ufeff/, ''); // Window BOM
|
||||||
@@ -206,7 +206,7 @@ module.exports.getInstaller = function (type) {
|
|||||||
events.emit('verbose', '<' + type + '> is not supported for android plugins');
|
events.emit('verbose', '<' + type + '> is not supported for android plugins');
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.getUninstaller = function(type) {
|
module.exports.getUninstaller = function (type) {
|
||||||
if (handlers[type] && handlers[type].uninstall) {
|
if (handlers[type] && handlers[type].uninstall) {
|
||||||
return handlers[type].uninstall;
|
return handlers[type].uninstall;
|
||||||
}
|
}
|
||||||
@@ -221,21 +221,19 @@ function copyFile (plugin_dir, src, project_dir, dest, link) {
|
|||||||
// check that src path is inside plugin directory
|
// check that src path is inside plugin directory
|
||||||
var real_path = fs.realpathSync(src);
|
var real_path = fs.realpathSync(src);
|
||||||
var real_plugin_path = fs.realpathSync(plugin_dir);
|
var real_plugin_path = fs.realpathSync(plugin_dir);
|
||||||
if (real_path.indexOf(real_plugin_path) !== 0)
|
if (real_path.indexOf(real_plugin_path) !== 0) { throw new CordovaError('File "' + src + '" is located outside the plugin directory "' + plugin_dir + '"'); }
|
||||||
throw new CordovaError('File "' + src + '" is located outside the plugin directory "' + plugin_dir + '"');
|
|
||||||
|
|
||||||
dest = path.resolve(project_dir, dest);
|
dest = path.resolve(project_dir, dest);
|
||||||
|
|
||||||
// check that dest path is located in project directory
|
// check that dest path is located in project directory
|
||||||
if (dest.indexOf(project_dir) !== 0)
|
if (dest.indexOf(project_dir) !== 0) { throw new CordovaError('Destination "' + dest + '" for source file "' + src + '" is located outside the project'); }
|
||||||
throw new CordovaError('Destination "' + dest + '" for source file "' + src + '" is located outside the project');
|
|
||||||
|
|
||||||
shell.mkdir('-p', path.dirname(dest));
|
shell.mkdir('-p', path.dirname(dest));
|
||||||
if (link) {
|
if (link) {
|
||||||
symlinkFileOrDirTree(src, dest);
|
symlinkFileOrDirTree(src, dest);
|
||||||
} else if (fs.statSync(src).isDirectory()) {
|
} else if (fs.statSync(src).isDirectory()) {
|
||||||
// XXX shelljs decides to create a directory when -R|-r is used which sucks. http://goo.gl/nbsjq
|
// XXX shelljs decides to create a directory when -R|-r is used which sucks. http://goo.gl/nbsjq
|
||||||
shell.cp('-Rf', src+'/*', dest);
|
shell.cp('-Rf', src + '/*', dest);
|
||||||
} else {
|
} else {
|
||||||
shell.cp('-f', src, dest);
|
shell.cp('-f', src, dest);
|
||||||
}
|
}
|
||||||
@@ -244,24 +242,22 @@ function copyFile (plugin_dir, src, project_dir, dest, link) {
|
|||||||
// Same as copy file but throws error if target exists
|
// Same as copy file but throws error if target exists
|
||||||
function copyNewFile (plugin_dir, src, project_dir, dest, link) {
|
function copyNewFile (plugin_dir, src, project_dir, dest, link) {
|
||||||
var target_path = path.resolve(project_dir, dest);
|
var target_path = path.resolve(project_dir, dest);
|
||||||
if (fs.existsSync(target_path))
|
if (fs.existsSync(target_path)) { throw new CordovaError('"' + target_path + '" already exists!'); }
|
||||||
throw new CordovaError('"' + target_path + '" already exists!');
|
|
||||||
|
|
||||||
copyFile(plugin_dir, src, project_dir, dest, !!link);
|
copyFile(plugin_dir, src, project_dir, dest, !!link);
|
||||||
}
|
}
|
||||||
|
|
||||||
function symlinkFileOrDirTree(src, dest) {
|
function symlinkFileOrDirTree (src, dest) {
|
||||||
if (fs.existsSync(dest)) {
|
if (fs.existsSync(dest)) {
|
||||||
shell.rm('-Rf', dest);
|
shell.rm('-Rf', dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs.statSync(src).isDirectory()) {
|
if (fs.statSync(src).isDirectory()) {
|
||||||
shell.mkdir('-p', dest);
|
shell.mkdir('-p', dest);
|
||||||
fs.readdirSync(src).forEach(function(entry) {
|
fs.readdirSync(src).forEach(function (entry) {
|
||||||
symlinkFileOrDirTree(path.join(src, entry), path.join(dest, entry));
|
symlinkFileOrDirTree(path.join(src, entry), path.join(dest, entry));
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
fs.symlinkSync(path.relative(fs.realpathSync(path.dirname(dest)), src), dest);
|
fs.symlinkSync(path.relative(fs.realpathSync(path.dirname(dest)), src), dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,8 +288,8 @@ function removeFileAndParents (baseDir, destFile, stopper) {
|
|||||||
// check if directory is empty
|
// check if directory is empty
|
||||||
var curDir = path.dirname(file);
|
var curDir = path.dirname(file);
|
||||||
|
|
||||||
while(curDir !== path.resolve(baseDir, stopper)) {
|
while (curDir !== path.resolve(baseDir, stopper)) {
|
||||||
if(fs.existsSync(curDir) && fs.readdirSync(curDir).length === 0) {
|
if (fs.existsSync(curDir) && fs.readdirSync(curDir).length === 0) {
|
||||||
fs.rmdirSync(curDir);
|
fs.rmdirSync(curDir);
|
||||||
curDir = path.resolve(curDir, '..');
|
curDir = path.resolve(curDir, '..');
|
||||||
} else {
|
} else {
|
||||||
@@ -303,6 +299,6 @@ function removeFileAndParents (baseDir, destFile, stopper) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateAttributeError(attribute, element, id) {
|
function generateAttributeError (attribute, element, id) {
|
||||||
return 'Required attribute "' + attribute + '" not specified in <' + element + '> element from plugin: ' + id;
|
return 'Required attribute "' + attribute + '" not specified in <' + element + '> element from plugin: ' + id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
specific language governing permissions and limitations
|
specific language governing permissions and limitations
|
||||||
under the License.
|
under the License.
|
||||||
*/
|
*/
|
||||||
|
/* eslint no-useless-escape: 0 */
|
||||||
|
|
||||||
var Q = require('q');
|
var Q = require('q');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
@@ -23,6 +24,7 @@ var path = require('path');
|
|||||||
var shell = require('shelljs');
|
var shell = require('shelljs');
|
||||||
var events = require('cordova-common').events;
|
var events = require('cordova-common').events;
|
||||||
var AndroidManifest = require('./AndroidManifest');
|
var AndroidManifest = require('./AndroidManifest');
|
||||||
|
var checkReqs = require('./check_reqs');
|
||||||
var xmlHelpers = require('cordova-common').xmlHelpers;
|
var xmlHelpers = require('cordova-common').xmlHelpers;
|
||||||
var CordovaError = require('cordova-common').CordovaError;
|
var CordovaError = require('cordova-common').CordovaError;
|
||||||
var ConfigParser = require('cordova-common').ConfigParser;
|
var ConfigParser = require('cordova-common').ConfigParser;
|
||||||
@@ -40,17 +42,14 @@ module.exports.prepare = function (cordovaProject, options) {
|
|||||||
this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations);
|
this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations);
|
||||||
|
|
||||||
// Update own www dir with project's www assets and plugins' assets and js-files
|
// Update own www dir with project's www assets and plugins' assets and js-files
|
||||||
return Q.when(updateWww(cordovaProject, this.locations))
|
return Q.when(updateWww(cordovaProject, this.locations)).then(function () {
|
||||||
.then(function () {
|
|
||||||
// update project according to config.xml changes.
|
// update project according to config.xml changes.
|
||||||
return updateProjectAccordingTo(self._config, self.locations);
|
return updateProjectAccordingTo(self._config, self.locations);
|
||||||
})
|
}).then(function () {
|
||||||
.then(function () {
|
|
||||||
updateIcons(cordovaProject, path.relative(cordovaProject.root, self.locations.res));
|
updateIcons(cordovaProject, path.relative(cordovaProject.root, self.locations.res));
|
||||||
updateSplashes(cordovaProject, path.relative(cordovaProject.root, self.locations.res));
|
updateSplashes(cordovaProject, path.relative(cordovaProject.root, self.locations.res));
|
||||||
updateFileResources(cordovaProject, path.relative(cordovaProject.root, self.locations.root));
|
updateFileResources(cordovaProject, path.relative(cordovaProject.root, self.locations.root));
|
||||||
})
|
}).then(function () {
|
||||||
.then(function () {
|
|
||||||
events.emit('verbose', 'Prepared android project successfully');
|
events.emit('verbose', 'Prepared android project successfully');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -91,7 +90,7 @@ module.exports.clean = function (options) {
|
|||||||
* represents current project's configuration. When returned, the
|
* represents current project's configuration. When returned, the
|
||||||
* configuration is already dumped to appropriate config.xml file.
|
* configuration is already dumped to appropriate config.xml file.
|
||||||
*/
|
*/
|
||||||
function updateConfigFilesFrom(sourceConfig, configMunger, locations) {
|
function updateConfigFilesFrom (sourceConfig, configMunger, locations) {
|
||||||
events.emit('verbose', 'Generating platform-specific config.xml from defaults for android at ' + locations.configXml);
|
events.emit('verbose', 'Generating platform-specific config.xml from defaults for android at ' + locations.configXml);
|
||||||
|
|
||||||
// First cleanup current config and merge project's one into own
|
// First cleanup current config and merge project's one into own
|
||||||
@@ -106,7 +105,7 @@ function updateConfigFilesFrom(sourceConfig, configMunger, locations) {
|
|||||||
// Merge changes from app's config.xml into platform's one
|
// Merge changes from app's config.xml into platform's one
|
||||||
var config = new ConfigParser(locations.configXml);
|
var config = new ConfigParser(locations.configXml);
|
||||||
xmlHelpers.mergeXml(sourceConfig.doc.getroot(),
|
xmlHelpers.mergeXml(sourceConfig.doc.getroot(),
|
||||||
config.doc.getroot(), 'android', /*clobber=*/true);
|
config.doc.getroot(), 'android', /* clobber= */true);
|
||||||
|
|
||||||
config.write();
|
config.write();
|
||||||
return config;
|
return config;
|
||||||
@@ -115,7 +114,7 @@ function updateConfigFilesFrom(sourceConfig, configMunger, locations) {
|
|||||||
/**
|
/**
|
||||||
* Logs all file operations via the verbose event stream, indented.
|
* Logs all file operations via the verbose event stream, indented.
|
||||||
*/
|
*/
|
||||||
function logFileOp(message) {
|
function logFileOp (message) {
|
||||||
events.emit('verbose', ' ' + message);
|
events.emit('verbose', ' ' + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +127,7 @@ function logFileOp(message) {
|
|||||||
* @param {Object} destinations An object that contains destination
|
* @param {Object} destinations An object that contains destination
|
||||||
* paths for www files.
|
* paths for www files.
|
||||||
*/
|
*/
|
||||||
function updateWww(cordovaProject, destinations) {
|
function updateWww (cordovaProject, destinations) {
|
||||||
var sourceDirs = [
|
var sourceDirs = [
|
||||||
path.relative(cordovaProject.root, cordovaProject.locations.www),
|
path.relative(cordovaProject.root, cordovaProject.locations.www),
|
||||||
path.relative(cordovaProject.root, destinations.platformWww)
|
path.relative(cordovaProject.root, destinations.platformWww)
|
||||||
@@ -151,7 +150,7 @@ function updateWww(cordovaProject, destinations) {
|
|||||||
/**
|
/**
|
||||||
* Cleans all files from the platform 'www' directory.
|
* Cleans all files from the platform 'www' directory.
|
||||||
*/
|
*/
|
||||||
function cleanWww(projectRoot, locations) {
|
function cleanWww (projectRoot, locations) {
|
||||||
var targetDir = path.relative(projectRoot, locations.www);
|
var targetDir = path.relative(projectRoot, locations.www);
|
||||||
events.emit('verbose', 'Cleaning ' + targetDir);
|
events.emit('verbose', 'Cleaning ' + targetDir);
|
||||||
|
|
||||||
@@ -167,19 +166,26 @@ function cleanWww(projectRoot, locations) {
|
|||||||
* be used to update project
|
* be used to update project
|
||||||
* @param {Object} locations A map of locations for this platform
|
* @param {Object} locations A map of locations for this platform
|
||||||
*/
|
*/
|
||||||
function updateProjectAccordingTo(platformConfig, locations) {
|
function updateProjectAccordingTo (platformConfig, locations) {
|
||||||
// Update app name by editing res/values/strings.xml
|
// Update app name by editing res/values/strings.xml
|
||||||
var name = platformConfig.name();
|
|
||||||
var strings = xmlHelpers.parseElementtreeSync(locations.strings);
|
var strings = xmlHelpers.parseElementtreeSync(locations.strings);
|
||||||
|
|
||||||
|
var name = platformConfig.name();
|
||||||
strings.find('string[@name="app_name"]').text = name.replace(/\'/g, '\\\'');
|
strings.find('string[@name="app_name"]').text = name.replace(/\'/g, '\\\'');
|
||||||
|
|
||||||
|
var shortName = platformConfig.shortName && platformConfig.shortName();
|
||||||
|
if (shortName && shortName !== name) {
|
||||||
|
strings.find('string[@name="launcher_name"]').text = shortName.replace(/\'/g, '\\\'');
|
||||||
|
}
|
||||||
|
|
||||||
fs.writeFileSync(locations.strings, strings.write({indent: 4}), 'utf-8');
|
fs.writeFileSync(locations.strings, strings.write({indent: 4}), 'utf-8');
|
||||||
events.emit('verbose', 'Wrote out android application name "' + name + '" to ' + locations.strings);
|
events.emit('verbose', 'Wrote out android application name "' + name + '" to ' + locations.strings);
|
||||||
|
|
||||||
// Java packages cannot support dashes
|
// Java packages cannot support dashes
|
||||||
var pkg = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_');
|
var androidPkgName = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_');
|
||||||
|
|
||||||
var manifest = new AndroidManifest(locations.manifest);
|
var manifest = new AndroidManifest(locations.manifest);
|
||||||
var orig_pkg = manifest.getPackageId();
|
var manifestId = manifest.getPackageId();
|
||||||
|
|
||||||
manifest.getActivity()
|
manifest.getActivity()
|
||||||
.setOrientation(platformConfig.getPreference('orientation'))
|
.setOrientation(platformConfig.getPreference('orientation'))
|
||||||
@@ -187,36 +193,40 @@ function updateProjectAccordingTo(platformConfig, locations) {
|
|||||||
|
|
||||||
manifest.setVersionName(platformConfig.version())
|
manifest.setVersionName(platformConfig.version())
|
||||||
.setVersionCode(platformConfig.android_versionCode() || default_versionCode(platformConfig.version()))
|
.setVersionCode(platformConfig.android_versionCode() || default_versionCode(platformConfig.version()))
|
||||||
.setPackageId(pkg)
|
.setPackageId(androidPkgName)
|
||||||
.setMinSdkVersion(platformConfig.getPreference('android-minSdkVersion', 'android'))
|
.setMinSdkVersion(platformConfig.getPreference('android-minSdkVersion', 'android'))
|
||||||
.setMaxSdkVersion(platformConfig.getPreference('android-maxSdkVersion', 'android'))
|
.setMaxSdkVersion(platformConfig.getPreference('android-maxSdkVersion', 'android'))
|
||||||
.setTargetSdkVersion(platformConfig.getPreference('android-targetSdkVersion', 'android'))
|
.setTargetSdkVersion(platformConfig.getPreference('android-targetSdkVersion', 'android'))
|
||||||
.write();
|
.write();
|
||||||
|
|
||||||
var javaPattern = path.join(locations.root, 'src', orig_pkg.replace(/\./g, '/'), '*.java');
|
var javaPattern = path.join(locations.root, 'src', manifestId.replace(/\./g, '/'), '*.java');
|
||||||
var java_files = shell.ls(javaPattern).filter(function(f) {
|
var java_files = shell.ls(javaPattern).filter(function (f) {
|
||||||
return shell.grep(/extends\s+CordovaActivity/g, f);
|
return shell.grep(/extends\s+CordovaActivity/g, f);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (java_files.length === 0) {
|
if (java_files.length === 0) {
|
||||||
throw new CordovaError('No Java files found that extend CordovaActivity.');
|
throw new CordovaError('No Java files found that extend CordovaActivity.');
|
||||||
} else if(java_files.length > 1) {
|
} else if (java_files.length > 1) {
|
||||||
events.emit('log', 'Multiple candidate Java files that extend CordovaActivity found. Guessing at the first one, ' + java_files[0]);
|
events.emit('log', 'Multiple candidate Java files that extend CordovaActivity found. Guessing at the first one, ' + java_files[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var destFile = path.join(locations.root, 'src', pkg.replace(/\./g, '/'), path.basename(java_files[0]));
|
var destFile = path.join(locations.root, 'src', androidPkgName.replace(/\./g, '/'), path.basename(java_files[0]));
|
||||||
shell.mkdir('-p', path.dirname(destFile));
|
shell.mkdir('-p', path.dirname(destFile));
|
||||||
shell.sed(/package [\w\.]*;/, 'package ' + pkg + ';', java_files[0]).to(destFile);
|
shell.sed(/package [\w\.]*;/, 'package ' + androidPkgName + ';', java_files[0]).to(destFile);
|
||||||
events.emit('verbose', 'Wrote out Android package name "' + pkg + '" to ' + destFile);
|
events.emit('verbose', 'Wrote out Android package name "' + androidPkgName + '" to ' + destFile);
|
||||||
|
|
||||||
if (orig_pkg !== pkg) {
|
var removeOrigPkg = checkReqs.isWindows() || checkReqs.isDarwin() ?
|
||||||
|
manifestId.toUpperCase() !== androidPkgName.toUpperCase() :
|
||||||
|
manifestId !== androidPkgName;
|
||||||
|
|
||||||
|
if (removeOrigPkg) {
|
||||||
// If package was name changed we need to remove old java with main activity
|
// If package was name changed we need to remove old java with main activity
|
||||||
shell.rm('-Rf',java_files[0]);
|
shell.rm('-Rf', java_files[0]);
|
||||||
// remove any empty directories
|
// remove any empty directories
|
||||||
var currentDir = path.dirname(java_files[0]);
|
var currentDir = path.dirname(java_files[0]);
|
||||||
var sourcesRoot = path.resolve(locations.root, 'src');
|
var sourcesRoot = path.resolve(locations.root, 'src');
|
||||||
while(currentDir !== sourcesRoot) {
|
while (currentDir !== sourcesRoot) {
|
||||||
if(fs.existsSync(currentDir) && fs.readdirSync(currentDir).length === 0) {
|
if (fs.existsSync(currentDir) && fs.readdirSync(currentDir).length === 0) {
|
||||||
fs.rmdirSync(currentDir);
|
fs.rmdirSync(currentDir);
|
||||||
currentDir = path.resolve(currentDir, '..');
|
currentDir = path.resolve(currentDir, '..');
|
||||||
} else {
|
} else {
|
||||||
@@ -229,7 +239,7 @@ function updateProjectAccordingTo(platformConfig, locations) {
|
|||||||
// Consturct the default value for versionCode as
|
// Consturct the default value for versionCode as
|
||||||
// PATCH + MINOR * 100 + MAJOR * 10000
|
// PATCH + MINOR * 100 + MAJOR * 10000
|
||||||
// see http://developer.android.com/tools/publishing/versioning.html
|
// see http://developer.android.com/tools/publishing/versioning.html
|
||||||
function default_versionCode(version) {
|
function default_versionCode (version) {
|
||||||
var nums = version.split('-')[0].split('.');
|
var nums = version.split('-')[0].split('.');
|
||||||
var versionCode = 0;
|
var versionCode = 0;
|
||||||
if (+nums[0]) {
|
if (+nums[0]) {
|
||||||
@@ -246,7 +256,7 @@ function default_versionCode(version) {
|
|||||||
return versionCode;
|
return versionCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getImageResourcePath(resourcesDir, type, density, name, sourceName) {
|
function getImageResourcePath (resourcesDir, type, density, name, sourceName) {
|
||||||
if (/\.9\.png$/.test(sourceName)) {
|
if (/\.9\.png$/.test(sourceName)) {
|
||||||
name = name.replace(/\.png$/, '.9.png');
|
name = name.replace(/\.png$/, '.9.png');
|
||||||
}
|
}
|
||||||
@@ -254,7 +264,7 @@ function getImageResourcePath(resourcesDir, type, density, name, sourceName) {
|
|||||||
return resourcePath;
|
return resourcePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSplashes(cordovaProject, platformResourcesDir) {
|
function updateSplashes (cordovaProject, platformResourcesDir) {
|
||||||
var resources = cordovaProject.projectConfig.getSplashScreens('android');
|
var resources = cordovaProject.projectConfig.getSplashScreens('android');
|
||||||
|
|
||||||
// if there are "splash" elements in config.xml
|
// if there are "splash" elements in config.xml
|
||||||
@@ -270,7 +280,7 @@ function updateSplashes(cordovaProject, platformResourcesDir) {
|
|||||||
if (!resource.density) {
|
if (!resource.density) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (resource.density == 'mdpi') {
|
if (resource.density === 'mdpi') {
|
||||||
hadMdpi = true;
|
hadMdpi = true;
|
||||||
}
|
}
|
||||||
var targetPath = getImageResourcePath(
|
var targetPath = getImageResourcePath(
|
||||||
@@ -290,7 +300,7 @@ function updateSplashes(cordovaProject, platformResourcesDir) {
|
|||||||
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanSplashes(projectRoot, projectConfig, platformResourcesDir) {
|
function cleanSplashes (projectRoot, projectConfig, platformResourcesDir) {
|
||||||
var resources = projectConfig.getSplashScreens('android');
|
var resources = projectConfig.getSplashScreens('android');
|
||||||
if (resources.length > 0) {
|
if (resources.length > 0) {
|
||||||
var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'drawable', 'screen.png');
|
var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'drawable', 'screen.png');
|
||||||
@@ -302,7 +312,7 @@ function cleanSplashes(projectRoot, projectConfig, platformResourcesDir) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateIcons(cordovaProject, platformResourcesDir) {
|
function updateIcons (cordovaProject, platformResourcesDir) {
|
||||||
var icons = cordovaProject.projectConfig.getIcons('android');
|
var icons = cordovaProject.projectConfig.getIcons('android');
|
||||||
|
|
||||||
// if there are icon elements in config.xml
|
// if there are icon elements in config.xml
|
||||||
@@ -326,7 +336,7 @@ function updateIcons(cordovaProject, platformResourcesDir) {
|
|||||||
};
|
};
|
||||||
// find the best matching icon for a given density or size
|
// find the best matching icon for a given density or size
|
||||||
// @output android_icons
|
// @output android_icons
|
||||||
var parseIcon = function(icon, icon_size) {
|
var parseIcon = function (icon, icon_size) {
|
||||||
// do I have a platform icon for that density already
|
// do I have a platform icon for that density already
|
||||||
var density = icon.density || sizeToDensityMap[icon_size];
|
var density = icon.density || sizeToDensityMap[icon_size];
|
||||||
if (!density) {
|
if (!density) {
|
||||||
@@ -341,7 +351,7 @@ function updateIcons(cordovaProject, platformResourcesDir) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// iterate over all icon elements to find the default icon and call parseIcon
|
// iterate over all icon elements to find the default icon and call parseIcon
|
||||||
for (var i=0; i<icons.length; i++) {
|
for (var i = 0; i < icons.length; i++) {
|
||||||
var icon = icons[i];
|
var icon = icons[i];
|
||||||
var size = icon.width;
|
var size = icon.width;
|
||||||
if (!size) {
|
if (!size) {
|
||||||
@@ -378,7 +388,7 @@ function updateIcons(cordovaProject, platformResourcesDir) {
|
|||||||
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanIcons(projectRoot, projectConfig, platformResourcesDir) {
|
function cleanIcons (projectRoot, projectConfig, platformResourcesDir) {
|
||||||
var icons = projectConfig.getIcons('android');
|
var icons = projectConfig.getIcons('android');
|
||||||
if (icons.length > 0) {
|
if (icons.length > 0) {
|
||||||
var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'icon.png');
|
var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'icon.png');
|
||||||
@@ -393,18 +403,16 @@ function cleanIcons(projectRoot, projectConfig, platformResourcesDir) {
|
|||||||
/**
|
/**
|
||||||
* Gets a map containing resources of a specified name from all drawable folders in a directory.
|
* Gets a map containing resources of a specified name from all drawable folders in a directory.
|
||||||
*/
|
*/
|
||||||
function mapImageResources(rootDir, subDir, type, resourceName) {
|
function mapImageResources (rootDir, subDir, type, resourceName) {
|
||||||
var pathMap = {};
|
var pathMap = {};
|
||||||
shell.ls(path.join(rootDir, subDir, type + '-*'))
|
shell.ls(path.join(rootDir, subDir, type + '-*')).forEach(function (drawableFolder) {
|
||||||
.forEach(function (drawableFolder) {
|
|
||||||
var imagePath = path.join(subDir, path.basename(drawableFolder), resourceName);
|
var imagePath = path.join(subDir, path.basename(drawableFolder), resourceName);
|
||||||
pathMap[imagePath] = null;
|
pathMap[imagePath] = null;
|
||||||
});
|
});
|
||||||
return pathMap;
|
return pathMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateFileResources (cordovaProject, platformDir) {
|
||||||
function updateFileResources(cordovaProject, platformDir) {
|
|
||||||
var files = cordovaProject.projectConfig.getFileResources('android');
|
var files = cordovaProject.projectConfig.getFileResources('android');
|
||||||
|
|
||||||
// if there are resource-file elements in config.xml
|
// if there are resource-file elements in config.xml
|
||||||
@@ -414,7 +422,7 @@ function updateFileResources(cordovaProject, platformDir) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var resourceMap = {};
|
var resourceMap = {};
|
||||||
files.forEach(function(res) {
|
files.forEach(function (res) {
|
||||||
var targetPath = path.join(platformDir, res.target);
|
var targetPath = path.join(platformDir, res.target);
|
||||||
resourceMap[targetPath] = res.src;
|
resourceMap[targetPath] = res.src;
|
||||||
});
|
});
|
||||||
@@ -424,20 +432,20 @@ function updateFileResources(cordovaProject, platformDir) {
|
|||||||
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cleanFileResources (projectRoot, projectConfig, platformDir) {
|
||||||
function cleanFileResources(projectRoot, projectConfig, platformDir) {
|
var files = projectConfig.getFileResources('android', true);
|
||||||
var files = projectConfig.getFileResources('android');
|
|
||||||
if (files.length > 0) {
|
if (files.length > 0) {
|
||||||
events.emit('verbose', 'Cleaning resource files at ' + platformDir);
|
events.emit('verbose', 'Cleaning resource files at ' + platformDir);
|
||||||
|
|
||||||
var resourceMap = {};
|
var resourceMap = {};
|
||||||
files.forEach(function(res) {
|
files.forEach(function (res) {
|
||||||
var filePath = path.join(platformDir, res.target);
|
var filePath = path.join(platformDir, res.target);
|
||||||
resourceMap[filePath] = null;
|
resourceMap[filePath] = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
FileUpdater.updatePaths(
|
FileUpdater.updatePaths(
|
||||||
resourceMap, { rootDir: projectRoot, all: true}, logFileOp);
|
resourceMap, {
|
||||||
|
rootDir: projectRoot, all: true}, logFileOp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,7 +460,7 @@ function cleanFileResources(projectRoot, projectConfig, platformDir) {
|
|||||||
* default value, if there is no such preference. The default value is
|
* default value, if there is no such preference. The default value is
|
||||||
* 'singleTop'
|
* 'singleTop'
|
||||||
*/
|
*/
|
||||||
function findAndroidLaunchModePreference(platformConfig) {
|
function findAndroidLaunchModePreference (platformConfig) {
|
||||||
var launchMode = platformConfig.getPreference('AndroidLaunchMode');
|
var launchMode = platformConfig.getPreference('AndroidLaunchMode');
|
||||||
if (!launchMode) {
|
if (!launchMode) {
|
||||||
// Return a default value
|
// Return a default value
|
||||||
|
|||||||
@@ -45,12 +45,12 @@ module.exports.retryPromise = function (attemts_left, promiseFunction) {
|
|||||||
return promiseFunction.apply(undefined, promiseFunctionArguments).then(
|
return promiseFunction.apply(undefined, promiseFunctionArguments).then(
|
||||||
|
|
||||||
// on success pass results through
|
// on success pass results through
|
||||||
function onFulfilled(value) {
|
function onFulfilled (value) {
|
||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
|
|
||||||
// on rejection either retry, or throw the error
|
// on rejection either retry, or throw the error
|
||||||
function onRejected(error) {
|
function onRejected (error) {
|
||||||
|
|
||||||
attemts_left -= 1;
|
attemts_left -= 1;
|
||||||
|
|
||||||
|
|||||||
@@ -21,14 +21,14 @@
|
|||||||
|
|
||||||
/* jshint loopfunc:true */
|
/* jshint loopfunc:true */
|
||||||
|
|
||||||
var path = require('path'),
|
var path = require('path');
|
||||||
build = require('./build'),
|
var build = require('./build');
|
||||||
emulator = require('./emulator'),
|
var emulator = require('./emulator');
|
||||||
device = require('./device'),
|
var device = require('./device');
|
||||||
Q = require('q'),
|
var Q = require('q');
|
||||||
events = require('cordova-common').events;
|
var events = require('cordova-common').events;
|
||||||
|
|
||||||
function getInstallTarget(runOptions) {
|
function getInstallTarget (runOptions) {
|
||||||
var install_target;
|
var install_target;
|
||||||
if (runOptions.target) {
|
if (runOptions.target) {
|
||||||
install_target = runOptions.target;
|
install_target = runOptions.target;
|
||||||
@@ -51,17 +51,15 @@ function getInstallTarget(runOptions) {
|
|||||||
*
|
*
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
module.exports.run = function(runOptions) {
|
module.exports.run = function (runOptions) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var install_target = getInstallTarget(runOptions);
|
var install_target = getInstallTarget(runOptions);
|
||||||
|
|
||||||
return Q()
|
return Q().then(function () {
|
||||||
.then(function() {
|
|
||||||
if (!install_target) {
|
if (!install_target) {
|
||||||
// no target given, deploy to device if available, otherwise use the emulator.
|
// no target given, deploy to device if available, otherwise use the emulator.
|
||||||
return device.list()
|
return device.list().then(function (device_list) {
|
||||||
.then(function(device_list) {
|
|
||||||
if (device_list.length > 0) {
|
if (device_list.length > 0) {
|
||||||
events.emit('warn', 'No target specified, deploying to device \'' + device_list[0] + '\'.');
|
events.emit('warn', 'No target specified, deploying to device \'' + device_list[0] + '\'.');
|
||||||
install_target = device_list[0];
|
install_target = device_list[0];
|
||||||
@@ -71,36 +69,31 @@ function getInstallTarget(runOptions) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).then(function() {
|
}).then(function () {
|
||||||
if (install_target == '--device') {
|
if (install_target === '--device') {
|
||||||
return device.resolveTarget(null);
|
return device.resolveTarget(null);
|
||||||
} else if (install_target == '--emulator') {
|
} else if (install_target === '--emulator') {
|
||||||
// Give preference to any already started emulators. Else, start one.
|
// Give preference to any already started emulators. Else, start one.
|
||||||
return emulator.list_started()
|
return emulator.list_started().then(function (started) {
|
||||||
.then(function(started) {
|
|
||||||
return started && started.length > 0 ? started[0] : emulator.start();
|
return started && started.length > 0 ? started[0] : emulator.start();
|
||||||
}).then(function(emulatorId) {
|
}).then(function (emulatorId) {
|
||||||
return emulator.resolveTarget(emulatorId);
|
return emulator.resolveTarget(emulatorId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// They specified a specific device/emulator ID.
|
// They specified a specific device/emulator ID.
|
||||||
return device.list()
|
return device.list().then(function (devices) {
|
||||||
.then(function(devices) {
|
|
||||||
if (devices.indexOf(install_target) > -1) {
|
if (devices.indexOf(install_target) > -1) {
|
||||||
return device.resolveTarget(install_target);
|
return device.resolveTarget(install_target);
|
||||||
}
|
}
|
||||||
return emulator.list_started()
|
return emulator.list_started().then(function (started_emulators) {
|
||||||
.then(function(started_emulators) {
|
|
||||||
if (started_emulators.indexOf(install_target) > -1) {
|
if (started_emulators.indexOf(install_target) > -1) {
|
||||||
return emulator.resolveTarget(install_target);
|
return emulator.resolveTarget(install_target);
|
||||||
}
|
}
|
||||||
return emulator.list_images()
|
return emulator.list_images().then(function (avds) {
|
||||||
.then(function(avds) {
|
|
||||||
// if target emulator isn't started, then start it.
|
// if target emulator isn't started, then start it.
|
||||||
for (var avd in avds) {
|
for (var avd in avds) {
|
||||||
if (avds[avd].name == install_target) {
|
if (avds[avd].name === install_target) {
|
||||||
return emulator.start(install_target)
|
return emulator.start(install_target).then(function (emulatorId) {
|
||||||
.then(function(emulatorId) {
|
|
||||||
return emulator.resolveTarget(emulatorId);
|
return emulator.resolveTarget(emulatorId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -109,16 +102,14 @@ function getInstallTarget(runOptions) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).then(function(resolvedTarget) {
|
}).then(function (resolvedTarget) {
|
||||||
// Better just call self.build, but we're doing some processing of
|
// Better just call self.build, but we're doing some processing of
|
||||||
// build results (according to platformApi spec) so they are in different
|
// build results (according to platformApi spec) so they are in different
|
||||||
// format than emulator.install expects.
|
// format than emulator.install expects.
|
||||||
// TODO: Update emulator/device.install to handle this change
|
// TODO: Update emulator/device.install to handle this change
|
||||||
return build.run.call(self, runOptions, resolvedTarget)
|
return build.run.call(self, runOptions, resolvedTarget).then(function (buildResults) {
|
||||||
.then(function(buildResults) {
|
|
||||||
if (resolvedTarget.isEmulator) {
|
if (resolvedTarget.isEmulator) {
|
||||||
return emulator.wait_for_boot(resolvedTarget.target)
|
return emulator.wait_for_boot(resolvedTarget.target).then(function () {
|
||||||
.then(function () {
|
|
||||||
return emulator.install(resolvedTarget, buildResults);
|
return emulator.install(resolvedTarget, buildResults);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -127,7 +118,7 @@ function getInstallTarget(runOptions) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports.help = function() {
|
module.exports.help = function () {
|
||||||
console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]) + ' [options]');
|
console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]) + ' [options]');
|
||||||
console.log('Build options :');
|
console.log('Build options :');
|
||||||
console.log(' --debug : Builds project in debug mode');
|
console.log(' --debug : Builds project in debug mode');
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
@ECHO OFF
|
@ECHO OFF
|
||||||
SET script_path="%~dp0start-emulator"
|
SET script_path="%~dp0start-emulator"
|
||||||
IF EXIST %script_path% (
|
IF EXIST %script_path% (
|
||||||
node "%script_path%" %*
|
node %script_path% %*
|
||||||
) ELSE (
|
) ELSE (
|
||||||
ECHO.
|
ECHO.
|
||||||
ECHO ERROR: Could not find 'start-emulator' script in 'cordova\lib' folder, aborting...>&2
|
ECHO ERROR: Could not find 'start-emulator' script in 'cordova\lib' folder, aborting...>&2
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Coho updates this line:
|
// Coho updates this line:
|
||||||
var VERSION = "6.2.3";
|
var VERSION = "6.4.1-dev";
|
||||||
|
|
||||||
module.exports.version = VERSION;
|
module.exports.version = VERSION;
|
||||||
|
|
||||||
|
|||||||
@@ -18,25 +18,25 @@
|
|||||||
*/
|
*/
|
||||||
var app = {
|
var app = {
|
||||||
// Application Constructor
|
// Application Constructor
|
||||||
initialize: function() {
|
initialize: function () {
|
||||||
this.bindEvents();
|
this.bindEvents();
|
||||||
},
|
},
|
||||||
// Bind Event Listeners
|
// Bind Event Listeners
|
||||||
//
|
//
|
||||||
// Bind any events that are required on startup. Common events are:
|
// Bind any events that are required on startup. Common events are:
|
||||||
// 'load', 'deviceready', 'offline', and 'online'.
|
// 'load', 'deviceready', 'offline', and 'online'.
|
||||||
bindEvents: function() {
|
bindEvents: function () {
|
||||||
document.addEventListener('deviceready', this.onDeviceReady, false);
|
document.addEventListener('deviceready', this.onDeviceReady, false);
|
||||||
},
|
},
|
||||||
// deviceready Event Handler
|
// deviceready Event Handler
|
||||||
//
|
//
|
||||||
// The scope of 'this' is the event. In order to call the 'receivedEvent'
|
// The scope of 'this' is the event. In order to call the 'receivedEvent'
|
||||||
// function, we must explicitly call 'app.receivedEvent(...);'
|
// function, we must explicitly call 'app.receivedEvent(...);'
|
||||||
onDeviceReady: function() {
|
onDeviceReady: function () {
|
||||||
app.receivedEvent('deviceready');
|
app.receivedEvent('deviceready');
|
||||||
},
|
},
|
||||||
// Update DOM on a Received Event
|
// Update DOM on a Received Event
|
||||||
receivedEvent: function(id) {
|
receivedEvent: function (id) {
|
||||||
var parentElement = document.getElementById(id);
|
var parentElement = document.getElementById(id);
|
||||||
var listeningElement = parentElement.querySelector('.listening');
|
var listeningElement = parentElement.querySelector('.listening');
|
||||||
var receivedElement = parentElement.querySelector('.received');
|
var receivedElement = parentElement.querySelector('.received');
|
||||||
@@ -48,4 +48,4 @@ var app = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
app.initialize();
|
app.initialize();
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ apply plugin: 'com.android.application'
|
|||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven {
|
||||||
|
url "https://maven.google.com"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch the Android Gradle plugin version requirement depending on the
|
// Switch the Android Gradle plugin version requirement depending on the
|
||||||
@@ -30,20 +32,22 @@ buildscript {
|
|||||||
// http://tools.android.com/tech-docs/new-build-system/version-compatibility
|
// http://tools.android.com/tech-docs/new-build-system/version-compatibility
|
||||||
// and https://issues.apache.org/jira/browse/CB-8143
|
// and https://issues.apache.org/jira/browse/CB-8143
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.2.3'
|
classpath 'com.android.tools.build:gradle:3.0.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow plugins to declare Maven dependencies via build-extras.gradle.
|
// Allow plugins to declare Maven dependencies via build-extras.gradle.
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral();
|
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven {
|
||||||
|
url "https://maven.google.com"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
task wrapper(type: Wrapper) {
|
task wrapper(type: Wrapper) {
|
||||||
gradleVersion = '2.14.1'
|
gradleVersion = '4.1.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties.
|
// Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties.
|
||||||
@@ -70,6 +74,10 @@ ext {
|
|||||||
if (!project.hasProperty('cdvBuildMultipleApks')) {
|
if (!project.hasProperty('cdvBuildMultipleApks')) {
|
||||||
cdvBuildMultipleApks = null
|
cdvBuildMultipleApks = null
|
||||||
}
|
}
|
||||||
|
// Whether to append a 0 "abi digit" to versionCode when only a single APK is build
|
||||||
|
if (!project.hasProperty('cdvVersionCodeForceAbiDigit')) {
|
||||||
|
cdvVersionCodeForceAbiDigit = null
|
||||||
|
}
|
||||||
// .properties files to use for release signing.
|
// .properties files to use for release signing.
|
||||||
if (!project.hasProperty('cdvReleaseSigningPropertiesFile')) {
|
if (!project.hasProperty('cdvReleaseSigningPropertiesFile')) {
|
||||||
cdvReleaseSigningPropertiesFile = null
|
cdvReleaseSigningPropertiesFile = null
|
||||||
@@ -111,6 +119,7 @@ if (ext.cdvReleaseSigningPropertiesFile == null && file('release-signing.propert
|
|||||||
|
|
||||||
// Cast to appropriate types.
|
// Cast to appropriate types.
|
||||||
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
|
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
|
||||||
|
ext.cdvVersionCodeForceAbiDigit = cdvVersionCodeForceAbiDigit == null ? false : cdvVersionCodeForceAbiDigit.toBoolean();
|
||||||
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' + cdvMinSdkVersion)
|
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' + cdvMinSdkVersion)
|
||||||
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
|
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
|
||||||
|
|
||||||
@@ -138,6 +147,7 @@ task cdvPrintProps << {
|
|||||||
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
|
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
|
||||||
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
|
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
|
||||||
println('cdvVersionCode=' + cdvVersionCode)
|
println('cdvVersionCode=' + cdvVersionCode)
|
||||||
|
println('cdvVersionCodeForceAbiDigit=' + cdvVersionCodeForceAbiDigit)
|
||||||
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
|
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
|
||||||
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
|
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
|
||||||
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
|
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
|
||||||
@@ -180,25 +190,45 @@ android {
|
|||||||
buildToolsVersion cdvBuildToolsVersion
|
buildToolsVersion cdvBuildToolsVersion
|
||||||
|
|
||||||
if (Boolean.valueOf(cdvBuildMultipleApks)) {
|
if (Boolean.valueOf(cdvBuildMultipleApks)) {
|
||||||
|
flavorDimensions "default"
|
||||||
|
|
||||||
productFlavors {
|
productFlavors {
|
||||||
|
armeabi {
|
||||||
|
versionCode defaultConfig.versionCode*10 + 1
|
||||||
|
ndk {
|
||||||
|
abiFilters = ["armeabi"]
|
||||||
|
}
|
||||||
|
}
|
||||||
armv7 {
|
armv7 {
|
||||||
versionCode defaultConfig.versionCode*10 + 2
|
versionCode defaultConfig.versionCode*10 + 2
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters "armeabi-v7a", ""
|
abiFilters = ["armeabi-v7a"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arm64 {
|
||||||
|
versionCode defaultConfig.versionCode*10 + 3
|
||||||
|
ndk {
|
||||||
|
abiFilters = ["arm64-v8a"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x86 {
|
x86 {
|
||||||
versionCode defaultConfig.versionCode*10 + 4
|
versionCode defaultConfig.versionCode*10 + 4
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters "x86", ""
|
abiFilters = ["x86"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
all {
|
x86_64 {
|
||||||
|
versionCode defaultConfig.versionCode*10 + 5
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters "all", ""
|
abiFilters = ["x86_64"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (Boolean.valueOf(cdvVersionCodeForceAbiDigit)) {
|
||||||
|
// This provides compatibility to the default logic for versionCode before cordova-android 5.2.0
|
||||||
|
defaultConfig {
|
||||||
|
versionCode defaultConfig.versionCode*10
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@@ -245,7 +275,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile fileTree(dir: 'libs', include: '*.jar')
|
implementation fileTree(dir: 'libs', include: '*.jar')
|
||||||
// SUB-PROJECT DEPENDENCIES START
|
// SUB-PROJECT DEPENDENCIES START
|
||||||
// SUB-PROJECT DEPENDENCIES END
|
// SUB-PROJECT DEPENDENCIES END
|
||||||
}
|
}
|
||||||
@@ -264,7 +294,7 @@ def promptForReleaseKeyPassword() {
|
|||||||
|
|
||||||
gradle.taskGraph.whenReady { taskGraph ->
|
gradle.taskGraph.whenReady { taskGraph ->
|
||||||
taskGraph.getAllTasks().each() { task ->
|
taskGraph.getAllTasks().each() { task ->
|
||||||
if (task.name == 'validateReleaseSigning' || task.name == 'validateSigningRelease') {
|
if (['validateReleaseSigning', 'validateSigningRelease', 'validateSigningArmv7Release', 'validateSigningX86Release'].contains(task.name)) {
|
||||||
promptForReleaseKeyPassword()
|
promptForReleaseKeyPassword()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 478 KiB After Width: | Height: | Size: 139 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 222 KiB |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 286 KiB |
|
Before Width: | Height: | Size: 217 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 493 KiB After Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 207 KiB |
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 292 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 7.7 KiB |
@@ -24,12 +24,14 @@ ext {
|
|||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven {
|
||||||
|
url "https://maven.google.com"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.2.3'
|
classpath 'com.android.tools.build:gradle:3.0.0'
|
||||||
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
|
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
|
||||||
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
|
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
|
||||||
}
|
}
|
||||||
@@ -40,7 +42,7 @@ apply plugin: 'com.github.dcendents.android-maven'
|
|||||||
apply plugin: 'com.jfrog.bintray'
|
apply plugin: 'com.jfrog.bintray'
|
||||||
|
|
||||||
group = 'org.apache.cordova'
|
group = 'org.apache.cordova'
|
||||||
version = '6.2.3'
|
version = '6.4.1-dev'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion cdvCompileSdkVersion
|
compileSdkVersion cdvCompileSdkVersion
|
||||||
@@ -127,9 +129,9 @@ bintray {
|
|||||||
licenses = ['Apache-2.0']
|
licenses = ['Apache-2.0']
|
||||||
labels = ['android', 'cordova', 'phonegap']
|
labels = ['android', 'cordova', 'phonegap']
|
||||||
version {
|
version {
|
||||||
name = '6.2.3'
|
name = '6.4.1-dev'
|
||||||
released = new Date()
|
released = new Date()
|
||||||
vcsTag = '6.2.3'
|
vcsTag = '6.4.1-dev'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#Mon Dec 28 10:00:20 PST 2015
|
#Thu Nov 09 10:50:25 PST 2017
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
# Indicates whether an apk should be generated for each density.
|
# Indicates whether an apk should be generated for each density.
|
||||||
split.density=false
|
split.density=false
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-25
|
target=android-26
|
||||||
apk-configurations=
|
apk-configurations=
|
||||||
renderscript.opt.level=O0
|
renderscript.opt.level=O0
|
||||||
android.library=true
|
android.library=true
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a utility class that allows us to get the BuildConfig variable, which is required
|
||||||
|
* for the use of different providers. This is not guaranteed to work, and it's better for this
|
||||||
|
* to be set in the build step in config.xml
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
|
||||||
|
public class BuildHelper {
|
||||||
|
|
||||||
|
|
||||||
|
private static String TAG="BuildHelper";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This needs to be implemented if you wish to use the Camera Plugin or other plugins
|
||||||
|
* that read the Build Configuration.
|
||||||
|
*
|
||||||
|
* Thanks to Phil@Medtronic and Graham Borland for finding the answer and posting it to
|
||||||
|
* StackOverflow. This is annoying as hell! However, this method does not work with
|
||||||
|
* ProGuard, and you should use the config.xml to define the application_id
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
public static Object getBuildConfigValue(Context ctx, String key)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class<?> clazz = Class.forName(ctx.getPackageName() + ".BuildConfig");
|
||||||
|
Field field = clazz.getField(key);
|
||||||
|
return field.get(null);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
LOG.d(TAG, "Unable to get the BuildConfig, is this built with ANT?");
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
LOG.d(TAG, key + " is not a valid field. Check your build.gradle");
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
LOG.d(TAG, "Illegal Access Exception: Let's print a stack trace.");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
|
||||||
import org.apache.cordova.CordovaPlugin;
|
import org.apache.cordova.CordovaPlugin;
|
||||||
@@ -51,10 +52,18 @@ public interface CordovaInterface {
|
|||||||
/**
|
/**
|
||||||
* Get the Android activity.
|
* Get the Android activity.
|
||||||
*
|
*
|
||||||
|
* If a custom engine lives outside of the Activity's lifecycle the return value may be null.
|
||||||
|
*
|
||||||
* @return the Activity
|
* @return the Activity
|
||||||
*/
|
*/
|
||||||
public abstract Activity getActivity();
|
public abstract Activity getActivity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Android context.
|
||||||
|
*
|
||||||
|
* @return the Context
|
||||||
|
*/
|
||||||
|
public Context getContext();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a message is sent to plugin.
|
* Called when a message is sent to plugin.
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -84,6 +85,11 @@ public class CordovaInterfaceImpl implements CordovaInterface {
|
|||||||
return activity;
|
return activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Context getContext() {
|
||||||
|
return activity;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object onMessage(String id, Object data) {
|
public Object onMessage(String id, Object data) {
|
||||||
if ("exit".equals(id)) {
|
if ("exit".equals(id)) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import android.webkit.WebChromeClient.CustomViewCallback;
|
|||||||
* are not expected to implement it.
|
* are not expected to implement it.
|
||||||
*/
|
*/
|
||||||
public interface CordovaWebView {
|
public interface CordovaWebView {
|
||||||
public static final String CORDOVA_VERSION = "6.2.3";
|
public static final String CORDOVA_VERSION = "6.4.1-dev";
|
||||||
|
|
||||||
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);
|
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides reflective methods for permission requesting and checking so that plugins
|
||||||
|
* written for cordova-android 5.0.0+ can still compile with earlier cordova-android versions.
|
||||||
|
*/
|
||||||
|
public class PermissionHelper {
|
||||||
|
private static final String LOG_TAG = "CordovaPermissionHelper";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests a "dangerous" permission for the application at runtime. This is a helper method
|
||||||
|
* alternative to cordovaInterface.requestPermission() that does not require the project to be
|
||||||
|
* built with cordova-android 5.0.0+
|
||||||
|
*
|
||||||
|
* @param plugin The plugin the permission is being requested for
|
||||||
|
* @param requestCode A requestCode to be passed to the plugin's onRequestPermissionResult()
|
||||||
|
* along with the result of the permission request
|
||||||
|
* @param permission The permission to be requested
|
||||||
|
*/
|
||||||
|
public static void requestPermission(CordovaPlugin plugin, int requestCode, String permission) {
|
||||||
|
PermissionHelper.requestPermissions(plugin, requestCode, new String[] {permission});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests "dangerous" permissions for the application at runtime. This is a helper method
|
||||||
|
* alternative to cordovaInterface.requestPermissions() that does not require the project to be
|
||||||
|
* built with cordova-android 5.0.0+
|
||||||
|
*
|
||||||
|
* @param plugin The plugin the permissions are being requested for
|
||||||
|
* @param requestCode A requestCode to be passed to the plugin's onRequestPermissionResult()
|
||||||
|
* along with the result of the permissions request
|
||||||
|
* @param permissions The permissions to be requested
|
||||||
|
*/
|
||||||
|
public static void requestPermissions(CordovaPlugin plugin, int requestCode, String[] permissions) {
|
||||||
|
plugin.cordova.requestPermissions(plugin, requestCode, permissions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks at runtime to see if the application has been granted a permission. This is a helper
|
||||||
|
* method alternative to cordovaInterface.hasPermission() that does not require the project to
|
||||||
|
* be built with cordova-android 5.0.0+
|
||||||
|
*
|
||||||
|
* @param plugin The plugin the permission is being checked against
|
||||||
|
* @param permission The permission to be checked
|
||||||
|
*
|
||||||
|
* @return True if the permission has already been granted and false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean hasPermission(CordovaPlugin plugin, String permission) {
|
||||||
|
return plugin.cordova.hasPermission(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void deliverPermissionResult(CordovaPlugin plugin, int requestCode, String[] permissions) {
|
||||||
|
// Generate the request results
|
||||||
|
int[] requestResults = new int[permissions.length];
|
||||||
|
Arrays.fill(requestResults, PackageManager.PERMISSION_GRANTED);
|
||||||
|
|
||||||
|
try {
|
||||||
|
plugin.onRequestPermissionResult(requestCode, permissions, requestResults);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
LOG.e(LOG_TAG, "JSONException when delivering permissions results", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -110,7 +110,11 @@ public class SystemWebViewEngine implements CordovaWebViewEngine {
|
|||||||
nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode.OnlineEventsBridgeModeDelegate() {
|
nativeToJsMessageQueue.addBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode(new NativeToJsMessageQueue.OnlineEventsBridgeMode.OnlineEventsBridgeModeDelegate() {
|
||||||
@Override
|
@Override
|
||||||
public void setNetworkAvailable(boolean value) {
|
public void setNetworkAvailable(boolean value) {
|
||||||
webView.setNetworkAvailable(value);
|
//sometimes this can be called after calling webview.destroy() on destroy()
|
||||||
|
//thus resulting in a NullPointerException
|
||||||
|
if(webView!=null) {
|
||||||
|
webView.setNetworkAvailable(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void runOnUiThread(Runnable r) {
|
public void runOnUiThread(Runnable r) {
|
||||||
@@ -210,11 +214,6 @@ public class SystemWebViewEngine implements CordovaWebViewEngine {
|
|||||||
settings.setAppCachePath(databasePath);
|
settings.setAppCachePath(databasePath);
|
||||||
settings.setAppCacheEnabled(true);
|
settings.setAppCacheEnabled(true);
|
||||||
|
|
||||||
// Enable scaling
|
|
||||||
// Fix for CB-12015
|
|
||||||
settings.setUseWideViewPort(true);
|
|
||||||
settings.setLoadWithOverviewMode(true);
|
|
||||||
|
|
||||||
// Fix for CB-1405
|
// Fix for CB-1405
|
||||||
// Google issue 4641
|
// Google issue 4641
|
||||||
String defaultUserAgent = settings.getUserAgentString();
|
String defaultUserAgent = settings.getUserAgentString();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"spec": ">=1.0.0 <2.0.0",
|
"spec": ">=1.0.0 <2.0.0",
|
||||||
"type": "range"
|
"type": "range"
|
||||||
},
|
},
|
||||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/nopt"
|
"/Users/jbowser/cordova/cordova-android/node_modules/nopt"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"_from": "abbrev@>=1.0.0 <2.0.0",
|
"_from": "abbrev@>=1.0.0 <2.0.0",
|
||||||
@@ -40,11 +40,11 @@
|
|||||||
"_requiredBy": [
|
"_requiredBy": [
|
||||||
"/nopt"
|
"/nopt"
|
||||||
],
|
],
|
||||||
"_resolved": "http://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
|
"_resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
|
||||||
"_shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f",
|
"_shasum": "d0554c2256636e2f56e7c2e5ad183f859428d81f",
|
||||||
"_shrinkwrap": null,
|
"_shrinkwrap": null,
|
||||||
"_spec": "abbrev@1",
|
"_spec": "abbrev@1",
|
||||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/nopt",
|
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/nopt",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Isaac Z. Schlueter",
|
"name": "Isaac Z. Schlueter",
|
||||||
"email": "i@izs.me"
|
"email": "i@izs.me"
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
.git/
|
||||||
|
node_modules/
|
||||||
|
coverage/
|
||||||
|
build/
|
||||||
|
assets/
|
||||||
|
dist/
|
||||||
|
docs/
|
||||||
|
tests/
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"indent": 2,
|
||||||
|
"forin": true,
|
||||||
|
"noarg": true,
|
||||||
|
"bitwise": true,
|
||||||
|
"nonew": true,
|
||||||
|
"strict": true,
|
||||||
|
|
||||||
|
"browser": true,
|
||||||
|
"devel": true,
|
||||||
|
"node": false,
|
||||||
|
"jquery": false,
|
||||||
|
"esnext": false,
|
||||||
|
"moz": false,
|
||||||
|
"es3": false,
|
||||||
|
|
||||||
|
"asi": true,
|
||||||
|
|
||||||
|
"eqnull": true,
|
||||||
|
"debug": true,
|
||||||
|
"boss": true,
|
||||||
|
"evil": true,
|
||||||
|
"loopfunc": true,
|
||||||
|
"laxbreak": true,
|
||||||
|
|
||||||
|
"unused": true,
|
||||||
|
"undef": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "6.1.0"
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
Android Versions
|
||||||
|
================
|
||||||
|
|
||||||
|
A node module to get Android versions by API level, NDK level, semantic version, or version name.
|
||||||
|
|
||||||
|
Versions are referenced from [source.android.com/source/build-numbers.html](https://source.android.com/source/build-numbers.html#platform-code-names-versions-api-levels-and-ndk-releases). The version for "Current Development Build" (`"CUR_DEVELOPMENT"`) is not included in the list of `VERSIONS`.
|
||||||
|
|
||||||
|
[![NPM version][npm-image]][npm-url]
|
||||||
|
[![build status][travis-image]][travis-url]
|
||||||
|
|
||||||
|
[npm-image]: https://img.shields.io/npm/v/android-versions.svg?style=flat-square
|
||||||
|
[npm-url]: https://npmjs.org/package/android-versions
|
||||||
|
[travis-image]: https://img.shields.io/travis/dvoiss/android-versions.svg?style=flat-square
|
||||||
|
[travis-url]: https://travis-ci.org/dvoiss/android-versions
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# NPM
|
||||||
|
npm install android-versions --save
|
||||||
|
# YARN
|
||||||
|
yarn add android-versions
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
View the tests for more advanced usage.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const android = require('android-versions')
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Get by API level:
|
||||||
|
```javascript
|
||||||
|
console.log(android.get(23))
|
||||||
|
|
||||||
|
=> { api: 23, ndk: 8, semver: "6.0", name: "Marshmallow", versionCode: "M" }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Get by version:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
console.log(android.get("2.3.3"))
|
||||||
|
|
||||||
|
=> { api: 10, ndk: 5, semver: "2.3.3", name: "Gingerbread", versionCode: "GINGERBREAD_MR1" }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Get all by predicate:
|
||||||
|
|
||||||
|
```
|
||||||
|
android.getAll((version) => {
|
||||||
|
return version.ndk > 5 && version.api < 15
|
||||||
|
}).map((version) => version.versionCode)
|
||||||
|
|
||||||
|
=> [ "HONEYCOMB_MR1", "HONEYCOMB_MR2", "ICE_CREAM_SANDWICH" ]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Access a specific version with all info:
|
||||||
|
|
||||||
|
```
|
||||||
|
android.LOLLIPOP
|
||||||
|
|
||||||
|
=> { api: 21, ndk: 8, semver: "5.0", name: "Lollipop", versionCode: "LOLLIPOP" }
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Access the complete reference of Android versions with all info:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
android.VERSIONS
|
||||||
|
|
||||||
|
=> {
|
||||||
|
BASE: { api: 1, ndk: 0, semver: "1.0", name: "(no code name)", versionCode: "BASE" },
|
||||||
|
...
|
||||||
|
N: { api: 24, ndk: 8, semver: "7.0", name: "Nougat", versionCode: "N" }
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run test
|
||||||
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2016, David Voiss <davidvoiss@gmail.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
* with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
* and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
* THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* jshint node: true */
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A module to get Android versions by API level, NDK level, semantic version, or version name.
|
||||||
|
*
|
||||||
|
* Versions are referenced from here:
|
||||||
|
* {@link https://source.android.com/source/build-numbers.html#platform-code-names-versions-api-levels-and-ndk-releases}
|
||||||
|
* {@link https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/Build.java}
|
||||||
|
*
|
||||||
|
* The version for "Current Development Build" ("CUR_DEVELOPMENT") is not included.
|
||||||
|
*
|
||||||
|
* @module android-versions
|
||||||
|
*/
|
||||||
|
|
||||||
|
var VERSIONS = {
|
||||||
|
BASE: { api: 1, ndk: 0, semver: "1.0", name: "(no code name)", versionCode: "BASE" },
|
||||||
|
BASE_1_1: { api: 2, ndk: 0, semver: "1.1", name: "(no code name)", versionCode: "BASE_1_1" },
|
||||||
|
CUPCAKE: { api: 3, ndk: 1, semver: "1.5", name: "Cupcake", versionCode: "CUPCAKE" },
|
||||||
|
DONUT: { api: 4, ndk: 2, semver: "1.6", name: "Donut", versionCode: "DONUT" },
|
||||||
|
ECLAIR: { api: 5, ndk: 2, semver: "2.0", name: "Eclair", versionCode: "ECLAIR" },
|
||||||
|
ECLAIR_0_1: { api: 6, ndk: 2, semver: "2.0.1", name: "Eclair", versionCode: "ECLAIR_0_1" },
|
||||||
|
ECLAIR_MR1: { api: 7, ndk: 3, semver: "2.1", name: "Eclair", versionCode: "ECLAIR_MR1" },
|
||||||
|
FROYO: { api: 8, ndk: 4, semver: "2.2", name: "Froyo", versionCode: "FROYO" },
|
||||||
|
GINGERBREAD: { api: 9, ndk: 5, semver: "2.3", name: "Gingerbread", versionCode: "GINGERBREAD" },
|
||||||
|
GINGERBREAD_MR1: { api: 10, ndk: 5, semver: "2.3.3", name: "Gingerbread", versionCode: "GINGERBREAD_MR1" },
|
||||||
|
HONEYCOMB: { api: 11, ndk: 5, semver: "3.0", name: "Honeycomb", versionCode: "HONEYCOMB" },
|
||||||
|
HONEYCOMB_MR1: { api: 12, ndk: 6, semver: "3.1", name: "Honeycomb", versionCode: "HONEYCOMB_MR1" },
|
||||||
|
HONEYCOMB_MR2: { api: 13, ndk: 6, semver: "3.2", name: "Honeycomb", versionCode: "HONEYCOMB_MR2" },
|
||||||
|
ICE_CREAM_SANDWICH: { api: 14, ndk: 7, semver: "4.0", name: "Ice Cream Sandwich", versionCode: "ICE_CREAM_SANDWICH" },
|
||||||
|
ICE_CREAM_SANDWICH_MR1: { api: 15, ndk: 8, semver: "4.0.3", name: "Ice Cream Sandwich", versionCode: "ICE_CREAM_SANDWICH_MR1" },
|
||||||
|
JELLY_BEAN: { api: 16, ndk: 8, semver: "4.1", name: "Jellybean", versionCode: "JELLY_BEAN" },
|
||||||
|
JELLY_BEAN_MR1: { api: 17, ndk: 8, semver: "4.2", name: "Jellybean", versionCode: "JELLY_BEAN_MR1" },
|
||||||
|
JELLY_BEAN_MR2: { api: 18, ndk: 8, semver: "4.3", name: "Jellybean", versionCode: "JELLY_BEAN_MR2" },
|
||||||
|
KITKAT: { api: 19, ndk: 8, semver: "4.4", name: "KitKat", versionCode: "KITKAT" },
|
||||||
|
KITKAT_WATCH: { api: 20, ndk: 8, semver: "4.4", name: "KitKat Watch", versionCode: "KITKAT_WATCH" },
|
||||||
|
LOLLIPOP: { api: 21, ndk: 8, semver: "5.0", name: "Lollipop", versionCode: "LOLLIPOP" },
|
||||||
|
LOLLIPOP_MR1: { api: 22, ndk: 8, semver: "5.1", name: "Lollipop", versionCode: "LOLLIPOP_MR1" },
|
||||||
|
M: { api: 23, ndk: 8, semver: "6.0", name: "Marshmallow", versionCode: "M" },
|
||||||
|
N: { api: 24, ndk: 8, semver: "7.0", name: "Nougat", versionCode: "N" },
|
||||||
|
N_MR1: { api: 25, ndk: 8, semver: "7.1", name: "Nougat", versionCode: "N_MR1" },
|
||||||
|
O: { api: 26, ndk: 8, semver: "8.0.0", name: "Oreo", versionCode: "O" }
|
||||||
|
}
|
||||||
|
|
||||||
|
// This altSemVer accomodates the variations of semantic versions in the table above.
|
||||||
|
// For instance, Oreo is 8.0.0 while N is 7.0, searching for "8.0" or "8.0.0" will
|
||||||
|
// return Oreo, or searching for "7.0" or "7.0.0" will return N. "2.2.0" will return Froyo.
|
||||||
|
function getAlternateSemVer(semver) {
|
||||||
|
if (semver.match(/\d+.\d+.0/)) {
|
||||||
|
return semver.replace(/.\d+$/, '')
|
||||||
|
} else if (semver.match(/^\d+.\d+$/)) {
|
||||||
|
return semver + '.0'
|
||||||
|
} else {
|
||||||
|
return semver
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The default predicate compares against API level, semver, name, or code.
|
||||||
|
function getFromDefaultPredicate(arg) {
|
||||||
|
// Coerce arg to string for comparisons below.
|
||||||
|
arg = arg.toString()
|
||||||
|
|
||||||
|
return getFromPredicate(function(version) {
|
||||||
|
// Check API level before all else.
|
||||||
|
if (arg === version.api.toString()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare semver and alternate semver (see above).
|
||||||
|
var altSemVer = getAlternateSemVer(arg)
|
||||||
|
if (version.semver === arg || version.semver === altSemVer) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare version name and code.
|
||||||
|
return arg === version.name || arg === version.versionCode
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// The function to allow passing a predicate.
|
||||||
|
function getFromPredicate(predicate) {
|
||||||
|
if (predicate === null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.keys(VERSIONS).filter(function(version) {
|
||||||
|
return predicate(VERSIONS[version])
|
||||||
|
}).map(function(key) { return VERSIONS[key] })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Android version codes available as keys for easier look-up.
|
||||||
|
*/
|
||||||
|
Object.keys(VERSIONS).forEach(function(name) {
|
||||||
|
exports[name] = VERSIONS[name]
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The complete reference of Android versions for easier look-up.
|
||||||
|
*/
|
||||||
|
exports.VERSIONS = VERSIONS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a single Android version.
|
||||||
|
*
|
||||||
|
* @param {object | Function} arg - The value or predicate to use to retrieve values.
|
||||||
|
*
|
||||||
|
* @return {object} An object representing the version found or null if none found.
|
||||||
|
*/
|
||||||
|
exports.get = function(arg) {
|
||||||
|
var result = exports.getAll(arg)
|
||||||
|
|
||||||
|
if (result === null || result.length === 0) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return result[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve all Android versions that meet the criteria of the argument.
|
||||||
|
*
|
||||||
|
* @param {object | Function} arg - The value or predicate to use to retrieve values.
|
||||||
|
*
|
||||||
|
* @return {object} An object representing the version found or null if none found.
|
||||||
|
*/
|
||||||
|
exports.getAll = function(arg) {
|
||||||
|
if (arg === null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof arg === "function") {
|
||||||
|
return getFromPredicate(arg)
|
||||||
|
} else {
|
||||||
|
return getFromDefaultPredicate(arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
"_args": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"raw": "android-versions@^1.2.0",
|
||||||
|
"scope": null,
|
||||||
|
"escapedName": "android-versions",
|
||||||
|
"name": "android-versions",
|
||||||
|
"rawSpec": "^1.2.0",
|
||||||
|
"spec": ">=1.2.0 <2.0.0",
|
||||||
|
"type": "range"
|
||||||
|
},
|
||||||
|
"/Users/jbowser/cordova/cordova-android"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"_from": "android-versions@>=1.2.0 <2.0.0",
|
||||||
|
"_id": "android-versions@1.2.1",
|
||||||
|
"_inCache": true,
|
||||||
|
"_location": "/android-versions",
|
||||||
|
"_nodeVersion": "8.0.0",
|
||||||
|
"_npmOperationalInternal": {
|
||||||
|
"host": "s3://npm-registry-packages",
|
||||||
|
"tmp": "tmp/android-versions-1.2.1.tgz_1505373302036_0.5689644906669855"
|
||||||
|
},
|
||||||
|
"_npmUser": {
|
||||||
|
"name": "dvoiss",
|
||||||
|
"email": "davidvoiss@gmail.com"
|
||||||
|
},
|
||||||
|
"_npmVersion": "5.4.0",
|
||||||
|
"_phantomChildren": {},
|
||||||
|
"_requested": {
|
||||||
|
"raw": "android-versions@^1.2.0",
|
||||||
|
"scope": null,
|
||||||
|
"escapedName": "android-versions",
|
||||||
|
"name": "android-versions",
|
||||||
|
"rawSpec": "^1.2.0",
|
||||||
|
"spec": ">=1.2.0 <2.0.0",
|
||||||
|
"type": "range"
|
||||||
|
},
|
||||||
|
"_requiredBy": [
|
||||||
|
"/"
|
||||||
|
],
|
||||||
|
"_resolved": "https://registry.npmjs.org/android-versions/-/android-versions-1.2.1.tgz",
|
||||||
|
"_shasum": "3f50baf693e73a512c3c5403542291cead900063",
|
||||||
|
"_shrinkwrap": null,
|
||||||
|
"_spec": "android-versions@^1.2.0",
|
||||||
|
"_where": "/Users/jbowser/cordova/cordova-android",
|
||||||
|
"author": {
|
||||||
|
"name": "dvoiss"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/dvoiss/android-versions/issues"
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"description": "Get the name, API level, version level, NDK level, or version code from any version of Android.",
|
||||||
|
"devDependencies": {
|
||||||
|
"jsdoc": "^3.4.0",
|
||||||
|
"jshint": "^2.9.2",
|
||||||
|
"tape": "^4.6.0"
|
||||||
|
},
|
||||||
|
"directories": {},
|
||||||
|
"dist": {
|
||||||
|
"integrity": "sha512-k6zlrtWbJ3tx1ZsyyJ0Bo3r6cqPA3JUnFGv7pnIaLr1XVxSi2Tcem2lg3kBebFp27v/A40tZqdlouPyakpyKrw==",
|
||||||
|
"shasum": "3f50baf693e73a512c3c5403542291cead900063",
|
||||||
|
"tarball": "https://registry.npmjs.org/android-versions/-/android-versions-1.2.1.tgz"
|
||||||
|
},
|
||||||
|
"gitHead": "7e2def6e70634a4ebcaaa639a4c4955ae2a566e7",
|
||||||
|
"homepage": "https://github.com/dvoiss/android-versions#readme",
|
||||||
|
"keywords": [
|
||||||
|
"android",
|
||||||
|
"version",
|
||||||
|
"versions",
|
||||||
|
"ndk",
|
||||||
|
"nougat",
|
||||||
|
"marshmallow",
|
||||||
|
"api",
|
||||||
|
"level"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"main": "index.js",
|
||||||
|
"maintainers": [
|
||||||
|
{
|
||||||
|
"name": "dvoiss",
|
||||||
|
"email": "davidvoiss@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "android-versions",
|
||||||
|
"optionalDependencies": {},
|
||||||
|
"pre-commit": [
|
||||||
|
"jshint"
|
||||||
|
],
|
||||||
|
"readme": "ERROR: No README data found!",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/dvoiss/android-versions.git"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"docs": "jsdoc index.js -d ./docs/ -R README.md --debug",
|
||||||
|
"jshint": "jshint .",
|
||||||
|
"test": "tape tests/**/*.js"
|
||||||
|
},
|
||||||
|
"version": "1.2.1"
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
"spec": ">=0.3.1 <0.4.0",
|
"spec": ">=0.3.1 <0.4.0",
|
||||||
"type": "range"
|
"type": "range"
|
||||||
},
|
},
|
||||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common"
|
"/Users/jbowser/cordova/cordova-android/node_modules/cordova-common"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"_from": "ansi@>=0.3.1 <0.4.0",
|
"_from": "ansi@>=0.3.1 <0.4.0",
|
||||||
@@ -36,11 +36,11 @@
|
|||||||
"_requiredBy": [
|
"_requiredBy": [
|
||||||
"/cordova-common"
|
"/cordova-common"
|
||||||
],
|
],
|
||||||
"_resolved": "http://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz",
|
"_resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz",
|
||||||
"_shasum": "0c42d4fb17160d5a9af1e484bace1c66922c1b21",
|
"_shasum": "0c42d4fb17160d5a9af1e484bace1c66922c1b21",
|
||||||
"_shrinkwrap": null,
|
"_shrinkwrap": null,
|
||||||
"_spec": "ansi@^0.3.1",
|
"_spec": "ansi@^0.3.1",
|
||||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common",
|
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/cordova-common",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Nathan Rajlich",
|
"name": "Nathan Rajlich",
|
||||||
"email": "nathan@tootallnate.net",
|
"email": "nathan@tootallnate.net",
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
'use strict';
|
||||||
module.exports = balanced;
|
module.exports = balanced;
|
||||||
function balanced(a, b, str) {
|
function balanced(a, b, str) {
|
||||||
if (a instanceof RegExp) a = maybeMatch(a, str);
|
if (a instanceof RegExp) a = maybeMatch(a, str);
|
||||||
|
|||||||
@@ -2,49 +2,49 @@
|
|||||||
"_args": [
|
"_args": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"raw": "balanced-match@^0.4.1",
|
"raw": "balanced-match@^1.0.0",
|
||||||
"scope": null,
|
"scope": null,
|
||||||
"escapedName": "balanced-match",
|
"escapedName": "balanced-match",
|
||||||
"name": "balanced-match",
|
"name": "balanced-match",
|
||||||
"rawSpec": "^0.4.1",
|
"rawSpec": "^1.0.0",
|
||||||
"spec": ">=0.4.1 <0.5.0",
|
"spec": ">=1.0.0 <2.0.0",
|
||||||
"type": "range"
|
"type": "range"
|
||||||
},
|
},
|
||||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion"
|
"/Users/jbowser/cordova/cordova-android/node_modules/brace-expansion"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"_from": "balanced-match@>=0.4.1 <0.5.0",
|
"_from": "balanced-match@>=1.0.0 <2.0.0",
|
||||||
"_id": "balanced-match@0.4.2",
|
"_id": "balanced-match@1.0.0",
|
||||||
"_inCache": true,
|
"_inCache": true,
|
||||||
"_location": "/balanced-match",
|
"_location": "/balanced-match",
|
||||||
"_nodeVersion": "4.4.7",
|
"_nodeVersion": "7.8.0",
|
||||||
"_npmOperationalInternal": {
|
"_npmOperationalInternal": {
|
||||||
"host": "packages-16-east.internal.npmjs.com",
|
"host": "s3://npm-registry-packages",
|
||||||
"tmp": "tmp/balanced-match-0.4.2.tgz_1468834991581_0.6590619895141572"
|
"tmp": "tmp/balanced-match-1.0.0.tgz_1497251909645_0.8755026108119637"
|
||||||
},
|
},
|
||||||
"_npmUser": {
|
"_npmUser": {
|
||||||
"name": "juliangruber",
|
"name": "juliangruber",
|
||||||
"email": "julian@juliangruber.com"
|
"email": "julian@juliangruber.com"
|
||||||
},
|
},
|
||||||
"_npmVersion": "2.15.8",
|
"_npmVersion": "4.2.0",
|
||||||
"_phantomChildren": {},
|
"_phantomChildren": {},
|
||||||
"_requested": {
|
"_requested": {
|
||||||
"raw": "balanced-match@^0.4.1",
|
"raw": "balanced-match@^1.0.0",
|
||||||
"scope": null,
|
"scope": null,
|
||||||
"escapedName": "balanced-match",
|
"escapedName": "balanced-match",
|
||||||
"name": "balanced-match",
|
"name": "balanced-match",
|
||||||
"rawSpec": "^0.4.1",
|
"rawSpec": "^1.0.0",
|
||||||
"spec": ">=0.4.1 <0.5.0",
|
"spec": ">=1.0.0 <2.0.0",
|
||||||
"type": "range"
|
"type": "range"
|
||||||
},
|
},
|
||||||
"_requiredBy": [
|
"_requiredBy": [
|
||||||
"/brace-expansion"
|
"/brace-expansion"
|
||||||
],
|
],
|
||||||
"_resolved": "http://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
|
"_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
"_shasum": "cb3f3e3c732dc0f01ee70b403f302e61d7709838",
|
"_shasum": "89b4d199ab2bee49de164ea02b89ce462d71b767",
|
||||||
"_shrinkwrap": null,
|
"_shrinkwrap": null,
|
||||||
"_spec": "balanced-match@^0.4.1",
|
"_spec": "balanced-match@^1.0.0",
|
||||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion",
|
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/brace-expansion",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Julian Gruber",
|
"name": "Julian Gruber",
|
||||||
"email": "mail@juliangruber.com",
|
"email": "mail@juliangruber.com",
|
||||||
@@ -56,14 +56,15 @@
|
|||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"description": "Match balanced character pairs, like \"{\" and \"}\"",
|
"description": "Match balanced character pairs, like \"{\" and \"}\"",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"matcha": "^0.7.0",
|
||||||
"tape": "^4.6.0"
|
"tape": "^4.6.0"
|
||||||
},
|
},
|
||||||
"directories": {},
|
"directories": {},
|
||||||
"dist": {
|
"dist": {
|
||||||
"shasum": "cb3f3e3c732dc0f01ee70b403f302e61d7709838",
|
"shasum": "89b4d199ab2bee49de164ea02b89ce462d71b767",
|
||||||
"tarball": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz"
|
"tarball": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz"
|
||||||
},
|
},
|
||||||
"gitHead": "57c2ea29d89a2844ae3bdcc637c6e2cbb73725e2",
|
"gitHead": "d701a549a7653a874eebce7eca25d3577dc868ac",
|
||||||
"homepage": "https://github.com/juliangruber/balanced-match",
|
"homepage": "https://github.com/juliangruber/balanced-match",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"match",
|
"match",
|
||||||
@@ -88,6 +89,7 @@
|
|||||||
"url": "git://github.com/juliangruber/balanced-match.git"
|
"url": "git://github.com/juliangruber/balanced-match.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"bench": "make bench",
|
||||||
"test": "make test"
|
"test": "make test"
|
||||||
},
|
},
|
||||||
"testling": {
|
"testling": {
|
||||||
@@ -106,5 +108,5 @@
|
|||||||
"android-browser/4.2..latest"
|
"android-browser/4.2..latest"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"version": "0.4.2"
|
"version": "1.0.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"spec": "0.0.8",
|
"spec": "0.0.8",
|
||||||
"type": "version"
|
"type": "version"
|
||||||
},
|
},
|
||||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/plist"
|
"/Users/jbowser/cordova/cordova-android/node_modules/plist"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"_from": "base64-js@0.0.8",
|
"_from": "base64-js@0.0.8",
|
||||||
@@ -36,11 +36,11 @@
|
|||||||
"_requiredBy": [
|
"_requiredBy": [
|
||||||
"/plist"
|
"/plist"
|
||||||
],
|
],
|
||||||
"_resolved": "http://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
|
"_resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz",
|
||||||
"_shasum": "1101e9544f4a76b1bc3b26d452ca96d7a35e7978",
|
"_shasum": "1101e9544f4a76b1bc3b26d452ca96d7a35e7978",
|
||||||
"_shrinkwrap": null,
|
"_shrinkwrap": null,
|
||||||
"_spec": "base64-js@0.0.8",
|
"_spec": "base64-js@0.0.8",
|
||||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/plist",
|
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/plist",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "T. Jameson Little",
|
"name": "T. Jameson Little",
|
||||||
"email": "t.jameson.little@gmail.com"
|
"email": "t.jameson.little@gmail.com"
|
||||||
|
|||||||
@@ -1038,14 +1038,31 @@ var bigInt = (function (undefined) {
|
|||||||
}
|
}
|
||||||
var parseBase = function (text, base) {
|
var parseBase = function (text, base) {
|
||||||
var length = text.length;
|
var length = text.length;
|
||||||
|
var i;
|
||||||
|
var absBase = Math.abs(base);
|
||||||
|
for(var i = 0; i < length; i++) {
|
||||||
|
var c = text[i].toLowerCase();
|
||||||
|
if(c === "-") continue;
|
||||||
|
if(/[a-z0-9]/.test(c)) {
|
||||||
|
if(/[0-9]/.test(c) && +c >= absBase) {
|
||||||
|
if(c === "1" && absBase === 1) continue;
|
||||||
|
throw new Error(c + " is not a valid digit in base " + base + ".");
|
||||||
|
} else if(c.charCodeAt(0) - 87 >= absBase) {
|
||||||
|
throw new Error(c + " is not a valid digit in base " + base + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (2 <= base && base <= 36) {
|
if (2 <= base && base <= 36) {
|
||||||
if (length <= LOG_MAX_INT / Math.log(base)) {
|
if (length <= LOG_MAX_INT / Math.log(base)) {
|
||||||
|
var result = parseInt(text, base);
|
||||||
|
if(isNaN(result)) {
|
||||||
|
throw new Error(c + " is not a valid digit in base " + base + ".");
|
||||||
|
}
|
||||||
return new SmallInteger(parseInt(text, base));
|
return new SmallInteger(parseInt(text, base));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
base = parseValue(base);
|
base = parseValue(base);
|
||||||
var digits = [];
|
var digits = [];
|
||||||
var i;
|
|
||||||
var isNegative = text[0] === "-";
|
var isNegative = text[0] === "-";
|
||||||
for (i = isNegative ? 1 : 0; i < text.length; i++) {
|
for (i = isNegative ? 1 : 0; i < text.length; i++) {
|
||||||
var c = text[i].toLowerCase(),
|
var c = text[i].toLowerCase(),
|
||||||
@@ -1126,11 +1143,13 @@ var bigInt = (function (undefined) {
|
|||||||
var sign = this.sign ? "-" : "";
|
var sign = this.sign ? "-" : "";
|
||||||
return sign + str;
|
return sign + str;
|
||||||
};
|
};
|
||||||
|
|
||||||
SmallInteger.prototype.toString = function (radix) {
|
SmallInteger.prototype.toString = function (radix) {
|
||||||
if (radix === undefined) radix = 10;
|
if (radix === undefined) radix = 10;
|
||||||
if (radix != 10) return toBase(this, radix);
|
if (radix != 10) return toBase(this, radix);
|
||||||
return String(this.value);
|
return String(this.value);
|
||||||
};
|
};
|
||||||
|
BigInteger.prototype.toJSON = SmallInteger.prototype.toJSON = function() { return this.toString(); }
|
||||||
|
|
||||||
BigInteger.prototype.valueOf = function () {
|
BigInteger.prototype.valueOf = function () {
|
||||||
return +this.toString();
|
return +this.toString();
|
||||||
@@ -1227,7 +1246,7 @@ if (typeof module !== "undefined" && module.hasOwnProperty("exports")) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//amd check
|
//amd check
|
||||||
if ( typeof define === "function" && define.amd ) {
|
if ( typeof define === "function" && define.amd ) {
|
||||||
define( "big-integer", [], function() {
|
define( "big-integer", [], function() {
|
||||||
return bigInt;
|
return bigInt;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ Returns `true` if the number is prime, `false` otherwise.
|
|||||||
|
|
||||||
#### `isProbablePrime([iterations])`
|
#### `isProbablePrime([iterations])`
|
||||||
|
|
||||||
Returns `true` if the number is very likely to be positive, `false` otherwise.
|
Returns `true` if the number is very likely to be prime, `false` otherwise.
|
||||||
Argument is optional and determines the amount of iterations of the test (default: `5`). The more iterations, the lower chance of getting a false positive.
|
Argument is optional and determines the amount of iterations of the test (default: `5`). The more iterations, the lower chance of getting a false positive.
|
||||||
This uses the [Fermat primality test](https://en.wikipedia.org/wiki/Fermat_primality_test).
|
This uses the [Fermat primality test](https://en.wikipedia.org/wiki/Fermat_primality_test).
|
||||||
|
|
||||||
@@ -517,4 +517,4 @@ There are performance benchmarks that can be viewed from the `benchmarks/index.h
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is public domain. For more details, read about the [Unlicense](http://unlicense.org/).
|
This project is public domain. For more details, read about the [Unlicense](http://unlicense.org/).
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
"bower_components",
|
"bower_components",
|
||||||
"test",
|
"test",
|
||||||
"coverage",
|
"coverage",
|
||||||
"spec",
|
|
||||||
"tests"
|
"tests"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,17 +10,17 @@
|
|||||||
"spec": ">=1.6.7 <2.0.0",
|
"spec": ">=1.6.7 <2.0.0",
|
||||||
"type": "range"
|
"type": "range"
|
||||||
},
|
},
|
||||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/bplist-parser"
|
"/Users/jbowser/cordova/cordova-android/node_modules/bplist-parser"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"_from": "big-integer@>=1.6.7 <2.0.0",
|
"_from": "big-integer@>=1.6.7 <2.0.0",
|
||||||
"_id": "big-integer@1.6.22",
|
"_id": "big-integer@1.6.25",
|
||||||
"_inCache": true,
|
"_inCache": true,
|
||||||
"_location": "/big-integer",
|
"_location": "/big-integer",
|
||||||
"_nodeVersion": "6.9.4",
|
"_nodeVersion": "6.10.3",
|
||||||
"_npmOperationalInternal": {
|
"_npmOperationalInternal": {
|
||||||
"host": "packages-12-west.internal.npmjs.com",
|
"host": "s3://npm-registry-packages",
|
||||||
"tmp": "tmp/big-integer-1.6.22.tgz_1493091323169_0.5048394540790468"
|
"tmp": "tmp/big-integer-1.6.25.tgz_1504748727289_0.9231066561769694"
|
||||||
},
|
},
|
||||||
"_npmUser": {
|
"_npmUser": {
|
||||||
"name": "peterolson",
|
"name": "peterolson",
|
||||||
@@ -40,11 +40,11 @@
|
|||||||
"_requiredBy": [
|
"_requiredBy": [
|
||||||
"/bplist-parser"
|
"/bplist-parser"
|
||||||
],
|
],
|
||||||
"_resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.22.tgz",
|
"_resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.25.tgz",
|
||||||
"_shasum": "487c95fce886022ea48ff5f19e388932df46dd2e",
|
"_shasum": "1de45a9f57542ac20121c682f8d642220a34e823",
|
||||||
"_shrinkwrap": null,
|
"_shrinkwrap": null,
|
||||||
"_spec": "big-integer@^1.6.7",
|
"_spec": "big-integer@^1.6.7",
|
||||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/bplist-parser",
|
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/bplist-parser",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Peter Olson",
|
"name": "Peter Olson",
|
||||||
"email": "peter.e.c.olson+npm@gmail.com"
|
"email": "peter.e.c.olson+npm@gmail.com"
|
||||||
@@ -57,24 +57,28 @@
|
|||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"description": "An arbitrary length integer library for Javascript",
|
"description": "An arbitrary length integer library for Javascript",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/lodash": "^4.14.64",
|
||||||
|
"@types/node": "^7.0.22",
|
||||||
"coveralls": "^2.11.4",
|
"coveralls": "^2.11.4",
|
||||||
"jasmine": "2.1.x",
|
"jasmine": "2.1.x",
|
||||||
"jasmine-core": "^2.3.4",
|
"jasmine-core": "^2.3.4",
|
||||||
"karma": "^0.13.3",
|
"karma": "^0.13.3",
|
||||||
"karma-coverage": "^0.4.2",
|
"karma-coverage": "^0.4.2",
|
||||||
"karma-jasmine": "^0.3.6",
|
"karma-jasmine": "^0.3.6",
|
||||||
"karma-phantomjs-launcher": "~0.1",
|
"karma-phantomjs-launcher": "^1.0.4",
|
||||||
|
"lodash": "^4.17.4",
|
||||||
|
"typescript": "^2.3.3",
|
||||||
"uglifyjs": "^2.4.10"
|
"uglifyjs": "^2.4.10"
|
||||||
},
|
},
|
||||||
"directories": {},
|
"directories": {},
|
||||||
"dist": {
|
"dist": {
|
||||||
"shasum": "487c95fce886022ea48ff5f19e388932df46dd2e",
|
"shasum": "1de45a9f57542ac20121c682f8d642220a34e823",
|
||||||
"tarball": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.22.tgz"
|
"tarball": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.25.tgz"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.6"
|
"node": ">=0.6"
|
||||||
},
|
},
|
||||||
"gitHead": "40483b881b4380931e5af6f2f8a161b6caa71690",
|
"gitHead": "a0c10d68aae8f5df56a67b3e3eb353b428abf170",
|
||||||
"homepage": "https://github.com/peterolson/BigInteger.js#readme",
|
"homepage": "https://github.com/peterolson/BigInteger.js#readme",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"math",
|
"math",
|
||||||
@@ -104,7 +108,8 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"minify": "uglifyjs BigInteger.js -o BigInteger.min.js",
|
"minify": "uglifyjs BigInteger.js -o BigInteger.min.js",
|
||||||
"test": "karma start my.conf.js"
|
"test": "tsc && node_modules/.bin/karma start my.conf.js && node spec/tsDefinitions.js"
|
||||||
},
|
},
|
||||||
"version": "1.6.22"
|
"typings": "./BigInteger.d.ts",
|
||||||
|
"version": "1.6.25"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"lib": [
|
||||||
|
"es6"
|
||||||
|
],
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"strictNullChecks": false,
|
||||||
|
"baseUrl": "./",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"allowJs": true,
|
||||||
|
"typeRoots": [
|
||||||
|
"./"
|
||||||
|
],
|
||||||
|
"types": [
|
||||||
|
"node"
|
||||||
|
],
|
||||||
|
"forceConsistentCasingInFileNames": true
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"BigInteger.d.ts",
|
||||||
|
"spec/tsDefinitions.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
"spec": ">=0.1.0 <0.2.0",
|
"spec": ">=0.1.0 <0.2.0",
|
||||||
"type": "range"
|
"type": "range"
|
||||||
},
|
},
|
||||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common"
|
"/Users/jbowser/cordova/cordova-android/node_modules/cordova-common"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"_from": "bplist-parser@>=0.1.0 <0.2.0",
|
"_from": "bplist-parser@>=0.1.0 <0.2.0",
|
||||||
@@ -36,11 +36,11 @@
|
|||||||
"_requiredBy": [
|
"_requiredBy": [
|
||||||
"/cordova-common"
|
"/cordova-common"
|
||||||
],
|
],
|
||||||
"_resolved": "http://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz",
|
"_resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz",
|
||||||
"_shasum": "d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6",
|
"_shasum": "d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6",
|
||||||
"_shrinkwrap": null,
|
"_shrinkwrap": null,
|
||||||
"_spec": "bplist-parser@^0.1.0",
|
"_spec": "bplist-parser@^0.1.0",
|
||||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/cordova-common",
|
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/cordova-common",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Joe Ferner",
|
"name": "Joe Ferner",
|
||||||
"email": "joe.ferner@nearinfinity.com"
|
"email": "joe.ferner@nearinfinity.com"
|
||||||
|
|||||||
@@ -2,25 +2,25 @@
|
|||||||
"_args": [
|
"_args": [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"raw": "brace-expansion@^1.0.0",
|
"raw": "brace-expansion@^1.1.7",
|
||||||
"scope": null,
|
"scope": null,
|
||||||
"escapedName": "brace-expansion",
|
"escapedName": "brace-expansion",
|
||||||
"name": "brace-expansion",
|
"name": "brace-expansion",
|
||||||
"rawSpec": "^1.0.0",
|
"rawSpec": "^1.1.7",
|
||||||
"spec": ">=1.0.0 <2.0.0",
|
"spec": ">=1.1.7 <2.0.0",
|
||||||
"type": "range"
|
"type": "range"
|
||||||
},
|
},
|
||||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/minimatch"
|
"/Users/jbowser/cordova/cordova-android/node_modules/minimatch"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"_from": "brace-expansion@>=1.0.0 <2.0.0",
|
"_from": "brace-expansion@>=1.1.7 <2.0.0",
|
||||||
"_id": "brace-expansion@1.1.7",
|
"_id": "brace-expansion@1.1.8",
|
||||||
"_inCache": true,
|
"_inCache": true,
|
||||||
"_location": "/brace-expansion",
|
"_location": "/brace-expansion",
|
||||||
"_nodeVersion": "7.8.0",
|
"_nodeVersion": "7.8.0",
|
||||||
"_npmOperationalInternal": {
|
"_npmOperationalInternal": {
|
||||||
"host": "packages-12-west.internal.npmjs.com",
|
"host": "s3://npm-registry-packages",
|
||||||
"tmp": "tmp/brace-expansion-1.1.7.tgz_1491552830231_0.7213963181711733"
|
"tmp": "tmp/brace-expansion-1.1.8.tgz_1497251980593_0.6575565172825009"
|
||||||
},
|
},
|
||||||
"_npmUser": {
|
"_npmUser": {
|
||||||
"name": "juliangruber",
|
"name": "juliangruber",
|
||||||
@@ -29,22 +29,22 @@
|
|||||||
"_npmVersion": "4.2.0",
|
"_npmVersion": "4.2.0",
|
||||||
"_phantomChildren": {},
|
"_phantomChildren": {},
|
||||||
"_requested": {
|
"_requested": {
|
||||||
"raw": "brace-expansion@^1.0.0",
|
"raw": "brace-expansion@^1.1.7",
|
||||||
"scope": null,
|
"scope": null,
|
||||||
"escapedName": "brace-expansion",
|
"escapedName": "brace-expansion",
|
||||||
"name": "brace-expansion",
|
"name": "brace-expansion",
|
||||||
"rawSpec": "^1.0.0",
|
"rawSpec": "^1.1.7",
|
||||||
"spec": ">=1.0.0 <2.0.0",
|
"spec": ">=1.1.7 <2.0.0",
|
||||||
"type": "range"
|
"type": "range"
|
||||||
},
|
},
|
||||||
"_requiredBy": [
|
"_requiredBy": [
|
||||||
"/minimatch"
|
"/minimatch"
|
||||||
],
|
],
|
||||||
"_resolved": "http://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz",
|
"_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
|
||||||
"_shasum": "3effc3c50e000531fb720eaff80f0ae8ef23cf59",
|
"_shasum": "c07b211c7c952ec1f8efd51a77ef0d1d3990a292",
|
||||||
"_shrinkwrap": null,
|
"_shrinkwrap": null,
|
||||||
"_spec": "brace-expansion@^1.0.0",
|
"_spec": "brace-expansion@^1.1.7",
|
||||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/minimatch",
|
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/minimatch",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Julian Gruber",
|
"name": "Julian Gruber",
|
||||||
"email": "mail@juliangruber.com",
|
"email": "mail@juliangruber.com",
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
"url": "https://github.com/juliangruber/brace-expansion/issues"
|
"url": "https://github.com/juliangruber/brace-expansion/issues"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^0.4.1",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
},
|
},
|
||||||
"description": "Brace expansion as known from sh/bash",
|
"description": "Brace expansion as known from sh/bash",
|
||||||
@@ -64,10 +64,10 @@
|
|||||||
},
|
},
|
||||||
"directories": {},
|
"directories": {},
|
||||||
"dist": {
|
"dist": {
|
||||||
"shasum": "3effc3c50e000531fb720eaff80f0ae8ef23cf59",
|
"shasum": "c07b211c7c952ec1f8efd51a77ef0d1d3990a292",
|
||||||
"tarball": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz"
|
"tarball": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz"
|
||||||
},
|
},
|
||||||
"gitHead": "892512024872ca7680554be90f6e8ce065053372",
|
"gitHead": "8f59e68bd5c915a0d624e8e39354e1ccf672edf6",
|
||||||
"homepage": "https://github.com/juliangruber/brace-expansion",
|
"homepage": "https://github.com/juliangruber/brace-expansion",
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -110,5 +110,5 @@
|
|||||||
"android-browser/4.2..latest"
|
"android-browser/4.2..latest"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"version": "1.1.7"
|
"version": "1.1.8"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"spec": "0.0.1",
|
"spec": "0.0.1",
|
||||||
"type": "version"
|
"type": "version"
|
||||||
},
|
},
|
||||||
"/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion"
|
"/Users/jbowser/cordova/cordova-android/node_modules/brace-expansion"
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"_from": "concat-map@0.0.1",
|
"_from": "concat-map@0.0.1",
|
||||||
@@ -35,11 +35,11 @@
|
|||||||
"_requiredBy": [
|
"_requiredBy": [
|
||||||
"/brace-expansion"
|
"/brace-expansion"
|
||||||
],
|
],
|
||||||
"_resolved": "http://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"_resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
"_shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b",
|
"_shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b",
|
||||||
"_shrinkwrap": null,
|
"_shrinkwrap": null,
|
||||||
"_spec": "concat-map@0.0.1",
|
"_spec": "concat-map@0.0.1",
|
||||||
"_where": "/Users/steveng/repo/cordova/cordova-android/node_modules/brace-expansion",
|
"_where": "/Users/jbowser/cordova/cordova-android/node_modules/brace-expansion",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "James Halliday",
|
"name": "James Halliday",
|
||||||
"email": "mail@substack.net",
|
"email": "mail@substack.net",
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
spec/fixtures/*
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
root: true
|
||||||
|
extends: semistandard
|
||||||
|
rules:
|
||||||
|
indent:
|
||||||
|
- error
|
||||||
|
- 4
|
||||||
|
camelcase: off
|
||||||
|
padded-blocks: off
|
||||||
|
operator-linebreak: off
|
||||||
|
no-throw-literal: off
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
spec/fixtures/*
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
fixtures
|
fixtures
|
||||||
coverage
|
coverage
|
||||||
jasmine.json
|
jasmine.json
|
||||||
|
appveyor.yml
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
language: node_js
|
||||||
|
sudo: false
|
||||||
|
git:
|
||||||
|
depth: 10
|
||||||
|
node_js:
|
||||||
|
- "4"
|
||||||
|
- "6"
|
||||||
|
install:
|
||||||
|
- npm install
|
||||||
|
- npm install -g codecov
|
||||||
|
script:
|
||||||
|
- npm test
|
||||||
|
- npm run cover
|
||||||
|
after_script:
|
||||||
|
- codecov
|
||||||
@@ -19,6 +19,10 @@
|
|||||||
#
|
#
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
[](https://ci.appveyor.com/project/ApacheSoftwareFoundation/cordova-common/branch/master)
|
||||||
|
[](https://travis-ci.org/apache/cordova-common)
|
||||||
|
[](https://nodei.co/npm/cordova-common/)
|
||||||
|
|
||||||
# cordova-common
|
# cordova-common
|
||||||
Expoeses shared functionality used by [cordova-lib](https://github.com/apache/cordova-lib/) and Cordova platforms.
|
Expoeses shared functionality used by [cordova-lib](https://github.com/apache/cordova-lib/) and Cordova platforms.
|
||||||
## Exposed APIs
|
## Exposed APIs
|
||||||
|
|||||||
@@ -20,6 +20,21 @@
|
|||||||
-->
|
-->
|
||||||
# Cordova-common Release Notes
|
# Cordova-common Release Notes
|
||||||
|
|
||||||
|
### 2.1.0 (August 30, 2017)
|
||||||
|
* [CB-13145](https://issues.apache.org/jira/browse/CB-13145) added variable replacing to `framework` tag
|
||||||
|
* [CB-13211](https://issues.apache.org/jira/browse/CB-13211) Add `allows-arbitrary-loads-for-media` attribute parsing for `getAccesses`
|
||||||
|
* [CB-11968](https://issues.apache.org/jira/browse/CB-11968) Added support for `<config-file>` in `config.xml`
|
||||||
|
* [CB-12895](https://issues.apache.org/jira/browse/CB-12895) set up `eslint` and removed `jshint`
|
||||||
|
* [CB-12785](https://issues.apache.org/jira/browse/CB-12785) added `.gitignore`, `travis`, and `appveyor` support
|
||||||
|
* [CB-12250](https://issues.apache.org/jira/browse/CB-12250) & [CB-12409](https://issues.apache.org/jira/browse/CB-12409) *iOS*: Fix bug with escaping properties from `plist` file
|
||||||
|
* [CB-12762](https://issues.apache.org/jira/browse/CB-12762) updated `common`, `fetch`, and `serve` `pkgJson` to point `pkgJson` repo items to github mirrors
|
||||||
|
* [CB-12766](https://issues.apache.org/jira/browse/CB-12766) Consistently write `JSON` with 2 spaces indentation
|
||||||
|
|
||||||
|
### 2.0.3 (May 02, 2017)
|
||||||
|
* [CB-8978](https://issues.apache.org/jira/browse/CB-8978) Add option to get `resource-file` from `root`
|
||||||
|
* [CB-11908](https://issues.apache.org/jira/browse/CB-11908) Add tests for `edit-config` in `config.xml`
|
||||||
|
* [CB-12665](https://issues.apache.org/jira/browse/CB-12665) removed `enginestrict` since it is deprecated
|
||||||
|
|
||||||
### 2.0.2 (Apr 14, 2017)
|
### 2.0.2 (Apr 14, 2017)
|
||||||
* [CB-11233](https://issues.apache.org/jira/browse/CB-11233) - Support installing frameworks into 'Embedded Binaries' section of the Xcode project
|
* [CB-11233](https://issues.apache.org/jira/browse/CB-11233) - Support installing frameworks into 'Embedded Binaries' section of the Xcode project
|
||||||
* [CB-10438](https://issues.apache.org/jira/browse/CB-10438) - Install correct dependency version. Removed shell.remove, added pkg.json to dependency tests 1-3, and updated install.js (.replace) to fix tests in uninstall.spec.js and update to workw with jasmine 2.0
|
* [CB-10438](https://issues.apache.org/jira/browse/CB-10438) - Install correct dependency version. Removed shell.remove, added pkg.json to dependency tests 1-3, and updated install.js (.replace) to fix tests in uninstall.spec.js and update to workw with jasmine 2.0
|
||||||
|
|||||||