Skip to content
Open
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
1 change: 0 additions & 1 deletion api-sample/database/docker-compose.apple-silicon.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: "3.3"
services:
{{PROJECT_NAME_KEBAPCASE}}-db:
container_name: {{PROJECT_NAME_KEBAPCASE}}-mysql-db
Expand Down
3 changes: 1 addition & 2 deletions api-sample/database/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
version: "3.3"
services:
{{PROJECT_NAME_KEBAPCASE}}-db:
container_name: {{PROJECT_NAME_KEBAPCASE}}-mysql-db
image: mysql:5.7
image: mysql:latest
restart: always
command: --sql_mode="NO_ENGINE_SUBSTITUTION"
environment:
Expand Down
26 changes: 18 additions & 8 deletions cli/commands/run/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const run = async () => {
const projectDetails = findProjectRoot();
if (!projectDetails) {
console.log(
chalk.red`You are not within a Xest project directory. Please check your current path directory.`
chalk.red`You are not within a Xest project directory. Please check your current path directory.`,
);
return;
}
Expand All @@ -34,7 +34,7 @@ const run = async () => {

const checkDatabaseSchemaAppliedQuery = `select count(*) as count from migrations where name = '/20211107064304-database-schema';`;
const mySQLConnectionString = `mysql -h localhost -u root -ppassword ${snakeCase(
projectName
projectName,
)}_db`;
const checkDatabaseSchema = `printf "${checkDatabaseSchemaAppliedQuery}" | docker exec -i ${mySQLContainerId} ${mySQLConnectionString}`;
// insert database schema
Expand Down Expand Up @@ -73,7 +73,7 @@ const run = async () => {
});
const checkMigrationsQuery = `select count(*) as count from migrations where name='/${latestMigrationFile.replace(
".js",
""
"",
)}';`;
const checkMigrations = `printf "${checkMigrationsQuery}" | docker exec -i ${mySQLContainerId} ${mySQLConnectionString}`;
({ error, output } = await runSqlQueryWithinContainer(checkMigrations));
Expand Down Expand Up @@ -101,7 +101,7 @@ const run = async () => {

if (error && error.includes("ERROR")) {
console.log(
chalk.red`Failed to populate database with seed data. This might happen if you have recently updated your migrations, please modify your seed data to match new schema changes.`
chalk.red`Failed to populate database with seed data. This might happen if you have recently updated your migrations, please modify your seed data to match new schema changes.`,
);

console.log(chalk.red`Error: ${error.split("ERROR")[1]}`);
Expand All @@ -112,12 +112,22 @@ const run = async () => {
process.stdin.resume();
let isExiting = false;

let dockerComposeCommand = `docker-compose --project-name ${projectName} down`;
const usingAppleSiliconChipset = isAppleSilicon();
if (usingAppleSiliconChipset) {
dockerComposeCommand = `docker-compose --project-name ${projectName} -f docker-compose.apple-silicon.yml down`;
const composeFileName = usingAppleSiliconChipset
? "docker-compose.apple-silicon.yml"
: "docker-compose.yml";

let dockerComposePrefixByVersion = "docker compose";

try {
execSync("docker compose version");
} catch (err) {
// Fallback to legacy docker-compose command if docker compose fails
dockerComposePrefixByVersion = "docker-compose";
}

let dockerComposeCommand = `${dockerComposePrefixByVersion} --project-name ${projectName} -f ${composeFileName} down`;

// shutdown procedure
[
`exit`,
Expand All @@ -141,7 +151,7 @@ const run = async () => {
{ cwd: path.join(rootPath, "database") },
() => {
process.exit(0);
}
},
);
}
});
Expand Down
39 changes: 22 additions & 17 deletions cli/utils/runMySQLContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const runMySQLContainer = async (rootPath, projectName) => {
} catch (err) {
if (err.toString().includes("Error")) {
console.log(
chalk.red`Docker is currently not running. Please start Docker and repeat ${chalk.green`xx run`} again.`
chalk.red`Docker is currently not running. Please start Docker and repeat ${chalk.green`xx run`} again.`,
);
return false;
}
Expand All @@ -26,7 +26,7 @@ const runMySQLContainer = async (rootPath, projectName) => {
`docker ps --format "table {{.ID}}\t{{.Names}}" | grep ${projectName}-mysql-db | cut -d ' ' -f 1`,
{
cwd: path.join(rootPath, "database"),
}
},
).toString();

let ready = false;
Expand All @@ -36,12 +36,13 @@ const runMySQLContainer = async (rootPath, projectName) => {

// read from docker-compose file the PORT number
const usingAppleSiliconChipset = isAppleSilicon();
const composeFileName = usingAppleSiliconChipset
? "docker-compose.apple-silicon.yml"
: "docker-compose.yml";
const dockerComposeFilePath = path.join(
rootPath,
"database",
usingAppleSiliconChipset
? "docker-compose.apple-silicon.yml"
: "docker-compose.yml"
composeFileName,
);

const dockerComposeFile = fs.readFileSync(dockerComposeFilePath, "utf8");
Expand All @@ -52,7 +53,7 @@ const runMySQLContainer = async (rootPath, projectName) => {
// Regex pattern to extract the host port
const pattern = new RegExp(
`${serviceName}:\\s*\\n(?:\\s*\\w+:.*\\n)*\\s*ports:\\s*\\n(?:\\s*-\\s*"?(\\d+):\\d+"?\\n)*`,
"gm"
"gm",
);
const match = pattern.exec(dockerComposeFile);
let mysqlHostPort = 3306;
Expand All @@ -64,13 +65,17 @@ const runMySQLContainer = async (rootPath, projectName) => {
let mySQLContainerId = isDockerMySQLContainerRunning.trim();
if (!Boolean(isDockerMySQLContainerRunning)) {
// check if mysql port is available for use
await resolvePortConflict(mysqlHostPort, "MySQL Docker Container", false, );

let dockerComposeCommand = `docker-compose --project-name ${projectName} up -d`;

if (usingAppleSiliconChipset) {
dockerComposeCommand = `docker-compose --project-name ${projectName} -f docker-compose.apple-silicon.yml up -d`;
await resolvePortConflict(mysqlHostPort, "MySQL Docker Container", false);

// Since Docker Compose V2, docker compose is preferred over docker-compose
let dockerComposePrefixByVersion = "docker compose";
try {
execSync("docker compose version");
} catch (err) {
// Fallback to legacy docker-compose command if docker compose fails
dockerComposePrefixByVersion = "docker-compose";
}
let dockerComposeCommand = `${dockerComposePrefixByVersion} --project-name ${projectName} -f ${composeFileName} up -d`;

const runMySQLContainer = execSync(dockerComposeCommand, {
cwd: path.join(rootPath, "database"),
Expand All @@ -81,21 +86,21 @@ const runMySQLContainer = async (rootPath, projectName) => {
`docker ps --format "table {{.ID}}\t{{.Names}}" | grep ${projectName}-mysql-db | cut -d ' ' -f 1`,
{
cwd: path.join(rootPath, "database"),
}
},
).toString();
mySQLContainerId = isDockerMySQLContainerRunningAgain.trim();

// check whether mysql is ready
console.log(
chalk.yellow`Waiting for MySQL Container to become ready. This should only take a few seconds.`
chalk.yellow`Waiting for MySQL Container to become ready. This should only take a few seconds.`,
);

while (!ready && retryCount < 60) {
const query = `SELECT COUNT(*) as tbl_count FROM information_schema.tables WHERE table_schema = '${snakeCase(
projectName
projectName,
)}_db';`;
const mySQLConnectionString = `mysql -h localhost -u root -ppassword ${snakeCase(
projectName
projectName,
)}_db`;
const checkDatabaseSchema = `printf "${query}" | docker exec -i ${mySQLContainerId} ${mySQLConnectionString}`;
({ error, output } = await runSqlQueryWithinContainer(checkDatabaseSchema));
Expand All @@ -113,7 +118,7 @@ const runMySQLContainer = async (rootPath, projectName) => {
}
if (!ready) {
console.log(
chalk.red`MySQL instance is not ready yet. Try running ${chalk.green`xx run`} again.`
chalk.red`MySQL instance is not ready yet. Try running ${chalk.green`xx run`} again.`,
);
return false;
}
Expand Down
Loading