Skip to content

Commit

Permalink
Refactor CLI to use Boxen + create utils file (#26)
Browse files Browse the repository at this point in the history
* use boxen + refactor into utils file

* update lockfile

* simplify box
  • Loading branch information
alex-saunders authored Apr 25, 2019
1 parent 681b6c9 commit e0e1783
Show file tree
Hide file tree
Showing 4 changed files with 1,186 additions and 1,450 deletions.
140 changes: 26 additions & 114 deletions bin/index.js
Original file line number Diff line number Diff line change
@@ -1,135 +1,47 @@
#!/usr/bin/env node
/* eslint-disable */
const path = require('path');
const spawn = require('cross-spawn');
const chalk = require('chalk');
const clear = require('clear');
const ora = require('ora');
const getPort = require('get-port');
const inquirer = require('inquirer');
const opn = require('opn');
const fs = require('fs');

const glicky = require('commander');
const { version } = require('../package');

('use strict');

// Log Utility
function logWarning(...params) {
console.log(chalk.yellow.bold(...params));
}

function logError(...params) {
console.log(chalk.red.bold(...params));
}

function packagePresent() {
const packagePath = path.join(process.cwd(), 'package.json');
return fs.existsSync(packagePath);
}

function parseBoolean(value) {
return value === 'true'
}

function parseInteger(value) {
return parseInt(value);
}

// starts local server with given port and opens the application
// in the users default browser (if open === true)
function startServer(port, { open }) {
clear();
const {
logError,
packagePresent,
parseBoolean,
parseInteger,
startServer,
getFreePort
} = require('./utils');

const loadingMessage = ora(`Starting CLI-GUI server on port ${port}`);
loadingMessage.start();

const serverPath = path.resolve(
__dirname,
'../',
'dist',
'server',
'server.bundle.js'
);

const productionEnv = Object.create(process.env);
productionEnv.GLICKY_ENV = 'production';
productionEnv.FORCE_COLOR = 1;

const proc = spawn('node', [serverPath, `--port=${port}`], {
env: productionEnv
});
const { version } = require('../package');

proc.stdout.on('data', data => {
// TODO: do this better
if (data.toString().startsWith('🚀')) {
if (open) {
opn(`http://localhost:${port}`);
}
loadingMessage.stop();
printSuccessMessage(port);
}
});
}
function printSuccessMessage(port) {
console.log(
chalk.green(
'🐭 Success! Glicky is now running and you can view it in your preferred browser at this URL:\n'
)
);
console.log(`\t✨ http://localhost:${port} ✨\n`);
logWarning('NOTE: This is an early pre-release. There will undoubtedly be bugs but it mostly works and important features are upcoming.');
logWarning('Please report any bugs you encounter to the issues page on the Github repository:');
console.log('🐞 https://github.com/alex-saunders/glicky/issues\n');
console.log(chalk.grey('(press ctrl+C to stop Glicky at any time)'));
}
// is not free, falling back to a random port number if all of these are busy // e.g. check 5000 -> busy -> check 5001 -> busy -> ... -> check 5004 -> busy -> random port number // finds free port, using preferredPort as base and checking 4 above this if it
async function getFreePort(preferredPort = 5000) {
const preferredPorts = Array.from(Array(5), (_, x) => preferredPort + x);
const [initialPort, ...rest] = preferredPorts;
let freePort = await getPort({ port: initialPort });
if (freePort === initialPort) {
return initialPort;
}
freePort = await getPort({ port: rest });
return await inquirer
.prompt([
{
type: 'confirm',
name: 'portConfirmation',
message: chalk.red(
`Port ${initialPort} not available, would you like to start CLI-GUI on port ${freePort} instead?`
),
default: true
}
])
.then(answers => {
if (answers.portConfirmation) {
return freePort;
} else {
console.log('Maybe next time then...');
throw Error();
}
});
}
('use strict');

/**
* Register Glicky commands
*/
// Register Glicky commands
glicky
.version(version, '-v, --version')
.usage('[options]')
.option('-o, --open <boolean>', 'Open Glicky in default browser', parseBoolean, true)
.option('-p, --port <number>', 'Open Glicky on the specified port number', parseInteger, 5000)
.option(
'-o, --open <boolean>',
'Open Glicky in default browser',
parseBoolean,
true
)
.option(
'-p, --port <number>',
'Open Glicky on the specified port number',
parseInteger,
5000
)
.parse(process.argv);

const { open, port } = glicky;

(async () => {
try {
if (!packagePresent()) {
logError('At the moment, Glicky does not support projects that have not been initialised with a package.json file. Please run `npm init` before running Glicky in this directory.');
logError(
'At the moment, Glicky does not support projects that have not been initialised with a package.json file. Please run `npm init` before running Glicky in this directory.'
);
throw Error();
}
clear();
Expand Down
126 changes: 126 additions & 0 deletions bin/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
const getPort = require('get-port');
const inquirer = require('inquirer');
const path = require('path');
const spawn = require('cross-spawn');
const chalk = require('chalk');
const clear = require('clear');
const ora = require('ora');
const opn = require('opn');
const fs = require('fs');
const boxen = require('boxen');
const ip = require('ip');

const log = console.log;

// Utilities
function logWarning(...params) {
log(chalk.yellow(...params));
}

function logError(...params) {
log(chalk.red.bold(...params));
}

function packagePresent() {
const packagePath = path.join(process.cwd(), 'package.json');
return fs.existsSync(packagePath);
}

function parseBoolean(value) {
return value === 'true';
}

function parseInteger(value) {
return parseInt(value);
}

async function getFreePort(preferredPort = 5000) {
const preferredPorts = Array.from(Array(5), (_, x) => preferredPort + x);
const [initialPort, ...rest] = preferredPorts;
let freePort = await getPort({ port: initialPort });
if (freePort === initialPort) {
return initialPort;
}
freePort = await getPort({ port: rest });
return await inquirer
.prompt([
{
type: 'confirm',
name: 'portConfirmation',
message: chalk.red(
`Port ${initialPort} not available, would you like to start CLI-GUI on port ${freePort} instead?`
),
default: true
}
])
.then(answers => {
if (answers.portConfirmation) {
return freePort;
} else {
log('Maybe next time then...');
throw Error();
}
});
}

function printSuccessMessage(port) {
const box = boxen(
`${chalk.green('Glicky is now running!')}\n
${chalk.bold('Local:')} http://localhost:${port}
${chalk.bold('On your network:')} http://${ip.address()}:${port}
`,
{
padding: 1,
borderColor: 'white'
}
);
log(box, '\n');

logWarning(
'NOTE: This is an early pre-release. There will undoubtedly be bugs but it mostly works and important features are upcoming.'
);
logWarning(
'Please report any bugs you encounter to the issues page on the Github repository: https://github.com/alex-saunders/glicky/issues\n'
);
log(chalk.grey('(press ctrl+C to stop Glicky at any time)'));
}
function startServer(port, { open }) {
clear();

const loadingMessage = ora(`Starting CLI-GUI server on port ${port}`);
loadingMessage.start();

const serverPath = path.resolve(
__dirname,
'../',
'dist',
'server',
'server.bundle.js'
);
const productionEnv = Object.create(process.env);
productionEnv.GLICKY_ENV = 'production';
productionEnv.FORCE_COLOR = 1;

const proc = spawn('node', [serverPath, `--port=${port}`], {
env: productionEnv
});
proc.stdout.on('data', data => {
// TODO: do this better
if (data.toString().startsWith('🚀')) {
if (open) {
opn(`http://localhost:${port}`);
}
loadingMessage.stop();
printSuccessMessage(port);
}
});
}
module.exports = {
logError,
packagePresent,
parseBoolean,
parseInteger,
printSuccessMessage,
startServer,
getFreePort
};
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
"nodemon": "^1.18.3",
"normalize.css": "^8.0.0",
"polished": "^2.0.2",
"prettier": "^1.14.2",
"prettier": "^1.17.0",
"react": "^16.8.3",
"react-dom": "^16.8.3",
"react-focus-lock": "^1.17.7",
Expand Down Expand Up @@ -113,6 +113,7 @@
"xterm": "^3.11.0"
},
"dependencies": {
"boxen": "^3.1.0",
"chalk": "^2.4.1",
"clear": "^0.1.0",
"commander": "^2.20.0",
Expand All @@ -121,6 +122,7 @@
"express": "^4.16.3",
"get-port": "^4.0.0",
"inquirer": "^6.2.0",
"ip": "^1.1.5",
"minimist": "^1.2.0",
"opn": "^5.4.0",
"ora": "^3.0.0",
Expand Down
Loading

0 comments on commit e0e1783

Please sign in to comment.