Compare commits
166 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1f472297a | ||
|
|
030af05839 | ||
|
|
7e8b47d012 | ||
|
|
902aa32dda | ||
|
|
42c0cba7f7 | ||
|
|
f2b84d8d83 | ||
|
|
1b11206174 | ||
|
|
c93e3e9f6f | ||
|
|
9808a0d4d3 | ||
|
|
bd1697dbd2 | ||
|
|
b3b8690bbd | ||
|
|
ad742ec93c | ||
|
|
1de7c38134 | ||
|
|
997943a194 | ||
|
|
47c6048d53 | ||
|
|
a64d459c8e | ||
|
|
a5ad440f17 | ||
|
|
acad24d62a | ||
|
|
989b4cc913 | ||
|
|
38c6627999 | ||
|
|
4b9e18c6b8 | ||
|
|
906f8cc002 | ||
|
|
01ab11644c | ||
|
|
4cf3dcfaae | ||
|
|
b177f84825 | ||
|
|
485e6e0e4d | ||
|
|
516c3411aa | ||
|
|
908354e7fa | ||
|
|
9531dbbc7b | ||
|
|
d10dd1c0b4 | ||
|
|
6533474070 | ||
|
|
576edb53bb | ||
|
|
20e390af85 | ||
|
|
931251a5a8 | ||
|
|
9697550488 | ||
|
|
3dac984613 | ||
|
|
867da56e2e | ||
|
|
719acd3ab1 | ||
|
|
549cae0a06 | ||
|
|
bb45f4f3ba | ||
|
|
b4de6f55c4 | ||
|
|
e99c145d55 | ||
|
|
9cb9f32fbb | ||
|
|
a6f30b6977 | ||
|
|
73692e60d8 | ||
|
|
4abe3d3a49 | ||
|
|
54df4a116c | ||
|
|
715ce2f9ac | ||
|
|
7a98708eef | ||
|
|
d9c08f12a7 | ||
|
|
e41fbc5708 | ||
|
|
634f92efb6 | ||
|
|
98a7b759e8 | ||
|
|
3976685e4e | ||
|
|
f7688bc64e | ||
|
|
18e28294d6 | ||
|
|
39bd0d6463 | ||
|
|
c1819cc027 | ||
|
|
f228d90ca2 | ||
|
|
5f44af3757 | ||
|
|
8a4ae311ce | ||
|
|
ef2434188e | ||
|
|
a014228f7c | ||
|
|
2163c8ae05 | ||
|
|
47bb5184a0 | ||
|
|
f1f1ac3cbd | ||
|
|
f1396c7aad | ||
|
|
21ae48eada | ||
|
|
53e1c1b65c | ||
|
|
858611f95e | ||
|
|
5c334b6c10 | ||
|
|
cf5a02ea0f | ||
|
|
a67bc75b93 | ||
|
|
895ab0c970 | ||
|
|
21f84732c8 | ||
|
|
7eed65e9b4 | ||
|
|
cf5915ad01 | ||
|
|
a4caa87d29 | ||
|
|
bbb3913a36 | ||
|
|
92f07d0418 | ||
|
|
578a642209 | ||
|
|
9d03e4ec0a | ||
|
|
576ad183e7 | ||
|
|
e31596f60e | ||
|
|
ef493b4c0f | ||
|
|
c15312ee70 | ||
|
|
3caefcae49 | ||
|
|
c2f6631f91 | ||
|
|
fb1dfb27df | ||
|
|
898a6a8d8d | ||
|
|
7da53741cd | ||
|
|
47aabc631d | ||
|
|
fb75ac371d | ||
|
|
98c866704a | ||
|
|
e58453d3e6 | ||
|
|
03c62e1ce2 | ||
|
|
2c10545cd8 | ||
|
|
ff2ec7eed1 | ||
|
|
8dfddef6f9 | ||
|
|
73edf4de7b | ||
|
|
cfa58a5661 | ||
|
|
905bff3d59 | ||
|
|
eadcd33e84 | ||
|
|
76fe89dd1f | ||
|
|
3f487c5c28 | ||
|
|
c35a46ec45 | ||
|
|
e3eb933182 | ||
|
|
dacb0e5c72 | ||
|
|
23b24491c3 | ||
|
|
7ab0cf123d | ||
|
|
8f2a4c7231 | ||
|
|
ce53154555 | ||
|
|
c0188ab95a | ||
|
|
ebbd91f87d | ||
|
|
4b0725dfc2 | ||
|
|
350d35fb24 | ||
|
|
8ee3a73dd1 | ||
|
|
b6e4598e7c | ||
|
|
bd2ad99402 | ||
|
|
d26c1199ab | ||
|
|
1ea7c1366a | ||
|
|
b2263fe35e | ||
|
|
bd07907a4c | ||
|
|
ca8931c8af | ||
|
|
46a036ef26 | ||
|
|
e9750b5cab | ||
|
|
0bf0e48698 | ||
|
|
4f1aa97ea9 | ||
|
|
f90f004dea | ||
|
|
559b0833b4 | ||
|
|
31bad290d5 | ||
|
|
2e88f7ead2 | ||
|
|
1a8154c90e | ||
|
|
8fb49ec7ec | ||
|
|
393dad6349 | ||
|
|
2c3db19310 | ||
|
|
472ab626d6 | ||
|
|
2106e2e081 | ||
|
|
d3c80ea5d5 | ||
|
|
6dad25668c | ||
|
|
d862d42e76 | ||
|
|
828b5f053a | ||
|
|
032d1fa9cb | ||
|
|
83ad646734 | ||
|
|
88c25a6a6a | ||
|
|
a254cfc841 | ||
|
|
0d4b9f4ba6 | ||
|
|
bf29fe0e10 | ||
|
|
3df8f8b120 | ||
|
|
38d0e684f1 | ||
|
|
83e9aefff5 | ||
|
|
02ee925103 | ||
|
|
fc69da7a42 | ||
|
|
5dc179ebef | ||
|
|
59e3b907e9 | ||
|
|
fe7629e8fc | ||
|
|
76180d3ea1 | ||
|
|
5c4f8ca246 | ||
|
|
b8530a6b70 | ||
|
|
83686542b2 | ||
|
|
b1551cad98 | ||
|
|
5af6b016c1 | ||
|
|
6abd6d6b47 | ||
|
|
e456a325f9 | ||
|
|
eddad666ff | ||
|
|
ca9a25e860 |
@@ -1 +1,2 @@
|
||||
bin/templates/project/assets/www/cordova.js
|
||||
bin/templates/project/assets/www/cordova.js
|
||||
test/app
|
||||
|
||||
42
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<!--
|
||||
Please have a look at the issue templates you get when you click "New issue" in the GitHub UI.
|
||||
We very much prefer issues created by using one of these templates.
|
||||
-->
|
||||
|
||||
### Issue Type
|
||||
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
|
||||
|
||||
- [ ] Bug Report
|
||||
- [ ] Feature Request
|
||||
- [ ] Support Question
|
||||
|
||||
## Description
|
||||
|
||||
## Information
|
||||
<!-- Include all relevant information that might help understand and reproduce the problem -->
|
||||
|
||||
### Command or Code
|
||||
<!-- What command or code is needed to reproduce the problem? -->
|
||||
|
||||
### Environment, Platform, Device
|
||||
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->
|
||||
|
||||
|
||||
|
||||
### Version information
|
||||
<!--
|
||||
What are relevant versions you are using?
|
||||
For example:
|
||||
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
|
||||
Other Frameworks: Ionic Framework and CLI version
|
||||
Operating System, Android Studio, Xcode etc.
|
||||
-->
|
||||
|
||||
|
||||
|
||||
## Checklist
|
||||
<!-- Please check the boxes by putting an `x` in the `[ ]` like so: `[x]` -->
|
||||
|
||||
- [ ] I searched for already existing GitHub issues about this
|
||||
- [ ] I updated all Cordova tooling to their most recent version
|
||||
- [ ] I included all the necessary information above
|
||||
50
.github/ISSUE_TEMPLATE/BUG_REPORT.md
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
name: 🐛 Bug Report
|
||||
about: If something isn't working as expected.
|
||||
|
||||
---
|
||||
|
||||
# Bug Report
|
||||
|
||||
## Problem
|
||||
|
||||
### What is expected to happen?
|
||||
|
||||
|
||||
|
||||
### What does actually happen?
|
||||
|
||||
|
||||
|
||||
## Information
|
||||
<!-- Include all relevant information that might help understand and reproduce the problem -->
|
||||
|
||||
|
||||
|
||||
### Command or Code
|
||||
<!-- What command or code is needed to reproduce the problem? -->
|
||||
|
||||
|
||||
|
||||
### Environment, Platform, Device
|
||||
<!-- In what environment, on what platform or on which device are you experiencing the issue? -->
|
||||
|
||||
|
||||
|
||||
### Version information
|
||||
<!--
|
||||
What are relevant versions you are using?
|
||||
For example:
|
||||
Cordova: Cordova CLI, Cordova Platforms, Cordova Plugins
|
||||
Other Frameworks: Ionic Framework and CLI version
|
||||
Operating System, Android Studio, Xcode etc.
|
||||
-->
|
||||
|
||||
|
||||
|
||||
## Checklist
|
||||
<!-- Please check the boxes by putting an x in the [ ] like so: [x] -->
|
||||
|
||||
- [ ] I searched for existing GitHub issues
|
||||
- [ ] I updated all Cordova tooling to most recent version
|
||||
- [ ] I included all the necessary information above
|
||||
29
.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: 🚀 Feature Request
|
||||
about: A suggestion for a new functionality
|
||||
|
||||
---
|
||||
|
||||
# Feature Request
|
||||
|
||||
## Motivation Behind Feature
|
||||
<!-- Why should this feature be implemented? What problem does it solve? -->
|
||||
|
||||
|
||||
|
||||
## Feature Description
|
||||
<!--
|
||||
Describe your feature request in detail
|
||||
Please provide any code examples or screenshots of what this feature would look like
|
||||
Are there any drawbacks? Will this break anything for existing users?
|
||||
-->
|
||||
|
||||
|
||||
|
||||
## Alternatives or Workarounds
|
||||
<!--
|
||||
Describe alternatives or workarounds you are currently using
|
||||
Are there ways to do this with existing functionality?
|
||||
-->
|
||||
|
||||
|
||||
27
.github/ISSUE_TEMPLATE/SUPPORT_QUESTION.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
name: 💬 Support Question
|
||||
about: If you have a question, please check out our Slack or StackOverflow!
|
||||
|
||||
---
|
||||
|
||||
<!------------^ Click "Preview" for a nicer view! -->
|
||||
|
||||
Apache Cordova uses GitHub Issues as a feature request and bug tracker _only_.
|
||||
For usage and support questions, please check out the resources below. Thanks!
|
||||
|
||||
---
|
||||
|
||||
You can get answers to your usage and support questions about **Apache Cordova** on:
|
||||
|
||||
* Slack Community Chat: https://cordova.slack.com (you can sign-up at http://slack.cordova.io/)
|
||||
* StackOverflow: https://stackoverflow.com/questions/tagged/cordova using the tag `cordova`
|
||||
|
||||
---
|
||||
|
||||
If you are using a tool that uses Cordova internally, like e.g. Ionic, check their support channels:
|
||||
|
||||
* **Ionic Framework**
|
||||
* [Ionic Community Forum](https://forum.ionicframework.com/)
|
||||
* [Ionic Worldwide Slack](https://ionicworldwide.herokuapp.com/)
|
||||
* **PhoneGap**
|
||||
* [PhoneGap Developer Community](https://forums.adobe.com/community/phonegap)
|
||||
27
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,6 +1,5 @@
|
||||
<!--
|
||||
Please make sure the checklist boxes are all checked before submitting the PR. The checklist
|
||||
is intended as a quick reference, for complete details please see our Contributor Guidelines:
|
||||
Please make sure the checklist boxes are all checked before submitting the PR. The checklist is intended as a quick reference, for complete details please see our Contributor Guidelines:
|
||||
|
||||
http://cordova.apache.org/contribute/contribute_guidelines.html
|
||||
|
||||
@@ -10,13 +9,27 @@ Thanks!
|
||||
### Platforms affected
|
||||
|
||||
|
||||
### What does this PR do?
|
||||
|
||||
### Motivation and Context
|
||||
<!-- Why is this change required? What problem does it solve? -->
|
||||
<!-- If it fixes an open issue, please link to the issue here. -->
|
||||
|
||||
|
||||
### What testing has been done on this change?
|
||||
|
||||
### Description
|
||||
<!-- Describe your changes in detail -->
|
||||
|
||||
|
||||
|
||||
### Testing
|
||||
<!-- Please describe in detail how you tested your changes. -->
|
||||
|
||||
|
||||
|
||||
### Checklist
|
||||
- [ ] [Reported an issue](http://cordova.apache.org/contribute/issues.html) in the JIRA database
|
||||
- [ ] Commit message follows the format: "CB-3232: (android) Fix bug with resolving file paths", where CB-xxxx is the JIRA ID & "android" is the platform affected.
|
||||
- [ ] Added automated test coverage as appropriate for this change.
|
||||
|
||||
- [ ] I've run the tests to see all new and existing tests pass
|
||||
- [ ] I added automated test coverage as appropriate for this change
|
||||
- [ ] Commit is prefixed with `(platform)` if this change only applies to one platform (e.g. `(android)`)
|
||||
- [ ] If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct [keyword to close issues using keywords](https://help.github.com/articles/closing-issues-using-keywords/))
|
||||
- [ ] I've updated the documentation if necessary
|
||||
|
||||
95
.gitignore
vendored
@@ -26,7 +26,6 @@ example
|
||||
/framework/javadoc-public
|
||||
/framework/javadoc-private
|
||||
/test/.externalNativeBuild
|
||||
/test/build.gradle
|
||||
/test/gradle
|
||||
/test/gradlew
|
||||
/test/gradlew.bat
|
||||
@@ -43,93 +42,7 @@ tmp/**/*
|
||||
**/.idea/**/*
|
||||
*.iml
|
||||
npm-debug.log
|
||||
node_modules/jshint
|
||||
node_modules/promise-matchers
|
||||
node_modules/jasmine
|
||||
node_modules/rewire
|
||||
node_modules/istanbul
|
||||
node_modules/.bin/cake
|
||||
node_modules/.bin/coffee
|
||||
node_modules/.bin/escodegen
|
||||
node_modules/.bin/esgenerate
|
||||
node_modules/.bin/esparse
|
||||
node_modules/.bin/esvalidate
|
||||
node_modules/.bin/handlebars
|
||||
node_modules/.bin/istanbul
|
||||
node_modules/.bin/jasmine
|
||||
node_modules/.bin/js-yaml
|
||||
node_modules/.bin/jshint
|
||||
node_modules/.bin/mkdirp
|
||||
node_modules/.bin/r.js
|
||||
node_modules/.bin/r_js
|
||||
node_modules/.bin/strip-json-comments
|
||||
node_modules/.bin/uglifyjs
|
||||
node_modules/.bin/which
|
||||
node_modules/align-text/
|
||||
node_modules/amdefine/
|
||||
node_modules/argparse/
|
||||
node_modules/async/
|
||||
node_modules/camelcase/
|
||||
node_modules/center-align/
|
||||
node_modules/cli/
|
||||
node_modules/cliui/
|
||||
node_modules/coffee-script/
|
||||
node_modules/console-browserify/
|
||||
node_modules/core-util-is/
|
||||
node_modules/date-now/
|
||||
node_modules/decamelize/
|
||||
node_modules/deep-is/
|
||||
node_modules/dom-serializer/
|
||||
node_modules/domelementtype/
|
||||
node_modules/domhandler/
|
||||
node_modules/domutils/
|
||||
node_modules/entities/
|
||||
node_modules/escodegen/
|
||||
node_modules/esprima/
|
||||
node_modules/estraverse/
|
||||
node_modules/esutils/
|
||||
node_modules/exit/
|
||||
node_modules/fast-levenshtein/
|
||||
node_modules/fileset/
|
||||
node_modules/gaze/
|
||||
node_modules/growl/
|
||||
node_modules/handlebars/
|
||||
node_modules/has-flag/
|
||||
node_modules/htmlparser2/
|
||||
node_modules/is-buffer/
|
||||
node_modules/isarray/
|
||||
node_modules/isexe/
|
||||
node_modules/jasmine-growl-reporter/
|
||||
node_modules/jasmine-reporters/
|
||||
node_modules/js-yaml/
|
||||
node_modules/kind-of/
|
||||
node_modules/lazy-cache/
|
||||
node_modules/levn/
|
||||
node_modules/longest/
|
||||
node_modules/lru-cache/
|
||||
node_modules/minimist/
|
||||
node_modules/mkdirp/
|
||||
node_modules/optimist/
|
||||
node_modules/optionator/
|
||||
node_modules/prelude-ls/
|
||||
node_modules/readable-stream/
|
||||
node_modules/repeat-string/
|
||||
node_modules/requirejs/
|
||||
node_modules/resolve/
|
||||
node_modules/right-align/
|
||||
node_modules/sigmund/
|
||||
node_modules/source-map/
|
||||
node_modules/sprintf-js/
|
||||
node_modules/string_decoder/
|
||||
node_modules/strip-json-comments/
|
||||
node_modules/supports-color/
|
||||
node_modules/type-check/
|
||||
node_modules/uglify-js/
|
||||
node_modules/uglify-to-browserify/
|
||||
node_modules/walkdir/
|
||||
node_modules/which/
|
||||
node_modules/window-size/
|
||||
node_modules/wordwrap/
|
||||
node_modules/yargs/
|
||||
node_modules/jasmine-core/
|
||||
node_modules/fs.realpath/
|
||||
node_modules/
|
||||
coverage/
|
||||
.nyc_output/
|
||||
package-lock.json
|
||||
|
||||
64
.travis.yml
@@ -1,28 +1,48 @@
|
||||
language: android
|
||||
sudo: false
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
|
||||
# NOTE: dist is added here to ensure that Travis CI works consistently
|
||||
# on Node.js 12. It is desired to remove it once this issue is resolved
|
||||
# or otherwise goes away.
|
||||
dist: trusty
|
||||
|
||||
env:
|
||||
global:
|
||||
- ANDROID_TOOLS=${ANDROID_HOME}/tools
|
||||
before_install:
|
||||
- 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
|
||||
- gradle --version
|
||||
- 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
|
||||
global:
|
||||
- ANDROID_API_LEVEL=28
|
||||
- ANDROID_BUILD_TOOLS_VERSION=28.0.3
|
||||
- TERM=dumb # Keep gradle from crapping all over the log
|
||||
matrix:
|
||||
- nodejs_version=6
|
||||
- nodejs_version=8
|
||||
- nodejs_version=10
|
||||
- nodejs_version=12
|
||||
|
||||
language: android
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
|
||||
android:
|
||||
components:
|
||||
- tools
|
||||
components:
|
||||
- tools
|
||||
- build-tools-$ANDROID_BUILD_TOOLS_VERSION
|
||||
- android-$ANDROID_API_LEVEL
|
||||
licenses:
|
||||
- 'android-sdk-preview-license-.+'
|
||||
- 'android-sdk-license-.+'
|
||||
- 'google-gdk-license-.+'
|
||||
|
||||
before_install:
|
||||
- nvm install $nodejs_version
|
||||
- node --version
|
||||
- npm --version
|
||||
- gradle --version
|
||||
|
||||
install:
|
||||
- npm install
|
||||
- npm install -g codecov
|
||||
- npm install
|
||||
- npm install -g codecov
|
||||
|
||||
script:
|
||||
- npm test
|
||||
- npm run cover
|
||||
- npm test
|
||||
- npm run cover
|
||||
|
||||
after_script:
|
||||
- codecov
|
||||
- codecov
|
||||
|
||||
@@ -30,7 +30,6 @@ For instructions on this, start with the
|
||||
[contribution overview](http://cordova.apache.org/contribute/).
|
||||
|
||||
The details are explained there, but the important items are:
|
||||
- Sign and submit an Apache ICLA (Contributor License Agreement).
|
||||
- Have a Jira issue open that corresponds to your contribution.
|
||||
- Run the tests so your patch doesn't break existing functionality.
|
||||
|
||||
|
||||
@@ -31,9 +31,6 @@ at the core, applications written with web technology: HTML, CSS and JavaScript.
|
||||
|
||||
[Apache Cordova](https://cordova.apache.org) is a project of The Apache Software Foundation (ASF).
|
||||
|
||||
:warning: Report issues on the [Apache Cordova issue tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20%28Open%2C%20%22In%20Progress%22%2C%20Reopened%29%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22Android%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)
|
||||
|
||||
|
||||
## Requires
|
||||
|
||||
- Java JDK 1.8 or greater
|
||||
|
||||
@@ -20,6 +20,87 @@
|
||||
-->
|
||||
## Release Notes for Cordova (Android) ##
|
||||
|
||||
### 8.1.0 (Sep 11, 2019)
|
||||
|
||||
* [GH-827](https://github.com/apache/cordova-android/pull/827) chore: bump dependencies for release 8.1.0
|
||||
* [GH-651](https://github.com/apache/cordova-android/pull/651) feat: added multiple selection for filepicker
|
||||
* [GH-672](https://github.com/apache/cordova-android/pull/672) chore: compress files in /res with tinypng.com
|
||||
* [GH-815](https://github.com/apache/cordova-android/pull/815) fix: `clean` command
|
||||
* [GH-750](https://github.com/apache/cordova-android/pull/750) Don't request focus explicitly if not needed
|
||||
* [GH-800](https://github.com/apache/cordova-android/pull/800) [GH-799](https://github.com/apache/cordova-android/pull/799) (android) Stop webview from restarting when activity resizes
|
||||
* [GH-764](https://github.com/apache/cordova-android/pull/764) feat: Build app bundles (.aab files)
|
||||
* [GH-788](https://github.com/apache/cordova-android/pull/788) Simplify `apkSorter` using `compare-func` package
|
||||
* [GH-787](https://github.com/apache/cordova-android/pull/787) Simplify and fix promise handling in specs
|
||||
* [GH-784](https://github.com/apache/cordova-android/pull/784) Properly handle promise in create script
|
||||
* [GH-783](https://github.com/apache/cordova-android/pull/783) Do not clobber process properties with test mocks
|
||||
* [GH-782](https://github.com/apache/cordova-android/pull/782) Do not clobber `console.log` to spy on it
|
||||
* [GH-724](https://github.com/apache/cordova-android/pull/724) Add Node.js 12 to CI Services
|
||||
* [GH-777](https://github.com/apache/cordova-android/pull/777) ci(travis): set `dist: trusty` in `.travis.yml`
|
||||
* [GH-779](https://github.com/apache/cordova-android/pull/779) Consistent order from `ProjectBuilder.apkSorter`
|
||||
* [GH-778](https://github.com/apache/cordova-android/pull/778) test: use verbose spec reporter
|
||||
* [GH-774](https://github.com/apache/cordova-android/pull/774) `rewire` workaround for NodeJS 12
|
||||
* [GH-772](https://github.com/apache/cordova-android/pull/772) `nyc@14` update in devDependencies
|
||||
* [GH-765](https://github.com/apache/cordova-android/pull/765) ci(travis): Fix **Android** SDK
|
||||
* [GH-713](https://github.com/apache/cordova-android/pull/713) Do not explicitly require modules from project directory
|
||||
* [GH-676](https://github.com/apache/cordova-android/pull/676) Added allprojects repositories for Framework Release Builds
|
||||
* [GH-699](https://github.com/apache/cordova-android/pull/699) Improve Gradle Build Arguments
|
||||
* [GH-710](https://github.com/apache/cordova-android/pull/710) Fix deprecation warning in `SystemCookieManager`
|
||||
* [GH-691](https://github.com/apache/cordova-android/pull/691) [GH-690](https://github.com/apache/cordova-android/pull/690): Run `prepare` with the correct `ConfigParser`
|
||||
* [GH-673](https://github.com/apache/cordova-android/pull/673) Updated `Android_HOME` Test to Follow [GH-656](https://github.com/apache/cordova-android/pull/656) Change
|
||||
|
||||
### 8.0.0 (Feb 13, 2019)
|
||||
* [GH-669](https://github.com/apache/cordova-android/pull/669) Added Missing License Headers
|
||||
* [GH-655](https://github.com/apache/cordova-android/pull/655) Use custom Gradle properties to read minSdkVersion value from `config.xml`
|
||||
* [GH-656](https://github.com/apache/cordova-android/pull/656) Quick fix to support **Android**_SDK_ROOT
|
||||
* [GH-632](https://github.com/apache/cordova-android/pull/632) Ignore more Gradle build artifacts in **Android** project
|
||||
* [GH-642](https://github.com/apache/cordova-android/pull/642) **Android** tools 3.3 & **Gradle** 4.10.3 update
|
||||
* [GH-654](https://github.com/apache/cordova-android/pull/654) Quick updates to top-level `project.properties`
|
||||
* [GH-635](https://github.com/apache/cordova-android/pull/635) Ignore **Android** Studio `.idea` files in project
|
||||
* [GH-624](https://github.com/apache/cordova-android/pull/624) Add missing log to Java version check
|
||||
* [GH-630](https://github.com/apache/cordova-android/pull/630) Update `emulator.js` to fix issue [GH-608](https://github.com/apache/cordova-android/pull/608)
|
||||
* [GH-626](https://github.com/apache/cordova-android/pull/626) Added `package-lock.json` to `.gitignore`
|
||||
* [GH-620](https://github.com/apache/cordova-android/pull/620) Fix requirements error messages for JDK 8
|
||||
* [GH-619](https://github.com/apache/cordova-android/pull/619) javac error message fixes in requirements check
|
||||
* [GH-612](https://github.com/apache/cordova-android/pull/612) Android Platform Release Preparation (Cordova 9)
|
||||
* [GH-607](https://github.com/apache/cordova-android/pull/607) Copy `node_modules` if the directory exists
|
||||
* [GH-582](https://github.com/apache/cordova-android/pull/582) Improve Test `README`
|
||||
* [GH-589](https://github.com/apache/cordova-android/pull/589) Rewrite install dir resolution for legacy plugins
|
||||
* [GH-572](https://github.com/apache/cordova-android/pull/572) Resolve issue with plugin `target-dir="app*"` subdirs
|
||||
* [GH-567](https://github.com/apache/cordova-android/pull/567) Output current package name if package name can't be validated
|
||||
* [GH-507](https://github.com/apache/cordova-android/pull/507) Gradle Updates
|
||||
* [GH-559](https://github.com/apache/cordova-android/pull/559) Eslint ignore version file
|
||||
* [GH-550](https://github.com/apache/cordova-android/pull/550) Fix for old plugins with non-Java sources
|
||||
* [GH-558](https://github.com/apache/cordova-android/pull/558) Update `cordova.js` from `cordova-js@4.2.3`
|
||||
* [GH-553](https://github.com/apache/cordova-android/pull/553) Check for `build-extras.gradle` in the app-parent directory
|
||||
* [GH-551](https://github.com/apache/cordova-android/pull/551) Add missing cast for `cdvMinSdkVersion`
|
||||
* [GH-539](https://github.com/apache/cordova-android/pull/539) Fix destination path fallback
|
||||
* [GH-544](https://github.com/apache/cordova-android/pull/544) Remove obsolete check for JellyBean
|
||||
* [GH-465](https://github.com/apache/cordova-android/pull/465) Removes Gradle property in-line command arguments for `gradle.properties`
|
||||
* [GH-523](https://github.com/apache/cordova-android/pull/523) Always put the Google repo above jcenter
|
||||
* [GH-486](https://github.com/apache/cordova-android/pull/486) Change deprecated "compile" to "implementation"
|
||||
* [GH-495](https://github.com/apache/cordova-android/pull/495) Incorrect default sdk version issue fix
|
||||
* [GH-493](https://github.com/apache/cordova-android/pull/493) Remove bundled dependencies
|
||||
* [GH-490](https://github.com/apache/cordova-android/pull/490) Fixes build & run related bugs from builder refactor
|
||||
* [GH-464](https://github.com/apache/cordova-android/pull/464) Unit tests for **Android**_sdk and **Android**Project
|
||||
* [GH-448](https://github.com/apache/cordova-android/pull/448) [CB-13685](https://issues.apache.org/jira/browse/CB-13685) Adaptive Icon Support
|
||||
* [GH-487](https://github.com/apache/cordova-android/pull/487) Do not attempt an activity intent AND a url load into the webview, return from the internal webview load.
|
||||
* [GH-461](https://github.com/apache/cordova-android/pull/461) Remove old builders code
|
||||
* [GH-463](https://github.com/apache/cordova-android/pull/463) Emulator: Add unit tests and remove Q
|
||||
* [GH-462](https://github.com/apache/cordova-android/pull/462) Device: Add unit tests and remove Q
|
||||
* [GH-457](https://github.com/apache/cordova-android/pull/457) Emulator: handle "device still connecting" error
|
||||
* [GH-445](https://github.com/apache/cordova-android/pull/445) Run and retryPromise improvements and tests
|
||||
* [GH-453](https://github.com/apache/cordova-android/pull/453) Lint JS files w/out extension too
|
||||
* [GH-452](https://github.com/apache/cordova-android/pull/452) Emit log event instead of logging directly
|
||||
* [GH-449](https://github.com/apache/cordova-android/pull/449) Increase old plugin compatibility
|
||||
* [GH-442](https://github.com/apache/cordova-android/pull/442) Fixes and cleanup for Java tests and CI
|
||||
* [GH-446](https://github.com/apache/cordova-android/pull/446) [CB-14101](https://issues.apache.org/jira/browse/CB-14101) Fix Java version check for Java >= 9
|
||||
* [CB-14127](https://issues.apache.org/jira/browse/CB-14127) Move google maven repo ahead of jcenter
|
||||
* [CB-14038](https://issues.apache.org/jira/browse/CB-14038) Fix false positive detecting project type
|
||||
* [CB-14008](https://issues.apache.org/jira/browse/CB-14008) Updating Gradle Libraries to work with **Android** Studio 3.1.0
|
||||
* [CB-13975](https://issues.apache.org/jira/browse/CB-13975) Fix to fire pause event when cdvStartInBackground=true
|
||||
* [CB-13830](https://issues.apache.org/jira/browse/CB-13830) Add handlers for plugins that use non-Java source files, such as Camera
|
||||
* [CB-13923](https://issues.apache.org/jira/browse/CB-13923) Fix -1 length for compressed files
|
||||
|
||||
### 7.1.0 (Feb 20, 2018)
|
||||
* [CB-13879](https://issues.apache.org/jira/browse/CB-13879) updated gradle tools dependency to 3.0.1 for project template
|
||||
* [CB-13831](https://issues.apache.org/jira/browse/CB-13831) Update `android-versions` to 1.3.0 to support SDK 27.
|
||||
|
||||
59
appveyor.yml
@@ -1,38 +1,37 @@
|
||||
image:
|
||||
- Previous Visual Studio 2015
|
||||
|
||||
environment:
|
||||
ANDROID_HOME: "C:\\android"
|
||||
matrix:
|
||||
- nodejs_version: "4"
|
||||
- nodejs_version: "6"
|
||||
- nodejs_version: "8"
|
||||
ANDROID_HOME: "C:\\android"
|
||||
|
||||
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"
|
||||
# If the gradle daemon is used, the build hangs after generating the wrapper
|
||||
GRADLE_OPTS: -Dorg.gradle.daemon=false
|
||||
|
||||
# URL for SDK Tools, Revision 26.1.1 (September 2017)
|
||||
SDK_TOOLS_URL: https://dl.google.com/android/repository/sdk-tools-windows-4333796.zip
|
||||
|
||||
matrix:
|
||||
- nodejs_version: 6
|
||||
- nodejs_version: 8
|
||||
- nodejs_version: 10
|
||||
- nodejs_version: 12
|
||||
|
||||
install:
|
||||
- choco install gradle -version 3.4.1
|
||||
- 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
|
||||
- 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%
|
||||
# Install Android SDK Tools
|
||||
- mkdir "%ANDROID_HOME%"
|
||||
- appveyor DownloadFile "%SDK_TOOLS_URL%" -FileName "%TMP%/sdk-tools.zip"
|
||||
- 7z x "%TMP%/sdk-tools.zip" -o"%ANDROID_HOME%" > nul
|
||||
- set PATH=%PATH%;"%ANDROID_HOME%\tools\bin"
|
||||
|
||||
- yes 2> nul | sdkmanager --licenses > nul
|
||||
- sdkmanager "build-tools;28.0.3"
|
||||
|
||||
- choco install gradle --version 3.4.1
|
||||
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
- npm install
|
||||
|
||||
build: off
|
||||
|
||||
test_script:
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm test
|
||||
- gradle --version
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm test
|
||||
|
||||
@@ -21,9 +21,7 @@
|
||||
|
||||
var android_sdk = require('./templates/cordova/lib/android_sdk');
|
||||
|
||||
android_sdk.print_newest_available_sdk_target().done(null, function(err) {
|
||||
android_sdk.print_newest_available_sdk_target().done(null, function (err) {
|
||||
console.error(err);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -22,9 +22,10 @@
|
||||
var check_reqs = require('./templates/cordova/lib/check_reqs');
|
||||
|
||||
check_reqs.run().done(
|
||||
function success() {
|
||||
function success () {
|
||||
console.log('Looks like your environment fully supports cordova-android development!');
|
||||
}, function fail(err) {
|
||||
},
|
||||
function fail (err) {
|
||||
console.log(err);
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
12
bin/create
@@ -23,12 +23,12 @@ var ConfigParser = require('cordova-common').ConfigParser;
|
||||
var Api = require('./templates/cordova/Api');
|
||||
|
||||
var argv = require('nopt')({
|
||||
'help' : Boolean,
|
||||
'cli' : Boolean,
|
||||
'shared' : Boolean,
|
||||
'link' : Boolean,
|
||||
'activity-name' : [String, undefined]
|
||||
}, { 'd' : '--verbose' });
|
||||
'help': Boolean,
|
||||
'cli': Boolean,
|
||||
'shared': Boolean,
|
||||
'link': Boolean,
|
||||
'activity-name': [String, undefined]
|
||||
}, { 'd': '--verbose' });
|
||||
|
||||
if (argv.help || argv.argv.remain.length === 0) {
|
||||
console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'create')) + ' <path_to_new_project> <package_name> <project_name> [<template_path>] [--activity-name <activity_name>] [--link]');
|
||||
|
||||
@@ -141,9 +141,9 @@ function writeProjectProperties (projectPath, target_api) {
|
||||
}
|
||||
|
||||
// This makes no sense, what if you're building with a different build system?
|
||||
function prepBuildFiles (projectPath, builder) {
|
||||
var buildModule = require(path.resolve(projectPath, 'cordova/lib/builders/builders'));
|
||||
buildModule.getBuilder(builder).prepBuildFiles();
|
||||
function prepBuildFiles (projectPath) {
|
||||
var buildModule = require('../templates/cordova/lib/builders/builders');
|
||||
buildModule.getBuilder(projectPath).prepBuildFiles();
|
||||
}
|
||||
|
||||
function copyBuildRules (projectPath, isLegacy) {
|
||||
@@ -168,7 +168,10 @@ function copyScripts (projectPath) {
|
||||
shell.rm('-rf', destScriptsDir);
|
||||
// Copy in the new ones.
|
||||
shell.cp('-r', srcScriptsDir, projectPath);
|
||||
shell.cp('-r', path.join(ROOT, 'node_modules'), destScriptsDir);
|
||||
|
||||
let nodeModulesDir = path.join(ROOT, 'node_modules');
|
||||
if (fs.existsSync(nodeModulesDir)) shell.cp('-r', nodeModulesDir, destScriptsDir);
|
||||
|
||||
shell.cp(path.join(bin, 'check_reqs*'), destScriptsDir);
|
||||
shell.cp(path.join(bin, 'android_sdk_version*'), destScriptsDir);
|
||||
var check_reqs = path.join(destScriptsDir, 'check_reqs');
|
||||
@@ -194,7 +197,7 @@ function validatePackageName (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)) {
|
||||
return Q.reject(new CordovaError(msg + 'Package name must look like: com.company.Name'));
|
||||
return Q.reject(new CordovaError(msg + 'Must look like: `com.company.Name`. Currently is: `' + package_name + '`'));
|
||||
}
|
||||
|
||||
// Class is a reserved word
|
||||
@@ -269,7 +272,7 @@ exports.create = function (project_path, config, options, events) {
|
||||
// Make the package conform to Java package types
|
||||
return exports.validatePackageName(package_name)
|
||||
.then(function () {
|
||||
exports.validateProjectName(project_name);
|
||||
return exports.validateProjectName(project_name);
|
||||
}).then(function () {
|
||||
// Log the given values for the project
|
||||
events.emit('log', 'Creating Cordova project for the Android platform:');
|
||||
@@ -318,7 +321,6 @@ exports.create = function (project_path, config, options, events) {
|
||||
|
||||
var manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
|
||||
manifest.setPackageId(package_name)
|
||||
.setTargetSdkVersion(target_api.split('-')[1])
|
||||
.getActivity().setName(safe_activity_name);
|
||||
|
||||
var manifest_path = path.join(app_path, 'AndroidManifest.xml');
|
||||
@@ -329,7 +331,7 @@ exports.create = function (project_path, config, options, events) {
|
||||
});
|
||||
// Link it to local android install.
|
||||
exports.writeProjectProperties(project_path, target_api);
|
||||
exports.prepBuildFiles(project_path, 'studio');
|
||||
exports.prepBuildFiles(project_path);
|
||||
events.emit('log', generateDoneMessage('create', options.link));
|
||||
}).thenResolve(project_path);
|
||||
};
|
||||
|
||||
97
bin/templates/cordova/Api.js
vendored
@@ -21,11 +21,11 @@ var path = require('path');
|
||||
var Q = require('q');
|
||||
|
||||
var AndroidProject = require('./lib/AndroidProject');
|
||||
var AndroidStudio = require('./lib/AndroidStudio');
|
||||
var PluginManager = require('cordova-common').PluginManager;
|
||||
|
||||
var CordovaLogger = require('cordova-common').CordovaLogger;
|
||||
var selfEvents = require('cordova-common').events;
|
||||
var ConfigParser = require('cordova-common').ConfigParser;
|
||||
|
||||
var PLATFORM = 'android';
|
||||
|
||||
@@ -56,41 +56,24 @@ function setupEvents (externalEventEmitter) {
|
||||
function Api (platform, platformRootDir, events) {
|
||||
this.platform = PLATFORM;
|
||||
this.root = path.resolve(__dirname, '..');
|
||||
this.builder = 'gradle';
|
||||
|
||||
setupEvents(events);
|
||||
|
||||
var self = this;
|
||||
const appMain = path.join(this.root, 'app', 'src', 'main');
|
||||
const appRes = path.join(appMain, 'res');
|
||||
|
||||
this.locations = {
|
||||
root: self.root,
|
||||
www: path.join(self.root, 'assets/www'),
|
||||
res: path.join(self.root, 'res'),
|
||||
platformWww: path.join(self.root, 'platform_www'),
|
||||
configXml: path.join(self.root, 'res/xml/config.xml'),
|
||||
defaultConfigXml: path.join(self.root, 'cordova/defaults.xml'),
|
||||
strings: path.join(self.root, 'res/values/strings.xml'),
|
||||
manifest: path.join(self.root, 'AndroidManifest.xml'),
|
||||
build: path.join(self.root, 'build'),
|
||||
javaSrc: path.join(self.root, 'src'),
|
||||
// NOTE: Due to platformApi spec we need to return relative paths here
|
||||
cordovaJs: 'bin/templates/project/assets/www/cordova.js',
|
||||
cordovaJsSrc: 'cordova-js-src'
|
||||
root: this.root,
|
||||
www: path.join(appMain, 'assets', 'www'),
|
||||
res: appRes,
|
||||
platformWww: path.join(this.root, 'platform_www'),
|
||||
configXml: path.join(appRes, 'xml', 'config.xml'),
|
||||
defaultConfigXml: path.join(this.root, 'cordova', 'defaults.xml'),
|
||||
strings: path.join(appRes, 'values', 'strings.xml'),
|
||||
manifest: path.join(appMain, 'AndroidManifest.xml'),
|
||||
build: path.join(this.root, 'build'),
|
||||
javaSrc: path.join(appMain, 'java')
|
||||
};
|
||||
|
||||
// XXX Override some locations for Android Studio projects
|
||||
if (AndroidStudio.isAndroidStudioProject(self.root) === true) {
|
||||
selfEvents.emit('log', 'Android Studio project detected');
|
||||
this.builder = 'studio';
|
||||
this.android_studio = true;
|
||||
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/values/strings.xml');
|
||||
this.locations.manifest = path.join(self.root, 'app/src/main/AndroidManifest.xml');
|
||||
// We could have Java Source, we could have other languages
|
||||
this.locations.javaSrc = path.join(self.root, 'app/src/main/java/');
|
||||
this.locations.www = path.join(self.root, 'app/src/main/assets/www');
|
||||
this.locations.res = path.join(self.root, 'app/src/main/res');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,8 +99,7 @@ Api.createPlatform = function (destination, config, options, events) {
|
||||
var result;
|
||||
try {
|
||||
result = require('../../lib/create').create(destination, config, options, events).then(function (destination) {
|
||||
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
||||
return new PlatformApi(PLATFORM, destination, events);
|
||||
return new Api(PLATFORM, destination, events);
|
||||
});
|
||||
} catch (e) {
|
||||
events.emit('error', 'createPlatform is not callable from the android project API.');
|
||||
@@ -147,8 +129,7 @@ Api.updatePlatform = function (destination, options, events) {
|
||||
var result;
|
||||
try {
|
||||
result = require('../../lib/create').update(destination, options, events).then(function (destination) {
|
||||
var PlatformApi = require(path.resolve(destination, 'cordova/Api'));
|
||||
return new PlatformApi('android', destination, events);
|
||||
return new Api(PLATFORM, destination, events);
|
||||
});
|
||||
} catch (e) {
|
||||
events.emit('error', 'updatePlatform is not callable from the android project API, you will need to do this manually.');
|
||||
@@ -189,6 +170,8 @@ Api.prototype.getPlatformInfo = function () {
|
||||
* CordovaError instance.
|
||||
*/
|
||||
Api.prototype.prepare = function (cordovaProject, prepareOptions) {
|
||||
cordovaProject.projectConfig = new ConfigParser(cordovaProject.locations.rootConfigXml || cordovaProject.projectConfig.path);
|
||||
|
||||
return require('./lib/prepare').prepare.call(this, cordovaProject, prepareOptions);
|
||||
};
|
||||
|
||||
@@ -223,33 +206,13 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
|
||||
installOptions.variables.PACKAGE_NAME = project.getPackageName();
|
||||
}
|
||||
|
||||
if (this.android_studio === true) {
|
||||
installOptions.android_studio = true;
|
||||
}
|
||||
|
||||
return Q().then(function () {
|
||||
// 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
|
||||
// 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
|
||||
// to pass additional options.
|
||||
|
||||
// Do some basic argument parsing
|
||||
var opts = {};
|
||||
|
||||
// Skip cleaning prepared files when not invoking via cordova CLI.
|
||||
opts.noPrepare = true;
|
||||
|
||||
if (!AndroidStudio.isAndroidStudioProject(self.root) && !project.isClean()) {
|
||||
return self.clean(opts);
|
||||
}
|
||||
}).then(function () {
|
||||
return PluginManager.get(self.platform, self.locations, project).addPlugin(plugin, installOptions);
|
||||
}).then(function () {
|
||||
if (plugin.getFrameworks(this.platform).length === 0) return;
|
||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||
// This should pick the correct builder, not just get gradle
|
||||
require('./lib/builders/builders').getBuilder(this.builder).prepBuildFiles();
|
||||
// This should pick the correct builder, not just get gradle
|
||||
require('./lib/builders/builders').getBuilder().prepBuildFiles();
|
||||
}.bind(this))
|
||||
// CB-11022 Return truthy value to prevent running prepare after
|
||||
.thenResolve(true);
|
||||
@@ -271,9 +234,8 @@ Api.prototype.addPlugin = function (plugin, installOptions) {
|
||||
Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
||||
var project = AndroidProject.getProjectFile(this.root);
|
||||
|
||||
if (uninstallOptions && uninstallOptions.usePlatformWww === true && this.android_studio === true) {
|
||||
if (uninstallOptions && uninstallOptions.usePlatformWww === true) {
|
||||
uninstallOptions.usePlatformWww = false;
|
||||
uninstallOptions.android_studio = true;
|
||||
}
|
||||
|
||||
return PluginManager.get(this.platform, this.locations, project)
|
||||
@@ -282,7 +244,7 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
||||
if (plugin.getFrameworks(this.platform).length === 0) return;
|
||||
|
||||
selfEvents.emit('verbose', 'Updating build files since android plugin contained <framework>');
|
||||
require('./lib/builders/builders').getBuilder(this.builder).prepBuildFiles();
|
||||
require('./lib/builders/builders').getBuilder().prepBuildFiles();
|
||||
}.bind(this))
|
||||
// CB-11022 Return truthy value to prevent running prepare after
|
||||
.thenResolve(true);
|
||||
@@ -335,19 +297,17 @@ Api.prototype.removePlugin = function (plugin, uninstallOptions) {
|
||||
*/
|
||||
Api.prototype.build = function (buildOptions) {
|
||||
var self = this;
|
||||
if (this.android_studio) {
|
||||
buildOptions.studio = true;
|
||||
}
|
||||
|
||||
return require('./lib/check_reqs').run().then(function () {
|
||||
return require('./lib/build').run.call(self, buildOptions);
|
||||
}).then(function (buildResults) {
|
||||
// Cast build result to array of build artifacts
|
||||
return buildResults.apkPaths.map(function (apkPath) {
|
||||
return buildResults.paths.map(function (apkPath) {
|
||||
return {
|
||||
buildType: buildResults.buildType,
|
||||
buildMethod: buildResults.buildMethod,
|
||||
path: apkPath,
|
||||
type: 'apk'
|
||||
type: path.extname(apkPath).replace(/\./g, '')
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -381,12 +341,9 @@ Api.prototype.run = function (runOptions) {
|
||||
*/
|
||||
Api.prototype.clean = function (cleanOptions) {
|
||||
var self = this;
|
||||
if (this.android_studio) {
|
||||
// This will lint, checking for null won't
|
||||
if (typeof cleanOptions === 'undefined') {
|
||||
cleanOptions = {};
|
||||
}
|
||||
cleanOptions.studio = true;
|
||||
// This will lint, checking for null won't
|
||||
if (typeof cleanOptions === 'undefined') {
|
||||
cleanOptions = {};
|
||||
}
|
||||
|
||||
return require('./lib/check_reqs').run().then(function () {
|
||||
|
||||
@@ -19,24 +19,25 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var args = process.argv;
|
||||
var args = process.argv;
|
||||
var Api = require('./Api');
|
||||
var nopt = require('nopt');
|
||||
var path = require('path');
|
||||
|
||||
// Support basic help commands
|
||||
if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0)
|
||||
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(args[2]) >= 0) {
|
||||
require('./lib/build').help();
|
||||
}
|
||||
|
||||
// Do some basic argument parsing
|
||||
var buildOpts = nopt({
|
||||
'verbose' : Boolean,
|
||||
'silent' : Boolean,
|
||||
'debug' : Boolean,
|
||||
'release' : Boolean,
|
||||
'verbose': Boolean,
|
||||
'silent': Boolean,
|
||||
'debug': Boolean,
|
||||
'release': Boolean,
|
||||
'nobuild': Boolean,
|
||||
'buildConfig' : path
|
||||
}, { 'd' : '--verbose' });
|
||||
'buildConfig': path
|
||||
}, { 'd': '--verbose' });
|
||||
|
||||
// Make buildOptions compatible with PlatformApi build method spec
|
||||
buildOpts.argv = buildOpts.argv.original;
|
||||
@@ -44,7 +45,7 @@ buildOpts.argv = buildOpts.argv.original;
|
||||
require('./loggingHelper').adjustLoggerLevel(buildOpts);
|
||||
|
||||
new Api().build(buildOpts)
|
||||
.catch(function(err) {
|
||||
console.error(err.stack);
|
||||
process.exit(2);
|
||||
});
|
||||
.catch(function (err) {
|
||||
console.error(err.stack);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
*/
|
||||
|
||||
var Api = require('./Api');
|
||||
var path = require('path');
|
||||
var path = require('path');
|
||||
var nopt = require('nopt');
|
||||
|
||||
// Support basic help commands
|
||||
if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
|
||||
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
|
||||
console.log('Usage: ' + path.relative(process.cwd(), process.argv[1]));
|
||||
console.log('Cleans the project directory.');
|
||||
process.exit(0);
|
||||
@@ -32,9 +32,9 @@ if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >=
|
||||
|
||||
// Do some basic argument parsing
|
||||
var opts = nopt({
|
||||
'verbose' : Boolean,
|
||||
'silent' : Boolean
|
||||
}, { 'd' : '--verbose' });
|
||||
'verbose': Boolean,
|
||||
'silent': Boolean
|
||||
}, { 'd': '--verbose' });
|
||||
|
||||
// Make buildOptions compatible with PlatformApi clean method spec
|
||||
opts.argv = opts.argv.original;
|
||||
@@ -45,7 +45,7 @@ opts.noPrepare = true;
|
||||
require('./loggingHelper').adjustLoggerLevel(opts);
|
||||
|
||||
new Api().clean(opts)
|
||||
.catch(function(err) {
|
||||
console.error(err.stack);
|
||||
process.exit(2);
|
||||
});
|
||||
.catch(function (err) {
|
||||
console.error(err.stack);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
8
bin/templates/cordova/lib/Adb.js
vendored
@@ -44,7 +44,7 @@ function isEmulator (line) {
|
||||
* devices/emulators
|
||||
*/
|
||||
Adb.devices = function (opts) {
|
||||
return spawn('adb', ['devices'], {cwd: os.tmpdir()}).then(function (output) {
|
||||
return spawn('adb', ['devices'], { cwd: os.tmpdir() }).then(function (output) {
|
||||
return output.split('\n').filter(function (line) {
|
||||
// Filter out either real devices or emulators, depending on options
|
||||
return (line && opts && opts.emulators) ? isEmulator(line) : isDevice(line);
|
||||
@@ -58,7 +58,7 @@ Adb.install = function (target, packagePath, opts) {
|
||||
events.emit('verbose', 'Installing apk ' + packagePath + ' on target ' + target + '...');
|
||||
var args = ['-s', target, 'install'];
|
||||
if (opts && opts.replace) args.push('-r');
|
||||
return spawn('adb', args.concat(packagePath), {cwd: os.tmpdir()}).then(function (output) {
|
||||
return spawn('adb', args.concat(packagePath), { cwd: os.tmpdir() }).then(function (output) {
|
||||
// 'adb install' seems to always returns no error, even if installation fails
|
||||
// so we catching output to detect installation failure
|
||||
if (output.match(/Failure/)) {
|
||||
@@ -77,14 +77,14 @@ Adb.install = function (target, packagePath, opts) {
|
||||
|
||||
Adb.uninstall = function (target, packageId) {
|
||||
events.emit('verbose', 'Uninstalling package ' + packageId + ' from target ' + target + '...');
|
||||
return spawn('adb', ['-s', target, 'uninstall', packageId], {cwd: os.tmpdir()});
|
||||
return spawn('adb', ['-s', target, 'uninstall', packageId], { cwd: os.tmpdir() });
|
||||
};
|
||||
|
||||
Adb.shell = function (target, shellCommand) {
|
||||
events.emit('verbose', 'Running adb shell command "' + shellCommand + '" on target ' + target + '...');
|
||||
var args = ['-s', target, 'shell'];
|
||||
shellCommand = shellCommand.split(/\s+/);
|
||||
return spawn('adb', args.concat(shellCommand), {cwd: os.tmpdir()}).catch(function (output) {
|
||||
return spawn('adb', args.concat(shellCommand), { cwd: os.tmpdir() }).catch(function (output) {
|
||||
return Q.reject(new CordovaError('Failed to execute shell command "' +
|
||||
shellCommand + '"" on device: ' + output));
|
||||
});
|
||||
|
||||
36
bin/templates/cordova/lib/AndroidManifest.js
vendored
@@ -18,7 +18,6 @@
|
||||
*/
|
||||
|
||||
var fs = require('fs');
|
||||
var et = require('elementtree');
|
||||
var xml = require('cordova-common').xmlHelpers;
|
||||
|
||||
var DEFAULT_ORIENTATION = 'default';
|
||||
@@ -51,15 +50,11 @@ AndroidManifest.prototype.setVersionCode = function (versionCode) {
|
||||
};
|
||||
|
||||
AndroidManifest.prototype.getPackageId = function () {
|
||||
/* jshint -W069 */
|
||||
return this.doc.getroot().attrib['package'];
|
||||
/* jshint +W069 */
|
||||
};
|
||||
|
||||
AndroidManifest.prototype.setPackageId = function (pkgId) {
|
||||
/* jshint -W069 */
|
||||
this.doc.getroot().attrib['package'] = pkgId;
|
||||
/* jshint +W069 */
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -102,31 +97,6 @@ AndroidManifest.prototype.getActivity = function () {
|
||||
};
|
||||
};
|
||||
|
||||
['minSdkVersion', 'maxSdkVersion', 'targetSdkVersion'].forEach(function (sdkPrefName) {
|
||||
// Copy variable reference to avoid closure issues
|
||||
var prefName = sdkPrefName;
|
||||
|
||||
AndroidManifest.prototype['get' + capitalize(prefName)] = function () {
|
||||
var usesSdk = this.doc.getroot().find('./uses-sdk');
|
||||
return usesSdk && usesSdk.attrib['android:' + prefName];
|
||||
};
|
||||
|
||||
AndroidManifest.prototype['set' + capitalize(prefName)] = function (prefValue) {
|
||||
var usesSdk = this.doc.getroot().find('./uses-sdk');
|
||||
|
||||
if (!usesSdk && prefValue) { // if there is no required uses-sdk element, we should create it first
|
||||
usesSdk = new et.Element('uses-sdk');
|
||||
this.doc.getroot().append(usesSdk);
|
||||
}
|
||||
|
||||
if (prefValue) {
|
||||
usesSdk.attrib['android:' + prefName] = prefValue;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
});
|
||||
|
||||
AndroidManifest.prototype.getDebuggable = function () {
|
||||
return this.doc.getroot().find('./application').attrib['android:debuggable'] === 'true';
|
||||
};
|
||||
@@ -150,11 +120,7 @@ AndroidManifest.prototype.setDebuggable = function (value) {
|
||||
* manifest will be written to file it has been read from.
|
||||
*/
|
||||
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');
|
||||
};
|
||||
|
||||
module.exports = AndroidManifest;
|
||||
|
||||
function capitalize (str) {
|
||||
return str.charAt(0).toUpperCase() + str.slice(1);
|
||||
}
|
||||
|
||||
11
bin/templates/cordova/lib/AndroidProject.js
vendored
@@ -21,7 +21,6 @@ var fs = require('fs');
|
||||
var path = require('path');
|
||||
var properties_parser = require('properties-parser');
|
||||
var AndroidManifest = require('./AndroidManifest');
|
||||
var AndroidStudio = require('./AndroidStudio');
|
||||
var pluginHandlers = require('./pluginHandlers');
|
||||
|
||||
var projectFileCache = {};
|
||||
@@ -62,10 +61,7 @@ function AndroidProject (projectDir) {
|
||||
this._dirty = false;
|
||||
this.projectDir = projectDir;
|
||||
this.platformWww = path.join(this.projectDir, 'platform_www');
|
||||
this.www = path.join(this.projectDir, 'assets/www');
|
||||
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');
|
||||
}
|
||||
|
||||
AndroidProject.getProjectFile = function (projectDir) {
|
||||
@@ -92,10 +88,7 @@ AndroidProject.purgeCache = function (projectDir) {
|
||||
* @return {String} The name of the package
|
||||
*/
|
||||
AndroidProject.prototype.getPackageName = function () {
|
||||
var manifestPath = path.join(this.projectDir, 'AndroidManifest.xml');
|
||||
if (AndroidStudio.isAndroidStudioProject(this.projectDir) === true) {
|
||||
manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml');
|
||||
}
|
||||
var manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml');
|
||||
return new AndroidManifest(manifestPath).getPackageId();
|
||||
};
|
||||
|
||||
|
||||
42
bin/templates/cordova/lib/AndroidStudio.js
vendored
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* This is a simple routine that checks if project is an Android Studio Project
|
||||
*
|
||||
* @param {String} root Root folder of the project
|
||||
*/
|
||||
|
||||
/* jshint esnext: false */
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
|
||||
module.exports.isAndroidStudioProject = function isAndroidStudioProject (root) {
|
||||
var eclipseFiles = ['AndroidManifest.xml', 'libs', 'res'];
|
||||
var androidStudioFiles = ['app', 'app/src/main'];
|
||||
|
||||
// assume it is an AS project and not an Eclipse project
|
||||
var isEclipse = false;
|
||||
var isAS = true;
|
||||
|
||||
if (!fs.existsSync(root)) {
|
||||
throw new CordovaError('AndroidStudio.js:inAndroidStudioProject root does not exist: ' + root);
|
||||
}
|
||||
|
||||
// if any of the following exists, then we are not an ASProj
|
||||
eclipseFiles.forEach(function (file) {
|
||||
if (fs.existsSync(path.join(root, file))) {
|
||||
isEclipse = true;
|
||||
}
|
||||
});
|
||||
|
||||
// if it is NOT an eclipse project, check that all required files exist
|
||||
if (!isEclipse) {
|
||||
androidStudioFiles.forEach(function (file) {
|
||||
if (!fs.existsSync(path.join(root, file))) {
|
||||
console.log('missing file :: ' + file);
|
||||
isAS = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
return (!isEclipse && isAS);
|
||||
};
|
||||
25
bin/templates/cordova/lib/PackageType.js
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
|
||||
const PackageType = {
|
||||
APK: 'apk',
|
||||
BUNDLE: 'bundle'
|
||||
};
|
||||
|
||||
module.exports = PackageType;
|
||||
3
bin/templates/cordova/lib/android_sdk.js
vendored
@@ -17,7 +17,6 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var Q = require('q');
|
||||
var superspawn = require('cordova-common').superspawn;
|
||||
|
||||
var suffix_number_regex = /(\d+)$/;
|
||||
@@ -95,7 +94,7 @@ module.exports.list_targets = function () {
|
||||
} else throw err;
|
||||
}).then(function (targets) {
|
||||
if (targets.length === 0) {
|
||||
return Q.reject(new Error('No android targets (SDKs) installed!'));
|
||||
return Promise.reject(new Error('No android targets (SDKs) installed!'));
|
||||
}
|
||||
return targets;
|
||||
});
|
||||
|
||||
91
bin/templates/cordova/lib/build.js
vendored
@@ -30,46 +30,38 @@ var builders = require('./builders/builders');
|
||||
var events = require('cordova-common').events;
|
||||
var spawn = require('cordova-common').superspawn.spawn;
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var PackageType = require('./PackageType');
|
||||
|
||||
module.exports.parseBuildOptions = parseOpts;
|
||||
function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
options = options || {};
|
||||
options.argv = nopt({
|
||||
gradle: Boolean,
|
||||
studio: Boolean,
|
||||
prepenv: Boolean,
|
||||
versionCode: String,
|
||||
minSdkVersion: String,
|
||||
maxSdkVersion: String,
|
||||
targetSdkVersion: String,
|
||||
gradleArg: [String, Array],
|
||||
keystore: path,
|
||||
alias: String,
|
||||
storePassword: String,
|
||||
password: String,
|
||||
keystoreType: String
|
||||
keystoreType: String,
|
||||
packageType: String
|
||||
}, {}, options.argv, 0);
|
||||
|
||||
// Android Studio Build method is the default
|
||||
var ret = {
|
||||
buildType: options.release ? 'release' : 'debug',
|
||||
buildMethod: process.env.ANDROID_BUILD || 'studio',
|
||||
prepEnv: options.argv.prepenv,
|
||||
arch: resolvedTarget && resolvedTarget.arch,
|
||||
extraArgs: []
|
||||
};
|
||||
|
||||
if (options.argv.gradle || options.argv.studio) {
|
||||
ret.buildMethod = options.argv.studio ? 'studio' : 'gradle';
|
||||
}
|
||||
|
||||
// This comes from cordova/run
|
||||
if (options.studio) ret.buildMethod = 'studio';
|
||||
if (options.gradle) ret.buildMethod = 'gradle';
|
||||
|
||||
if (options.nobuild) ret.buildMethod = 'none';
|
||||
|
||||
if (options.argv.versionCode) { ret.extraArgs.push('-PcdvVersionCode=' + options.argv.versionCode); }
|
||||
|
||||
if (options.argv.minSdkVersion) { ret.extraArgs.push('-PcdvMinSdkVersion=' + options.argv.minSdkVersion); }
|
||||
|
||||
if (options.argv.maxSdkVersion) { ret.extraArgs.push('-PcdvMaxSdkVersion=' + options.argv.maxSdkVersion); }
|
||||
if (options.argv.targetSdkVersion) { ret.extraArgs.push('-PcdvTargetSdkVersion=' + options.argv.targetSdkVersion); }
|
||||
if (options.argv.gradleArg) {
|
||||
ret.extraArgs = ret.extraArgs.concat(options.argv.gradleArg);
|
||||
}
|
||||
@@ -78,14 +70,14 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
|
||||
if (options.argv.keystore) { packageArgs.keystore = path.relative(projectRoot, path.resolve(options.argv.keystore)); }
|
||||
|
||||
['alias', 'storePassword', 'password', 'keystoreType'].forEach(function (flagName) {
|
||||
['alias', 'storePassword', 'password', 'keystoreType', 'packageType'].forEach(function (flagName) {
|
||||
if (options.argv[flagName]) { packageArgs[flagName] = options.argv[flagName]; }
|
||||
});
|
||||
|
||||
var buildConfig = options.buildConfig;
|
||||
|
||||
// If some values are not specified as command line arguments - use build config to supplement them.
|
||||
// Command line arguemnts have precedence over build config.
|
||||
// Command line arguments have precedence over build config.
|
||||
if (buildConfig) {
|
||||
if (!fs.existsSync(buildConfig)) {
|
||||
throw new Error('Specified build config file does not exist: ' + buildConfig);
|
||||
@@ -103,7 +95,7 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
events.emit('log', 'Reading the keystore from: ' + packageArgs.keystore);
|
||||
}
|
||||
|
||||
['alias', 'storePassword', 'password', 'keystoreType'].forEach(function (key) {
|
||||
['alias', 'storePassword', 'password', 'keystoreType', 'packageType'].forEach(function (key) {
|
||||
packageArgs[key] = packageArgs[key] || androidInfo[key];
|
||||
});
|
||||
}
|
||||
@@ -115,11 +107,38 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
}
|
||||
|
||||
if (!ret.packageInfo) {
|
||||
if (Object.keys(packageArgs).length > 0) {
|
||||
// The following loop is to decide whether to print a warning about generating a signed archive
|
||||
// We only want to produce a warning if they are using a config property that is related to signing, but
|
||||
// missing the required properties for signing. We don't want to produce a warning if they are simply
|
||||
// using a build property that isn't related to signing, such as --packageType
|
||||
let shouldWarn = false;
|
||||
const signingKeys = ['keystore', 'alias', 'storePassword', 'password', 'keystoreType'];
|
||||
|
||||
for (let key in packageArgs) {
|
||||
if (!shouldWarn && signingKeys.indexOf(key) > -1) {
|
||||
// If we enter this condition, we have a key used for signing a build,
|
||||
// but we are missing some required signing properties
|
||||
shouldWarn = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldWarn) {
|
||||
events.emit('warn', '\'keystore\' and \'alias\' need to be specified to generate a signed archive.');
|
||||
}
|
||||
}
|
||||
|
||||
if (packageArgs.packageType) {
|
||||
const VALID_PACKAGE_TYPES = [PackageType.APK, PackageType.BUNDLE];
|
||||
if (VALID_PACKAGE_TYPES.indexOf(packageArgs.packageType) === -1) {
|
||||
events.emit('warn', '"' + packageArgs.packageType + '" is an invalid packageType. Valid values are: ' + VALID_PACKAGE_TYPES.join(', ') + '\nDefaulting packageType to ' + PackageType.APK);
|
||||
ret.packageType = PackageType.APK;
|
||||
} else {
|
||||
ret.packageType = packageArgs.packageType;
|
||||
}
|
||||
} else {
|
||||
ret.packageType = PackageType.APK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -129,7 +148,8 @@ function parseOpts (options, resolvedTarget, projectRoot) {
|
||||
*/
|
||||
module.exports.runClean = function (options) {
|
||||
var opts = parseOpts(options, null, this.root);
|
||||
var builder = builders.getBuilder(opts.buildMethod);
|
||||
var builder = builders.getBuilder();
|
||||
|
||||
return builder.prepEnv(opts).then(function () {
|
||||
return builder.clean(opts);
|
||||
});
|
||||
@@ -149,20 +169,26 @@ module.exports.runClean = function (options) {
|
||||
*/
|
||||
module.exports.run = function (options, optResolvedTarget) {
|
||||
var opts = parseOpts(options, optResolvedTarget, this.root);
|
||||
console.log(opts.buildMethod);
|
||||
var builder = builders.getBuilder(opts.buildMethod);
|
||||
var builder = builders.getBuilder();
|
||||
|
||||
return builder.prepEnv(opts).then(function () {
|
||||
if (opts.prepEnv) {
|
||||
events.emit('verbose', 'Build file successfully prepared.');
|
||||
return;
|
||||
}
|
||||
return builder.build(opts).then(function () {
|
||||
var apkPaths = builder.findOutputApks(opts.buildType, opts.arch);
|
||||
events.emit('log', 'Built the following apk(s): \n\t' + apkPaths.join('\n\t'));
|
||||
var paths;
|
||||
if (opts.packageType === PackageType.BUNDLE) {
|
||||
paths = builder.findOutputBundles(opts.buildType);
|
||||
events.emit('log', 'Built the following bundle(s): \n\t' + paths.join('\n\t'));
|
||||
} else {
|
||||
paths = builder.findOutputApks(opts.buildType, opts.arch);
|
||||
events.emit('log', 'Built the following apk(s): \n\t' + paths.join('\n\t'));
|
||||
}
|
||||
|
||||
return {
|
||||
apkPaths: apkPaths,
|
||||
buildType: opts.buildType,
|
||||
buildMethod: opts.buildMethod
|
||||
paths: paths,
|
||||
buildType: opts.buildType
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -276,13 +302,14 @@ module.exports.help = function () {
|
||||
console.log('Flags:');
|
||||
console.log(' \'--debug\': will build project in debug mode (default)');
|
||||
console.log(' \'--release\': will build project for release');
|
||||
console.log(' \'--ant\': will build project with ant');
|
||||
console.log(' \'--gradle\': will build project with gradle (default)');
|
||||
console.log(' \'--nobuild\': will skip build process (useful when using run command)');
|
||||
console.log(' \'--prepenv\': don\'t build, but copy in build scripts where necessary');
|
||||
console.log(' \'--versionCode=#\': Override versionCode for this build. Useful for uploading multiple APKs. Requires --gradle.');
|
||||
console.log(' \'--minSdkVersion=#\': Override minSdkVersion for this build. Useful for uploading multiple APKs. Requires --gradle.');
|
||||
console.log(' \'--versionCode=#\': Override versionCode for this build. Useful for uploading multiple APKs.');
|
||||
console.log(' \'--minSdkVersion=#\': Override minSdkVersion for this build.');
|
||||
console.log(' \'--maxSdkVersion=#\': Override maxSdkVersion for this build. (Not Recommended)');
|
||||
console.log(' \'--targetSdkVersion=#\': Override targetSdkVersion for this build.');
|
||||
console.log(' \'--gradleArg=<gradle command line arg>\': Extra args to pass to the gradle command. Use one flag per arg. Ex. --gradleArg=-PcdvBuildMultipleApks=true');
|
||||
console.log(' \'--packageType=<apk|bundle>\': Builds an APK or a bundle');
|
||||
console.log('');
|
||||
console.log('Signed APK flags (overwrites debug/release-signing.proprties) :');
|
||||
console.log(' \'--keystore=<path to keystore>\': Key store used to build a signed archive. (Required)');
|
||||
|
||||
124
bin/templates/cordova/lib/builders/GenericBuilder.js
vendored
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
/* eslint no-self-assign: 0 */
|
||||
/* eslint no-unused-vars: 0 */
|
||||
|
||||
var Q = require('q');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var shell = require('shelljs');
|
||||
var events = require('cordova-common').events;
|
||||
|
||||
function GenericBuilder (projectDir) {
|
||||
this.root = projectDir || path.resolve(__dirname, '../../..');
|
||||
this.binDirs = {
|
||||
studio: path.join(this.root, 'app', 'build', 'outputs', 'apk'),
|
||||
gradle: path.join(this.root, 'build', 'outputs', 'apk')
|
||||
};
|
||||
}
|
||||
|
||||
GenericBuilder.prototype.prepEnv = function () {
|
||||
return Q();
|
||||
};
|
||||
|
||||
GenericBuilder.prototype.build = function () {
|
||||
events.emit('log', 'Skipping build...');
|
||||
return Q(null);
|
||||
};
|
||||
|
||||
GenericBuilder.prototype.clean = function () {
|
||||
return Q();
|
||||
};
|
||||
|
||||
GenericBuilder.prototype.findOutputApks = function (build_type, arch) {
|
||||
var self = this;
|
||||
return Object.keys(this.binDirs).reduce(function (result, builderName) {
|
||||
var binDir = self.binDirs[builderName];
|
||||
return result.concat(findOutputApksHelper(binDir, build_type, builderName === 'ant' ? null : arch));
|
||||
}, []).sort(apkSorter);
|
||||
};
|
||||
|
||||
module.exports = GenericBuilder;
|
||||
|
||||
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
|
||||
var unsignedRE = /-unsigned/;
|
||||
if (unsignedRE.exec(fileA)) {
|
||||
return 1;
|
||||
} else if (unsignedRE.exec(fileB)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var timeDiff = fs.statSync(fileB).mtime - fs.statSync(fileA).mtime;
|
||||
return timeDiff === 0 ? fileA.length - fileB.length : timeDiff;
|
||||
}
|
||||
|
||||
function findOutputApksHelper (dir, build_type, arch) {
|
||||
var shellSilent = shell.config.silent;
|
||||
shell.config.silent = true;
|
||||
|
||||
// list directory recursively
|
||||
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);
|
||||
// Need to choose between release and debug .apk.
|
||||
if (build_type === 'debug') {
|
||||
return /-debug/.exec(apkName) && !/-unaligned|-unsigned/.exec(apkName);
|
||||
}
|
||||
if (build_type === 'release') {
|
||||
return /-release/.exec(apkName) && !/-unaligned/.exec(apkName);
|
||||
}
|
||||
return true;
|
||||
}).sort(apkSorter);
|
||||
|
||||
shellSilent = shellSilent;
|
||||
|
||||
if (ret.length === 0) {
|
||||
return ret;
|
||||
}
|
||||
// Assume arch-specific build if newest apk has -x86 or -arm.
|
||||
var archSpecific = !!/-x86|-arm/.exec(path.basename(ret[0]));
|
||||
// And show only arch-specific ones (or non-arch-specific)
|
||||
ret = ret.filter(function (p) {
|
||||
/* jshint -W018 */
|
||||
return !!/-x86|-arm/.exec(path.basename(p)) === archSpecific;
|
||||
/* jshint +W018 */
|
||||
});
|
||||
|
||||
if (archSpecific && ret.length > 1 && arch) {
|
||||
ret = ret.filter(function (p) {
|
||||
return path.basename(p).indexOf('-' + arch) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
330
bin/templates/cordova/lib/builders/GradleBuilder.js
vendored
@@ -1,330 +0,0 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
var Q = require('q');
|
||||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
var path = require('path');
|
||||
var shell = require('shelljs');
|
||||
var superspawn = require('cordova-common').superspawn;
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var check_reqs = require('../check_reqs');
|
||||
|
||||
var GenericBuilder = require('./GenericBuilder');
|
||||
|
||||
var MARKER = 'YOUR CHANGES WILL BE ERASED!';
|
||||
var SIGNING_PROPERTIES = '-signing.properties';
|
||||
var TEMPLATE =
|
||||
'# This file is automatically generated.\n' +
|
||||
'# Do not modify this file -- ' + MARKER + '\n';
|
||||
|
||||
function GradleBuilder (projectRoot) {
|
||||
GenericBuilder.call(this, projectRoot);
|
||||
|
||||
this.binDirs = { gradle: this.binDirs.gradle };
|
||||
}
|
||||
|
||||
util.inherits(GradleBuilder, GenericBuilder);
|
||||
|
||||
GradleBuilder.prototype.getArgs = function (cmd, opts) {
|
||||
if (cmd === 'release') {
|
||||
cmd = 'cdvBuildRelease';
|
||||
} else if (cmd === 'debug') {
|
||||
cmd = 'cdvBuildDebug';
|
||||
}
|
||||
var args = [cmd, '-b', path.join(this.root, 'build.gradle')];
|
||||
if (opts.arch) {
|
||||
args.push('-PcdvBuildArch=' + opts.arch);
|
||||
}
|
||||
|
||||
// 10 seconds -> 6 seconds
|
||||
args.push('-Dorg.gradle.daemon=true');
|
||||
// to allow dex in process
|
||||
args.push('-Dorg.gradle.jvmargs=-Xmx2048m');
|
||||
// allow NDK to be used - required by Gradle 1.5 plugin
|
||||
args.push('-Pandroid.useDeprecatedNdk=true');
|
||||
args.push.apply(args, opts.extraArgs);
|
||||
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
|
||||
// args.push('-Dorg.gradle.parallel=true');
|
||||
return args;
|
||||
};
|
||||
|
||||
/*
|
||||
* This returns a promise
|
||||
*/
|
||||
|
||||
GradleBuilder.prototype.runGradleWrapper = function (gradle_cmd, gradle_file) {
|
||||
var gradlePath = path.join(this.root, 'gradlew');
|
||||
gradle_file = path.join(this.root, (gradle_file || 'wrapper.gradle'));
|
||||
if (fs.existsSync(gradlePath)) {
|
||||
// Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
|
||||
} else {
|
||||
return superspawn.spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', gradle_file], { stdio: 'pipe' })
|
||||
.progress(function (stdio) {
|
||||
suppressJavaOptionsInfo(stdio);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* We need to kill this in a fire.
|
||||
*/
|
||||
|
||||
GradleBuilder.prototype.readProjectProperties = function () {
|
||||
function findAllUniq (data, r) {
|
||||
var s = {};
|
||||
var m;
|
||||
while ((m = r.exec(data))) {
|
||||
s[m[1]] = 1;
|
||||
}
|
||||
return Object.keys(s);
|
||||
}
|
||||
|
||||
var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8');
|
||||
return {
|
||||
libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg),
|
||||
gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg),
|
||||
systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg)
|
||||
};
|
||||
};
|
||||
|
||||
GradleBuilder.prototype.extractRealProjectNameFromManifest = function () {
|
||||
var manifestPath = path.join(this.root, 'AndroidManifest.xml');
|
||||
var manifestData = fs.readFileSync(manifestPath, 'utf8');
|
||||
var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
|
||||
if (!m) {
|
||||
throw new CordovaError('Could not find package name in ' + manifestPath);
|
||||
}
|
||||
|
||||
var packageName = m[1];
|
||||
var lastDotIndex = packageName.lastIndexOf('.');
|
||||
return packageName.substring(lastDotIndex + 1);
|
||||
};
|
||||
|
||||
// Makes the project buildable, minus the gradle wrapper.
|
||||
GradleBuilder.prototype.prepBuildFiles = function () {
|
||||
// Update the version of build.gradle in each dependent library.
|
||||
var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle');
|
||||
var propertiesObj = this.readProjectProperties();
|
||||
var subProjects = propertiesObj.libs;
|
||||
|
||||
// Check and copy the gradle file into the subproject.
|
||||
// Called by the loop below this function def.
|
||||
var checkAndCopy = function (subProject, root) {
|
||||
var subProjectGradle = path.join(root, subProject, 'build.gradle');
|
||||
// This is the future-proof way of checking if a file exists
|
||||
// This must be synchronous to satisfy a Travis test
|
||||
try {
|
||||
fs.accessSync(subProjectGradle, fs.F_OK);
|
||||
} catch (e) {
|
||||
shell.cp('-f', pluginBuildGradle, subProjectGradle);
|
||||
}
|
||||
};
|
||||
|
||||
// Some dependencies on Android don't use gradle, or don't have default
|
||||
// gradle files. This copies a dummy gradle file into them
|
||||
for (var i = 0; i < subProjects.length; ++i) {
|
||||
if (subProjects[i] !== 'CordovaLib' && subProjects[i] !== 'app') {
|
||||
checkAndCopy(subProjects[i], this.root);
|
||||
}
|
||||
}
|
||||
|
||||
var name = this.extractRealProjectNameFromManifest();
|
||||
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
|
||||
var settingsGradlePaths = subProjects.map(function (p) {
|
||||
var realDir = p.replace(/[/\\]/g, ':');
|
||||
var libName = realDir.replace(name + '-', '');
|
||||
var str = 'include ":' + libName + '"\n';
|
||||
if (realDir.indexOf(name + '-') !== -1) { str += 'project(":' + libName + '").projectDir = new File("' + p + '")\n'; }
|
||||
return str;
|
||||
});
|
||||
|
||||
// Write the settings.gradle file.
|
||||
fs.writeFileSync(path.join(this.root, 'settings.gradle'),
|
||||
'// GENERATED FILE - DO NOT EDIT\n' +
|
||||
'include ":"\n' + settingsGradlePaths.join(''));
|
||||
// Update dependencies within build.gradle.
|
||||
var buildGradle = fs.readFileSync(path.join(this.root, 'build.gradle'), 'utf8');
|
||||
var depsList = '';
|
||||
var root = this.root;
|
||||
|
||||
// Cordova Plugins can be written as library modules that would use Cordova as a
|
||||
// dependency. Because we need to make sure that Cordova is compiled only once for
|
||||
// dexing, we make sure to exclude CordovaLib from these modules
|
||||
var insertExclude = function (p) {
|
||||
var gradlePath = path.join(root, p, 'build.gradle');
|
||||
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
|
||||
if (projectGradleFile.indexOf('CordovaLib') !== -1) {
|
||||
depsList += '{\n exclude module:("CordovaLib")\n }\n';
|
||||
} else {
|
||||
depsList += '\n';
|
||||
}
|
||||
};
|
||||
|
||||
subProjects.forEach(function (p) {
|
||||
console.log('Subproject Path: ' + p);
|
||||
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
|
||||
depsList += ' implementation(project(path: "' + libName + '"))';
|
||||
insertExclude(p);
|
||||
});
|
||||
|
||||
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
|
||||
var SYSTEM_LIBRARY_MAPPINGS = [
|
||||
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
|
||||
[/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+']
|
||||
];
|
||||
propertiesObj.systemLibs.forEach(function (p) {
|
||||
var mavenRef;
|
||||
// It's already in gradle form if it has two ':'s
|
||||
if (/:.*:/.exec(p)) {
|
||||
mavenRef = p;
|
||||
} else {
|
||||
for (var i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) {
|
||||
var pair = SYSTEM_LIBRARY_MAPPINGS[i];
|
||||
if (pair[0].exec(p)) {
|
||||
mavenRef = p.replace(pair[0], pair[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mavenRef) {
|
||||
throw new CordovaError('Unsupported system library (does not work with gradle): ' + p);
|
||||
}
|
||||
}
|
||||
depsList += ' compile "' + mavenRef + '"\n';
|
||||
});
|
||||
|
||||
// This code is dangerous and actually writes gradle declarations directly into the build.gradle
|
||||
// Try not to mess with this if possible
|
||||
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2');
|
||||
var includeList = '';
|
||||
propertiesObj.gradleIncludes.forEach(function (includePath) {
|
||||
includeList += 'apply from: "' + includePath + '"\n';
|
||||
});
|
||||
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);
|
||||
};
|
||||
|
||||
GradleBuilder.prototype.prepEnv = function (opts) {
|
||||
var self = this;
|
||||
return check_reqs.check_gradle().then(function (gradlePath) {
|
||||
return self.runGradleWrapper(gradlePath);
|
||||
}).then(function () {
|
||||
return self.prepBuildFiles();
|
||||
}).then(function () {
|
||||
// We now copy the gradle out of the framework
|
||||
// This is a dirty patch to get the build working
|
||||
/*
|
||||
var wrapperDir = path.join(self.root, 'CordovaLib');
|
||||
if (process.platform == 'win32') {
|
||||
shell.rm('-f', path.join(self.root, 'gradlew.bat'));
|
||||
shell.cp(path.join(wrapperDir, 'gradlew.bat'), self.root);
|
||||
} else {
|
||||
shell.rm('-f', path.join(self.root, 'gradlew'));
|
||||
shell.cp(path.join(wrapperDir, 'gradlew'), self.root);
|
||||
}
|
||||
shell.rm('-rf', path.join(self.root, 'gradle', 'wrapper'));
|
||||
shell.mkdir('-p', path.join(self.root, 'gradle'));
|
||||
shell.cp('-r', path.join(wrapperDir, 'gradle', 'wrapper'), path.join(self.root, 'gradle'));
|
||||
*/
|
||||
// If the gradle distribution URL is set, make sure it points to version we want.
|
||||
// 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.
|
||||
var distributionUrlRegex = /distributionUrl.*zip/;
|
||||
/* jshint -W069 */
|
||||
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.1-all.zip';
|
||||
/* jshint +W069 */
|
||||
var gradleWrapperPropertiesPath = path.join(self.root, 'gradle', 'wrapper', 'gradle-wrapper.properties');
|
||||
shell.chmod('u+w', gradleWrapperPropertiesPath);
|
||||
shell.sed('-i', distributionUrlRegex, 'distributionUrl=' + distributionUrl, gradleWrapperPropertiesPath);
|
||||
|
||||
var propertiesFile = opts.buildType + SIGNING_PROPERTIES;
|
||||
var propertiesFilePath = path.join(self.root, propertiesFile);
|
||||
if (opts.packageInfo) {
|
||||
fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties());
|
||||
} else if (isAutoGenerated(propertiesFilePath)) {
|
||||
shell.rm('-f', propertiesFilePath);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Builds the project with gradle.
|
||||
* Returns a promise.
|
||||
*/
|
||||
GradleBuilder.prototype.build = function (opts) {
|
||||
var wrapper = path.join(this.root, 'gradlew');
|
||||
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
|
||||
|
||||
return superspawn.spawn(wrapper, args, { stdio: 'pipe' })
|
||||
.progress(function (stdio) {
|
||||
suppressJavaOptionsInfo(stdio);
|
||||
}).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) {
|
||||
var builder = this;
|
||||
var wrapper = path.join(this.root, 'gradlew');
|
||||
var args = builder.getArgs('clean', opts);
|
||||
return Q().then(function () {
|
||||
return superspawn.spawn(wrapper, args, { stdio: 'inherit' });
|
||||
}).then(function () {
|
||||
shell.rm('-rf', path.join(builder.root, 'out'));
|
||||
|
||||
['debug', 'release'].forEach(function (config) {
|
||||
var propertiesFilePath = path.join(builder.root, config + SIGNING_PROPERTIES);
|
||||
if (isAutoGenerated(propertiesFilePath)) {
|
||||
shell.rm('-f', propertiesFilePath);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = GradleBuilder;
|
||||
|
||||
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;
|
||||
}
|
||||
412
bin/templates/cordova/lib/builders/ProjectBuilder.js
vendored
Normal file
@@ -0,0 +1,412 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
/* eslint no-self-assign: 0 */
|
||||
/* eslint no-unused-vars: 0 */
|
||||
|
||||
var Q = require('q');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var shell = require('shelljs');
|
||||
var spawn = require('cordova-common').superspawn.spawn;
|
||||
var events = require('cordova-common').events;
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var check_reqs = require('../check_reqs');
|
||||
var PackageType = require('../PackageType');
|
||||
const compareFunc = require('compare-func');
|
||||
|
||||
const MARKER = 'YOUR CHANGES WILL BE ERASED!';
|
||||
const SIGNING_PROPERTIES = '-signing.properties';
|
||||
const TEMPLATE =
|
||||
'# This file is automatically generated.\n' +
|
||||
'# Do not modify this file -- ' + MARKER + '\n';
|
||||
|
||||
class ProjectBuilder {
|
||||
constructor (rootDirectory) {
|
||||
this.root = rootDirectory || path.resolve(__dirname, '../../..');
|
||||
this.apkDir = path.join(this.root, 'app', 'build', 'outputs', 'apk');
|
||||
this.aabDir = path.join(this.root, 'app', 'build', 'outputs', 'bundle');
|
||||
}
|
||||
|
||||
getArgs (cmd, opts) {
|
||||
let args;
|
||||
let buildCmd = cmd;
|
||||
if (opts.packageType === PackageType.BUNDLE) {
|
||||
if (cmd === 'release') {
|
||||
buildCmd = ':app:bundleRelease';
|
||||
} else if (cmd === 'debug') {
|
||||
buildCmd = ':app:bundleDebug';
|
||||
}
|
||||
|
||||
args = [buildCmd, '-b', path.join(this.root, 'build.gradle')];
|
||||
} else {
|
||||
if (cmd === 'release') {
|
||||
buildCmd = 'cdvBuildRelease';
|
||||
} else if (cmd === 'debug') {
|
||||
buildCmd = 'cdvBuildDebug';
|
||||
}
|
||||
|
||||
args = [buildCmd, '-b', path.join(this.root, 'build.gradle')];
|
||||
|
||||
if (opts.arch) {
|
||||
args.push('-PcdvBuildArch=' + opts.arch);
|
||||
}
|
||||
|
||||
args.push.apply(args, opts.extraArgs);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
/*
|
||||
* This returns a promise
|
||||
*/
|
||||
runGradleWrapper (gradle_cmd) {
|
||||
var gradlePath = path.join(this.root, 'gradlew');
|
||||
var wrapperGradle = path.join(this.root, 'wrapper.gradle');
|
||||
if (fs.existsSync(gradlePath)) {
|
||||
// Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
|
||||
} else {
|
||||
return spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', wrapperGradle], { stdio: 'inherit' });
|
||||
}
|
||||
}
|
||||
|
||||
readProjectProperties () {
|
||||
function findAllUniq (data, r) {
|
||||
var s = {};
|
||||
var m;
|
||||
while ((m = r.exec(data))) {
|
||||
s[m[1]] = 1;
|
||||
}
|
||||
return Object.keys(s);
|
||||
}
|
||||
|
||||
var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8');
|
||||
return {
|
||||
libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg),
|
||||
gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg),
|
||||
systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg)
|
||||
};
|
||||
}
|
||||
|
||||
extractRealProjectNameFromManifest () {
|
||||
var manifestPath = path.join(this.root, 'app', 'src', 'main', 'AndroidManifest.xml');
|
||||
var manifestData = fs.readFileSync(manifestPath, 'utf8');
|
||||
var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
|
||||
if (!m) {
|
||||
throw new CordovaError('Could not find package name in ' + manifestPath);
|
||||
}
|
||||
|
||||
var packageName = m[1];
|
||||
var lastDotIndex = packageName.lastIndexOf('.');
|
||||
return packageName.substring(lastDotIndex + 1);
|
||||
}
|
||||
|
||||
// Makes the project buildable, minus the gradle wrapper.
|
||||
prepBuildFiles () {
|
||||
// Update the version of build.gradle in each dependent library.
|
||||
var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle');
|
||||
var propertiesObj = this.readProjectProperties();
|
||||
var subProjects = propertiesObj.libs;
|
||||
|
||||
// Check and copy the gradle file into the subproject
|
||||
// Called by the loop before this function def
|
||||
|
||||
var checkAndCopy = function (subProject, root) {
|
||||
var subProjectGradle = path.join(root, subProject, 'build.gradle');
|
||||
// This is the future-proof way of checking if a file exists
|
||||
// This must be synchronous to satisfy a Travis test
|
||||
try {
|
||||
fs.accessSync(subProjectGradle, fs.F_OK);
|
||||
} catch (e) {
|
||||
shell.cp('-f', pluginBuildGradle, subProjectGradle);
|
||||
}
|
||||
};
|
||||
|
||||
for (var i = 0; i < subProjects.length; ++i) {
|
||||
if (subProjects[i] !== 'CordovaLib') {
|
||||
checkAndCopy(subProjects[i], this.root);
|
||||
}
|
||||
}
|
||||
var name = this.extractRealProjectNameFromManifest();
|
||||
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
|
||||
var settingsGradlePaths = subProjects.map(function (p) {
|
||||
var realDir = p.replace(/[/\\]/g, ':');
|
||||
var libName = realDir.replace(name + '-', '');
|
||||
var str = 'include ":' + libName + '"\n';
|
||||
if (realDir.indexOf(name + '-') !== -1) {
|
||||
str += 'project(":' + libName + '").projectDir = new File("' + p + '")\n';
|
||||
}
|
||||
return str;
|
||||
});
|
||||
|
||||
fs.writeFileSync(path.join(this.root, 'settings.gradle'),
|
||||
'// GENERATED FILE - DO NOT EDIT\n' +
|
||||
'include ":"\n' + settingsGradlePaths.join(''));
|
||||
|
||||
// Update dependencies within build.gradle.
|
||||
var buildGradle = fs.readFileSync(path.join(this.root, 'app', 'build.gradle'), 'utf8');
|
||||
var depsList = '';
|
||||
var root = this.root;
|
||||
var insertExclude = function (p) {
|
||||
var gradlePath = path.join(root, p, 'build.gradle');
|
||||
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
|
||||
if (projectGradleFile.indexOf('CordovaLib') !== -1) {
|
||||
depsList += '{\n exclude module:("CordovaLib")\n }\n';
|
||||
} else {
|
||||
depsList += '\n';
|
||||
}
|
||||
};
|
||||
subProjects.forEach(function (p) {
|
||||
events.emit('log', 'Subproject Path: ' + p);
|
||||
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
|
||||
if (libName !== 'app') {
|
||||
depsList += ' implementation(project(path: ":' + libName + '"))';
|
||||
insertExclude(p);
|
||||
}
|
||||
});
|
||||
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
|
||||
var SYSTEM_LIBRARY_MAPPINGS = [
|
||||
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
|
||||
[/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+']
|
||||
];
|
||||
|
||||
propertiesObj.systemLibs.forEach(function (p) {
|
||||
var mavenRef;
|
||||
// It's already in gradle form if it has two ':'s
|
||||
if (/:.*:/.exec(p)) {
|
||||
mavenRef = p;
|
||||
} else {
|
||||
for (var i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) {
|
||||
var pair = SYSTEM_LIBRARY_MAPPINGS[i];
|
||||
if (pair[0].exec(p)) {
|
||||
mavenRef = p.replace(pair[0], pair[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mavenRef) {
|
||||
throw new CordovaError('Unsupported system library (does not work with gradle): ' + p);
|
||||
}
|
||||
}
|
||||
depsList += ' implementation "' + mavenRef + '"\n';
|
||||
});
|
||||
|
||||
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2');
|
||||
var includeList = '';
|
||||
|
||||
propertiesObj.gradleIncludes.forEach(function (includePath) {
|
||||
includeList += 'apply from: "../' + includePath + '"\n';
|
||||
});
|
||||
buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2');
|
||||
// This needs to be stored in the app gradle, not the root grade
|
||||
fs.writeFileSync(path.join(this.root, 'app', 'build.gradle'), buildGradle);
|
||||
}
|
||||
|
||||
prepEnv (opts) {
|
||||
var self = this;
|
||||
return check_reqs.check_gradle()
|
||||
.then(function (gradlePath) {
|
||||
return self.runGradleWrapper(gradlePath);
|
||||
}).then(function () {
|
||||
return self.prepBuildFiles();
|
||||
}).then(function () {
|
||||
// If the gradle distribution URL is set, make sure it points to version we want.
|
||||
// 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.
|
||||
var distributionUrlRegex = /distributionUrl.*zip/;
|
||||
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.10.3-all.zip';
|
||||
var gradleWrapperPropertiesPath = path.join(self.root, 'gradle', 'wrapper', 'gradle-wrapper.properties');
|
||||
shell.chmod('u+w', gradleWrapperPropertiesPath);
|
||||
shell.sed('-i', distributionUrlRegex, 'distributionUrl=' + distributionUrl, gradleWrapperPropertiesPath);
|
||||
|
||||
var propertiesFile = opts.buildType + SIGNING_PROPERTIES;
|
||||
var propertiesFilePath = path.join(self.root, propertiesFile);
|
||||
if (opts.packageInfo) {
|
||||
fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties());
|
||||
} else if (isAutoGenerated(propertiesFilePath)) {
|
||||
shell.rm('-f', propertiesFilePath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds the project with gradle.
|
||||
* Returns a promise.
|
||||
*/
|
||||
build (opts) {
|
||||
var wrapper = path.join(this.root, 'gradlew');
|
||||
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
|
||||
|
||||
return spawn(wrapper, args, { stdio: 'pipe' })
|
||||
.progress(function (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);
|
||||
}
|
||||
}).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);
|
||||
});
|
||||
}
|
||||
|
||||
clean (opts) {
|
||||
var builder = this;
|
||||
var wrapper = path.join(this.root, 'gradlew');
|
||||
var args = builder.getArgs('clean', opts);
|
||||
return Q().then(function () {
|
||||
return spawn(wrapper, args, { stdio: 'inherit' });
|
||||
})
|
||||
.then(function () {
|
||||
shell.rm('-rf', path.join(builder.root, 'out'));
|
||||
|
||||
['debug', 'release'].forEach(function (config) {
|
||||
var propertiesFilePath = path.join(builder.root, config + SIGNING_PROPERTIES);
|
||||
if (isAutoGenerated(propertiesFilePath)) {
|
||||
shell.rm('-f', propertiesFilePath);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
findOutputApks (build_type, arch) {
|
||||
return findOutputApksHelper(this.apkDir, build_type, arch).sort(apkSorter);
|
||||
}
|
||||
|
||||
findOutputBundles (build_type) {
|
||||
return findOutputBundlesHelper(this.aabDir, build_type);
|
||||
}
|
||||
|
||||
fetchBuildResults (build_type, arch) {
|
||||
return {
|
||||
apkPaths: this.findOutputApks(build_type, arch),
|
||||
buildType: build_type
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ProjectBuilder;
|
||||
|
||||
const apkSorter = compareFunc([
|
||||
// Sort arch specific builds after generic ones
|
||||
apkPath => /-x86|-arm/.test(apkPath),
|
||||
|
||||
// Sort unsigned builds after signed ones
|
||||
apkPath => /-unsigned/.test(apkPath),
|
||||
|
||||
// Sort by file modification time, latest first
|
||||
apkPath => -fs.statSync(apkPath).mtime.getTime(),
|
||||
|
||||
// Sort by file name length, ascending
|
||||
'length'
|
||||
]);
|
||||
|
||||
function findOutputApksHelper (dir, build_type, arch) {
|
||||
var shellSilent = shell.config.silent;
|
||||
shell.config.silent = true;
|
||||
|
||||
// list directory recursively
|
||||
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);
|
||||
// Need to choose between release and debug .apk.
|
||||
if (build_type === 'debug') {
|
||||
return /-debug/.exec(apkName) && !/-unaligned|-unsigned/.exec(apkName);
|
||||
}
|
||||
if (build_type === 'release') {
|
||||
return /-release/.exec(apkName) && !/-unaligned/.exec(apkName);
|
||||
}
|
||||
return true;
|
||||
}).sort(apkSorter);
|
||||
|
||||
shellSilent = shellSilent;
|
||||
|
||||
if (ret.length === 0) {
|
||||
return ret;
|
||||
}
|
||||
// Assume arch-specific build if newest apk has -x86 or -arm.
|
||||
var archSpecific = !!/-x86|-arm/.exec(path.basename(ret[0]));
|
||||
// And show only arch-specific ones (or non-arch-specific)
|
||||
ret = ret.filter(function (p) {
|
||||
return !!/-x86|-arm/.exec(path.basename(p)) === archSpecific;
|
||||
});
|
||||
|
||||
if (archSpecific && ret.length > 1 && arch) {
|
||||
ret = ret.filter(function (p) {
|
||||
return path.basename(p).indexOf('-' + arch) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// This method was a copy of findOutputApksHelper and modified to look for bundles
|
||||
// While replacing shell with fs-extra, it might be a good idea to see if we can
|
||||
// generalise these findOutput methods.
|
||||
function findOutputBundlesHelper (dir, build_type) {
|
||||
// This is an unused variable that was copied from findOutputApksHelper
|
||||
// we are pretty sure it was meant to reset shell.config.silent back to
|
||||
// the original value. However shell is planned to be replaced,
|
||||
// it was left as is to avoid unintended consequences.
|
||||
const shellSilent = shell.config.silent;
|
||||
shell.config.silent = true;
|
||||
|
||||
// list directory recursively
|
||||
const ret = shell.ls('-R', dir).map(function (file) {
|
||||
return path.join(dir, file); // ls does not include base directory
|
||||
}).filter(function (file) {
|
||||
return file.match(/\.aab?$/i); // find all bundles
|
||||
}).filter(function (candidate) {
|
||||
// Need to choose between release and debug bundle.
|
||||
if (build_type === 'debug') {
|
||||
return /debug/.exec(candidate);
|
||||
}
|
||||
if (build_type === 'release') {
|
||||
return /release/.exec(candidate);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
function isAutoGenerated (file) {
|
||||
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
||||
}
|
||||
302
bin/templates/cordova/lib/builders/StudioBuilder.js
vendored
@@ -1,302 +0,0 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
var Q = require('q');
|
||||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
var path = require('path');
|
||||
var shell = require('shelljs');
|
||||
var spawn = require('cordova-common').superspawn.spawn;
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
var check_reqs = require('../check_reqs');
|
||||
|
||||
var GenericBuilder = require('./GenericBuilder');
|
||||
|
||||
var MARKER = 'YOUR CHANGES WILL BE ERASED!';
|
||||
var SIGNING_PROPERTIES = '-signing.properties';
|
||||
var TEMPLATE =
|
||||
'# This file is automatically generated.\n' +
|
||||
'# Do not modify this file -- ' + MARKER + '\n';
|
||||
|
||||
function StudioBuilder (projectRoot) {
|
||||
GenericBuilder.call(this, projectRoot);
|
||||
|
||||
this.binDirs = {gradle: this.binDirs.studio};
|
||||
}
|
||||
|
||||
util.inherits(StudioBuilder, GenericBuilder);
|
||||
|
||||
StudioBuilder.prototype.getArgs = function (cmd, opts) {
|
||||
if (cmd === 'release') {
|
||||
cmd = 'cdvBuildRelease';
|
||||
} else if (cmd === 'debug') {
|
||||
cmd = 'cdvBuildDebug';
|
||||
}
|
||||
var args = [cmd, '-b', path.join(this.root, 'build.gradle')];
|
||||
if (opts.arch) {
|
||||
args.push('-PcdvBuildArch=' + opts.arch);
|
||||
}
|
||||
|
||||
// 10 seconds -> 6 seconds
|
||||
args.push('-Dorg.gradle.daemon=true');
|
||||
// to allow dex in process
|
||||
args.push('-Dorg.gradle.jvmargs=-Xmx2048m');
|
||||
// allow NDK to be used - required by Gradle 1.5 plugin
|
||||
// args.push('-Pandroid.useDeprecatedNdk=true');
|
||||
args.push.apply(args, opts.extraArgs);
|
||||
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
|
||||
// args.push('-Dorg.gradle.parallel=true');
|
||||
return args;
|
||||
};
|
||||
|
||||
/*
|
||||
* This returns a promise
|
||||
*/
|
||||
|
||||
StudioBuilder.prototype.runGradleWrapper = function (gradle_cmd) {
|
||||
var gradlePath = path.join(this.root, 'gradlew');
|
||||
var wrapperGradle = path.join(this.root, 'wrapper.gradle');
|
||||
if (fs.existsSync(gradlePath)) {
|
||||
// Literally do nothing, for some reason this works, while !fs.existsSync didn't on Windows
|
||||
} else {
|
||||
return spawn(gradle_cmd, ['-p', this.root, 'wrapper', '-b', wrapperGradle], {stdio: 'inherit'});
|
||||
}
|
||||
};
|
||||
|
||||
StudioBuilder.prototype.readProjectProperties = function () {
|
||||
|
||||
function findAllUniq (data, r) {
|
||||
var s = {};
|
||||
var m;
|
||||
while ((m = r.exec(data))) {
|
||||
s[m[1]] = 1;
|
||||
}
|
||||
return Object.keys(s);
|
||||
}
|
||||
|
||||
var data = fs.readFileSync(path.join(this.root, 'project.properties'), 'utf8');
|
||||
return {
|
||||
libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg),
|
||||
gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg),
|
||||
systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=(.*)(?:\s|$)/mg)
|
||||
};
|
||||
};
|
||||
|
||||
StudioBuilder.prototype.extractRealProjectNameFromManifest = function () {
|
||||
var manifestPath = path.join(this.root, 'app', 'src', 'main', 'AndroidManifest.xml');
|
||||
var manifestData = fs.readFileSync(manifestPath, 'utf8');
|
||||
var m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
|
||||
if (!m) {
|
||||
throw new CordovaError('Could not find package name in ' + manifestPath);
|
||||
}
|
||||
|
||||
var packageName = m[1];
|
||||
var lastDotIndex = packageName.lastIndexOf('.');
|
||||
return packageName.substring(lastDotIndex + 1);
|
||||
};
|
||||
|
||||
// Makes the project buildable, minus the gradle wrapper.
|
||||
StudioBuilder.prototype.prepBuildFiles = function () {
|
||||
// Update the version of build.gradle in each dependent library.
|
||||
var pluginBuildGradle = path.join(this.root, 'cordova', 'lib', 'plugin-build.gradle');
|
||||
var propertiesObj = this.readProjectProperties();
|
||||
var subProjects = propertiesObj.libs;
|
||||
|
||||
// Check and copy the gradle file into the subproject
|
||||
// Called by the loop before this function def
|
||||
|
||||
var checkAndCopy = function (subProject, root) {
|
||||
var subProjectGradle = path.join(root, subProject, 'build.gradle');
|
||||
// This is the future-proof way of checking if a file exists
|
||||
// This must be synchronous to satisfy a Travis test
|
||||
try {
|
||||
fs.accessSync(subProjectGradle, fs.F_OK);
|
||||
} catch (e) {
|
||||
shell.cp('-f', pluginBuildGradle, subProjectGradle);
|
||||
}
|
||||
};
|
||||
|
||||
for (var i = 0; i < subProjects.length; ++i) {
|
||||
if (subProjects[i] !== 'CordovaLib') {
|
||||
checkAndCopy(subProjects[i], this.root);
|
||||
}
|
||||
}
|
||||
var name = this.extractRealProjectNameFromManifest();
|
||||
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
|
||||
var settingsGradlePaths = subProjects.map(function (p) {
|
||||
var realDir = p.replace(/[/\\]/g, ':');
|
||||
var libName = realDir.replace(name + '-', '');
|
||||
var str = 'include ":' + libName + '"\n';
|
||||
if (realDir.indexOf(name + '-') !== -1) {
|
||||
str += 'project(":' + libName + '").projectDir = new File("' + p + '")\n';
|
||||
}
|
||||
return str;
|
||||
});
|
||||
|
||||
fs.writeFileSync(path.join(this.root, 'settings.gradle'),
|
||||
'// GENERATED FILE - DO NOT EDIT\n' +
|
||||
'include ":"\n' + settingsGradlePaths.join(''));
|
||||
|
||||
// Update dependencies within build.gradle.
|
||||
var buildGradle = fs.readFileSync(path.join(this.root, 'app', 'build.gradle'), 'utf8');
|
||||
var depsList = '';
|
||||
var root = this.root;
|
||||
var insertExclude = function (p) {
|
||||
var gradlePath = path.join(root, p, 'build.gradle');
|
||||
var projectGradleFile = fs.readFileSync(gradlePath, 'utf-8');
|
||||
if (projectGradleFile.indexOf('CordovaLib') !== -1) {
|
||||
depsList += '{\n exclude module:("CordovaLib")\n }\n';
|
||||
} else {
|
||||
depsList += '\n';
|
||||
}
|
||||
};
|
||||
subProjects.forEach(function (p) {
|
||||
console.log('Subproject Path: ' + p);
|
||||
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
|
||||
if (libName !== 'app') {
|
||||
depsList += ' implementation(project(path: ":' + libName + '"))';
|
||||
insertExclude(p);
|
||||
}
|
||||
});
|
||||
// For why we do this mapping: https://issues.apache.org/jira/browse/CB-8390
|
||||
var SYSTEM_LIBRARY_MAPPINGS = [
|
||||
[/^\/?extras\/android\/support\/(.*)$/, 'com.android.support:support-$1:+'],
|
||||
[/^\/?google\/google_play_services\/libproject\/google-play-services_lib\/?$/, 'com.google.android.gms:play-services:+']
|
||||
];
|
||||
|
||||
propertiesObj.systemLibs.forEach(function (p) {
|
||||
var mavenRef;
|
||||
// It's already in gradle form if it has two ':'s
|
||||
if (/:.*:/.exec(p)) {
|
||||
mavenRef = p;
|
||||
} else {
|
||||
for (var i = 0; i < SYSTEM_LIBRARY_MAPPINGS.length; ++i) {
|
||||
var pair = SYSTEM_LIBRARY_MAPPINGS[i];
|
||||
if (pair[0].exec(p)) {
|
||||
mavenRef = p.replace(pair[0], pair[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mavenRef) {
|
||||
throw new CordovaError('Unsupported system library (does not work with gradle): ' + p);
|
||||
}
|
||||
}
|
||||
depsList += ' compile "' + mavenRef + '"\n';
|
||||
});
|
||||
|
||||
buildGradle = buildGradle.replace(/(SUB-PROJECT DEPENDENCIES START)[\s\S]*(\/\/ SUB-PROJECT DEPENDENCIES END)/, '$1\n' + depsList + ' $2');
|
||||
var includeList = '';
|
||||
|
||||
propertiesObj.gradleIncludes.forEach(function (includePath) {
|
||||
includeList += 'apply from: "../' + includePath + '"\n';
|
||||
});
|
||||
buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2');
|
||||
// This needs to be stored in the app gradle, not the root grade
|
||||
fs.writeFileSync(path.join(this.root, 'app', 'build.gradle'), buildGradle);
|
||||
};
|
||||
|
||||
StudioBuilder.prototype.prepEnv = function (opts) {
|
||||
var self = this;
|
||||
return check_reqs.check_gradle()
|
||||
.then(function (gradlePath) {
|
||||
return self.runGradleWrapper(gradlePath);
|
||||
}).then(function () {
|
||||
return self.prepBuildFiles();
|
||||
}).then(function () {
|
||||
// If the gradle distribution URL is set, make sure it points to version we want.
|
||||
// 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.
|
||||
var distributionUrlRegex = /distributionUrl.*zip/;
|
||||
var distributionUrl = process.env['CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL'] || 'https\\://services.gradle.org/distributions/gradle-4.1-all.zip';
|
||||
var gradleWrapperPropertiesPath = path.join(self.root, 'gradle', 'wrapper', 'gradle-wrapper.properties');
|
||||
shell.chmod('u+w', gradleWrapperPropertiesPath);
|
||||
shell.sed('-i', distributionUrlRegex, 'distributionUrl=' + distributionUrl, gradleWrapperPropertiesPath);
|
||||
|
||||
var propertiesFile = opts.buildType + SIGNING_PROPERTIES;
|
||||
var propertiesFilePath = path.join(self.root, propertiesFile);
|
||||
if (opts.packageInfo) {
|
||||
fs.writeFileSync(propertiesFilePath, TEMPLATE + opts.packageInfo.toProperties());
|
||||
} else if (isAutoGenerated(propertiesFilePath)) {
|
||||
shell.rm('-f', propertiesFilePath);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Builds the project with gradle.
|
||||
* Returns a promise.
|
||||
*/
|
||||
StudioBuilder.prototype.build = function (opts) {
|
||||
var wrapper = path.join(this.root, 'gradlew');
|
||||
var args = this.getArgs(opts.buildType === 'debug' ? 'debug' : 'release', opts);
|
||||
|
||||
return spawn(wrapper, args, {stdio: 'pipe'})
|
||||
.progress(function (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);
|
||||
}
|
||||
}).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);
|
||||
});
|
||||
};
|
||||
|
||||
StudioBuilder.prototype.clean = function (opts) {
|
||||
var builder = this;
|
||||
var wrapper = path.join(this.root, 'gradlew');
|
||||
var args = builder.getArgs('clean', opts);
|
||||
return Q().then(function () {
|
||||
return spawn(wrapper, args, {stdio: 'inherit'});
|
||||
})
|
||||
.then(function () {
|
||||
shell.rm('-rf', path.join(builder.root, 'out'));
|
||||
|
||||
['debug', 'release'].forEach(function (config) {
|
||||
var propertiesFilePath = path.join(builder.root, config + SIGNING_PROPERTIES);
|
||||
if (isAutoGenerated(propertiesFilePath)) {
|
||||
shell.rm('-f', propertiesFilePath);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = StudioBuilder;
|
||||
|
||||
function isAutoGenerated (file) {
|
||||
return fs.existsSync(file) && fs.readFileSync(file, 'utf8').indexOf(MARKER) > 0;
|
||||
}
|
||||
54
bin/templates/cordova/lib/builders/builders.js
vendored
@@ -1,46 +1,34 @@
|
||||
/*
|
||||
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
|
||||
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
|
||||
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.
|
||||
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.
|
||||
*/
|
||||
|
||||
var CordovaError = require('cordova-common').CordovaError;
|
||||
|
||||
var knownBuilders = {
|
||||
gradle: 'GradleBuilder',
|
||||
studio: 'StudioBuilder',
|
||||
none: 'GenericBuilder'
|
||||
};
|
||||
const CordovaError = require('cordova-common').CordovaError;
|
||||
|
||||
/**
|
||||
* Helper method that instantiates and returns a builder for specified build
|
||||
* type.
|
||||
* Helper method that instantiates and returns a builder for specified build type.
|
||||
*
|
||||
* @param {String} builderType Builder name to construct and return. Must
|
||||
* be one of 'ant', 'gradle' or 'none'
|
||||
*
|
||||
* @return {Builder} A builder instance for specified build type.
|
||||
* @return {Builder} A builder instance for specified build type.
|
||||
*/
|
||||
module.exports.getBuilder = function (builderType, projectRoot) {
|
||||
if (!knownBuilders[builderType]) { throw new CordovaError('Builder ' + builderType + ' is not supported.'); }
|
||||
|
||||
module.exports.getBuilder = function (projectPath) {
|
||||
try {
|
||||
var Builder = require('./' + knownBuilders[builderType]);
|
||||
return new Builder(projectRoot);
|
||||
const Builder = require('./ProjectBuilder');
|
||||
return new Builder(projectPath);
|
||||
} catch (err) {
|
||||
throw new CordovaError('Failed to instantiate ' + knownBuilders[builderType] + ' builder: ' + err);
|
||||
throw new CordovaError('Failed to instantiate ProjectBuilder builder: ' + err);
|
||||
}
|
||||
};
|
||||
|
||||
66
bin/templates/cordova/lib/check_reqs.js
vendored
@@ -19,8 +19,6 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
/* jshint sub:true */
|
||||
|
||||
var shelljs = require('shelljs');
|
||||
var child_process = require('child_process');
|
||||
var Q = require('q');
|
||||
@@ -41,17 +39,6 @@ function forgivingWhichSync (cmd) {
|
||||
}
|
||||
}
|
||||
|
||||
function tryCommand (cmd, errMsg, catchStderr) {
|
||||
var d = Q.defer();
|
||||
child_process.exec(cmd, function (err, stdout, stderr) {
|
||||
if (err) d.reject(new CordovaError(errMsg));
|
||||
// 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
|
||||
else d.resolve((catchStderr ? stderr : stdout).trim());
|
||||
});
|
||||
return d.promise;
|
||||
}
|
||||
|
||||
module.exports.isWindows = function () {
|
||||
return (os.platform() === 'win32');
|
||||
};
|
||||
@@ -207,19 +194,24 @@ module.exports.check_java = function () {
|
||||
}
|
||||
}
|
||||
}).then(function () {
|
||||
var msg =
|
||||
'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';
|
||||
if (process.env['JAVA_HOME']) {
|
||||
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'] + '\n';
|
||||
}
|
||||
// We use tryCommand with catchStderr = true, because
|
||||
// javac writes version info to stderr instead of stdout
|
||||
return tryCommand('javac -version', msg, true).then(function (output) {
|
||||
// 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);
|
||||
return match && match[1];
|
||||
});
|
||||
return Q.denodeify(child_process.exec)('javac -version')
|
||||
.then(outputs => {
|
||||
// outputs contains two entries: stdout and stderr
|
||||
// Java <= 8 writes version info to stderr, Java >= 9 to stdout
|
||||
const output = outputs.join('').trim();
|
||||
const match = /javac\s+([\d.]+)/i.exec(output);
|
||||
return match && match[1];
|
||||
}, () => {
|
||||
var msg =
|
||||
'Failed to run "javac -version", make sure that you have a JDK version 8 installed.\n' +
|
||||
'You can get it from the following location:\n' +
|
||||
'https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html';
|
||||
if (process.env['JAVA_HOME']) {
|
||||
msg += '\n\n';
|
||||
msg += 'Your JAVA_HOME is invalid: ' + process.env['JAVA_HOME'];
|
||||
}
|
||||
throw new CordovaError(msg);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -239,6 +231,14 @@ module.exports.check_android = function () {
|
||||
// First ensure ANDROID_HOME is set
|
||||
// If we have no hints (nothing in PATH), try a few default locations
|
||||
if (!hasAndroidHome && !androidCmdPath && !adbInPath && !avdmanagerInPath) {
|
||||
if (process.env['ANDROID_SDK_ROOT']) {
|
||||
// Quick fix to set ANDROID_HOME according to ANDROID_SDK_ROOT
|
||||
// if ANDROID_HOME is **not** defined and
|
||||
// ANDROID_SDK_ROOT **is** defined
|
||||
// according to environment variables as documented in:
|
||||
// https://developer.android.com/studio/command-line/variables
|
||||
maybeSetAndroidHome(path.join(process.env['ANDROID_SDK_ROOT']));
|
||||
}
|
||||
if (module.exports.isWindows()) {
|
||||
// Android Studio 1.0 installer
|
||||
maybeSetAndroidHome(path.join(process.env['LOCALAPPDATA'], 'Android', 'sdk'));
|
||||
@@ -363,15 +363,19 @@ module.exports.check_android_target = function (originalError) {
|
||||
// Returns a promise.
|
||||
module.exports.run = function () {
|
||||
return Q.all([this.check_java(), this.check_android()]).then(function (values) {
|
||||
console.log('ANDROID_HOME=' + process.env['ANDROID_HOME']);
|
||||
console.log('JAVA_HOME=' + process.env['JAVA_HOME']);
|
||||
console.log('Checking Java JDK and Android SDK versions');
|
||||
console.log('ANDROID_SDK_ROOT=' + process.env['ANDROID_SDK_ROOT'] + ' (recommended setting)');
|
||||
console.log('ANDROID_HOME=' + process.env['ANDROID_HOME'] + ' (DEPRECATED)');
|
||||
|
||||
if (!values[0]) {
|
||||
throw new CordovaError('Requirements check failed for JDK 1.8 or greater');
|
||||
if (!String(values[0]).startsWith('1.8.')) {
|
||||
throw new CordovaError(
|
||||
'Requirements check failed for JDK 8 (\'1.8.*\')! Detected version: ' + values[0] + '\n' +
|
||||
'Check your ANDROID_SDK_ROOT / JAVA_HOME / PATH environment variables.'
|
||||
);
|
||||
}
|
||||
|
||||
if (!values[1]) {
|
||||
throw new CordovaError('Requirements check failed for Android SDK');
|
||||
throw new CordovaError('Requirements check failed for Android SDK! Android SDK was not detected.');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
114
bin/templates/cordova/lib/config/GradlePropertiesParser.js
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
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.
|
||||
*/
|
||||
|
||||
let fs = require('fs');
|
||||
let path = require('path');
|
||||
let propertiesParser = require('properties-parser');
|
||||
let events = require('cordova-common').events;
|
||||
|
||||
class GradlePropertiesParser {
|
||||
/**
|
||||
* Loads and Edits Gradle Properties File.
|
||||
*
|
||||
* @param {String} platformDir is the path of the Android platform directory
|
||||
*/
|
||||
constructor (platformDir) {
|
||||
this._defaults = {
|
||||
// 10 seconds -> 6 seconds
|
||||
'org.gradle.daemon': 'true',
|
||||
|
||||
// to allow dex in process
|
||||
'org.gradle.jvmargs': '-Xmx2048m',
|
||||
|
||||
// allow NDK to be used - required by Gradle 1.5 plugin
|
||||
'android.useDeprecatedNdk': 'true'
|
||||
|
||||
// Shaves another 100ms, but produces a "try at own risk" warning. Not worth it (yet):
|
||||
// 'org.gradle.parallel': 'true'
|
||||
};
|
||||
|
||||
this.gradleFilePath = path.join(platformDir, 'gradle.properties');
|
||||
}
|
||||
|
||||
configure (userConfigs) {
|
||||
events.emit('verbose', '[Gradle Properties] Preparing Configuration');
|
||||
|
||||
this._initializeEditor();
|
||||
|
||||
events.emit('verbose', '[Gradle Properties] Appending default configuration properties');
|
||||
this._configureProperties(this._defaults);
|
||||
|
||||
events.emit('verbose', '[Gradle Properties] Appending custom configuration properties');
|
||||
this._configureProperties(userConfigs);
|
||||
|
||||
this._save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the properties editor for parsing, setting, etc.
|
||||
*/
|
||||
_initializeEditor () {
|
||||
// Touch empty gradle.properties file if missing.
|
||||
if (!fs.existsSync(this.gradleFilePath)) {
|
||||
events.emit('verbose', '[Gradle Properties] File missing, creating file with Cordova defaults.');
|
||||
fs.writeFileSync(this.gradleFilePath, '', 'utf-8');
|
||||
}
|
||||
|
||||
// Create an editor for parsing, getting, and setting configurations.
|
||||
this.gradleFile = propertiesParser.createEditor(this.gradleFilePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that defaults or user configuration properties are set and
|
||||
* set the missing items.
|
||||
*/
|
||||
_configureProperties (properties) {
|
||||
// Iterate though the properties and set only if missing.
|
||||
Object.keys(properties).forEach(key => {
|
||||
let value = this.gradleFile.get(key);
|
||||
|
||||
if (!value) {
|
||||
// Handles the case of adding missing defaults or new properties that are missing.
|
||||
events.emit('verbose', `[Gradle Properties] Appending configuration item: ${key}=${properties[key]}`);
|
||||
this.gradleFile.set(key, properties[key]);
|
||||
} else if (value !== properties[key]) {
|
||||
if (this._defaults[key] && this._defaults[key] !== properties[key]) {
|
||||
// Since the value does not match default, we will notify the discrepancy with Cordova's recommended value.
|
||||
events.emit('info', `[Gradle Properties] Detected Gradle property "${key}" with the value of "${properties[key]}", Cordova's recommended value is "${this._defaults[key]}"`);
|
||||
} else {
|
||||
// When the current value exists but does not match the new value or does matches the default key value, the new value it set.
|
||||
events.emit('verbose', `[Gradle Properties] Updating Gradle property "${key}" with the value of "${properties[key]}"`);
|
||||
}
|
||||
|
||||
// We will set the new value in either case.
|
||||
this.gradleFile.set(key, properties[key]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves any changes that has been made to the properties file.
|
||||
*/
|
||||
_save () {
|
||||
events.emit('verbose', '[Gradle Properties] Updating and Saving File');
|
||||
this.gradleFile.save();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GradlePropertiesParser;
|
||||
11
bin/templates/cordova/lib/device.js
vendored
@@ -19,7 +19,6 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var Q = require('q');
|
||||
var build = require('./build');
|
||||
var path = require('path');
|
||||
var Adb = require('./Adb');
|
||||
@@ -53,13 +52,13 @@ module.exports.list = function (lookHarder) {
|
||||
module.exports.resolveTarget = function (target) {
|
||||
return this.list(true).then(function (device_list) {
|
||||
if (!device_list || !device_list.length) {
|
||||
return Q.reject(new CordovaError('Failed to deploy to device, no devices found.'));
|
||||
return Promise.reject(new CordovaError('Failed to deploy to device, no devices found.'));
|
||||
}
|
||||
// default device
|
||||
target = target || device_list[0];
|
||||
|
||||
if (device_list.indexOf(target) < 0) {
|
||||
return Q.reject('ERROR: Unable to find target \'' + target + '\'.');
|
||||
return Promise.reject(new CordovaError('ERROR: Unable to find target \'' + target + '\'.'));
|
||||
}
|
||||
|
||||
return build.detectArchitecture(target).then(function (arch) {
|
||||
@@ -74,7 +73,7 @@ module.exports.resolveTarget = function (target) {
|
||||
* Returns a promise.
|
||||
*/
|
||||
module.exports.install = function (target, buildResults) {
|
||||
return Q().then(function () {
|
||||
return Promise.resolve().then(function () {
|
||||
if (target && typeof target === 'object') {
|
||||
return target;
|
||||
}
|
||||
@@ -87,7 +86,7 @@ module.exports.install = function (target, buildResults) {
|
||||
events.emit('log', 'Using apk: ' + apk_path);
|
||||
events.emit('log', 'Package name: ' + pkgName);
|
||||
|
||||
return Adb.install(resolvedTarget.target, apk_path, {replace: true}).catch(function (error) {
|
||||
return Adb.install(resolvedTarget.target, apk_path, { replace: true }).catch(function (error) {
|
||||
// CB-9557 CB-10157 only uninstall and reinstall app if the one that
|
||||
// is already installed on device was signed w/different certificate
|
||||
if (!/INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES/.test(error.toString())) { throw error; }
|
||||
@@ -98,7 +97,7 @@ module.exports.install = function (target, buildResults) {
|
||||
// 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.
|
||||
return Adb.uninstall(resolvedTarget.target, pkgName).then(function () {
|
||||
return Adb.install(resolvedTarget.target, apk_path, {replace: true});
|
||||
return Adb.install(resolvedTarget.target, apk_path, { replace: true });
|
||||
});
|
||||
}).then(function () {
|
||||
// unlock screen
|
||||
|
||||
61
bin/templates/cordova/lib/emulator.js
vendored
@@ -19,8 +19,6 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
/* jshint sub:true */
|
||||
|
||||
var android_versions = require('android-versions');
|
||||
var retry = require('./retry');
|
||||
var build = require('./build');
|
||||
@@ -34,7 +32,6 @@ var shelljs = require('shelljs');
|
||||
var android_sdk = require('./android_sdk');
|
||||
var check_reqs = require('./check_reqs');
|
||||
|
||||
var Q = require('q');
|
||||
var os = require('os');
|
||||
var fs = require('fs');
|
||||
var child_process = require('child_process');
|
||||
@@ -170,15 +167,13 @@ module.exports.list_images_using_android = function () {
|
||||
}
|
||||
*/
|
||||
module.exports.list_images = function () {
|
||||
return Q.fcall(function () {
|
||||
return Promise.resolve().then(function () {
|
||||
if (forgivingWhichSync('avdmanager')) {
|
||||
return module.exports.list_images_using_avdmanager();
|
||||
} else if (forgivingWhichSync('android')) {
|
||||
return module.exports.list_images_using_android();
|
||||
} else {
|
||||
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?');
|
||||
});
|
||||
return Promise.reject(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.
|
||||
@@ -228,13 +223,13 @@ module.exports.best_image = function () {
|
||||
|
||||
// Returns a promise.
|
||||
module.exports.list_started = function () {
|
||||
return Adb.devices({emulators: true});
|
||||
return Adb.devices({ emulators: true });
|
||||
};
|
||||
|
||||
// Returns a promise.
|
||||
// TODO: we should remove this, there's a more robust method under android_sdk.js
|
||||
module.exports.list_targets = function () {
|
||||
return superspawn.spawn('android', ['list', 'targets'], {cwd: os.tmpdir()}).then(function (output) {
|
||||
return superspawn.spawn('android', ['list', 'targets'], { cwd: os.tmpdir() }).then(function (output) {
|
||||
var target_out = output.split('\n');
|
||||
var targets = [];
|
||||
for (var i = target_out.length; i >= 0; i--) {
|
||||
@@ -277,8 +272,8 @@ module.exports.get_available_port = function () {
|
||||
module.exports.start = function (emulator_ID, boot_timeout) {
|
||||
var self = this;
|
||||
|
||||
return Q().then(function () {
|
||||
if (emulator_ID) return Q(emulator_ID);
|
||||
return Promise.resolve().then(function () {
|
||||
if (emulator_ID) return Promise.resolve(emulator_ID);
|
||||
|
||||
return self.best_image().then(function (best) {
|
||||
if (best && best.name) {
|
||||
@@ -287,7 +282,7 @@ module.exports.start = function (emulator_ID, boot_timeout) {
|
||||
}
|
||||
|
||||
var androidCmd = check_reqs.getAbsoluteAndroidCmd();
|
||||
return Q.reject(new CordovaError('No emulator images (avds) found.\n' +
|
||||
return Promise.reject(new CordovaError('No emulator images (avds) found.\n' +
|
||||
'1. Download desired System Image by running: ' + androidCmd + ' sdk\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'));
|
||||
@@ -308,7 +303,7 @@ module.exports.start = function (emulator_ID, boot_timeout) {
|
||||
return self.wait_for_emulator(port);
|
||||
});
|
||||
}).then(function (emulatorId) {
|
||||
if (!emulatorId) { return Q.reject(new CordovaError('Failed to start emulator')); }
|
||||
if (!emulatorId) { return Promise.reject(new CordovaError('Failed to start emulator')); }
|
||||
|
||||
// wait for emulator to boot up
|
||||
process.stdout.write('Waiting for emulator to boot (this may take a while)...');
|
||||
@@ -334,7 +329,7 @@ module.exports.start = function (emulator_ID, boot_timeout) {
|
||||
*/
|
||||
module.exports.wait_for_emulator = function (port) {
|
||||
var self = this;
|
||||
return Q().then(function () {
|
||||
return Promise.resolve().then(function () {
|
||||
var emulator_id = 'emulator-' + port;
|
||||
return Adb.shell(emulator_id, 'getprop dev.bootcomplete').then(function (output) {
|
||||
if (output.indexOf('1') >= 0) {
|
||||
@@ -344,7 +339,9 @@ module.exports.wait_for_emulator = function (port) {
|
||||
}, function (error) {
|
||||
if ((error && error.message &&
|
||||
(error.message.indexOf('not found') > -1)) ||
|
||||
(error.message.indexOf('device offline') > -1)) {
|
||||
(error.message.indexOf('device offline') > -1) ||
|
||||
(error.message.indexOf('device still connecting') > -1) ||
|
||||
(error.message.indexOf('device still authorizing') > -1)) {
|
||||
// emulator not yet started, continue waiting
|
||||
return self.wait_for_emulator(port);
|
||||
} else {
|
||||
@@ -370,10 +367,13 @@ module.exports.wait_for_boot = function (emulator_id, time_remaining) {
|
||||
} else {
|
||||
process.stdout.write('.');
|
||||
|
||||
// Check at regular intervals
|
||||
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;
|
||||
return self.wait_for_boot(emulator_id, updated_time);
|
||||
return new Promise(resolve => {
|
||||
const delay = time_remaining < CHECK_BOOTED_INTERVAL ? time_remaining : CHECK_BOOTED_INTERVAL;
|
||||
|
||||
setTimeout(() => {
|
||||
const updated_time = time_remaining >= 0 ? Math.max(time_remaining - CHECK_BOOTED_INTERVAL, 0) : time_remaining;
|
||||
resolve(self.wait_for_boot(emulator_id, updated_time));
|
||||
}, delay);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -399,7 +399,7 @@ module.exports.create_image = function (name, target) {
|
||||
// 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('Ensure you have targets available by running the "android" command');
|
||||
return Q.reject();
|
||||
return Promise.reject(new CordovaError());
|
||||
}, function (error) {
|
||||
console.error('ERROR : Failed to create emulator image : ');
|
||||
console.error(error);
|
||||
@@ -410,17 +410,17 @@ module.exports.create_image = function (name, target) {
|
||||
module.exports.resolveTarget = function (target) {
|
||||
return this.list_started().then(function (emulator_list) {
|
||||
if (emulator_list.length < 1) {
|
||||
return Q.reject('No running Android emulators found, please start an emulator before deploying your project.');
|
||||
return Promise.reject(new CordovaError('No running Android emulators found, please start an emulator before deploying your project.'));
|
||||
}
|
||||
|
||||
// default emulator
|
||||
target = target || emulator_list[0];
|
||||
if (emulator_list.indexOf(target) < 0) {
|
||||
return Q.reject('Unable to find target \'' + target + '\'. Failed to deploy to emulator.');
|
||||
return Promise.reject(new CordovaError('Unable to find target \'' + target + '\'. Failed to deploy to emulator.'));
|
||||
}
|
||||
|
||||
return build.detectArchitecture(target).then(function (arch) {
|
||||
return {target: target, arch: arch, isEmulator: true};
|
||||
return { target: target, arch: arch, isEmulator: true };
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -435,15 +435,12 @@ module.exports.install = function (givenTarget, buildResults) {
|
||||
|
||||
var target;
|
||||
// We need to find the proper path to the Android Manifest
|
||||
var manifestPath = path.join(__dirname, '..', '..', 'app', 'src', 'main', 'AndroidManifest.xml');
|
||||
if (buildResults.buildMethod === 'gradle') {
|
||||
manifestPath = path.join(__dirname, '../../AndroidManifest.xml');
|
||||
}
|
||||
var manifest = new AndroidManifest(manifestPath);
|
||||
var pkgName = manifest.getPackageId();
|
||||
const manifestPath = path.join(__dirname, '..', '..', 'app', 'src', 'main', 'AndroidManifest.xml');
|
||||
const manifest = new AndroidManifest(manifestPath);
|
||||
const pkgName = manifest.getPackageId();
|
||||
|
||||
// resolve the target emulator
|
||||
return Q().then(function () {
|
||||
return Promise.resolve().then(function () {
|
||||
if (givenTarget && typeof givenTarget === 'object') {
|
||||
return givenTarget;
|
||||
} else {
|
||||
@@ -458,7 +455,7 @@ module.exports.install = function (givenTarget, buildResults) {
|
||||
}).then(function () {
|
||||
// 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.
|
||||
return Q.when().then(function () {
|
||||
return Promise.resolve().then(function () {
|
||||
|
||||
var apk_path = build.findBestApkForArchitecture(buildResults, target.arch);
|
||||
var execOptions = {
|
||||
@@ -478,7 +475,7 @@ module.exports.install = function (givenTarget, buildResults) {
|
||||
events.emit('verbose', 'Installing apk ' + apk + ' on ' + target + '...');
|
||||
|
||||
var command = 'adb -s ' + target + ' install -r "' + apk + '"';
|
||||
return Q.promise(function (resolve, reject) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
child_process.exec(command, opts, function (err, stdout, 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
|
||||
|
||||
@@ -19,23 +19,23 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var device = require('./device'),
|
||||
args = process.argv;
|
||||
var device = require('./device');
|
||||
var args = process.argv;
|
||||
|
||||
if(args.length > 2) {
|
||||
if (args.length > 2) {
|
||||
var install_target;
|
||||
if (args[2].substring(0, 9) == '--target=') {
|
||||
if (args[2].substring(0, 9) === '--target=') {
|
||||
install_target = args[2].substring(9, args[2].length);
|
||||
device.install(install_target).done(null, function(err) {
|
||||
device.install(install_target).catch(function (err) {
|
||||
console.error('ERROR: ' + err);
|
||||
process.exit(2);
|
||||
});
|
||||
} else {
|
||||
} else {
|
||||
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
device.install().done(null, function(err) {
|
||||
device.install().catch(function (err) {
|
||||
console.error('ERROR: ' + err);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
@@ -19,20 +19,20 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var emulator = require('./emulator'),
|
||||
args = process.argv;
|
||||
var emulator = require('./emulator');
|
||||
var args = process.argv;
|
||||
|
||||
var install_target;
|
||||
if(args.length > 2) {
|
||||
if (args[2].substring(0, 9) == '--target=') {
|
||||
if (args.length > 2) {
|
||||
if (args[2].substring(0, 9) === '--target=') {
|
||||
install_target = args[2].substring(9, args[2].length);
|
||||
} else {
|
||||
} else {
|
||||
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emulator.install(install_target).done(null, function(err) {
|
||||
emulator.install(install_target).catch(function (err) {
|
||||
console.error('ERROR: ' + err);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
var devices = require('./device');
|
||||
|
||||
// Usage support for when args are given
|
||||
require('./check_reqs').check_android().then(function() {
|
||||
devices.list().done(function(device_list) {
|
||||
device_list && device_list.forEach(function(dev) {
|
||||
require('./check_reqs').check_android().then(function () {
|
||||
devices.list().then(function (device_list) {
|
||||
device_list && device_list.forEach(function (dev) {
|
||||
console.log(dev);
|
||||
});
|
||||
}, function(err) {
|
||||
}, function (err) {
|
||||
console.error('ERROR: ' + err);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
var emulators = require('./emulator');
|
||||
|
||||
// Usage support for when args are given
|
||||
require('./check_reqs').check_android().then(function() {
|
||||
emulators.list_images().done(function(emulator_list) {
|
||||
emulator_list && emulator_list.forEach(function(emu) {
|
||||
require('./check_reqs').check_android().then(function () {
|
||||
emulators.list_images().then(function (emulator_list) {
|
||||
emulator_list && emulator_list.forEach(function (emu) {
|
||||
console.log(emu.name);
|
||||
});
|
||||
}, function(err) {
|
||||
}, function (err) {
|
||||
console.error('ERROR: ' + err);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
@@ -22,12 +22,12 @@
|
||||
var emulators = require('./emulator');
|
||||
|
||||
// Usage support for when args are given
|
||||
require('./check_reqs').check_android().then(function() {
|
||||
emulators.list_started().done(function(emulator_list) {
|
||||
emulator_list && emulator_list.forEach(function(emu) {
|
||||
require('./check_reqs').check_android().then(function () {
|
||||
emulators.list_started().then(function (emulator_list) {
|
||||
emulator_list && emulator_list.forEach(function (emu) {
|
||||
console.log(emu);
|
||||
});
|
||||
}, function(err) {
|
||||
}, function (err) {
|
||||
console.error('ERROR: ' + err);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
2
bin/templates/cordova/lib/log.js
vendored
@@ -31,7 +31,7 @@ var ROOT = path.join(__dirname, '..', '..');
|
||||
*/
|
||||
module.exports.run = function () {
|
||||
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) {
|
||||
var lines = data ? data.toString().split('\n') : [];
|
||||
|
||||
@@ -20,10 +20,8 @@
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven {
|
||||
url "https://maven.google.com"
|
||||
}
|
||||
}
|
||||
|
||||
// Switch the Android Gradle plugin version requirement depending on the
|
||||
@@ -38,7 +36,7 @@ buildscript {
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: '*.jar')
|
||||
implementation fileTree(dir: 'libs', include: '*.jar')
|
||||
debugCompile project(path: ":CordovaLib", configuration: "debug")
|
||||
releaseCompile project(path: ":CordovaLib", configuration: "release")
|
||||
}
|
||||
@@ -46,7 +44,6 @@ dependencies {
|
||||
android {
|
||||
compileSdkVersion cdvCompileSdkVersion
|
||||
buildToolsVersion cdvBuildToolsVersion
|
||||
publishNonDefault true
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_6
|
||||
|
||||
92
bin/templates/cordova/lib/pluginHandlers.js
vendored
@@ -14,8 +14,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* jshint unused: vars */
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var shell = require('shelljs');
|
||||
@@ -28,22 +26,7 @@ var handlers = {
|
||||
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));
|
||||
|
||||
var dest = path.join(obj.targetDir, path.basename(obj.src));
|
||||
|
||||
// TODO: This code needs to be replaced, since the core plugins need to be re-mapped to a different location in
|
||||
// a later plugins release. This is for legacy plugins to work with Cordova.
|
||||
|
||||
if (options && options.android_studio === true) {
|
||||
// If a Java file is using the new directory structure, don't penalize it
|
||||
if (!obj.targetDir.includes('app/src/main')) {
|
||||
if (obj.src.endsWith('.java')) {
|
||||
dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src));
|
||||
} else if (obj.src.endsWith('.xml')) {
|
||||
// We are making a huge assumption here that XML files will be going to res/xml or values/xml
|
||||
dest = path.join('app/src/main', obj.targetDir, path.basename(obj.src));
|
||||
}
|
||||
}
|
||||
}
|
||||
var dest = getInstallDestination(obj);
|
||||
|
||||
if (options && options.force) {
|
||||
copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
|
||||
@@ -52,44 +35,34 @@ var handlers = {
|
||||
}
|
||||
},
|
||||
uninstall: function (obj, plugin, project, options) {
|
||||
var dest = path.join(obj.targetDir, path.basename(obj.src));
|
||||
var dest = getInstallDestination(obj);
|
||||
|
||||
if (options && options.android_studio === true) {
|
||||
dest = path.join('app/src/main/java', obj.targetDir.substring(4), path.basename(obj.src));
|
||||
// TODO: Add Koltin extension to uninstall, since they are handled like Java files
|
||||
if (obj.src.endsWith('java')) {
|
||||
deleteJava(project.projectDir, dest);
|
||||
} else {
|
||||
// Just remove the file, not the whole parent directory
|
||||
removeFile(project.projectDir, dest);
|
||||
}
|
||||
|
||||
deleteJava(project.projectDir, dest);
|
||||
}
|
||||
},
|
||||
'lib-file': {
|
||||
install: function (obj, plugin, project, options) {
|
||||
var dest = path.join('libs', path.basename(obj.src));
|
||||
if (options && options.android_studio === true) {
|
||||
dest = path.join('app/libs', path.basename(obj.src));
|
||||
}
|
||||
var dest = path.join('app/libs', path.basename(obj.src));
|
||||
copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
|
||||
},
|
||||
uninstall: function (obj, plugin, project, options) {
|
||||
var dest = path.join('libs', path.basename(obj.src));
|
||||
if (options && options.android_studio === true) {
|
||||
dest = path.join('app/libs', path.basename(obj.src));
|
||||
}
|
||||
var dest = path.join('app/libs', path.basename(obj.src));
|
||||
removeFile(project.projectDir, dest);
|
||||
}
|
||||
},
|
||||
'resource-file': {
|
||||
install: function (obj, plugin, project, options) {
|
||||
var dest = path.normalize(obj.target);
|
||||
if (options && options.android_studio === true) {
|
||||
dest = path.join('app/src/main', dest);
|
||||
}
|
||||
var dest = path.join('app', 'src', 'main', obj.target);
|
||||
copyFile(plugin.dir, obj.src, project.projectDir, dest, !!(options && options.link));
|
||||
},
|
||||
uninstall: function (obj, plugin, project, options) {
|
||||
var dest = path.normalize(obj.target);
|
||||
if (options && options.android_studio === true) {
|
||||
dest = path.join('app/src/main', dest);
|
||||
}
|
||||
var dest = path.join('app', 'src', 'main', obj.target);
|
||||
removeFile(project.projectDir, dest);
|
||||
}
|
||||
},
|
||||
@@ -318,3 +291,44 @@ function removeFileAndParents (baseDir, destFile, stopper) {
|
||||
function generateAttributeError (attribute, element, id) {
|
||||
return 'Required attribute "' + attribute + '" not specified in <' + element + '> element from plugin: ' + id;
|
||||
}
|
||||
|
||||
function getInstallDestination (obj) {
|
||||
var APP_MAIN_PREFIX = 'app/src/main';
|
||||
var PATH_SEPARATOR = '/';
|
||||
|
||||
var PATH_SEP_MATCH = '\\' + PATH_SEPARATOR;
|
||||
var PATH_SEP_OR_EOL_MATCH = '(\\' + PATH_SEPARATOR + '|$)';
|
||||
|
||||
var appReg = new RegExp('^app' + PATH_SEP_OR_EOL_MATCH);
|
||||
var libsReg = new RegExp('^libs' + PATH_SEP_OR_EOL_MATCH);
|
||||
var srcReg = new RegExp('^src' + PATH_SEP_OR_EOL_MATCH);
|
||||
var srcMainReg = new RegExp('^src' + PATH_SEP_MATCH + 'main' + PATH_SEP_OR_EOL_MATCH);
|
||||
|
||||
if (appReg.test(obj.targetDir)) {
|
||||
// If any source file is using the new app directory structure,
|
||||
// don't penalize it
|
||||
return path.join(obj.targetDir, path.basename(obj.src));
|
||||
} else {
|
||||
// Plugin using deprecated target directory structure (GH-580)
|
||||
if (obj.src.endsWith('.java')) {
|
||||
return path.join(APP_MAIN_PREFIX, 'java', obj.targetDir.replace(srcReg, ''),
|
||||
path.basename(obj.src));
|
||||
} else if (obj.src.endsWith('.aidl')) {
|
||||
return path.join(APP_MAIN_PREFIX, 'aidl', obj.targetDir.replace(srcReg, ''),
|
||||
path.basename(obj.src));
|
||||
} else if (libsReg.test(obj.targetDir)) {
|
||||
if (obj.src.endsWith('.so')) {
|
||||
return path.join(APP_MAIN_PREFIX, 'jniLibs', obj.targetDir.replace(libsReg, ''),
|
||||
path.basename(obj.src));
|
||||
} else {
|
||||
return path.join('app', obj.targetDir, path.basename(obj.src));
|
||||
}
|
||||
} else if (srcMainReg.test(obj.targetDir)) {
|
||||
return path.join('app', obj.targetDir, path.basename(obj.src));
|
||||
}
|
||||
|
||||
// For all other source files not using the new app directory structure,
|
||||
// add 'app/src/main' to the targetDir
|
||||
return path.join(APP_MAIN_PREFIX, obj.targetDir, path.basename(obj.src));
|
||||
}
|
||||
}
|
||||
|
||||
296
bin/templates/cordova/lib/prepare.js
vendored
@@ -33,6 +33,8 @@ var PlatformJson = require('cordova-common').PlatformJson;
|
||||
var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
|
||||
var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
|
||||
|
||||
const GradlePropertiesParser = require('./config/GradlePropertiesParser');
|
||||
|
||||
module.exports.prepare = function (cordovaProject, options) {
|
||||
var self = this;
|
||||
|
||||
@@ -41,6 +43,19 @@ module.exports.prepare = function (cordovaProject, options) {
|
||||
|
||||
this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations);
|
||||
|
||||
// Get the min SDK version from config.xml
|
||||
const minSdkVersion = this._config.getPreference('android-minSdkVersion', 'android');
|
||||
const maxSdkVersion = this._config.getPreference('android-maxSdkVersion', 'android');
|
||||
const targetSdkVersion = this._config.getPreference('android-targetSdkVersion', 'android');
|
||||
|
||||
let gradlePropertiesUserConfig = {};
|
||||
if (minSdkVersion) gradlePropertiesUserConfig.cdvMinSdkVersion = minSdkVersion;
|
||||
if (maxSdkVersion) gradlePropertiesUserConfig.cdvMaxSdkVersion = maxSdkVersion;
|
||||
if (targetSdkVersion) gradlePropertiesUserConfig.cdvTargetSdkVersion = targetSdkVersion;
|
||||
|
||||
let gradlePropertiesParser = new GradlePropertiesParser(this.locations.root);
|
||||
gradlePropertiesParser.configure(gradlePropertiesUserConfig);
|
||||
|
||||
// Update own www dir with project's www assets and plugins' assets and js-files
|
||||
return Q.when(updateWww(cordovaProject, this.locations)).then(function () {
|
||||
// update project according to config.xml changes.
|
||||
@@ -178,7 +193,7 @@ function updateProjectAccordingTo (platformConfig, locations) {
|
||||
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);
|
||||
|
||||
// Java packages cannot support dashes
|
||||
@@ -194,9 +209,6 @@ function updateProjectAccordingTo (platformConfig, locations) {
|
||||
manifest.setVersionName(platformConfig.version())
|
||||
.setVersionCode(platformConfig.android_versionCode() || default_versionCode(platformConfig.version()))
|
||||
.setPackageId(androidPkgName)
|
||||
.setMinSdkVersion(platformConfig.getPreference('android-minSdkVersion', 'android'))
|
||||
.setMaxSdkVersion(platformConfig.getPreference('android-maxSdkVersion', 'android'))
|
||||
.setTargetSdkVersion(platformConfig.getPreference('android-targetSdkVersion', 'android'))
|
||||
.write();
|
||||
|
||||
// Java file paths shouldn't be hard coded
|
||||
@@ -265,6 +277,14 @@ function getImageResourcePath (resourcesDir, type, density, name, sourceName) {
|
||||
return resourcePath;
|
||||
}
|
||||
|
||||
function getAdaptiveImageResourcePath (resourcesDir, type, density, name, sourceName) {
|
||||
if (/\.9\.png$/.test(sourceName)) {
|
||||
name = name.replace(/\.png$/, '.9.png');
|
||||
}
|
||||
var resourcePath = path.join(resourcesDir, (density ? type + '-' + density + '-v26' : type), name);
|
||||
return resourcePath;
|
||||
}
|
||||
|
||||
function updateSplashes (cordovaProject, platformResourcesDir) {
|
||||
var resources = cordovaProject.projectConfig.getSplashScreens('android');
|
||||
|
||||
@@ -314,20 +334,197 @@ function cleanSplashes (projectRoot, projectConfig, platformResourcesDir) {
|
||||
}
|
||||
|
||||
function updateIcons (cordovaProject, platformResourcesDir) {
|
||||
var icons = cordovaProject.projectConfig.getIcons('android');
|
||||
let icons = cordovaProject.projectConfig.getIcons('android');
|
||||
|
||||
// if there are icon elements in config.xml
|
||||
// Skip if there are no app defined icons in config.xml
|
||||
if (icons.length === 0) {
|
||||
events.emit('verbose', 'This app does not have launcher icons defined');
|
||||
return;
|
||||
}
|
||||
|
||||
var resourceMap = mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'icon.png');
|
||||
// 1. loop icons determin if there is an error in the setup.
|
||||
// 2. during initial loop, also setup for legacy support.
|
||||
let errorMissingAttributes = [];
|
||||
let errorLegacyIconNeeded = [];
|
||||
let hasAdaptive = false;
|
||||
icons.forEach((icon, key) => {
|
||||
if (
|
||||
(icon.background && !icon.foreground)
|
||||
|| (!icon.background && icon.foreground)
|
||||
|| (!icon.background && !icon.foreground && !icon.src)
|
||||
) {
|
||||
errorMissingAttributes.push(icon.density ? icon.density : 'size=' + (icon.height || icon.width));
|
||||
}
|
||||
|
||||
var android_icons = {};
|
||||
var default_icon;
|
||||
if (icon.foreground) {
|
||||
hasAdaptive = true;
|
||||
|
||||
if (
|
||||
!icon.src
|
||||
&& (
|
||||
icon.foreground.startsWith('@color')
|
||||
|| path.extname(path.basename(icon.foreground)) === '.xml'
|
||||
)
|
||||
) {
|
||||
errorLegacyIconNeeded.push(icon.density ? icon.density : 'size=' + (icon.height || icon.width));
|
||||
} else if (!icon.src) {
|
||||
icons[key].src = icon.foreground;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let errorMessage = [];
|
||||
if (errorMissingAttributes.length > 0) {
|
||||
errorMessage.push('One of the following attributes are set but missing the other for the density type: ' + errorMissingAttributes.join(', ') + '. Please ensure that all require attributes are defined.');
|
||||
}
|
||||
|
||||
if (errorLegacyIconNeeded.length > 0) {
|
||||
errorMessage.push('For the following icons with the density of: ' + errorLegacyIconNeeded.join(', ') + ', adaptive foreground with a defined color or vector can not be used as a standard fallback icon for older Android devices. To support older Android environments, please provide a value for the src attribute.');
|
||||
}
|
||||
|
||||
if (errorMessage.length > 0) {
|
||||
throw new CordovaError(errorMessage.join(' '));
|
||||
}
|
||||
|
||||
let resourceMap = Object.assign(
|
||||
{},
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.png'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),
|
||||
mapImageResources(cordovaProject.root, platformResourcesDir, 'mipmap', 'ic_launcher.xml')
|
||||
);
|
||||
|
||||
let preparedIcons = prepareIcons(icons);
|
||||
|
||||
if (hasAdaptive) {
|
||||
resourceMap = updateIconResourceForAdaptive(preparedIcons, resourceMap, platformResourcesDir);
|
||||
}
|
||||
|
||||
resourceMap = updateIconResourceForLegacy(preparedIcons, resourceMap, platformResourcesDir);
|
||||
|
||||
events.emit('verbose', 'Updating icons at ' + platformResourcesDir);
|
||||
FileUpdater.updatePaths(resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
||||
}
|
||||
|
||||
function updateIconResourceForAdaptive (preparedIcons, resourceMap, platformResourcesDir) {
|
||||
let android_icons = preparedIcons.android_icons;
|
||||
let default_icon = preparedIcons.default_icon;
|
||||
|
||||
// The source paths for icons and splashes are relative to
|
||||
// project's config.xml location, so we use it as base path.
|
||||
let background;
|
||||
let foreground;
|
||||
let targetPathBackground;
|
||||
let targetPathForeground;
|
||||
|
||||
for (let density in android_icons) {
|
||||
let backgroundVal = '@mipmap/ic_launcher_background';
|
||||
let foregroundVal = '@mipmap/ic_launcher_foreground';
|
||||
|
||||
background = android_icons[density].background;
|
||||
foreground = android_icons[density].foreground;
|
||||
|
||||
if (background.startsWith('@color')) {
|
||||
// Colors Use Case
|
||||
backgroundVal = background; // Example: @color/background_foobar_1
|
||||
} else if (path.extname(path.basename(background)) === '.xml') {
|
||||
// Vector Use Case
|
||||
targetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_background.xml', path.basename(android_icons[density].background));
|
||||
resourceMap[targetPathBackground] = android_icons[density].background;
|
||||
} else if (path.extname(path.basename(background)) === '.png') {
|
||||
// Images Use Case
|
||||
targetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_background.png', path.basename(android_icons[density].background));
|
||||
resourceMap[targetPathBackground] = android_icons[density].background;
|
||||
}
|
||||
|
||||
if (foreground.startsWith('@color')) {
|
||||
// Colors Use Case
|
||||
foregroundVal = foreground;
|
||||
} else if (path.extname(path.basename(foreground)) === '.xml') {
|
||||
// Vector Use Case
|
||||
targetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_foreground.xml', path.basename(android_icons[density].foreground));
|
||||
resourceMap[targetPathForeground] = android_icons[density].foreground;
|
||||
} else if (path.extname(path.basename(foreground)) === '.png') {
|
||||
// Images Use Case
|
||||
targetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher_foreground.png', path.basename(android_icons[density].foreground));
|
||||
resourceMap[targetPathForeground] = android_icons[density].foreground;
|
||||
}
|
||||
|
||||
// create an XML for DPI and set color
|
||||
const icLauncherTemplate = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="` + backgroundVal + `" />
|
||||
<foreground android:drawable="` + foregroundVal + `" />
|
||||
</adaptive-icon>`;
|
||||
|
||||
let launcherXmlPath = path.join(platformResourcesDir, 'mipmap-' + density + '-v26', 'ic_launcher.xml');
|
||||
|
||||
// Remove the XML from the resourceMap so the file does not get removed.
|
||||
delete resourceMap[launcherXmlPath];
|
||||
|
||||
fs.writeFileSync(path.resolve(launcherXmlPath), icLauncherTemplate);
|
||||
}
|
||||
|
||||
// There's no "default" drawable, so assume default == mdpi.
|
||||
if (default_icon && !android_icons.mdpi) {
|
||||
let defaultTargetPathBackground;
|
||||
let defaultTargetPathForeground;
|
||||
|
||||
if (background.startsWith('@color')) {
|
||||
// Colors Use Case
|
||||
targetPathBackground = default_icon.background;
|
||||
} else if (path.extname(path.basename(background)) === '.xml') {
|
||||
// Vector Use Case
|
||||
defaultTargetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_background.xml', path.basename(default_icon.background));
|
||||
resourceMap[defaultTargetPathBackground] = default_icon.background;
|
||||
} else if (path.extname(path.basename(background)) === '.png') {
|
||||
// Images Use Case
|
||||
defaultTargetPathBackground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_background.png', path.basename(default_icon.background));
|
||||
resourceMap[defaultTargetPathBackground] = default_icon.background;
|
||||
}
|
||||
|
||||
if (foreground.startsWith('@color')) {
|
||||
// Colors Use Case
|
||||
targetPathForeground = default_icon.foreground;
|
||||
} else if (path.extname(path.basename(foreground)) === '.xml') {
|
||||
// Vector Use Case
|
||||
defaultTargetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_foreground.xml', path.basename(default_icon.foreground));
|
||||
resourceMap[defaultTargetPathForeground] = default_icon.foreground;
|
||||
} else if (path.extname(path.basename(foreground)) === '.png') {
|
||||
// Images Use Case
|
||||
defaultTargetPathForeground = getAdaptiveImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher_foreground.png', path.basename(default_icon.foreground));
|
||||
resourceMap[defaultTargetPathForeground] = default_icon.foreground;
|
||||
}
|
||||
}
|
||||
|
||||
return resourceMap;
|
||||
}
|
||||
|
||||
function updateIconResourceForLegacy (preparedIcons, resourceMap, platformResourcesDir) {
|
||||
let android_icons = preparedIcons.android_icons;
|
||||
let default_icon = preparedIcons.default_icon;
|
||||
|
||||
// The source paths for icons and splashes are relative to
|
||||
// project's config.xml location, so we use it as base path.
|
||||
for (var density in android_icons) {
|
||||
var targetPath = getImageResourcePath(platformResourcesDir, 'mipmap', density, 'ic_launcher.png', path.basename(android_icons[density].src));
|
||||
resourceMap[targetPath] = android_icons[density].src;
|
||||
}
|
||||
|
||||
// There's no "default" drawable, so assume default == mdpi.
|
||||
if (default_icon && !android_icons.mdpi) {
|
||||
var defaultTargetPath = getImageResourcePath(platformResourcesDir, 'mipmap', 'mdpi', 'ic_launcher.png', path.basename(default_icon.src));
|
||||
resourceMap[defaultTargetPath] = default_icon.src;
|
||||
}
|
||||
|
||||
return resourceMap;
|
||||
}
|
||||
|
||||
function prepareIcons (icons) {
|
||||
// http://developer.android.com/design/style/iconography.html
|
||||
var sizeToDensityMap = {
|
||||
const SIZE_TO_DENSITY_MAP = {
|
||||
36: 'ldpi',
|
||||
48: 'mdpi',
|
||||
72: 'hdpi',
|
||||
@@ -335,11 +532,15 @@ function updateIcons (cordovaProject, platformResourcesDir) {
|
||||
144: 'xxhdpi',
|
||||
192: 'xxxhdpi'
|
||||
};
|
||||
|
||||
let android_icons = {};
|
||||
let default_icon;
|
||||
|
||||
// find the best matching icon for a given density or size
|
||||
// @output android_icons
|
||||
var parseIcon = function (icon, icon_size) {
|
||||
// do I have a platform icon for that density already
|
||||
var density = icon.density || sizeToDensityMap[icon_size];
|
||||
var density = icon.density || SIZE_TO_DENSITY_MAP[icon_size];
|
||||
if (!density) {
|
||||
// invalid icon defition ( or unsupported size)
|
||||
return;
|
||||
@@ -355,12 +556,34 @@ function updateIcons (cordovaProject, platformResourcesDir) {
|
||||
for (var i = 0; i < icons.length; i++) {
|
||||
var icon = icons[i];
|
||||
var size = icon.width;
|
||||
|
||||
if (!size) {
|
||||
size = icon.height;
|
||||
}
|
||||
|
||||
if (!size && !icon.density) {
|
||||
if (default_icon) {
|
||||
events.emit('verbose', 'Found extra default icon: ' + icon.src + ' (ignoring in favor of ' + default_icon.src + ')');
|
||||
let found = {};
|
||||
let favor = {};
|
||||
|
||||
// populating found icon.
|
||||
if (icon.background && icon.foreground) {
|
||||
found.background = icon.background;
|
||||
found.foreground = icon.foreground;
|
||||
}
|
||||
if (icon.src) {
|
||||
found.src = icon.src;
|
||||
}
|
||||
|
||||
if (default_icon.background && default_icon.foreground) {
|
||||
favor.background = default_icon.background;
|
||||
favor.foreground = default_icon.foreground;
|
||||
}
|
||||
if (default_icon.src) {
|
||||
favor.src = default_icon.src;
|
||||
}
|
||||
|
||||
events.emit('verbose', 'Found extra default icon: ' + JSON.stringify(found) + ' and ignoring in favor of ' + JSON.stringify(favor) + '.');
|
||||
} else {
|
||||
default_icon = icon;
|
||||
}
|
||||
@@ -369,36 +592,35 @@ function updateIcons (cordovaProject, platformResourcesDir) {
|
||||
}
|
||||
}
|
||||
|
||||
// The source paths for icons and splashes are relative to
|
||||
// project's config.xml location, so we use it as base path.
|
||||
for (var density in android_icons) {
|
||||
var targetPath = getImageResourcePath(
|
||||
platformResourcesDir, 'mipmap', density, 'icon.png', path.basename(android_icons[density].src));
|
||||
resourceMap[targetPath] = android_icons[density].src;
|
||||
}
|
||||
|
||||
// There's no "default" drawable, so assume default == mdpi.
|
||||
if (default_icon && !android_icons.mdpi) {
|
||||
var defaultTargetPath = getImageResourcePath(
|
||||
platformResourcesDir, 'mipmap', 'mdpi', 'icon.png', path.basename(default_icon.src));
|
||||
resourceMap[defaultTargetPath] = default_icon.src;
|
||||
}
|
||||
|
||||
events.emit('verbose', 'Updating icons at ' + platformResourcesDir);
|
||||
FileUpdater.updatePaths(
|
||||
resourceMap, { rootDir: cordovaProject.root }, logFileOp);
|
||||
return {
|
||||
android_icons: android_icons,
|
||||
default_icon: default_icon
|
||||
};
|
||||
}
|
||||
|
||||
function cleanIcons (projectRoot, projectConfig, platformResourcesDir) {
|
||||
var icons = projectConfig.getIcons('android');
|
||||
if (icons.length > 0) {
|
||||
var resourceMap = mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'icon.png');
|
||||
events.emit('verbose', 'Cleaning icons at ' + platformResourcesDir);
|
||||
|
||||
// No source paths are specified in the map, so updatePaths() will delete the target files.
|
||||
FileUpdater.updatePaths(
|
||||
resourceMap, { rootDir: projectRoot, all: true }, logFileOp);
|
||||
// Skip if there are no app defined icons in config.xml
|
||||
if (icons.length === 0) {
|
||||
events.emit('verbose', 'This app does not have launcher icons defined');
|
||||
return;
|
||||
}
|
||||
|
||||
let resourceMap = Object.assign(
|
||||
{},
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher.png'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.png'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_background.png'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_foreground.xml'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher_background.xml'),
|
||||
mapImageResources(projectRoot, platformResourcesDir, 'mipmap', 'ic_launcher.xml')
|
||||
);
|
||||
|
||||
events.emit('verbose', 'Cleaning icons at ' + platformResourcesDir);
|
||||
|
||||
// No source paths are specified in the map, so updatePaths() will delete the target files.
|
||||
FileUpdater.updatePaths(resourceMap, { rootDir: projectRoot, all: true }, logFileOp);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -446,7 +668,7 @@ function cleanFileResources (projectRoot, projectConfig, platformDir) {
|
||||
|
||||
FileUpdater.updatePaths(
|
||||
resourceMap, {
|
||||
rootDir: projectRoot, all: true}, logFileOp);
|
||||
rootDir: projectRoot, all: true }, logFileOp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
20
bin/templates/cordova/lib/retry.js
vendored
@@ -19,8 +19,6 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
/* jshint node: true */
|
||||
|
||||
'use strict';
|
||||
|
||||
var events = require('cordova-common').events;
|
||||
@@ -29,21 +27,20 @@ var events = require('cordova-common').events;
|
||||
* Retry a promise-returning function a number of times, propagating its
|
||||
* results on success or throwing its error on a failed final attempt.
|
||||
*
|
||||
* @arg {Number} attemts_left - The number of times to retry the passed call.
|
||||
* @arg {Number} attemptsLeft - The number of times to retry the passed call.
|
||||
* @arg {Function} promiseFunction - A function that returns a promise.
|
||||
* @arg {...} - Arguments to pass to promiseFunction.
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
module.exports.retryPromise = function (attemts_left, promiseFunction) {
|
||||
module.exports.retryPromise = function (attemptsLeft, promiseFunction) {
|
||||
|
||||
// NOTE:
|
||||
// get all trailing arguments, by skipping the first two (attemts_left and
|
||||
// get all trailing arguments, by skipping the first two (attemptsLeft and
|
||||
// promiseFunction) because they shouldn't get passed to promiseFunction
|
||||
var promiseFunctionArguments = Array.prototype.slice.call(arguments, 2);
|
||||
|
||||
return promiseFunction.apply(undefined, promiseFunctionArguments).then(
|
||||
|
||||
// on success pass results through
|
||||
function onFulfilled (value) {
|
||||
return value;
|
||||
@@ -51,17 +48,16 @@ module.exports.retryPromise = function (attemts_left, promiseFunction) {
|
||||
|
||||
// on rejection either retry, or throw the error
|
||||
function onRejected (error) {
|
||||
attemptsLeft -= 1;
|
||||
|
||||
attemts_left -= 1;
|
||||
|
||||
if (attemts_left < 1) {
|
||||
if (attemptsLeft < 1) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
events.emit('verbose', 'A retried call failed. Retrying ' + attemts_left + ' more time(s).');
|
||||
events.emit('verbose', 'A retried call failed. Retrying ' + attemptsLeft + ' more time(s).');
|
||||
|
||||
// retry call self again with the same arguments, except attemts_left is now lower
|
||||
var fullArguments = [attemts_left, promiseFunction].concat(promiseFunctionArguments);
|
||||
// retry call self again with the same arguments, except attemptsLeft is now lower
|
||||
var fullArguments = [attemptsLeft, promiseFunction].concat(promiseFunctionArguments);
|
||||
return module.exports.retryPromise.apply(undefined, fullArguments);
|
||||
}
|
||||
);
|
||||
|
||||
26
bin/templates/cordova/lib/run.js
vendored
@@ -19,13 +19,11 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
/* jshint loopfunc:true */
|
||||
|
||||
var path = require('path');
|
||||
var build = require('./build');
|
||||
var emulator = require('./emulator');
|
||||
var device = require('./device');
|
||||
var Q = require('q');
|
||||
var PackageType = require('./PackageType');
|
||||
var events = require('cordova-common').events;
|
||||
|
||||
function getInstallTarget (runOptions) {
|
||||
@@ -52,6 +50,7 @@ function getInstallTarget (runOptions) {
|
||||
* @return {Promise}
|
||||
*/
|
||||
module.exports.run = function (runOptions) {
|
||||
runOptions = runOptions || {};
|
||||
|
||||
var self = this;
|
||||
var install_target = getInstallTarget(runOptions);
|
||||
@@ -103,16 +102,25 @@ module.exports.run = function (runOptions) {
|
||||
});
|
||||
});
|
||||
}).then(function (resolvedTarget) {
|
||||
// Better just call self.build, but we're doing some processing of
|
||||
// build results (according to platformApi spec) so they are in different
|
||||
// format than emulator.install expects.
|
||||
// TODO: Update emulator/device.install to handle this change
|
||||
return build.run.call(self, runOptions, resolvedTarget).then(function (buildResults) {
|
||||
if (resolvedTarget.isEmulator) {
|
||||
return new Promise((resolve) => {
|
||||
const builder = require('./builders/builders').getBuilder();
|
||||
const buildOptions = require('./build').parseBuildOptions(runOptions, null, self.root);
|
||||
|
||||
// Android app bundles cannot be deployed directly to the device
|
||||
if (buildOptions.packageType === PackageType.BUNDLE) {
|
||||
const packageTypeErrorMessage = 'Package type "bundle" is not supported during cordova run.';
|
||||
events.emit('error', packageTypeErrorMessage);
|
||||
throw packageTypeErrorMessage;
|
||||
}
|
||||
|
||||
resolve(builder.fetchBuildResults(buildOptions.buildType, buildOptions.arch));
|
||||
}).then(function (buildResults) {
|
||||
if (resolvedTarget && resolvedTarget.isEmulator) {
|
||||
return emulator.wait_for_boot(resolvedTarget.target).then(function () {
|
||||
return emulator.install(resolvedTarget, buildResults);
|
||||
});
|
||||
}
|
||||
|
||||
return device.install(resolvedTarget, buildResults);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,21 +19,20 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var emulator = require('./emulator'),
|
||||
args = process.argv;
|
||||
var emulator = require('./emulator');
|
||||
var args = process.argv;
|
||||
|
||||
var install_target;
|
||||
if(args.length > 2) {
|
||||
if (args[2].substring(0, 9) == '--target=') {
|
||||
if (args.length > 2) {
|
||||
if (args[2].substring(0, 9) === '--target=') {
|
||||
install_target = args[2].substring(9, args[2].length);
|
||||
} else {
|
||||
} else {
|
||||
console.error('ERROR : argument \'' + args[2] + '\' not recognized.');
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emulator.start(install_target).done(null, function(err) {
|
||||
emulator.start(install_target).catch(function (err) {
|
||||
console.error('ERROR: ' + err);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
|
||||
@@ -19,17 +19,17 @@
|
||||
under the License.
|
||||
*/
|
||||
|
||||
var log = require('./lib/log'),
|
||||
reqs = require('./lib/check_reqs'),
|
||||
args = process.argv;
|
||||
var log = require('./lib/log');
|
||||
var reqs = require('./lib/check_reqs');
|
||||
var args = process.argv;
|
||||
|
||||
// Usage support for when args are given
|
||||
if(args.length > 2) {
|
||||
if (args.length > 2) {
|
||||
log.help();
|
||||
} else {
|
||||
reqs.run().done(function() {
|
||||
reqs.run().done(function () {
|
||||
return log.run();
|
||||
}, function(err) {
|
||||
}, function (err) {
|
||||
console.error('ERROR: ' + err);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
@@ -24,22 +24,23 @@ var nopt = require('nopt');
|
||||
var path = require('path');
|
||||
|
||||
// Support basic help commands
|
||||
if(['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0)
|
||||
if (['--help', '/?', '-h', 'help', '-help', '/help'].indexOf(process.argv[2]) >= 0) {
|
||||
require('./lib/run').help();
|
||||
}
|
||||
|
||||
// Do some basic argument parsing
|
||||
var runOpts = nopt({
|
||||
'verbose' : Boolean,
|
||||
'silent' : Boolean,
|
||||
'debug' : Boolean,
|
||||
'release' : Boolean,
|
||||
'verbose': Boolean,
|
||||
'silent': Boolean,
|
||||
'debug': Boolean,
|
||||
'release': Boolean,
|
||||
'nobuild': Boolean,
|
||||
'buildConfig' : path,
|
||||
'archs' : String,
|
||||
'device' : Boolean,
|
||||
'buildConfig': path,
|
||||
'archs': String,
|
||||
'device': Boolean,
|
||||
'emulator': Boolean,
|
||||
'target' : String
|
||||
}, { 'd' : '--verbose' });
|
||||
'target': String
|
||||
}, { 'd': '--verbose' });
|
||||
|
||||
// Make runOptions compatible with PlatformApi run method spec
|
||||
runOpts.argv = runOpts.argv.remain;
|
||||
@@ -47,7 +48,7 @@ runOpts.argv = runOpts.argv.remain;
|
||||
require('./loggingHelper').adjustLoggerLevel(runOpts);
|
||||
|
||||
new Api().run(runOpts)
|
||||
.catch(function(err) {
|
||||
console.error(err, err.stack);
|
||||
process.exit(2);
|
||||
});
|
||||
.catch(function (err) {
|
||||
console.error(err, err.stack);
|
||||
process.exit(2);
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
// Coho updates this line:
|
||||
var VERSION = "7.1.0-dev";
|
||||
var VERSION = "8.1.0";
|
||||
|
||||
module.exports.version = VERSION;
|
||||
|
||||
|
||||
@@ -30,20 +30,18 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application android:icon="@mipmap/icon" android:label="@string/app_name"
|
||||
<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name"
|
||||
android:hardwareAccelerated="true" android:supportsRtl="true">
|
||||
<activity android:name="__ACTIVITY__"
|
||||
android:label="@string/activity_name"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale">
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode">
|
||||
<intent-filter android:label="@string/launcher_name">
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="__APILEVEL__"/>
|
||||
</manifest>
|
||||
|
||||
@@ -22,33 +22,32 @@ apply plugin: 'com.android.application'
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
jcenter()
|
||||
maven {
|
||||
url "https://maven.google.com"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
}
|
||||
}
|
||||
|
||||
// Allow plugins to declare Maven dependencies via build-extras.gradle.
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenCentral();
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.1.0'
|
||||
gradleVersion = '4.10.3'
|
||||
}
|
||||
|
||||
// Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties.
|
||||
// Refer to: http://www.gradle.org/docs/current/userguide/tutorial_this_and_that.html
|
||||
ext {
|
||||
apply from: '../CordovaLib/cordova.gradle'
|
||||
|
||||
// The value for android.compileSdkVersion.
|
||||
if (!project.hasProperty('cdvCompileSdkVersion')) {
|
||||
cdvCompileSdkVersion = null;
|
||||
@@ -65,11 +64,19 @@ ext {
|
||||
if (!project.hasProperty('cdvMinSdkVersion')) {
|
||||
cdvMinSdkVersion = null
|
||||
}
|
||||
// Sets the maxSdkVersion to the given value.
|
||||
if (!project.hasProperty('cdvMaxSdkVersion')) {
|
||||
cdvMaxSdkVersion = null
|
||||
}
|
||||
// The value for android.targetSdkVersion.
|
||||
if (!project.hasProperty('cdvTargetSdkVersion')) {
|
||||
cdvTargetSdkVersion = null;
|
||||
}
|
||||
// Whether to build architecture-specific APKs.
|
||||
if (!project.hasProperty('cdvBuildMultipleApks')) {
|
||||
cdvBuildMultipleApks = null
|
||||
}
|
||||
// Whether to append a 0 "abi digit" to versionCode when only a single APK is build
|
||||
// Whether to append a 0 "abi digit" to versionCode when only a single APK is build
|
||||
if (!project.hasProperty('cdvVersionCodeForceAbiDigit')) {
|
||||
cdvVersionCodeForceAbiDigit = null
|
||||
}
|
||||
@@ -93,16 +100,23 @@ ext {
|
||||
// PLUGIN GRADLE EXTENSIONS START
|
||||
// PLUGIN GRADLE EXTENSIONS END
|
||||
|
||||
def hasBuildExtras = file('build-extras.gradle').exists()
|
||||
if (hasBuildExtras) {
|
||||
def hasBuildExtras1 = file('build-extras.gradle').exists()
|
||||
if (hasBuildExtras1) {
|
||||
apply from: 'build-extras.gradle'
|
||||
}
|
||||
|
||||
// Set property defaults after extension .gradle files.
|
||||
if (ext.cdvCompileSdkVersion == null) {
|
||||
ext.cdvCompileSdkVersion = privateHelpers.getProjectTarget()
|
||||
//ext.cdvCompileSdkVersion = project.ext.defaultCompileSdkVersion
|
||||
def hasBuildExtras2 = file('../build-extras.gradle').exists()
|
||||
if (hasBuildExtras2) {
|
||||
apply from: '../build-extras.gradle'
|
||||
}
|
||||
|
||||
// Set property defaults after extension .gradle files.
|
||||
ext.cdvCompileSdkVersion = cdvCompileSdkVersion == null ? (
|
||||
defaultCompileSdkVersion == null
|
||||
? privateHelpers.getProjectTarget()
|
||||
: defaultCompileSdkVersion
|
||||
) : Integer.parseInt('' + cdvCompileSdkVersion);
|
||||
|
||||
if (ext.cdvBuildToolsVersion == null) {
|
||||
ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
|
||||
//ext.cdvBuildToolsVersion = project.ext.defaultBuildToolsVersion
|
||||
@@ -117,7 +131,14 @@ if (ext.cdvReleaseSigningPropertiesFile == null && file('../release-signing.prop
|
||||
// Cast to appropriate types.
|
||||
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
|
||||
ext.cdvVersionCodeForceAbiDigit = cdvVersionCodeForceAbiDigit == null ? false : cdvVersionCodeForceAbiDigit.toBoolean();
|
||||
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : defaultMinSdkVersion
|
||||
|
||||
// minSdkVersion, maxSdkVersion and targetSdkVersion
|
||||
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? defaultMinSdkVersion : Integer.parseInt('' + cdvMinSdkVersion)
|
||||
if (cdvMaxSdkVersion != null) {
|
||||
ext.cdvMaxSdkVersion = Integer.parseInt('' + cdvMaxSdkVersion)
|
||||
}
|
||||
ext.cdvTargetSdkVersion = cdvTargetSdkVersion == null ? defaultTargetSdkVersion : Integer.parseInt('' + cdvTargetSdkVersion)
|
||||
|
||||
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
|
||||
|
||||
def computeBuildTargetName(debugBuild) {
|
||||
@@ -140,24 +161,27 @@ cdvBuildRelease.dependsOn {
|
||||
return computeBuildTargetName(false)
|
||||
}
|
||||
|
||||
task cdvPrintProps << {
|
||||
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
|
||||
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
|
||||
println('cdvVersionCode=' + cdvVersionCode)
|
||||
println('cdvVersionCodeForceAbiDigit=' + cdvVersionCodeForceAbiDigit)
|
||||
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
|
||||
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
|
||||
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
|
||||
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
|
||||
println('cdvBuildArch=' + cdvBuildArch)
|
||||
println('computedVersionCode=' + android.defaultConfig.versionCode)
|
||||
android.productFlavors.each { flavor ->
|
||||
println('computed' + flavor.name.capitalize() + 'VersionCode=' + flavor.versionCode)
|
||||
task cdvPrintProps {
|
||||
doLast {
|
||||
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
|
||||
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
|
||||
println('cdvVersionCode=' + cdvVersionCode)
|
||||
println('cdvVersionCodeForceAbiDigit=' + cdvVersionCodeForceAbiDigit)
|
||||
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
|
||||
println('cdvMaxSdkVersion=' + cdvMaxSdkVersion)
|
||||
println('cdvTargetSdkVersion=' + cdvTargetSdkVersion)
|
||||
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
|
||||
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
|
||||
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
|
||||
println('cdvBuildArch=' + cdvBuildArch)
|
||||
println('computedVersionCode=' + android.defaultConfig.versionCode)
|
||||
android.productFlavors.each { flavor ->
|
||||
println('computed' + flavor.name.capitalize() + 'VersionCode=' + flavor.versionCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
|
||||
defaultConfig {
|
||||
versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
|
||||
applicationId privateHelpers.extractStringFromManifest("package")
|
||||
@@ -165,6 +189,14 @@ android {
|
||||
if (cdvMinSdkVersion != null) {
|
||||
minSdkVersion cdvMinSdkVersion
|
||||
}
|
||||
|
||||
if (cdvMaxSdkVersion != null) {
|
||||
maxSdkVersion cdvMaxSdkVersion
|
||||
}
|
||||
|
||||
if(cdvTargetSdkVersion != null) {
|
||||
targetSdkVersion cdvTargetSdkVersion
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
@@ -174,10 +206,11 @@ android {
|
||||
compileSdkVersion cdvCompileSdkVersion
|
||||
buildToolsVersion cdvBuildToolsVersion
|
||||
|
||||
//This code exists for Crosswalk and other Native APIs.
|
||||
//By default, we multiply the existing version code in the Android Manifest by 10 and
|
||||
//add a number for each architecture. If you are not using Crosswalk or SQLite, you can
|
||||
//ignore this chunk of code, and your version codes will be respected.
|
||||
// This code exists for Crosswalk and other Native APIs.
|
||||
// By default, we multiply the existing version code in the
|
||||
// Android Manifest by 10 and add a number for each architecture.
|
||||
// If you are not using Crosswalk or SQLite, you can
|
||||
// ignore this chunk of code, and your version codes will be respected.
|
||||
|
||||
if (Boolean.valueOf(cdvBuildMultipleApks)) {
|
||||
flavorDimensions "default"
|
||||
@@ -243,6 +276,7 @@ android {
|
||||
}
|
||||
addSigningProps(cdvReleaseSigningPropertiesFile, signingConfigs.release)
|
||||
}
|
||||
|
||||
if (cdvDebugSigningPropertiesFile) {
|
||||
addSigningProps(cdvDebugSigningPropertiesFile, signingConfigs.debug)
|
||||
}
|
||||
|
||||
341
bin/templates/project/assets/www/cordova.js
vendored
@@ -1,5 +1,5 @@
|
||||
// Platform: android
|
||||
// 4450a4cea50616e080a82e8ede9e3d6a1fe3c3ec
|
||||
// 74fdba8b327b2a13b4366dd141b52def96d4cb56
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
@@ -8,9 +8,9 @@
|
||||
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
|
||||
@@ -19,12 +19,8 @@
|
||||
under the License.
|
||||
*/
|
||||
;(function() {
|
||||
var PLATFORM_VERSION_BUILD_LABEL = '7.1.0-dev';
|
||||
var PLATFORM_VERSION_BUILD_LABEL = '8.1.0';
|
||||
// file: src/scripts/require.js
|
||||
|
||||
/* jshint -W079 */
|
||||
/* jshint -W020 */
|
||||
|
||||
var require;
|
||||
var define;
|
||||
|
||||
@@ -73,7 +69,7 @@ var define;
|
||||
};
|
||||
|
||||
define = function (id, factory) {
|
||||
if (modules[id]) {
|
||||
if (Object.prototype.hasOwnProperty.call(modules, id)) {
|
||||
throw 'module ' + id + ' already defined';
|
||||
}
|
||||
|
||||
@@ -208,8 +204,8 @@ var cordova = {
|
||||
* @return object
|
||||
*/
|
||||
getOriginalHandlers: function () {
|
||||
return {'document': {'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener},
|
||||
'window': {'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener}};
|
||||
return { 'document': { 'addEventListener': m_document_addEventListener, 'removeEventListener': m_document_removeEventListener },
|
||||
'window': { 'addEventListener': m_window_addEventListener, 'removeEventListener': m_window_removeEventListener } };
|
||||
},
|
||||
/**
|
||||
* Method to fire event from native code
|
||||
@@ -307,6 +303,7 @@ var cordova = {
|
||||
} catch (err) {
|
||||
var msg = 'Error in ' + (isSuccess ? 'Success' : 'Error') + ' callbackId: ' + callbackId + ' : ' + err;
|
||||
console && console.log && console.log(msg);
|
||||
console && console.log && err.stack && console.log(err.stack);
|
||||
cordova.fireWindowEvent('cordovacallbackerror', { 'message': msg });
|
||||
throw err;
|
||||
}
|
||||
@@ -326,7 +323,7 @@ module.exports = cordova;
|
||||
|
||||
});
|
||||
|
||||
// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/android/nativeapiprovider.js
|
||||
// file: ../cordova-android/cordova-js-src/android/nativeapiprovider.js
|
||||
define("cordova/android/nativeapiprovider", function(require, exports, module) {
|
||||
|
||||
/**
|
||||
@@ -349,7 +346,7 @@ module.exports = {
|
||||
|
||||
});
|
||||
|
||||
// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/android/promptbasednativeapi.js
|
||||
// file: ../cordova-android/cordova-js-src/android/promptbasednativeapi.js
|
||||
define("cordova/android/promptbasednativeapi", function(require, exports, module) {
|
||||
|
||||
/**
|
||||
@@ -388,9 +385,38 @@ var typeMap = {
|
||||
};
|
||||
|
||||
function extractParamName (callee, argIndex) {
|
||||
return (/.*?\((.*?)\)/).exec(callee)[1].split(', ')[argIndex];
|
||||
return (/\(\s*([^)]*?)\s*\)/).exec(callee)[1].split(/\s*,\s*/)[argIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given arguments' types and throws if they are not as expected.
|
||||
*
|
||||
* `spec` is a string where each character stands for the required type of the
|
||||
* argument at the same position. In other words: the character at `spec[i]`
|
||||
* specifies the required type for `args[i]`. The characters in `spec` are the
|
||||
* first letter of the required type's name. The supported types are:
|
||||
*
|
||||
* Array, Date, Number, String, Function, Object
|
||||
*
|
||||
* Lowercase characters specify arguments that must not be `null` or `undefined`
|
||||
* while uppercase characters allow those values to be passed.
|
||||
*
|
||||
* Finally, `*` can be used to allow any type at the corresponding position.
|
||||
*
|
||||
* @example
|
||||
* function foo (arr, opts) {
|
||||
* // require `arr` to be an Array and `opts` an Object, null or undefined
|
||||
* checkArgs('aO', 'my.package.foo', arguments);
|
||||
* // ...
|
||||
* }
|
||||
* @param {String} spec - the type specification for `args` as described above
|
||||
* @param {String} functionName - full name of the callee.
|
||||
* Used in the error message
|
||||
* @param {Array|arguments} args - the arguments to be checked against `spec`
|
||||
* @param {Function} [opt_callee=args.callee] - the recipient of `args`.
|
||||
* Used to extract parameter names for the error message
|
||||
* @throws {TypeError} if args do not satisfy spec
|
||||
*/
|
||||
function checkArgs (spec, functionName, args, opt_callee) {
|
||||
if (!moduleExports.enableChecks) {
|
||||
return;
|
||||
@@ -881,7 +907,7 @@ module.exports = channel;
|
||||
|
||||
});
|
||||
|
||||
// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/exec.js
|
||||
// file: ../cordova-android/cordova-js-src/exec.js
|
||||
define("cordova/exec", function(require, exports, module) {
|
||||
|
||||
/**
|
||||
@@ -974,17 +1000,6 @@ function androidExec(success, fail, service, action, args) {
|
||||
}
|
||||
|
||||
androidExec.init = function() {
|
||||
//CB-11828
|
||||
//This failsafe checks the version of Android and if it's Jellybean, it switches it to
|
||||
//using the Online Event bridge for communicating from Native to JS
|
||||
//
|
||||
//It's ugly, but it's necessary.
|
||||
var check = navigator.userAgent.toLowerCase().match(/android\s[0-9].[0-9]/);
|
||||
var version_code = check && check[0].match(/4.[0-3].*/);
|
||||
if (version_code != null && nativeToJsBridgeMode == nativeToJsModes.EVAL_BRIDGE) {
|
||||
nativeToJsBridgeMode = nativeToJsModes.ONLINE_EVENT;
|
||||
}
|
||||
|
||||
bridgeSecret = +prompt('', 'gap_init:' + nativeToJsBridgeMode);
|
||||
channel.onNativeReady.fire();
|
||||
};
|
||||
@@ -1319,130 +1334,6 @@ channel.join(function () {
|
||||
|
||||
});
|
||||
|
||||
// file: src/common/init_b.js
|
||||
define("cordova/init_b", function(require, exports, module) {
|
||||
|
||||
var channel = require('cordova/channel');
|
||||
var cordova = require('cordova');
|
||||
var modulemapper = require('cordova/modulemapper');
|
||||
var platform = require('cordova/platform');
|
||||
var pluginloader = require('cordova/pluginloader');
|
||||
var utils = require('cordova/utils');
|
||||
|
||||
var platformInitChannelsArray = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];
|
||||
|
||||
// setting exec
|
||||
cordova.exec = require('cordova/exec');
|
||||
|
||||
function logUnfiredChannels (arr) {
|
||||
for (var i = 0; i < arr.length; ++i) {
|
||||
if (arr[i].state !== 2) {
|
||||
console.log('Channel not fired: ' + arr[i].type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.setTimeout(function () {
|
||||
if (channel.onDeviceReady.state !== 2) {
|
||||
console.log('deviceready has not fired after 5 seconds.');
|
||||
logUnfiredChannels(platformInitChannelsArray);
|
||||
logUnfiredChannels(channel.deviceReadyChannelsArray);
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
// Replace navigator before any modules are required(), to ensure it happens as soon as possible.
|
||||
// We replace it so that properties that can't be clobbered can instead be overridden.
|
||||
function replaceNavigator (origNavigator) {
|
||||
var CordovaNavigator = function () {};
|
||||
CordovaNavigator.prototype = origNavigator;
|
||||
var newNavigator = new CordovaNavigator();
|
||||
// This work-around really only applies to new APIs that are newer than Function.bind.
|
||||
// Without it, APIs such as getGamepads() break.
|
||||
if (CordovaNavigator.bind) {
|
||||
for (var key in origNavigator) {
|
||||
if (typeof origNavigator[key] === 'function') {
|
||||
newNavigator[key] = origNavigator[key].bind(origNavigator);
|
||||
} else {
|
||||
(function (k) {
|
||||
utils.defineGetterSetter(newNavigator, key, function () {
|
||||
return origNavigator[k];
|
||||
});
|
||||
})(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newNavigator;
|
||||
}
|
||||
if (window.navigator) {
|
||||
window.navigator = replaceNavigator(window.navigator);
|
||||
}
|
||||
|
||||
if (!window.console) {
|
||||
window.console = {
|
||||
log: function () {}
|
||||
};
|
||||
}
|
||||
if (!window.console.warn) {
|
||||
window.console.warn = function (msg) {
|
||||
this.log('warn: ' + msg);
|
||||
};
|
||||
}
|
||||
|
||||
// Register pause, resume and deviceready channels as events on document.
|
||||
channel.onPause = cordova.addDocumentEventHandler('pause');
|
||||
channel.onResume = cordova.addDocumentEventHandler('resume');
|
||||
channel.onActivated = cordova.addDocumentEventHandler('activated');
|
||||
channel.onDeviceReady = cordova.addStickyDocumentEventHandler('deviceready');
|
||||
|
||||
// Listen for DOMContentLoaded and notify our channel subscribers.
|
||||
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
||||
channel.onDOMContentLoaded.fire();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
channel.onDOMContentLoaded.fire();
|
||||
}, false);
|
||||
}
|
||||
|
||||
// _nativeReady is global variable that the native side can set
|
||||
// to signify that the native code is ready. It is a global since
|
||||
// it may be called before any cordova JS is ready.
|
||||
if (window._nativeReady) {
|
||||
channel.onNativeReady.fire();
|
||||
}
|
||||
|
||||
// Call the platform-specific initialization.
|
||||
platform.bootstrap && platform.bootstrap();
|
||||
|
||||
// Wrap in a setTimeout to support the use-case of having plugin JS appended to cordova.js.
|
||||
// The delay allows the attached modules to be defined before the plugin loader looks for them.
|
||||
setTimeout(function () {
|
||||
pluginloader.load(function () {
|
||||
channel.onPluginsReady.fire();
|
||||
});
|
||||
}, 0);
|
||||
|
||||
/**
|
||||
* Create all cordova objects once native side is ready.
|
||||
*/
|
||||
channel.join(function () {
|
||||
modulemapper.mapModules(window);
|
||||
|
||||
platform.initialize && platform.initialize();
|
||||
|
||||
// Fire event to notify that all objects are created
|
||||
channel.onCordovaReady.fire();
|
||||
|
||||
// Fire onDeviceReady event once page has fully loaded, all
|
||||
// constructors have run and cordova info has been received from native
|
||||
// side.
|
||||
channel.join(function () {
|
||||
require('cordova').fireDocumentEvent('deviceready');
|
||||
}, channel.deviceReadyChannelsArray);
|
||||
|
||||
}, platformInitChannelsArray);
|
||||
|
||||
});
|
||||
|
||||
// file: src/common/modulemapper.js
|
||||
define("cordova/modulemapper", function(require, exports, module) {
|
||||
|
||||
@@ -1543,103 +1434,7 @@ exports.reset();
|
||||
|
||||
});
|
||||
|
||||
// file: src/common/modulemapper_b.js
|
||||
define("cordova/modulemapper_b", function(require, exports, module) {
|
||||
|
||||
var builder = require('cordova/builder');
|
||||
var symbolList = [];
|
||||
var deprecationMap;
|
||||
|
||||
exports.reset = function () {
|
||||
symbolList = [];
|
||||
deprecationMap = {};
|
||||
};
|
||||
|
||||
function addEntry (strategy, moduleName, symbolPath, opt_deprecationMessage) {
|
||||
symbolList.push(strategy, moduleName, symbolPath);
|
||||
if (opt_deprecationMessage) {
|
||||
deprecationMap[symbolPath] = opt_deprecationMessage;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: Android 2.3 does have Function.bind().
|
||||
exports.clobbers = function (moduleName, symbolPath, opt_deprecationMessage) {
|
||||
addEntry('c', moduleName, symbolPath, opt_deprecationMessage);
|
||||
};
|
||||
|
||||
exports.merges = function (moduleName, symbolPath, opt_deprecationMessage) {
|
||||
addEntry('m', moduleName, symbolPath, opt_deprecationMessage);
|
||||
};
|
||||
|
||||
exports.defaults = function (moduleName, symbolPath, opt_deprecationMessage) {
|
||||
addEntry('d', moduleName, symbolPath, opt_deprecationMessage);
|
||||
};
|
||||
|
||||
exports.runs = function (moduleName) {
|
||||
addEntry('r', moduleName, null);
|
||||
};
|
||||
|
||||
function prepareNamespace (symbolPath, context) {
|
||||
if (!symbolPath) {
|
||||
return context;
|
||||
}
|
||||
var parts = symbolPath.split('.');
|
||||
var cur = context;
|
||||
for (var i = 0, part; part = parts[i]; ++i) { // eslint-disable-line no-cond-assign
|
||||
cur = cur[part] = cur[part] || {};
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
exports.mapModules = function (context) {
|
||||
var origSymbols = {};
|
||||
context.CDV_origSymbols = origSymbols;
|
||||
for (var i = 0, len = symbolList.length; i < len; i += 3) {
|
||||
var strategy = symbolList[i];
|
||||
var moduleName = symbolList[i + 1];
|
||||
var module = require(moduleName);
|
||||
// <runs/>
|
||||
if (strategy === 'r') {
|
||||
continue;
|
||||
}
|
||||
var symbolPath = symbolList[i + 2];
|
||||
var lastDot = symbolPath.lastIndexOf('.');
|
||||
var namespace = symbolPath.substr(0, lastDot);
|
||||
var lastName = symbolPath.substr(lastDot + 1);
|
||||
|
||||
var deprecationMsg = symbolPath in deprecationMap ? 'Access made to deprecated symbol: ' + symbolPath + '. ' + deprecationMsg : null;
|
||||
var parentObj = prepareNamespace(namespace, context);
|
||||
var target = parentObj[lastName];
|
||||
|
||||
if (strategy === 'm' && target) {
|
||||
builder.recursiveMerge(target, module);
|
||||
} else if ((strategy === 'd' && !target) || (strategy !== 'd')) {
|
||||
if (!(symbolPath in origSymbols)) {
|
||||
origSymbols[symbolPath] = target;
|
||||
}
|
||||
builder.assignOrWrapInDeprecateGetter(parentObj, lastName, module, deprecationMsg);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
exports.getOriginalSymbol = function (context, symbolPath) {
|
||||
var origSymbols = context.CDV_origSymbols;
|
||||
if (origSymbols && (symbolPath in origSymbols)) {
|
||||
return origSymbols[symbolPath];
|
||||
}
|
||||
var parts = symbolPath.split('.');
|
||||
var obj = context;
|
||||
for (var i = 0; i < parts.length; ++i) {
|
||||
obj = obj && obj[parts[i]];
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
exports.reset();
|
||||
|
||||
});
|
||||
|
||||
// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/platform.js
|
||||
// file: ../cordova-android/cordova-js-src/platform.js
|
||||
define("cordova/platform", function(require, exports, module) {
|
||||
|
||||
// The last resume event that was received that had the result of a plugin call.
|
||||
@@ -1749,7 +1544,7 @@ function onMessageFromNative(msg) {
|
||||
|
||||
});
|
||||
|
||||
// file: /Users/jbowser/cordova/cordova-android/cordova-js-src/plugin/android/app.js
|
||||
// file: ../cordova-android/cordova-js-src/plugin/android/app.js
|
||||
define("cordova/plugin/android/app", function(require, exports, module) {
|
||||
|
||||
var exec = require('cordova/exec');
|
||||
@@ -1952,53 +1747,6 @@ exports.load = function (callback) {
|
||||
|
||||
});
|
||||
|
||||
// file: src/common/pluginloader_b.js
|
||||
define("cordova/pluginloader_b", function(require, exports, module) {
|
||||
|
||||
var modulemapper = require('cordova/modulemapper');
|
||||
|
||||
// Handler for the cordova_plugins.js content.
|
||||
// See plugman's plugin_loader.js for the details of this object.
|
||||
function handlePluginsObject (moduleList) {
|
||||
// if moduleList is not defined or empty, we've nothing to do
|
||||
if (!moduleList || !moduleList.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through all the modules and then through their clobbers and merges.
|
||||
for (var i = 0, module; module = moduleList[i]; i++) { // eslint-disable-line no-cond-assign
|
||||
if (module.clobbers && module.clobbers.length) {
|
||||
for (var j = 0; j < module.clobbers.length; j++) {
|
||||
modulemapper.clobbers(module.id, module.clobbers[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (module.merges && module.merges.length) {
|
||||
for (var k = 0; k < module.merges.length; k++) {
|
||||
modulemapper.merges(module.id, module.merges[k]);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, if runs is truthy we want to simply require() the module.
|
||||
if (module.runs) {
|
||||
modulemapper.runs(module.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loads all plugins' js-modules. Plugin loading is syncronous in browserified bundle
|
||||
// but the method accepts callback to be compatible with non-browserify flow.
|
||||
// onDeviceReady is blocked on onPluginsReady. onPluginsReady is fired when there are
|
||||
// no plugins to load, or they are all done.
|
||||
exports.load = function (callback) {
|
||||
var moduleList = require('cordova/plugin_list');
|
||||
handlePluginsObject(moduleList);
|
||||
|
||||
callback();
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
// file: src/common/urlutil.js
|
||||
define("cordova/urlutil", function(require, exports, module) {
|
||||
|
||||
@@ -2182,7 +1930,6 @@ utils.alert = function (msg) {
|
||||
|
||||
window.cordova = require('cordova');
|
||||
// file: src/scripts/bootstrap.js
|
||||
|
||||
require('cordova/init');
|
||||
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -20,32 +20,30 @@
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven {
|
||||
url "https://maven.google.com"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
|
||||
dependencies {
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
|
||||
classpath 'com.android.tools.build:gradle:3.3.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven {
|
||||
url "https://maven.google.com"
|
||||
}
|
||||
}
|
||||
|
||||
//This replaces project.properties w.r.t. build settings
|
||||
project.ext {
|
||||
defaultBuildToolsVersion="27.0.1" //String
|
||||
defaultBuildToolsVersion="28.0.3" //String
|
||||
defaultMinSdkVersion=19 //Integer - Minimum requirement is Android 4.4
|
||||
defaultTargetSdkVersion=27 //Integer - We ALWAYS target the latest by default
|
||||
defaultCompileSdkVersion=27 //Integer - We ALWAYS compile with the latest by default
|
||||
defaultTargetSdkVersion=28 //Integer - We ALWAYS target the latest by default
|
||||
defaultCompileSdkVersion=28 //Integer - We ALWAYS compile with the latest by default
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,5 +10,12 @@ ant-gen
|
||||
# Eclipse builds
|
||||
gen
|
||||
out
|
||||
# Gradle builds
|
||||
# Gradle build artifacts
|
||||
.gradle
|
||||
.gradletasknamecache
|
||||
/build
|
||||
/CordovaLib/build
|
||||
/app/build
|
||||
gradle-app.setting
|
||||
# Android Studio
|
||||
.idea
|
||||
|
||||
@@ -66,6 +66,14 @@ ext {
|
||||
if (!project.hasProperty('cdvMinSdkVersion')) {
|
||||
cdvMinSdkVersion = null
|
||||
}
|
||||
// Sets the maxSdkVersion to the given value.
|
||||
if (!project.hasProperty('cdvMaxSdkVersion')) {
|
||||
cdvMaxSdkVersion = null
|
||||
}
|
||||
// The value for android.targetSdkVersion.
|
||||
if (!project.hasProperty('cdvTargetSdkVersion')) {
|
||||
cdvTargetSdkVersion = null;
|
||||
}
|
||||
// Whether to build architecture-specific APKs.
|
||||
if (!project.hasProperty('cdvBuildMultipleApks')) {
|
||||
cdvBuildMultipleApks = null
|
||||
@@ -112,6 +120,11 @@ if (ext.cdvReleaseSigningPropertiesFile == null && file('release-signing.propert
|
||||
// Cast to appropriate types.
|
||||
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
|
||||
ext.cdvMinSdkVersion = cdvMinSdkVersion == null ? null : Integer.parseInt('' + cdvMinSdkVersion)
|
||||
|
||||
if(cdvMaxSdkVersion != null) {
|
||||
ext.cdvMaxSdkVersion = Integer.parseInt('' + cdvMaxSdkVersion)
|
||||
}
|
||||
|
||||
ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
|
||||
|
||||
def computeBuildTargetName(debugBuild) {
|
||||
@@ -139,6 +152,8 @@ task cdvPrintProps << {
|
||||
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
|
||||
println('cdvVersionCode=' + cdvVersionCode)
|
||||
println('cdvMinSdkVersion=' + cdvMinSdkVersion)
|
||||
println('cdvMaxSdkVersion=' + cdvMaxSdkVersion)
|
||||
println('cdvTargetSdkVersion=' + cdvTargetSdkVersion)
|
||||
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
|
||||
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
|
||||
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
|
||||
@@ -170,6 +185,14 @@ android {
|
||||
if (cdvMinSdkVersion != null) {
|
||||
minSdkVersion cdvMinSdkVersion
|
||||
}
|
||||
|
||||
if (cdvMaxSdkVersion != null) {
|
||||
maxSdkVersion cdvMaxSdkVersion
|
||||
}
|
||||
|
||||
if(cdvTargetSdkVersion != null) {
|
||||
targetSdkVersion cdvTargetSdkVersion
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
@@ -245,7 +268,7 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: '*.jar')
|
||||
implementation fileTree(dir: 'libs', include: '*.jar')
|
||||
// SUB-PROJECT DEPENDENCIES START
|
||||
// SUB-PROJECT DEPENDENCIES END
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 222 KiB After Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 286 KiB After Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 207 KiB After Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 292 KiB After Width: | Height: | Size: 192 KiB |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 86 B |
|
After Width: | Height: | Size: 2.6 KiB |
BIN
bin/templates/project/res/mipmap-hdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 83 B |
|
After Width: | Height: | Size: 1.5 KiB |
BIN
bin/templates/project/res/mipmap-ldpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 84 B |
|
After Width: | Height: | Size: 1.8 KiB |
BIN
bin/templates/project/res/mipmap-mdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 113 B |
|
After Width: | Height: | Size: 5.0 KiB |
BIN
bin/templates/project/res/mipmap-xhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 121 B |
|
After Width: | Height: | Size: 8.4 KiB |
BIN
bin/templates/project/res/mipmap-xxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@mipmap/ic_launcher_background" />
|
||||
<foreground android:drawable="@mipmap/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 131 B |
|
After Width: | Height: | Size: 11 KiB |
BIN
bin/templates/project/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 7.7 KiB |
@@ -18,13 +18,13 @@
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
var path = require('path');
|
||||
var path = require('path');
|
||||
var Api = require('./templates/cordova/Api');
|
||||
var args = require('nopt')({
|
||||
var args = require('nopt')({
|
||||
'link': Boolean,
|
||||
'shared': Boolean,
|
||||
'help': Boolean
|
||||
}, { 'd' : '--verbose' });
|
||||
}, { 'd': '--verbose' });
|
||||
|
||||
if (args.help || args.argv.remain.length === 0) {
|
||||
console.log('Usage: ' + path.relative(process.cwd(), path.join(__dirname, 'update')) + ' <path_to_project> [--link]');
|
||||
@@ -34,4 +34,4 @@ if (args.help || args.argv.remain.length === 0) {
|
||||
|
||||
require('./templates/cordova/loggingHelper').adjustLoggerLevel(args);
|
||||
|
||||
Api.updatePlatform(args.argv.remain[0], {link: (args.link || args.shared)}).done();
|
||||
Api.updatePlatform(args.argv.remain[0], { link: (args.link || args.shared) }).done();
|
||||
|
||||