From f4388e648277eaa3d7136b6655262fed8643d00d Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Fri, 16 Dec 2022 16:01:51 +0100 Subject: [PATCH 1/2] CLI: write into a log file if automigrations fail - the errors will get supressed in normal output but shown in the log file --- code/lib/cli/package.json | 1 + .../cli/src/automigrate/helpers/cleanLog.ts | 12 ++++ code/lib/cli/src/automigrate/index.ts | 58 ++++++++++++++++++- code/yarn.lock | 44 ++++++++++++++ 4 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 code/lib/cli/src/automigrate/helpers/cleanLog.ts diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index 2ad49543f1b6..4af9ac0ced8d 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -73,6 +73,7 @@ "shelljs": "^0.8.5", "simple-update-notifier": "^1.0.0", "strip-json-comments": "^3.0.1", + "tempy": "^1.0.1", "ts-dedent": "^2.0.0", "util-deprecate": "^1.0.2" }, diff --git a/code/lib/cli/src/automigrate/helpers/cleanLog.ts b/code/lib/cli/src/automigrate/helpers/cleanLog.ts new file mode 100644 index 000000000000..ab97c9d21b0a --- /dev/null +++ b/code/lib/cli/src/automigrate/helpers/cleanLog.ts @@ -0,0 +1,12 @@ +import { EOL } from 'os'; + +export const cleanLog = (str: string) => + str + // remove chalk ANSI colors + // eslint-disable-next-line no-control-regex + .replace(/\u001b\[.*?m/g, '') + // fix boxen output + .replace(/╮│/g, '╮\n│') + .replace(/││/g, '│\n│') + .replace(/│╰/g, '│\n╰') + .replace(/⚠️ {2}failed to check/g, `${EOL}⚠️ failed to check`); diff --git a/code/lib/cli/src/automigrate/index.ts b/code/lib/cli/src/automigrate/index.ts index 5ab50dc51064..473948217acd 100644 --- a/code/lib/cli/src/automigrate/index.ts +++ b/code/lib/cli/src/automigrate/index.ts @@ -2,13 +2,42 @@ import prompts from 'prompts'; import chalk from 'chalk'; import boxen from 'boxen'; +import { createWriteStream, move, remove } from 'fs-extra'; +import tempy from 'tempy'; import dedent from 'ts-dedent'; + +import { join } from 'path'; import { JsPackageManagerFactory, type PackageManagerName } from '../js-package-manager'; import type { Fix } from './fixes'; import { fixes } from './fixes'; +import { cleanLog } from './helpers/cleanLog'; const logger = console; +const LOG_FILE_NAME = 'migration-storybook.log'; +const LOG_FILE_PATH = join(process.cwd(), LOG_FILE_NAME); +let TEMP_LOG_FILE_PATH = ''; + +const originalStdOutWrite = process.stdout.write.bind(process.stdout); +const originalStdErrWrite = process.stderr.write.bind(process.stdout); + +const augmentLogsToFile = () => { + TEMP_LOG_FILE_PATH = tempy.file({ name: LOG_FILE_NAME }); + const logStream = createWriteStream(TEMP_LOG_FILE_PATH); + + process.stdout.write = (d: string) => { + originalStdOutWrite(d); + return logStream.write(cleanLog(d)); + }; + process.stderr.write = (d: string) => { + return logStream.write(cleanLog(d)); + }; +}; + +const cleanup = () => { + process.stdout.write = originalStdOutWrite; + process.stderr.write = originalStdErrWrite; +}; type FixId = string; @@ -38,6 +67,7 @@ type FixSummary = { }; export const automigrate = async ({ fixId, dryRun, yes, useNpm, force }: FixOptions = {}) => { + augmentLogsToFile(); const packageManager = JsPackageManagerFactory.getPackageManager({ useNpm, force }); const filtered = fixId ? fixes.filter((f) => f.id === fixId) : fixes; @@ -53,6 +83,7 @@ export const automigrate = async ({ fixId, dryRun, yes, useNpm, force }: FixOpti result = await f.check({ packageManager }); } catch (error) { logger.info(`⚠️ failed to check fix ${chalk.bold(f.id)}`); + logger.error(`\n${error.stack}`); fixSummary.failed[f.id] = error.message; fixResults[f.id] = FixStatus.CHECK_FAILED; } @@ -77,6 +108,10 @@ export const automigrate = async ({ fixId, dryRun, yes, useNpm, force }: FixOpti runAnswer = { fix: false }; } else if (yes) { runAnswer = { fix: true }; + if (f.promptOnly) { + fixResults[f.id] = FixStatus.MANUAL_SUCCEEDED; + fixSummary.manual.push(f.id); + } } else if (f.promptOnly) { fixResults[f.id] = FixStatus.MANUAL_SUCCEEDED; fixSummary.manual.push(f.id); @@ -148,14 +183,31 @@ export const automigrate = async ({ fixId, dryRun, yes, useNpm, force }: FixOpti } } + const hasFailures = Object.values(fixResults).some( + (r) => r === FixStatus.FAILED || r === FixStatus.CHECK_FAILED + ); + + // if migration failed, display a log file in the users cwd + if (hasFailures) { + await move(TEMP_LOG_FILE_PATH, join(process.cwd(), LOG_FILE_NAME), { overwrite: true }); + } else { + await remove(TEMP_LOG_FILE_PATH); + } + logger.info(); - logger.info(getMigrationSummary(fixResults, fixSummary)); + logger.info(getMigrationSummary(fixResults, fixSummary, LOG_FILE_PATH)); logger.info(); + cleanup(); + return fixResults; }; -function getMigrationSummary(fixResults: Record, fixSummary: FixSummary) { +function getMigrationSummary( + fixResults: Record, + fixSummary: FixSummary, + logFile?: string +) { const hasNoFixes = Object.values(fixResults).every((r) => r === FixStatus.UNNECESSARY); const hasFailures = Object.values(fixResults).some( (r) => r === FixStatus.FAILED || r === FixStatus.CHECK_FAILED @@ -185,7 +237,7 @@ function getMigrationSummary(fixResults: Record, fixSummary: }, '' )} - ` + \nYou can find the full logs in ${chalk.cyan(logFile)}\n` : ''; const manualFixesMessage = diff --git a/code/yarn.lock b/code/yarn.lock index 5bda16f3769f..11ed9a3120b3 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6164,6 +6164,7 @@ __metadata: shelljs: ^0.8.5 simple-update-notifier: ^1.0.0 strip-json-comments: ^3.1.1 + tempy: ^1.0.1 ts-dedent: ^2.0.0 typescript: ~4.9.3 util-deprecate: ^1.0.2 @@ -13578,6 +13579,13 @@ __metadata: languageName: node linkType: hard +"crypto-random-string@npm:^2.0.0": + version: 2.0.0 + resolution: "crypto-random-string@npm:2.0.0" + checksum: 288589b2484fe787f9e146f56c4be90b940018f17af1b152e4dde12309042ff5a2bf69e949aab8b8ac253948381529cc6f3e5a2427b73643a71ff177fa122b37 + languageName: node + linkType: hard + "css-blank-pseudo@npm:^3.0.2": version: 3.0.3 resolution: "css-blank-pseudo@npm:3.0.3" @@ -31140,6 +31148,13 @@ __metadata: languageName: node linkType: hard +"temp-dir@npm:^2.0.0": + version: 2.0.0 + resolution: "temp-dir@npm:2.0.0" + checksum: b1df969e3f3f7903f3426861887ed76ba3b495f63f6d0c8e1ce22588679d9384d336df6064210fda14e640ed422e2a17d5c40d901f60e161c99482d723f4d309 + languageName: node + linkType: hard + "temp-write@npm:^3.4.0": version: 3.4.0 resolution: "temp-write@npm:3.4.0" @@ -31163,6 +31178,19 @@ __metadata: languageName: node linkType: hard +"tempy@npm:^1.0.1": + version: 1.0.1 + resolution: "tempy@npm:1.0.1" + dependencies: + del: ^6.0.0 + is-stream: ^2.0.0 + temp-dir: ^2.0.0 + type-fest: ^0.16.0 + unique-string: ^2.0.0 + checksum: 864a1cf1b5536dc21e84ae45dbbc3ba4dd2c7ec1674d895f99c349cf209df959a53d797ca38d0b2cf69c7684d565fde5cfc67faaa63b7208ffb21d454b957472 + languageName: node + linkType: hard + "terminal-link@npm:^2.0.0": version: 2.1.1 resolution: "terminal-link@npm:2.1.1" @@ -31961,6 +31989,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^0.16.0": + version: 0.16.0 + resolution: "type-fest@npm:0.16.0" + checksum: 6b4d846534e7bcb49a6160b068ffaed2b62570d989d909ac3f29df5ef1e993859f890a4242eebe023c9e923f96adbcb3b3e88a198c35a1ee9a731e147a6839c3 + languageName: node + linkType: hard + "type-fest@npm:^0.18.0": version: 0.18.1 resolution: "type-fest@npm:0.18.1" @@ -32351,6 +32386,15 @@ __metadata: languageName: node linkType: hard +"unique-string@npm:^2.0.0": + version: 2.0.0 + resolution: "unique-string@npm:2.0.0" + dependencies: + crypto-random-string: ^2.0.0 + checksum: 11820db0a4ba069d174bedfa96c588fc2c96b083066fafa186851e563951d0de78181ac79c744c1ed28b51f9d82ac5b8196ff3e4560d0178046ef455d8c2244b + languageName: node + linkType: hard + "unist-util-generated@npm:^1.0.0, unist-util-generated@npm:^1.1.0": version: 1.1.6 resolution: "unist-util-generated@npm:1.1.6" From 2588dbe5753a7c1fe39c15ea2c7efe3e207d1fee Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Tue, 20 Dec 2022 10:09:00 +0100 Subject: [PATCH 2/2] fix linting --- code/lib/cli/src/automigrate/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/lib/cli/src/automigrate/index.ts b/code/lib/cli/src/automigrate/index.ts index 1dc20ba0a433..9f5a3c91a282 100644 --- a/code/lib/cli/src/automigrate/index.ts +++ b/code/lib/cli/src/automigrate/index.ts @@ -85,9 +85,9 @@ export const automigrate = async ({ fixId, dryRun, yes, useNpm, force, list }: F logAvailableMigrations(); return null; } - + augmentLogsToFile(); - + const packageManager = JsPackageManagerFactory.getPackageManager({ useNpm, force }); logger.info('🔎 checking possible migrations..');