feat!: unify & fix gradle library/tooling overrides (#1212)

* enhancement: Control SDK versions and other default projects in one place
* fix: target/compile sdk usage
* refactor: cleanup gradle process
* chore: cleanup and remove unused changes
* chore: remove more unneeded FILE_PATH
* chore: fix lint error
* revert change intended to be part of a different PR
* chore: apply changes to revert to fit new changes
* fix: Ensure proper types
* breaking: Removed TempateFile class
  * Replaced the one and only usage of it with the properties-parser editor.
  * Breaking change because we are converting a method into an asynchronous method.
* refactor: Use the sync version of properties editor
* Gh 1178 fix sdk use gradlearg fix (#2)
* fix: readd gradleArg support
* fix: variable name
* refactor: remove unused mock variables
* Update bin/templates/cordova/lib/builders/ProjectBuilder.js
* Update bin/lib/create.js
* fix: const naming (review suggestion)
* fix: use defaults for framework building
* chore: apply review suggestion
* chore: rename config.json & defaults.json (review suggestions)
* refactor: updateUserProjectGradleConfig method
* refactor: minor changes in updateUserProjectGradleConfig
* refactor: major changes in updateUserProjectGradleConfig
* fix: wrong handling of missing preferences
* fix: usage of undefined this
* fix(create.spec): mocking of getPreference
* test(check_reqs): reduce diff size
* refactor: add wrapper to load gradle config defaults
* fix(check_reqs): get_target
  * Reads default SDK from default gradle config now
* fix(check_reqs.spec): return correct types from mocks
* revert to using get_target in create
* fix: e2e test

Co-authored-by: Erisu <ellis.bryan@gmail.com>
Co-authored-by: Raphael von der Grün <raphinesse@gmail.com>
This commit is contained in:
Norman Breau 2021-07-06 03:38:28 -03:00 committed by GitHub
parent 47aa116b1d
commit 510596f515
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 268 additions and 254 deletions

1
.gitignore vendored
View File

@ -30,6 +30,7 @@ example
/test/androidx/gradle /test/androidx/gradle
/test/androidx/gradlew /test/androidx/gradlew
/test/androidx/gradlew.bat /test/androidx/gradlew.bat
/test/androidx/cdv-gradle-config.json
/test/assets/www/.tmp* /test/assets/www/.tmp*
/test/assets/www/cordova.js /test/assets/www/cordova.js

View File

@ -22,6 +22,7 @@ var fs = require('fs-extra');
var utils = require('../templates/cordova/lib/utils'); var utils = require('../templates/cordova/lib/utils');
var check_reqs = require('./../templates/cordova/lib/check_reqs'); var check_reqs = require('./../templates/cordova/lib/check_reqs');
var ROOT = path.join(__dirname, '..', '..'); var ROOT = path.join(__dirname, '..', '..');
const { createEditor } = require('properties-parser');
var CordovaError = require('cordova-common').CordovaError; var CordovaError = require('cordova-common').CordovaError;
var AndroidManifest = require('../templates/cordova/lib/AndroidManifest'); var AndroidManifest = require('../templates/cordova/lib/AndroidManifest');
@ -42,16 +43,12 @@ function getFrameworkDir (projectPath, shared) {
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib'); return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
} }
function copyJsAndLibrary (projectPath, shared, projectName, isLegacy) { function copyJsAndLibrary (projectPath, shared, projectName, targetAPI) {
var nestedCordovaLibPath = getFrameworkDir(projectPath, false); var nestedCordovaLibPath = getFrameworkDir(projectPath, false);
var srcCordovaJsPath = path.join(ROOT, 'bin', 'templates', 'project', 'assets', 'www', 'cordova.js'); var srcCordovaJsPath = path.join(ROOT, 'bin', 'templates', 'project', 'assets', 'www', 'cordova.js');
var app_path = path.join(projectPath, 'app', 'src', 'main'); var app_path = path.join(projectPath, 'app', 'src', 'main');
const platform_www = path.join(projectPath, 'platform_www'); const platform_www = path.join(projectPath, 'platform_www');
if (isLegacy) {
app_path = projectPath;
}
fs.copySync(srcCordovaJsPath, path.join(app_path, 'assets', 'www', 'cordova.js')); fs.copySync(srcCordovaJsPath, path.join(app_path, 'assets', 'www', 'cordova.js'));
// Copy the cordova.js file to platforms/<platform>/platform_www/ // Copy the cordova.js file to platforms/<platform>/platform_www/
@ -69,11 +66,14 @@ function copyJsAndLibrary (projectPath, shared, projectName, isLegacy) {
} else { } else {
fs.ensureDirSync(nestedCordovaLibPath); fs.ensureDirSync(nestedCordovaLibPath);
fs.copySync(path.join(ROOT, 'framework', 'AndroidManifest.xml'), path.join(nestedCordovaLibPath, 'AndroidManifest.xml')); fs.copySync(path.join(ROOT, 'framework', 'AndroidManifest.xml'), path.join(nestedCordovaLibPath, 'AndroidManifest.xml'));
fs.copySync(path.join(ROOT, 'framework', 'project.properties'), path.join(nestedCordovaLibPath, 'project.properties')); const propertiesEditor = createEditor(path.join(ROOT, 'framework', 'project.properties'));
propertiesEditor.set('target', targetAPI);
propertiesEditor.save(path.join(nestedCordovaLibPath, 'project.properties'));
fs.copySync(path.join(ROOT, 'framework', 'build.gradle'), path.join(nestedCordovaLibPath, 'build.gradle')); fs.copySync(path.join(ROOT, 'framework', 'build.gradle'), path.join(nestedCordovaLibPath, 'build.gradle'));
fs.copySync(path.join(ROOT, 'framework', 'cordova.gradle'), path.join(nestedCordovaLibPath, 'cordova.gradle')); fs.copySync(path.join(ROOT, 'framework', 'cordova.gradle'), path.join(nestedCordovaLibPath, 'cordova.gradle'));
fs.copySync(path.join(ROOT, 'framework', 'repositories.gradle'), path.join(nestedCordovaLibPath, 'repositories.gradle')); fs.copySync(path.join(ROOT, 'framework', 'repositories.gradle'), path.join(nestedCordovaLibPath, 'repositories.gradle'));
fs.copySync(path.join(ROOT, 'framework', 'src'), path.join(nestedCordovaLibPath, 'src')); fs.copySync(path.join(ROOT, 'framework', 'src'), path.join(nestedCordovaLibPath, 'src'));
fs.copySync(path.join(ROOT, 'framework', 'cdv-gradle-config-defaults.json'), path.join(projectPath, 'cdv-gradle-config.json'));
} }
} }
@ -277,7 +277,7 @@ exports.create = function (project_path, config, options, events) {
fs.ensureDirSync(path.join(app_path, 'libs')); fs.ensureDirSync(path.join(app_path, 'libs'));
// copy cordova.js, cordova.jar // copy cordova.js, cordova.jar
exports.copyJsAndLibrary(project_path, options.link, safe_activity_name); exports.copyJsAndLibrary(project_path, options.link, safe_activity_name, target_api);
// Set up ther Android Studio paths // Set up ther Android Studio paths
var java_path = path.join(app_path, 'java'); var java_path = path.join(app_path, 'java');

View File

@ -265,10 +265,11 @@ class ProjectBuilder {
}).then(function () { }).then(function () {
return self.prepBuildFiles(); return self.prepBuildFiles();
}).then(() => { }).then(() => {
const config = this._getCordovaConfig();
// update/set the distributionUrl in the gradle-wrapper.properties // update/set the distributionUrl in the gradle-wrapper.properties
const gradleWrapperPropertiesPath = path.join(self.root, 'gradle/wrapper/gradle-wrapper.properties'); const gradleWrapperPropertiesPath = path.join(self.root, 'gradle/wrapper/gradle-wrapper.properties');
const gradleWrapperProperties = createEditor(gradleWrapperPropertiesPath); const gradleWrapperProperties = createEditor(gradleWrapperPropertiesPath);
const distributionUrl = process.env.CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL || 'https://services.gradle.org/distributions/gradle-6.8.3-all.zip'; const distributionUrl = process.env.CORDOVA_ANDROID_GRADLE_DISTRIBUTION_URL || `https://services.gradle.org/distributions/gradle-${config.GRADLE_VERSION}-all.zip`;
gradleWrapperProperties.set('distributionUrl', distributionUrl); gradleWrapperProperties.set('distributionUrl', distributionUrl);
gradleWrapperProperties.save(); gradleWrapperProperties.save();
@ -287,6 +288,14 @@ class ProjectBuilder {
}); });
} }
/**
* @private
* @returns The user defined configs
*/
_getCordovaConfig () {
return fs.readJSONSync(path.join(this.root, 'cdv-gradle-config.json'));
}
/* /*
* Builds the project with gradle. * Builds the project with gradle.
* Returns a promise. * Returns a promise.

View File

@ -23,11 +23,10 @@ var fs = require('fs-extra');
const { forgivingWhichSync, isWindows, isDarwin } = require('./utils'); const { forgivingWhichSync, isWindows, isDarwin } = require('./utils');
const java = require('./env/java'); const java = require('./env/java');
var REPO_ROOT = path.join(__dirname, '..', '..', '..', '..'); var REPO_ROOT = path.join(__dirname, '..', '..', '..', '..');
var PROJECT_ROOT = path.join(__dirname, '..', '..');
const { CordovaError, ConfigParser, events } = require('cordova-common'); const { CordovaError, ConfigParser, events } = require('cordova-common');
var android_sdk = require('./android_sdk'); var android_sdk = require('./android_sdk');
const { createEditor } = require('properties-parser');
const semver = require('semver'); const semver = require('semver');
const { SDK_VERSION } = require('./gradle-config-defaults');
const EXPECTED_JAVA_VERSION = '1.8.x'; const EXPECTED_JAVA_VERSION = '1.8.x';
@ -36,44 +35,28 @@ const EXPECTED_JAVA_VERSION = '1.8.x';
Object.assign(module.exports, { isWindows, isDarwin }); Object.assign(module.exports, { isWindows, isDarwin });
/** /**
* @description Get valid target from framework/project.properties if run from this repo
* Otherwise get target from project.properties file within a generated cordova-android project
* @returns {string} The android target in format "android-${target}" * @returns {string} The android target in format "android-${target}"
*/ */
module.exports.get_target = function () { module.exports.get_target = function () {
const projectPropertiesPaths = [ const userTargetSdkVersion = getUserTargetSdkVersion();
path.join(REPO_ROOT, 'framework', 'project.properties'),
path.join(PROJECT_ROOT, 'project.properties')
];
// Get the minimum required target API from the framework. if (userTargetSdkVersion && userTargetSdkVersion < SDK_VERSION) {
let target = projectPropertiesPaths.filter(filePath => fs.existsSync(filePath)) events.emit('warn', `android-targetSdkVersion should be greater than or equal to ${SDK_VERSION}.`);
.map(filePath => createEditor(filePath).get('target'))
.pop();
if (!target) {
throw new Error(`We could not locate the target from the "project.properties" at either "${projectPropertiesPaths.join('", "')}".`);
} }
return `android-${Math.max(userTargetSdkVersion, SDK_VERSION)}`;
};
/** @returns {number} target sdk or 0 if undefined */
function getUserTargetSdkVersion () {
// If the repo config.xml file exists, find the desired targetSdkVersion. // If the repo config.xml file exists, find the desired targetSdkVersion.
const configFile = path.join(REPO_ROOT, 'config.xml'); const configFile = path.join(REPO_ROOT, 'config.xml');
if (!fs.existsSync(configFile)) return target; if (!fs.existsSync(configFile)) return 0;
const configParser = new ConfigParser(configFile); const configParser = new ConfigParser(configFile);
const desiredAPI = parseInt(configParser.getPreference('android-targetSdkVersion', 'android'), 10); const targetSdkVersion = parseInt(configParser.getPreference('android-targetSdkVersion', 'android'), 10);
return isNaN(targetSdkVersion) ? 0 : targetSdkVersion;
if (!isNaN(desiredAPI)) { }
const minimumAPI = parseInt(target.split('-').pop(), 10);
if (desiredAPI >= minimumAPI) {
target = `android-${desiredAPI}`;
} else {
events.emit('warn', `android-targetSdkVersion should be greater than or equal to ${minimumAPI}.`);
}
}
return target;
};
module.exports.get_gradle_wrapper = function () { module.exports.get_gradle_wrapper = function () {
var androidStudioPath; var androidStudioPath;

View File

@ -0,0 +1,30 @@
/*!
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 ABS_MODULE_PATH = '/framework/cdv-gradle-config-defaults.json';
try {
// Try relative require first, …
const REPO_ROOT = '../../../..';
module.exports = require(REPO_ROOT + ABS_MODULE_PATH);
} catch (error) {
// … then fall back to installed-package require
if (error.code !== 'MODULE_NOT_FOUND') throw error;
module.exports = require('cordova-android' + ABS_MODULE_PATH);
}

View File

@ -42,8 +42,8 @@ dependencies {
} }
android { android {
compileSdkVersion cdvCompileSdkVersion compileSdkVersion cordovaConfig.SDK_VERSION
buildToolsVersion cdvBuildToolsVersion buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6 sourceCompatibility JavaVersion.VERSION_1_6

View File

@ -32,6 +32,7 @@ var PlatformJson = require('cordova-common').PlatformJson;
var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger; var PlatformMunger = require('cordova-common').ConfigChanges.PlatformMunger;
var PluginInfoProvider = require('cordova-common').PluginInfoProvider; var PluginInfoProvider = require('cordova-common').PluginInfoProvider;
const utils = require('./utils'); const utils = require('./utils');
const gradleConfigDefaults = require('./gradle-config-defaults');
const GradlePropertiesParser = require('./config/GradlePropertiesParser'); const GradlePropertiesParser = require('./config/GradlePropertiesParser');
@ -55,29 +56,11 @@ module.exports.prepare = function (cordovaProject, options) {
this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations); this._config = updateConfigFilesFrom(cordovaProject.projectConfig, munger, this.locations);
// Get the min SDK version from config.xml // Update Gradle cdv-gradle-config.json
const minSdkVersion = this._config.getPreference('android-minSdkVersion', 'android'); updateUserProjectGradleConfig(this);
const maxSdkVersion = this._config.getPreference('android-maxSdkVersion', 'android');
const targetSdkVersion = this._config.getPreference('android-targetSdkVersion', 'android');
const isGradlePluginKotlinEnabled = this._config.getPreference('GradlePluginKotlinEnabled', 'android');
const gradlePluginKotlinCodeStyle = this._config.getPreference('GradlePluginKotlinCodeStyle', 'android');
const androidXAppCompatVersion = this._config.getPreference('AndroidXAppCompatVersion', 'android');
const gradlePropertiesUserConfig = {}; // Update Project's Gradle Properties
if (minSdkVersion) gradlePropertiesUserConfig.cdvMinSdkVersion = minSdkVersion; updateUserProjectGradlePropertiesConfig(this, args);
if (maxSdkVersion) gradlePropertiesUserConfig.cdvMaxSdkVersion = maxSdkVersion;
if (targetSdkVersion) gradlePropertiesUserConfig.cdvTargetSdkVersion = targetSdkVersion;
if (args.jvmargs) gradlePropertiesUserConfig['org.gradle.jvmargs'] = args.jvmargs;
if (isGradlePluginKotlinEnabled) {
gradlePropertiesUserConfig['kotlin.code.style'] = gradlePluginKotlinCodeStyle || 'official';
}
if (androidXAppCompatVersion) {
gradlePropertiesUserConfig.cdvAndroidXAppCompatVersion = androidXAppCompatVersion;
}
const gradlePropertiesParser = new GradlePropertiesParser(this.locations.root);
gradlePropertiesParser.configure(gradlePropertiesUserConfig);
// Update own www dir with project's www assets and plugins' assets and js-files // Update own www dir with project's www assets and plugins' assets and js-files
return Promise.resolve(updateWww(cordovaProject, this.locations)).then(function () { return Promise.resolve(updateWww(cordovaProject, this.locations)).then(function () {
@ -92,6 +75,76 @@ module.exports.prepare = function (cordovaProject, options) {
}); });
}; };
/** @param {PlatformApi} project */
function updateUserProjectGradleConfig (project) {
// Generate project gradle config
const projectGradleConfig = {
...gradleConfigDefaults,
...getUserGradleConfig(project._config)
};
// Write out changes
const projectGradleConfigPath = path.join(project.root, 'cdv-gradle-config.json');
fs.writeJSONSync(projectGradleConfigPath, projectGradleConfig, { spaces: 2 });
}
function getUserGradleConfig (configXml) {
const configXmlToGradleMapping = [
{ xmlKey: 'android-minSdkVersion', gradleKey: 'MIN_SDK_VERSION', type: Number },
{ xmlKey: 'android-maxSdkVersion', gradleKey: 'MAX_SDK_VERSION', type: Number },
{ xmlKey: 'android-targetSdkVersion', gradleKey: 'SDK_VERSION', type: Number },
{ xmlKey: 'android-buildToolsVersion', gradleKey: 'BUILD_TOOLS_VERSION', type: String },
{ xmlKey: 'GradleVersion', gradleKey: 'GRADLE_VERSION', type: String },
{ xmlKey: 'AndroidGradlePluginVersion', gradleKey: 'AGP_VERSION', type: String },
{ xmlKey: 'GradlePluginKotlinVersion', gradleKey: 'KOTLIN_VERSION', type: String },
{ xmlKey: 'AndroidXAppCompatVersion', gradleKey: 'ANDROIDX_APP_COMPAT_VERSION', type: String },
{ xmlKey: 'GradlePluginGoogleServicesVersion', gradleKey: 'GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION', type: String },
{ xmlKey: 'GradlePluginGoogleServicesEnabled', gradleKey: 'IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED', type: Boolean },
{ xmlKey: 'GradlePluginKotlinEnabled', gradleKey: 'IS_GRADLE_PLUGIN_KOTLIN_ENABLED', type: Boolean }
];
return configXmlToGradleMapping.reduce((config, mapping) => {
const rawValue = configXml.getPreference(mapping.xmlKey, 'android');
// ignore missing preferences (which occur as '')
if (rawValue) {
config[mapping.gradleKey] = parseStringAsType(rawValue, mapping.type);
}
return config;
}, {});
}
/** Converts given string to given type */
function parseStringAsType (value, type) {
switch (type) {
case String:
return String(value);
case Number:
return parseFloat(value);
case Boolean:
return value.toLowerCase() === 'true';
default:
throw new CordovaError('Invalid type: ' + type);
}
}
function updateUserProjectGradlePropertiesConfig (project, args) {
const gradlePropertiesUserConfig = {};
// Get the min SDK version from config.xml
if (args.jvmargs) gradlePropertiesUserConfig['org.gradle.jvmargs'] = args.jvmargs;
const isGradlePluginKotlinEnabled = project._config.getPreference('GradlePluginKotlinEnabled', 'android');
if (isGradlePluginKotlinEnabled) {
const gradlePluginKotlinCodeStyle = project._config.getPreference('GradlePluginKotlinCodeStyle', 'android');
gradlePropertiesUserConfig['kotlin.code.style'] = gradlePluginKotlinCodeStyle || 'official';
}
const gradlePropertiesParser = new GradlePropertiesParser(project.root);
gradlePropertiesParser.configure(gradlePropertiesUserConfig);
}
module.exports.clean = function (options) { module.exports.clean = function (options) {
// A cordovaProject isn't passed into the clean() function, because it might have // A cordovaProject isn't passed into the clean() function, because it might have
// been called from the platform shell script rather than the CLI. Check for the // been called from the platform shell script rather than the CLI. Check for the

View File

@ -19,7 +19,7 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
if (cdvHelpers.getConfigPreference('GradlePluginKotlinEnabled', 'false').toBoolean()) { if (cordovaConfig.IS_GRADLE_PLUGIN_KOTLIN_ENABLED) {
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
} }
@ -27,50 +27,31 @@ if (cdvHelpers.getConfigPreference('GradlePluginKotlinEnabled', 'false').toBoole
buildscript { buildscript {
apply from: '../CordovaLib/cordova.gradle' apply from: '../CordovaLib/cordova.gradle'
if(cdvHelpers.getConfigPreference('GradlePluginKotlinEnabled', 'false').toBoolean()) { // Checks if the kotlin version format is valid.
String defaultGradlePluginKotlinVersion = kotlin_version if(cordovaConfig.IS_GRADLE_PLUGIN_KOTLIN_ENABLED) {
if(!cdvHelpers.isVersionValid(cordovaConfig.KOTLIN_VERSION)) {
/** throw new GradleException("The defined Kotlin version (${cordovaConfig.KOTLIN_VERSION}) does not appear to be a valid version.")
* Fetches the user's defined Kotlin Version from config.xml.
* If the version is not set or invalid, it will default to the ${defaultGradlePluginKotlinVersion}
*/
String gradlePluginKotlinVersion = cdvHelpers.getConfigPreference('GradlePluginKotlinVersion', defaultGradlePluginKotlinVersion)
if(!cdvHelpers.isVersionValid(gradlePluginKotlinVersion)) {
println("The defined Kotlin version (${gradlePluginKotlinVersion}) does not appear to be a valid version. Falling back to version: ${defaultGradlePluginKotlinVersion}.")
gradlePluginKotlinVersion = defaultGradlePluginKotlinVersion
} }
// Change the version to be used.
ext.kotlin_version = gradlePluginKotlinVersion
} }
apply from: 'repositories.gradle' apply from: 'repositories.gradle'
repositories repos repositories repos
dependencies { dependencies {
apply from: '../CordovaLib/cordova.gradle' classpath "com.android.tools.build:gradle:${cordovaConfig.AGP_VERSION}"
classpath 'com.android.tools.build:gradle:4.2.1' if (cordovaConfig.IS_GRADLE_PLUGIN_KOTLIN_ENABLED) {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${cordovaConfig.KOTLIN_VERSION}"
if (cdvHelpers.getConfigPreference('GradlePluginKotlinEnabled', 'false').toBoolean()) {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
if(cdvHelpers.getConfigPreference('GradlePluginGoogleServicesEnabled', 'false').toBoolean()) { if(cordovaConfig.IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED) {
String defaultGradlePluginGoogleServicesVersion = '4.3.5' // Checks if the kotlin version format is valid.
/**
* Fetches the user's defined Google Services Plugin Version from config.xml.
* If the version is not set or invalid, it will default to the ${defaultGradlePluginGoogleServicesVersion}
*/
String gradlePluginGoogleServicesVersion = cdvHelpers.getConfigPreference('GradlePluginGoogleServicesVersion', defaultGradlePluginGoogleServicesVersion)
if(!cdvHelpers.isVersionValid(gradlePluginGoogleServicesVersion)) { if(!cdvHelpers.isVersionValid(gradlePluginGoogleServicesVersion)) {
println("The defined Google Services plugin version (${gradlePluginGoogleServicesVersion}) does not appear to be a valid version. Falling back to version: ${defaultGradlePluginGoogleServicesVersion}.") throw new GradleException("The defined Google Services plugin version (${cordovaConfig.GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION}) does not appear to be a valid version.")
gradlePluginGoogleServicesVersion = defaultGradlePluginGoogleServicesVersion
} }
// Create the Google Services classpath and set it. // Create the Google Services classpath and set it.
String gradlePluginGoogleServicesClassPath = "com.google.gms:google-services:${gradlePluginGoogleServicesVersion}" String gradlePluginGoogleServicesClassPath = "com.google.gms:google-services:${cordovaConfig.GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION}"
println "Adding classpath: ${gradlePluginGoogleServicesClassPath}" println "Adding classpath: ${gradlePluginGoogleServicesClassPath}"
classpath gradlePluginGoogleServicesClassPath classpath gradlePluginGoogleServicesClassPath
} }
@ -84,7 +65,7 @@ allprojects {
} }
task wrapper(type: Wrapper) { task wrapper(type: Wrapper) {
gradleVersion = '6.8.3' gradleVersion = cordovaConfig.GRADLE_VERSION
} }
// Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties. // Configuration properties. Set these via environment variables, build-extras.gradle, or gradle.properties.
@ -92,30 +73,10 @@ task wrapper(type: Wrapper) {
ext { ext {
apply from: '../CordovaLib/cordova.gradle' apply from: '../CordovaLib/cordova.gradle'
// The value for android.compileSdkVersion.
if (!project.hasProperty('cdvCompileSdkVersion')) {
cdvCompileSdkVersion = null;
}
// The value for android.buildToolsVersion.
if (!project.hasProperty('cdvBuildToolsVersion')) {
cdvBuildToolsVersion = null;
}
// Sets the versionCode to the given value. // Sets the versionCode to the given value.
if (!project.hasProperty('cdvVersionCode')) { if (!project.hasProperty('cdvVersionCode')) {
cdvVersionCode = null cdvVersionCode = null
} }
// Sets the minSdkVersion to the given value.
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. // Whether to build architecture-specific APKs.
if (!project.hasProperty('cdvBuildMultipleApks')) { if (!project.hasProperty('cdvBuildMultipleApks')) {
cdvBuildMultipleApks = null cdvBuildMultipleApks = null
@ -137,11 +98,6 @@ ext {
cdvBuildArch = null cdvBuildArch = null
} }
// Sets the default cdvAndroidXAppCompatVersion to the given value.
if (!project.hasProperty('cdvAndroidXAppCompatVersion')) {
cdvAndroidXAppCompatVersion = null
}
// Plugin gradle extensions can append to this to have code run at the end. // Plugin gradle extensions can append to this to have code run at the end.
cdvPluginPostBuildExtras = [] cdvPluginPostBuildExtras = []
} }
@ -159,17 +115,10 @@ if (hasBuildExtras2) {
apply from: '../build-extras.gradle' apply from: '../build-extras.gradle'
} }
// Set property defaults after extension .gradle files. // Apply updates that might come from build-extra.
ext.cdvCompileSdkVersion = cdvCompileSdkVersion == null ? ( privateHelpers.applyCordovaConfigCustomization()
defaultCompileSdkVersion == null
? privateHelpers.getProjectTarget()
: defaultCompileSdkVersion
) : Integer.parseInt('' + cdvCompileSdkVersion);
if (ext.cdvBuildToolsVersion == null) { // Set property defaults after extension .gradle files.
ext.cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
//ext.cdvBuildToolsVersion = project.ext.defaultBuildToolsVersion
}
if (ext.cdvDebugSigningPropertiesFile == null && file('../debug-signing.properties').exists()) { if (ext.cdvDebugSigningPropertiesFile == null && file('../debug-signing.properties').exists()) {
ext.cdvDebugSigningPropertiesFile = '../debug-signing.properties' ext.cdvDebugSigningPropertiesFile = '../debug-signing.properties'
} }
@ -180,18 +129,8 @@ if (ext.cdvReleaseSigningPropertiesFile == null && file('../release-signing.prop
// Cast to appropriate types. // Cast to appropriate types.
ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean(); ext.cdvBuildMultipleApks = cdvBuildMultipleApks == null ? false : cdvBuildMultipleApks.toBoolean();
ext.cdvVersionCodeForceAbiDigit = cdvVersionCodeForceAbiDigit == null ? false : cdvVersionCodeForceAbiDigit.toBoolean(); ext.cdvVersionCodeForceAbiDigit = cdvVersionCodeForceAbiDigit == null ? false : cdvVersionCodeForceAbiDigit.toBoolean();
// 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) ext.cdvVersionCode = cdvVersionCode == null ? null : Integer.parseInt('' + cdvVersionCode)
ext.cdvAndroidXAppCompatVersion = cdvAndroidXAppCompatVersion == null ? defaultAndroidXAppCompatVersion : cdvAndroidXAppCompatVersion
def computeBuildTargetName(debugBuild) { def computeBuildTargetName(debugBuild) {
def ret = 'assemble' def ret = 'assemble'
if (cdvBuildMultipleApks && cdvBuildArch) { if (cdvBuildMultipleApks && cdvBuildArch) {
@ -214,13 +153,12 @@ cdvBuildRelease.dependsOn {
task cdvPrintProps { task cdvPrintProps {
doLast { doLast {
println('cdvCompileSdkVersion=' + cdvCompileSdkVersion)
println('cdvBuildToolsVersion=' + cdvBuildToolsVersion) println('cdvBuildToolsVersion=' + cdvBuildToolsVersion)
println('cdvVersionCode=' + cdvVersionCode) println('cdvVersionCode=' + cdvVersionCode)
println('cdvVersionCodeForceAbiDigit=' + cdvVersionCodeForceAbiDigit) println('cdvVersionCodeForceAbiDigit=' + cdvVersionCodeForceAbiDigit)
println('cdvSdkVersion=' + cdvSdkVersion)
println('cdvMinSdkVersion=' + cdvMinSdkVersion) println('cdvMinSdkVersion=' + cdvMinSdkVersion)
println('cdvMaxSdkVersion=' + cdvMaxSdkVersion) println('cdvMaxSdkVersion=' + cdvMaxSdkVersion)
println('cdvTargetSdkVersion=' + cdvTargetSdkVersion)
println('cdvBuildMultipleApks=' + cdvBuildMultipleApks) println('cdvBuildMultipleApks=' + cdvBuildMultipleApks)
println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile) println('cdvReleaseSigningPropertiesFile=' + cdvReleaseSigningPropertiesFile)
println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile) println('cdvDebugSigningPropertiesFile=' + cdvDebugSigningPropertiesFile)
@ -238,25 +176,19 @@ android {
versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode")) versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
applicationId privateHelpers.extractStringFromManifest("package") applicationId privateHelpers.extractStringFromManifest("package")
if (cdvMinSdkVersion != null) { minSdkVersion cordovaConfig.MIN_SDK_VERSION
minSdkVersion cdvMinSdkVersion if (cordovaConfig.MAX_SDK_VERSION != null) {
} maxSdkVersion cordovaConfig.MAX_SDK_VERSION
if (cdvMaxSdkVersion != null) {
maxSdkVersion cdvMaxSdkVersion
}
if(cdvTargetSdkVersion != null) {
targetSdkVersion cdvTargetSdkVersion
} }
targetSdkVersion cordovaConfig.SDK_VERSION
compileSdkVersion cordovaConfig.SDK_VERSION
} }
lintOptions { lintOptions {
abortOnError false; abortOnError false
} }
compileSdkVersion cdvCompileSdkVersion buildToolsVersion cordovaConfig.LATEST_INSTALLED_BUILD_TOOLS
buildToolsVersion cdvBuildToolsVersion
// This code exists for Crosswalk and other Native APIs. // This code exists for Crosswalk and other Native APIs.
// By default, we multiply the existing version code in the // By default, we multiply the existing version code in the
@ -347,10 +279,10 @@ android {
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: '*.jar') implementation fileTree(dir: 'libs', include: '*.jar')
implementation "androidx.appcompat:appcompat:$cdvAndroidXAppCompatVersion" implementation "androidx.appcompat:appcompat:${cordovaConfig.ANDROIDX_APP_COMPAT_VERSION}"
if (cdvHelpers.getConfigPreference('GradlePluginKotlinEnabled', 'false').toBoolean()) { if (cordovaConfig.IS_GRADLE_PLUGIN_KOTLIN_ENABLED) {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${cordovaConfig.KOTLIN_VERSION}"
} }
// SUB-PROJECT DEPENDENCIES START // SUB-PROJECT DEPENDENCIES START
@ -379,7 +311,7 @@ def addSigningProps(propsFilePath, signingConfig) {
signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword)) signingConfig.storePassword = props.get('storePassword', props.get('key.store.password', signingConfig.storePassword))
def storeType = props.get('storeType', props.get('key.store.type', '')) def storeType = props.get('storeType', props.get('key.store.type', ''))
if (!storeType) { if (!storeType) {
def filename = storeFile.getName().toLowerCase(); def filename = storeFile.getName().toLowerCase()
if (filename.endsWith('.p12') || filename.endsWith('.pfx')) { if (filename.endsWith('.p12') || filename.endsWith('.pfx')) {
storeType = 'pkcs12' storeType = 'pkcs12'
} else { } else {
@ -399,6 +331,6 @@ if (hasProperty('postBuildExtras')) {
postBuildExtras() postBuildExtras()
} }
if (cdvHelpers.getConfigPreference('GradlePluginGoogleServicesEnabled', 'false').toBoolean()) { if (cordovaConfig.IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED) {
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'
} }

View File

@ -17,14 +17,13 @@
*/ */
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.4.32' apply from: 'CordovaLib/cordova.gradle'
apply from: 'repositories.gradle' apply from: 'repositories.gradle'
repositories repos repositories repos
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.2.1' classpath "com.android.tools.build:gradle:${cordovaConfig.AGP_VERSION}"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${cordovaConfig.KOTLIN_VERSION}"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
} }
@ -33,15 +32,6 @@ buildscript {
allprojects { allprojects {
apply from: 'repositories.gradle' apply from: 'repositories.gradle'
repositories repos repositories repos
//This replaces project.properties w.r.t. build settings
project.ext {
defaultBuildToolsVersion="30.0.3" //String
defaultMinSdkVersion=22 //Integer - Minimum requirement is Android 5.1
defaultTargetSdkVersion=30 //Integer - We ALWAYS target the latest by default
defaultCompileSdkVersion=30 //Integer - We ALWAYS compile with the latest by default
defaultAndroidXAppCompatVersion="1.2.0" //String - We ALWAYS compile with the latest stable by default
}
} }
task clean(type: Delete) { task clean(type: Delete) {

View File

@ -18,30 +18,17 @@
ext { ext {
apply from: 'cordova.gradle' apply from: 'cordova.gradle'
cdvCompileSdkVersion = privateHelpers.getProjectTarget()
cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
if (project.hasProperty('cdvMinSdkVersion') && cdvMinSdkVersion.isInteger()) {
cdvMinSdkVersion = cdvMinSdkVersion as int
println '[Cordova] cdvMinSdkVersion is overridden, try it at your own risk.'
} else {
cdvMinSdkVersion = 22; // current Cordova's default
}
if (project.hasProperty('cdvAndroidXAppCompatVersion')) {
cdvAndroidXAppCompatVersion = cdvAndroidXAppCompatVersion
println '[Cordova] cdvAndroidXAppCompatVersion is overridden, try it at your own risk.'
} else {
cdvAndroidXAppCompatVersion = "1.2.0"; // current Cordova's default
}
} }
buildscript { buildscript {
apply from: 'cordova.gradle'
apply from: 'repositories.gradle' apply from: 'repositories.gradle'
repositories repos repositories repos
dependencies { dependencies {
// Android Gradle Plugin (AGP) Build Tools // Android Gradle Plugin (AGP) Build Tools
classpath 'com.android.tools.build:gradle:4.2.1' classpath "com.android.tools.build:gradle:${cordovaConfig.AGP_VERSION}"
// @todo remove this abandoned plugin. maven-publish-plugin is now supported by Android Gradle plugin 3.6.0 and higher // @todo remove this abandoned plugin. maven-publish-plugin is now supported by Android Gradle plugin 3.6.0 and higher
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
@ -62,8 +49,8 @@ group = 'org.apache.cordova'
version = '10.0.0-dev' version = '10.0.0-dev'
android { android {
compileSdkVersion cdvCompileSdkVersion compileSdkVersion cordovaConfig.SDK_VERSION
buildToolsVersion cdvBuildToolsVersion buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
@ -72,7 +59,7 @@ android {
// For the Android Cordova Lib, we allow changing the minSdkVersion, but it is at the users own risk // For the Android Cordova Lib, we allow changing the minSdkVersion, but it is at the users own risk
defaultConfig { defaultConfig {
minSdkVersion cdvMinSdkVersion minSdkVersion cordovaConfig.MIN_SDK_VERSION
} }
sourceSets { sourceSets {
@ -132,7 +119,7 @@ task sourcesJar(type: Jar) {
} }
dependencies { dependencies {
implementation "androidx.appcompat:appcompat:$cdvAndroidXAppCompatVersion" implementation "androidx.appcompat:appcompat:${cordovaConfig.ANDROIDX_APP_COMPAT_VERSION}"
} }
artifacts { artifacts {

View File

@ -0,0 +1,12 @@
{
"MIN_SDK_VERSION": 22,
"SDK_VERSION": 30,
"GRADLE_VERSION": "6.8.3",
"BUILD_TOOLS_VERSION": "30.0.3",
"AGP_VERSION": "4.2.1",
"KOTLIN_VERSION": "1.4.32",
"ANDROIDX_APP_COMPAT_VERSION": "1.2.0",
"GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.3.5",
"IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED": false,
"IS_GRADLE_PLUGIN_KOTLIN_ENABLED": false
}

View File

@ -18,7 +18,6 @@
*/ */
import java.util.regex.Pattern import java.util.regex.Pattern
import groovy.swing.SwingBuilder
import io.github.g00fy2.versioncompare.Version import io.github.g00fy2.versioncompare.Version
String doEnsureValueExists(filePath, props, key) { String doEnsureValueExists(filePath, props, key) {
@ -151,12 +150,57 @@ def doGetConfigPreference(name, defaultValue) {
return ret return ret
} }
def doApplyCordovaConfigCustomization() {
// Apply user overide properties that comes from the "--gradleArg=-P" parameters
if (project.hasProperty('cdvMinSdkVersion')) {
cordovaConfig.MIN_SDK_VERSION = Integer.parseInt('' + cdvMinSdkVersion)
}
if (project.hasProperty('cdvSdkVersion')) {
cordovaConfig.SDK_VERSION = Integer.parseInt('' + cdvSdkVersion)
}
if (project.hasProperty('cdvMaxSdkVersion')) {
cordovaConfig.MAX_SDK_VERSION = Integer.parseInt('' + cdvMaxSdkVersion)
}
if (project.hasProperty('cdvBuildToolsVersion')) {
cordovaConfig.BUILD_TOOLS_VERSION = cdvBuildToolsVersion
}
if (project.hasProperty('cdvAndroidXAppCompatVersion')) {
cordovaConfig.ANDROIDX_APP_COMPAT_VERSION = cdvAndroidXAppCompatVersion
}
// Ensure the latest installed build tools is selected, with or without defined override
cordovaConfig.LATEST_INSTALLED_BUILD_TOOLS = doFindLatestInstalledBuildTools(
cordovaConfig.BUILD_TOOLS_VERSION
)
}
// Properties exported here are visible to all plugins. // Properties exported here are visible to all plugins.
ext { ext {
def defaultsFilePath = './cdv-gradle-config-defaults.json'
def projectConfigFilePath = "$rootDir/cdv-gradle-config.json"
def targetConfigFilePath = null
/**
* Check if the project config file path exists. This file will exist if coming from CLI project.
* If this file does not exist, falls back onto the default file.
* This scenario can occur if building the framework's AAR package for publishing.
*/
if(file(projectConfigFilePath).exists()) {
targetConfigFilePath = projectConfigFilePath
} else {
targetConfigFilePath = defaultsFilePath
}
def jsonFile = new File(targetConfigFilePath)
cordovaConfig = new groovy.json.JsonSlurper().parseText(jsonFile.text)
// Apply Gradle Properties
doApplyCordovaConfigCustomization()
// These helpers are shared, but are not guaranteed to be stable / unchanged. // These helpers are shared, but are not guaranteed to be stable / unchanged.
privateHelpers = {} privateHelpers = {}
privateHelpers.getProjectTarget = { doGetProjectTarget() } privateHelpers.getProjectTarget = { doGetProjectTarget() }
privateHelpers.findLatestInstalledBuildTools = { doFindLatestInstalledBuildTools('19.1.0') } privateHelpers.applyCordovaConfigCustomization = { doApplyCordovaConfigCustomization() }
privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) } privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) }
privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) } privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) }
privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) } privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) }

View File

@ -1,14 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Indicates whether an apk should be generated for each density.
split.density=false
# Project target.
target=android-14
apk-configurations=

View File

@ -3,4 +3,3 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip

View File

@ -1,3 +1,5 @@
# GENERATED FILE! DO NOT EDIT!
# This file was originally created by the Android Tools, but is now # This file was originally created by the Android Tools, but is now
# used by cordova-android to manage the project configuration. # used by cordova-android to manage the project configuration.
@ -5,7 +7,6 @@
split.density=false split.density=false
# Project target. # Project target.
target=android-30
apk-configurations= apk-configurations=
renderscript.opt.level=O0 renderscript.opt.level=O0
android.library=true android.library=true

View File

@ -46,6 +46,13 @@ describe('plugin add', function () {
return Promise.resolve() return Promise.resolve()
.then(() => execa(createBin, [projectPath, projectid, projectname])) .then(() => execa(createBin, [projectPath, projectid, projectname]))
.then(() => { .then(() => {
// Allow test project to find the `cordova-android` module
fs.ensureSymlinkSync(
path.join(__dirname, '../..'),
path.join(projectPath, 'node_modules/cordova-android'),
'junction'
);
const Api = require(path.join(projectPath, 'cordova/Api.js')); const Api = require(path.join(projectPath, 'cordova/Api.js'));
return new Api('android', projectPath).addPlugin(pluginInfo); return new Api('android', projectPath).addPlugin(pluginInfo);
}); });

View File

@ -281,30 +281,15 @@ describe('check_reqs', function () {
check_reqs.__set__('ConfigParser', ConfigParser); check_reqs.__set__('ConfigParser', ConfigParser);
}); });
it('should retrieve target from framework project.properties file', function () { it('should retrieve DEFAULT_TARGET_API', function () {
var target = check_reqs.get_target(); var target = check_reqs.get_target();
expect(target).toBeDefined(); expect(target).toBeDefined();
expect(target).toContain('android-' + DEFAULT_TARGET_API); expect(target).toContain('android-' + DEFAULT_TARGET_API);
}); });
it('should throw error if target cannot be found', function () {
spyOn(fs, 'existsSync').and.returnValue(false);
expect(function () {
check_reqs.get_target();
}).toThrow();
});
it('should override target from config.xml preference', () => { it('should override target from config.xml preference', () => {
var realExistsSync = fs.existsSync; spyOn(fs, 'existsSync').and.returnValue(true);
spyOn(fs, 'existsSync').and.callFake(function (path) { getPreferenceSpy.and.returnValue(String(DEFAULT_TARGET_API + 1));
if (path.indexOf('config.xml') > -1) {
return true;
} else {
return realExistsSync.call(fs, path);
}
});
getPreferenceSpy.and.returnValue(DEFAULT_TARGET_API + 1);
var target = check_reqs.get_target(); var target = check_reqs.get_target();
@ -313,16 +298,8 @@ describe('check_reqs', function () {
}); });
it('should fallback to default target if config.xml has invalid preference', () => { it('should fallback to default target if config.xml has invalid preference', () => {
var realExistsSync = fs.existsSync; spyOn(fs, 'existsSync').and.returnValue(true);
spyOn(fs, 'existsSync').and.callFake(function (path) { getPreferenceSpy.and.returnValue('android-99');
if (path.indexOf('config.xml') > -1) {
return true;
} else {
return realExistsSync.call(fs, path);
}
});
getPreferenceSpy.and.returnValue(NaN);
var target = check_reqs.get_target(); var target = check_reqs.get_target();
@ -331,18 +308,11 @@ describe('check_reqs', function () {
}); });
it('should warn if target sdk preference is lower than the minimum required target SDK', () => { it('should warn if target sdk preference is lower than the minimum required target SDK', () => {
var realExistsSync = fs.existsSync; spyOn(fs, 'existsSync').and.returnValue(true);
spyOn(fs, 'existsSync').and.callFake(function (path) {
if (path.indexOf('config.xml') > -1) {
return true;
} else {
return realExistsSync.call(fs, path);
}
});
spyOn(events, 'emit'); spyOn(events, 'emit');
getPreferenceSpy.and.returnValue(DEFAULT_TARGET_API - 1); getPreferenceSpy.and.returnValue(String(DEFAULT_TARGET_API - 1));
var target = check_reqs.get_target(); var target = check_reqs.get_target();

View File

@ -809,6 +809,7 @@ describe('prepare', () => {
prepare.__set__('events', { prepare.__set__('events', {
emit: jasmine.createSpy('emit') emit: jasmine.createSpy('emit')
}); });
prepare.__set__('updateUserProjectGradleConfig', jasmine.createSpy());
prepare.__set__('updateWww', jasmine.createSpy()); prepare.__set__('updateWww', jasmine.createSpy());
prepare.__set__('updateProjectAccordingTo', jasmine.createSpy('updateProjectAccordingTo') prepare.__set__('updateProjectAccordingTo', jasmine.createSpy('updateProjectAccordingTo')
.and.returnValue(Promise.resolve())); .and.returnValue(Promise.resolve()));

View File

@ -18,14 +18,16 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply from: '../../../framework/cordova.gradle'
android { android {
compileSdkVersion 30 compileSdkVersion cordovaConfig.SDK_VERSION
buildToolsVersion "30.0.3" buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION
defaultConfig { defaultConfig {
applicationId "org.apache.cordova.unittests" applicationId "org.apache.cordova.unittests"
minSdkVersion 22 minSdkVersion cordovaConfig.MIN_SDK_VERSION
targetSdkVersion 30 targetSdkVersion cordovaConfig.SDK_VERSION
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@ -42,7 +44,7 @@ android {
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(path: ':CordovaLib') implementation project(path: ':CordovaLib')
implementation 'androidx.appcompat:appcompat:1.0.2' implementation "androidx.appcompat:appcompat:${cordovaConfig.ANDROIDX_APP_COMPAT_VERSION}"
testImplementation 'org.json:json:20140107' testImplementation 'org.json:json:20140107'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'

View File

@ -19,6 +19,8 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
apply from: '../../framework/cordova.gradle'
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
@ -28,7 +30,7 @@ buildscript {
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
classpath 'com.android.tools.build:gradle:4.2.1' classpath "com.android.tools.build:gradle:${cordovaConfig.AGP_VERSION}"
} }
} }

View File

@ -17,5 +17,6 @@
*/ */
wrapper { wrapper {
gradleVersion = '6.8.3' apply from: '../../framework/cordova.gradle'
gradleVersion = cordovaConfig.GRADLE_VERSION
} }

View File

@ -21,6 +21,7 @@
const path = require('path'); const path = require('path');
const execa = require('execa'); const execa = require('execa');
const fs = require('fs-extra');
const ProjectBuilder = require('../bin/templates/cordova/lib/builders/ProjectBuilder'); const ProjectBuilder = require('../bin/templates/cordova/lib/builders/ProjectBuilder');
class AndroidTestRunner { class AndroidTestRunner {
@ -48,6 +49,9 @@ class AndroidTestRunner {
run () { run () {
return Promise.resolve() return Promise.resolve()
.then(_ => console.log(`[${this.testTitle}] Preparing Gradle wrapper for Java unit tests.`)) .then(_ => console.log(`[${this.testTitle}] Preparing Gradle wrapper for Java unit tests.`))
.then(_ => {
fs.copyFileSync(path.resolve(this.projectDir, '../../framework/cdv-gradle-config-defaults.json'), path.resolve(this.projectDir, 'cdv-gradle-config.json'));
})
.then(_ => this._createProjectBuilder()) .then(_ => this._createProjectBuilder())
.then(_ => this._gradlew('--version')) .then(_ => this._gradlew('--version'))
.then(_ => console.log(`[${this.testTitle}] Gradle wrapper is ready. Running tests now.`)) .then(_ => console.log(`[${this.testTitle}] Gradle wrapper is ready. Running tests now.`))