From 782e88895149657fd139bc99ac2019abf4ba1c3d Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Sun, 7 Mar 2021 23:00:33 +0100 Subject: [PATCH] [portal,#59][s]: add the in-progress portal cli. NB: portal CLI is currently a bit broken (it starts but some errors) as needs a bit more work to refactor for new location in this repo. Have not done all this refactoring as probably bigger changes needed. --- packages/portal/bin/portal.js | 130 ++++++++++++++++++++++++++++++++++ packages/portal/package.json | 22 ++++-- 2 files changed, 148 insertions(+), 4 deletions(-) create mode 100755 packages/portal/bin/portal.js diff --git a/packages/portal/bin/portal.js b/packages/portal/bin/portal.js new file mode 100755 index 00000000..914bbb80 --- /dev/null +++ b/packages/portal/bin/portal.js @@ -0,0 +1,130 @@ +#!/usr/bin/env node +const Listr = require('listr') +const { program } = require('commander') +const chalk = require('chalk') +const path = require('path') +const figlet = require('figlet') +const { exec } = require('child_process'); +const package = require('../package.json') +const fs = require('fs') + + +console.log( + chalk.yellow(figlet.textSync('Portal App', { horizontalLayout: 'full' })) +) + +function directoryExists(filePath) { + return fs.existsSync(filePath); +} + +/** + * Executes a shell command and return it as a Promise. + * @param cmd {string} + * @return {Promise} + */ +function execShellCommand(cmd) { + return new Promise((resolve, reject) => { + exec(cmd, (error, stdout, stderr) => { + if (error) { + console.warn(error); + reject(error) + } + resolve(stdout ? stdout : stderr); + }); + }); +} + +function processArgs(args) { + const userArgs = { npm: false, override: false, port: 3000, path: process.cwd() } + args.forEach((arg) => { + if (arg.includes("=")) { + let temp = arg.split("=") + userArgs[temp[0]] = temp[1] + } + }) + return userArgs +} +// Output path to create new portal app + + +// Commander parameters to specify CLI behavior +program + .version(package.version) + .usage('show [ path=/some/path | npm=true | port=3000 ]') + .description('Creates a portal application from specified dataset', + ) + .option('npm', '[true || false] Install dependencies using npm instead yarn, defaults to false (yarn)') + .option('port', 'Server port, defaults to 3000') + .parse(process.argv,) + +const userArgs = processArgs(program.args) + + +/** + * Main method to start CLI and validate inputs + */ +async function run() { + const datasetPath = userArgs.path.trim() + + if (directoryExists(datasetPath)) { + console.log( + `${chalk.yellow(`Using dataset found in: ${chalk.cyan(datasetPath)}`)}` + ) + } else { + console.log( + `${chalk.red(`Directory: ${chalk.cyan(datasetPath)} does not exist!`)}` + ) + process.exit(1) + } + + const portalGithubRepo = "https://github.com/datopian/portal-experiment.git" + const portalLocalRepoDirectory = path.join(datasetPath, 'portal-experiment') + + const cloneRepoCmd = `cd ${datasetPath} && + export PORTAL_DATASET_PATH=${datasetPath} && + git clone ${portalGithubRepo}` + + const buildNextAppCmd = userArgs.npm ? `cd ${portalLocalRepoDirectory} && npm install && npm run build` : + `cd ${portalLocalRepoDirectory} && yarn && yarn build` + + const startNextAppCmd = userArgs.npm ? + `cd ${portalLocalRepoDirectory} && npm run start -p ${userArgs.port}` : + `cd ${portalLocalRepoDirectory} && yarn start -p ${userArgs.port}` + + + //Tasks workflow + const tasks = new Listr([ + { + title: 'Getting portal tools...', + task: async () => { + try { + if (directoryExists(portalLocalRepoDirectory)) { + console.log( + chalk.cyan(`${package.name} ${chalk.yellow('already exists! Skipping this step')}`)) + } else { + await execShellCommand(cloneRepoCmd) + } + + } catch (error) { + throw error + } + }, + }, + { + title: 'Preparing your app...', + task: async () => { await execShellCommand(buildNextAppCmd) } + }, + { + title: `Displaying dataset at http://localhost:${userArgs.port}`, + task: () => execShellCommand(startNextAppCmd), + } + ]) + + tasks.run() +} + +run().catch((error) => { + console.log(error) + console.log() + process.exit(1) +}) diff --git a/packages/portal/package.json b/packages/portal/package.json index f52a1550..6ad1f965 100644 --- a/packages/portal/package.json +++ b/packages/portal/package.json @@ -1,7 +1,12 @@ { - "name": "with-tailwindcss", + "name": "portal", + "description": "The data presentation framework", + "author": "Datopian", + "license": "MIT", "version": "0.1.0", - "private": true, + "bin": { + "portal": "./bin/portal.js" + }, "scripts": { "dev": "next dev", "build": "next build", @@ -28,7 +33,16 @@ "remark-html": "^13.0.1", "tailwindcss": "^2.0.2", "vega": "^5.19.1", - "vega-lite": "^5.0.0" + "vega-lite": "^5.0.0", + "chalk": "^4.1.0", + "commander": "^6.2.0", + "cpy": "^8.1.1", + "cross-spawn": "^7.0.3", + "figlet": "^1.5.0", + "listr": "^0.14.3", + "open": "^8.0.2", + "ora": "^5.1.0", + "prompts": "^2.4.0" }, "devDependencies": { "@testing-library/dom": "^7.29.6", @@ -40,4 +54,4 @@ "jest-canvas-mock": "^2.3.1", "jest-dom": "^4.0.0" } -} \ No newline at end of file +}