From 61981c57b9e29e524a085728ce88579c0c3a778b Mon Sep 17 00:00:00 2001 From: Bottersnike Date: Mon, 12 Sep 2022 01:39:59 +0100 Subject: [PATCH 1/4] Modify database-seeds/repo.ts to not use cd --- server/src/lib/database-seeds/repo.ts | 59 +++++++++++++++------------ server/src/utils/misc.ts | 4 +- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/server/src/lib/database-seeds/repo.ts b/server/src/lib/database-seeds/repo.ts index 472bae1c7..32f300e72 100644 --- a/server/src/lib/database-seeds/repo.ts +++ b/server/src/lib/database-seeds/repo.ts @@ -59,9 +59,7 @@ export class DatabaseSeedsRepo { await fs.writeFile(this.CollectionNameToPath(collectionName), JSON.stringify(content)); // Deterministically sort whatever content we just wrote. - await asyncExec( - `cd "${this.baseDir}" || exit 1; node scripts/deterministic-collection-sort.js` - ); + await asyncExec(`node scripts/deterministic-collection-sort.js`, this.baseDir); } async *IterateCollections() { @@ -108,12 +106,16 @@ export class DatabaseSeedsRepo { ); } - // @ereti is insistent that this sleep 1 is fine, so, whatever. - return asyncExec( - `git config user.name "${ServerConfig.SEEDS_CONFIG.USER_NAME}" || exit 3; - git config user.email "${ServerConfig.SEEDS_CONFIG.USER_EMAIL}" || exit 4; - git config credential.helper '!f() { sleep 1; echo "username=\${GIT_USER}"; echo "password=\${GIT_PASSWORD}"; }; f' || exit 5;` - ); + const email = ServerConfig.SEEDS_CONFIG.USER_EMAIL; // Ensure this is still defined by the second exec + + return asyncExec(`git config user.name "${ServerConfig.SEEDS_CONFIG.USER_NAME}"`) + .then(() => asyncExec(`git config user.email "${email}"`)) + .then(() => + // @ereti is insistent that this sleep 1 is fine, so, whatever. + asyncExec( + `git config credential.helper '!f() { sleep 1; echo "username=\${GIT_USER}"; echo "password=\${GIT_PASSWORD}"; }; f'` + ) + ); } /** @@ -127,9 +129,7 @@ export class DatabaseSeedsRepo { this.logger.verbose(`Received commit-back request.`); try { - const { stdout: statusOut } = await asyncExec( - `cd "${this.baseDir}" || exit 1; git status --porcelain` - ); + const { stdout: statusOut } = await asyncExec(`git status --porcelain`, this.baseDir); if (statusOut === "") { this.logger.info(`No changes. Not committing any changes back.`); @@ -154,13 +154,14 @@ export class DatabaseSeedsRepo { await this.#AuthenticateWithGitServer(); + await asyncExec(`git add .`, this.baseDir); const { stdout: commitOut } = await asyncExec( - `cd "${this.baseDir}" || exit 2; - git add . || exit 3; - git commit -am "${commitMsg}" || exit 4; - git push` + `git commit -am "${commitMsg}"`, + this.baseDir ); + await asyncExec(`git push`, this.baseDir); + this.logger.info(`Commit: ${commitOut}.`); return true; @@ -211,23 +212,27 @@ export async function PullDatabaseSeeds( // stderr in git clone is normal output. // stdout is for errors. // there were expletives below this comment, but I have removed them. - const { stdout } = await asyncExec( + const { stdout: cloneStdout } = await asyncExec( `git clone --sparse --depth=1 "${ServerConfig.SEEDS_CONFIG.REPO_URL}" -b "${ Environment.nodeEnv === "production" ? `release/${VERSION_INFO.major}.${VERSION_INFO.minor}` : "staging" - }" '${seedsDir}'; - - - cd '${seedsDir}'; - git sparse-checkout add database-seeds` - - // ^ now that we're in a monorepo, we only want the seeds. + }" "${seedsDir}"` ); - // isn't that confusing - if (stdout) { - logger.error(stdout); + if (cloneStdout) { + throw new Error({ stderr: cloneStdout }); + } + + const { stdout: checkoutStdout } = await asyncExec( + `git sparse-checkout add database-seeds`, + seedsDir + ); + + // ^ now that we're in a monorepo, we only want the seeds. + + if (checkoutStdout) { + throw new Error({ stderr: checkoutStdout }); } return new DatabaseSeedsRepo( diff --git a/server/src/utils/misc.ts b/server/src/utils/misc.ts index b0324c41f..96da890d1 100644 --- a/server/src/utils/misc.ts +++ b/server/src/utils/misc.ts @@ -181,9 +181,9 @@ export function OmitUndefinedKeys(obj: Partial): Partial { * @param command A bash command to execute on the system. * @returns stdout and stderr as strings. */ -export function asyncExec(command: string) { +export function asyncExec(command: string, cwd?: string) { return new Promise<{ stdout: string; stderr: string }>((resolve, reject) => { - exec(command, (err, stdout, stderr) => { + exec(command, { cwd }, (err, stdout, stderr) => { if (err) { // eslint-disable-next-line prefer-promise-reject-errors reject({ err, stdout, stderr }); From 9358ddb63a799cd111c06f5be5449578eb4b3ec4 Mon Sep 17 00:00:00 2001 From: zkldi Date: Mon, 12 Sep 2022 02:49:15 +0100 Subject: [PATCH 2/4] style: fix lines-around-comment this is a cadence bug and it will be fixed at some point --- server/src/lib/database-seeds/repo.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/server/src/lib/database-seeds/repo.ts b/server/src/lib/database-seeds/repo.ts index 32f300e72..7fd54fa42 100644 --- a/server/src/lib/database-seeds/repo.ts +++ b/server/src/lib/database-seeds/repo.ts @@ -111,6 +111,7 @@ export class DatabaseSeedsRepo { return asyncExec(`git config user.name "${ServerConfig.SEEDS_CONFIG.USER_NAME}"`) .then(() => asyncExec(`git config user.email "${email}"`)) .then(() => + // eslint-disable-next-line lines-around-comment // @ereti is insistent that this sleep 1 is fine, so, whatever. asyncExec( `git config credential.helper '!f() { sleep 1; echo "username=\${GIT_USER}"; echo "password=\${GIT_PASSWORD}"; }; f'` From 95acde45055cb136bc7f2d5b6bdec44349cc7196 Mon Sep 17 00:00:00 2001 From: zkldi Date: Mon, 12 Sep 2022 03:38:27 +0100 Subject: [PATCH 3/4] fix: improve local binding explanation --- server/src/lib/database-seeds/repo.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/server/src/lib/database-seeds/repo.ts b/server/src/lib/database-seeds/repo.ts index 7fd54fa42..4035ec19d 100644 --- a/server/src/lib/database-seeds/repo.ts +++ b/server/src/lib/database-seeds/repo.ts @@ -95,7 +95,7 @@ export class DatabaseSeedsRepo { */ #AuthenticateWithGitServer() { if (!ServerConfig.SEEDS_CONFIG) { - // Shouldn't be possible. Ever, since SEEDS_CONFIG must be deffed in order + // Shouldn't be possible. Ever, since SEEDS_CONFIG must be defined in order // to run PullDBSeeds throw new Error(`Cannot commit changes back. SEEDS_CONFIG is not set.`); } @@ -106,17 +106,21 @@ export class DatabaseSeedsRepo { ); } - const email = ServerConfig.SEEDS_CONFIG.USER_EMAIL; // Ensure this is still defined by the second exec + // TS complains that SEEDS_CONFIG.USER_EMAIL might not still be a string by the time the second + // callback is called, so lets just define it to a local variable. + const email = ServerConfig.SEEDS_CONFIG.USER_EMAIL; + + return ( + asyncExec(`git config user.name "${ServerConfig.SEEDS_CONFIG.USER_NAME}"`) + .then(() => asyncExec(`git config user.email "${email}"`)) - return asyncExec(`git config user.name "${ServerConfig.SEEDS_CONFIG.USER_NAME}"`) - .then(() => asyncExec(`git config user.email "${email}"`)) - .then(() => - // eslint-disable-next-line lines-around-comment // @ereti is insistent that this sleep 1 is fine, so, whatever. - asyncExec( - `git config credential.helper '!f() { sleep 1; echo "username=\${GIT_USER}"; echo "password=\${GIT_PASSWORD}"; }; f'` + .then(() => + asyncExec( + `git config credential.helper '!f() { sleep 1; echo "username=\${GIT_USER}"; echo "password=\${GIT_PASSWORD}"; }; f'` + ) ) - ); + ); } /** From 806fc5789a0f4e8f5d31cf2e62ffbe9be835ad90 Mon Sep 17 00:00:00 2001 From: zkldi Date: Mon, 19 Sep 2022 00:49:16 +0100 Subject: [PATCH 4/4] fix: new Error in JS takes a string, not an object future employers, please ignore this small mishap on part of the contributor. Consider hiring them, they're very good at their job and make excellent coffees. --- server/src/lib/database-seeds/repo.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/server/src/lib/database-seeds/repo.ts b/server/src/lib/database-seeds/repo.ts index 4035ec19d..3acc7ee62 100644 --- a/server/src/lib/database-seeds/repo.ts +++ b/server/src/lib/database-seeds/repo.ts @@ -214,19 +214,20 @@ export async function PullDatabaseSeeds( await fs.rm(seedsDir, { recursive: true, force: true }); try { + const branch = + Environment.nodeEnv === "production" + ? `release/${VERSION_INFO.major}.${VERSION_INFO.minor}` + : "staging"; + // stderr in git clone is normal output. // stdout is for errors. // there were expletives below this comment, but I have removed them. const { stdout: cloneStdout } = await asyncExec( - `git clone --sparse --depth=1 "${ServerConfig.SEEDS_CONFIG.REPO_URL}" -b "${ - Environment.nodeEnv === "production" - ? `release/${VERSION_INFO.major}.${VERSION_INFO.minor}` - : "staging" - }" "${seedsDir}"` + `git clone --sparse --depth=1 "${ServerConfig.SEEDS_CONFIG.REPO_URL}" -b "${branch}" "${seedsDir}"` ); if (cloneStdout) { - throw new Error({ stderr: cloneStdout }); + throw new Error(cloneStdout); } const { stdout: checkoutStdout } = await asyncExec( @@ -235,9 +236,10 @@ export async function PullDatabaseSeeds( ); // ^ now that we're in a monorepo, we only want the seeds. + // this shaves quite a bit of time off of the clone. if (checkoutStdout) { - throw new Error({ stderr: checkoutStdout }); + throw new Error(checkoutStdout); } return new DatabaseSeedsRepo(