Skip to content

Commit

Permalink
Add support for WinMD and DLL combination
Browse files Browse the repository at this point in the history
  • Loading branch information
Nikita Matrosov committed Dec 21, 2016
1 parent e4e9573 commit 99a7016
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 2 deletions.
12 changes: 12 additions & 0 deletions spec/unit/fixtures/testProj/plugins/testPlugin/plugin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version='1.0' encoding='utf-8'?>
<plugin id="testPlugin" version="0.0.1" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>testPlugin</name>
<js-module name="testPlugin" src="www/testPlugin.js">
<clobbers target="cordova.plugins.testPlugin" />
</js-module>
<platform name="windows">
<framework src="src/deps/x86/x86.winmd" target-dir="x86" arch="x86" custom="true" versions="10.*" implementation="src/deps/x86/x86.dll"/>
<framework src="src/deps/x64/x64.winmd" target-dir="x64" arch="x64" custom="true" versions="10.*" implementation="src/deps/x64/x64.UWP.dll" />
<framework src="src/deps/ARM/arm.winmd" target-dir="ARM" arch="ARM" custom="true" versions="10.*" implementation="src/deps/ARM/arm.dll"/>
</platform>
</plugin>
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
46 changes: 46 additions & 0 deletions spec/unit/pluginHandler/windows.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,22 @@ var rewire = require('rewire');
var PluginHandler = rewire('../../../template/cordova/lib/PluginHandler');
var JsprojManager = require('../../../template/cordova/lib/JsprojManager');
var cordovaProjectDir = path.join(os.tmpdir(), 'plugman');
var testProjectWindowsPlatformDir = path.join(__dirname, '../fixtures/testProj', 'platforms', 'windows');

var cordovaProjectWindowsPlatformDir = path.join(cordovaProjectDir, 'platforms', 'windows');
var cordovaProjectPluginsDir = path.join(cordovaProjectDir, 'plugins');
var PluginInfo = require('cordova-common').PluginInfo;
var pluginInfo = require('../../../template/cordova/lib/PluginInfo').PluginInfo;

var dummyplugin = path.join(__dirname, '../fixtures/testProj/plugins/org.test.plugins.dummyplugin');
var testPlugin = path.join(__dirname, '../fixtures/testProj/plugins/testPlugin');
var dummyPluginInfo = new PluginInfo(dummyplugin);
var testPluginInfo = new pluginInfo(testPlugin);
var valid_source = dummyPluginInfo.getSourceFiles('windows');
var valid_resourceFiles = dummyPluginInfo.getResourceFiles('windows');
var valid_libfiles = dummyPluginInfo.getLibFiles('windows');
var valid_frameworks = dummyPluginInfo.getFrameworks('windows');
var test_frameworks = testPluginInfo.getFrameworks('windows');

var faultyplugin = path.join(__dirname, '../fixtures/org.test.plugins.faultyplugin');
var faultyPluginInfo = new PluginInfo(faultyplugin);
Expand Down Expand Up @@ -304,6 +309,47 @@ describe('windows project handler', function () {
xpath = 'Reference[@Include="dummy6"]/HintPath';
validateInstalledProjects('framework', frameworks[5], xpath, ['windows', 'windows10', 'phone']);
});

