Skip to content

Commit

Permalink
feat: features as per issue vuestorefront#6902 and fix vuestorefront#…
Browse files Browse the repository at this point in the history
  • Loading branch information
skirianov committed Apr 4, 2023
1 parent bee8444 commit 5b38700
Show file tree
Hide file tree
Showing 15 changed files with 260 additions and 95 deletions.
13 changes: 11 additions & 2 deletions packages/cli/locales/en-US/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
"skipping": "😞 Can't generate the store. Please run the command again and provide a valid project name.",
"success": "🎉 Sucessfully generated your store at \"./{{projectName}}\"!",
"install": "To finish the installation, run the following commands:",
"install_commands": ["cd {{ projectName }}", "yarn"],
"install_commands": ["cd {{ projectName }}"],
"configure": "Project is conifugred. \nIf you want more advanced configuration go to the \n{{ documentationURL }} to learn how to do it.",
"cd_message": "To start working with the project, cd into project directory:",
"cd_directory": "cd {{ projectName }}",
"start": "Start the project using this command:",
"start_command": "yarn dev",
"canceled": "Store generation cancelled 😞\nWe hope to see you soon! 🤗"
Expand Down Expand Up @@ -42,6 +44,7 @@
"info": "Please make sure that magento directory name \nis unique and was not used before",
"node_ok": "🙌 Node.js version is compatible",
"node_not_ok": "😩 Node.js version is incompatible. Please make sure you use Node.js version >= 16.13 and <17.",
"yarn_not_ok": "😩 Yarn version is incompatible. Please make sure you use Yarn version >= 1 and <3.",
"install": "🤓 Do you want to install Magento 2 locally on your computer? (BETA)",
"install_note": "This feature is still in beta.\nThanks for your patience! 🙏 \nYou can report any issues here: \nhttps://github.com/vuestorefront/vue-storefront/issues",
"directory": "⌨️ Please provide a name for the Magento 2 directory",
Expand All @@ -61,7 +64,13 @@
"sample_data_note": "☝️ You can generate sample data later \nby running `bin/magento sampledata:deploy` \nin the Magento directory.",
"success": "🎉 Magento 2 has been installed successfully.",
"image_exists": "Project directory \"/var/www/html/.\" is not empty. \nPlease remove previous installation or use another directory name.",
"docker_log": "You can find the log file in the {{ magentoDirName }} directory."
"failed_log": "You can find the log in the current directory in the file CLI_logs.txt",
"error": {
"same_dir": "😞 Magento directory name: {{ magentoDirName }} cannot be the same as Vue Storefront project name: {{ projectName }}. Please choose another name."
}
},
"logs": {
"project_name_selected": "\nProject name selected {{ projectName }}"
}
},
"generate_template": {
Expand Down
107 changes: 57 additions & 50 deletions packages/cli/src/commands/generate/store.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
import { Command } from '@oclif/core';
import fs from 'fs';
import { t } from 'i18next';
import * as path from 'path';
import { intro, confirm, isCancel, spinner, note } from '@clack/prompts';
import { intro, isCancel, spinner, note } from '@clack/prompts';
import picocolors from 'picocolors';
import { getIntegration } from '../../domains/integration';
import { getProjectName } from '../../domains/project-name';
import {
cloneGitRepository,
terminateGitRepository
} from '../../domains/git-repository';
import { existsDirectory } from '../../domains/directory';
import {
copyEnv,
installMg2Prompt,
getMagentoDetails
} from '../../domains/magento2/functions';
import {
logSimpleErrorMessage,
logSimpleWarningMessage,
simpleLog
} from '../../domains/magento2/functions/terminalHelpers';

import { installMagento } from '../../domains/magento2/installMagento';
import { checkDocker } from '../../domains/magento2/docker';
import {
checkDocker,
getMagentoDomainName
} from '../../domains/magento2/docker';
import installDeps from '../../domains/magento2/functions/installDeps';
import checkNode from '../../domains/magento2/functions/checkNode';
import checkYarn from '../../domains/magento2/functions/checkYarn';
import { handleProjectDiretoryExists } from '../../domains/directory/handleProjectDiretoryExists';
import { initLogger } from '../../domains/logging/logger';

export default class GenerateStore extends Command {
static override description = t('command.generate_store.description');
Expand All @@ -41,42 +43,25 @@ export default class GenerateStore extends Command {
let magentoDomain = '';
const sp = spinner();

const { writeLog, deleteLog } = initLogger();

intro(t('command.generate_store.message.intro'));

// get project name
const projectName = await getProjectName(
t('command.generate_store.input.project_name')
);

const projectDir = path.resolve(projectName);

if (await existsDirectory(projectDir)) {
const overwrite = await confirm({
message: t('command.generate_store.input.overwrite', {
projectName
}) as string
});

if (isCancel(overwrite)) {
logSimpleWarningMessage(t('command.generate_store.message.canceled'));
this.exit(0);
}

if (overwrite) {
sp.start(
picocolors.cyan(t('command.generate_store.progress.delete_start'))
);
await fs.rmSync(projectDir, { recursive: true, force: true });
await fs.mkdirSync(projectDir);
sp.stop(
picocolors.green(t('command.generate_store.progress.delete_end'))
);
}

if (!overwrite) {
logSimpleErrorMessage(t('command.generate_store.message.skipping'));
this.exit(0);
}
}
// check if project directory exists and ask for overwrite
await handleProjectDiretoryExists({
projectName,
projectDir,
sp
});

// get integration
const integration = await getIntegration({
message: t('command.generate_store.input.integration'),
customIntegrationRepositoryMessage: t(
Expand All @@ -85,61 +70,83 @@ export default class GenerateStore extends Command {
});

const { name: integrationName } = integration;
const isMagento2 = integrationName === 'Magento 2';

if (integrationName === 'Magento 2') {
await checkNode(writeLog);
await checkYarn(writeLog);

// install Magento 2 if needed
if (isMagento2) {
const isInstallMagento = await installMg2Prompt(
t('command.generate_store.magento.install')
);

await checkNode();
await checkYarn();
await checkDocker();

if (isCancel(isInstallMagento)) {
logSimpleWarningMessage(t('command.generate_store.message.canceled'));
process.exit(0);
}

const {
magentoDirName,
magentoDomainName,
magentoAccessKey,
magentoSecretKey
} = await getMagentoDetails();
if (isInstallMagento) {
await checkDocker(writeLog);

magentoDomain = magentoDomainName;
const { magentoDirName, magentoAccessKey, magentoSecretKey } =
await getMagentoDetails(projectName);

magentoDomain = await getMagentoDomainName(
t('command.generate_store.magento.domain')
);

if (isInstallMagento) {
await installMagento({
isInstallMagento,
magentoDirName,
magentoDomainName,
magentoDomain,
magentoAccessKey,
magentoSecretKey
magentoSecretKey,
writeLog
});
} else {
magentoDomain = await getMagentoDomainName(
t('command.generate_store.magento.domain')
);
}
}

// generate VSF project
sp.start(t('command.generate_store.progress.vsf_start'));
await cloneGitRepository({
projectDir,
gitRepositoryURL: integration.gitRepositoryURL
});

await copyEnv(projectDir, magentoDomain);
// copy .env file if Magento 2 integration
if (isMagento2) {
await copyEnv(projectDir, magentoDomain);
}
await terminateGitRepository(projectDir);

sp.stop(picocolors.green(t('command.generate_store.progress.vsf_end')));

await installDeps(projectDir);
// install dependencies
await installDeps(projectDir, writeLog);

// show success message
if (integration.documentationURL) {
note(
t('command.generate_store.message.configure', {
documentationURL: integration.documentationURL
})
);
}

deleteLog();

simpleLog(t('command.generate_store.message.cd_message'));
simpleLog(
t<string>('command.generate_store.message.cd_directory', {
projectName
}),
picocolors.magenta
);
simpleLog(t('command.generate_store.message.start'));
simpleLog(
t<string>('command.generate_store.message.start_command', {
Expand Down
14 changes: 11 additions & 3 deletions packages/cli/src/commands/generate/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ export default class GenerateTemplate extends Command {
public async run(): Promise<void> {
const { flags } = await this.parse(GenerateTemplate);

const integrationPath = await getDirectory(t('command.generate_template.input.integration_path'));
const integrationPath = await getDirectory(
t('command.generate_template.input.integration_path')
);

const projectName = await getProjectName(t('command.generate_template.input.project_name'));
const projectName = await getProjectName(
t('command.generate_template.input.project_name')
);

const projectPath = path.join(flags.output, projectName);

Expand All @@ -39,7 +43,11 @@ export default class GenerateTemplate extends Command {
integrationPath
});

this.log(t('command.generate_template.message.success', { projectName: projectPath }));
this.log(
t('command.generate_template.message.success', {
projectName: projectPath
})
);
this.exit(0);
}
}
47 changes: 47 additions & 0 deletions packages/cli/src/domains/directory/handleProjectDiretoryExists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import fs from 'fs';
import { confirm, isCancel } from '@clack/prompts';
import existsDirectory from './existsDirectory';
import {
logSimpleErrorMessage,
logSimpleWarningMessage
} from '../magento2/functions/terminalHelpers';
import { t } from 'i18next';
import picocolors from 'picocolors';

export const handleProjectDiretoryExists = async ({
projectName,
projectDir,
sp
}: {
projectName: string;
projectDir: string;
sp: any;
}): Promise<void> => {
if (await existsDirectory(projectDir)) {
const overwrite = await confirm({
message: t('command.generate_store.input.overwrite', {
projectName
}) as string
});
if (isCancel(overwrite)) {
logSimpleWarningMessage(t('command.generate_store.message.canceled'));
process.exit(0);
}

if (overwrite) {
sp.start(
picocolors.cyan(t('command.generate_store.progress.delete_start'))
);
await fs.rmSync(projectDir, { recursive: true, force: true });
await fs.mkdirSync(projectDir);
sp.stop(
picocolors.green(t('command.generate_store.progress.delete_end'))
);
}

if (!overwrite) {
logSimpleErrorMessage(t('command.generate_store.message.skipping'));
process.exit(0);
}
}
};
18 changes: 18 additions & 0 deletions packages/cli/src/domains/logging/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import fs from 'fs';

export const initLogger = () => {
const logFile = fs.createWriteStream('CLI_logs.txt', { flags: 'a' });

const writeLog = (message: string) => {
logFile.write(`${message}\n`);
};

const deleteLog = () => {
fs.unlinkSync('CLI_logs.txt');
};

return {
writeLog,
deleteLog
};
};
11 changes: 10 additions & 1 deletion packages/cli/src/domains/magento2/docker/checkDocker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ import {
logSimpleInfoMessage,
simpleLog
} from '../functions/terminalHelpers';
import { t } from 'i18next';

/** Checking if Docker is installed and running on user's machine */
const checkDocker = async (): Promise<void> => {
const checkDocker = async (
writeLog: (message: string) => void
): Promise<void> => {
const docker =
process.platform === 'darwin'
? spawn('docker', ['info'])
: spawn('sudo', ['docker', 'info']);

docker.stderr.on('data', (data) => {
writeLog(data.toString());
simpleLog(data.toString());
});

Expand All @@ -21,11 +25,16 @@ const checkDocker = async (): Promise<void> => {
});

if (!isDockerInstalled) {
writeLog(
'Docker is not installed or not running. Please make sure that prerequisites are complied with and run command again. For more information, please visit https://docs.vuestorefront.io/magento/installation-setup/configure-magento.html'
);
logSimpleErrorMessage(
'Docker is not installed or not running. Please make sure that prerequisites are complied with and run command again. For more information, please visit https://docs.vuestorefront.io/magento/installation-setup/configure-magento.html'
);
logSimpleInfoMessage(t('command.generate_store.magento.failed_log'));
process.exit(1);
} else {
writeLog('🐳 Docker is installed and running.');
logSimpleInfoMessage('🐳 Docker is installed and running.');
}
};
Expand Down
10 changes: 4 additions & 6 deletions packages/cli/src/domains/magento2/docker/installMagentoImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
logSimpleErrorMessage,
logSimpleInfoMessage
} from '../functions/terminalHelpers';
import fs from 'fs';

import { note, spinner } from '@clack/prompts';
import picocolors from 'picocolors';
Expand All @@ -13,7 +12,8 @@ import { t } from 'i18next';
/** Handles Magento 2 Docker Image installation */
const installMagentoImage = async (
magentoDirName: string,
magentoDomainName: string
magentoDomainName: string,
writeLog: (message: string) => void
): Promise<any> => {
const options = {
cwd: magentoDirName
Expand Down Expand Up @@ -86,11 +86,9 @@ const installMagentoImage = async (
note(t('command.generate_store.magento.image_exists'));
}
// create a log file
await fs.writeFileSync(`${magentoDirName}/docker.log`, stdout, 'utf8');
writeLog(stdout);

logSimpleInfoMessage(
t('command.generate_store.magento.docker_log', { magentoDirName })
);
logSimpleInfoMessage(t('command.generate_store.magento.failed_log'));
}
});
});
Expand Down
Loading

0 comments on commit 5b38700

Please sign in to comment.