允许用户为Cordova插件指定Gradle依赖项

时间:2016-12-07 21:46:50

标签: android xml cordova gradle cordova-plugins

我正在编写一个具有Gradle依赖关系的Android Cordova插件。 我希望开发人员能够指定他们想要的依赖版本,而无需直接编辑插件。

现在我在plugin.xml中有这个:

<hook type="before_plugin_install" src="modifyPluginXML.js" />
<framework src="resources/custom.gradle" custom="true" type="gradleReference"/>
<framework src="$TO_BE_DEFINED_PACKAGE" type="gradleReference"/>

我有一个钩子,它接受命令行参数,并用参数中提供的包路径/名称替换plugin.xml中的$ TO_BE_DEFINED_PACKAGE。

这是modifyPluginXML.js钩子:

module.exports = function(context) {
var Q = context.requireCordovaModule('q');
var deferral = new Q.defer();
var fs = require('fs'),
    xml2js = require('xml2js'),
    path = require('path'),
    util = require('util');

    var parser = new xml2js.Parser({explicitArray:false});
    var cb = function(data){
        console.log("plugin.xml updated");
        deferral.resolve();
    }

    fs.readFile(__dirname + '/plugin.xml', function(err, data) {
        parser.parseString(data, function (err, result) {
            //console.log(util.inspect(result, false, null));

            var externalDep = "";
            for (var i = 0; i < process.argv.length;i++){
                if(process.argv[i].indexOf('EXTERNAL_DEP') >= 0){
                    externalDep = process.argv[i].replace("EXTERNAL_DEP=", "");
                    console.log(externalDep);
                }
            }
            result.plugin.platform.framework[1]['$'].src = externalDep;
            var builder = new xml2js.Builder();
            var xml = builder.buildObject(result);
            var filepath = path.normalize(path.join(__dirname, '/plugin.xml'));
            fs.writeFile(filepath, xml, cb);
        });
    });
     return deferral.promise;
 }

截至目前,如果您使用cordova plugin add plugin-name EXTERNAL_DEP=5.0添加插件,它将使用命令行参数中指定的源正确替换plugin.xml中的框架src。

我遇到的问题是cordova似乎并不关心新的plugin.xml。它仍然使用旧的plugin.xml框架标记。

在generate build.gradle文件中,我仍然看到:

dependencies {
    compile fileTree(dir: 'libs', include: '*.jar')
    // SUB-PROJECT DEPENDENCIES START
    debugCompile project(path: "CordovaLib", configuration: "debug")
    releaseCompile project(path: "CordovaLib", configuration: "release")
    compile "$TO_BE_DEFINED_PACKAGE"
    // SUB-PROJECT DEPENDENCIES END
}

因此即使使用before_plugin_install挂钩正确更新plugin.xml,cordova也会使用旧值生成build.gradle文件。

有没有人有任何建议,或者我可以采取不同的路线?

2 个答案:

答案 0 :(得分:1)

您不必在plugin.xml中写入,因为只能在插件安装中阅读。

如果要编辑gradle引用,可以在platforms / android / build.gradle文件上编写,即复制plugin.xml中的引用。

无论如何,我认为允许用户选择要使用的版本是一个好主意,作为插件的开发者,您应该选择您测试的版本,并且您确信它运行正常,使用不同的版本可能会使插件无法正常工作或根本无法工作。

答案 1 :(得分:0)

获取@jcesarmobile建议,然后写入build.gradle文件。我首先检查cmd行是否有任何参数,而不是检查config.xml以查找为特定插件设置的任何变量。这是我提出的脚本。

module.exports = function (context) {
  var Q = context.requireCordovaModule('q');
  var deferral = new Q.defer();
  var result = null;
  var externalDep = null;

  var fs = require('fs'),
    xml2js = require('xml2js'),
    path = require('path'),
    util = require('util');
  var gradleLocation = process.cwd() + "/platforms/android/build.gradle";
  var parser = new xml2js.Parser({explicitArray: false});

  function findPluginVarInConfig() {
    fs.readFile(process.cwd() + '/config.xml', function (err, data) {
      parser.parseString(data, function (err, result) {
        //console.log(util.inspect(result, false, null));
        for (var i = 0; i < result.widget.plugin.length; i++) {
          if (result.widget.plugin[i]['$'].name == 'plugin-name') {
            externalDep = result.widget.plugin[i].variable['$'].value;
          }
        }
        if (externalDep) {
          console.log("found " + externalDep + " in config.xml");
          replaceGradleReference();
        } else {
          console.log("plugin-name could not find defined dependency defined in config.xml or cmd line args defaulting to 0.0.1");
          externalDep = "0.0.1";
          replaceGradleReference();
        }
      });
    });
  }

  function findPluginVarInCmdArgs() {
    for (var i = 0; i < process.argv.length; i++) {
      if (process.argv[i].indexOf('EXTERNAL_DEP') >= 0) {
        externalDep = process.argv[i].replace("EXTERNAL_DEP=", "");
      }
    }
    if (externalDep) {
      console.log("found " + externalDep + " in command line args");
      replaceGradleReference();
    } else {
      findPluginVarInConfig();
    }
  }

  function replaceGradleReference() {
    fs.readFile(gradleLocation, 'utf8', function (err, data) {
      if (err) {
        return console.log(err);
      }
      var replaced = false;
      if (data.indexOf('$INITIAL_PBR_SOURCE' >= 0)) {
        result = data.replace('$INITIAL_PBR_SOURCE', function (text) {
          replaced = true;
          return externalDep
        });
        if (!replaced) {
          console.log("FAILED TO ADD " + externalDep + " TO BUILD SCRIPT");
        }
      }
      if (result) {
        fs.writeFile(gradleLocation, result, 'utf8', function (err) {
          if (err) {
            console.log(err);
          } else {
            console.log("Succesfully added " + externalDep + " to buildscript");
          }
          deferral.resolve();
        });
      } else {
        console.log("PBR external dependency is already added to buildscript");
      }
    });
  }

  findPluginVarInCmdArgs();
  return deferral.promise;
};