it('with .winmd and .dll files', function() {
var frameworks = copyArray(test_frameworks);
var install = PluginHandler.getInstaller('framework');
var uninstall = PluginHandler.getUninstaller('framework');
var testProject = JsprojManager.getProject(testProjectWindowsPlatformDir);

frameworks.forEach(function(framework) {
install(framework, testPluginInfo, testProject);
});

var jsProjFileFromPlatform = path.join(testProjectWindowsPlatformDir, 'CordovaApp.Windows10.jsproj');
var searchProjects = testProject._projects.filter(function(project) {
return path.normalize(project.location) === jsProjFileFromPlatform;
});

expect(searchProjects.length).toBe(1);
var projectXmlTree = searchProjects[0].xml;

var refHintPaths = projectXmlTree.findall('./ItemGroup/Reference/HintPath');
var pathsEqual = refHintPaths.every(function(hintPath, index) {
return path.basename(hintPath.text) === path.basename(frameworks[index].src);
});

expect(pathsEqual).toBeTruthy();

var refWinMdStatus = projectXmlTree.findall('./ItemGroup/Reference/IsWinMDFile');
var allReferencesHaveMetadata = refWinMdStatus.every(function(isWinMd) {
return isWinMd.text === 'true';
});

expect(allReferencesHaveMetadata).toBeTruthy();

var refImplements = projectXmlTree.findall('./ItemGroup/Reference/Implementation');
expect(refImplements.length).toBe(1);
expect(refImplements[0].text).toBe(path.basename(frameworks[1].implementation));

frameworks.forEach(function(framework) {
uninstall(framework, testPluginInfo, testProject);
});
});
});

describe('of <framework> elements of type \'projectReference\'', function () {
Expand Down
9 changes: 8 additions & 1 deletion template/cordova/lib/JsprojManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ jsprojManager.prototype = {
});
},

addReference: function (relPath, targetConditions) {
addReference: function (relPath, targetConditions, implPath) {
events.emit('verbose', 'jsprojManager.addReference(incText: ' + relPath + ', targetConditions: ' + JSON.stringify(targetConditions) + ')');

// add hint path with full path
Expand All @@ -149,6 +149,13 @@ jsprojManager.prototype = {
children.push(mdFileTag);
}

// We only need to add <Implementation> tag when dll base name differs from winmd name
if (implPath && path.basename(relPath, '.winmd') !== path.basename(implPath, '.dll')) {
var implementTag = new et.Element('Implementation');
implementTag.text = path.basename(implPath);
children.push(implementTag);
}

var item = createItemGroupElement('ItemGroup/Reference', path.basename(relPath, extName), targetConditions, children);
this._getMatchingProjects(targetConditions).forEach(function (project) {
project.appendToRoot(item);
Expand Down
6 changes: 5 additions & 1 deletion template/cordova/lib/PluginHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ var handlers = {
var dest = src;
var type = obj.type;
var targetDir = obj.targetDir || '';
var implementPath = obj.implementation;

if(type === 'projectReference') {
dest = path.join(path.relative(project.projectFolder, plugin.dir), targetDir, src);
Expand All @@ -94,7 +95,10 @@ var handlers = {
// path.join ignores empty paths passed so we don't check whether targetDir is not empty
dest = path.join('plugins', plugin.id, targetDir, path.basename(src));
copyFile(plugin.dir, src, project.root, dest);
project.addReference(dest, getTargetConditions(obj));
if (implementPath) {
copyFile(plugin.dir, implementPath, project.root, path.join(path.dirname(dest), path.basename(implementPath)));
}
project.addReference(dest, getTargetConditions(obj), implementPath);
}

},
Expand Down
27 changes: 27 additions & 0 deletions template/cordova/lib/PluginInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,33 @@ function PluginInfo(dirname) {
var configFiles = parentGetConfigFiles(platform);
return processChanges(configFiles);
};

this.getFrameworks = function(platform) {
return _getTags(this._et, 'framework', platform, function(el) {
var ret = {
itemType: 'framework',
type: el.attrib.type,
parent: el.attrib.parent,
custom: String(el.attrib.custom).toLowerCase() == 'true',
src: el.attrib.src,
versions: el.attrib.versions,
targetDir: el.attrib['target-dir'],
deviceTarget: el.attrib['device-target'] || el.attrib.target,
arch: el.attrib.arch,
implementation: el.attrib.implementation
};
return ret;
});
};
}

function _getTags(pelem, tag, platform, transform) {
var platformTag = pelem.find('./platform[@name="' + platform + '"]');
var tagsInPlatform = platformTag ? platformTag.findall(tag) : [];
if ( typeof transform === 'function' ) {
tagsInPlatform = tagsInPlatform.map(transform);
}
return tagsInPlatform;
}

exports.PluginInfo = PluginInfo;

0 comments on commit 99a7016

Please sign in to comment.