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 19, 2022
1 parent b012aa7 commit 38ff53b
Show file tree
Hide file tree
Showing 12 changed files with 159 additions and 37 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
### Draft

- feat: STRF-9741 Verbose error logging in Stencil CLI by default ([x](https:/bigcommerce/stencil-cli/pull/x))

### 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
9 changes: 3 additions & 6 deletions bin/stencil-download.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,18 @@ 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
8 changes: 3 additions & 5 deletions bin/stencil-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,17 @@ 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
21 changes: 21 additions & 0 deletions lib/StencilCLISettings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

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;
18 changes: 18 additions & 0 deletions lib/StencilCLISettings.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
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();
})
})
50 changes: 50 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 @@ -24,11 +25,38 @@ function printCliResultError(error) {
}
}

if (error && error.response) {
printNetworkError(error);
}

console.log(messages.visitTroubleshootingPage);

console.log(messages.submitGithubIssue);
}

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

function printObject(object) {
for (const property in object) {
console.log(`${property}: ${object[property]}`);
}
}

/**
* @param {Error} error
* @returns {void}
Expand All @@ -52,9 +80,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 38ff53b

Please sign in to comment.