UNPKG

grunt-nuget-pack

Version:

Grunt task for creating nuget packages without using nuget.exe.

235 lines (181 loc) 6.74 kB
var ZipWriter = require("moxie-zip").ZipWriter; var XMLWriter = require("xml-writer"); var path = require("path"); var fs = require("fs"); module.exports = function(meta) { var zip = new ZipWriter(), extensions = {nuspec: true}; var propsId = "7857dbf80735479b8ee19fa60cb8239e", excludePaths = {}; // MIT licensed by Sindre Sorhus https://github.com/sindresorhus/semver-regex var semVerRegex = /\bv?(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?\b/ig; function verifyMeta() { if (!meta.id) { throw new Error("Missing required package id."); } if (!/^[a-z0-9\.]+$/i.test(meta.id)) { throw new Error("Package id isn't in a valid format."); } if (!meta.version) { throw new Error("Missing required package version."); } if (!semVerRegex.test(meta.version)) { throw new Error("Version isn't proper sem-ver \"x.x.x\"."); } if (!meta.authors) { throw new Error("Missing required package authors."); } if (!meta.description) { throw new Error("Missing required package description."); } } function getContentTypesXml() { var xw = new XMLWriter(true, "utf-8"); xw.startDocument(); xw.startElement("Types"); xw.writeAttribute("xmlns", "http://schemas.openxmlformats.org/package/2006/content-types"); xw.startElement("Default"); xw.writeAttribute("Extension", "rels"); xw.writeAttribute("ContentType", "application/vnd.openxmlformats-package.relationships+xml"); xw.endElement(); for (var ext in extensions) { xw.startElement("Default"); xw.writeAttribute("Extension", ext); xw.writeAttribute("ContentType", "application/octet"); xw.endElement(); } xw.startElement("Default"); xw.writeAttribute("Extension", "psmdcp"); xw.writeAttribute("ContentType", "application/vnd.openxmlformats-package.core-properties+xml"); xw.endElement(); xw.endDocument(); return xw.toString(); } function getNuSpecXml() { var properties = [ "id", "title", "version", "authors", "owners", "license", "licenseUrl", "projectUrl", "icon", "iconUrl", "requireLicenseAcceptance", "description", "summary", "releaseNotes", "copyright", "language", "tags", "dependencies" ]; function normalizeVersionDep(version) { version = version.replace(/\s+/, ''); if (!/^(\[[0-9\,\.]+\]|\([0-9\,\.]+\)|\([0-9\,\.]+\]|[0-9]+\.[0-9]+)$/.test(version)) { throw new Error("Invalid version dependecy: " + version); } if (/^[0-9]+\.[0-9]+$/.test(version)) { return version; } version = version[0] + version.substr(1, version.length - 2).split(',').join(', ') + version[version.length - 1]; return version; } var xw = new XMLWriter(true); xw.startDocument(); xw.startElement("package"); xw.writeAttribute("xmlns", "http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"); xw.startElement("metadata"); properties.forEach(function(property) { if (property in meta) { if (property == "dependencies") { xw.startElement("dependencies"); meta[property].forEach(function(dep) { xw.startElement("dependency"); xw.writeAttribute("id", dep.id); if (dep.version) { xw.writeAttribute("version", normalizeVersionDep(dep.version)); } xw.endElement(); }); xw.endElement(); return; } if (property === "license") { xw.startElement(property); xw.writeAttribute("type", "expression"); xw.text(meta[property].toString()); xw.endElement(); return; } xw.writeElement(property, meta[property].toString()); } }); xw.endDocument(); return xw.toString(); } function getCorePropertiesXml() { var xw = new XMLWriter(true, "utf-8"); function writeProp(name, value) { if (value) { xw.writeElement(name, value); } } xw.startDocument(); xw.startElement("coreProperties"); xw.writeAttribute("xmlns:dc", "http://purl.org/dc/elements/1.1/"); xw.writeAttribute("xmlns:dcterms", "http://purl.org/dc/terms/"); xw.writeAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); xw.writeAttribute("xmlns", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"); writeProp("dc:creator", meta.authors); writeProp("dc:description", meta.description); writeProp("dc:identifier", meta.id); writeProp("version", meta.version); writeProp("dc:language", meta.language); writeProp("keywords", meta.tags); writeProp("lastModifiedBy", "NuGet, Version=2.8.50320.36, Culture=neutral, PublicKeyToken=null;Microsoft Windows NT 6.2.9200.0;.NET Framework 4"); xw.endDocument(); return xw.toString(); } function getRelsXml() { var xw = new XMLWriter(true, "utf-8"); xw.startDocument(); xw.startElement("Relationships"); xw.writeAttribute("xmlns", "http://schemas.openxmlformats.org/package/2006/relationships"); xw.startElement("Relationship"); xw.writeAttribute("Type", "http://schemas.microsoft.com/packaging/2010/07/manifest"); xw.writeAttribute("Target", "/" + meta.id + ".nuspec"); xw.writeAttribute("Id", "R569c48f3cf1b4b14"); xw.endElement(); xw.startElement("Relationship"); xw.writeAttribute("Type", "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"); xw.writeAttribute("Target", "/package/services/metadata/core-properties/" + propsId + ".psmdcp"); xw.writeAttribute("Id", "R9e8f0077d5174f67"); xw.endElement(); xw.endDocument(); return xw.toString(); } this.addExcludes = function(excludes) { if (Array.isArray(excludes)) { excludes.forEach(function(excludePath) { excludePaths[path.resolve(excludePath)] = true; }); } }; this.addFile = function(srcPath, destPath) { function process(filePath, zipFilePath) { var stat; if (excludePaths[path.resolve(filePath)]) { return; } stat = fs.statSync(filePath); filePath = filePath.replace(/\\/g, '/'); zipFilePath = zipFilePath.replace(/\\/g, '/'); if (stat.isFile()) { extensions[path.extname(filePath).substr(1)] = true; zip.addFile(zipFilePath, filePath); } else if (stat.isDirectory()) { fs.readdirSync(filePath).forEach(function(fileName) { if (fileName.charAt(0) != '.') { process(path.join(filePath, fileName), path.join(zipFilePath, fileName)); } }); } } process(srcPath, destPath); }; this.saveAs = function(destPath, callback) { verifyMeta(); zip.addData("[Content_Types].xml", getContentTypesXml()); zip.addData(meta.id + ".nuspec", getNuSpecXml()); zip.addData("package/services/metadata/core-properties/" + propsId + ".psmdcp", getCorePropertiesXml()); zip.addData("_rels/.rels", getRelsXml()); zip.saveAs(destPath, callback); }; };