vcpkg-tool/vcpkg-artifacts/vcpkg.ts

81 строка
2.9 KiB
TypeScript
Исходник Обычный вид История

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { spawn } from 'child_process';
import { i } from './i18n';
import { DownloadEvents } from './interfaces/events';
import { Session } from './session';
import { Uri } from './util/uri';
function streamVcpkg(vcpkgCommand: string | undefined, args: Array<string>, listener: (chunk: any) => void): Promise<void> {
return new Promise((accept, reject) => {
if (!vcpkgCommand) {
reject(i`VCPKG_COMMAND was not set`);
return;
}
const subproc = spawn(vcpkgCommand, args, { stdio: ['ignore', 'pipe', 'pipe'] });
subproc.stdout.on('data', listener);
subproc.stderr.pipe(process.stdout);
subproc.on('error', (err) => { reject(err); });
subproc.on('close', (code: number, signal) => {
if (code === 0) { accept(); }
reject(i`Running vcpkg internally returned a nonzero exit code: ${code}`);
});
});
}
async function runVcpkg(vcpkgCommand: string | undefined, args: Array<string>): Promise<string> {
let result = '';
await streamVcpkg(vcpkgCommand, args, (chunk) => { result += chunk; });
return result.trimEnd();
}
export function vcpkgFetch(session: Session, fetchKey: string): Promise<string> {
return runVcpkg(session.vcpkgCommand, ['fetch', fetchKey, '--x-stderr-status']).then((output) => {
return output;
}, (error) => {
if (fetchKey === 'git') {
session.channels.warning('failed to fetch git, falling back to attempting to use git from the PATH');
return Promise.resolve('git');
}
return Promise.reject(error);
});
}
Add z-extract command / artifacts uses z-extract (#1039) * Make commands physical design consistent. In the vcpkg technical review meeting today we said: * We want commands.Xxx.cpp for every "vcpkg Xxx" subcommand, rather than Xxx.cpp. * We want x- commands to not have the x in their code names or x- in their file names, and z- commands have the z in their code names and z- in their file names. * Command cpps have dashes. Drive by fixes as part of this audit: * FooCommand structs are gone, all users were stateless and are better served by plain function pointers. This also allows the command tables to be constexpr. * commands.interface.h is dead, as it only existed to declare those structs that are dead. Future changes: * I really want all the Commands::Xxx and the commands namespace itself to go away. But ran out of time to sell this to the team. * Xxx::COMMAND_STRUCTURE => XxxCommandMetadata * Xxx::perform_and_exit => xxx_command_and_exit Notes: build, install, and export probably deserve to have functionality split out, but that would probably be intricate so I have not attempted to do it here. export.*.cpp seem like they *really* shouldn't be separate .cpps. * Missed some _command s. * wip * wip * format * minimal impl * add .xz * Add help text for command * vcpkg-artifacts uses x-extract * format * oops * x-extract -> z-extract * rename extract_archive_to_empty -> extract_archive and rename the old extract_archive to set_directory_to_archive_content * fix comment * wip * add strip setting * add strip option localized message * format * wip * Add testing for strip mapping * add --extract-type option to bypass file extension detection * format * wip * test * wip * wip * wip * forward slash delim for non-windows * wip * try again * maybe fix paths for non-windows * use generic_Xxx * use + instead of / * convert back to path * use appropriate path separators in test * set VCPKG_COMMAND env variable * set VCPKG_COMMAND * set VCPKG_COMMAND in yaml * wip * use matrix.preset * remove archive unit test from artifacts * debug * const everything * create destination if it does not exist * use fsPath instead * bug fixes and remove installers * fix end-to-end check * wip * wip * debug messages * fix strip for macos and linux * print output * wip * cleanup * format * rename to command_extract_and_exit as per convention * response to feedback * remove the extract-type option and just fall back to cmake * fix strip_map to proper behavior, better temp dir handling, etc * fix unit tests * for real this time * wip * wip * reuse logic for is_slash functionality * oops * testing * test * testing * verify problem * try this * fix * use Strings::strto<int> instead of std::stoi * add AUTO option + unit test * add strip=AUTO * switch artifacts to use strip=AUTO * format * cleanup * fix compiler warnings * fix conversion * format * remove magic -1, respond to feedback, format * update localized messages * add e2e * test executable bits on non-windows * oops * better naming * try this * update end2end * for real this time * verify file exists * print UnixMode * oops * fix indentation * look for the right unixMode * Simplify tests. * Delete unreferenced test assets, add archive start events back. * remove = from #define * format * minor fix * Fix casing for enum class * rename strip_map and get_common_prefix_count and add minimum documentation * wip * missed a couple renames * rename test folder from "archive" to "folder0" * remove then from artifact caller * some structural changes * enforce relationship between stripMode and stripCount * use files is_slash * check strip option is >=0 * format * minor refactoring * remove empty entries from get_archive_deploy_operations * minor refactor * adds testing for guess_extraction_type and get_strip_setting * add testing for get_strip_setting * minor feedback --------- Co-authored-by: Billy Robert O'Neal III <bion@microsoft.com>
2023-08-01 01:54:26 +03:00
export async function vcpkgExtract(session: Session, archive: string, target:string, strip:string): Promise<string> {
return runVcpkg(session.vcpkgCommand, ['z-extract', archive, target, strip]);
}
export async function vcpkgDownload(session: Session, destination: string, sha512: string | undefined, uris: Array<Uri>, events: Partial<DownloadEvents>) : Promise<void> {
const args = ['x-download', destination, '--z-machine-readable-progress'];
if (sha512) {
args.push(`--sha512=${sha512}`);
} else {
args.push('--skip-sha512');
}
for (const uri of uris) {
events.downloadProgress?.(uri, destination, 0);
const uriArgs = [...args, `--url=${uri.toString()}`];
try {
await streamVcpkg(session.vcpkgCommand, uriArgs, (chunk) => {
const match = /(\d+)(\.\d+)?%\s*$/.exec(chunk);
if (!match) { return; }
const number = parseFloat(match[1]);
// throwing out 100s avoids displaying temporarily full progress bars resulting from redirects getting resolved
if (number && number < 100) {
events.downloadProgress?.(uri, destination, number);
}
});
return;
} catch {
session.channels.warning(i`failed to download from ${uri.toString()}`);
}
}
throw new Error(i`failed to download ${destination} from any source`);
}