serverless/scripts/pkg/generate-choco-package.js
2021-02-11 14:01:41 +01:00

119 lines
3.7 KiB
JavaScript
Executable File

#!/usr/bin/env node
// Node.js v10+ only
'use strict';
require('essentials');
const argv = require('../../lib/cli/parse-args')(process.argv.slice(2), {
boolean: new Set(['help']),
alias: new Map([['h', 'help']]),
});
const [versionTag] = argv._;
const usage = `Usage: ./scripts/pkg/generate-choco-package [-h | --help] <versionTag>
Generates choco package
Options:
--help, -h Show this message
`;
if (argv.help) {
process.stdout.write(usage);
return;
}
if (!versionTag) {
process.stdout.write(usage);
return;
}
const chalk = require('chalk');
if (!/^v\d+\.\d+\.\d+$/.test(versionTag)) {
process.stdout.write(chalk.red(`Invalid version tag: ${versionTag}\n`));
process.exitCode = 1;
return;
}
const path = require('path');
const fs = require('fs');
const os = require('os');
const { promisify } = require('util');
const pipeline = promisify(require('stream').pipeline);
const fse = require('fs-extra');
const fetch = require('node-fetch');
const xml2js = require('xml2js');
const packageMeta = require('../../package');
const xmlToJson = promisify(xml2js.parseString);
const { readFile, writeFile } = fs.promises;
const serverlessPath = path.join(__dirname, '../../');
const chocoPackageTemplatePath = path.join(__dirname, 'choco-package-template');
(async () => {
const deferredLicenseContent = Promise.all([
readFile(path.join(chocoPackageTemplatePath, 'tools/LICENSE.txt'), 'utf8'),
readFile(path.join(serverlessPath, 'LICENSE.txt'), 'utf8'),
]);
const chocoPackagePath = path.join(os.tmpdir(), 'serverless-choco-package');
const chocoPackageToolsPath = path.join(chocoPackagePath, 'tools');
const binaryUrl =
'https://github.com/serverless/serverless/releases/download/' +
`${versionTag}/serverless-win-x64.exe`;
await fse.ensureDir(chocoPackageToolsPath).then(() =>
Promise.all([
// Copy package template to temporary package directory
fse.copy(chocoPackageTemplatePath, chocoPackagePath).then(() =>
Promise.all([
// Copy LICENSE
(async () => {
const [packagedLicenseTemplateContent, licenseContent] = await deferredLicenseContent;
return writeFile(
path.join(chocoPackageToolsPath, 'LICENSE.txt'),
packagedLicenseTemplateContent.replace('TO_BE_GENERATED', licenseContent)
);
})(),
(async () => {
// Autogenerate meta data
const nuspecPath = path.join(chocoPackagePath, 'serverless.nuspec');
const data = await xmlToJson(await readFile(nuspecPath));
const {
metadata: [metadata],
} = data.package;
metadata.version[0] = versionTag.slice(1);
metadata.releaseNotes[0] = `https://github.com/serverless/serverless/releases/tag/${versionTag}`;
metadata.copyright[0] = `${new Date().getFullYear()}, Serverless Inc.`;
metadata.tags[0] = packageMeta.keywords
.filter((keyword) => !keyword.includes(' '))
.join(' ');
metadata.summary[0] = packageMeta.description;
metadata.description[0] = packageMeta.description;
const xmlBuilder = new xml2js.Builder();
const result = xmlBuilder.buildObject(data);
return writeFile(nuspecPath, result);
})(),
])
),
// Download binary into package tools folder
fetch(binaryUrl).then((response) => {
if (response.status >= 400) {
throw new Error(`${response.status}: Request to ${binaryUrl} was rejected`);
}
return pipeline(
response.body,
fs.createWriteStream(path.join(chocoPackageToolsPath, 'serverless.exe'))
);
}),
])
);
process.stdout.write(`${chocoPackagePath}\n`);
})();