From 132ef7caad3eb3ab0b1b5cdd1d873f40dcae0ca7 Mon Sep 17 00:00:00 2001 From: Thomas Vaillant Date: Tue, 19 Jan 2021 16:15:07 +0100 Subject: [PATCH] fix(init): sed behavior on macOS replace sed by a Node native implementation --- packages/init/src/commands/InitCommand.ts | 27 ++++++++--------------- packages/init/src/utils.ts | 27 +++++++++++++++++++++++ 2 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 packages/init/src/utils.ts diff --git a/packages/init/src/commands/InitCommand.ts b/packages/init/src/commands/InitCommand.ts index eb4a222..b05a7d7 100644 --- a/packages/init/src/commands/InitCommand.ts +++ b/packages/init/src/commands/InitCommand.ts @@ -10,6 +10,7 @@ import path from "path"; import moment from "moment-timezone"; import type { AppConsole } from "@log4brains/cli-common"; import { FailureExit } from "@log4brains/cli-common"; +import { replaceAllInFile } from "@src/utils"; const assetsPath = path.resolve(path.join(__dirname, "../../assets")); const docLink = "https://github.com/thomvaill/log4brains"; @@ -230,7 +231,7 @@ export class InitCommand { adrFolder: string, title: string, source: string, - replacements: string[][] = [] + replacements: [string, string][] = [] ): Promise { const slug = ( await execa( @@ -247,23 +248,13 @@ export class InitCommand { ) ).stdout; - // eslint-disable-next-line no-restricted-syntax - for (const replacement of [ - ["{DATE_YESTERDAY}", moment().subtract(1, "days").format("YYYY-MM-DD")], // we use yesterday's date so that we are sure new ADRs will appear on top - ...replacements - ]) { - await execa( - "sed", - [ - "-i", - `s/${replacement[0]}/${replacement[1]}/g`, - forceUnixPath(path.join(cwd, adrFolder, `${slug}.md`)) - ], - { - cwd - } - ); - } + await replaceAllInFile( + forceUnixPath(path.join(cwd, adrFolder, `${slug}.md`)), + [ + ["{DATE_YESTERDAY}", moment().subtract(1, "days").format("YYYY-MM-DD")], // we use yesterday's date so that we are sure new ADRs will appear on top + ...replacements + ] + ); return slug; } diff --git a/packages/init/src/utils.ts b/packages/init/src/utils.ts new file mode 100644 index 0000000..b747a94 --- /dev/null +++ b/packages/init/src/utils.ts @@ -0,0 +1,27 @@ +import { promises as fsP } from "fs"; + +function escapeRegExp(str: string) { + return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string +} + +/** + * string.replaceAll() polyfill + * TODO: remove when support down to Node 15 + * @param str + * @param search + * @param replacement + */ +function replaceAll(str: string, search: string, replacement: string): string { + return str.replace(new RegExp(escapeRegExp(search), "g"), replacement); +} + +export async function replaceAllInFile( + path: string, + replacements: [string, string][] +): Promise { + let content = await fsP.readFile(path, "utf-8"); + content = replacements.reduce((prevContent, replacement) => { + return replaceAll(prevContent, replacement[0], replacement[1]); + }, content); + await fsP.writeFile(path, content, "utf-8"); +}