Skip to content

Commit

Permalink
Refactoring to improve code maintainability:
Browse files Browse the repository at this point in the history
 * Fixing the error handling bug introduced by the config feature

 * Refactor options validation and parsing into a new Options class

 * Move the HTML generation and tool options module to bin

 * Refactor paths for options and generate html modules

 * Improve linting and indentation
  • Loading branch information
dhillonks committed Oct 14, 2021
1 parent caa585d commit b406d2f
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 65 deletions.
68 changes: 13 additions & 55 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
#!/usr/bin/env node

const package = require("../package");
const generateHtml = require("../generateHtml");
const fs = require("fs");
const generateHtml = require("./modules/generateHtml");
const figlet = require("figlet");
const path = require("path");
const { exit } = require("process");
const { Options } = require("./modules/configOptions");

const outputDir = './dist';
const defaultLang = 'en-CA';
let options;

const decoratedHeader = figlet.textSync(package.name, {horizontalLayout: 'full'});
console.log(decoratedHeader);
Expand Down Expand Up @@ -52,61 +51,20 @@ var argv = require('yargs/yargs')(process.argv.slice(2))
}
})
.check((argv) => {
options = new Options(argv.i, argv.o, argv.s, argv.l);

//Input
if(argv.i){

if(!fs.existsSync(argv.i)){
throw new Error("Input path must be a file or directory");
}
}

//Output
else if(argv.o != outputDir){
if(fs.existsSync(argv.o)){
if(!fs.lstatSync(argv.o).isDirectory()){
throw new Error("Output path points to a file. Output directory must be valid")
}
}
else throw new Error("Output directory must be valid");
if(argv.c){
//Parse and use options from the config file
options.parseConfig(argv.c);
}

//Config
else if(argv.c){

if(isJSON(process.argv[3])){

if(!fs.existsSync(argv.c)){
throw new Error("JSON file path does not exist");
}
var data = JSON.parse(fs.readFileSync(argv.c));

if(data.input) argv.i = data.input
if(data.output) argv.o = data.output
if(data.stylesheet) argv.s = data.stylesheet
if(data.lang) argv.l = data.lang

}else{
throw new Error("The passed file should be of JSON format")
}
}
else {
throw new Error("A config file(.JSON) or an input file is required");
}

return true;
//Validate the options
return options.validateInput() && options.validateOutput();
})
.argv;

try {
generateHtml(argv.i, argv.o, argv.s, argv.l);
} catch (err) {
console.error(err)
}

function isJSON(stats){
if(path.extname(stats) == ".json")
return true
else
return false
}
generateHtml(options.input, options.output, options.stylesheet, options.lang);
} catch (err) {
console.error(err)
}
76 changes: 76 additions & 0 deletions bin/modules/configOptions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
const fs = require("fs");
const path = require("path");
const chalk = require("chalk");

class Options {
constructor(input, output, stylesheet, lang){
this.input = input;
this.output = output;
this.stylesheet = stylesheet;
this.lang = lang;
}
static get DEFAULT_OUTPUT(){ return './dist'; }
static get DEFAULT_LANG(){ return 'en-CA'; }

//Returns true if the input path is validated, otherwise throws an error
validateInput(){
if(!fs.existsSync(this.input)){
throw new Error(`${this.input} does not exist. Input path must be a file or directory`);
}
return true;
}

//Returns true if the output path is validated, otherwise throws an error
validateOutput(){
if(this.output != Options.DEFAULT_OUTPUT){
if(fs.existsSync((this.output))){
if(!fs.lstatSync((this.output)).isDirectory()){
throw new Error("Output path points to a file. Output directory must be valid")
}
}
else throw new Error(`${this.output} does not exist. Output directory must be valid`);
}
return true;
}

/**
* Parses options using a file path
* @param {string} filePath
* @return {Boolean} true if the options were parsed
*/
parseConfig(filePath){
if(fs.existsSync(filePath)){
if(path.extname(filePath).toLocaleLowerCase() == '.json'){
let fileContents = fs.readFileSync(filePath);
let configData;

try{
configData = JSON.parse(fileContents);
}
catch(err){
console.log('Error while parsing JSON: ', err);
process.exit(-1);
}

this.input = configData.input;
this.output = configData.output ? configData.output : Options.DEFAULT_OUTPUT;
this.lang = configData.lang ? configData.lang : Options.DEFAULT_LANG;
this.stylesheet = configData.s;

}
else {
console.log("Config file must be JSON!", path.extname(filePath));
process.exit(-1);
}
}
else {
console.log(`${filePath} not found! A JSON config file must be supplied`);
process.exit(-1);
}

console.log(chalk.green(`Options successfully retrieved from ${filePath}`));
return true;
}
}

module.exports.Options = Options;
18 changes: 8 additions & 10 deletions generateHtml.js → bin/modules/generateHtml.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ const convertMdFileToHtml = (filePath, stylesheet, lang) => {
.replace(/\~\~(.*)\~\~/gim, '<del>$1</del>')
.replace(/\[(.*?)\]\((.*?)\)/gim, "<a href='$2'>$1</a>")
.replace(/^<http(.*)$/gim, "<a href='http$1'>http$1</a>");



const html = encloseInHtml(title[0].slice(2), body.trim(), stylesheet, lang);
const outputFilePath = path.join(outputDir, path.basename(filePath, '.md') + '.html')
Expand All @@ -73,12 +71,12 @@ const convertMdFileToHtml = (filePath, stylesheet, lang) => {
* @param {string} path
*/
const parseFile = (path) => {
try {
const data = fs.readFileSync(path, 'utf8')
return data;
} catch (err) {
console.error(err)
}
try {
const data = fs.readFileSync(path, 'utf8')
return data;
} catch (err) {
console.error(err)
}
}

/**
Expand All @@ -102,7 +100,7 @@ const parseFile = (path) => {
<h1>${title}</h1>
${body}
</body>
</html>`
</html>`;
}

/**
Expand Down Expand Up @@ -140,8 +138,8 @@ const checkDirForTxt = (dirPath) => {
* @param {string} stylesheet - optional language attribute for html element
*/
const main = (input, output, stylesheet, lang) => {

outputDir = output;

//Create empty directory for output
if (!fs.existsSync(outputDir)){
fs.mkdirSync(outputDir, {recursive: true});
Expand Down

1 comment on commit b406d2f

@vercel
Copy link

@vercel vercel bot commented on b406d2f Oct 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.