// Copyright 2023 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only // @ts-check import { styleText } from 'node:util'; import { execa } from 'execa'; import fs from 'node:fs/promises'; import pLimit from 'p-limit'; import path from 'node:path'; import { DAY } from './utils/durations.mjs'; import { DELETED_REGEXP } from './utils/intlMessages.mjs'; import { assert } from './utils/assert.mjs'; const ROOT_DIR = path.join(import.meta.dirname, '..'); const MESSAGES_FILE = path.join(ROOT_DIR, '_locales', 'en', 'messages.json'); const MAX_AGE = 30 * DAY; const limitter = pLimit(10); const removeBefore = Date.now() - MAX_AGE; const messages = JSON.parse(await fs.readFile(MESSAGES_FILE, 'utf-8')); /** @type {Set} */ const stillUsed = new Set(); await Promise.all( Object.keys(messages).map(key => limitter(async () => { /** @type {{ description?: string }} */ const value = messages[key]; const match = value.description?.match(DELETED_REGEXP); if (!match) { return; } const deletedAtStr = match[1]; assert(deletedAtStr != null, 'Missing deletedAtStr'); const deletedAt = new Date(deletedAtStr).getTime(); if (deletedAt <= removeBefore) { return; } // Find uses in either: // - `i18n('key')` // - `` try { const result = await execa( 'git', // prettier-ignore [ 'grep', '--extended-regexp', `'${key}'|id="${key}"`, '--', '**', ':!\\_locales/**', ':!\\sticker-creator/**', ], { cwd: ROOT_DIR, stdin: 'ignore', stdout: 'pipe', stderr: 'inherit', } ); // Match found console.error( styleText( 'red', `ERROR: String is still used: "${key}", deleted on ${match[1]}` ) ); console.error(result.stdout.trim()); console.error(''); stillUsed.add(key); } catch (error) { if (error.exitCode === 1) { console.log( styleText( 'dim', `Removing string: "${key}", deleted on ${match[1]}` ) ); delete messages[key]; } else { throw error; } } }) ) ); if (stillUsed.size !== 0) { console.error( `ERROR: Didn't remove ${stillUsed.size} strings because of errors above`, Array.from(stillUsed) .map(str => `- ${str}`) .join('\n') ); console.error('ERROR: Not saving changes'); process.exit(1); } await fs.writeFile(MESSAGES_FILE, `${JSON.stringify(messages, null, 2)}\n`);