PHP WebShell
Текущая директория: /opt/BitGoJS/scripts
Просмотр файла: prepare-release.ts
import * as assert from 'node:assert';
import { readFileSync, writeFileSync } from 'fs';
import * as path from 'path';
import { inc, lt } from 'semver';
import * as yargs from 'yargs';
import { hideBin } from 'yargs/helpers';
import {
walk,
getDistTagsForModules,
getLernaModules,
changeScopeInFile,
setDependencyVersion,
DistTags,
LernaModule,
} from './prepareRelease';
function replacePackageScopes(rootDir: string, lernaModules: LernaModule[], targetScope: string): number {
let filesChanged = 0;
// replace all @bitgo packages & source code with alternate SCOPE
const filePaths = [...walk(path.join(rootDir, 'modules')), ...walk(path.join(rootDir, 'webpack'))];
const moduleNames = lernaModules.map(({ name }) => name);
filePaths.forEach((file) => {
filesChanged += changeScopeInFile(file, moduleNames, targetScope);
});
return filesChanged;
}
// modules/bitgo is the only package we publish without an `@bitgo` prefix, so
// we must manually set one
function replaceBitGoPackageScope(rootDir: string, targetScope: string): void {
const cwd = path.join(rootDir, 'modules', 'bitgo');
const json = JSON.parse(readFileSync(path.join(cwd, 'package.json'), { encoding: 'utf-8' }));
json.name = `${targetScope}/bitgo`;
writeFileSync(path.join(cwd, 'package.json'), JSON.stringify(json, null, 2) + '\n');
}
/**
* Read package.json for a module
* @param module The module to read package.json from
* @returns The parsed package.json content
*/
function readModulePackageJson(module: LernaModule): any {
return JSON.parse(readFileSync(path.join(module.location, 'package.json'), { encoding: 'utf-8' }));
}
/**
* Write package.json for a module
* @param module The module to write package.json to
* @param json The content to write
*/
function writeModulePackageJson(module: LernaModule, json: any): void {
writeFileSync(path.join(module.location, 'package.json'), JSON.stringify(json, null, 2) + '\n');
}
/**
* Increment the version for a single module based on the preid.
*
* @param {String} preid - The prerelease identifier
* @param {LernaModule} module - The module to update
* @param {DistTags|undefined} tags - The dist tags for the module
* @param {LernaModule[]} allModules - All modules for dependency updates
* @returns {String|undefined} - The new version if set, undefined otherwise
*/
function incrementVersionsForModuleLocation(
preid: string,
module: LernaModule,
tags: DistTags | undefined,
allModules: LernaModule[]
): string | undefined {
const json = readModulePackageJson(module);
let prevTag: string | undefined = undefined;
if (tags) {
if (tags[preid]) {
const version = tags[preid].split('-');
const latest = tags?.latest?.split('-') ?? ['0.0.0'];
prevTag = lt(version[0], latest[0]) ? `${tags.latest}-${preid}` : tags[preid];
} else {
prevTag = `${tags.latest}-${preid}`;
}
}
if (prevTag) {
const next = inc(prevTag, 'prerelease', undefined, preid);
assert(typeof next === 'string', `Failed to increment version for ${json.name} prevTag=${prevTag}`);
console.log(`Setting next version for ${json.name} to ${next}`);
json.version = next;
writeModulePackageJson(module, json);
// since we're manually setting new versions, we must also reconcile all other lerna packages to use the 'next' version for this module
allModules.forEach((otherModule) => {
// skip it for the current version
if (otherModule.location === module.location) {
return;
}
// Use readModulePackageJson here instead of direct readFileSync
const otherJson = readModulePackageJson(otherModule);
// Check if this module depends on the one we're updating
const otherJsonString = JSON.stringify(otherJson);
if (otherJsonString.includes(json.name)) {
setDependencyVersion(otherJson, json.name, next);
writeModulePackageJson(otherModule, otherJson);
}
});
return next;
}
return undefined;
}
/**
* increment the version based on the preid.
*
* @param {String} preid - The prerelease identifier
* @param {LernaModule[]} lernaModules - The modules to update
*/
async function incrementVersions(preid: string, lernaModules: LernaModule[]): Promise<void> {
const distTags = await getDistTagsForModules(lernaModules);
for (const m of lernaModules) {
try {
incrementVersionsForModuleLocation(preid, m, distTags.get(m), lernaModules);
} catch (e) {
// it's not necessarily a blocking error. Let lerna try and publish anyways
console.warn(`Couldn't set next version for ${m.name} at ${m.location}`, e);
}
}
}
yargs(hideBin(process.argv))
.command(
'$0 [preid]',
'Prepare packages for release with a new scope and incremented versions',
(yargs) => {
return yargs
.positional('preid', {
type: 'string',
describe: 'Prerelease identifier',
default: 'beta',
})
.option('scope', {
type: 'string',
description: 'Target scope for packages',
default: '@bitgo-beta',
})
.option('root-dir', {
type: 'string',
description: 'Root directory of the repository',
default: process.env.BITGO_PREPARE_RELEASE_ROOT_DIR || path.join(__dirname, '..'),
});
},
async (argv) => {
const { preid, scope: targetScope, rootDir } = argv;
console.log(`Preparing to re-target to ${targetScope}`);
console.log(`Using root directory: ${rootDir}`);
console.log(`Using prerelease identifier: ${preid}`);
try {
// Get lerna modules directly
const lernaModules = await getLernaModules();
// Replace package scopes
const filesChanged = replacePackageScopes(rootDir, lernaModules, targetScope);
// Replace BitGo package scope
replaceBitGoPackageScope(rootDir, targetScope);
// Increment versions
await incrementVersions(preid, lernaModules);
if (filesChanged) {
console.log(`Successfully re-targeted ${filesChanged} files.`);
process.exit(0);
} else {
console.error('No files were changed, something must have gone wrong.');
process.exit(1);
}
} catch (error) {
console.error('Error in prepare-release script:', error);
process.exit(1);
}
}
)
.help()
.alias('help', 'h')
.parse();
Выполнить команду
Для локальной разработки. Не используйте в интернете!