Learn more  » Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

vipera-npm-registry / de-doc-generator   js

Repository URL to install this package:

Version: 1.0.0 

/ bin / cli / DocGenerator.js

/**
 * Created by marcobonati on 15/05/2017.
 */

"use strict";

const fs = require("fs-extra");
const path = require('path');
const _ = require('lodash');
const globby = require('globby');
const recursiveReadSync = require('recursive-readdir-sync');
const parseString = require('xml2js').parseString;
const XML = require('pixl-xml');
const md5 = require('md5');
const markdownRender = require('markdown-styles').render;
const opts = require('yargs');
const resolveArgs = require('markdown-styles').resolveArgs;

/**
 *
 * @constructor
 */
function DocGenerator(){
    this.config = {};
}

DocGenerator.prototype.runCli = function(inputArgs,callback) {

    var that = this;

    this.readConfig(inputArgs);

    this.cleanTempFolder();

    this.prepareMaster().then(function(success){
        var fileList = that.scanDoc(success.mainDocTempFolder);
        that.mergeDocs(fileList).then(function(){
            console.log("Documentation Generation Completed Successfully!");

            var cmdArgs = [ process.argv0, __filename, '--input' , success.mainDocTempFolder,  '--output', that.outFolder ];
            console.log("out folder=" + that.outFolder);

            opts.options({
                'layouts': { },
                'help': { },
                'header-links': { 'default': true },
                'layout': { },
                'input': { },
                'output': { },
                'v': { },
                'version': { }
            }).boolean('layouts').boolean('help').boolean('v').boolean('version').boolean('header-links');
            var argv = opts.parse(cmdArgs);
            argv = resolveArgs(argv);
            //var layoutDir = __dirname + '/../layouts/';

            markdownRender(argv, function(){
            });

        }, function(err){
            console.log("ERROR !!!!! " + err);
        });
    }, function(err){
        console.trace(err);
    });

}

/**
 * Merge main doc with the given pages from file list
 * @param fileList
 */
DocGenerator.prototype.mergeDocs = function(fileList) {

    var that = this;
    var i = 0;
    this.merged = 0;
    this.toMerge = fileList.length;

    return new Promise(function(fullfill, reject){

        for (i=0;i<fileList.length;i++){
            that.mergeDoc(fileList[i]).then(function(fileInfo){
                that.merged++;
                console.log("Merged doc " + that.merged +"/" + that.toMerge);
                if (that.merged===that.toMerge){
                    fullfill();
                }
            }, function(err){
                console.log("Error! " + err.stack);
                reject(err);
            });
        }

    });

}

/**
 * Merge the main doc page with the given remote source page
 * @param fileInfo
 */
DocGenerator.prototype.mergeDoc = function(fileInfo) {

    var that = this;
    console.log("Replacing " + fileInfo.completeFileName + " with remote " + fileInfo.src + " on repo " + fileInfo.srcRepo +"...");

    return new Promise(function(fullfill, reject) {

        that.cloneRepo(fileInfo.srcRepo, fileInfo.id).then(function(cloneFolder){

            var mainDocBaseFolder = path.dirname(fileInfo.completeFileName);
            var mainDocBaseFileName = path.basename(fileInfo.completeFileName);

            //copy images if required
            if (fileInfo.imageSrc){
                try {
                    //copy images folder into main doc relative path
                    var imageSrcFolder = path.join(cloneFolder, fileInfo.imageSrc);
                    var imageDestFolder = mainDocBaseFolder;
                    //if defined use imagePath, elsewhere use the root folder
                    if (fileInfo.imagePath){
                        imageDestFolder = path.join(mainDocBaseFolder, fileInfo.imagePath);
                    }
                    fs.copySync(imageSrcFolder, imageDestFolder);
                    console.log("Copied images into "+ mainDocBaseFolder + "");
                } catch (ee){
                    console.log(ee);
                }
            }

            //copy the file
            var docSrcFile = path.join(cloneFolder, fileInfo.src);
            fs.copySync(docSrcFile, fileInfo.completeFileName);
            fullfill(fileInfo);

        }, function(er){
            console.trace();
            reject(er);
        });

    });




}


