Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STRF-8747: split .stencil file into 2 separate config files #662

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions bin/stencil-download.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ require('colors');
const inquirer = require('inquirer');
const program = require('../lib/commander');

const { API_HOST, PACKAGE_INFO, DOT_STENCIL_FILE_PATH } = require('../constants');
const { API_HOST, PACKAGE_INFO } = require('../constants');
const stencilDownload = require('../lib/stencil-download');
const { checkNodeVersion } = require('../lib/cliCommon');
const { printCliResultErrorAndExit } = require('../lib/cliCommon');
Expand All @@ -22,7 +22,6 @@ checkNodeVersion();
const cliOptions = program.opts();
const extraExclude = cliOptions.exclude ? [cliOptions.exclude] : [];
const options = {
dotStencilFilePath: DOT_STENCIL_FILE_PATH,
exclude: ['parsed', 'manifest.json', ...extraExclude],
apiHost: cliOptions.host || API_HOST,
channelId: cliOptions.channel_id || 1,
Expand Down
16 changes: 9 additions & 7 deletions bin/stencil-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
const program = require('../lib/commander');

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

program
.version(PACKAGE_INFO.version)
Expand All @@ -17,8 +17,10 @@ checkNodeVersion();

const cliOptions = program.opts();

new StencilInit().run(DOT_STENCIL_FILE_PATH, {
normalStoreUrl: cliOptions.url,
accessToken: cliOptions.token,
port: cliOptions.port,
});
new StencilInit()
.run({
normalStoreUrl: cliOptions.url,
accessToken: cliOptions.token,
port: cliOptions.port,
})
.catch(printCliResultErrorAndExit);
3 changes: 1 addition & 2 deletions bin/stencil-pull.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require('colors');

const { DOT_STENCIL_FILE_PATH, PACKAGE_INFO, API_HOST } = require('../constants');
const { PACKAGE_INFO, API_HOST } = require('../constants');
const program = require('../lib/commander');
const stencilPull = require('../lib/stencil-pull');
const { checkNodeVersion } = require('../lib/cliCommon');
Expand All @@ -28,7 +28,6 @@ checkNodeVersion();

const cliOptions = program.opts();
const options = {
dotStencilFilePath: DOT_STENCIL_FILE_PATH,
apiHost: cliOptions.host || API_HOST,
saveConfigName: cliOptions.filename,
channelId: cliOptions.channel_id || 1,
Expand Down
3 changes: 1 addition & 2 deletions bin/stencil-push.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env node

require('colors');
const { DOT_STENCIL_FILE_PATH, PACKAGE_INFO, API_HOST } = require('../constants');
const { PACKAGE_INFO, API_HOST } = require('../constants');
const program = require('../lib/commander');
const stencilPush = require('../lib/stencil-push');
const { checkNodeVersion } = require('../lib/cliCommon');
Expand All @@ -20,7 +20,6 @@ checkNodeVersion();

const cliOptions = program.opts();
const options = {
dotStencilFilePath: DOT_STENCIL_FILE_PATH,
apiHost: cliOptions.host || API_HOST,
bundleZipPath: cliOptions.file,
activate: cliOptions.activate,
Expand Down
6 changes: 2 additions & 4 deletions bin/stencil-start.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env node

require('colors');
const { PACKAGE_INFO, DOT_STENCIL_FILE_PATH } = require('../constants');
const { PACKAGE_INFO } = require('../constants');
const program = require('../lib/commander');
const StencilStart = require('../lib/stencil-start');
const { printCliResultErrorAndExit } = require('../lib/cliCommon');
Expand All @@ -20,6 +20,4 @@ program
)
.parse(process.argv);

new StencilStart()
.run(program.opts(), DOT_STENCIL_FILE_PATH, PACKAGE_INFO.version)
.catch(printCliResultErrorAndExit);
new StencilStart().run(program.opts(), PACKAGE_INFO.version).catch(printCliResultErrorAndExit);
5 changes: 0 additions & 5 deletions constants.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
const path = require('path');

/// ////////////////////////////////////// Stencil CLI ///////////////////////////////////// ///

const PACKAGE_INFO = require('./package.json');
Expand All @@ -8,8 +6,6 @@ const PACKAGE_INFO = require('./package.json');

const THEME_PATH = process.cwd();

const DOT_STENCIL_FILE_PATH = path.join(THEME_PATH, '.stencil');

const DEFAULT_CUSTOM_LAYOUTS_CONFIG = {
brand: {},
category: {},
Expand All @@ -24,7 +20,6 @@ const API_HOST = 'https://api.bigcommerce.com';
module.exports = {
PACKAGE_INFO,
THEME_PATH,
DOT_STENCIL_FILE_PATH,
DEFAULT_CUSTOM_LAYOUTS_CONFIG,
API_HOST,
};
8 changes: 4 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ module.exports = {
coverageDirectory: './.coverage',
coverageThreshold: {
global: {
branches: 33,
functions: 47,
lines: 47,
statements: 47,
branches: 40,
functions: 50,
lines: 50,
statements: 50,
},
},
moduleFileExtensions: ['js', 'json', 'node'],
Expand Down
8 changes: 5 additions & 3 deletions lib/BuildConfigManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ const { fork } = require('child_process');
const path = require('path');
const fsModule = require('fs');

const { THEME_PATH } = require('../constants');

class BuildConfigManager {
constructor({ workDir = process.cwd(), fs = fsModule } = {}) {
this.CONFIG_FILE_NAME = 'stencil.conf.js';
constructor({ workDir = THEME_PATH, fs = fsModule } = {}) {
this.configFileName = 'stencil.conf.js';

this._workDir = workDir;
this._buildConfigPath = path.join(workDir, this.CONFIG_FILE_NAME);
this._buildConfigPath = path.join(workDir, this.configFileName);
this._fs = fs;
this._onReadyCallbacks = [];
this._worker = null;
Expand Down
134 changes: 134 additions & 0 deletions lib/StencilConfigManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
require('colors');
const fsModule = require('fs');
const path = require('path');

const fsUtilsModule = require('./utils/fsUtils');
const { THEME_PATH } = require('../constants');

class StencilConfigManager {
constructor({
themePath = THEME_PATH,
fs = fsModule,
fsUtils = fsUtilsModule,
logger = console,
} = {}) {
this.oldConfigFileName = '.stencil';
this.configFileName = 'config.stencil.json';
this.secretsFileName = 'secrets.stencil.json';

this.themePath = themePath;
this.oldConfigPath = path.join(themePath, this.oldConfigFileName);
this.configPath = path.join(themePath, this.configFileName);
this.secretsPath = path.join(themePath, this.secretsFileName);
this.secretFieldsSet = new Set(['accessToken', 'githubToken']);

this._fs = fs;
this._fsUtils = fsUtils;
this._logger = logger;
}

/**
* @param {boolean} ignoreFileNotExists
* @param {boolean} ignoreMissingFields
* @returns {object|null}
*/
async read(ignoreFileNotExists = false, ignoreMissingFields = false) {
if (this._fs.existsSync(this.oldConfigPath)) {
let parsedConfig;
try {
parsedConfig = await this._fsUtils.parseJsonFile(this.oldConfigPath);
// Tolerate broken files. We should migrate the old config first
// and then validation will throw an error about missing fields
// eslint-disable-next-line no-empty
} catch {
parsedConfig = {};
}
await this._migrateOldConfig(parsedConfig);
return this._validateStencilConfig(parsedConfig, ignoreMissingFields);
}

const generalConfig = this._fs.existsSync(this.configPath)
? await this._fsUtils.parseJsonFile(this.configPath)
: null;
const secretsConfig = this._fs.existsSync(this.secretsPath)
? await this._fsUtils.parseJsonFile(this.secretsPath)
: null;
if (generalConfig || secretsConfig) {
const parsedConfig = { ...generalConfig, ...secretsConfig };
return this._validateStencilConfig(parsedConfig, ignoreMissingFields);
}

if (ignoreFileNotExists) {
return null;
}

throw new Error('Please run'.red + ' $ stencil init'.cyan + ' first.'.red);
}

/**
* @param {object} config
*/
async save(config) {
const { generalConfig, secretsConfig } = this._splitStencilConfig(config);

await this._fs.promises.writeFile(this.configPath, JSON.stringify(generalConfig, null, 2));
await this._fs.promises.writeFile(this.secretsPath, JSON.stringify(secretsConfig, null, 2));
}

/**
* @private
* @param {object} config
*/
_splitStencilConfig(config) {
jairo-bc marked this conversation as resolved.
Show resolved Hide resolved
return Object.entries(config).reduce(
(res, [key, value]) => {
if (this.secretFieldsSet.has(key)) {
res.secretsConfig[key] = value;
} else {
res.generalConfig[key] = value;
}
return res;
},
{ secretsConfig: {}, generalConfig: {} },
);
}

/**
* @private
* @param {object} config
* @param {boolean} ignoreMissingFields
* @returns {object}
*/
_validateStencilConfig(config, ignoreMissingFields) {
if (!ignoreMissingFields && (!config.normalStoreUrl || !config.customLayouts)) {
throw new Error(
'Error: Your stencil config is outdated. Please run'.red +
' $ stencil init'.cyan +
' again.'.red,
);
}
return config;
}

/**
* @private
* @param {object} config
*/
async _migrateOldConfig(config) {
this._logger.log(
`Detected a deprecated ${this.oldConfigFileName.cyan} file.\n` +
`It will be replaced with ${this.configFileName.cyan} and ${this.secretsFileName.cyan}\n`,
);

await this.save(config);
await this._fs.promises.unlink(this.oldConfigPath);

this._logger.log(
`The deprecated ${this.oldConfigFileName.cyan} file was successfully replaced.\n` +
`Make sure to add ${this.secretsFileName.cyan} to .gitignore.\n` +
`${this.configFileName.cyan} can by tracked by git if you wish.\n`,
);
}
}

module.exports = StencilConfigManager;
Loading