blob: c1e2c9eaf000ab8c30b990e4a282f2c894869de6 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
'use strict';
var fs = require('fs');
var fse = require('fs-extra');
var https = require('https');
var path = require('path');
var child_process = require('child_process');
var yaml = require('js-yaml');
var optimist = require('optimist');
var util = require('./util');
// constants
var DEFAULT_REPO_PATH = 'README.md';
var DEFAULT_VERSION_NAME = 'dev';
var DEFAULT_LANGUAGE_NAME = 'en';
var THIS_FILE = path.basename(__filename);
var WARNING_COMMENT = '<!-- WARNING: This file is generated. See ' + THIS_FILE + '. -->\n\n';
// helpers
function isPluginName (packageName) {
return packageName.match(/cordova-plugin-.*/);
}
function getRepoFileURI (repoName, commit, filePath) {
return 'https://raw.githubusercontent.com/' + repoName + '/' + commit + '/' + filePath;
}
function getRepoEditURI (repoName, commit, filePath) {
return 'https://github.com/' + repoName + '/blob/' + commit + '/' + filePath;
}
function getLatestRelease (packageName) {
var latestRelease = child_process.execSync('npm info ' + packageName + ' dist-tags.latest');
return latestRelease.toString().trim();
}
function packageNameFromRepoName (repoName) {
return repoName.split('/')[1];
}
function getFetchedFileConfig (entry) {
// get entry components
var srcConfig = entry.src;
var destConfig = entry.dest;
// validate entry
if (!srcConfig) {
console.error("entry '" + entry.toString() + "' missing 'src'");
return;
}
if (!srcConfig.repoName) {
console.error("entry '" + entry.toString() + "' missing 'repoName' in 'src'");
return;
}
if (!srcConfig.repoName) {
console.error("entry '" + entry.toString() + "' missing 'repoName' in 'src'");
return;
}
if (!destConfig) {
console.error("entry '" + entry.toString() + "' missing 'dest'");
return;
}
if (!destConfig.path) {
console.error("entry '" + entry.toString() + "' missing 'path' in 'dest'");
return;
}
// complete src config
if (!srcConfig.packageName) {
srcConfig.packageName = packageNameFromRepoName(srcConfig.repoName);
}
if (!srcConfig.path) {
srcConfig.path = DEFAULT_REPO_PATH;
}
if (!srcConfig.commit) {
srcConfig.commit = getLatestRelease(srcConfig.packageName);
}
// make front matter
var frontMatter = {
edit_link: getRepoEditURI(srcConfig.repoName, srcConfig.commit, srcConfig.path),
title: srcConfig.packageName
};
// set special front matter values for plugins
if (isPluginName(srcConfig.packageName)) {
frontMatter.plugin_name = srcConfig.packageName;
frontMatter.plugin_version = srcConfig.commit;
}
// set returned values
var fetchedFileConfig = {
frontMatter: frontMatter,
downloadURI: getRepoFileURI(srcConfig.repoName, srcConfig.commit, srcConfig.path),
savePath: destConfig.path
};
return fetchedFileConfig;
}
function getFrontMatter (text) {
var frontMatterString = util.getFrontMatterString(text);
if (frontMatterString !== null) {
return yaml.load(frontMatterString);
}
return {};
}
function setFrontMatter (text, frontMatter, options) {
var frontMatterString = yaml.dump(frontMatter, options);
return util.setFrontMatterString(text, frontMatterString);
}
function dumpEntries (downloadPrefix, entries) {
entries.forEach(function (entry) {
// validate entry's dest config
if (!entry.dest) {
console.error("entry '" + entry.toString() + "' missing 'dest'");
return;
}
if (!entry.dest.path) {
console.error("entry '" + entry.toString() + "' missing 'path' in 'dest'");
return;
}
// print the save path for the entry
if (entry.dest && entry.dest.path) {
var filePath = path.join(downloadPrefix, entry.dest.path);
console.log(filePath);
// error out on invalid entries
} else {
console.error('Invalid dest: ' + entry);
process.exit(1);
}
});
}
function downloadEntries (downloadPrefix, entries) {
entries.forEach(function (entry) {
// verify and process entry
var fetchedFileConfig = getFetchedFileConfig(entry);
if (!fetchedFileConfig) {
process.exit(1);
}
// get info for fetching
var fetchURI = fetchedFileConfig.downloadURI;
var outFilePath = path.join(downloadPrefix, fetchedFileConfig.savePath);
var outFileDir = path.dirname(outFilePath);
// create directory for the file if it doesn't exist
if (!fs.existsSync(outFileDir)) {
fse.mkdirsSync(outFileDir);
}
console.log(fetchURI + ' -> ' + outFilePath);
// open the file for writing
var outFile = fs.createWriteStream(outFilePath);
// open an HTTP request for the file
https.get(fetchURI, function (response) {
if (response.statusCode !== 200) {
console.error('Failed to download ' + fetchURI + ': got ' + response.statusCode);
process.exit(1);
}
// read in the response
var fileContents = '';
response.setEncoding('utf8');
response.on('data', function (data) {
fileContents += data;
});
// process the response when it finishes
response.on('end', function () {
// merge new front matter and file's own front matter (if it had any)
//
// NOTE:
// fileFrontMatter's properties should override those of newFrontMatter
var newFrontMatter = fetchedFileConfig.frontMatter;
var fileFrontMatter = getFrontMatter(fileContents);
var mergedFrontMatter = util.mergeObjects(newFrontMatter, fileFrontMatter);
// add a warning and set the merged file matter in the file
var contentsOnly = util.stripFrontMatter(fileContents);
contentsOnly = WARNING_COMMENT + contentsOnly;
var augmentedContents = setFrontMatter(contentsOnly, mergedFrontMatter);
// write out the file
outFile.end(augmentedContents);
}).on('error', function (e) {
console.error(e);
});
}); // http request
}); // entries
}
// main
function main () {
// get args
var argv = optimist
.usage('Usage: $0 [options]')
.demand('config')
.demand('docsRoot')
.string('version')
.string('language')
.boolean('dump')
.describe('config', '.yml file listing fetched files')
.describe('docsRoot', 'docs root directory')
.describe('version', 'version in which to save the downloaded files').default('version', DEFAULT_VERSION_NAME)
.describe('language', 'language in which to save the downloaded files').default('language', DEFAULT_LANGUAGE_NAME)
.describe('dump', 'only print the downloaded files')
.argv;
var configFile = argv.config;
var docsRoot = argv.docsRoot;
var targetVersion = argv.version;
var targetLanguage = argv.language;
var printOnly = argv.dump;
var downloadPrefix = path.join(docsRoot, targetLanguage, targetVersion);
// validate args
if (!fs.existsSync(configFile)) {
console.error("Config file doesn't exist.");
process.exit();
}
if (!fs.existsSync(docsRoot)) {
console.error("Docs root doesn't exist.");
process.exit();
}
// get config
var fetchConfig = fs.readFileSync(configFile);
var configEntries = yaml.load(fetchConfig);
// just dump entries if --dump was passed
if (printOnly === true) {
dumpEntries(downloadPrefix, configEntries);
// otherwise, fetch them
} else {
downloadEntries(downloadPrefix, configEntries);
}
}
main();