Skip to content

Commit

Permalink
feat: STRF-11741 Stencil init: auto install dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
jairo-bc committed Apr 8, 2024
1 parent 9ed9f62 commit 2231516
Show file tree
Hide file tree
Showing 8 changed files with 2,888 additions and 5,176 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"sourceType": "module",
"ecmaFeatures": {
"impliedStrict": true
}
},
"ecmaVersion": "2021"
},
"plugins": ["jest", "node", "prettier"],
"extends": [
Expand Down
5 changes: 2 additions & 3 deletions lib/StencilConfigManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,9 @@ class StencilConfigManager {
}

if (!config.apiHost) {
this._logger.log(
`No api host found in config file, falling back to ${API_HOST}. You may need to run 'stencil init' again.`,
);
config.apiHost = API_HOST;
} else {
this._logger.log(`API host set in config file: ${config.apiHost}`);
}

return config;
Expand Down
4 changes: 2 additions & 2 deletions lib/StencilConfigManager.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ describe('StencilConfigManager unit tests', () => {
expect(fsUtilsStub.parseJsonFile).toHaveBeenCalledTimes(1);
expect(fsUtilsStub.parseJsonFile).toHaveBeenCalledWith(defaultOldConfigPath);

expect(loggerStub.log).toHaveBeenCalledTimes(2);
expect(loggerStub.log).toHaveBeenCalledTimes(3);
expect(loggerStub.log).toHaveBeenCalledWith(
expect.stringMatching(`will be replaced`),
);
Expand Down Expand Up @@ -253,7 +253,7 @@ describe('StencilConfigManager unit tests', () => {
expect(fsUtilsStub.parseJsonFile).toHaveBeenCalledTimes(1);
expect(fsUtilsStub.parseJsonFile).toHaveBeenCalledWith(defaultOldConfigPath);

expect(loggerStub.log).toHaveBeenCalledTimes(3);
expect(loggerStub.log).toHaveBeenCalledTimes(2);
expect(loggerStub.log).toHaveBeenCalledWith(
expect.stringMatching(`will be replaced`),
);
Expand Down
10 changes: 10 additions & 0 deletions lib/spinner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const spinner = async (action, options) => {
// eslint-disable-next-line node/no-unsupported-features/es-syntax
const { oraPromise } = await import('ora');
return oraPromise(action, {
spinner: 'triangle',
...options,
});
};

module.exports = spinner;
56 changes: 55 additions & 1 deletion lib/stencil-init.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
require('colors');

const inquirerModule = require('inquirer');
const nypmModule = require('nypm');

const spinnerModule = require('./spinner');
const serverConfigModule = require('../server/config');
const StencilConfigManager = require('./StencilConfigManager');
const { DEFAULT_CUSTOM_LAYOUTS_CONFIG, API_HOST } = require('../constants');
const { DEFAULT_CUSTOM_LAYOUTS_CONFIG, API_HOST, THEME_PATH } = require('../constants');

class StencilInit {
/**
* @param inquirer
* @param stencilConfigManager
* @param serverConfig
* @param logger
* @param nypm
* @param spinner
*/
constructor({
inquirer = inquirerModule,
stencilConfigManager = new StencilConfigManager(),
serverConfig = serverConfigModule,
logger = console,
nypm = nypmModule,
spinner = spinnerModule,
} = {}) {
this._inquirer = inquirer;
this._stencilConfigManager = stencilConfigManager;
this._serverConfig = serverConfig;
this._logger = logger;
this._nypm = nypm;
this._spinner = spinner;
}

/**
Expand All @@ -39,6 +47,7 @@ class StencilInit {
const answers = await this.askQuestions(questions);
const updatedStencilConfig = this.applyAnswers(oldStencilConfig, answers, cliOptions);
await this._stencilConfigManager.save(updatedStencilConfig);
await this.installDependencies(THEME_PATH, answers.packageManager);

this._logger.log(
'You are now ready to go! To start developing, run $ ' + 'stencil start'.cyan,
Expand Down Expand Up @@ -123,6 +132,16 @@ class StencilInit {
});
}

if (!cliOptions.packageManager) {
prompts.push({
type: 'list',
name: 'packageManager',
message: 'What is your favourite Package Manager?',
choices: ['npm', 'yarn', 'pnpm'],
default: this.getPackageManager(),
});
}

return prompts;
}

Expand Down Expand Up @@ -157,6 +176,41 @@ class StencilInit {
...answers,
};
}

getPackageManager() {
const userAgent = process.env.npm_config_user_agent || '';

if (userAgent.startsWith('yarn')) {
return 'yarn';
}

if (userAgent.startsWith('pnpm')) {
return 'pnpm';
}

return 'npm';
}

/**
*
* @param {string} projectDir
* @param {object} packageManager
* @returns
*/
installDependencies(projectDir, packageManager) {
return this._spinner(
this._nypm.installDependencies({
cwd: projectDir,
silent: true,
packageManager,
}),
{
text: `Installing dependencies. This could take a minute...`,
successText: `Dependencies installed successfully`,
failText: (err) => `Failed to install dependencies: ${err.message}`.red,
},
);
}
}

module.exports = StencilInit;
30 changes: 26 additions & 4 deletions lib/stencil-init.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const getAnswers = () => ({
port: 3003,
accessToken: 'accessToken_from_answers',
apiHost: API_HOST,
packageManager: 'npm',
});
const getCliOptions = () => ({
normalStoreUrl: 'https://url-from-cli-options.mybigcommerce.com',
Expand Down Expand Up @@ -65,8 +66,20 @@ const getQuestions = () => [
return true;
},
},
{
type: 'list',
name: 'packageManager',
message: 'What is your favourite Package Manager?',
choices: ['npm', 'yarn', 'pnpm'],
default: 'npm',
},
];

const getNypmStub = () => ({
installDependencies: jest.fn().mockResolvedValue(true),
});
const getSpinnnerStub = () => jest.fn().mockResolvedValue(true);

afterEach(() => jest.restoreAllMocks());

describe('StencilInit integration tests', () => {
Expand Down Expand Up @@ -94,12 +107,14 @@ describe('StencilInit integration tests', () => {
inquirer: inquirerModule,
stencilConfigManager,
logger: console,
nypm: getNypmStub(),
spinner: getSpinnnerStub(),
});
await instance.run();

expect(inquirerPromptStub).toHaveBeenCalledTimes(1);
expect(consoleErrorStub).toHaveBeenCalledTimes(0);
expect(consoleLogStub).toHaveBeenCalledTimes(3);
expect(consoleLogStub).toHaveBeenCalledTimes(2);
expect(saveStencilConfigStub).toHaveBeenCalledTimes(1);

expect(saveStencilConfigStub).toHaveBeenCalledWith(expectedResult);
Expand Down Expand Up @@ -129,12 +144,14 @@ describe('StencilInit integration tests', () => {
inquirer: inquirerModule,
stencilConfigManager,
logger: console,
nypm: getNypmStub(),
spinner: getSpinnnerStub(),
});
await instance.run(cliOptions);

expect(inquirerPromptStub).toHaveBeenCalledTimes(0);
expect(inquirerPromptStub).toHaveBeenCalledTimes(1);
expect(consoleErrorStub).toHaveBeenCalledTimes(0);
expect(consoleLogStub).toHaveBeenCalledTimes(3);
expect(consoleLogStub).toHaveBeenCalledTimes(2);
expect(saveStencilConfigStub).toHaveBeenCalledTimes(1);

expect(saveStencilConfigStub).toHaveBeenCalledWith(expectedResult);
Expand Down Expand Up @@ -179,6 +196,8 @@ describe('StencilInit unit tests', () => {
stencilConfigManager: stencilConfigManager || getStencilConfigManagerStub(),
serverConfig: serverConfig || getServerConfigStub(),
logger: logger || getLoggerStub(),
nypm: getNypmStub(),
spinner: getSpinnnerStub(),
};
const instance = new StencilInit(passedArgs);

Expand All @@ -190,7 +209,10 @@ describe('StencilInit unit tests', () => {

describe('constructor', () => {
it('should create an instance of StencilInit without options parameters passed', async () => {
const instance = new StencilInit();
const instance = new StencilInit({
nypm: getNypmStub(),
spinner: getSpinnnerStub(),
});

expect(instance).toBeInstanceOf(StencilInit);
});
Expand Down
Loading

0 comments on commit 2231516

Please sign in to comment.