feat!: bump Gradle 7.6 & AGP 7.4.2 (#1539)

* feat: bump gradle 7.6
* feat: bump android gradle plugin 7.3.1
* feat: bump android gradle plugin 7.4.2
* fix!: move android package name to build.gradle namespace
* fix!: remove deprecated package name from AndroidManifest
* fix: package name
* fix: rename CordovaGradleConfigParser's _save to write
* test: fix CordovaGradleConfigParser related specs
* fix: test refactoring for gradle namespace
* fix: accidental variable naming mixing

---------

Co-authored-by: Norman Breau <norman@nbsolutions.ca>
This commit is contained in:
エリス 2023-04-12 14:39:47 +09:00 committed by GitHub
parent 841710edf7
commit a9d4d4ebd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 243 additions and 108 deletions

View File

@ -18,5 +18,6 @@
under the License. under the License.
--> -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.apache.cordova" android:versionName="1.0" android:versionCode="1"> android:versionName="1.0"
android:versionCode="1">
</manifest> </manifest>

View File

@ -44,6 +44,8 @@ allprojects {
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
android { android {
namespace 'org.apache.cordova'
compileSdkVersion cordovaConfig.COMPILE_SDK_VERSION compileSdkVersion cordovaConfig.COMPILE_SDK_VERSION
buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION

View File

@ -2,14 +2,15 @@
"MIN_SDK_VERSION": 24, "MIN_SDK_VERSION": 24,
"SDK_VERSION": 33, "SDK_VERSION": 33,
"COMPILE_SDK_VERSION": null, "COMPILE_SDK_VERSION": null,
"GRADLE_VERSION": "7.4.2", "GRADLE_VERSION": "7.6",
"MIN_BUILD_TOOLS_VERSION": "33.0.2", "MIN_BUILD_TOOLS_VERSION": "33.0.2",
"AGP_VERSION": "7.2.1", "AGP_VERSION": "7.4.2",
"KOTLIN_VERSION": "1.5.21", "KOTLIN_VERSION": "1.5.21",
"ANDROIDX_APP_COMPAT_VERSION": "1.6.1", "ANDROIDX_APP_COMPAT_VERSION": "1.6.1",
"ANDROIDX_WEBKIT_VERSION": "1.6.0", "ANDROIDX_WEBKIT_VERSION": "1.6.0",
"ANDROIDX_CORE_SPLASHSCREEN_VERSION": "1.0.0", "ANDROIDX_CORE_SPLASHSCREEN_VERSION": "1.0.0",
"GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.3.15", "GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.3.15",
"IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED": false, "IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED": false,
"IS_GRADLE_PLUGIN_KOTLIN_ENABLED": false "IS_GRADLE_PLUGIN_KOTLIN_ENABLED": false,
"PACKAGE_NAMESPACE": "io.cordova.helloCordova"
} }

View File

@ -125,14 +125,6 @@ def doExtractIntFromManifest(name) {
return new BigInteger(matcher.group(1)) return new BigInteger(matcher.group(1))
} }
def doExtractStringFromManifest(name) {
def manifestFile = file(android.sourceSets.main.manifest.srcFile)
def pattern = Pattern.compile(name + "=\"(\\S+)\"")
def matcher = pattern.matcher(manifestFile.getText())
matcher.find()
return matcher.group(1)
}
def doGetConfigXml() { def doGetConfigXml() {
def xml = file("src/main/res/xml/config.xml").getText() def xml = file("src/main/res/xml/config.xml").getText()
// Disable namespace awareness since Cordova doesn't use them properly // Disable namespace awareness since Cordova doesn't use them properly
@ -231,7 +223,6 @@ ext {
privateHelpers.getProjectTarget = { doGetProjectTarget() } privateHelpers.getProjectTarget = { doGetProjectTarget() }
privateHelpers.applyCordovaConfigCustomization = { doApplyCordovaConfigCustomization() } privateHelpers.applyCordovaConfigCustomization = { doApplyCordovaConfigCustomization() }
privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) } privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) }
privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) }
privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) } privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) }
// These helpers can be used by plugins / projects and will not change. // These helpers can be used by plugins / projects and will not change.

View File

