Skip to content
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
5 changes: 5 additions & 0 deletions .changeset/modern-cycles-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@vue-storefront/cli": patch
---

[CHANGED] Added back the previously removed `m2-only` command.
52 changes: 52 additions & 0 deletions packages/cli/src/commands/m2-only.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { intro } from "@clack/prompts";
import { Command } from "@oclif/core";
import picocolors from "picocolors";
import { t } from "i18next";
import { initLogger } from "../domains/generate/logging/logger";
import {
checkDocker,
getMagentoDomainName,
} from "../domains/generate/magento2/docker";
import { getMagentoDetails } from "../domains/generate/magento2/functions";
import { installMagento } from "../domains/generate/magento2/installMagento";
import { simpleLog } from "../domains/generate/magento2/functions/terminalHelpers";

export default class M2Only extends Command {
static override description = "Install local Magento 2 instance";

static override examples = ["<%= config.bin %> <%= command.id %>"];

static override flags = {};

static override args = [];

async run(): Promise<void> {
const { writeLog, deleteLog } = initLogger();

intro("Welcome to the Magento 2 local instance installer!");

await checkDocker(writeLog);

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

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

await installMagento({
isInstallMagento: true,
magentoDirName,
magentoDomain,
magentoAccessKey,
magentoSecretKey,
writeLog,
});

deleteLog();

simpleLog("Happy coding! 🎉", picocolors.green);

this.exit(0);
}
}
18 changes: 18 additions & 0 deletions packages/cli/src/domains/generate/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,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { spawn } from "child_process";
import { t } from "i18next";
import {
logSimpleErrorMessage,
logSimpleInfoMessage,
simpleLog,
} from "../functions/terminalHelpers";

/** Checking if Docker is installed and running on user's machine */
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());
});

const isDockerInstalled = await new Promise((resolve) => {
docker.on("close", (code) => resolve(code === 0));
});

if (!isDockerInstalled) {
writeLog(
"Docker is not installed or not running. Please make sure that prerequisites are complied with and run command again."
);
logSimpleErrorMessage(
"Docker is not installed or not running. Please make sure that prerequisites are complied with and run command again."
);
logSimpleInfoMessage(t("command.generate_store.magento.failed_log"));
process.exit(1);
} else {
writeLog("🐳 Docker is installed and running.");
logSimpleInfoMessage("🐳 Docker is installed and running.");
}
};

export default checkDocker;
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import execa from "execa";

const checkExistingDockerContainers = async (magentoDirName = "server") => {
const execaFunc =
process.platform === "darwin"
? execa("docker", ["container", "ls", "--format", "{{.Names}}"])
: execa("sudo", ["docker", "container", "ls", "--format", "{{.Names}}"]);

const { stdout } = await execaFunc;

const isExistingDockerContainers = stdout.includes(magentoDirName);

return isExistingDockerContainers;
};

export default checkExistingDockerContainers;
5 changes: 5 additions & 0 deletions packages/cli/src/domains/generate/magento2/docker/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export { default as checkDocker } from "./checkDocker";
export { default as installMagentoImage } from "./installMagentoImage";
export { default as getMagentoDomainName } from "../prompts/getMagentoDomain";
export { default as checkExistingDockerContainers } from "./checkExistingDockerContainers";
export { default as removeDockerContainer } from "./removeDocker";
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { spawn } from "child_process";

import { note, spinner } from "@clack/prompts";
import picocolors from "picocolors";
import { t } from "i18next";
import {
logSimpleErrorMessage,
logSimpleInfoMessage,
} from "../functions/terminalHelpers";
import removeDockerContainer from "./removeDocker";

/** Handles Magento 2 Docker Image installation */
const installMagentoImage = async (
magentoDirName: string,
magentoDomainName: string,
writeLog: (message: string) => void
): Promise<any> => {
const options = {
cwd: magentoDirName,
};

const sp = spinner();

return new Promise((resolve) => {
const curl = spawn(
"curl",
[
"-s",
"https://raw.githubusercontent.com/markshust/docker-magento/master/lib/onelinesetup",
],
options
);
const bash = spawn("bash", ["-s", "--", magentoDomainName], options);

let stdout = "";

note(t("command.generate_store.magento.note_long"));

sp.start(
picocolors.cyan(t("command.generate_store.progress.docker_start"))
);

curl.stdout.pipe(bash.stdin);

bash.stdout.on("data", (data) => {
if (
data.toString().toLowerCase().includes("system") &&
data.toString().toLowerCase().includes("password")
) {
sp.stop(
picocolors.yellow(t("command.generate_store.magento.password"))
);
}

if (data.toString().includes("Restarting containers to apply updates")) {
sp.start(
picocolors.cyan(t("command.generate_store.progress.docker_start"))
);
}
});

bash.stderr.on("data", async (data) => {
stdout += data.toString();
if (stdout.includes("port is already allocated")) {
sp.stop();
logSimpleErrorMessage(t("command.generate_store.magento.port_busy"));
// delete the directory
await removeDockerContainer(magentoDirName);
}
});

bash.on("exit", async (code) => {
if (code === 0) {
sp.stop(
picocolors.green(t("command.generate_store.progress.docker_end"))
);
resolve(1);
} else {
sp.stop(
picocolors.red(t("command.generate_store.progress.docker_failed"))
);

if (
stdout.includes('Project directory "/var/www/html/." is not empty')
) {
note(t("command.generate_store.magento.image_exists"));
}
// create a log file
writeLog(stdout);

logSimpleInfoMessage(t("command.generate_store.magento.failed_log"));
}
});
});
};

