Skip to content

Commit

Permalink
feat!: bump Gradle 7.6 & AGP 7.4.2 (#1539)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
erisu and breautek committed Apr 12, 2023
1 parent 841710e commit a9d4d4e
Show file tree
Hide file tree
Showing 25 changed files with 243 additions and 108 deletions.
3 changes: 2 additions & 1 deletion framework/AndroidManifest.xml
Expand Up @@ -18,5 +18,6 @@
under the License.
-->
<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>
2 changes: 2 additions & 0 deletions framework/build.gradle
Expand Up @@ -44,6 +44,8 @@ allprojects {
apply plugin: 'com.android.library'

android {
namespace 'org.apache.cordova'

compileSdkVersion cordovaConfig.COMPILE_SDK_VERSION
buildToolsVersion cordovaConfig.BUILD_TOOLS_VERSION

Expand Down
7 changes: 4 additions & 3 deletions framework/cdv-gradle-config-defaults.json
Expand Up @@ -2,14 +2,15 @@
"MIN_SDK_VERSION": 24,
"SDK_VERSION": 33,
"COMPILE_SDK_VERSION": null,
"GRADLE_VERSION": "7.4.2",
"GRADLE_VERSION": "7.6",
"MIN_BUILD_TOOLS_VERSION": "33.0.2",
"AGP_VERSION": "7.2.1",
"AGP_VERSION": "7.4.2",
"KOTLIN_VERSION": "1.5.21",
"ANDROIDX_APP_COMPAT_VERSION": "1.6.1",
"ANDROIDX_WEBKIT_VERSION": "1.6.0",
"ANDROIDX_CORE_SPLASHSCREEN_VERSION": "1.0.0",
"GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.3.15",
"IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED": false,
"IS_GRADLE_PLUGIN_KOTLIN_ENABLED": false
"IS_GRADLE_PLUGIN_KOTLIN_ENABLED": false,
"PACKAGE_NAMESPACE": "io.cordova.helloCordova"
}
9 changes: 0 additions & 9 deletions framework/cordova.gradle
Expand Up @@ -125,14 +125,6 @@ def doExtractIntFromManifest(name) {
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 xml = file("src/main/res/xml/config.xml").getText()
// Disable namespace awareness since Cordova doesn't use them properly
Expand Down Expand Up @@ -231,7 +223,6 @@ ext {
privateHelpers.getProjectTarget = { doGetProjectTarget() }
privateHelpers.applyCordovaConfigCustomization = { doApplyCordovaConfigCustomization() }
privateHelpers.extractIntFromManifest = { name -> doExtractIntFromManifest(name) }
privateHelpers.extractStringFromManifest = { name -> doExtractStringFromManifest(name) }
privateHelpers.ensureValueExists = { filePath, props, key -> doEnsureValueExists(filePath, props, key) }

// These helpers can be used by plugins / projects and will not change.
Expand Down
9 changes: 0 additions & 9 deletions lib/AndroidManifest.js
Expand Up @@ -50,15 +50,6 @@ class AndroidManifest {
return this;
}

getPackageId () {
return this.doc.getroot().attrib.package;
}

setPackageId (pkgId) {
this.doc.getroot().attrib.package = pkgId;
return this;
}

getActivity () {
const activity = this.doc.getroot().find('./application/activity');
return {
Expand Down
8 changes: 4 additions & 4 deletions lib/AndroidProject.js
Expand Up @@ -20,8 +20,8 @@
const fs = require('fs');
const path = require('path');
const properties_parser = require('properties-parser');
const AndroidManifest = require('./AndroidManifest');
const pluginHandlers = require('./pluginHandlers');
const CordovaGradleConfigParserFactory = require('./config/CordovaGradleConfigParserFactory');

let projectFileCache = {};

Expand Down Expand Up @@ -63,17 +63,17 @@ class AndroidProject {
this.projectDir = projectDir;
this.platformWww = path.join(this.projectDir, 'platform_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
* @return {String} The name of the package
*/
getPackageName () {
const manifestPath = path.join(this.projectDir, 'app/src/main/AndroidManifest.xml');
return new AndroidManifest(manifestPath).getPackageId();
return this.cordovaGradleConfigParser.getPackageName();
}

getCustomSubprojectRelativeDir (plugin_id, src) {
Expand Down
20 changes: 6 additions & 14 deletions lib/builders/ProjectBuilder.js
Expand Up @@ -27,6 +27,7 @@ const check_reqs = require('../check_reqs');
const PackageType = require('../PackageType');
const { compareByAll } = require('../utils');
const { createEditor } = require('properties-parser');
const CordovaGradleConfigParserFactory = require('../config/CordovaGradleConfigParserFactory');

const MARKER = 'YOUR CHANGES WILL BE ERASED!';
const SIGNING_PROPERTIES = '-signing.properties';
Expand Down Expand Up @@ -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.
prepBuildFiles () {
// Update the version of build.gradle in each dependent library.
Expand All @@ -184,7 +172,11 @@ class ProjectBuilder {
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
const settingsGradlePaths = subProjects.map(function (p) {
const realDir = p.replace(/[/\\]/g, ':');
Expand Down
71 changes: 71 additions & 0 deletions lib/config/CordovaGradleConfigParser.js
@@ -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;
35 changes: 35 additions & 0 deletions lib/config/CordovaGradleConfigParserFactory.js
@@ -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);
}
};
9 changes: 7 additions & 2 deletions lib/create.js
Expand Up @@ -23,6 +23,7 @@ const utils = require('./utils');
const check_reqs = require('./check_reqs');
const ROOT = path.join(__dirname, '..');
const { createEditor } = require('properties-parser');
const CordovaGradleConfigParserFactory = require('./config/CordovaGradleConfigParserFactory');

const CordovaError = require('cordova-common').CordovaError;
const AndroidManifest = require('./AndroidManifest');
Expand Down Expand Up @@ -249,6 +250,11 @@ exports.create = function (project_path, config, options, events) {
fs.ensureDirSync(assets_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
const packagePath = package_name.replace(/\./g, path.sep);
const activity_dir = path.join(java_path, packagePath);
Expand All @@ -261,8 +267,7 @@ exports.create = function (project_path, config, options, events) {
utils.replaceFileContents(activity_path, /__ID__/, package_name);

const manifest = new AndroidManifest(path.join(project_template_dir, 'AndroidManifest.xml'));
manifest.setPackageId(package_name)
.getActivity().setName(safe_activity_name);
manifest.getActivity().setName(safe_activity_name);

const manifest_path = path.join(app_path, 'AndroidManifest.xml');
manifest.write(manifest_path);
Expand Down
11 changes: 7 additions & 4 deletions lib/prepare.js
Expand Up @@ -34,6 +34,7 @@ const utils = require('./utils');
const gradleConfigDefaults = require('./gradle-config-defaults');
const checkReqs = require('./check_reqs');
const GradlePropertiesParser = require('./config/GradlePropertiesParser');
const CordovaGradleConfigParserFactory = require('./config/CordovaGradleConfigParserFactory');

function parseArguments (argv) {
return nopt({
Expand Down Expand Up @@ -278,20 +279,22 @@ function updateProjectAccordingTo (platformConfig, locations) {
// Java packages cannot support dashes
const androidPkgName = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_');

const manifest = new AndroidManifest(locations.manifest);
const manifestId = manifest.getPackageId();
// updating cdv-gradle-config with new androidPkgName.
const cdvGradleConfig = CordovaGradleConfigParserFactory.create(locations.root);
cdvGradleConfig.setPackageName(androidPkgName)
.write();

const manifest = new AndroidManifest(locations.manifest);
manifest.getActivity()
.setOrientation(platformConfig.getPreference('orientation'))
.setLaunchMode(findAndroidLaunchModePreference(platformConfig));

manifest.setVersionName(platformConfig.version())
.setVersionCode(platformConfig.android_versionCode() || default_versionCode(platformConfig.version()))
.setPackageId(androidPkgName)
.write();

// 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 contents = fs.readFileSync(f, 'utf-8');
return /extends\s+CordovaActivity/.test(contents);
Expand Down
4 changes: 3 additions & 1 deletion lib/run.js
Expand Up @@ -23,6 +23,7 @@ const build = require('./build');
const PackageType = require('./PackageType');
const AndroidManifest = require('./AndroidManifest');
const { CordovaError, events } = require('cordova-common');
const CordovaGradleConfigParserFactory = require('./config/CordovaGradleConfigParserFactory');

/**
* Builds a target spec from a runOptions object
Expand Down Expand Up @@ -78,6 +79,7 @@ module.exports.run = async function (runOptions = {}) {
}

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 });
};
4 changes: 2 additions & 2 deletions lib/target.js
Expand Up @@ -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 pkgName = manifest.getPackageId();
const pkgName = cordovaGradleConfigParser.getPackageName();
const launchName = pkgName + '/.' + manifest.getActivity().getName();

events.emit('log', 'Using apk: ' + apk_path);
Expand Down
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
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
12 changes: 0 additions & 12 deletions spec/unit/AndroidManifest.spec.js
Expand Up @@ -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', () => {
let activity;

Expand Down

0 comments on commit a9d4d4e

Please sign in to comment.