From 8d20f842a32a0ebc29750896fa1ec5819cb3dee6 Mon Sep 17 00:00:00 2001 From: Erisu Date: Tue, 12 May 2026 13:02:42 +0900 Subject: [PATCH] feat: support adding project build script dependencies --- lib/AndroidProject.js | 14 ++++++++++++++ lib/builders/ProjectBuilder.js | 15 +++++++++++++++ lib/pluginHandlers.js | 12 ++++++++++-- spec/unit/pluginHandlers/handlers.spec.js | 14 ++++++++++++++ templates/project/app/build.gradle | 3 +++ 5 files changed, 56 insertions(+), 2 deletions(-) diff --git a/lib/AndroidProject.js b/lib/AndroidProject.js index bc5f36c5..6665b3a2 100644 --- a/lib/AndroidProject.js +++ b/lib/AndroidProject.js @@ -124,6 +124,20 @@ class AndroidProject { this._dirty = true; } + addAppBuildScriptDependency (parentDir, value) { + const parentProjectFile = path.resolve(parentDir, 'project.properties'); + const parentProperties = this._getPropertiesFile(parentProjectFile); + addToPropertyList(parentProperties, 'cordova.appbuildscript.dependency', value); + this._dirty = true; + } + + removeAppBuildScriptDependency (parentDir, value) { + const parentProjectFile = path.resolve(parentDir, 'project.properties'); + const parentProperties = this._getPropertiesFile(parentProjectFile); + removeFromPropertyList(parentProperties, 'cordova.appbuildscript.dependency', value); + this._dirty = true; + } + addSystemLibrary (parentDir, value) { const parentProjectFile = path.resolve(parentDir, 'project.properties'); const parentProperties = this._getPropertiesFile(parentProjectFile); diff --git a/lib/builders/ProjectBuilder.js b/lib/builders/ProjectBuilder.js index 94658ee6..23345d82 100644 --- a/lib/builders/ProjectBuilder.js +++ b/lib/builders/ProjectBuilder.js @@ -153,6 +153,7 @@ class ProjectBuilder { return { libs: findAllUniq(data, /^\s*android\.library\.reference\.\d+=(.*)(?:\s|$)/mg), gradleIncludes: findAllUniq(data, /^\s*cordova\.gradle\.include\.\d+=(.*)(?:\s|$)/mg), + appBuildScriptDependencies: findAllUniq(data, /^\s*cordova\.appbuildscript\.dependency\.\d+=((?!.*\().*)(?:\s|$)/mg), systemLibs: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=((?!.*\().*)(?:\s|$)/mg), bomPlatforms: findAllUniq(data, /^\s*cordova\.system\.library\.\d+=platform\((?:'|")(.*)(?:'|")\)/mg) }; @@ -280,6 +281,20 @@ class ProjectBuilder { includeList += 'apply from: "../' + includePath + '"\n'; }); buildGradle = buildGradle.replace(/(PLUGIN GRADLE EXTENSIONS START)[\s\S]*(\/\/ PLUGIN GRADLE EXTENSIONS END)/, '$1\n' + includeList + '$2'); + + // Injecting buildscript dependencies + if (propertiesObj.appBuildScriptDependencies.length > 0) { + const buildScriptClasspaths = propertiesObj.appBuildScriptDependencies.map(d => `classpath "${d}"`); + buildGradle = buildGradle.replace( + /^([ \t]*)(\/\/ APP-BUILDSCRIPT-DEPENDENCIES START)[\s\S]*(\/\/ APP-BUILDSCRIPT-DEPENDENCIES END)/m, + (match, indentLevel, startLine, endLine) => [ + startLine, + ...buildScriptClasspaths, + endLine + ].map(l => `${indentLevel}${l}`).join('\n') + ); + } + // This needs to be stored in the app gradle, not the root grade fs.writeFileSync(path.join(this.root, 'app', 'build.gradle'), buildGradle); } diff --git a/lib/pluginHandlers.js b/lib/pluginHandlers.js index 14b0744f..eb3035cf 100644 --- a/lib/pluginHandlers.js +++ b/lib/pluginHandlers.js @@ -83,12 +83,16 @@ const handlers = { copyNewFile(plugin.dir, src, project.projectDir, subRelativeDir, !!(options && options.link)); subDir = path.resolve(project.projectDir, subRelativeDir); } else { - obj.type = 'sys'; + if (obj.type !== 'appBuildScriptDependency') { + obj.type = 'sys'; + } subDir = src; } if (obj.type === 'gradleReference') { project.addGradleReference(parentDir, subDir); + } else if (obj.type === 'appBuildScriptDependency') { + project.addAppBuildScriptDependency(parentDir, subDir); } else if (obj.type === 'sys') { project.addSystemLibrary(parentDir, subDir); } else { @@ -113,12 +117,16 @@ const handlers = { fs.rmdirSync(parDir); } } else { - obj.type = 'sys'; + if (obj.type !== 'appBuildScriptDependency') { + obj.type = 'sys'; + } subDir = src; } if (obj.type === 'gradleReference') { project.removeGradleReference(parentDir, subDir); + } else if (obj.type === 'appBuildScriptDependency') { + project.removeAppBuildScriptDependency(parentDir, subDir); } else if (obj.type === 'sys') { project.removeSystemLibrary(parentDir, subDir); } else { diff --git a/spec/unit/pluginHandlers/handlers.spec.js b/spec/unit/pluginHandlers/handlers.spec.js index b2145af8..2447fd57 100644 --- a/spec/unit/pluginHandlers/handlers.spec.js +++ b/spec/unit/pluginHandlers/handlers.spec.js @@ -197,6 +197,7 @@ describe('android project handler', function () { spyOn(dummyProject, 'addSystemLibrary'); spyOn(dummyProject, 'addSubProject'); spyOn(dummyProject, 'addGradleReference'); + spyOn(dummyProject, 'addAppBuildScriptDependency'); common.__set__('copyNewFile', copyNewFileSpy); }); @@ -241,6 +242,12 @@ describe('android project handler', function () { expect(copyNewFileSpy).toHaveBeenCalledWith(dummyPluginInfo.dir, framework.src, dummyProject.projectDir, someString, false); expect(dummyProject.addGradleReference).toHaveBeenCalledWith(dummyProject.projectDir, someString); }); + + it('Test#013 : should install app buildscript dependency using project.addAppBuildScriptDependency', () => { + const framework = { src: 'plugin-dependency', type: 'appBuildScriptDependency' }; + android.framework.install(framework, dummyPluginInfo, dummyProject); + expect(dummyProject.addAppBuildScriptDependency).toHaveBeenCalledWith(dummyProject.projectDir, someString); + }); }); describe('of elements', function () { @@ -402,6 +409,7 @@ describe('android project handler', function () { spyOn(dummyProject, 'removeSystemLibrary'); spyOn(dummyProject, 'removeSubProject'); spyOn(dummyProject, 'removeGradleReference'); + spyOn(dummyProject, 'removeAppBuildScriptDependency'); }); it('Test#020 : should throw if framework doesn\'t have "src" attribute', function () { @@ -433,6 +441,12 @@ describe('android project handler', function () { expect(rmSyncSpy).toHaveBeenCalledWith(someString, { recursive: true, force: true }); expect(dummyProject.removeGradleReference).toHaveBeenCalledWith(dummyProject.projectDir, someString); }); + + it('Test#025 : should uninstall app buildscript dependency using project.removeAppBuildScriptDependency', () => { + const framework = { src: 'plugin-dependency', type: 'appBuildScriptDependency' }; + android.framework.uninstall(framework, dummyPluginInfo, dummyProject); + expect(dummyProject.removeAppBuildScriptDependency).toHaveBeenCalledWith(dummyProject.projectDir, someString); + }); }); describe('of elements', function () { diff --git a/templates/project/app/build.gradle b/templates/project/app/build.gradle index 8bfae15e..393b9804 100644 --- a/templates/project/app/build.gradle +++ b/templates/project/app/build.gradle @@ -59,6 +59,9 @@ buildscript { println "Adding classpath: ${gradlePluginGoogleServicesClassPath}" classpath gradlePluginGoogleServicesClassPath } + + // APP-BUILDSCRIPT-DEPENDENCIES START + // APP-BUILDSCRIPT-DEPENDENCIES END } }