export default installMagentoImage;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { spawn } from "child_process";
import fs from "fs";

// rewrite with exec
const removeDockerContainer = async (magentoDirName: string): Promise<any> => {
const options = {
cwd: magentoDirName,
};

return new Promise(() => {
const removeDocker = spawn("docker-compose", ["rm", "-f"], options);

removeDocker.on("exit", () => {
fs.rmdirSync(magentoDirName, { recursive: true });
});
});
};

export default removeDockerContainer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { spawn } from "child_process";
import { t } from "i18next";
import {
logSimpleErrorMessage,
logSimpleSuccessMessage,
} from "./terminalHelpers";

const checkNodeVersion = (nodeString: string): boolean => {
const nodeVersion = nodeString.split("v")[1]?.split(".")[0];
const subNodeVersion = nodeString.split("v")[1]?.split(".")[1];

if (Number(nodeVersion) === 16 && Number(subNodeVersion) >= 13) {
return true;
}

return false;
};

/** Checking if Node version is correct as per prerequisites */
const checkNode = async (
writeLog: (message: string) => void
): Promise<void> => {
const node = spawn("node", ["-v"]);

return await new Promise((resolve) => {
node.stdout.on("data", (data) => {
writeLog(data.toString());
if (!checkNodeVersion(data.toString())) {
logSimpleErrorMessage(t("command.generate_store.magento.node_not_ok"));
process.exit(1);
}
});

node.on("close", () => {
writeLog(t("command.generate_store.magento.node_ok"));
logSimpleSuccessMessage(t("command.generate_store.magento.node_ok"));
resolve();
});
});
};

export default checkNode;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { spawn } from "child_process";
import { t } from "i18next";
import {
logSimpleErrorMessage,
logSimpleInfoMessage,
simpleLog,
} from "./terminalHelpers";

const checkYarnVersion = (yarnString: string): boolean => {
const yarnVersion = yarnString.split(".")[0];

if (Number(yarnVersion) === 1 || Number(yarnVersion) === 2) {
return true;
}

return false;
};

/** Checking if Yarn is installed */
const checkYarn = async (
writeLog: (message: string) => void
): Promise<void> => {
const yarn =
process.platform === "win32"
? spawn("yarn.cmd", ["--version"])
: spawn("yarn", ["--version"]);

yarn.stdout.on("data", (data) => {
if (!checkYarnVersion(data.toString())) {
writeLog(t("command.generate_store.magento.yarn_not_ok"));
logSimpleErrorMessage(t("command.generate_store.magento.yarn_not_ok"));
logSimpleInfoMessage(t("command.generate_store.magento.failed_log"));
process.exit(1);
}
});

yarn.stderr.on("data", (data) => {
writeLog(data.toString());
simpleLog(data.toString());
});

const isYarnVersionCorrect = await new Promise((resolve) => {
yarn.on("close", (code) => resolve(code === 0));
});

if (!isYarnVersionCorrect) {
writeLog(t("command.generate_store.magento.yarn_not_ok"));
logSimpleErrorMessage(t("command.generate_store.magento.yarn_not_ok"));
logSimpleInfoMessage(t("command.generate_store.magento.failed_log"));
process.exit(1);
}
};

export default checkYarn;
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { spawn } from "child_process";
import fs from "fs";
import path from "path";

/** Copy auth.json file to Docker container */
const copyAuth = async (
magentoDirName: string,
accessKey: string,
secretKey: string
) => {
const options = {
cwd: magentoDirName,
};

const authFile = await fs.readFileSync(
path.join(magentoDirName, "src/auth.json.sample"),
"utf-8"
);

await fs.writeFileSync(
path.join(magentoDirName, "src/auth.json"),
authFile
.replace(/<public-key>/g, accessKey)
.replace(/<private-key>/g, secretKey),
"utf-8"
);

const copyToContainer = spawn(
"bin/copytocontainer",
["src/auth.json"],
options
);

copyToContainer.on("close", () => undefined);
};

export default copyAuth;
Loading
Loading