Skip to content

Commit

Permalink
feat: STRF-9741 Verbose error logging in Stencil CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
jairo-bc committed Apr 21, 2022
1 parent b012aa7 commit 0794605
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 39 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
### Draft

- feat: STRF-9741 Verbose network requests logging in Stencil CLI by default ([x](https://github.com/bigcommerce/stencil-cli/pull/x))
Introduced `--no-verbose` option on all commands to supress verbose network requests logging.

### 4.0.0 (2022-04-11)

- Added support for node 14 and drop node 10
Expand Down
9 changes: 3 additions & 6 deletions bin/stencil-bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const { THEME_PATH, PACKAGE_INFO } = require('../constants');
const ThemeConfig = require('../lib/theme-config');
const Bundle = require('../lib/stencil-bundle');
const { printCliResultErrorAndExit } = require('../lib/cliCommon');
const { checkNodeVersion } = require('../lib/cliCommon');
const { prepareCommand } = require('../lib/cliCommon');
const BuildConfigManager = require('../lib/BuildConfigManager');

program
Expand All @@ -28,16 +28,13 @@ program
'-t, --timeout [timeout]',
'Set a timeout for the bundle operation. Default is 20 secs',
'60',
)
.parse(process.argv);
);

const cliOptions = program.opts();
const cliOptions = prepareCommand(program);
const themeConfig = ThemeConfig.getInstance(THEME_PATH);

