PHP WebShell
Текущая директория: /opt/BitGoJS/scripts
Просмотр файла: pack-scoped.ts
/**
* This is a helper that creates a archive package with a new scope (similar to what `prepare-release.ts` does).
*
* The archive can be used with `npm install path/to/tgz` to test the package locally.
*/
import * as fs from 'fs';
import * as execa from 'execa';
import * as mpath from 'path';
import * as yargs from 'yargs';
import {
walk,
getLernaModules,
changeScopeInFile,
getDistTagsForModuleNames,
updateModuleNames,
setDependencyVersion,
DistTags,
LernaModule,
getNewModuleName,
} from './prepareRelease';
/** The directory to pack the module into */
const scopedPackageDir = 'pack-scoped';
async function changeModuleScope(dir: string, params: { lernaModules: LernaModule[]; scope: string }) {
console.log(`Changing scope of module at ${dir} to ${params.scope}`);
walk(dir).forEach((file) => {
changeScopeInFile(
file,
params.lernaModules.map((m) => m.name),
params.scope
);
});
}
async function changeModuleVersions(
dir: string,
params: {
moduleNames: string[];
scope: string;
distTagsByModuleName?: Map<string, DistTags>;
}
) {
const newModuleNames = params.moduleNames.map((m) => updateModuleNames(m, params.moduleNames, params.scope));
const { distTagsByModuleName = await getDistTagsForModuleNames(newModuleNames) } = params;
const packageJsonPath = mpath.join(dir, 'package.json');
const packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, 'utf-8'));
newModuleNames.forEach((m) => {
if (!distTagsByModuleName.has(m)) {
console.warn(`No dist tags found for ${m}`);
return;
}
const newVersion = distTagsByModuleName.get(m)?.beta;
if (newVersion) {
setDependencyVersion(packageJson, m, newVersion);
}
});
await fs.promises.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
}
async function getDistTagsFromPackageJson(
newModuleNames: string[],
packageJsonPath: string
): Promise<Map<string, DistTags>> {
const packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, 'utf-8'));
return new Map<string, DistTags>(
newModuleNames.map((m) => {
const distTags = packageJson.dependencies[m];
if (distTags) {
return [m, { beta: distTags }];
}
return [m, { beta: '0.0.0' }];
})
);
}
async function getDistTagsForModuleNamesCached(
dir: string,
newModuleNames: string[],
params: {
scope: string;
sourceFile?: string;
cache?: string;
}
): Promise<Map<string, DistTags>> {
if (params.sourceFile) {
if (params.sourceFile.endsWith('package.json')) {
return getDistTagsFromPackageJson(newModuleNames, params.sourceFile);
}
}
if (params.cache) {
try {
console.log(`Loading cached dist tags from ${params.cache}`);
return new Map<string, DistTags>(JSON.parse(await fs.promises.readFile(params.cache, 'utf-8')));
} catch (e) {
if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
console.log(`No cached dist tags found at ${params.cache}`);
// ignore
} else {
throw e;
}
}
}
const distTagsByModuleName = await getDistTagsForModuleNames(newModuleNames);
if (params.cache) {
console.log(`Caching dist tags to ${params.cache}`);
await fs.promises.writeFile(params.cache, JSON.stringify([...distTagsByModuleName.entries()], null, 2) + '\n');
}
return distTagsByModuleName;
}
/** Change the scope of a module and update its dependencies */
async function runChangeScope(
dir: string,
params: {
lernaModules?: LernaModule[];
scope: string;
distTagsFrom?: string;
cacheDistTags?: string;
}
) {
const { lernaModules = await getLernaModules() } = params;
const moduleNames = lernaModules.map((m) => m.name);
const newModuleNames = moduleNames.map((m) => updateModuleNames(m, moduleNames, params.scope));
await changeModuleScope(dir, { ...params, lernaModules });
await changeModuleVersions(dir, {
...params,
moduleNames,
distTagsByModuleName: await getDistTagsForModuleNamesCached(dir, newModuleNames, {
scope: params.scope,
sourceFile: params.distTagsFrom,
cache: params.cacheDistTags,
}),
});
}
function getModuleByDir(lernaModules: LernaModule[], dir: string): LernaModule {
for (const m of lernaModules) {
if (mpath.relative(m.location, dir) === '') {
return m;
}
}
throw new Error(`Could not find module name for directory ${dir}`);
}
function getArchiveName(m: LernaModule) {
// normalize package name: @bitgo-beta/express -> bitgo-beta-express
const packageName = m.name.replace(/^@/, '').replace(/\//g, '-');
return `${packageName}-v${m.version}.tgz`;
}
/** Pack the module and extract it to a directory */
async function packExtract(moduleDir: string, archiveName: string, packDir: string): Promise<void> {
// Create the directory if it doesn't exist
const packDirPath = mpath.join(moduleDir, packDir);
try {
await fs.promises.rm(mpath.join(packDirPath, 'package'), { recursive: true });
} catch (e) {
if ((e as NodeJS.ErrnoException).code !== 'ENOENT') {
throw e;
}
}
await fs.promises.mkdir(packDirPath, { recursive: true });
await execa('yarn', ['build'], { cwd: moduleDir });
try {
// Pack the module using yarn to temp file
await execa('yarn', ['pack'], {
cwd: moduleDir,
});
// Extract the archive
await execa('tar', ['xzf', archiveName, '-C', packDir], {
cwd: moduleDir,
});
console.log(`Packed and extracted module to ${packDir}`);
} finally {
// Clean up temp file
await fs.promises.unlink(mpath.join(moduleDir, archiveName)).catch((e) => {
console.error(`Failed to clean up file: ${e}`);
});
}
}
/** Pack the extracted package into a new archive */
async function packArchive(moduleDir: string, archiveName: string, packDir: string): Promise<void> {
await execa('tar', ['czf', archiveName, '-C', packDir, 'package'], {
cwd: moduleDir,
});
}
const optScope = {
describe: 'The new scope to set',
type: 'string',
default: '@bitgo-beta',
} as const;
yargs
.command({
command: 'pack-scoped <dir>',
describe: [
'Pack a module with a specific scope. ',
`Creates a package archive with the scope set to the specified value. `,
].join(''),
builder(yargs) {
return yargs
.positional('dir', {
describe: 'Module directory',
type: 'string',
demandOption: true,
})
.options({
scope: optScope,
distTagsFrom: {
describe: 'Path to a file to read dist tags from',
type: 'string',
},
});
},
async handler({ dir, scope, distTagsFrom }) {
const lernaModules = await getLernaModules();
const module = getModuleByDir(lernaModules, dir);
const archiveName = getArchiveName(module);
await packExtract(dir, archiveName, scopedPackageDir);
await runChangeScope(mpath.join(dir, scopedPackageDir, 'package'), {
scope,
lernaModules,
distTagsFrom,
cacheDistTags: mpath.join(dir, scopedPackageDir, '.distTags.cache.json'),
});
await packArchive(dir, archiveName, scopedPackageDir);
console.log(`Packed ${getNewModuleName(module.name, scope)} to ${mpath.join(dir, archiveName)}.`);
console.log(`Use 'npm install ${mpath.join(dir, archiveName)} --no-save' to test the package.`);
},
})
.command({
// Low-level command to the scope of a module for a directory without packing it. Useful for testing
command: 'change-scope <dir>',
describe: false,
builder(yargs) {
return yargs
.positional('dir', {
describe: 'Module directory',
type: 'string',
demandOption: true,
})
.option({
scope: optScope,
});
},
async handler({ dir, scope }) {
await runChangeScope(dir, { scope });
},
})
.help()
.strict().argv;
Выполнить команду
Для локальной разработки. Не используйте в интернете!