/**
 * Clone the Master Doc project and move the documentation folder in the mainDocTempFolder
 * @returns {Promise}
 */
DocGenerator.prototype.prepareMaster = function() {

    var that = this;

    return new Promise(function(fullfill, reject){

        that.cloneMaster().then(function (cloneFolder){
            console.log("Success: " + cloneFolder);
            var mainDocTempFolder = that.mainDocTempFolder();
            fs.moveSync(cloneFolder + that.config.mainDoc.folder, mainDocTempFolder);
            fullfill({
                "cloneFolder" : cloneFolder,
                "mainDocTempFolder" : mainDocTempFolder
            });
        }, function (err){
            console.trace(err);
            reject(err);
        });

    });


}

/**
 * Clone the Master Doc project defined into the config object mainDoc.repoUrl
 */
DocGenerator.prototype.cloneMaster = function() {
    //var repoUrl = "https://gitlab.vipera.com/dynamic-engine/de-cli.git";
    return this.cloneRepo(this.config.mainDoc.repoUrl, "/main-doc/");
}

/**
 * Scan a documentation folder in order to find "<include>" tag and return the list of files with their content
 */
DocGenerator.prototype.scanDoc = function(docfolder){

    var completeFileList = globby.sync(['**/*.md'], { cwd: docfolder });
    var fileList = new Array();

    for (var i=0;i<completeFileList.length;i++){
        var fileName = completeFileList[i];
        var completeFileName = path.join(docfolder, fileName);
        var contents = fs.readFileSync(completeFileName);
        var isIncludeFile = contents.includes("<dedoc-include");
        if (isIncludeFile){
            var doc = XML.parse( contents );
            var id = md5(doc.repo + "_" + completeFileName);
            var fileInfo = { "completeFileName": completeFileName,
                             "docFile": fileName,
                             "rawDocContent": contents,
                             "srcRepo" : doc.repo,
                             "src" : doc.src,
                             "docContent" : doc,
                             "id": id,
                             "imageSrc": doc.imageSrc,
                             "imagePath" : doc.imagePath
                            };
            fileList.push(fileInfo);
        }
    }
    return fileList;
}

DocGenerator.prototype.cloneRepo = function(repoURL, tempFolder){
    var that = this;
    console.log("Cloning git repo " + repoURL +"...");
    return new Promise(function (fulfill, reject){
        var workingDirPath = that.gitTempFolder(tempFolder);
        var simpleGit = require('simple-git')();
        var localPath = workingDirPath;
        var gitOptions = {};
        simpleGit.clone(repoURL, localPath, gitOptions, function(err, data){
            if (err) {
                reject(err);
            }
            else {
                console.log("Git repo clone done.");
                fulfill(localPath);
            }
        });
    });
}

DocGenerator.prototype.gitTempFolder = function(folder) {
    return this.tempFolder("/git/" + folder);
}

DocGenerator.prototype.mainDocTempFolder = function() {
    return this.tempFolder("/main-doc/");
}

DocGenerator.prototype.tempFolder = function(folder) {
    return path.join(this.tempFolderPath, folder);
}

DocGenerator.prototype.readConfig = function(args) {

    var configFile = args.config;
    if (!configFile){
        configFile = "./docgen.json";
    }
    var obj = JSON.parse(fs.readFileSync(configFile, 'utf8'));

    this.config = obj;

    if (this.config.global && this.config.global.tempFolder){
        this.tempFolderPath = this.config.global.tempFolder;
    }
    if (!this.tempFolderPath){
        this.tempFolderPath = "./temp";
    }

    this.outFolder = args.out;
    if (this.config.global && this.config.global.outFolder){
        this.outFolder = this.config.global.outFolder;
    }
    if (!this.outFolder){
        this.outFolder = "./out";
    }

}

DocGenerator.prototype.cleanTempFolder = function()
{
    fs.removeSync(this.tempFolderPath);
}


// export the class
module.exports = DocGenerator;