[vcpkg-artifacts] Find git using `vcpkg fetch git`. (#569)

* Fix x-regenerate to forward the path to the registry to ce correctly.

I wrote this forwarder to what ce's documentation said: --registry to point to the registry. But that command on the ce side just accepts the first parameter as the path to the registry, so the mapping was wrong.

Also moves handling of --debug into the common bits.

* Spell check. :)

* Delete --from-vcpkg and use VCPKG_COMMAND instead.

* Add --x-stderr-status to vcpkg fetch, which sends all status/downloading messages to stderr rather than stdout. Note that error messages still go to stdout.

Get the path to git by running `vcpkg fetch`

* Fix *nix build.

* Remove unused variables

* Pipe fetch's stderr to our stdout.

* Use the rejection channel for fetch failure.

* Make the MessageSink implementations static.

* Add smoke test doc.

* eslint
This commit is contained in:
Billy O'Neal 2022-06-06 15:53:59 -07:00 коммит произвёл GitHub
Родитель 1f792fe344
Коммит b521efb230
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
29 изменённых файлов: 410 добавлений и 198 удалений

Просмотреть файл

@ -32,7 +32,7 @@ export class Git {
* @param events The events that may need to be updated in order to track progress.
* @param options The options that will modify how the clone will be called.
* @returns Boolean representing whether the execution was completed without error, this is not necessarily
* a gaurantee that the clone did what we expected.
* a guarantee that the clone did what we expected.
*/
async clone(repo: Uri, events: Partial<InstallEvents>, options: { recursive?: boolean, depth?: number } = {}) {
const remote = await isFilePath(repo) ? repo.fsPath : repo.toString();
@ -72,7 +72,7 @@ export class Git {
* @param events Events that may be called in order to present progress.
* @param options Options to modify how fetch is called.
* @returns Boolean representing whether the execution was completed without error, this is not necessarily
* a gaurantee that the fetch did what we expected.
* a guarantee that the fetch did what we expected.
*/
async fetch(remoteName: string, events: Partial<InstallEvents>, options: { commit?: string, recursive?: boolean, depth?: number } = {}) {
const result = await execute(this.#toolPath, [
@ -100,7 +100,7 @@ export class Git {
* @param events Events to possibly track progress.
* @param options Passing along a commit or branch to checkout, optionally.
* @returns Boolean representing whether the execution was completed without error, this is not necessarily
* a gaurantee that the checkout did what we expected.
* a guarantee that the checkout did what we expected.
*/
async checkout(events: Partial<InstallEvents>, options: { commit?: string } = {}) {
const result = await execute(this.#toolPath, [
@ -124,7 +124,7 @@ export class Git {
* @param events Events to possibly track progress.
* @param options Options to control how the reset is called.
* @returns Boolean representing whether the execution was completed without error, this is not necessarily
* a gaurantee that the reset did what we expected.
* a guarantee that the reset did what we expected.
*/
async reset(events: Partial<InstallEvents>, options: { commit?: string, recurse?: boolean, hard?: boolean } = {}) {
const result = await execute(this.#toolPath, [

Просмотреть файл

@ -422,7 +422,7 @@ export class Activation {
return `$${obj}.${member}`;
}
this.#session.channels.debug(i`Unresolved varible reference found ($${obj}.${member}) during variable substitution.`);
this.#session.channels.debug(i`Unresolved variable reference found ($${obj}.${member}) during variable substitution.`);
return `$${obj}.${member}`;
}
@ -764,4 +764,4 @@ async function toArrayAsync<T>(iterable: AsyncIterable<T>) {
result.push(item);
}
return result;
}
}

Просмотреть файл

@ -96,6 +96,13 @@ export class CommandLine {
join(process.env['HOME'] || process.env['USERPROFILE'] || tmpdir(), '.vcpkg')));
}
#vcpkgCommand?: string;
get vcpkgCommand() {
return this.#vcpkgCommand || (this.#vcpkgCommand = resolvePath(
this.switches['vcpkg-command']?.[0] ||
process.env['VCPKG_COMMAND']));
}
get force() {
return !!this.switches['force'];
}
@ -108,10 +115,6 @@ export class CommandLine {
return !!this.switches['verbose'];
}
get fromVCPKG() {
return !!this.switches['from-vcpkg'];
}
get language() {
const l = this.switches['language'] || [];
strict.ok((l?.length || 0) < 2, i`Expected a single value for ${cmdSwitch('language')} - found multiple`);

Просмотреть файл

@ -2,7 +2,7 @@
// Licensed under the MIT License.
export const undo = 'Z_VCPKG_UNDO';
export const postscriptVarible = 'Z_VCPKG_POSTSCRIPT';
export const postscriptVariable = 'Z_VCPKG_POSTSCRIPT';
export const blank = '\n';
export const latestVersion = '*';
export const vcpkgDownloadFolder = 'VCPKG_DOWNLOADS';

Просмотреть файл

@ -7,11 +7,12 @@ import { InstallEvents, InstallOptions } from '../interfaces/events';
import { CloneSettings, GitInstaller } from '../interfaces/metadata/installers/git';
import { Session } from '../session';
import { Uri } from '../util/uri';
import { Vcpkg } from '../vcpkg';
export async function installGit(session: Session, name: string, targetLocation: Uri, install: GitInstaller, events: Partial<InstallEvents>, options: Partial<InstallOptions & CloneOptions & CloneSettings>): Promise<void> {
// const gitPath = await session.activation.getAlias('git');
const gitPath = '';
const vcpkg = new Vcpkg(session);
const gitPath = await vcpkg.fetch('git');
if (!gitPath) {
throw new Error(i`Git is not installed`);

Просмотреть файл

@ -39,7 +39,7 @@ const commandline = new CommandLine(argv.slice(2));
setLocale(commandline.language, `${__dirname}/i18n/`);
function header() {
if (!commandline.fromVCPKG) {
if (!commandline.vcpkgCommand) {
if (commandline.debug) {
// eslint-disable-next-line @typescript-eslint/no-var-requires
log(`${green.bold(`${product} command line utility`)} ${white.bold(cliVersion)} [node: ${white.bold(process.version)}; max-memory: ${white.bold(Math.round((require('v8').getHeapStatistics().heap_size_limit) / (1024 * 1024)) & 0xffffffff00)} gb]`);

Просмотреть файл

@ -7,7 +7,7 @@ import { MetadataFile } from './amf/metadata-file';
import { Activation, deactivate } from './artifacts/activation';
import { Artifact, InstalledArtifact } from './artifacts/artifact';
import { Registry } from './artifacts/registry';
import { defaultConfig, globalConfigurationFile, postscriptVarible, profileNames, registryIndexFile, undo, vcpkgDownloadFolder } from './constants';
import { defaultConfig, globalConfigurationFile, postscriptVariable, profileNames, registryIndexFile, undo, vcpkgDownloadFolder } from './constants';
import { FileSystem, FileType } from './fs/filesystem';
import { HttpsFileSystem } from './fs/http-filesystem';
import { LocalFileSystem } from './fs/local-filesystem';
@ -71,6 +71,7 @@ export class Session {
readonly tmpFolder: Uri;
readonly installFolder: Uri;
readonly registryFolder: Uri;
readonly vcpkgCommand?: string;
readonly activation: Activation = new Activation(this);
readonly globalConfig: Uri;
@ -106,6 +107,8 @@ export class Session {
this.cache = this.environment[vcpkgDownloadFolder] ? this.parseUri(this.environment[vcpkgDownloadFolder]!) : this.homeFolder.join('downloads');
this.globalConfig = this.homeFolder.join(globalConfigurationFile);
this.vcpkgCommand = settings['vcpkgCommand'];
this.tmpFolder = this.homeFolder.join('tmp');
this.installFolder = this.homeFolder.join('artifacts');
@ -250,7 +253,7 @@ export class Session {
#postscriptFile?: Uri;
get postscriptFile() {
return this.#postscriptFile || (this.#postscriptFile = this.environment[postscriptVarible] ? this.fileSystem.file(this.environment[postscriptVarible]!) : undefined);
return this.#postscriptFile || (this.#postscriptFile = this.environment[postscriptVariable] ? this.fileSystem.file(this.environment[postscriptVariable]!) : undefined);
}
async init() {

43
ce/ce/vcpkg.ts Normal file
Просмотреть файл

@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { spawn } from 'child_process';
import { i } from './i18n';
import { Session } from './session';
/** @internal */
export class Vcpkg {
constructor(private readonly session: Session) { }
fetch(fetchKey: string): Promise<string> {
return this.runVcpkg(['fetch', fetchKey, '--x-stderr-status']).then((output) => {
return output.trimEnd();
}, (error) => {
if (fetchKey === 'git') {
this.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);
});
}
private runVcpkg(args: Array<string>): Promise<string> {
return new Promise((accept, reject) => {
if (!this.session.vcpkgCommand) {
reject(i`VCPKG_COMMAND was not set`);
return;
}
const subproc = spawn(this.session.vcpkgCommand, args, { stdio: ['ignore', 'pipe', 'pipe'] });
let result = '';
subproc.stdout.on('data', (chunk) => { result += chunk; });
subproc.stderr.pipe(process.stdout);
subproc.on('error', (err) => { reject(err); });
subproc.on('close', (code: number, signal) => {
if (code === 0) { accept(result); }
reject(i`Running vcpkg internally returned a nonzero exit code: ${code}`);
});
});
}
}

Просмотреть файл

@ -16,20 +16,26 @@ namespace vcpkg
// Extract `archive` to `to_path` using `cmake_tool`. (CMake's built in tar)
void extract_tar_cmake(const Path& cmake_tool, const Path& archive, const Path& to_path);
// Extract `archive` to `to_path`, deleting `to_path` first.
void extract_archive(Filesystem& fs, const ToolCache& tools, const Path& archive, const Path& to_path);
void extract_archive(
Filesystem& fs, const ToolCache& tools, MessageSink& status_sink, const Path& archive, const Path& to_path);
#ifdef _WIN32
// Extract the 7z archive part of a self extracting 7z installer
void win32_extract_self_extracting_7z(Filesystem& fs, const Path& archive, const Path& to_path);
// Extract `archive` to `to_path`, deleting `to_path` first. `archive` must be a zip file.
// This function will use potentially less performant tools that are reliably available on any machine.
void win32_extract_bootstrap_zip(Filesystem& fs, const ToolCache& tools, const Path& archive, const Path& to_path);
void win32_extract_bootstrap_zip(
Filesystem& fs, const ToolCache& tools, MessageSink& status_sink, const Path& archive, const Path& to_path);
#endif
// Compress the source directory into the destination file.
int compress_directory_to_zip(Filesystem& fs, const ToolCache& tools, const Path& source, const Path& destination);
int compress_directory_to_zip(
Filesystem& fs, const ToolCache& tools, MessageSink& status_sink, const Path& source, const Path& destination);
Command decompress_zip_archive_cmd(const ToolCache& tools, const Path& dst, const Path& archive_path);
Command decompress_zip_archive_cmd(const ToolCache& tools,
MessageSink& status_sink,
const Path& dst,
const Path& archive_path);
std::vector<ExitCodeAndOutput> decompress_in_parallel(View<Command> jobs);
}

Просмотреть файл

@ -23,9 +23,11 @@ namespace vcpkg
#endif
struct LocalizedString;
struct MessageSink;
}
namespace vcpkg::msg
{
void write_unlocalized_text_to_stdout(Color c, vcpkg::StringView sv);
void write_unlocalized_text_to_stderr(Color c, vcpkg::StringView sv);
}

Просмотреть файл

@ -205,23 +205,23 @@ namespace vcpkg::msg
}
template<class Message, class... Ts>
void print(Message m, Ts... args)
typename Message::is_message_type print(Message m, Ts... args)
{
print(format(m, args...));
}
template<class Message, class... Ts>
void println(Message m, Ts... args)
typename Message::is_message_type println(Message m, Ts... args)
{
print(format(m, args...).append_raw('\n'));
}
template<class Message, class... Ts>
void print(Color c, Message m, Ts... args)
typename Message::is_message_type print(Color c, Message m, Ts... args)
{
print(c, format(m, args...));
}
template<class Message, class... Ts>
void println(Color c, Message m, Ts... args)
typename Message::is_message_type println(Color c, Message m, Ts... args)
{
print(c, format(m, args...).append_raw('\n'));
}
@ -340,4 +340,60 @@ namespace vcpkg::msg
{
return format(msgErrorMessage).append(m, args...);
}
}
namespace vcpkg
{
struct MessageSink
{
virtual void print(Color c, StringView sv) = 0;
void println() { this->print(Color::none, "\n"); }
void print(const LocalizedString& s) { this->print(Color::none, s); }
void println(Color c, const LocalizedString& s)
{
this->print(c, s);
this->print(Color::none, "\n");
}
inline void println(const LocalizedString& s)
{
this->print(Color::none, s);
this->print(Color::none, "\n");
}
template<class Message, class... Ts>
typename Message::is_message_type print(Message m, Ts... args)
{
this->print(Color::none, msg::format(m, args...));
}
template<class Message, class... Ts>
typename Message::is_message_type println(Message m, Ts... args)
{
this->print(Color::none, msg::format(m, args...).append_raw('\n'));
}
template<class Message, class... Ts>
typename Message::is_message_type print(Color c, Message m, Ts... args)
{
this->print(c, msg::format(m, args...));
}
template<class Message, class... Ts>
typename Message::is_message_type println(Color c, Message m, Ts... args)
{
this->print(c, msg::format(m, args...).append_raw('\n'));
}
MessageSink(const MessageSink&) = delete;
MessageSink& operator=(const MessageSink&) = delete;
protected:
MessageSink() = default;
~MessageSink() = default;
};
extern MessageSink& stdout_sink;
extern MessageSink& stderr_sink;
}

Просмотреть файл

@ -39,8 +39,8 @@ namespace vcpkg
{
virtual ~ToolCache() = default;
virtual const Path& get_tool_path(StringView tool) const = 0;
virtual const std::string& get_tool_version(StringView tool) const = 0;
virtual const Path& get_tool_path(StringView tool, MessageSink& status_sink) const = 0;
virtual const std::string& get_tool_version(StringView tool, MessageSink& status_sink) const = 0;
};
ExpectedS<std::string> extract_prefixed_nonwhitespace(StringLiteral prefix,

Просмотреть файл

@ -129,8 +129,8 @@ namespace vcpkg
std::string get_toolver_diagnostics() const;
const ToolCache& get_tool_cache() const;
const Path& get_tool_exe(StringView tool) const;
const std::string& get_tool_version(StringView tool) const;
const Path& get_tool_exe(StringView tool, MessageSink& status_messages) const;
const std::string& get_tool_version(StringView tool, MessageSink& status_messages) const;
GitConfig git_builtin_config() const;
Command git_cmd_builder(const Path& dot_git_dir, const Path& work_tree) const;

Просмотреть файл

@ -0,0 +1,31 @@
1. Build `vcpkg-tool`. Set `VCPKG_COMMAND` to the built bits. For example:
$env:VCPKG_COMMAND="C:\Dev\vcpkg-tool\out\build\x64-Release\vcpkg.exe"
2. Set `VCPKG_ROOT` to a vcpkg root. For example:
$env:VCPKG_ROOT="C:\Dev\vcpkg"
3. `cd ce && rush update && rush rebuild`
4. Go to your normal dev directory or similar and `git clone https://github.com/raspberrypi/pico-examples`
5. `cd` to that clone and copy this `vcpkg-configuration.json` there:
```
{
"registries": [
{
"name": "test",
"location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/metadata-changes.zip",
"kind": "artifact"
}
],
"requires": {
"test:compilers/arm/gcc": "2020.10.0",
"test:raspberrypi/pico-sdk": "* 1.3.0",
"test:tools/kitware/cmake": "3.20.1",
"test:tools/microsoft/openocd": "* 0.11.0"
}
}
```
6. Run `C:\Path\To\vcpkg-tool\ce\ce.ps1 activate`

Просмотреть файл

@ -23,9 +23,9 @@ namespace
"Could not deduce nuget id and version from filename: {path}");
#if defined(_WIN32)
void win32_extract_nupkg(const ToolCache& tools, const Path& archive, const Path& to_path)
void win32_extract_nupkg(const ToolCache& tools, MessageSink& status_sink, const Path& archive, const Path& to_path)
{
const auto nuget_exe = tools.get_tool_path(Tools::NUGET);
const auto nuget_exe = tools.get_tool_path(Tools::NUGET, status_sink);
const auto stem = archive.stem();
@ -133,13 +133,14 @@ namespace
}
#endif // ^^^ _WIN32
void extract_archive_to_empty(Filesystem& fs, const ToolCache& tools, const Path& archive, const Path& to_path)
void extract_archive_to_empty(
Filesystem& fs, const ToolCache& tools, MessageSink& status_sink, const Path& archive, const Path& to_path)
{
const auto ext = archive.extension();
#if defined(_WIN32)
if (Strings::case_insensitive_ascii_equals(ext, ".nupkg"))
{
win32_extract_nupkg(tools, archive, to_path);
win32_extract_nupkg(tools, status_sink, archive, to_path);
}
else if (Strings::case_insensitive_ascii_equals(ext, ".msi"))
{
@ -148,7 +149,7 @@ namespace
else if (Strings::case_insensitive_ascii_equals(ext, ".zip") ||
Strings::case_insensitive_ascii_equals(ext, ".7z"))
{
extract_tar_cmake(tools.get_tool_path(Tools::CMAKE), archive, to_path);
extract_tar_cmake(tools.get_tool_path(Tools::CMAKE, status_sink), archive, to_path);
}
else if (Strings::case_insensitive_ascii_equals(ext, ".exe"))
{
@ -156,7 +157,7 @@ namespace
const Path stem = filename.stem();
const Path to_archive = Path(archive.parent_path()) / stem;
win32_extract_self_extracting_7z(fs, archive, to_archive);
extract_archive_to_empty(fs, tools, to_archive, to_path);
extract_archive_to_empty(fs, tools, status_sink, to_archive, to_path);
}
#else
(void)fs;
@ -169,7 +170,7 @@ namespace
#endif
else if (ext == ".gz" || ext == ".bz2" || ext == ".tgz")
{
vcpkg::extract_tar(tools.get_tool_path(Tools::TAR), archive, to_path);
vcpkg::extract_tar(tools.get_tool_path(Tools::TAR, status_sink), archive, to_path);
}
else
{
@ -177,10 +178,8 @@ namespace
}
}
Path extract_archive_to_temp_subdirectory(Filesystem& fs,
const ToolCache& tools,
const Path& archive,
const Path& to_path)
Path extract_archive_to_temp_subdirectory(
Filesystem& fs, const ToolCache& tools, MessageSink& status_sink, const Path& archive, const Path& to_path)
{
Path to_path_partial = to_path + ".partial";
#if defined(_WIN32)
@ -189,7 +188,7 @@ namespace
fs.remove_all(to_path_partial, VCPKG_LINE_INFO);
fs.create_directories(to_path_partial, VCPKG_LINE_INFO);
extract_archive_to_empty(fs, tools, archive, to_path_partial);
extract_archive_to_empty(fs, tools, status_sink, archive, to_path_partial);
return to_path_partial;
}
}
@ -218,7 +217,8 @@ namespace vcpkg
fs.write_contents(to_path, std::move(contents), VCPKG_LINE_INFO);
}
void win32_extract_bootstrap_zip(Filesystem& fs, const ToolCache& tools, const Path& archive, const Path& to_path)
void win32_extract_bootstrap_zip(
Filesystem& fs, const ToolCache& tools, MessageSink& status_sink, const Path& archive, const Path& to_path)
{
fs.remove_all(to_path, VCPKG_LINE_INFO);
Path to_path_partial = to_path + ".partial." + std::to_string(GetCurrentProcessId());
@ -240,7 +240,8 @@ namespace vcpkg
// Example:
// msiexec unpacks 7zip_msi unpacks cmake unpacks 7zip unpacks git
win32_extract_with_seven_zip(tools.get_tool_path(Tools::SEVEN_ZIP_MSI), archive, to_path_partial);
win32_extract_with_seven_zip(
tools.get_tool_path(Tools::SEVEN_ZIP_MSI, status_sink), archive, to_path_partial);
}
fs.rename_with_retry(to_path_partial, to_path, VCPKG_LINE_INFO);
}
@ -262,18 +263,20 @@ namespace vcpkg
Checks::check_exit(VCPKG_LINE_INFO, code == 0, "CMake failed while extracting %s", archive);
}
void extract_archive(Filesystem& fs, const ToolCache& tools, const Path& archive, const Path& to_path)
void extract_archive(
Filesystem& fs, const ToolCache& tools, MessageSink& status_sink, const Path& archive, const Path& to_path)
{
fs.remove_all(to_path, VCPKG_LINE_INFO);
Path to_path_partial = extract_archive_to_temp_subdirectory(fs, tools, archive, to_path);
Path to_path_partial = extract_archive_to_temp_subdirectory(fs, tools, status_sink, archive, to_path);
fs.rename_with_retry(to_path_partial, to_path, VCPKG_LINE_INFO);
}
int compress_directory_to_zip(Filesystem& fs, const ToolCache& tools, const Path& source, const Path& destination)
int compress_directory_to_zip(
Filesystem& fs, const ToolCache& tools, MessageSink& status_sink, const Path& source, const Path& destination)
{
fs.remove(destination, VCPKG_LINE_INFO);
#if defined(_WIN32)
auto&& seven_zip_exe = tools.get_tool_path(Tools::SEVEN_ZIP);
auto&& seven_zip_exe = tools.get_tool_path(Tools::SEVEN_ZIP, status_sink);
return cmd_execute_and_capture_output(
Command{seven_zip_exe}.string_arg("a").string_arg(destination).string_arg(source / "*"),
@ -283,6 +286,7 @@ namespace vcpkg
#else
(void)tools;
(void)status_sink;
return cmd_execute_clean(Command{"zip"}
.string_arg("--quiet")
.string_arg("-y")
@ -295,11 +299,14 @@ namespace vcpkg
#endif
}
Command decompress_zip_archive_cmd(const ToolCache& tools, const Path& dst, const Path& archive_path)
Command decompress_zip_archive_cmd(const ToolCache& tools,
MessageSink& status_sink,
const Path& dst,
const Path& archive_path)
{
Command cmd;
#if defined(_WIN32)
auto&& seven_zip_exe = tools.get_tool_path(Tools::SEVEN_ZIP);
auto&& seven_zip_exe = tools.get_tool_path(Tools::SEVEN_ZIP, status_sink);
cmd.string_arg(seven_zip_exe)
.string_arg("x")
.string_arg(archive_path)
@ -307,6 +314,7 @@ namespace vcpkg
.string_arg("-y");
#else
(void)tools;
(void)status_sink;
cmd.string_arg("unzip").string_arg("-qq").string_arg(archive_path).string_arg("-d" + dst.native());
#endif
return cmd;

Просмотреть файл

@ -2,6 +2,8 @@
#include <vcpkg/base/messages.h>
#include <vcpkg/base/system.debug.h>
using namespace vcpkg;
namespace vcpkg::msg
{
DECLARE_AND_REGISTER_MESSAGE(NoLocalizationForMessages, (), "", "No localization for the following messages:");
@ -34,22 +36,19 @@ namespace vcpkg::msg
}
static DWORD size_to_write(::size_t size) { return size > MAXDWORD ? MAXDWORD : static_cast<DWORD>(size); }
void write_unlocalized_text_to_stdout(Color c, StringView sv)
static void write_unlocalized_text_impl(Color c, StringView sv, HANDLE the_handle, bool is_console)
{
if (sv.empty()) return;
static const HANDLE stdout_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
static const bool stdout_is_console = is_console(stdout_handle);
if (stdout_is_console)
if (is_console)
{
WORD original_color = 0;
if (c != Color::none)
{
CONSOLE_SCREEN_BUFFER_INFO console_screen_buffer_info{};
::GetConsoleScreenBufferInfo(stdout_handle, &console_screen_buffer_info);
::GetConsoleScreenBufferInfo(the_handle, &console_screen_buffer_info);
original_color = console_screen_buffer_info.wAttributes;
::SetConsoleTextAttribute(stdout_handle, static_cast<WORD>(c) | (original_color & 0xF0));
::SetConsoleTextAttribute(the_handle, static_cast<WORD>(c) | (original_color & 0xF0));
}
auto as_wstr = Strings::to_utf16(sv);
@ -60,14 +59,14 @@ namespace vcpkg::msg
while (size != 0)
{
DWORD written = 0;
check_write(::WriteConsoleW(stdout_handle, pointer, size_to_write(size), &written, nullptr));
check_write(::WriteConsoleW(the_handle, pointer, size_to_write(size), &written, nullptr));
pointer += written;
size -= written;
}
if (c != Color::none)
{
::SetConsoleTextAttribute(stdout_handle, original_color);
::SetConsoleTextAttribute(the_handle, original_color);
}
}
else
@ -78,18 +77,32 @@ namespace vcpkg::msg
while (size != 0)
{
DWORD written = 0;
check_write(::WriteFile(stdout_handle, pointer, size_to_write(size), &written, nullptr));
check_write(::WriteFile(the_handle, pointer, size_to_write(size), &written, nullptr));
pointer += written;
size -= written;
}
}
}
void write_unlocalized_text_to_stdout(Color c, StringView sv)
{
static const HANDLE stdout_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
static const bool stdout_is_console = is_console(stdout_handle);
return write_unlocalized_text_impl(c, sv, stdout_handle, stdout_is_console);
}
void write_unlocalized_text_to_stderr(Color c, StringView sv)
{
static const HANDLE stderr_handle = ::GetStdHandle(STD_ERROR_HANDLE);
static const bool stderr_is_console = is_console(stderr_handle);
return write_unlocalized_text_impl(c, sv, stderr_handle, stderr_is_console);
}
#else
static void write_all(const char* ptr, size_t to_write)
static void write_all(const char* ptr, size_t to_write, int fd)
{
while (to_write != 0)
{
auto written = ::write(STDOUT_FILENO, ptr, to_write);
auto written = ::write(fd, ptr, to_write);
if (written == -1)
{
::fprintf(stderr, "[DEBUG] Failed to print to stdout: %d\n", errno);
@ -100,30 +113,40 @@ namespace vcpkg::msg
}
}
void write_unlocalized_text_to_stdout(Color c, StringView sv)
static void write_unlocalized_text_impl(Color c, StringView sv, int fd, bool is_a_tty)
{
static constexpr char reset_color_sequence[] = {'\033', '[', '0', 'm'};
if (sv.empty()) return;
static bool is_a_tty = ::isatty(STDOUT_FILENO);
bool reset_color = false;
if (is_a_tty && c != Color::none)
{
reset_color = true;
const char set_color_sequence[] = {'\033', '[', '9', static_cast<char>(c), 'm'};
write_all(set_color_sequence, sizeof(set_color_sequence));
write_all(set_color_sequence, sizeof(set_color_sequence), fd);
}
write_all(sv.data(), sv.size());
write_all(sv.data(), sv.size(), fd);
if (reset_color)
{
write_all(reset_color_sequence, sizeof(reset_color_sequence));
write_all(reset_color_sequence, sizeof(reset_color_sequence), fd);
}
}
void write_unlocalized_text_to_stdout(Color c, StringView sv)
{
static bool is_a_tty = ::isatty(STDOUT_FILENO);
return write_unlocalized_text_impl(c, sv, STDOUT_FILENO, is_a_tty);
}
void write_unlocalized_text_to_stderr(Color c, StringView sv)
{
static bool is_a_tty = ::isatty(STDERR_FILENO);
return write_unlocalized_text_impl(c, sv, STDERR_FILENO, is_a_tty);
}
#endif
namespace
@ -353,3 +376,26 @@ namespace vcpkg::msg
print(Color::error, format(msgErrorMessage).append(s).append_raw('\n'));
}
}
namespace
{
struct StdOutMessageSink : MessageSink
{
virtual void print(Color c, StringView sv) override { msg::write_unlocalized_text_to_stdout(c, sv); }
};
StdOutMessageSink stdout_sink_instance;
struct StdErrMessageSink : MessageSink
{
virtual void print(Color c, StringView sv) override { msg::write_unlocalized_text_to_stderr(c, sv); }
};
StdErrMessageSink stderr_sink_instance;
}
namespace vcpkg
{
MessageSink& stdout_sink = stdout_sink_instance;
MessageSink& stderr_sink = stderr_sink_instance;
}

Просмотреть файл

@ -335,7 +335,8 @@ namespace
{
auto pkg_path = paths.package_dir(spec);
clean_prepare_dir(fs, pkg_path);
jobs.push_back(decompress_zip_archive_cmd(paths.get_tool_cache(), pkg_path, archive_path));
jobs.push_back(
decompress_zip_archive_cmd(paths.get_tool_cache(), stdout_sink, pkg_path, archive_path));
action_idxs.push_back(i);
archive_paths.push_back(std::move(archive_path));
}
@ -397,7 +398,8 @@ namespace
auto& fs = paths.get_filesystem();
const auto archive_subpath = make_archive_subpath(abi_tag);
const auto tmp_archive_path = make_temp_archive_path(paths.buildtrees(), spec);
int code = compress_directory_to_zip(fs, paths.get_tool_cache(), paths.package_dir(spec), tmp_archive_path);
int code = compress_directory_to_zip(
fs, paths.get_tool_cache(), stdout_sink, paths.package_dir(spec), tmp_archive_path);
if (code != 0)
{
vcpkg::print2(
@ -552,6 +554,7 @@ namespace
{
action_idxs.push_back(i);
jobs.push_back(decompress_zip_archive_cmd(paths.get_tool_cache(),
stdout_sink,
paths.package_dir(actions[url_indices[i]].spec),
url_paths[i].second));
}
@ -759,7 +762,7 @@ namespace
print2("Attempting to fetch ", attempts.size(), " packages from nuget.\n");
auto packages_config = paths.buildtrees() / "packages.config";
const auto& nuget_exe = paths.get_tool_exe("nuget");
const auto& nuget_exe = paths.get_tool_exe("nuget", stdout_sink);
std::vector<Command> cmdlines;
if (!m_read_sources.empty())
@ -767,7 +770,7 @@ namespace
// First check using all sources
Command cmdline;
#ifndef _WIN32
cmdline.string_arg(paths.get_tool_exe(Tools::MONO));
cmdline.string_arg(paths.get_tool_exe(Tools::MONO, stdout_sink));
#endif
cmdline.string_arg(nuget_exe)
.string_arg("install")
@ -800,7 +803,7 @@ namespace
// Then check using each config
Command cmdline;
#ifndef _WIN32
cmdline.string_arg(paths.get_tool_exe(Tools::MONO));
cmdline.string_arg(paths.get_tool_exe(Tools::MONO, stdout_sink));
#endif
cmdline.string_arg(nuget_exe)
.string_arg("install")
@ -892,10 +895,10 @@ namespace
fs.write_contents(
nuspec_path, generate_nuspec(paths.package_dir(spec), action, nuget_ref), VCPKG_LINE_INFO);
const auto& nuget_exe = paths.get_tool_exe("nuget");
const auto& nuget_exe = paths.get_tool_exe("nuget", stdout_sink);
Command cmdline;
#ifndef _WIN32
cmdline.string_arg(paths.get_tool_exe(Tools::MONO));
cmdline.string_arg(paths.get_tool_exe(Tools::MONO, stdout_sink));
#endif
cmdline.string_arg(nuget_exe)
.string_arg("pack")
@ -921,7 +924,7 @@ namespace
{
Command cmd;
#ifndef _WIN32
cmd.string_arg(paths.get_tool_exe(Tools::MONO));
cmd.string_arg(paths.get_tool_exe(Tools::MONO, stdout_sink));
#endif
cmd.string_arg(nuget_exe)
.string_arg("push")
@ -948,7 +951,7 @@ namespace
{
Command cmd;
#ifndef _WIN32
cmd.string_arg(paths.get_tool_exe(Tools::MONO));
cmd.string_arg(paths.get_tool_exe(Tools::MONO, stdout_sink));
#endif
cmd.string_arg(nuget_exe)
.string_arg("push")
@ -1046,7 +1049,7 @@ namespace
auto&& url_path = url_paths[idx];
if (!download_file(url_path.first, url_path.second)) continue;
jobs.push_back(decompress_zip_archive_cmd(
paths.get_tool_cache(), paths.package_dir(action.spec), url_path.second));
paths.get_tool_cache(), stdout_sink, paths.package_dir(action.spec), url_path.second));
idxs.push_back(idx);
}
@ -1088,7 +1091,7 @@ namespace
auto& spec = action.spec;
const auto tmp_archive_path = make_temp_archive_path(paths.buildtrees(), spec);
int code = compress_directory_to_zip(
paths.get_filesystem(), paths.get_tool_cache(), paths.package_dir(spec), tmp_archive_path);
paths.get_filesystem(), paths.get_tool_cache(), stdout_sink, paths.package_dir(spec), tmp_archive_path);
if (code != 0)
{
vcpkg::msg::println_warning(
@ -1167,7 +1170,7 @@ namespace
StringLiteral vendor() const override { return "GCS"; }
Command command() const { return Command{paths.get_tool_exe(Tools::GSUTIL)}; }
Command command() const { return Command{paths.get_tool_exe(Tools::GSUTIL, stdout_sink)}; }
bool stat(StringView url) const override
{
@ -1223,7 +1226,7 @@ namespace
StringLiteral vendor() const override { return "AWS"; }
Command command() const { return Command{paths.get_tool_exe(Tools::AWSCLI)}; }
Command command() const { return Command{paths.get_tool_exe(Tools::AWSCLI, stdout_sink)}; }
bool stat(StringView url) const override
{
@ -1297,7 +1300,7 @@ namespace
StringLiteral vendor() const override { return "COS"; }
Command command() const { return Command{paths.get_tool_exe(Tools::COSCLI)}; }
Command command() const { return Command{paths.get_tool_exe(Tools::COSCLI, stdout_sink)}; }
bool stat(StringView url) const override
{

Просмотреть файл

@ -645,7 +645,7 @@ namespace vcpkg::Build
});
return base_env.cmd_cache.get_lazy(build_env_cmd, [&]() {
const Path& powershell_exe_path = paths.get_tool_exe("powershell-core");
const Path& powershell_exe_path = paths.get_tool_exe("powershell-core", stdout_sink);
auto clean_env = get_modified_clean_environment(base_env.env_map, powershell_exe_path.parent_path());
if (build_env_cmd.empty())
return clean_env;
@ -804,7 +804,7 @@ namespace vcpkg::Build
{"VCPKG_PLATFORM_TOOLSET", toolset.version.c_str()},
});
// Make sure GIT could be found
const Path& git_exe_path = paths.get_tool_exe(Tools::GIT);
const Path& git_exe_path = paths.get_tool_exe(Tools::GIT, stdout_sink);
out_vars.push_back({"GIT", git_exe_path});
}
@ -911,7 +911,7 @@ namespace vcpkg::Build
if (action.build_options.download_tool == DownloadTool::ARIA2)
{
variables.push_back({"ARIA2", paths.get_tool_exe(Tools::ARIA2)});
variables.push_back({"ARIA2", paths.get_tool_exe(Tools::ARIA2, stdout_sink)});
}
for (auto cmake_arg : args.cmake_args)
@ -1306,11 +1306,11 @@ namespace vcpkg::Build
}
}
abi_tag_entries.emplace_back("cmake", paths.get_tool_version(Tools::CMAKE));
abi_tag_entries.emplace_back("cmake", paths.get_tool_version(Tools::CMAKE, stdout_sink));
// This #ifdef is mirrored in tools.cpp's PowershellProvider
#if defined(_WIN32)
abi_tag_entries.emplace_back("powershell", paths.get_tool_version("powershell-core"));
abi_tag_entries.emplace_back("powershell", paths.get_tool_version("powershell-core", stdout_sink));
#endif
auto& helpers = paths.get_cmake_script_hashes();

Просмотреть файл

@ -17,6 +17,6 @@ namespace vcpkg
local_variables.emplace_back("_VCPKG_INSTALLED_DIR", paths.installed().root());
local_variables.emplace_back("DOWNLOADS", paths.downloads);
local_variables.emplace_back("VCPKG_MANIFEST_INSTALL", "OFF");
return make_basic_cmake_cmd(paths.get_tool_exe(Tools::CMAKE), cmake_script, local_variables);
return make_basic_cmake_cmd(paths.get_tool_exe(Tools::CMAKE, stdout_sink), cmake_script, local_variables);
}
}

Просмотреть файл

@ -6,20 +6,25 @@
namespace vcpkg::Commands::Fetch
{
static constexpr CommandSwitch STDERR_STATUS = {
"x-stderr-status",
"Direct status/downloading messages to stderr rather than stdout. (Errors/failures still go to stdout)"};
const CommandStructure COMMAND_STRUCTURE = {
Strings::format("The argument should be a tool name\n%s", create_example_string("fetch cmake")),
1,
1,
{},
{{&STDERR_STATUS, 1}},
nullptr,
};
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths)
{
(void)args.parse_arguments(COMMAND_STRUCTURE);
const auto parsed = args.parse_arguments(COMMAND_STRUCTURE);
const bool stderr_status = Util::Sets::contains(parsed.switches, STDERR_STATUS.name);
const std::string tool = args.command_arguments[0];
const Path tool_path = paths.get_tool_exe(tool);
print2(tool_path, '\n');
const Path tool_path = paths.get_tool_exe(tool, stderr_status ? stderr_sink : stdout_sink);
msg::write_unlocalized_text_to_stdout(Color::none, tool_path.native() + '\n');
Checks::exit_success(VCPKG_LINE_INFO);
}

Просмотреть файл

@ -414,7 +414,7 @@ CMake projects should use: "-DCMAKE_TOOLCHAIN_FILE=%s"
{
auto& fs = paths.get_filesystem();
const Path& nuget_exe = paths.get_tool_exe(Tools::NUGET);
const Path& nuget_exe = paths.get_tool_exe(Tools::NUGET, stdout_sink);
const Path& buildsystems_dir = paths.buildsystems;
const auto tmp_dir = buildsystems_dir / "tmp";
@ -472,7 +472,7 @@ With a project open, go to Tools->NuGet Package Manager->Package Manager Console
static constexpr StringLiteral TITLE = "PowerShell Tab-Completion";
const auto script_path = paths.scripts / "addPoshVcpkgToPowershellProfile.ps1";
const auto& ps = paths.get_tool_exe("powershell-core");
const auto& ps = paths.get_tool_exe("powershell-core", stdout_sink);
auto cmd = Command(ps)
.string_arg("-NoProfile")
.string_arg("-ExecutionPolicy")

Просмотреть файл

@ -1,6 +1,5 @@
#include <vcpkg/base/basic_checks.h>
#include <vcpkg/base/stringview.h>
#include <vcpkg/base/system.debug.h>
#include <vcpkg/base/util.h>
#include <vcpkg/commands.regenerate.h>
@ -17,38 +16,19 @@ namespace
constexpr StringLiteral DRY_RUN = "dry-run";
constexpr StringLiteral FORCE = "force";
constexpr StringLiteral PROJECT = "project";
constexpr StringLiteral REGISTRY = "registry";
constexpr std::array<CommandSwitch, 2> command_switches = {{
{FORCE, "proceeds with the (potentially dangerous) action without confirmation"},
{DRY_RUN, "does not actually perform the action, shows only what would be done"},
}};
constexpr std::array<CommandSetting, 2> command_settings = {{
{PROJECT, "override the path to the project folder"},
{REGISTRY, "override the path to the registry"},
}};
static const CommandStructure command_structure = {
Strings::format("Regenerates an artifact registry.\n%s\n", create_example_string("x-regenerate")),
0,
0,
{command_switches, command_settings},
1,
1,
{command_switches},
nullptr,
};
static void forward_setting(std::vector<std::string>& forwarded_args,
const std::map<std::string, std::string, std::less<>>& settings,
StringLiteral name)
{
auto found_setting = settings.find(name);
if (found_setting != settings.end())
{
forwarded_args.push_back(Strings::concat("--", name));
forwarded_args.push_back(found_setting->second);
}
}
}
namespace vcpkg
@ -58,11 +38,6 @@ namespace vcpkg
std::vector<std::string> forwarded_args;
forwarded_args.push_back("regenerate");
const auto parsed = args.parse_arguments(command_structure);
if (Debug::g_debugging)
{
forwarded_args.push_back("--debug");
}
if (Util::Sets::contains(parsed.switches, FORCE))
{
forwarded_args.push_back("--force");
@ -73,9 +48,7 @@ namespace vcpkg
forwarded_args.push_back("--what-if");
}
forward_setting(forwarded_args, parsed.settings, PROJECT);
forward_setting(forwarded_args, parsed.settings, REGISTRY);
forwarded_args.push_back(args.command_arguments[0]);
Checks::exit_with_code(VCPKG_LINE_INFO, run_configure_environment_command(paths, forwarded_args));
}
}

Просмотреть файл

@ -1,5 +1,6 @@
#include <vcpkg/base/basic_checks.h>
#include <vcpkg/base/downloads.h>
#include <vcpkg/base/system.debug.h>
#include <vcpkg/base/system.print.h>
#include <vcpkg/base/system.process.h>
@ -72,7 +73,7 @@ namespace vcpkg
msg::println_warning(msgVcpkgCeIsExperimental);
auto& fs = paths.get_filesystem();
auto& download_manager = paths.get_download_manager();
auto node_path = paths.get_tool_exe(Tools::NODE);
auto node_path = paths.get_tool_exe(Tools::NODE, stdout_sink);
auto node_modules = paths.root / "node_modules";
auto ce_path = node_modules / "vcpkg-ce";
auto ce_sha_path = node_modules / "ce-sha.txt";
@ -115,7 +116,11 @@ namespace vcpkg
cmd_run.string_arg("--harmony");
cmd_run.string_arg(ce_path);
cmd_run.forwarded_args(args);
cmd_run.string_arg("--from-vcpkg");
if (Debug::g_debugging)
{
cmd_run.string_arg("--debug");
}
return cmd_execute(cmd_run, WorkingDirectory{paths.original_cwd});
}

Просмотреть файл

@ -160,7 +160,7 @@ if (Test-Path $installedDir)
const auto vcpkg_root_path = paths.root;
const auto raw_exported_dir_path = vcpkg_root_path / "chocolatey";
const auto exported_dir_path = vcpkg_root_path / "chocolatey_exports";
const Path& nuget_exe = paths.get_tool_exe(Tools::NUGET);
const Path& nuget_exe = paths.get_tool_exe(Tools::NUGET, stdout_sink);
fs.remove_all(raw_exported_dir_path, VCPKG_LINE_INFO);
fs.create_directory(raw_exported_dir_path, VCPKG_LINE_INFO);

Просмотреть файл

@ -168,9 +168,9 @@ namespace vcpkg::Export
// -NoDefaultExcludes is needed for ".vcpkg-root"
Command cmd;
#ifndef _WIN32
cmd.string_arg(paths.get_tool_exe(Tools::MONO));
cmd.string_arg(paths.get_tool_exe(Tools::MONO, stdout_sink));
#endif
cmd.string_arg(paths.get_tool_exe(Tools::NUGET))
cmd.string_arg(paths.get_tool_exe(Tools::NUGET, stdout_sink))
.string_arg("pack")
.string_arg(nuspec_file_path)
.string_arg("-OutputDirectory")
@ -225,7 +225,7 @@ namespace vcpkg::Export
const Path& output_dir,
const ArchiveFormat& format)
{
const Path& cmake_exe = paths.get_tool_exe(Tools::CMAKE);
const Path& cmake_exe = paths.get_tool_exe(Tools::CMAKE, stdout_sink);
const auto exported_dir_filename = raw_exported_dir.filename();
const auto exported_archive_filename = Strings::format("%s.%s", exported_dir_filename, format.extension());

Просмотреть файл

@ -320,7 +320,7 @@ namespace vcpkg::Export::IFW
Filesystem& fs = paths.get_filesystem();
const Path& installerbase_exe = paths.get_tool_exe(Tools::IFW_INSTALLER_BASE);
const Path& installerbase_exe = paths.get_tool_exe(Tools::IFW_INSTALLER_BASE, stdout_sink);
auto tempmaintenancetool_dir = ifw_packages_dir_path / "maintenance/data";
auto tempmaintenancetool = tempmaintenancetool_dir / "tempmaintenancetool.exe";
fs.create_directories(tempmaintenancetool_dir, VCPKG_LINE_INFO);
@ -354,7 +354,7 @@ namespace vcpkg::Export::IFW
void do_repository(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
{
Path repogen_exe = paths.get_tool_exe(Tools::IFW_INSTALLER_BASE);
Path repogen_exe = paths.get_tool_exe(Tools::IFW_INSTALLER_BASE, stdout_sink);
repogen_exe.replace_filename("repogen.exe");
const auto packages_dir = get_packages_dir_path(export_id, ifw_options, paths);
const auto repository_dir = get_repository_dir_path(export_id, ifw_options, paths);
@ -376,7 +376,7 @@ namespace vcpkg::Export::IFW
void do_installer(const std::string& export_id, const Options& ifw_options, const VcpkgPaths& paths)
{
Path binarycreator_exe = paths.get_tool_exe(Tools::IFW_INSTALLER_BASE);
Path binarycreator_exe = paths.get_tool_exe(Tools::IFW_INSTALLER_BASE, stdout_sink);
binarycreator_exe.replace_filename("binarycreator.exe");
const auto config_file = get_config_file_path(export_id, ifw_options, paths);
const auto packages_dir = get_packages_dir_path(export_id, ifw_options, paths);

Просмотреть файл

@ -636,11 +636,13 @@ namespace vcpkg::Export::Prefab
"[DEBUG] Exporting AAR And POM\n\tAAR Path %s\n\tPOM Path %s\n", exported_archive_path, pom_path));
}
Checks::check_exit(
VCPKG_LINE_INFO,
compress_directory_to_zip(
paths.get_filesystem(), paths.get_tool_cache(), package_directory, exported_archive_path) != 0,
Strings::concat("Failed to compress folder ", package_directory));
Checks::check_exit(VCPKG_LINE_INFO,
compress_directory_to_zip(paths.get_filesystem(),
paths.get_tool_cache(),
stdout_sink,
package_directory,
exported_archive_path) != 0,
Strings::concat("Failed to compress folder ", package_directory));
std::string POM = R"(<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"

Просмотреть файл

@ -8,7 +8,6 @@
#include <vcpkg/base/strings.h>
#include <vcpkg/base/stringview.h>
#include <vcpkg/base/system.h>
#include <vcpkg/base/system.print.h>
#include <vcpkg/base/system.process.h>
#include <vcpkg/base/util.h>
@ -228,7 +227,9 @@ namespace vcpkg
virtual bool is_abi_sensitive() const = 0;
virtual void add_system_paths(std::vector<Path>& out_candidate_paths) const { (void)out_candidate_paths; }
virtual ExpectedS<std::string> get_version(const ToolCache& cache, const Path& exe_path) const = 0;
virtual ExpectedS<std::string> get_version(const ToolCache& cache,
MessageSink& status_sink,
const Path& exe_path) const = 0;
virtual void add_system_package_info(LocalizedString& out) const
{
@ -249,7 +250,7 @@ namespace vcpkg
virtual StringView system_exe_stem() const override { return {}; }
virtual std::array<int, 3> default_min_version() const override { return {0}; }
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path&) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path&) const override
{
return {"0", expected_left_tag};
}
@ -272,7 +273,7 @@ namespace vcpkg
out_candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe");
}
#endif
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
return run_to_extract_version(Tools::CMAKE, exe_path, Command(exe_path).string_arg("--version"))
.then([&](std::string&& output) {
@ -295,7 +296,7 @@ namespace vcpkg
virtual StringView system_exe_stem() const override { return Tools::NINJA; }
virtual std::array<int, 3> default_min_version() const override { return {3, 5, 1}; }
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
// Sample output: 1.8.2
return run_to_extract_version(Tools::NINJA, exe_path, Command(exe_path).string_arg("--version"));
@ -317,22 +318,26 @@ namespace vcpkg
virtual StringView system_exe_stem() const override { return Tools::NUGET; }
virtual std::array<int, 3> default_min_version() const override { return {4, 6, 2}; }
virtual ExpectedS<std::string> get_version(const ToolCache& cache, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache& cache,
MessageSink& status_sink,
const Path& exe_path) const override
{
(void)cache;
(void)status_sink;
Command cmd;
#ifndef _WIN32
cmd.string_arg(cache.get_tool_path(Tools::MONO));
#endif
#if !defined(_WIN32)
cmd.string_arg(cache.get_tool_path(Tools::MONO, status_sink));
#endif // ^^^ !_WIN32
cmd.string_arg(exe_path);
return run_to_extract_version(Tools::NUGET, exe_path, std::move(cmd))
#ifndef _WIN32
#if !defined(_WIN32)
.map_error([](std::string&& error) {
error.push_back('\n');
error.append(msg::format(msgMonoInstructions).extract_data());
return std::move(error);
})
#endif
#endif // ^^^ !_WIN32
.then([&](std::string&& output) {
// Sample output:
// NuGet Version: 4.6.2.5055
@ -349,7 +354,7 @@ namespace vcpkg
virtual StringView tool_data_name() const override { return Tools::ARIA2; }
virtual StringView system_exe_stem() const override { return "aria2c"; }
virtual std::array<int, 3> default_min_version() const override { return {1, 33, 1}; }
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
return run_to_extract_version(Tools::ARIA2, exe_path, Command(exe_path).string_arg("--version"))
.then([&](std::string&& output) {
@ -378,7 +383,7 @@ namespace vcpkg
}
#endif
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
return run_to_extract_version(Tools::NODE, exe_path, Command(exe_path).string_arg("--version"))
.then([&](std::string&& output) {
@ -408,7 +413,7 @@ namespace vcpkg
}
#endif
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
return run_to_extract_version(Tools::GIT, exe_path, Command(exe_path).string_arg("--version"))
.then([&](std::string&& output) {
@ -430,7 +435,7 @@ namespace vcpkg
virtual StringView system_exe_stem() const override { return Tools::MONO; }
virtual std::array<int, 3> default_min_version() const override { return {0, 0, 0}; }
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
return run_to_extract_version(Tools::MONO, exe_path, Command(exe_path).string_arg("--version"))
.then([&](std::string&& output) {
@ -461,7 +466,7 @@ namespace vcpkg
virtual StringView system_exe_stem() const override { return Tools::GSUTIL; }
virtual std::array<int, 3> default_min_version() const override { return {4, 56, 0}; }
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
return run_to_extract_version(Tools::GSUTIL, exe_path, Command(exe_path).string_arg("version"))
.then([&](std::string&& output) {
@ -479,7 +484,7 @@ namespace vcpkg
virtual StringView system_exe_stem() const override { return Tools::AWSCLI; }
virtual std::array<int, 3> default_min_version() const override { return {2, 4, 4}; }
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
return run_to_extract_version(Tools::AWSCLI, exe_path, Command(exe_path).string_arg("--version"))
.then([&](std::string&& output) {
@ -496,7 +501,7 @@ namespace vcpkg
virtual StringView system_exe_stem() const override { return "cos"; }
virtual std::array<int, 3> default_min_version() const override { return {0, 11, 0}; }
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
return run_to_extract_version(Tools::COSCLI, exe_path, Command(exe_path).string_arg("--version"))
.then([&](std::string&& output) {
@ -514,7 +519,7 @@ namespace vcpkg
virtual StringView system_exe_stem() const override { return {}; }
virtual std::array<int, 3> default_min_version() const override { return {0, 0, 0}; }
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
// Sample output: 3.1.81
return run_to_extract_version(
@ -537,7 +542,7 @@ namespace vcpkg
virtual StringView system_exe_stem() const override { return "pwsh"; }
virtual std::array<int, 3> default_min_version() const override { return {7, 0, 3}; }
virtual ExpectedS<std::string> get_version(const ToolCache&, const Path& exe_path) const override
virtual ExpectedS<std::string> get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override
{
return run_to_extract_version(Tools::POWERSHELL_CORE, exe_path, Command(exe_path).string_arg("--version"))
.then([&](std::string&& output) {
@ -576,14 +581,15 @@ namespace vcpkg
}
template<typename Func>
Optional<PathAndVersion> find_first_with_sufficient_version(const ToolProvider& tool_provider,
Optional<PathAndVersion> find_first_with_sufficient_version(MessageSink& status_sink,
const ToolProvider& tool_provider,
const std::vector<Path>& candidates,
Func&& accept_version) const
{
for (auto&& candidate : candidates)
{
if (!fs.exists(candidate, IgnoreErrors{})) continue;
auto maybe_version = tool_provider.get_version(*this, candidate);
auto maybe_version = tool_provider.get_version(*this, status_sink, candidate);
const auto version = maybe_version.get();
if (!version) continue;
const auto parsed_version = parse_tool_version_string(*version);
@ -597,7 +603,7 @@ namespace vcpkg
return nullopt;
}
Path download_tool(const ToolData& tool_data) const
Path download_tool(const ToolData& tool_data, MessageSink& status_sink) const
{
const std::array<int, 3>& version = tool_data.version;
const std::string version_as_string = Strings::format("%d.%d.%d", version[0], version[1], version[2]);
@ -609,16 +615,25 @@ namespace vcpkg
tool_data.name,
version_as_string,
tool_data.name);
vcpkg::printf("A suitable version of %s was not found (required v%s). Downloading portable %s v%s...\n",
tool_data.name,
version_as_string,
tool_data.name,
version_as_string);
status_sink.print(Color::none,
Strings::concat("A suitable version of ",
tool_data.name,
" was not found (required v",
version_as_string,
"). Downloading portable ",
tool_data.name,
" v",
version_as_string,
"...\n"));
const auto download_path = downloads / tool_data.download_subpath;
if (!fs.exists(download_path, IgnoreErrors{}))
{
print2("Downloading ", tool_data.name, "...\n");
print2(" ", tool_data.url, " -> ", download_path, "\n");
status_sink.print(
Color::none,
Strings::concat(
"Downloading ", tool_data.name, "...\n ", tool_data.url, " -> ", download_path, "\n"));
downloader->download_file(fs, tool_data.url, download_path, tool_data.sha512);
}
else
@ -631,18 +646,18 @@ namespace vcpkg
if (tool_data.is_archive)
{
print2("Extracting ", tool_data.name, "...\n");
status_sink.print(Color::none, Strings::concat("Extracting ", tool_data.name, "...\n"));
#if defined(_WIN32)
if (tool_data.name == "cmake")
{
// We use cmake as the core extractor on Windows, so we need to perform a special dance when
// extracting it.
win32_extract_bootstrap_zip(fs, *this, download_path, tool_dir_path);
win32_extract_bootstrap_zip(fs, *this, status_sink, download_path, tool_dir_path);
}
else
#endif // ^^^ _WIN32
{
extract_archive(fs, *this, download_path, tool_dir_path);
extract_archive(fs, *this, status_sink, download_path, tool_dir_path);
}
}
else
@ -663,11 +678,14 @@ namespace vcpkg
[this]() { return this->fs.read_contents(this->xml_config, VCPKG_LINE_INFO); });
}
virtual const Path& get_tool_path(StringView tool) const override { return get_tool_pathversion(tool).p; }
virtual const Path& get_tool_path(StringView tool, MessageSink& status_sink) const override
{
return get_tool_pathversion(tool, status_sink).p;
}
static constexpr StringLiteral s_env_vcpkg_force_system_binaries = "VCPKG_FORCE_SYSTEM_BINARIES";
PathAndVersion get_path(const ToolProvider& tool) const
PathAndVersion get_path(const ToolProvider& tool, MessageSink& status_sink) const
{
const bool env_force_system_binaries =
get_environment_variable(s_env_vcpkg_force_system_binaries).has_value();
@ -729,7 +747,10 @@ namespace vcpkg
// Otherwise, execute each entry and compare its version against the constraint. Take the first that
// matches.
const auto maybe_path = find_first_with_sufficient_version(
tool, candidate_paths, [&min_version, exact_version](const std::array<int, 3>& actual_version) {
status_sink,
tool,
candidate_paths,
[&min_version, exact_version](const std::array<int, 3>& actual_version) {
if (exact_version)
{
return actual_version[0] == min_version[0] && actual_version[1] == min_version[1] &&
@ -751,8 +772,9 @@ namespace vcpkg
// If none of the current entries are acceptable, fall back to downloading if possible
if (auto tool_data = maybe_tool_data.get())
{
auto downloaded_path = download_tool(*tool_data);
auto downloaded_version = tool.get_version(*this, downloaded_path).value_or_exit(VCPKG_LINE_INFO);
auto downloaded_path = download_tool(*tool_data, status_sink);
auto downloaded_version =
tool.get_version(*this, status_sink, downloaded_path).value_or_exit(VCPKG_LINE_INFO);
return {std::move(downloaded_path), std::move(downloaded_version)};
}
}
@ -775,36 +797,36 @@ namespace vcpkg
Checks::msg_exit_maybe_upgrade(VCPKG_LINE_INFO, s);
}
const PathAndVersion& get_tool_pathversion(StringView tool) const
const PathAndVersion& get_tool_pathversion(StringView tool, MessageSink& status_sink) const
{
return path_version_cache.get_lazy(tool, [&]() -> PathAndVersion {
// First deal with specially handled tools.
// For these we may look in locations like Program Files, the PATH etc as well as the auto-downloaded
// location.
if (tool == Tools::CMAKE) return get_path(CMakeProvider());
if (tool == Tools::GIT) return get_path(GitProvider());
if (tool == Tools::NINJA) return get_path(NinjaProvider());
if (tool == Tools::POWERSHELL_CORE) return get_path(PowerShellCoreProvider());
if (tool == Tools::NUGET) return get_path(NuGetProvider());
if (tool == Tools::ARIA2) return get_path(Aria2Provider());
if (tool == Tools::NODE) return get_path(NodeProvider());
if (tool == Tools::IFW_INSTALLER_BASE) return get_path(IfwInstallerBaseProvider());
if (tool == Tools::MONO) return get_path(MonoProvider());
if (tool == Tools::GSUTIL) return get_path(GsutilProvider());
if (tool == Tools::AWSCLI) return get_path(AwsCliProvider());
if (tool == Tools::COSCLI) return get_path(CosCliProvider());
if (tool == Tools::CMAKE) return get_path(CMakeProvider(), status_sink);
if (tool == Tools::GIT) return get_path(GitProvider(), status_sink);
if (tool == Tools::NINJA) return get_path(NinjaProvider(), status_sink);
if (tool == Tools::POWERSHELL_CORE) return get_path(PowerShellCoreProvider(), status_sink);
if (tool == Tools::NUGET) return get_path(NuGetProvider(), status_sink);
if (tool == Tools::ARIA2) return get_path(Aria2Provider(), status_sink);
if (tool == Tools::NODE) return get_path(NodeProvider(), status_sink);
if (tool == Tools::IFW_INSTALLER_BASE) return get_path(IfwInstallerBaseProvider(), status_sink);
if (tool == Tools::MONO) return get_path(MonoProvider(), status_sink);
if (tool == Tools::GSUTIL) return get_path(GsutilProvider(), status_sink);
if (tool == Tools::AWSCLI) return get_path(AwsCliProvider(), status_sink);
if (tool == Tools::COSCLI) return get_path(CosCliProvider(), status_sink);
if (tool == Tools::TAR)
{
return {find_system_tar(fs).value_or_exit(VCPKG_LINE_INFO), {}};
}
GenericToolProvider provider{tool};
return get_path(provider);
return get_path(provider, status_sink);
});
}
virtual const std::string& get_tool_version(StringView tool) const override
virtual const std::string& get_tool_version(StringView tool, MessageSink& status_sink) const override
{
return get_tool_pathversion(tool).version;
return get_tool_pathversion(tool, status_sink).version;
}
};

Просмотреть файл

@ -915,16 +915,19 @@ namespace vcpkg
}
const ToolCache& VcpkgPaths::get_tool_cache() const { return *m_pimpl->m_tool_cache; }
const Path& VcpkgPaths::get_tool_exe(StringView tool) const { return m_pimpl->m_tool_cache->get_tool_path(tool); }
const std::string& VcpkgPaths::get_tool_version(StringView tool) const
const Path& VcpkgPaths::get_tool_exe(StringView tool, MessageSink& status_messages) const
{
return m_pimpl->m_tool_cache->get_tool_version(tool);
return m_pimpl->m_tool_cache->get_tool_path(tool, status_messages);
}
const std::string& VcpkgPaths::get_tool_version(StringView tool, MessageSink& status_messages) const
{
return m_pimpl->m_tool_cache->get_tool_version(tool, status_messages);
}
GitConfig VcpkgPaths::git_builtin_config() const
{
GitConfig conf;
conf.git_exe = get_tool_exe(Tools::GIT);
conf.git_exe = get_tool_exe(Tools::GIT, stdout_sink);
conf.git_dir = this->root / ".git";
conf.git_work_tree = this->root;
return conf;
@ -932,7 +935,7 @@ namespace vcpkg
Command VcpkgPaths::git_cmd_builder(const Path& dot_git_dir, const Path& work_tree) const
{
Command ret(get_tool_exe(Tools::GIT));
Command ret(get_tool_exe(Tools::GIT, stdout_sink));
if (!dot_git_dir.empty())
{
ret.string_arg(Strings::concat("--git-dir=", dot_git_dir));
@ -1111,7 +1114,7 @@ namespace vcpkg
expected_right_tag};
}
extract_tar_cmake(this->get_tool_exe(Tools::CMAKE), destination_tar, destination_tmp);
extract_tar_cmake(this->get_tool_exe(Tools::CMAKE, stdout_sink), destination_tar, destination_tmp);
fs.remove(destination_tar, ec);
if (ec)
{
@ -1277,7 +1280,7 @@ namespace vcpkg
expected_right_tag};
}
extract_tar_cmake(get_tool_exe(Tools::CMAKE), git_tree_temp_tar, git_tree_temp);
extract_tar_cmake(get_tool_exe(Tools::CMAKE, stdout_sink), git_tree_temp_tar, git_tree_temp);
// Attempt to remove temporary files, though non-critical.
fs.remove(git_tree_temp_tar, IgnoreErrors{});