@ -50,15 +50,6 @@ class AndroidManifest {
return this; return this;
} }
getPackageId () {
return this.doc.getroot().attrib.package;
}
setPackageId (pkgId) {
this.doc.getroot().attrib.package = pkgId;
return this;
}
getActivity () { getActivity () {
const activity = this.doc.getroot().find('./application/activity'); const activity = this.doc.getroot().find('./application/activity');
return { return {

View File

@ -20,8 +20,8 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const properties_parser = require('properties-parser'); const properties_parser = require('properties-parser');
const AndroidManifest = require('./AndroidManifest');
const pluginHandlers = require('./pluginHandlers'); const pluginHandlers = require('./pluginHandlers');
const CordovaGradleConfigParserFactory = require('./config/CordovaGradleConfigParserFactory');
let projectFileCache = {}; let projectFileCache = {};
@ -63,17 +63,17 @@ class AndroidProject {
this.projectDir = projectDir; this.projectDir = projectDir;
this.platformWww = path.join(this.projectDir, 'platform_www'); this.platformWww = path.join(this.projectDir, 'platform_www');
this.www = path.join(this.projectDir, 'app/src/main/assets/www'); this.www = path.join(this.projectDir, 'app/src/main/assets/www');
this.cordovaGradleConfigParser = CordovaGradleConfigParserFactory.create(this.projectDir);
} }
/** /**
* Reads the package name out of the Android Manifest file * Reads the package name out of the Cordova's Gradle Config file
* *
* @param {String} projectDir The absolute path to the directory containing the project * @param {String} projectDir The absolute path to the directory containing the project
* @return {String} The name of the package * @return {String} The name of the package
*/ */
getPackageName () { getPackageName () {
const manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml'); return this.cordovaGradleConfigParser.getPackageName();
return new AndroidManifest(manifestPath).getPackageId();
} }
getCustomSubprojectRelativeDir (plugin_id, src) { getCustomSubprojectRelativeDir (plugin_id, src) {

View File

@ -27,6 +27,7 @@ const check_reqs = require('../check_reqs');
const PackageType = require('../PackageType'); const PackageType = require('../PackageType');
const { compareByAll } = require('../utils'); const { compareByAll } = require('../utils');
const { createEditor } = require('properties-parser'); const { createEditor } = require('properties-parser');
const CordovaGradleConfigParserFactory = require('../config/CordovaGradleConfigParserFactory');
const MARKER = 'YOUR CHANGES WILL BE ERASED!'; const MARKER = 'YOUR CHANGES WILL BE ERASED!';
const SIGNING_PROPERTIES = '-signing.properties'; const SIGNING_PROPERTIES = '-signing.properties';
@ -145,19 +146,6 @@ class ProjectBuilder {
}; };
} }
extractRealProjectNameFromManifest () {
const manifestPath = path.join(this.root, 'app', 'src', 'main', 'AndroidManifest.xml');
const manifestData = fs.readFileSync(manifestPath, 'utf8');
const m = /<manifest[\s\S]*?package\s*=\s*"(.*?)"/i.exec(manifestData);
if (!m) {
throw new CordovaError('Could not find package name in ' + manifestPath);
}
const packageName = m[1];
const lastDotIndex = packageName.lastIndexOf('.');
return packageName.substring(lastDotIndex + 1);
}
// Makes the project buildable, minus the gradle wrapper. // Makes the project buildable, minus the gradle wrapper.
prepBuildFiles () { prepBuildFiles () {
// Update the version of build.gradle in each dependent library. // Update the version of build.gradle in each dependent library.
@ -184,7 +172,11 @@ class ProjectBuilder {
checkAndCopy(subProjects[i], this.root); checkAndCopy(subProjects[i], this.root);
} }
} }
const projectName = this.extractRealProjectNameFromManifest();
// get project name cdv-gradle-config.
const cdvGradleConfig = CordovaGradleConfigParserFactory.create(this.root);
const projectName = cdvGradleConfig.getProjectNameFromPackageName();
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149 // Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
const settingsGradlePaths = subProjects.map(function (p) { const settingsGradlePaths = subProjects.map(function (p) {
const realDir = p.replace(/[/\\]/g, ':'); const realDir = p.replace(/[/\\]/g, ':');

View File

@ -0,0 +1,71 @@
/**
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 fs = require('fs-extra');
const path = require('path');
const events = require('cordova-common').events;
class CordovaGradleConfigParser {
/**
* Loads and Edits Gradle Properties File.
*
* Do not construct this directly. Use CordovaGradleConfigParserFactory instead.
*
* @param {String} platformDir is the path of the Android platform directory
*/
constructor (platformDir) {
this._cdvGradleConfigFilePath = path.join(platformDir, 'cdv-gradle-config.json');
this._cdvGradleConfig = this._readConfig(this._cdvGradleConfigFilePath);
}
/**
* Reads and parses the configuration JSON file
*
* @param {String} configPath
* @returns {Record<any, any>} The parsed JSON object representing the gradle config.
*/
_readConfig (configPath) {
return fs.readJSONSync(configPath, 'utf-8');
}
setPackageName (packageName) {
events.emit('verbose', '[Cordova Gradle Config] Setting "PACKAGE_NAMESPACE" to ' + packageName);
this._cdvGradleConfig.PACKAGE_NAMESPACE = packageName;
return this;
}
getPackageName () {
return this._cdvGradleConfig.PACKAGE_NAMESPACE;
}
getProjectNameFromPackageName () {
const packageName = this._cdvGradleConfig.PACKAGE_NAMESPACE;
return packageName.substring(packageName.lastIndexOf('.') + 1);
}
/**
* Saves any changes that has been made to the properties file.
*/
write () {
events.emit('verbose', '[Cordova Gradle Config] Saving File');
fs.writeJSONSync(this._cdvGradleConfigFilePath, this._cdvGradleConfig, 'utf-8');
}
}
module.exports = CordovaGradleConfigParser;

View File

@ -0,0 +1,35 @@
/**
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 CordovaGradleConfigParser = require('./CordovaGradleConfigParser');
/**
* Builds new gradle config parsers
*/
module.exports = class CordovaGradleConfigParserFactory {
/**
* Loads and Edits Gradle Properties File.
*
* @param {String} platformDir is the path of the Android platform directory
*/
static create (platformDir) {
return new CordovaGradleConfigParser(platformDir);
}
};

View File

@ -23,6 +23,7 @@ const utils = require('./utils');
const check_reqs = require('./check_reqs'); const check_reqs = require('./check_reqs');
const ROOT = path.join(__dirname, '..'); const ROOT = path.join(__dirname, '..');
const { createEditor } = require('properties-parser'); const { createEditor } = require('properties-parser');
const CordovaGradleConfigParserFactory = require('./config/CordovaGradleConfigParserFactory');
const CordovaError = require('cordova-common').CordovaError; const CordovaError = require('cordova-common').CordovaError;
const AndroidManifest = require('./AndroidManifest'); const AndroidManifest = require('./AndroidManifest');
@ -249,6 +250,11 @@ exports.create = function (project_path, config, options, events) {
fs.ensureDirSync(assets_path); fs.ensureDirSync(assets_path);
fs.ensureDirSync(resource_path); fs.ensureDirSync(resource_path);
// store package name in cdv-gradle-config
const cdvGradleConfig = CordovaGradleConfigParserFactory.create(project_path);
cdvGradleConfig.setPackageName(package_name)
.write();
// interpolate the activity name and package // interpolate the activity name and package
const packagePath = package_name.replace(/\./g, path.sep); const packagePath = package_name.replace(/\./g, path.sep);
const activity_dir = path.join(java_path, packagePath); const activity_dir = path.join(java_path, packagePath);
@ -261,8 +267,7 @@ exports.create = function (project_path, config, options, events) {
utils.replaceFileContents(activity_path, /__ID__/, package_name); utils.replaceFileContents(activity_path, /__ID__/, package_name);
const manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml')); const manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
manifest.setPackageId(package_name) manifest.getActivity().setName(safe_activity_name);
.getActivity().setName(safe_activity_name);
const manifest_path = path.join(app_path, 'AndroidManifest.xml'); const manifest_path = path.join(app_path, 'AndroidManifest.xml');
manifest.write(manifest_path); manifest.write(manifest_path);

View File

@ -34,6 +34,7 @@ const utils = require('./utils');
const gradleConfigDefaults = require('./gradle-config-defaults'); const gradleConfigDefaults = require('./gradle-config-defaults');
const checkReqs = require('./check_reqs'); const checkReqs = require('./check_reqs');
const GradlePropertiesParser = require('./config/GradlePropertiesParser'); const GradlePropertiesParser = require('./config/GradlePropertiesParser');
const CordovaGradleConfigParserFactory = require('./config/CordovaGradleConfigParserFactory');
function parseArguments (argv) { function parseArguments (argv) {
return nopt({ return nopt({
@ -278,20 +279,22 @@ function updateProjectAccordingTo (platformConfig, locations) {
// Java packages cannot support dashes // Java packages cannot support dashes
const androidPkgName = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_'); const androidPkgName = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_');
const manifest = new AndroidManifest(locations.manifest); // updating cdv-gradle-config with new androidPkgName.
const manifestId = manifest.getPackageId(); const cdvGradleConfig = CordovaGradleConfigParserFactory.create(locations.root);
cdvGradleConfig.setPackageName(androidPkgName)
.write();
const manifest = new AndroidManifest(locations.manifest);
manifest.getActivity() manifest.getActivity()
.setOrientation(platformConfig.getPreference('orientation')) .setOrientation(platformConfig.getPreference('orientation'))
.setLaunchMode(findAndroidLaunchModePreference(platformConfig)); .setLaunchMode(findAndroidLaunchModePreference(platformConfig));
manifest.setVersionName(platformConfig.version()) manifest.setVersionName(platformConfig.version())
.setVersionCode(platformConfig.android_versionCode() || default_versionCode(platformConfig.version())) .setVersionCode(platformConfig.android_versionCode() || default_versionCode(platformConfig.version()))
.setPackageId(androidPkgName)
.write(); .write();
// Java file paths shouldn't be hard coded // Java file paths shouldn't be hard coded
const javaDirectory = path.join(locations.javaSrc, manifestId.replace(/\./g, '/')); const javaDirectory = path.join(locations.javaSrc, androidPkgName.replace(/\./g, '/'));
const java_files = glob.sync('**/*.java', { cwd: javaDirectory, absolute: true }).filter(f => { const java_files = glob.sync('**/*.java', { cwd: javaDirectory, absolute: true }).filter(f => {
const contents = fs.readFileSync(f, 'utf-8'); const contents = fs.readFileSync(f, 'utf-8');
return /extends\s+CordovaActivity/.test(contents); return /extends\s+CordovaActivity/.test(contents);

View File

@ -23,6 +23,7 @@ const build = require('./build');
const PackageType = require('./PackageType'); const PackageType = require('./PackageType');
const AndroidManifest = require('./AndroidManifest'); const AndroidManifest = require('./AndroidManifest');
const { CordovaError, events } = require('cordova-common'); const { CordovaError, events } = require('cordova-common');
const CordovaGradleConfigParserFactory = require('./config/CordovaGradleConfigParserFactory');
/** /**
* Builds a target spec from a runOptions object * Builds a target spec from a runOptions object
@ -78,6 +79,7 @@ module.exports.run = async function (runOptions = {}) {
} }
const manifest = new AndroidManifest(this.locations.manifest); const manifest = new AndroidManifest(this.locations.manifest);
const cordovaGradleConfigParser = CordovaGradleConfigParserFactory.create(this.locations.root);
return target.install(resolvedTarget, { manifest, buildResults }); return target.install(resolvedTarget, { manifest, buildResults, cordovaGradleConfigParser });
}; };

View File

@ -127,9 +127,9 @@ exports.resolve = async (spec, buildResults) => {
}; };
}; };
exports.install = async function ({ id: target, arch, type }, { manifest, buildResults }) { exports.install = async function ({ id: target, arch, type }, { manifest, buildResults, cordovaGradleConfigParser }) {
const apk_path = build.findBestApkForArchitecture(buildResults, arch); const apk_path = build.findBestApkForArchitecture(buildResults, arch);
const pkgName = manifest.getPackageId(); const pkgName = cordovaGradleConfigParser.getPackageName();
const launchName = pkgName + '/.' + manifest.getActivity().getName(); const launchName = pkgName + '/.' + manifest.getActivity().getName();
events.emit('log', 'Using apk: ' + apk_path); events.emit('log', 'Using apk: ' + apk_path);

View File

@ -3,4 +3,4 @@ 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-7.4.2-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip

View File

@ -110,18 +110,6 @@ describe('AndroidManifest', () => {
}); });
}); });
describe('packageId', () => {
it('should get the package ID', () => {
expect(manifest.getPackageId()).toBe(PACKAGE_ID);
});
it('should set the package ID', () => {
const newPackageId = `${PACKAGE_ID}new`;
manifest.setPackageId(newPackageId);
expect(manifest.getPackageId()).toBe(newPackageId);
});
});
describe('activity', () => { describe('activity', () => {
let activity; let activity;

View File

@ -19,6 +19,8 @@
const path = require('path'); const path = require('path');
const rewire = require('rewire'); const rewire = require('rewire');
const MockCordovaGradleConfigParser = require('./mocks/config/MockCordovaGradleConfigParser');
const CordovaGradleConfigParserFactory = require('../../lib/config/CordovaGradleConfigParserFactory');
describe('AndroidProject', () => { describe('AndroidProject', () => {
const PROJECT_DIR = 'platforms/android'; const PROJECT_DIR = 'platforms/android';
@ -30,6 +32,8 @@ describe('AndroidProject', () => {
AndroidStudioSpy = jasmine.createSpyObj('AndroidStudio', ['isAndroidStudioProject']); AndroidStudioSpy = jasmine.createSpyObj('AndroidStudio', ['isAndroidStudioProject']);
AndroidProject.__set__('AndroidStudio', AndroidStudioSpy); AndroidProject.__set__('AndroidStudio', AndroidStudioSpy);
spyOn(CordovaGradleConfigParserFactory, 'create').and.returnValue(new MockCordovaGradleConfigParser(PROJECT_DIR));
}); });
describe('constructor', () => { describe('constructor', () => {
@ -87,26 +91,20 @@ describe('AndroidProject', () => {
}); });
describe('getPackageName', () => { describe('getPackageName', () => {
let AndroidManifestSpy;
let AndroidManifestFns;
let androidProject; let androidProject;
beforeEach(() => { beforeEach(() => {
AndroidManifestFns = jasmine.createSpyObj('AndroidManifestFns', ['getPackageId']);
AndroidManifestSpy = jasmine.createSpy('AndroidManifest').and.returnValue(AndroidManifestFns);
AndroidProject.__set__('AndroidManifest', AndroidManifestSpy);
androidProject = new AndroidProject(PROJECT_DIR); androidProject = new AndroidProject(PROJECT_DIR);
}); });
it('should get the package name AndroidManifest', () => { it('should get the package name Cordova Gradle Config file', () => {
spyOn(MockCordovaGradleConfigParser.prototype, 'getPackageName');
androidProject.getPackageName(); androidProject.getPackageName();
expect(AndroidManifestSpy).toHaveBeenCalledWith(path.join(PROJECT_DIR, 'app/src/main/AndroidManifest.xml')); expect(MockCordovaGradleConfigParser.prototype.getPackageName).toHaveBeenCalled();
}); });
it('should return the package name', () => { it('should return the package name', () => {
const packageName = 'io.cordova.unittest'; const packageName = 'io.cordova.unittest';
AndroidManifestFns.getPackageId.and.returnValue(packageName);
expect(androidProject.getPackageName()).toBe(packageName); expect(androidProject.getPackageName()).toBe(packageName);
}); });

View File

@ -21,8 +21,6 @@ const fs = require('fs-extra');
const path = require('path'); const path = require('path');
const rewire = require('rewire'); const rewire = require('rewire');
const CordovaError = require('cordova-common').CordovaError;
describe('ProjectBuilder', () => { describe('ProjectBuilder', () => {
const rootDir = '/root'; const rootDir = '/root';
@ -143,30 +141,6 @@ describe('ProjectBuilder', () => {
expect(execaSpy).not.toHaveBeenCalledWith('/my/sweet/gradle', jasmine.any(Array), jasmine.any(Object)); expect(execaSpy).not.toHaveBeenCalledWith('/my/sweet/gradle', jasmine.any(Array), jasmine.any(Object));
}); });
}); });
describe('extractRealProjectNameFromManifest', () => {
it('should get the project name from the Android Manifest', () => {
const projectName = 'unittestproject';
const projectId = `io.cordova.${projectName}`;
const manifest = `<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="${projectId}"></manifest>`;
spyOn(fs, 'readFileSync').and.returnValue(manifest);
expect(builder.extractRealProjectNameFromManifest()).toBe(projectName);
});
it('should throw an error if there is no package in the Android manifest', () => {
const manifest = `<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"></manifest>`;
spyOn(fs, 'readFileSync').and.returnValue(manifest);
expect(() => builder.extractRealProjectNameFromManifest()).toThrow(jasmine.any(CordovaError));
});
});
describe('build', () => { describe('build', () => {
beforeEach(() => { beforeEach(() => {
spyOn(builder, 'getArgs'); spyOn(builder, 'getArgs');

View File

@ -23,8 +23,16 @@ const create = rewire('../../lib/create');
const check_reqs = require('../../lib/check_reqs'); const check_reqs = require('../../lib/check_reqs');
const fs = require('fs-extra'); const fs = require('fs-extra');
const path = require('path'); const path = require('path');
const MockCordovaGradleConfigParser = require('./mocks/config/MockCordovaGradleConfigParser');
const CordovaGradleConfigParserFactory = require('../../lib/config/CordovaGradleConfigParserFactory');
describe('create', function () { describe('create', function () {
const PROJECT_DIR = 'platforms/android';
beforeAll(() => {
spyOn(CordovaGradleConfigParserFactory, 'create').and.returnValue(new MockCordovaGradleConfigParser(PROJECT_DIR));
});
describe('validatePackageName helper method', function () { describe('validatePackageName helper method', function () {
describe('happy path (valid package names)', function () { describe('happy path (valid package names)', function () {
const valid = [ const valid = [

View File

@ -0,0 +1,32 @@
/**
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 CordovaGradleConfigParser = require('../../../../lib/config/CordovaGradleConfigParser');
module.exports = class MockCordoCordovaGradleConfigParservaGradleConfigParser extends CordovaGradleConfigParser {
_readConfig (configPath) {
return {
PACKAGE_NAMESPACE: 'io.cordova.unittest'
};
}
write () {
// Pretend write :)
}
};

View File

@ -32,6 +32,9 @@ const android_studio_project = path.join(__dirname, '../../fixtures/android_stud
const PluginInfo = require('cordova-common').PluginInfo; const PluginInfo = require('cordova-common').PluginInfo;
const AndroidProject = require('../../../lib/AndroidProject'); const AndroidProject = require('../../../lib/AndroidProject');
const MockCordovaGradleConfigParser = require('../mocks/config/MockCordovaGradleConfigParser');
const CordovaGradleConfigParserFactory = require('../../../lib/config/CordovaGradleConfigParserFactory');
const dummyPluginInfo = new PluginInfo(dummyplugin); const dummyPluginInfo = new PluginInfo(dummyplugin);
const valid_source = dummyPluginInfo.getSourceFiles('android'); const valid_source = dummyPluginInfo.getSourceFiles('android');
const valid_resources = dummyPluginInfo.getResourceFiles('android'); const valid_resources = dummyPluginInfo.getResourceFiles('android');
@ -41,6 +44,12 @@ const faultyPluginInfo = new PluginInfo(faultyplugin);
const invalid_source = faultyPluginInfo.getSourceFiles('android'); const invalid_source = faultyPluginInfo.getSourceFiles('android');
describe('android project handler', function () { describe('android project handler', function () {
const PROJECT_DIR = 'platforms/android';
beforeAll(() => {
spyOn(CordovaGradleConfigParserFactory, 'create').and.returnValue(new MockCordovaGradleConfigParser(PROJECT_DIR));
});
describe('installation', function () { describe('installation', function () {
const copyFileOrig = common.__get__('copyFile'); const copyFileOrig = common.__get__('copyFile');
const copyFileSpy = jasmine.createSpy('copyFile'); const copyFileSpy = jasmine.createSpy('copyFile');

View File

@ -23,6 +23,8 @@ const CordovaError = require('cordova-common').CordovaError;
const GradlePropertiesParser = require('../../lib/config/GradlePropertiesParser'); const GradlePropertiesParser = require('../../lib/config/GradlePropertiesParser');
const utils = require('../../lib/utils'); const utils = require('../../lib/utils');
const et = require('elementtree'); const et = require('elementtree');
const MockCordovaGradleConfigParser = require('./mocks/config/MockCordovaGradleConfigParser');
const CordovaGradleConfigParserFactory = require('../../lib/config/CordovaGradleConfigParserFactory');
const PATH_RESOURCE = path.join('platforms', 'android', 'app', 'src', 'main', 'res'); const PATH_RESOURCE = path.join('platforms', 'android', 'app', 'src', 'main', 'res');
@ -93,6 +95,12 @@ describe('prepare', () => {
let emitSpy; let emitSpy;
let updatePathsSpy; let updatePathsSpy;
const PROJECT_DIR = 'platforms/android';
beforeAll(() => {
spyOn(CordovaGradleConfigParserFactory, 'create').and.returnValue(new MockCordovaGradleConfigParser(PROJECT_DIR));
});
beforeEach(() => { beforeEach(() => {
prepare = rewire('../../lib/prepare'); prepare = rewire('../../lib/prepare');
@ -912,9 +920,7 @@ describe('prepare', () => {
}), }),
setVersionName: jasmine.createSpy('setVersionName').and.returnValue({ setVersionName: jasmine.createSpy('setVersionName').and.returnValue({
setVersionCode: jasmine.createSpy('setVersionCode').and.returnValue({ setVersionCode: jasmine.createSpy('setVersionCode').and.returnValue({
setPackageId: jasmine.createSpy('setPackageId').and.returnValue({ write: jasmine.createSpy('write')
write: jasmine.createSpy('write')
})
}) })
}) })
})); }));

View File

@ -19,10 +19,19 @@
const rewire = require('rewire'); const rewire = require('rewire');
const builders = require('../../lib/builders/builders'); const builders = require('../../lib/builders/builders');
const MockCordovaGradleConfigParser = require('./mocks/config/MockCordovaGradleConfigParser');
const CordovaGradleConfigParser = require('../../lib/config/CordovaGradleConfigParser');
const CordovaGradleConfigParserFactory = require('../../lib/config/CordovaGradleConfigParserFactory');
describe('run', () => { describe('run', () => {
let run; let run;
const PROJECT_DIR = 'platforms/android';
beforeAll(() => {
spyOn(CordovaGradleConfigParserFactory, 'create').and.returnValue(new MockCordovaGradleConfigParser(PROJECT_DIR));
});
beforeEach(() => { beforeEach(() => {
run = rewire('../../lib/run'); run = rewire('../../lib/run');
run.__set__({ run.__set__({
@ -84,7 +93,8 @@ describe('run', () => {
buildResults: { buildResults: {
buildType: 'debug', buildType: 'debug',
apkPaths: ['fake.apk'] apkPaths: ['fake.apk']
} },
cordovaGradleConfigParser: jasmine.any(CordovaGradleConfigParser)
} }
); );
}); });

View File

@ -19,10 +19,18 @@
const rewire = require('rewire'); const rewire = require('rewire');
const { CordovaError } = require('cordova-common'); const { CordovaError } = require('cordova-common');
const MockCordovaGradleConfigParser = require('./mocks/config/MockCordovaGradleConfigParser');
const CordovaGradleConfigParserFactory = require('../../lib/config/CordovaGradleConfigParserFactory');
describe('target', () => { describe('target', () => {
let target; let target;
const PROJECT_DIR = 'platforms/android';
beforeAll(() => {
spyOn(CordovaGradleConfigParserFactory, 'create').and.returnValue(new MockCordovaGradleConfigParser(PROJECT_DIR));
});
beforeEach(() => { beforeEach(() => {
target = rewire('../../lib/target'); target = rewire('../../lib/target');
}); });
@ -228,14 +236,18 @@ describe('target', () => {
describe('install', () => { describe('install', () => {
let AdbSpy; let AdbSpy;
let buildSpy; let buildSpy;
let installTarget, manifest, appSpec; let installTarget, manifest, cordovaGradleConfigParser, appSpec;
beforeEach(() => { beforeEach(() => {
installTarget = { id: 'emulator-5556', type: 'emulator', arch: 'atari' }; installTarget = { id: 'emulator-5556', type: 'emulator', arch: 'atari' };
manifest = jasmine.createSpyObj('manifestStub', ['getPackageId', 'getActivity']); manifest = jasmine.createSpyObj('manifestStub', ['getActivity']);
manifest.getActivity.and.returnValue(jasmine.createSpyObj('Activity', ['getName'])); manifest.getActivity.and.returnValue(jasmine.createSpyObj('Activity', ['getName']));
appSpec = { manifest, buildResults: {} };
cordovaGradleConfigParser = jasmine.createSpyObj('cordovaGradleConfigParserStub', ['getPackageName']);
cordovaGradleConfigParser.getPackageName.and.returnValue('unittestapp');
appSpec = { manifest, buildResults: {}, cordovaGradleConfigParser };
buildSpy = jasmine.createSpyObj('build', ['findBestApkForArchitecture']); buildSpy = jasmine.createSpyObj('build', ['findBestApkForArchitecture']);
target.__set__('build', buildSpy); target.__set__('build', buildSpy);
@ -267,7 +279,7 @@ describe('target', () => {
const apkPath = 'my/apk/path/app.apk'; const apkPath = 'my/apk/path/app.apk';
buildSpy.findBestApkForArchitecture.and.returnValue(apkPath); buildSpy.findBestApkForArchitecture.and.returnValue(apkPath);
return target.install(installTarget, { manifest, buildResults }).then(() => { return target.install(installTarget, { manifest, buildResults, cordovaGradleConfigParser: CordovaGradleConfigParserFactory.create(PROJECT_DIR) }).then(() => {
expect(buildSpy.findBestApkForArchitecture).toHaveBeenCalledWith(buildResults, installTarget.arch); expect(buildSpy.findBestApkForArchitecture).toHaveBeenCalledWith(buildResults, installTarget.arch);
expect(AdbSpy.install.calls.argsFor(0)[1]).toBe(apkPath); expect(AdbSpy.install.calls.argsFor(0)[1]).toBe(apkPath);
@ -308,7 +320,7 @@ describe('target', () => {
it('should start the newly installed app on the device', () => { it('should start the newly installed app on the device', () => {
const packageId = 'unittestapp'; const packageId = 'unittestapp';
const activityName = 'TestActivity'; const activityName = 'TestActivity';
manifest.getPackageId.and.returnValue(packageId); cordovaGradleConfigParser.getPackageName.and.returnValue(packageId);
manifest.getActivity().getName.and.returnValue(activityName); manifest.getActivity().getName.and.returnValue(activityName);
return target.install(installTarget, appSpec).then(() => { return target.install(installTarget, appSpec).then(() => {

View File

@ -18,7 +18,9 @@
under the License. under the License.
--> -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="__PACKAGE__" android:versionName="1.0" android:versionCode="1" android:hardwareAccelerated="true"> android:versionName="1.0"
android:versionCode="1"
android:hardwareAccelerated="true">
<supports-screens <supports-screens
android:largeScreens="true" android:largeScreens="true"
android:normalScreens="true" android:normalScreens="true"

View File

@ -179,9 +179,11 @@ task cdvPrintProps {
} }
android { android {
namespace cordovaConfig.PACKAGE_NAMESPACE
defaultConfig { defaultConfig {
versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode")) versionCode cdvVersionCode ?: new BigInteger("" + privateHelpers.extractIntFromManifest("versionCode"))
applicationId privateHelpers.extractStringFromManifest("package") applicationId cordovaConfig.PACKAGE_NAMESPACE
minSdkVersion cordovaConfig.MIN_SDK_VERSION minSdkVersion cordovaConfig.MIN_SDK_VERSION
if (cordovaConfig.MAX_SDK_VERSION != null) { if (cordovaConfig.MAX_SDK_VERSION != null) {