async function run() {
try {
checkNodeVersion();

if (cliOptions.dest === true) {
throw new Error('You have to specify a value for -d or --dest'.red);
}
Expand Down
10 changes: 3 additions & 7 deletions bin/stencil-download.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,17 @@ const program = require('../lib/commander');

const { PACKAGE_INFO } = require('../constants');
const stencilDownload = require('../lib/stencil-download');
const { checkNodeVersion } = require('../lib/cliCommon');
const { prepareCommand } = require('../lib/cliCommon');
const { printCliResultErrorAndExit } = require('../lib/cliCommon');

program
.version(PACKAGE_INFO.version)
.option('-h, --host [hostname]', 'specify the api host')
.option('-f, --file [filename]', 'specify the filename to download only')
.option('-e, --exclude [exclude]', 'specify a directory to exclude from download')
.option('-c, --channel_id [channelId]', 'specify the channel ID of the storefront', parseInt)
.option('-o, --overwrite', 'overwrite local with remote files')
.parse(process.argv);
.option('-o, --overwrite', 'overwrite local with remote files');

checkNodeVersion();

const cliOptions = program.opts();
const cliOptions = prepareCommand(program);
const extraExclude = cliOptions.exclude ? [cliOptions.exclude] : [];
const options = {
exclude: ['parsed', 'manifest.json', ...extraExclude],
Expand Down
9 changes: 3 additions & 6 deletions bin/stencil-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ const program = require('../lib/commander');

const StencilInit = require('../lib/stencil-init');
const { PACKAGE_INFO } = require('../constants');
const { checkNodeVersion, printCliResultErrorAndExit } = require('../lib/cliCommon');
const { prepareCommand, printCliResultErrorAndExit } = require('../lib/cliCommon');

program
.version(PACKAGE_INFO.version)
.option('-u, --url [url]', 'Store URL')
.option('-t, --token [token]', 'Access Token')
.option('-p, --port [port]', 'Port')
.option('-h, --apiHost [host]', 'API Host')
.parse(process.argv);
.option('-h, --apiHost [host]', 'API Host');

checkNodeVersion();

const cliOptions = program.opts();
const cliOptions = prepareCommand(program);

new StencilInit()
.run({
Expand Down
10 changes: 3 additions & 7 deletions bin/stencil-pull.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ require('colors');
const { PACKAGE_INFO } = require('../constants');
const program = require('../lib/commander');
const stencilPull = require('../lib/stencil-pull');
const { checkNodeVersion } = require('../lib/cliCommon');
const { prepareCommand } = require('../lib/cliCommon');
const { printCliResultErrorAndExit } = require('../lib/cliCommon');

program
.version(PACKAGE_INFO.version)
.option('-s, --saved', 'get the saved configuration instead of the active one')
.option('-h, --host [hostname]', 'specify the api host')
.option(
'-f, --filename [filename]',
'specify the filename to save the config as',
Expand All @@ -21,12 +20,9 @@ program
'-c, --channel_id [channelId]',
'specify the channel ID of the storefront to pull configuration from',
parseInt,
)
.parse(process.argv);

checkNodeVersion();
);

const cliOptions = program.opts();
const cliOptions = prepareCommand(program);

const options = {
apiHost: cliOptions.host,
Expand Down
10 changes: 3 additions & 7 deletions bin/stencil-push.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ require('colors');
const { PACKAGE_INFO } = require('../constants');
const program = require('../lib/commander');
const stencilPush = require('../lib/stencil-push');
const { checkNodeVersion } = require('../lib/cliCommon');
const { prepareCommand } = require('../lib/cliCommon');
const { printCliResultErrorAndExit } = require('../lib/cliCommon');

program
.version(PACKAGE_INFO.version)
.option('--host [hostname]', 'specify the api host')
.option('-f, --file [filename]', 'specify the filename of the bundle to upload')
.option('-s, --save [filename]', 'specify the filename to save the bundle as')
.option('-a, --activate [variationname]', 'specify the variation of the theme to activate')
Expand All @@ -18,12 +17,9 @@ program
'-c, --channel_ids <channelIds...>',
'specify the channel IDs of the storefront to push the theme to',
)
.option('-allc, --all_channels', 'push a theme to all available channels')
.parse(process.argv);
.option('-allc, --all_channels', 'push a theme to all available channels');

checkNodeVersion();

const cliOptions = program.opts();
const cliOptions = prepareCommand(program);
const options = {
apiHost: cliOptions.host,
channelIds: cliOptions.channel_ids,
Expand Down
9 changes: 3 additions & 6 deletions bin/stencil-start.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ require('colors');
const { PACKAGE_INFO } = require('../constants');
const program = require('../lib/commander');
const StencilStart = require('../lib/stencil-start');
const { printCliResultErrorAndExit } = require('../lib/cliCommon');
const { printCliResultErrorAndExit, prepareCommand } = require('../lib/cliCommon');
const BuildConfigManager = require('../lib/BuildConfigManager');

program
.version(PACKAGE_INFO.version)
.option('-o, --open', 'Automatically open default browser')
.option('-v, --variation [name]', 'Set which theme variation to use while developing')
.option('-c, --channelId [channelId]', 'Set the channel id for the storefront')
.option('--host [hostname]', 'specify the api host')
.option(
'--tunnel [name]',
'Create a tunnel URL which points to your local server that anyone can use.',
Expand All @@ -21,11 +20,9 @@ program
'-n, --no-cache',
'Turns off caching for API resource data per storefront page. The cache lasts for 5 minutes before automatically refreshing.',
)
.option('-t, --timeout', 'Set a timeout for the bundle operation. Default is 20 secs', '60')
.parse(process.argv);

const cliOptions = program.opts();
.option('-t, --timeout', 'Set a timeout for the bundle operation. Default is 20 secs', '60');

const cliOptions = prepareCommand(program);
const options = {
open: cliOptions.open,
variation: cliOptions.variation,
Expand Down
18 changes: 18 additions & 0 deletions lib/StencilCLISettings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class StencilCLISettings {
constructor() {
// The setting enables/disables verbose network requests logging
this.versboseNetworkLogging = true;
}

setVerbose(flag) {
this.versboseNetworkLogging = flag;
}

isVerbose() {
return this.versboseNetworkLogging === true;
}
}

const settings = new StencilCLISettings();

module.exports = settings;
17 changes: 17 additions & 0 deletions lib/StencilCLISettings.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const stencilCLISettings = require('./StencilCLISettings');

describe('StencilCLISettings', () => {
afterEach(() => {
// setting to default
stencilCLISettings.setVerbose(true);
});

it('should set network logging to verbose by default', () => {
expect(stencilCLISettings.isVerbose()).toBeTruthy();
});

it('should set network logging to NOT verbose', () => {
stencilCLISettings.setVerbose(false);
expect(stencilCLISettings.isVerbose()).toBeFalsy();
});
});
54 changes: 54 additions & 0 deletions lib/cliCommon.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const semver = require('semver');
const { PACKAGE_INFO } = require('../constants');
const stencilCLISettings = require('./StencilCLISettings');

const messages = {
visitTroubleshootingPage:
Expand All @@ -8,6 +9,31 @@ const messages = {
'If this error persists, please visit https://github.com/bigcommerce/stencil-cli/issues and submit an issue.',
};

/**
* @param {Object} object
* @returns {void}
*/
function printObject(object) {
for (const property of Object.keys(object)) {
console.log(`${property}: ${object[property]}`);
}
}

/**
* @param {Error} error
* @returns {void}
*/
function printNetworkError(config) {
console.log(`URL: `.yellow + config.url);
console.log(`Method: `.yellow + config.method.toUpperCase());
if (config.data) {
console.log(`Data: `.yellow);
printObject(config.data);
}
}

/**
* @param {Error} error
* @param {Array<{message: string}>} [error.messages]
Expand All @@ -24,6 +50,12 @@ function printCliResultError(error) {
}
}

if (error && (error.config || error.response)) {
// In case if request didn't receive any response, response object is not available
const networkReq = error.config || error.response;
printNetworkError(networkReq);
}

console.log(messages.visitTroubleshootingPage);

console.log(messages.submitGithubIssue);
Expand Down Expand Up @@ -52,9 +84,31 @@ function checkNodeVersion() {
return satisfies;
}

function applyCommonOptions(program) {
program
.option('-h, --host [hostname]', 'specify the api host')
.option('-nov, --no-verbose', 'supress verbose info logging', false)
.parse(process.argv);
}

function setupCLI(options) {
stencilCLISettings.setVerbose(options.verbose);
}

function prepareCommand(program) {
applyCommonOptions(program);
checkNodeVersion();

const options = program.opts();
setupCLI(options);

return options;
}

module.exports = {
messages,
printCliResultError,
printCliResultErrorAndExit,
checkNodeVersion,
prepareCommand,
};
12 changes: 12 additions & 0 deletions lib/utils/NetworkUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const fsModule = require('fs');
const axios = require('axios');

const { PACKAGE_INFO } = require('../../constants');
const stencilCLISettings = require('../StencilCLISettings');

const defaultHttpsAgent = new https.Agent({ rejectUnauthorized: false });

Expand All @@ -16,11 +17,13 @@ class NetworkUtils {
httpsAgent = defaultHttpsAgent,
reqLibrary = axios,
packageInfo = PACKAGE_INFO,
logger = console,
} = {}) {
this._fs = fs;
this._httpsAgent = httpsAgent;
this._reqLibrary = reqLibrary;
this._packageInfo = packageInfo;
this._logger = logger;
}

/** Used to send request to our (Bigcommerce) servers only.
Expand Down Expand Up @@ -50,6 +53,10 @@ class NetworkUtils {
reqConfig.headers['x-auth-token'] = accessToken;
}

if (stencilCLISettings.isVerbose()) {
this.log(reqConfig);
}

return this._reqLibrary(reqConfig);
}

Expand All @@ -71,6 +78,11 @@ class NetworkUtils {
.on('error', reject);
});
}

log(config) {
const method = config.method || 'GET';
this._logger.info(`Upcoming request ${method.green}: ${config.url.green}`);
}
}

module.exports = NetworkUtils;
Loading

0 comments on commit 0794605

Please sign in to comment.