diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index fa5a8a9ac0..608ff9310f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -21,13 +21,13 @@ jobs: runs-on: ${{ matrix.os }} timeout-minutes: 120 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: "18.x" cache: 'npm' cache-dependency-path: vcpkg-artifacts/package-lock.json - - uses: lukka/get-cmake@v3.26.3 + - uses: lukka/get-cmake@v3.31.0 with: cmakeVersion: 3.22.1 # ubuntu 22.04 ninjaVersion: 1.11.1 @@ -70,7 +70,7 @@ jobs: run: | "VCPKG_SHA="+(Get-Content vcpkg-init/vcpkg-scripts-sha.txt -Raw).Trim() >> $env:GITHUB_OUTPUT - name: Checkout microsoft/vcpkg for end-to-end tests - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 path: ${{ github.workspace }}/vcpkg-root diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index ab6c0a15eb..7235b23e13 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -18,13 +18,13 @@ jobs: runs-on: windows-2022 timeout-minutes: 60 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: "18.x" cache: 'npm' cache-dependency-path: vcpkg-artifacts/package-lock.json - - uses: lukka/get-cmake@v3.26.3 + - uses: lukka/get-cmake@v3.31.0 with: cmakeVersion: 3.22.1 # ubuntu 22.04 ninjaVersion: 1.11.1 @@ -65,7 +65,7 @@ jobs: exit 1 } - name: 'Publish Format and Messages File Diff' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: failure() && steps.diff.outcome == 'failure' with: name: format.patch @@ -75,14 +75,14 @@ jobs: runs-on: windows-2022 timeout-minutes: 10 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Get microsoft/vcpkg pinned sha into VCPKG_SHA id: vcpkg_sha shell: pwsh run: | "VCPKG_SHA="+(Get-Content vcpkg-init/vcpkg-scripts-sha.txt -Raw).Trim() >> $env:GITHUB_OUTPUT - name: Checkout microsoft/vcpkg for end-to-end tests - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 path: ${{ github.workspace }}/vcpkg-root diff --git a/README.md b/README.md index acf045e580..1ac90b8e01 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Vcpkg: Overview -[中文总览](https://github.com/microsoft/vcpkg/blob/master/README_zh_CN.md) -[Español](https://github.com/microsoft/vcpkg/blob/master/README_es.md) -[한국어](https://github.com/microsoft/vcpkg/blob/master/README_ko_KR.md) -[Français](https://github.com/microsoft/vcpkg/blob/master/README_fr.md) +[中文总览](https://learn.microsoft.com/zh-cn/vcpkg/get_started/overview) +[Español](https://learn.microsoft.com/es/vcpkg/get_started/overview) +[한국어](https://learn.microsoft.com/ko-kr/vcpkg/get_started/overview) +[Français](https://learn.microsoft.com/fr/vcpkg/get_started/overview) Vcpkg helps you manage C and C++ libraries on Windows, Linux and MacOS. This tool and ecosystem are constantly evolving, and we always appreciate contributions! diff --git a/azure-pipelines/e2e-assets/asset-caching/bad-hash-script.ps1 b/azure-pipelines/e2e-assets/asset-caching/bad-hash-script.ps1 new file mode 100644 index 0000000000..0f30f60271 --- /dev/null +++ b/azure-pipelines/e2e-assets/asset-caching/bad-hash-script.ps1 @@ -0,0 +1,3 @@ +Param([string]$File) +Write-Host "Creating file with the wrong hash" +Set-Content -Path $File -Value "This is a file with the wrong hash" -Encoding Ascii -NoNewline diff --git a/azure-pipelines/e2e-assets/asset-caching/failing-script.ps1 b/azure-pipelines/e2e-assets/asset-caching/failing-script.ps1 new file mode 100644 index 0000000000..fafc73a496 --- /dev/null +++ b/azure-pipelines/e2e-assets/asset-caching/failing-script.ps1 @@ -0,0 +1,2 @@ +Write-Host "Script download error" +exit 1 diff --git a/azure-pipelines/e2e-assets/asset-caching/no-file-script.ps1 b/azure-pipelines/e2e-assets/asset-caching/no-file-script.ps1 new file mode 100644 index 0000000000..16bcc8c21d --- /dev/null +++ b/azure-pipelines/e2e-assets/asset-caching/no-file-script.ps1 @@ -0,0 +1 @@ +Write-Host "Not creating a file" diff --git a/azure-pipelines/e2e-ports/broken-manifests/broken-duplicate-overrides/portfile.cmake b/azure-pipelines/e2e-ports/broken-manifests/broken-duplicate-overrides/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-ports/broken-manifests/broken-duplicate-overrides/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-ports/broken-manifests/broken-duplicate-overrides/vcpkg.json b/azure-pipelines/e2e-ports/broken-manifests/broken-duplicate-overrides/vcpkg.json new file mode 100644 index 0000000000..881ff493a3 --- /dev/null +++ b/azure-pipelines/e2e-ports/broken-manifests/broken-duplicate-overrides/vcpkg.json @@ -0,0 +1,17 @@ +{ + "name": "broken-duplicate-overrides", + "version": "1", + "dependencies": [ + "zlib" + ], + "overrides": [ + { + "name": "zlib", + "version": "1.2.13" + }, + { + "name": "zlib", + "version": "1.3.1" + } + ] +} diff --git a/azure-pipelines/e2e-ports/vcpkg-test-x-script/portfile.cmake b/azure-pipelines/e2e-ports/vcpkg-test-x-script/portfile.cmake index 3b193ceb28..fc60ed599a 100644 --- a/azure-pipelines/e2e-ports/vcpkg-test-x-script/portfile.cmake +++ b/azure-pipelines/e2e-ports/vcpkg-test-x-script/portfile.cmake @@ -2,6 +2,7 @@ vcpkg_download_distfile( SOURCE_PATH URLS https://example.com/hello-world.txt + # This must stay uppercase to check that the SHA512 is properly tolower'd when it gets passed to x-script SHA512 09E1E2A84C92B56C8280F4A1203C7CFFD61B162CFE987278D4D6BE9AFBF38C0E8934CDADF83751F4E99D111352BFFEFC958E5A4852C8A7A29C95742CE59288A8 FILENAME hello-world.txt ) diff --git a/azure-pipelines/e2e-projects/overlays-dot/vcpkg-configuration.json b/azure-pipelines/e2e-projects/overlays-dot/vcpkg-configuration.json new file mode 100644 index 0000000000..8bf3475a84 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-dot/vcpkg-configuration.json @@ -0,0 +1,3 @@ +{ + "overlay-ports": [ "." ] +} diff --git a/azure-pipelines/e2e-projects/overlays-dot/vcpkg.json b/azure-pipelines/e2e-projects/overlays-dot/vcpkg.json new file mode 100644 index 0000000000..bf720c8018 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-dot/vcpkg.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "a" + ] +} diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/builtin-malformed/a/portfile.cmake b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/builtin-malformed/a/portfile.cmake new file mode 100644 index 0000000000..c48b693754 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/builtin-malformed/a/portfile.cmake @@ -0,0 +1,2 @@ +# This port is intentionally malformed and should not be loaded, because ../../a should be loaded instead +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/builtin-malformed/a/vcpkg.json b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/builtin-malformed/a/vcpkg.json new file mode 100644 index 0000000000..4383ff0404 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/builtin-malformed/a/vcpkg.json @@ -0,0 +1,5 @@ +{ + "name": "a", + "version": "0", + "intentionally-malformed" +} diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/config-overlays/a/portfile.cmake b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/config-overlays/a/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/config-overlays/a/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/config-overlays/a/vcpkg.json b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/config-overlays/a/vcpkg.json new file mode 100644 index 0000000000..dcd0298dbe --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/config-overlays/a/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "a", + "version": "0" +} diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/vcpkg-configuration.json b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/vcpkg-configuration.json new file mode 100644 index 0000000000..f07f9aa131 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/vcpkg-configuration.json @@ -0,0 +1,4 @@ +{ + "$comment": "'config-overlays/a' in . should get loaded first, so we should never consider 'builtin-malformed/a'", + "overlay-ports": [ "config-overlays" ] +} diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/vcpkg.json b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/vcpkg.json new file mode 100644 index 0000000000..bf720c8018 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing-builtin/vcpkg.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "a" + ] +} diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/a/portfile.cmake b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/a/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/a/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/a/vcpkg.json b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/a/vcpkg.json new file mode 100644 index 0000000000..dcd0298dbe --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/a/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "a", + "version": "0" +} diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/malformed/a/portfile.cmake b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/malformed/a/portfile.cmake new file mode 100644 index 0000000000..c48b693754 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/malformed/a/portfile.cmake @@ -0,0 +1,2 @@ +# This port is intentionally malformed and should not be loaded, because ../../a should be loaded instead +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/malformed/a/vcpkg.json b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/malformed/a/vcpkg.json new file mode 100644 index 0000000000..4383ff0404 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/config-overlays/malformed/a/vcpkg.json @@ -0,0 +1,5 @@ +{ + "name": "a", + "version": "0", + "intentionally-malformed" +} diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing/vcpkg-configuration.json b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/vcpkg-configuration.json new file mode 100644 index 0000000000..cbf8b52cfe --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/vcpkg-configuration.json @@ -0,0 +1,4 @@ +{ + "$comment": "'config-overlays/a' in . should get loaded first, so we should never consider 'config-overlays/malformed/a'", + "overlay-ports": [ "config-overlays", "config-overlays/malformed" ] +} diff --git a/azure-pipelines/e2e-projects/overlays-malformed-shadowing/vcpkg.json b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/vcpkg.json new file mode 100644 index 0000000000..bf720c8018 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-malformed-shadowing/vcpkg.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "a" + ] +} diff --git a/azure-pipelines/e2e-projects/overlays-not-quite-dot/hello/ensure-directory.txt b/azure-pipelines/e2e-projects/overlays-not-quite-dot/hello/ensure-directory.txt new file mode 100644 index 0000000000..00ff321468 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-not-quite-dot/hello/ensure-directory.txt @@ -0,0 +1 @@ +This file exists only to ensure that git creates the directory containing it, so that ./hello/.. is a valid path. \ No newline at end of file diff --git a/azure-pipelines/e2e-projects/overlays-not-quite-dot/vcpkg-configuration.json b/azure-pipelines/e2e-projects/overlays-not-quite-dot/vcpkg-configuration.json new file mode 100644 index 0000000000..dfbb7f3ebc --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-not-quite-dot/vcpkg-configuration.json @@ -0,0 +1,3 @@ +{ + "overlay-ports": [ "./hello/.." ] +} diff --git a/azure-pipelines/e2e-projects/overlays-not-quite-dot/vcpkg.json b/azure-pipelines/e2e-projects/overlays-not-quite-dot/vcpkg.json new file mode 100644 index 0000000000..bf720c8018 --- /dev/null +++ b/azure-pipelines/e2e-projects/overlays-not-quite-dot/vcpkg.json @@ -0,0 +1,5 @@ +{ + "dependencies": [ + "a" + ] +} diff --git a/azure-pipelines/e2e-specs/autocomplete-posh-vcpkg.Tests.ps1 b/azure-pipelines/e2e-specs/autocomplete-posh-vcpkg.Tests.ps1 new file mode 100644 index 0000000000..5e4d1b583e --- /dev/null +++ b/azure-pipelines/e2e-specs/autocomplete-posh-vcpkg.Tests.ps1 @@ -0,0 +1,378 @@ +param ( + [Parameter(Mandatory)][string]$poshVcpkgModulePath, + [Parameter(Mandatory)][System.IO.FileInfo]$vcpkgExe +) + +BeforeAll { + Import-Module $poshVcpkgModulePath + + $env:PATH = $vcpkgExe.Directory.FullName + [System.IO.Path]::PathSeparator + $env:PATH + + function Complete-InputCaret { + [OutputType([string[]])] + param ( + [Parameter(Mandatory, Position = 0, ValueFromPipeline)] + [string]$InputCaretScript + ) + $positionMatches = [regex]::Matches($InputCaretScript, '\^') + if ($positionMatches.Count -ne 1) { + throw 'Invalid caret cursor command, please indicate by only one ^ character' + } + $command = [string]$InputCaretScript.Replace('^', '') + $cursorPosition = [int]$positionMatches[0].Index + $result = [System.Management.Automation.CommandCompletion]::CompleteInput($command, $cursorPosition, $null) + return $result.CompletionMatches | Select-Object -ExpandProperty CompletionText + } + + $VcpkgPredefined = @{ + CommandList = @( + 'acquire_project', 'acquire', 'activate', 'add', 'create', 'deactivate', 'depend-info', 'edit', 'env' + 'export', 'fetch', 'find', 'format-manifest', 'hash', 'help', 'install', 'integrate', 'list', 'new', 'owns' + 'portsdiff', 'remove', 'search', 'update', 'upgrade', 'use', 'version', 'x-add-version', 'x-check-support' + 'x-init-registry', 'x-package-info', 'x-regenerate', 'x-set-installed', 'x-update-baseline' + 'x-update-registry', 'x-vsinstances' + ) + CommonParameterList = @() + CommandOptionList = @{ + install = @( + '--allow-unsupported', '--clean-after-build', '--clean-buildtrees-after-build' + '--clean-downloads-after-build', '--clean-packages-after-build', '--dry-run', '--editable' + '--enforce-port-checks', '--head', '--keep-going', '--no-downloads', '--no-print-usage' + '--only-binarycaching', '--only-downloads', '--recurse', '--x-feature', '--x-no-default-features' + '--x-prohibit-backcompat-features', '--x-write-nuget-packages-config', '--x-xunit' + ) + remove = @( + '--dry-run', '--outdated', '--purge', '--recurse' + ) + } + } + $VcpkgPredefined | Out-Null +} + +Describe 'Prerequisites tests' { + Context 'Internal function Complete-InputCaret tests' { + It 'Complete-InputCaret 1 caret string should success' { + { 'aaaa^' | Complete-InputCaret } | Should -Not -Throw + } + + It 'Complete-InputCaret 0 caret string should throw' { + { 'aaaa' | Complete-InputCaret } | Should -Throw + } + + It 'Complete-InputCaret 2 caret string should throw' { + { 'aaaa^^' | Complete-InputCaret } | Should -Throw + } + + It 'Complete-InputCaret self should success' { + 'Complete-InputCaret^' | Complete-InputCaret | Should -Contain 'Complete-InputCaret' + } + } + + Context 'Exist module and command tests' { + It 'Should imported module posh-vcpkg' { + (Get-Module -Name posh-vcpkg).Name | Should -Be 'posh-vcpkg' + } + + It 'Should version greater than or equal 0.0.2' { + (Get-Module posh-vcpkg).Version | Should -BeGreaterOrEqual '0.0.2' + } + + It 'Should have executable vcpkg' { + $vcpkgExe | Should -Exist + } + + It 'Should have command vcpkg' { + Get-Command -Name vcpkg | Should -Not -BeNullOrEmpty + } + + It 'Should command vcpkg is the executable' { + (Get-Command -Name vcpkg).Path | Should -Be $vcpkgExe.FullName + } + } +} + +Describe 'Complete basic tests' { + Context 'Complete full command contain tests' { + It 'Should complete command [vcpkg <_>^] contain [<_>]' -ForEach @( + 'help' + 'install' + 'version' + 'integrate' + ) { + 'vcpkg {0}^' -f $_ | Complete-InputCaret | Should -Contain $_ + } + } + + Context 'Complete full command exact match tests' { + It 'Should exact match command completions [vcpkg <_>^] be [<_>]' -ForEach @( + 'help' + 'install' + 'version' + 'integrate' + ) { + 'vcpkg {0}^' -f $_ | Complete-InputCaret | Should -Be $_ + } + } + + Context 'Complete part command contain tests' { + It 'Should complete command [vcpkg ^] contain []' -ForEach @( + @{command = 'he'; expected = 'help' } + @{command = 'in'; expected = 'install' } + @{command = 've'; expected = 'version' } + @{command = 'in'; expected = 'integrate' } + ) { + 'vcpkg {0}^' -f $command | Complete-InputCaret | Should -Contain $expected + } + } + + Context 'Complete space tests' { + It 'Should complete command for blank space [vcpkg ^] contain [<_>]' -ForEach @( + 'help' + 'install' + 'version' + 'integrate' + ) { + 'vcpkg ^' | Complete-InputCaret | Should -Contain $_ + } + + It 'Should exact match command completions for blank space [vcpkg ^]' { + $completions = 'vcpkg ^' | Complete-InputCaret + $expected = $VcpkgPredefined.CommandList + Compare-Object $completions $expected | Should -BeNullOrEmpty + } + } +} + +Describe 'Complete command tests' { + Context 'Complete common option tests' -Skip { + It 'Should complete common option for blank space [vcpkg ^] contain [--host-triplet]' { + 'vcpkg ^' | Complete-InputCaret | Should -Contain '--host-triplet' + } + + It 'Should complete common option for blank space [vcpkg ^] contain [--host-triplet=]' { + 'vcpkg ^' | Complete-InputCaret | Should -Contain '--host-triplet=' + } + + It 'Should complete common option for blank space [vcpkg ^] contain [--vcpkg-root]' { + 'vcpkg ^' | Complete-InputCaret | Should -Contain '--vcpkg-root' + } + + It 'Should complete common option for blank space [vcpkg ^] contain [--vcpkg-root=]' { + 'vcpkg ^' | Complete-InputCaret | Should -Contain '--vcpkg-root=' + } + } + + Context 'Complete common option argument tests' -Skip { + It 'Should complete common option arguments for [vcpkg --triplet^] contain [--triplet=]' { + 'vcpkg --triplet^' -f $argument | Complete-InputCaret | Should -Contain '--triplet=x64-windows' + } + + It 'Should complete common option arguments for [vcpkg --triplet=^] contain [--triplet=x64-windows]' { + 'vcpkg --triplet=^' -f $argument | Complete-InputCaret | Should -Contain '--triplet=x64-windows' + } + + It 'Should complete common option arguments for [vcpkg --triplet=x64^] contain [--triplet=x64-windows]' { + 'vcpkg --triplet=x64^' -f $argument | Complete-InputCaret | Should -Contain '--triplet=x64-windows' + } + } + + # Skip due to https://github.com/PowerShell/PowerShell/issues/2912 + Context 'Complete command option list tests conditionally - CoreOnly' -Tag CoreOnly { + It 'Should complete option flags with single minus [vcpkg -^] contain []' -ForEach @( + @{ command = 'install' ; expected = '--editable' } + @{ command = 'remove' ; expected = '--dry-run' } + ) { + 'vcpkg {0} -^' -f $command | Complete-InputCaret | Should -Contain $expected + } + + It 'Should complete option flags with double minus [vcpkg --^] contain []' -ForEach @( + @{ command = 'install' ; expected = '--editable' } + @{ command = 'remove' ; expected = '--dry-run' } + ) { + 'vcpkg {0} --^' -f $command | Complete-InputCaret | Should -Contain $expected + } + + It 'Should exact match command options for double minus [vcpkg <_> --^]' -ForEach @( + 'install' + 'remove' + ) { + $completions = 'vcpkg {0} --^' -f $_ | Complete-InputCaret + $expected = $VcpkgPredefined.CommandOptionList[$_] + Compare-Object $completions $expected | Should -BeNullOrEmpty + } + } + + Context 'Complete command argument tests conditionally' { + It 'Should complete install with port name [] contain []' -ForEach @( + @{ caretCmd = 'vcpkg install vcpkg-^' ; expected = 'vcpkg-cmake' } + ) { + $caretCmd | Complete-InputCaret | Should -Contain $expected + } + + It 'Should complete install port with triplet [] contain []' -ForEach @( + @{ caretCmd = 'vcpkg install vcpkg-cmake:^' ; expected = 'vcpkg-cmake:x64-windows' } + ) { + $caretCmd | Complete-InputCaret | Should -Contain $expected + } + + It 'Should complete integrate with subcommand [vcpkg integrate inst^] be [install]' { + 'vcpkg integrate inst^' | Complete-InputCaret | Should -Be 'install' + } + + It 'Should complete integrate with subcommand [vcpkg integrate ^] contain [powershell] - WindowsOnly' -Tag WindowsOnly { + 'vcpkg integrate ^' | Complete-InputCaret | Should -Contain 'powershell' + } + + It 'Should complete integrate with subcommand [vcpkg integrate ^] contain [bash] - NonWindowsOnly' -Tag NonWindowsOnly { + 'vcpkg integrate ^' | Complete-InputCaret | Should -Contain 'bash' + } + + It 'Should exact match command subcommands [vcpkg integrate ^] - WindowsOnly' -Tag WindowsOnly { + $expected = @('install', 'remove', 'powershell', 'project') + $completions = 'vcpkg integrate ^' | Complete-InputCaret + Compare-Object $completions $expected | Should -BeNullOrEmpty + } + + It 'Should exact match command subcommands [vcpkg integrate ^] - NonWindowsOnly' -Tag NonWindowsOnly { + $expected = @('install', 'remove', 'bash', 'x-fish', 'zsh') + $completions = 'vcpkg integrate ^' | Complete-InputCaret + Compare-Object $completions $expected | Should -BeNullOrEmpty + } + } +} + +Describe 'Complete variants tests' { + BeforeAll { + Set-Variable vcpkgWithExt ($vcpkgExe.FullName) + Set-Variable vcpkgNoExt ([System.IO.Path]::GetFileNameWithoutExtension($vcpkgExe.FullName)) + } + + Context 'Complete basic variant command tests' { + It 'Should exact match command completions with call operator absolute exe word be [version]' { + "& $vcpkgWithExt ver^" | Complete-InputCaret | Should -Be 'version' + } + + It 'Should exact match command completions [] be [version]' -ForEach @( + @{ caretCmd = 'vcpkg ver^' ; comment = 'with word' } + @{ caretCmd = '& vcpkg ver^' ; comment = 'with & word' } + ) { + $caretCmd | Complete-InputCaret | Should -Be 'version' + } + + It 'Should exact match command completions for exe path [] be [version]' -ForEach @( + @{ caretCmd = './vcpkg ver^' ; comment = 'with dot slash word' } + @{ caretCmd = '& ./vcpkg ver^' ; comment = 'with & dot slash word' } + ) { + Set-Location $vcpkgExe.Directory + $caretCmd | Complete-InputCaret | Should -Be 'version' + } + } + + Context 'Complete variant command tests conditionally - WindowsOnly' -Tag WindowsOnly { + It 'Should exact match command completions with call operator no-ext absolute exe word be [version]' { + "& $vcpkgNoExt ver^" | Complete-InputCaret | Should -Be 'version' + } + + It 'Should exact match command completions [] be [version]' -ForEach @( + @{ caretCmd = '& vcpkg.exe ver^' ; comment = 'with & extension word' } + @{ caretCmd = 'vcpkg.exe ver^' ; comment = 'with extension word' } + ) { + $caretCmd | Complete-InputCaret | Should -Be 'version' + } + + It 'Should exact match command completions for exe path [] be [version]' -ForEach @( + @{ caretCmd = '.\vcpkg ver^' ; comment = 'with dot backslash word' } + @{ caretCmd = '& .\vcpkg ver^' ; comment = 'with & dot backslash word' } + @{ caretCmd = './vcpkg.exe ver^' ; comment = 'with dot slash extension word' } + @{ caretCmd = '.\vcpkg.exe ver^' ; comment = 'with dot backslash extension word' } + @{ caretCmd = '& ./vcpkg.exe ver^' ; comment = 'with & dot slash extension word' } + @{ caretCmd = '& .\vcpkg.exe ver^' ; comment = 'with & dot backslash extension word' } + ) { + Set-Location $vcpkgExe.Directory + $caretCmd | Complete-InputCaret | Should -Be 'version' + } + } + + Context 'Complete command with spaces tests' { + It 'Should complete command [] contain [version]' -ForEach @( + @{ caretCmd = 'vcpkg ^' ; comment = 'many spaces' } + @{ caretCmd = 'vcpkg ver^' ; comment = 'middle many spaces' } + @{ caretCmd = ' vcpkg ver^' ; comment = 'with leading spaces' } + @{ caretCmd = ' & vcpkg ver^' ; comment = 'with leading spaces and call operator' } + ) { + $caretCmd | Complete-InputCaret | Should -Contain 'version' + } + } + + Context 'Complete command quotation tests' { + It "Should fallback to default completion with quoted full word [vcpkg 'install'^]" { + "vcpkg 'install'^" | Complete-InputCaret | Should -Be $null + } + + It "Should prevent completion for quoted space [vcpkg ' '^]" { + "vcpkg ' '^" | Complete-InputCaret | Should -Be $null + } + } +} + +Describe 'Complete position tests' { + Context 'Complete command intermediate tests' { + It 'Should exact match command completions [] be [version]' -ForEach @( + @{ caretCmd = 'vcpkg version^'; comment = 'end of word' } + @{ caretCmd = 'vcpkg ver^sion'; comment = 'middle of word' } + ) { + $caretCmd | Complete-InputCaret | Should -Be 'version' + } + + It 'Should exact match command completions [<_>]' -ForEach @( + 'vcpkg ^version' + 'vcpkg ^ ' + 'vcpkg ^ ' + ' vcpkg ^ ' + ' & vcpkg ^ ' + 'vcpkg ^ version ' + ) { + $completions = $_ | Complete-InputCaret + $expected = $VcpkgPredefined.CommandList + Compare-Object $completions $expected | Should -BeNullOrEmpty + } + } + + Context 'Complete complex tests' { + It 'Should complete complex command line [] be []' -ForEach ( + @{ caretCmd = 'echo powershell | % { vcpkg int^egr $_ }; echo $?'; expected = 'integrate' } + ) { + $caretCmd | Complete-InputCaret | Should -Be $expected + } + } +} + +Describe 'Impossible command tests' { + Context 'Complete non-exist command tests conditionally' { + It 'Should prevent completion for non-exist command [vcpkg zzzzzzzz^]' { + 'vcpkg zzzzzzzz^' | Complete-InputCaret | Should -Be $null + } + + It 'Should prevent completion for non-exist command [vcpkg ---^]' { + 'vcpkg ---^' | Complete-InputCaret | Should -Be $null + } + + It 'Should fallback to default for non-exist command with trailing spaces [vcpkg zzzzzzzz ^] - WindowsOnly' -Tag WindowsOnly { + 'vcpkg zzzzzzzz ^' | Complete-InputCaret | Should -BeLike '.\*' + } + + It 'Should fallback to default for non-exist command with trailing spaces [vcpkg zzzzzzzz ^] - NonWindowsOnly' -Tag NonWindowsOnly { + 'vcpkg zzzzzzzz ^' | Complete-InputCaret | Should -BeLike './*' + } + } + + Context 'Complete error command tests' { + It 'Should prevent error from error command [vcpkg --triplet^]' { + { $ErrorActionPreference = 'Stop'; 'vcpkg --triplet^' | Complete-InputCaret } | Should -Not -Throw + } + + It 'Should prevent completion for error command [vcpkg --triplet^]' { + 'vcpkg --triplet^' | Complete-InputCaret | Should -Be $null + } + } +} diff --git a/azure-pipelines/end-to-end-tests-dir/asset-caching.ps1 b/azure-pipelines/end-to-end-tests-dir/asset-caching.ps1 index b3725fcb9b..1b9ce231dc 100644 --- a/azure-pipelines/end-to-end-tests-dir/asset-caching.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/asset-caching.ps1 @@ -3,19 +3,23 @@ # Testing x-script Refresh-TestRoot Run-Vcpkg -TestArgs ($commonArgs + @('fetch', 'cmake')) +Throw-IfFailed +Run-Vcpkg -TestArgs ($commonArgs + @('fetch', 'ninja')) +Throw-IfFailed Run-Vcpkg -TestArgs ($commonArgs + @("install", "vcpkg-test-x-script", "--x-binarysource=clear", "--overlay-ports=$PSScriptRoot/../e2e-ports", "--x-asset-sources=x-script,$TestScriptAssetCacheExe {url} {sha512} {dst};x-block-origin")) Throw-IfFailed $env:VCPKG_FORCE_DOWNLOADED_BINARIES = "ON" +$assetCacheRegex = [regex]::Escape($AssetCache) # Testing asset cache miss (not configured) + x-block-origin enabled Refresh-TestRoot -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("install", "vcpkg-internal-e2e-test-port", "--overlay-ports=$PSScriptRoot/../e2e-ports", "--x-asset-sources=clear;x-block-origin", "--downloads-root=$DownloadsRoot")) -$actual = $actual -replace "`r`n", "`n" - +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("fetch", "cmake", "--x-asset-sources=clear;x-block-origin", "--downloads-root=$DownloadsRoot")) +Throw-IfNotFailed $expected = @( -"A suitable version of .* was not found \(required v[0-9\.]+\)." -"error: Missing .* and downloads are blocked by x-block-origin." +"A suitable version of cmake was not found \(required v[0-9.]+\)\.", +"Downloading cmake-[0-9.]+-[^.]+\.(zip|tar\.gz)", +"error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source https://github\.com/Kitware/CMake/releases/download/[^ ]+" ) -join "`n" if (-not ($actual -match $expected)) { @@ -23,12 +27,12 @@ if (-not ($actual -match $expected)) { } # Testing asset cache miss (not configured) + x-block-origin disabled -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("install", "vcpkg-internal-e2e-test-port", "--overlay-ports=$PSScriptRoot/../e2e-ports", "--x-asset-sources=clear;", "--downloads-root=$DownloadsRoot")) -$actual = $actual -replace "`r`n", "`n" - +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("fetch", "cmake", "--x-asset-sources=clear;", "--downloads-root=$DownloadsRoot")) +Throw-IfFailed $expected = @( -"A suitable version of .* was not found \(required v[0-9\.]+\)." -"Downloading .*." +"A suitable version of cmake was not found \(required v[0-9.]+\)\.", +"Downloading https://github\.com/Kitware/CMake/releases/download/[^ ]+ -> cmake-[0-9.]+-[^.]+\.(zip|tar\.gz)", +"Successfully downloaded cmake-[0-9.]+-[^.]+\.(zip|tar\.gz)" ) -join "`n" if (-not ($actual -match $expected)) { @@ -37,12 +41,22 @@ if (-not ($actual -match $expected)) { # Testing asset cache miss (configured) + x-block-origin enabled Refresh-TestRoot -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("install", "vcpkg-internal-e2e-test-port", "--overlay-ports=$PSScriptRoot/../e2e-ports", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;x-block-origin", "--downloads-root=$DownloadsRoot")) -$actual = $actual -replace "`r`n", "`n" - +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("fetch", "cmake", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;x-block-origin", "--downloads-root=$DownloadsRoot")) +Throw-IfNotFailed $expected = @( -"A suitable version of .* was not found \(required v[0-9\.]+\)." -"Asset cache miss for .* and downloads are blocked by x-block-origin" +"A suitable version of cmake was not found \(required v[0-9.]+\)\.", +"Trying to download cmake-[0-9.]+-[^.]+\.(zip|tar\.gz) using asset cache file://$assetCacheRegex/[0-9a-z]+", +"error: curl: \(37\) Couldn't open file [^\n]+", +"error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source https://github\.com/Kitware/CMake/releases/download/[^ ]+", +"note: If you are using a proxy, please ensure your proxy settings are correct\.", +"Possible causes are:", +"1\. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to ``https//address:port``\.", +"This is not correct, because ``https://`` prefix claims the proxy is an HTTPS proxy, while your proxy \(v2ray, shadowsocksr, etc\.\.\.\) is an HTTP proxy\.", +"Try setting ``http://address:port`` to both HTTP_PROXY and HTTPS_PROXY instead\." +"2\. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your proxy software\. See: https://github\.com/microsoft/vcpkg-tool/pull/77", +"The value set by your proxy might be wrong, or have same ``https://`` prefix issue\.", +"3\. Your proxy's remote server is our of service\.", +"If you believe this is not a temporary download server failure and vcpkg needs to be changed to download this file from a different location, please submit an issue to https://github\.com/Microsoft/vcpkg/issues" ) -join "`n" if (-not ($actual -match $expected)) { @@ -51,15 +65,14 @@ if (-not ($actual -match $expected)) { # Testing asset cache miss (configured) + x-block-origin disabled Refresh-TestRoot -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("install", "vcpkg-internal-e2e-test-port", "--overlay-ports=$PSScriptRoot/../e2e-ports", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;", "--downloads-root=$DownloadsRoot")) -$actual = $actual -replace "`r`n", "`n" - +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("fetch", "cmake", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;", "--downloads-root=$DownloadsRoot")) +Throw-IfFailed $expected = @( -"A suitable version of .* was not found \(required v[0-9\.]+\)." -"Asset cache miss; downloading from .*" -"Downloading .*" -"Successfully downloaded .*." -"Successfully stored .* to .*." +"A suitable version of cmake was not found \(required v[0-9\.]+\)\.", +"Trying to download cmake-[0-9.]+-[^.]+\.(zip|tar\.gz) using asset cache file://$assetCacheRegex/[0-9a-f]+" +"Asset cache miss; trying authoritative source https://github\.com/Kitware/CMake/releases/download/[^ ]+", +"Successfully downloaded cmake-[0-9.]+-[^.]+\.(zip|tar\.gz), storing to file://$assetCacheRegex/[0-9a-f]+", +"Store success" ) -join "`n" if (-not ($actual -match $expected)) { @@ -69,131 +82,434 @@ if (-not ($actual -match $expected)) { # Testing asset cache hit Refresh-Downloads Run-Vcpkg -TestArgs ($commonArgs + @('remove', 'vcpkg-internal-e2e-test-port')) -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("install", "vcpkg-internal-e2e-test-port", "--overlay-ports=$PSScriptRoot/../e2e-ports", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;", "--downloads-root=$DownloadsRoot")) -$actual = $actual -replace "`r`n", "`n" +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("fetch", "cmake", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;", "--downloads-root=$DownloadsRoot")) $expected = @( -"A suitable version of .* was not found \(required v[0-9\.]+\)." -"Asset cache hit for .*; downloaded from: .*" +"A suitable version of cmake was not found \(required v[0-9\.]+\)\.", +"Trying to download cmake-[0-9.]+-[^.]+\.(zip|tar\.gz) using asset cache file://$assetCacheRegex/[0-9a-z]+", +"Download successful! Asset cache hit, did not try authoritative source https://github\.com/Kitware/CMake/releases/download/[^ ]+" ) -join "`n" if (-not ($actual -match $expected)) { throw "Failure: asset cache hit" } -# Testing asset caching && x-block-orgin promises when --debug is passed (enabled) +# azurl (no), x-block-origin (no), asset-cache (n/a), download (fail) +# Expected: Download failure message, nothing about asset caching Refresh-TestRoot -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("install", "vcpkg-internal-e2e-test-port", "--overlay-ports=$PSScriptRoot/../e2e-ports", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;x-block-origin", "--downloads-root=$DownloadsRoot", "--debug")) -if (-not ($actual.Contains("[DEBUG] External asset downloads are blocked (x-block-origin is enabled)") -and $actual.Contains("[DEBUG] Asset caching is enabled."))) { - throw "Failure: couldn't find expected debug promises (asset caching enabled + x-block-origin enabled)" -} +$expected = @( +"^Downloading https://localhost:1234/foobar\.html -> example3\.html", +"error: curl: \(7\) Failed to connect to localhost port 1234( after \d+ ms)?: ((Could not|Couldn't) connect to server|Connection refused)", +"note: If you are using a proxy, please ensure your proxy settings are correct\.", +"Possible causes are:", +"1\. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to ``https//address:port``\.", +"This is not correct, because ``https://`` prefix claims the proxy is an HTTPS proxy, while your proxy \(v2ray, shadowsocksr, etc\.\.\.\) is an HTTP proxy\.", +"Try setting ``http://address:port`` to both HTTP_PROXY and HTTPS_PROXY instead\." +"2\. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your proxy software\. See: https://github\.com/microsoft/vcpkg-tool/pull/77", +"The value set by your proxy might be wrong, or have same ``https://`` prefix issue\.", +"3\. Your proxy's remote server is our of service\.", +"If you believe this is not a temporary download server failure and vcpkg needs to be changed to download this file from a different location, please submit an issue to https://github\.com/Microsoft/vcpkg/issues", +"$" +) -join "`n" -# Testing asset caching && x-block-orgin promises when --debug is passed (disabled) -Refresh-TestRoot -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("install", "vcpkg-internal-e2e-test-port", "--overlay-ports=$PSScriptRoot/../e2e-ports", "--x-asset-sources=clear", "--downloads-root=$DownloadsRoot", "--debug")) -if (-not ($actual.Contains("[DEBUG] External asset downloads are allowed (x-block-origin is disabled)") -and $actual.Contains("[DEBUG] Asset cache is not configured"))) { - throw "Failure: couldn't find expected debug promises (asset caching disabled + x-block-origin disabled)" +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://localhost:1234/foobar.html")) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { + throw "Failure: azurl (no), x-block-origin (no), asset-cache (n/a), download (fail)" } -# azurl (no), x-block-origin (no), asset-cache (n/a), download (fail) -# Expected: Download failure message, nothing about asset caching +# Also with multiple URLs Refresh-TestRoot -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://localhost:1234/foobar.html")) -if (-not ($actual.Contains("error: https://localhost:1234/foobar.html: curl failed to download with exit code 7"))) { +$expected = @( +"^Downloading example3\.html, trying https://localhost:1234/foobar\.html", +"Trying https://localhost:1235/baz\.html", +"error: curl: \(7\) Failed to connect to localhost port 1234( after \d+ ms)?: ((Could not|Couldn't) connect to server|Connection refused)", +"error: curl: \(7\) Failed to connect to localhost port 1235( after \d+ ms)?: ((Could not|Couldn't) connect to server|Connection refused)", +"note: If you are using a proxy, please ensure your proxy settings are correct\.", +"Possible causes are:", +"1\. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to ``https//address:port``\.", +"This is not correct, because ``https://`` prefix claims the proxy is an HTTPS proxy, while your proxy \(v2ray, shadowsocksr, etc\.\.\.\) is an HTTP proxy\.", +"Try setting ``http://address:port`` to both HTTP_PROXY and HTTPS_PROXY instead\." +"2\. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your proxy software\. See: https://github\.com/microsoft/vcpkg-tool/pull/77", +"The value set by your proxy might be wrong, or have same ``https://`` prefix issue\.", +"3\. Your proxy's remote server is our of service\.", +"If you believe this is not a temporary download server failure and vcpkg needs to be changed to download this file from a different location, please submit an issue to https://github\.com/Microsoft/vcpkg/issues", +"$" +) -join "`n" + +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "D06B93C883F8126A04589937A884032DF031B05518EED9D433EFB6447834DF2596AEBD500D69B8283E5702D988ED49655AE654C1683C7A4AE58BFA6B92F2B73A", "--url", "https://localhost:1234/foobar.html", "--url", "https://localhost:1235/baz.html")) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { throw "Failure: azurl (no), x-block-origin (no), asset-cache (n/a), download (fail)" } #azurl (no), x-block-origin (no), asset-cache (n/a), download (sha-mismatch) -#Expected: Download message with the "you might need to configure a proxy" message and with expected/actual sha +#Expected: Hash check failed message expected/actual sha. Note that the expected sha is changed to lowercase. Refresh-TestRoot +$expected = @( +"^Downloading https://example\.com -> example3\.html", +"[^\n]+example3\.html\.\d+\.part: error: download from https://example\.com had an unexpected hash", +"note: Expected: d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73b", +"note: Actual : d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", +"$" +) -join "`n" + $actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73b", "--url", "https://example.com")) -if (-not ($actual.Contains("Failed to download example3.html.") -and - $actual.Contains("If you are using a proxy, please ensure your proxy settings are correct.") -and - $actual.Contains("error: File does not have the expected hash:") -and - $actual.Contains("url: https://example.com") -and - $actual.Contains("Expected hash: d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73b") -and - $actual.Contains("Actual hash: d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a"))) { +Throw-IfNotFailed +if (-not ($actual -match $expected)) { throw "Failure: azurl (no), x-block-origin (no), asset-cache (n/a), download (sha-mismatch)" } # azurl (no), x-block-origin (no), asset-cache (n/a), download (succeed) # Expected: Download success message, nothing about asset caching Refresh-TestRoot +$expected = @( +"^Downloading https://example\.com -> example3\.html", +"Successfully downloaded example3\.html", +"$" +) -join "`n" + $actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com")) -if (-not ($actual.Contains("Downloading example3.html") -and - $actual.Contains("Successfully downloaded example3.html."))) { +Throw-IfFailed +if (-not ($actual -match $expected)) { + throw "Failure: azurl (no), x-block-origin (no), asset-cache (n/a), download (succeed)" +} + +# ... also with multiple authoritative URLs +if ($IsWindows) { + # WinHTTP + Refresh-TestRoot + $expected = @( + "^Downloading example3\.html, trying https://nonexistent\.example\.com", + "warning: Download https://nonexistent\.example\.com failed -- retrying after 1000ms", + "warning: Download https://nonexistent\.example\.com failed -- retrying after 2000ms", + "warning: Download https://nonexistent\.example\.com failed -- retrying after 4000ms", + "Trying https://example\.com", + "Successfully downloaded example3\.html", + "$" + ) -join "`n" + + $actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://nonexistent.example.com", "--url", "https://example.com")) + Throw-IfFailed + if (-not ($actual -match $expected)) { + throw "Failure: azurl (no), x-block-origin (no), asset-cache (n/a), download (succeed)" + } +} + +# Force curl with --header +Refresh-TestRoot +$expected = @( +"^Downloading example3\.html, trying https://nonexistent\.example\.com", +"warning: (Problem : timeout\.|Transient problem: timeout) Will retry in 1 seconds\. 3 retries left\.", +"warning: (Problem : timeout\.|Transient problem: timeout) Will retry in 2 seconds\. 2 retries left\.", +"warning: (Problem : timeout\.|Transient problem: timeout) Will retry in 4 seconds\. 1 retries left\.", +"Trying https://example\.com", +"Successfully downloaded example3\.html", +"$" +) -join "`n" + +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://nonexistent.example.com", "--url", "https://example.com", "--header", "Cache-Control: no-cache")) +Throw-IfFailed +if (-not ($actual -match $expected)) { throw "Failure: azurl (no), x-block-origin (no), asset-cache (n/a), download (succeed)" } # azurl (no), x-block-origin (yes), asset-cache (n/a), download (n/a) # Expected: Download failure message, nothing about asset caching, x-block-origin complaint Refresh-TestRoot +$expected = @( +"^Downloading example3\.html", +"error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source https://example\.com", +"$" +) -join "`n" $actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--x-asset-sources=clear;x-block-origin")) -if (-not ($actual.Contains("error: Missing example3.html and downloads are blocked by x-block-origin."))) { +Throw-IfNotFailed + if (-not ($actual -match $expected)) { throw "Failure: azurl (no), x-block-origin (yes), asset-cache (n/a), download (n/a)" } + # azurl (yes), x-block-origin (no), asset-cache (miss), download (fail) -# Expected: Download failure message, asset cache named, nothing about x-block-origin +# Expected: Download failure message, asset cache named, nothing about x-block-origin. Note that the expected SHA is changed to lowercase. Refresh-TestRoot -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://localhost:1234/foobar.html", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) -if (-not ($actual.Contains("Asset cache miss; downloading from https://localhost:1234/foobar.html") -and - $actual.Contains("Downloading example3.html") -and - $actual.Contains("error: file://$AssetCache") -and - $actual.Contains("curl failed to download with exit code 37"))) { +$expected = @( +"^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", +"Asset cache miss; trying authoritative source https://localhost:1234/foobar\.html", +"error: curl: \(37\) Couldn't open file [^\n]+", +"error: curl: \(7\) Failed to connect to localhost port 1234( after \d+ ms)?: ((Could not|Couldn't) connect to server|Connection refused)", +"note: If you are using a proxy, please ensure your proxy settings are correct\.", +"Possible causes are:", +"1\. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to ``https//address:port``\.", +"This is not correct, because ``https://`` prefix claims the proxy is an HTTPS proxy, while your proxy \(v2ray, shadowsocksr, etc\.\.\.\) is an HTTP proxy\.", +"Try setting ``http://address:port`` to both HTTP_PROXY and HTTPS_PROXY instead\." +"2\. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your proxy software\. See: https://github\.com/microsoft/vcpkg-tool/pull/77", +"The value set by your proxy might be wrong, or have same ``https://`` prefix issue\.", +"3\. Your proxy's remote server is our of service\.", +"If you believe this is not a temporary download server failure and vcpkg needs to be changed to download this file from a different location, please submit an issue to https://github\.com/Microsoft/vcpkg/issues", +"$" +) -join "`n" + +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "D06B93C883F8126A04589937A884032DF031B05518EED9D433EFB6447834DF2596AEBD500D69B8283E5702D988ED49655AE654C1683C7A4AE58BFA6B92F2B73A", "--url", "https://localhost:1234/foobar.html", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { throw "Failure: azurl (yes), x-block-origin (no), asset-cache (miss), download (fail)" } # azurl (yes), x-block-origin (no), asset-cache (hit), download (n/a) # Expected: Download success message, asset cache named, nothing about x-block-origin Refresh-TestRoot -$actual = $actual -replace "`r`n", "`n" -Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) +Run-Vcpkg -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) +Throw-IfFailed +Remove-Item "$downloadsRoot/example3.html" +$expected = @( +"^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", +"Download successful! Asset cache hit, did not try authoritative source https://example\.com", +"$" +) -join "`n" + +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) +Throw-IfFailed +if (-not ($actual -match $expected)) { + throw "Success: azurl (yes), x-block-origin (no), asset-cache (hit), download (n/a)" +} + +# azurl (yes), x-block-origin (no), asset-cache (hash mismatch), download (success) +# Expected: Asset cache named, nothing about x-block-origin +Remove-Item "$downloadsRoot/example3.html" +Set-Content -Path "$AssetCache/d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a" -Encoding Ascii -NoNewline -Value "The wrong hash content" +$expected = @( +"^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", +"Asset cache miss; trying authoritative source https://example\.com", +"Successfully downloaded example3\.html, storing to file://$assetCacheRegex/[0-9a-f]+", +"Store success", +"$" +) -join "`n" + $actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) -if (-not ($actual.Contains("Asset cache hit for example3.html; downloaded from: file://$AssetCache"))) { - throw "Failure: azurl (yes), x-block-origin (no), asset-cache (hit), download (n/a)" +Throw-IfFailed +if (-not ($actual -match $expected)) { + throw "Success: azurl (yes), x-block-origin (no), asset-cache (hit), download (n/a)" } # azurl (yes), x-block-origin (no), asset-cache (miss), download (sha-mismatch) -# Expected: Download message with "you might need to configure a proxy" and expected/actual sha -Refresh-TestRoot +# Expected: File read failure from the asset cache, hash check mismatch for the download. Proxy message emitted due to the asset cache miss even though it doesn't apply to the cache miss. +$expected = @( +"^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", +"Asset cache miss; trying authoritative source https://example\.com", +"error: curl: \(37\) Couldn't open file [^\n]+", +"note: If you are using a proxy, please ensure your proxy settings are correct\.", +"Possible causes are:", +"1\. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to ``https//address:port``\.", +"This is not correct, because ``https://`` prefix claims the proxy is an HTTPS proxy, while your proxy \(v2ray, shadowsocksr, etc\.\.\.\) is an HTTP proxy\.", +"Try setting ``http://address:port`` to both HTTP_PROXY and HTTPS_PROXY instead\." +"2\. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your proxy software\. See: https://github\.com/microsoft/vcpkg-tool/pull/77", +"The value set by your proxy might be wrong, or have same ``https://`` prefix issue\.", +"3\. Your proxy's remote server is our of service\.", +"If you believe this is not a temporary download server failure and vcpkg needs to be changed to download this file from a different location, please submit an issue to https://github\.com/Microsoft/vcpkg/issues", +"[^\n]+example3\.html\.\d+\.part: error: download from https://example\.com had an unexpected hash", +"note: Expected: d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73b", +"note: Actual : d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", +"$" +) -join "`n" $actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73b", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) -if (-not ($actual.Contains("Asset cache miss; downloading from https://example.com") -and - $actual.Contains("Downloading example3.html") -and - $actual.Contains("error: file://$AssetCache") -and - $actual.Contains("curl failed to download with exit code 37") -and - $actual.Contains("error: File does not have the expected hash:") -and - $actual.Contains("url: https://example.com") -and - $actual.Contains("Expected hash: d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73b") -and - $actual.Contains("Actual hash: d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a"))) { - throw "Failure: azurl (yes), x-block-origin (no), asset-cache (miss), download (sha-mismatch)" +Throw-IfNotFailed +if (-not ($actual -match $expected)) { + throw "Failure: azurl (yes), x-block-origin (no), asset-cache (sha-mismatch), download (sha-mismatch)" +} + +# azurl (yes), x-block-origin (no), asset-cache (sha-mismatch), download (sha-mismatch) +# Expected: Hash check failed message expected/actual sha +Copy-Item "$AssetCache/d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a" "$AssetCache/d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73b" +$expected = @( +"^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", +"Asset cache miss; trying authoritative source https://example\.com", +"[^\n]+example3\.html\.\d+\.part: error: download from file://$assetCacheRegex/[0-9a-z]+ had an unexpected hash", +"note: Expected: d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73b", +"note: Actual : d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", +"[^\n]+example3\.html\.\d+\.part: error: download from https://example\.com had an unexpected hash", +"note: Expected: d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73b", +"note: Actual : d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", +"$" +) -join "`n" +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73b", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { + throw "Failure: azurl (yes), x-block-origin (no), asset-cache (sha-mismatch), download (sha-mismatch)" } # azurl (yes), x-block-origin (no), asset-cache (miss), download (succeed) # Expected: Download success message, asset cache upload, nothing about x-block-origin Refresh-TestRoot +$expected = @( +"^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", +"Asset cache miss; trying authoritative source https://example\.com", +"Successfully downloaded example3\.html, storing to file://$assetCacheRegex/[0-9a-z]+", +"Store success", +"$" +) -join "`n" + $actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) -if (-not ($actual.Contains("Asset cache miss; downloading from https://example.com") -and - $actual.Contains("Downloading example3.html") -and - $actual.Contains("Successfully downloaded example3.html.") -and - $actual.Contains("Successfully stored example3.html to file://$AssetCache"))) { - throw "Failure: azurl (yes), x-block-origin (no), asset-cache (miss), download (succeed)" +Throw-IfFailed +if (-not ($actual -match $expected)) { + throw "Success: azurl (yes), x-block-origin (no), asset-cache (miss), download (succeed)" } # azurl (yes), x-block-origin (yes), asset-cache (miss), download (n/a) # Expected: Download failure message, which asset cache was tried, x-block-origin complaint Refresh-TestRoot -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;x-block-origin")) -if (-not ($actual.Contains("Asset cache miss for example3.html and downloads are blocked by x-block-origin.") -and - $actual.Contains("error: Missing example3.html and downloads are blocked by x-block-origin."))) { +$expected = @( +"^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", +"error: curl: \(37\) Couldn't open file [^\n]+", +"error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source https://example\.com", +"note: or https://alternate\.example\.com", +"note: If you are using a proxy, please ensure your proxy settings are correct\.", +"Possible causes are:", +"1\. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to ``https//address:port``\.", +"This is not correct, because ``https://`` prefix claims the proxy is an HTTPS proxy, while your proxy \(v2ray, shadowsocksr, etc\.\.\.\) is an HTTP proxy\.", +"Try setting ``http://address:port`` to both HTTP_PROXY and HTTPS_PROXY instead\." +"2\. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your proxy software\. See: https://github\.com/microsoft/vcpkg-tool/pull/77", +"The value set by your proxy might be wrong, or have same ``https://`` prefix issue\.", +"3\. Your proxy's remote server is our of service\.", +"If you believe this is not a temporary download server failure and vcpkg needs to be changed to download this file from a different location, please submit an issue to https://github\.com/Microsoft/vcpkg/issues", +"$" +) -join "`n" + +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--url", "https://alternate.example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;x-block-origin")) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { throw "Failure: azurl (yes), x-block-origin (yes), asset-cache (miss), download (n/a)" } # azurl (yes), x-block-origin (yes), asset-cache (hit), download (n/a) # Expected: Download success message, asset cache named, nothing about x-block-origin Refresh-TestRoot -Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) -$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;x-block-origin")) -if (-not ($actual.Contains("Asset cache hit for example3.html; downloaded from: file://$AssetCache"))) { - throw "Failure: azurl (yes), x-block-origin (yes), asset-cache (hit), download (n/a)" +$expected = @( +"^Trying to download example3\.html using asset cache file://$assetCacheRegex/[0-9a-z]+", +"Download successful! Asset cache hit, did not try authoritative source https://example\.com, or https://alternate\.example\.com", +"$" +) -join "`n" +Run-Vcpkg -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite")) +Throw-IfFailed +Remove-Item "$downloadsRoot/example3.html" +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", "--url", "https://example.com", "--url", "https://alternate.example.com", "--x-asset-sources=x-azurl,file://$AssetCache,,readwrite;x-block-origin")) +Throw-IfFailed +if (-not ($actual -match $expected)) { + throw "Success: azurl (yes), x-block-origin (yes), asset-cache (hit), download (n/a)" +} + +# Testing x-download failure with asset cache (x-script) and x-block-origin settings +$env:X_VCPKG_ASSET_SOURCES = "clear;x-script,pwsh $PSScriptRoot/../e2e-assets/asset-caching/failing-script.ps1 {url} {sha512} {dst};x-block-origin" +$expected = @( +"^Trying to download example3.html using asset cache script", +"Script download error", +"error: the asset cache script returned nonzero exit code 1", +"note: the full script command line was: pwsh .+/failing-script\.ps1 https://example\.com d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a `"?[^`"]+example3\.html\.\d+\.part`"?", +"error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source https://example\.com", +"$" +) -join "`n" +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--url", "https://example.com", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a")) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { + throw "Failure: azurl (no), x-block-origin (yes), asset-cache (hit), download (n/a)" +} + +Refresh-TestRoot +$env:X_VCPKG_ASSET_SOURCES = "clear;x-script,pwsh $PSScriptRoot/../e2e-assets/asset-caching/no-file-script.ps1 {url} {sha512} {dst};x-block-origin" +$expected = @( +"^Trying to download example3.html using asset cache script", +"Not creating a file", +"[^\n]+example3\.html\.\d+\.part: error: the asset cache script returned success but did not create expected result file", +"note: the full script command line was: pwsh .+/no-file-script\.ps1 https://example\.com d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a `"?[^`"]+example3\.html\.\d+\.part`"?", +"error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source https://example\.com", +"$" +) -join "`n" +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--url", "https://example.com", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a")) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { + throw "Failure: azurl (no), x-block-origin (yes), asset-cache (hit), download (n/a)" } + +Refresh-TestRoot +$env:X_VCPKG_ASSET_SOURCES = "clear;x-script,pwsh $PSScriptRoot/../e2e-assets/asset-caching/bad-hash-script.ps1 -File {dst};x-block-origin" +$expected = @( +"^Trying to download example3.html using asset cache script", +"Creating file with the wrong hash", +"[^\n]+example3\.html\.\d+\.part: error: the asset cache script returned success but the resulting file has an unexpected hash", +"note: the full script command line was: pwsh .+/bad-hash-script\.ps1 -File `"?[^`"]+example3\.html\.\d+\.part`"?", +"note: Expected: d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a", +"note: Actual : cc9c9070d8a54bfc32d6be2eb01b531f22f657d868200fbcdc7c4cc5f31e92909bd7c83971bebefa918c2c34e53d859ed49a79f4a943f36ec521fc0544b30d9e", +"error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source https://example\.com", +"$" +) -join "`n" +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--url", "https://example.com", "--sha512", "d06b93c883f8126a04589937a884032df031b05518eed9d433efb6447834df2596aebd500d69b8283e5702d988ed49655ae654c1683c7a4ae58bfa6b92f2b73a")) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { + throw "Failure: azurl (no), x-block-origin (yes), asset-cache (hit), download (n/a)" +} + +# Testing x-download success with asset cache (x-script) and x-block-origin settings +Refresh-TestRoot +$expected = @( +"^Trying to download example3.html using asset cache script", +"Download successful! Asset cache hit, did not try authoritative source https://example\.com/hello-world.txt", +"$" +) -join "`n" +$env:X_VCPKG_ASSET_SOURCES = "clear;x-script,$TestScriptAssetCacheExe {url} {sha512} {dst};x-block-origin" +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/example3.html", "--url", "https://example.com/hello-world.txt", "--sha512", "09e1e2a84c92b56c8280f4a1203c7cffd61b162cfe987278d4d6be9afbf38c0e8934cdadf83751f4e99d111352bffefc958e5a4852c8a7a29c95742ce59288a8")) +Throw-IfFailed +if (-not ($actual -match $expected)) { + throw "Success: x-script download success message" +} + +# Testing zero SHA does not try subsequent URLs and emits its special message +Remove-Item env:X_VCPKG_ASSET_SOURCES +Refresh-TestRoot +$testFile = Join-Path $TestingRoot 'download-this.txt' +Set-Content -Path $testFile -Value "This is some content to download" -Encoding Ascii -NoNewline +$downloadTargetUrl = "file://" + $testFile.Replace("\", "/") +$downloadTargetUrlRegex = [regex]::Escape($downloadTargetUrl) +$expected = @( +"^Downloading $downloadTargetUrlRegex -> download-result\.txt", +"Successfully downloaded download-result\.txt", +"error: failing download because the expected SHA512 was all zeros, please change the expected SHA512 to: b3b907ef86c0389954e2a4c85a4ac3d9228129cbe52202fc979873e03089bab448d6c9ae48f1a4925df3b496e3f6fdefbd997b925f3fc93f9418f24a3421e97d", +"$" +) -join "`n" + +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/download-result.txt", "--sha512", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "--url", $downloadTargetUrl)) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { + throw "Failure: zero sha" +} + +# Testing zero SHA but with x-script that wants SHA +# Note that this prints the 'unknown SHA' message for the x-script even though a SHA was supplied; we don't want to ever ask the script for all zeroes +$env:X_VCPKG_ASSET_SOURCES = "clear;x-script,some-script.ps1 {sha512};x-block-origin" +$expected = @( +"^Trying to download download-result\.txt using asset cache script", +"error: the script template some-script\.ps1 {sha512} requires a SHA, but no SHA is known for attempted download of $downloadTargetUrlRegex", +"error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source $downloadTargetUrlRegex", +"$" +) -join "`n" + +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/download-result.txt", "--sha512", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "--url", $downloadTargetUrl)) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { + throw "Failure: zero sha + x-script" +} + +# Testing unknown replacement in x-script +$env:X_VCPKG_ASSET_SOURCES = "clear;x-script,some-script.ps1 {sha};x-block-origin" +$expected = @( +"^Trying to download download-result\.txt using asset cache script", +"error: the script template some-script.ps1 {sha} contains unknown replacement sha", +"note: if you want this on the literal command line, use {{sha}}", +"error: there were no asset cache hits, and x-block-origin blocks trying the authoritative source $downloadTargetUrlRegex", +"$" +) -join "`n" + +$actual = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("x-download", "$downloadsRoot/download-result.txt", "--sha512", "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "--url", $downloadTargetUrl)) +Throw-IfNotFailed +if (-not ($actual -match $expected)) { + throw "Failure: bad replacement" +} + diff --git a/azure-pipelines/end-to-end-tests-dir/autocomplete.ps1 b/azure-pipelines/end-to-end-tests-dir/autocomplete-command.ps1 similarity index 100% rename from azure-pipelines/end-to-end-tests-dir/autocomplete.ps1 rename to azure-pipelines/end-to-end-tests-dir/autocomplete-command.ps1 diff --git a/azure-pipelines/end-to-end-tests-dir/autocomplete-posh-vcpkg.ps1 b/azure-pipelines/end-to-end-tests-dir/autocomplete-posh-vcpkg.ps1 new file mode 100644 index 0000000000..50a350ca9b --- /dev/null +++ b/azure-pipelines/end-to-end-tests-dir/autocomplete-posh-vcpkg.ps1 @@ -0,0 +1,37 @@ +Set-StrictMode -Version Latest + +[string]$poshVcpkgModulePath = "$PSScriptRoot/../../scripts/posh-vcpkg.psd1" +[System.IO.FileInfo]$vcpkgExe = $VcpkgItem + +[string]$TestSpecsDir = "$PSScriptRoot/../e2e-specs" + +$containerPosh = New-PesterContainer -Path @( + "$TestSpecsDir/autocomplete-posh-vcpkg.Tests.ps1" +) -Data @( + @{ + poshVcpkgModulePath = $poshVcpkgModulePath + vcpkgExe = $vcpkgExe + } +) + +if (-not (Test-Path variable:IsWindows)) { Set-Variable IsWindows $true } + +$configuration = [PesterConfiguration]@{ + Run = @{ + Container = @( + $containerPosh + ) + } + Output = @{ + Verbosity = 'Detailed' + } + Filter = @{ + ExcludeTag = @{ + NonWindowsOnly = -not $IsWindows + WindowsOnly = $IsWindows + CoreOnly = 'Core' -eq $PSEdition + }.GetEnumerator().Where{ -not $_.Value }.ForEach{ $_.Name } + } +} + +Invoke-Pester -Configuration $configuration diff --git a/azure-pipelines/end-to-end-tests-dir/build-test-ports.ps1 b/azure-pipelines/end-to-end-tests-dir/build-test-ports.ps1 index 42bf5aadc8..635d94fc72 100644 --- a/azure-pipelines/end-to-end-tests-dir/build-test-ports.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/build-test-ports.ps1 @@ -28,6 +28,12 @@ Throw-IfFailed Run-Vcpkg @commonArgs --overlay-ports="$PSScriptRoot/../e2e-ports" --overlay-ports="$PSScriptRoot/../e2e-ports/broken-manifests" install control-file Throw-IfFailed +$output = Run-VcpkgAndCaptureOutput @commonArgs --overlay-ports="$PSScriptRoot/../e2e-ports/broken-manifests" install broken-duplicate-overrides +Throw-IfNotFailed +if ($output -notmatch "vcpkg\.json: error: \$\.overrides\[1\] \(an override\): zlib already has an override") { + throw 'Did not detect duplicate override' +} + $output = Run-VcpkgAndCaptureOutput @commonArgs --overlay-ports="$PSScriptRoot/../e2e-ports/broken-manifests" install broken-no-name Throw-IfNotFailed if ($output -notmatch "missing required field 'name'") { diff --git a/azure-pipelines/end-to-end-tests-dir/ci-verify-versions.ps1 b/azure-pipelines/end-to-end-tests-dir/ci-verify-versions.ps1 index 5db2e83460..ddb513aac9 100644 --- a/azure-pipelines/end-to-end-tests-dir/ci-verify-versions.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/ci-verify-versions.ps1 @@ -153,7 +153,9 @@ $buildtreesRoot/versioning_/versions/version-scheme-mismatch/89c88798a9fa17ea675 note: versions must be unique, even if they are declared with different schemes "@ +Remove-Problem-Matchers $actual = Run-VcpkgAndCaptureOutput x-ci-verify-versions @directoryArgs "--x-builtin-ports-root=$TestingRoot/ci-verify-versions-registry/ports" "--x-builtin-registry-versions-dir=$TestingRoot/ci-verify-versions-registry/versions" --verbose --verify-git-trees +Restore-Problem-Matchers Throw-IfNotFailed function Sanitize() { diff --git a/azure-pipelines/end-to-end-tests-dir/commands.extract.ps1 b/azure-pipelines/end-to-end-tests-dir/commands.extract.ps1 index 366ce00147..f9776b2d5b 100644 --- a/azure-pipelines/end-to-end-tests-dir/commands.extract.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/commands.extract.ps1 @@ -12,8 +12,8 @@ if (-Not (Test-Path $extractedFilePath)) { if (-Not $IsWindows) { $unixMode = (Get-Item $extractedFilePath).UnixMode - if ($unixMode -ne "-rwxr-xr-x") { - throw "File does not have +x permission. UnixMode: $unixMode" + if (-not ($unixMode -match 'x.*x.*x')) { + throw "File does not have +x permission. $extractedFilePath UnixMode: $unixMode" } } diff --git a/azure-pipelines/end-to-end-tests-dir/env-tools.ps1 b/azure-pipelines/end-to-end-tests-dir/env-tools.ps1 index 90b9ea7db7..3ccea209d9 100644 --- a/azure-pipelines/end-to-end-tests-dir/env-tools.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/env-tools.ps1 @@ -4,4 +4,6 @@ $env:VCPKG_DOWNLOADS = Join-Path $TestingRoot 'empty downloads' Run-Vcpkg env --bin --tools --python set if ($IsWindows) { Throw-IfFailed +} else { + Throw-IfNotFailed } diff --git a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 index 831b70f1cb..768ab2576d 100644 --- a/azure-pipelines/end-to-end-tests-dir/fetch.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/fetch.ps1 @@ -1,95 +1,123 @@ . $PSScriptRoot/../end-to-end-tests-prelude.ps1 +$VcpkgToolsJsonSchemaFile = (Get-Item "$PSScriptRoot/../../docs/vcpkg-tools.schema.json").FullName +if (-not (Test-Json -ea:0 -LiteralPath "$VcpkgRoot/scripts/vcpkg-tools.json" -SchemaFile $VcpkgToolsJsonSchemaFile)) { + throw "real vcpkg-tools.json doesn't conform to schema" +} + if (-not $IsMacOS -and -not $IsLinux) { "" | Out-File -enc ascii $(Join-Path $TestingRoot .vcpkg-root) $Scripts = Join-Path $TestingRoot "scripts" mkdir $Scripts | Out-Null + + $VcpkgToolsJson = Join-Path $Scripts "vcpkg-tools.json" + + $7zip_version = "19.00" + $ninja_version = "1.10.2" -@" - - - - 19.00 - Files\7-Zip\7z.exe - https://www.7-zip.org/a/7z1900-x64.msi - 7837a8677a01eed9c3309923f7084bc864063ba214ee169882c5b04a7a8b198ed052c15e981860d9d7952c98f459a4fab87a72fd78e7d0303004dcb86f4324c8 - 7z1900-x64.msi - - - 1.10.2 - ninja.exe - https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip - 6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3 - ninja-win-1.10.2.zip - - - 1.10.2 - ninja.exe - https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip - 6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3 - ninja-win-1.10.2.zip - - - 3.22.2 - cmake-3.22.2-windows-i386\bin\cmake.exe - https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-windows-i386.zip - 969d3d58d56d8fa3cc3acae2b949bf58abab945f70ae292ff20c9060d845dfc094c613c367a924abff47f307cc33af1467cdb9b75bb857868e38b2c7cdc72f79 - cmake-3.22.2-windows-i386.zip - - - 3.22.2 - cmake-3.22.2-macos-universal/CMake.app/Contents/bin/cmake - https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-macos-universal.tar.gz - 08104f608ecb9a5cfef38e79f0957d21e425616c0677781445492f82cbfec805113e3b5eb4bc737b707bb26a00678e7bd55e17555a5611c08b0b9b44ac5136ac - cmake-3.22.2-macos-universal.tar.gz - - - 3.22.2 - cmake-3.22.2-linux-x86_64/bin/cmake - https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz - 579e08b086f6903ef063697fca1dc2692f68a7341dd35998990b772b4221cdb5b1deecfa73bad9d46817ef09e58882b2adff9d64f959c01002c11448a878746b - cmake-3.22.2linux-x86_64.tar.gz - - - 3.20.4 - usr/local/bin/cmake - https://pkg.freebsd.org/FreeBSD:13:amd64/quarterly/All/cmake-3.20.4.txz - 3e5b675d7ff924f92996d912e2365582e687375109ef99c9073fb8196bb329243a406b218cf1358d7cc518988b311ce9e5bf87de4d64f2e6377b7c2bc8894475 - cmake-3.20.4.txz - - -"@ | % { $_ -replace "`r","" } | Out-File -enc ascii $(Join-Path $Scripts "vcpkgTools.xml") + @' +{ + "schema-version": 1, + "tools": [{ + "name": "7zip_msi", + "os": "windows", + "version": "19.00", + "executable": "Files\\7-Zip\\7z.exe", + "url": "https://www.7-zip.org/a/7z1900-x64.msi", + "sha512": "7837a8677a01eed9c3309923f7084bc864063ba214ee169882c5b04a7a8b198ed052c15e981860d9d7952c98f459a4fab87a72fd78e7d0303004dcb86f4324c8", + "archive": "7z1900-x64.msi" + }, + { + "name": "ninja-testing", + "os": "windows", + "version": "1.10.2", + "executable": "ninja.exe", + "url": "https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip", + "sha512": "6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3", + "archive": "ninja-win-1.10.2.zip" + }, + { + "name": "ninja", + "os": "windows", + "version": "1.10.2", + "executable": "ninja.exe", + "url": "https://github.com/ninja-build/ninja/releases/download/v1.10.2/ninja-win.zip", + "sha512": "6004140d92e86afbb17b49c49037ccd0786ce238f340f7d0e62b4b0c29ed0d6ad0bab11feda2094ae849c387d70d63504393714ed0a1f4d3a1f155af7a4f1ba3", + "archive": "ninja-win-1.10.2.zip" + }, + { + "name": "cmake", + "os": "windows", + "version": "3.22.2", + "executable": "cmake-3.22.2-windows-i386\\bin\\cmake.exe", + "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-windows-i386.zip", + "sha512": "969d3d58d56d8fa3cc3acae2b949bf58abab945f70ae292ff20c9060d845dfc094c613c367a924abff47f307cc33af1467cdb9b75bb857868e38b2c7cdc72f79", + "archive": "cmake-3.22.2-windows-i386.zip" + }, + { + "name": "cmake", + "os": "osx", + "version": "3.22.2", + "executable": "cmake-3.22.2-macos-universal/CMake.app/Contents/bin/cmake", + "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-macos-universal.tar.gz", + "sha512": "08104f608ecb9a5cfef38e79f0957d21e425616c0677781445492f82cbfec805113e3b5eb4bc737b707bb26a00678e7bd55e17555a5611c08b0b9b44ac5136ac", + "archive": "cmake-3.22.2-macos-universal.tar.gz" + }, + { + "name": "cmake", + "os": "linux", + "version": "3.22.2", + "executable": "cmake-3.22.2-linux-x86_64/bin/cmake", + "url": "https://github.com/Kitware/CMake/releases/download/v3.22.2/cmake-3.22.2-linux-x86_64.tar.gz", + "sha512": "579e08b086f6903ef063697fca1dc2692f68a7341dd35998990b772b4221cdb5b1deecfa73bad9d46817ef09e58882b2adff9d64f959c01002c11448a878746b", + "archive": "cmake-3.22.2linux-x86_64.tar.gz" + }, + { + "name": "cmake", + "os": "freebsd", + "version": "3.20.4", + "executable": "/usr/local/bin/cmake", + "url": "https://pkg.freebsd.org/FreeBSD:13:amd64/quarterly/All/cmake-3.20.4.txz", + "sha512": "3e5b675d7ff924f92996d912e2365582e687375109ef99c9073fb8196bb329243a406b218cf1358d7cc518988b311ce9e5bf87de4d64f2e6377b7c2bc8894475", + "archive": "cmake-3.20.4.txz" + }] +} +'@ | % { $_ -replace "`r","" } | Out-File -enc ascii $VcpkgToolsJson + + if (-not (Test-Json -ea:0 -LiteralPath $VcpkgToolsJson -SchemaFile $VcpkgToolsJsonSchemaFile)) { + throw "testing vcpkg-tools.json doesn't conform to schema" + } $env:VCPKG_DOWNLOADS = Join-Path $TestingRoot 'down loads' - Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "7zip", "--vcpkg-root=$TestingRoot")) + Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "7zip_msi", "--vcpkg-root=$TestingRoot")) Throw-IfFailed - Require-FileExists "$TestingRoot/down loads/tools/7zip-19.00-windows/Files/7-Zip/7z.exe" + Require-FileExists "$env:VCPKG_DOWNLOADS/tools/7zip_msi-19.00-windows/Files/7-Zip/7z.exe" Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja-testing", "--vcpkg-root=$TestingRoot")) Throw-IfFailed - Require-FileExists "$TestingRoot/down loads/tools/ninja-testing-1.10.2-windows/ninja.exe" + Require-FileExists "$env:VCPKG_DOWNLOADS/tools/ninja-testing-1.10.2-windows/ninja.exe" $path = $env:PATH - $env:PATH = "$path;$TestingRoot/down loads/tools/ninja-testing-1.10.2-windows" + $env:PATH = "$path;$env:VCPKG_DOWNLOADS/tools/ninja-testing-1.10.2-windows" Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) Throw-IfFailed - Require-FileNotExists "$TestingRoot/down loads/tools/ninja-1.10.2-windows/ninja.exe" + Require-FileNotExists "$env:VCPKG_DOWNLOADS/tools/ninja-1.10.2-windows/ninja.exe" $env:VCPKG_FORCE_DOWNLOADED_BINARIES = "1" Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) Throw-IfFailed - Require-FileExists "$TestingRoot/down loads/tools/ninja-1.10.2-windows/ninja.exe" + Require-FileExists "$env:VCPKG_DOWNLOADS/tools/ninja-1.10.2-windows/ninja.exe" - Remove-Item -Recurse -Force "$TestingRoot/down loads/tools/ninja-1.10.2-windows" -ErrorAction SilentlyContinue + Remove-Item -Recurse -Force "$env:VCPKG_DOWNLOADS/tools/ninja-1.10.2-windows" -ErrorAction SilentlyContinue Remove-Item env:VCPKG_FORCE_DOWNLOADED_BINARIES $env:VCPKG_FORCE_SYSTEM_BINARIES = "1" $env:PATH = "$PSScriptRoot\..\e2e-assets\fetch;$path" Run-Vcpkg -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot")) Throw-IfFailed - Require-FileNotExists "$TestingRoot/down loads/tools/ninja-1.10.2-windows/ninja.exe" + Require-FileNotExists "$env:VCPKG_DOWNLOADS/tools/ninja-1.10.2-windows/ninja.exe" Remove-Item env:VCPKG_FORCE_SYSTEM_BINARIES $out = Run-VcpkgAndCaptureOutput -TestArgs ($commonArgs + @("fetch", "ninja", "--vcpkg-root=$TestingRoot", "--x-stderr-status")) diff --git a/azure-pipelines/end-to-end-tests-dir/manifests.ps1 b/azure-pipelines/end-to-end-tests-dir/manifests.ps1 index 2d900cfb7a..2441e7b34d 100644 --- a/azure-pipelines/end-to-end-tests-dir/manifests.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/manifests.ps1 @@ -7,6 +7,8 @@ $commonArgs += @("--x-builtin-ports-root=$PSScriptRoot/../e2e-ports") $manifestDirArgs = $commonArgs + @("--x-manifest-root=$manifestDir") $noDefaultFeatureArgs = $manifestDirArgs + @('--x-no-default-features') +$vcpkgDir = Join-Path -Path $installRoot -ChildPath "vcpkg" +$manifestInfoPath = Join-Path -Path $vcpkgDir -ChildPath "manifest-info.json" function feature { @{ 'description' = ''; @@ -53,13 +55,18 @@ Throw-IfNotFailed Write-Trace "test manifest features: no-default-features, features = []" Run-Vcpkg install @manifestDirArgs --x-no-default-features Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + Write-Trace "test manifest features: default-features, features = [core]" Run-Vcpkg install @manifestDirArgs --x-feature=core Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + # test having both Write-Trace "test manifest features: no-default-features, features = [core]" Run-Vcpkg install @manifestDirArgs --x-no-default-features --x-feature=core Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir Write-Trace "test manifest features: no-default-features, features = [default-fail]" Run-Vcpkg install @manifestDirArgs --x-no-default-features --x-feature=default-fail @@ -71,26 +78,38 @@ Throw-IfNotFailed Write-Trace "test manifest features: no-default-features, features = [copied-feature]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=copied-feature Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + Write-Trace "test manifest features: no-default-features, features = [copied-feature, copied-feature]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=copied-feature --x-feature=copied-feature Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir Write-Trace "test manifest features: no-default-features, features = [multiple-dep-1, multiple-dep-2]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=multiple-dep-1 --x-feature=multiple-dep-2 Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir Write-Trace "test manifest features: no-default-features, features = [no-default-features-1]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=no-default-features-1 Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + Write-Trace "test manifest features: no-default-features, features = [no-default-features-2]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=no-default-features-2 Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + Write-Trace "test manifest features: no-default-features, features = [no-default-features-1,no-default-features-3]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=no-default-features-1 --x-feature=no-default-features-3 Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + Write-Trace "test manifest features: no-default-features, features = [no-default-features-3]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=no-default-features-3 Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + $vcpkgJson = @{ 'default-features' = @( 'default-fail' ); @@ -122,17 +141,23 @@ Throw-IfNotFailed Write-Trace "test nameless manifest features: no-default-features, features = []" Run-Vcpkg install @manifestDirArgs --x-no-default-features Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + Write-Trace "test nameless manifest features: default-features, features = [core]" Run-Vcpkg install @manifestDirArgs --x-feature=core Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + # test having both Write-Trace "test nameless manifest features: no-default-features, features = [core]" Run-Vcpkg install @manifestDirArgs --x-no-default-features --x-feature=core Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir Write-Trace "test nameless manifest features: no-default-features, features = [default-fail]" Run-Vcpkg install @manifestDirArgs --x-no-default-features --x-feature=default-fail Throw-IfNotFailed + Write-Trace "test nameless manifest features: default-features, features = [core, default-fail]" Run-Vcpkg install @manifestDirArgs --x-feature=core --x-feature=default-fail Throw-IfNotFailed @@ -140,20 +165,27 @@ Throw-IfNotFailed Write-Trace "test nameless manifest features: no-default-features, features = [copied-feature]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=copied-feature Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + Write-Trace "test nameless manifest features: no-default-features, features = [copied-feature, copied-feature]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=copied-feature --x-feature=copied-feature Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir Write-Trace "test nameless manifest features: no-default-features, features = [multiple-dep-1, multiple-dep-2]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=multiple-dep-1 --x-feature=multiple-dep-2 Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir Write-Trace "test nameless manifest features: no-default-features, features = [no-default-features-1]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=no-default-features-1 Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + Write-Trace "test nameless manifest features: no-default-features, features = [no-default-features-2]" Run-Vcpkg install @noDefaultFeatureArgs --x-feature=no-default-features-2 Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir $vcpkgJson = @{ 'name' = "manifest-test"; @@ -181,10 +213,12 @@ Set-Content -Path "$manifestDir/manifest-test/vcpkg.json" ` Write-Trace "test manifest features: self-reference, features = [a]" Run-Vcpkg install @manifestDirArgs --x-feature=a Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir Write-Trace "test manifest features: self-reference, features = [a], with overlay" Run-Vcpkg install @manifestDirArgs --x-feature=a "--overlay-ports=$manifestDir/manifest-test" Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir Write-Trace "test manifest install with specific package names fails" $output = Run-VcpkgAndCaptureOutput install @manifestDirArgs vcpkg-empty-port @@ -194,6 +228,8 @@ Throw-IfNonContains -Expected 'error: In manifest mode, `vcpkg install` does not Write-Trace "test manifest install with specific package names forced to classic mode succeeds" $output = Run-VcpkgAndCaptureOutput install @manifestDirArgs --classic vcpkg-empty-port Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestDir + $expected = @" The following packages will be built and installed: vcpkg-empty-port: diff --git a/azure-pipelines/end-to-end-tests-dir/overlays.ps1 b/azure-pipelines/end-to-end-tests-dir/overlays.ps1 index bf58bbf0cf..74da2f3721 100644 --- a/azure-pipelines/end-to-end-tests-dir/overlays.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/overlays.ps1 @@ -1,10 +1,14 @@ . $PSScriptRoot/../end-to-end-tests-prelude.ps1 +$vcpkgDir = Join-Path -Path $installRoot -ChildPath "vcpkg" +$manifestInfoPath = Join-Path -Path $vcpkgDir -ChildPath "manifest-info.json" + # Tests a simple project with overlay ports and triplets configured on a vcpkg-configuration.json file Copy-Item -Recurse -LiteralPath @( - "$PSScriptRoot/../e2e-projects/overlays-project-with-config", + "$PSScriptRoot/../e2e-projects/overlays-malformed-shadowing", + "$PSScriptRoot/../e2e-projects/overlays-malformed-shadowing-builtin", "$PSScriptRoot/../e2e-projects/overlays-project-config-embedded", - "$PSScriptRoot/../e2e-projects/overlays-bad-paths" + "$PSScriptRoot/../e2e-projects/overlays-project-with-config" ) $TestingRoot $manifestRoot = "$TestingRoot/overlays-project-with-config" @@ -16,6 +20,7 @@ Run-Vcpkg install --x-manifest-root=$manifestRoot ` --x-install-root=$installRoot ` --triplet fancy-triplet Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestRoot # Tests overlays configured in env and cli on a project with configuration embedded on the manifest file $manifestRoot = "$TestingRoot/overlays-project-config-embedded" @@ -26,14 +31,39 @@ Run-Vcpkg install --x-manifest-root=$manifestRoot ` --x-install-root=$installRoot ` --triplet fancy-config-embedded-triplet Throw-IfFailed +Test-ManifestInfo -ManifestInfoPath $ManifestInfoPath -VcpkgDir $vcpkgDir -ManifestRoot $manifestRoot + +# ... and with command line overlay-ports being 'dot' +pushd "$manifestRoot/cli-overlays" +try { + Run-Vcpkg install --x-manifest-root=$manifestRoot ` + --overlay-ports=. ` + --overlay-triplets=$manifestRoot/my-triplets ` + --x-install-root=$installRoot ` + --triplet fancy-config-embedded-triplet + Throw-IfFailed +} finally { + popd +} # Config with bad paths -$manifestRoot = "$TestingRoot/overlays-bad-paths" +$manifestRoot = "$PSScriptRoot/../e2e-projects/overlays-bad-paths" $env:VCPKG_OVERLAY_PORTS = "$manifestRoot/env_overlays" Run-Vcpkg install --x-manifest-root=$manifestRoot ` --overlay-triplets=$manifestRoot/my-triplets ` --x-install-root=$installRoot Throw-IfNotFailed +Remove-Item env:VCPKG_OVERLAY_PORTS + +# Test that once an overlay port is loaded for a name, subsequent ports are not considered +$manifestRoot = "$TestingRoot/overlays-malformed-shadowing" +Run-Vcpkg install --x-manifest-root=$manifestRoot +Throw-IfFailed + +# ... even if that subsequent port is the builtin root +$manifestRoot = "$TestingRoot/overlays-malformed-shadowing-builtin" +Run-Vcpkg install --x-manifest-root=$manifestRoot --x-builtin-ports-root "$manifestRoot/builtin-malformed" +Throw-IfFailed # Test overlay_triplet paths remain relative to the manifest root after x-update-baseline $manifestRoot = "$TestingRoot/overlays-project-with-config" @@ -47,11 +77,27 @@ $overlaysAfter = $configurationAfter."overlay-triplets" $notEqual = @(Compare-Object $overlaysBefore $overlaysAfter -SyncWindow 0).Length -ne 0 if ($notEqual) { - Throw "Overlay triplets paths changed after x-update-baseline" + Throw "Overlay triplets paths changed after x-update-baseline" } +# Test that trying to declare overlay-ports as '.' fails +$manifestRoot = "$PSScriptRoot/../e2e-projects/overlays-dot" +$output = Run-VcpkgAndCaptureStdErr install --x-manifest-root=$manifestRoot --x-install-root=$installRoot +Throw-IfNotFailed +Throw-IfNonContains -Actual $output -Expected @" +error: The manifest directory cannot be the same as a directory configured in overlay-ports, so "overlay-ports" values cannot be ".". +"@ + +# Test that trying to declare overlay-ports as the same directory in a roundabout way fails +$manifestRoot = "$PSScriptRoot/../e2e-projects/overlays-not-quite-dot" +$canonicalManifestRoot = (Get-Item $manifestRoot).FullName +$output = Run-VcpkgAndCaptureStdErr install --x-manifest-root=$manifestRoot --x-install-root=$installRoot +Throw-IfNotFailed +Throw-IfNonContains -Actual $output -Expected @" +The manifest directory ($canonicalManifestRoot) cannot be the same as a directory configured in overlay-ports. +"@ + # Test that removals can happen without the overlay triplets -Remove-Item env:VCPKG_OVERLAY_PORTS Refresh-TestRoot Run-Vcpkg install another-vcpkg-empty-port:fancy-triplet ` --overlay-ports=$PSScriptRoot/../e2e-projects/overlays-project-with-config/cli-overlays ` diff --git a/azure-pipelines/end-to-end-tests-prelude.ps1 b/azure-pipelines/end-to-end-tests-prelude.ps1 index 7a11e196b6..f50f64e31b 100644 --- a/azure-pipelines/end-to-end-tests-prelude.ps1 +++ b/azure-pipelines/end-to-end-tests-prelude.ps1 @@ -106,6 +106,7 @@ function Throw-IfNotFailed { Write-Stack throw "'$Script:CurrentTest' had a step with an unexpectedly zero exit code" } + $global:LASTEXITCODE = 0 } function Write-Trace ([string]$text) { @@ -264,4 +265,22 @@ function Throw-IfNonContains { } } +function Test-ManifestInfo { + param ( + [string]$ManifestInfoPath, + [string]$VcpkgDir, + [string]$ManifestRoot + ) + + if (-not (Test-Path $ManifestInfoPath)) { + Throw "manifest-info.json missing from $VcpkgDir" + } + + $manifestInfoContent = Get-Content $ManifestInfoPath -Raw | ConvertFrom-Json + + if ($manifestInfoContent.'manifest-path' -ne (Join-Path -Path $ManifestRoot -ChildPath "vcpkg.json")) { + Throw "Mismatch in manifest-path. Expected: $ManifestRoot, Found: $($manifestInfoContent.'manifest-path')" + } +} + Refresh-TestRoot diff --git a/azure-pipelines/end-to-end-tests.ps1 b/azure-pipelines/end-to-end-tests.ps1 index 0450f51f28..88aefaa76c 100755 --- a/azure-pipelines/end-to-end-tests.ps1 +++ b/azure-pipelines/end-to-end-tests.ps1 @@ -41,6 +41,10 @@ if ($PSVersionTable.PSVersion.Major -lt 7) { Write-Error "vcpkg end to end tests must use pwsh rather than Windows PowerShell" } +# If you get an error on the next line, install Pester from an administrative command prompt with: +# Install-Module -Name Pester -Force -MinimumVersion '5.6.1' -MaximumVersion '5.99' -Scope AllUsers +Import-Module Pester -Force -MinimumVersion '5.6.1' -MaximumVersion '5.99' + if ($IsLinux) { $Triplet = 'x64-linux' } elseif ($IsMacOS) { @@ -49,7 +53,7 @@ if ($IsLinux) { $Triplet = 'x86-windows' } -New-Item -Path $WorkingRoot -ItemType Directory -Force +New-Item -Path $WorkingRoot -ItemType Directory -Force | Out-Null $WorkingRoot = (Get-Item $WorkingRoot).FullName if ([string]::IsNullOrWhitespace($VcpkgRoot)) { $VcpkgRoot = $env:VCPKG_ROOT @@ -77,10 +81,11 @@ $VcpkgItem = Get-Item $VcpkgExe $VcpkgExe = $VcpkgItem.FullName $VcpkgPs1 = Join-Path $VcpkgItem.Directory "vcpkg-shell.ps1" $TestScriptAssetCacheExe = Join-Path $VcpkgItem.Directory "test-script-asset-cache" +$TestSuitesDir = Join-Path $PSScriptRoot "end-to-end-tests-dir" -[Array]$AllTests = Get-ChildItem -LiteralPath "$PSScriptRoot/end-to-end-tests-dir" -Filter "*.ps1" | Sort-Object -Property Name -if ($Filter -ne $null) { - $AllTests = $AllTests | ? { $_.Name -match $Filter } +[System.IO.FileInfo[]]$AllTests = Get-ChildItem -LiteralPath $TestSuitesDir -File -Filter "*.ps1" | Sort-Object -Property Name +if ($null -ne $Filter) { + $AllTests = $AllTests | Where-Object Name -Match $Filter } $envvars_clear = @( @@ -103,21 +108,22 @@ $allTestsCount = $AllTests.Count for ($n = 1; $n -le $allTestsCount; $n++) { $Test = $AllTests[$n - 1] + $testDisplayName = [System.IO.Path]::GetRelativePath($TestSuitesDir, $Test.FullName) if ($StartAt.Length -ne 0) { [string]$TestName = $Test.Name $TestName = $TestName.Substring(0, $TestName.Length - 4) # remove .ps1 if ($StartAt.Equals($TestName, [System.StringComparison]::OrdinalIgnoreCase)) { $StartAt = [string]::Empty } else { - Write-Host -ForegroundColor Green "[end-to-end-tests.ps1] [$n/$allTestsCount] Suite $Test skipped by -StartAt" + Write-Host -ForegroundColor Green "[end-to-end-tests.ps1] [$n/$allTestsCount] Suite $testDisplayName skipped by -StartAt" continue } } if ($env:GITHUB_ACTIONS) { - Write-Host -ForegroundColor Green "::group::[end-to-end-tests.ps1] [$n/$allTestsCount] Running suite $Test" + Write-Host -ForegroundColor Green "::group::[end-to-end-tests.ps1] [$n/$allTestsCount] Running suite $testDisplayName" } else { - Write-Host -ForegroundColor Green "[end-to-end-tests.ps1] [$n/$allTestsCount] Running suite $Test" + Write-Host -ForegroundColor Green "[end-to-end-tests.ps1] [$n/$allTestsCount] Running suite $testDisplayName" } $envbackup = @{} @@ -126,6 +132,7 @@ for ($n = 1; $n -le $allTestsCount; $n++) $envbackup[$var] = [System.Environment]::GetEnvironmentVariable($var) } + [int]$lastTestExitCode = 0 try { foreach ($var in $envvars_clear) @@ -137,6 +144,7 @@ for ($n = 1; $n -le $allTestsCount; $n++) } $env:VCPKG_ROOT = $VcpkgRoot & $Test + $lastTestExitCode = $LASTEXITCODE } finally { @@ -158,7 +166,11 @@ for ($n = 1; $n -le $allTestsCount; $n++) if ($env:GITHUB_ACTIONS) { Write-Host "::endgroup::" } + + if ($lastTestExitCode -ne 0) + { + Write-Error "[end-to-end-tests.ps1] Suite $testDisplayName failed with exit code $lastTestExitCode" + } } Write-Host -ForegroundColor Green "[end-to-end-tests.ps1] All tests passed." -$global:LASTEXITCODE = 0 diff --git a/azure-pipelines/signing.yml b/azure-pipelines/signing.yml index 032466309e..b0df765575 100644 --- a/azure-pipelines/signing.yml +++ b/azure-pipelines/signing.yml @@ -524,39 +524,33 @@ extends: SymbolsFeatureName: 'vcpkg' SymbolsProject: 'VS' SymbolsAgentPath: '$(Build.ArtifactStagingDirectory)\symbols' - # Publish everything to a GitHub Release - - ${{ if eq(parameters.PublishTo, 'GitHub and NuGet') }}: - - task: DownloadSecureFile@1 - displayName: Download Deploy Key - name: githubDeployKey - condition: and(eq(variables.SignType, 'real'), succeeded()) - inputs: - secureFile: id_vcpkg_tool - # GitHub has a large, regularly changing set of IP address, so ignore the - # hostname and allow anything with the right key. - # https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/about-githubs-ip-addresses - # This public key should have the well-known fingerprint documented below. - # SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s - # https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints - - script: mkdir %USERPROFILE%\.ssh && echo github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=>>%USERPROFILE%\.ssh\known_hosts - displayName: Store GitHub Public Key - condition: and(eq(variables.SignType, 'real'), succeeded()) - - script: git -c user.email=embeddedbot@microsoft.com -c user.name="Embedded Bot" push git@github.com:microsoft/vcpkg-tool HEAD:refs/tags/%VCPKG_BASE_VERSION% - condition: and(eq(variables.SignType, 'real'), succeeded()) - env: - GIT_SSH_COMMAND: ssh -i "$(githubDeployKey.secureFilePath)" - displayName: Push Release Tag - - task: GitHubRelease@0 - displayName: Publish GitHub Release - condition: and(eq(variables.SignType, 'real'), succeeded()) - inputs: - gitHubConnection: embeddedbot - repositoryName: microsoft/vcpkg-tool - isPreRelease: true - isDraft: true - title: $(VCPKG_BASE_VERSION) Release - tagSource: manual - tag: $(VCPKG_BASE_VERSION) - assets: "$(Build.ArtifactStagingDirectory)\\drop\\*" - addChangeLog: false - compareWith: 'lastFullRelease' + - job: github_release + displayName: 'Publish GitHub Release' + condition: and(succeeded(), eq(variables.SignType, 'real'), ${{ eq(parameters.PublishTo, 'GitHub and NuGet') }}) + dependsOn: + - arch_independent + - windows_and_sign + pool: + name: 'VSEngSS-MicroBuild2022-1ES' + variables: + VCPKG_BASE_VERSION: $[ dependencies.arch_independent.outputs['versions.VCPKG_BASE_VERSION'] ] + templateContext: + type: releaseJob + isProduction: true + inputs: + - input: pipelineArtifact + artifactName: Drop + targetPath: $(Build.ArtifactStagingDirectory)/drop + steps: + - task: GitHubRelease@1 + displayName: Publish GitHub Release + inputs: + gitHubConnection: embeddedbot + repositoryName: microsoft/vcpkg-tool + isPreRelease: true + isDraft: true + title: $(VCPKG_BASE_VERSION) Release + tagSource: userSpecifiedTag + tag: $(VCPKG_BASE_VERSION) + assets: "$(Build.ArtifactStagingDirectory)\\drop\\*" + addChangeLog: false diff --git a/docs/manifest-info.schema.json b/docs/manifest-info.schema.json new file mode 100644 index 0000000000..0448836faf --- /dev/null +++ b/docs/manifest-info.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-manifest-info.schema.json", + "type": "object", + "properties": { + "manifest-path": { + "description": "Identifies the path of the vcpkg manifest file that produced this installed tree.", + "type": "string" + } + }, + "additionalProperties": true, + "required": [ + "manifest-path" + ] +} diff --git a/docs/testing.md b/docs/testing.md index 2630a105b6..1e9faaa8d3 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -7,6 +7,8 @@ the line when someone complains! ## Running end to end (e2e) tests +Before running the tests you must have installed the `Pester` module. +This can be done by running `Install-Module -Name Pester -MinimumVersion 5.6.1 -MaximumVersion 5.99 -Force` in a PowerShell session. To run the e2e test run the following command: `pwsh azure-pipelines/end-to-end-tests.ps1` **Parameters**: diff --git a/docs/vcpkg-tools.schema.json b/docs/vcpkg-tools.schema.json new file mode 100644 index 0000000000..f211e3c424 --- /dev/null +++ b/docs/vcpkg-tools.schema.json @@ -0,0 +1,69 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg-tools.schema.json", + "type": "object", + "properties": { + "schema-version": { + "description": "Identifies the version of the tools database format; currently always 1.", + "type": "number", + "minimum": 1, + "maximum": 1 + }, + "tools": { + "type": "array", + "description": "The set of known tools.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The name of the tool as exposed to `vcpkg fetch`." + }, + "os": { + "type": "string", + "description": "The platform where the record is valid.", + "enum": [ "windows", "osx", "linux", "freebsd", "openbsd" ] + }, + "version": { + "type": "string", + "description": "The version to match against against a system provided copy of this tool.", + "pattern": "\\d+(\\.\\d+(\\.\\d+)?)?" + }, + "arch": { + "type": "string", + "description": "The architecture where the record is valid.", + "enum": [ "x86", "x64", "amd64", "arm", "arm64", "arm64ec", "s390x", "ppc64le", "riscv32", "riscv64", "loongarch32", "loongarch64", "mips64" ] + }, + "executable": { + "type": "string", + "description": "The relative path to the executable for the tool within the downloaded archive, if any." + }, + "url": { + "type": "string", + "description": "The URL to download the tool from.", + "format": "uri" + }, + "sha512": { + "type": "string", + "description": "The SHA-512 hash of the downloaded archive.", + "pattern": "^[0-9a-fA-F]{128}$" + }, + "archive": { + "type": "string", + "description": "The name of the downloaded archive." + } + }, + "patternProperties": { + "^\\$": {} + }, + "required": ["name", "os", "version"], + "additionalProperties": false + } + } + }, + "patternProperties": { + "^\\$": {} + }, + "additionalProperties": false, + "required": [ "schema-version", "tools" ] +} diff --git a/docs/vcpkg_registry_release_process.md b/docs/vcpkg_registry_release_process.md index cb106ee6bc..1e06a0234f 100644 --- a/docs/vcpkg_registry_release_process.md +++ b/docs/vcpkg_registry_release_process.md @@ -2,16 +2,14 @@ This document describes the acceptance criteria / process we use when doing a vcpkg registry release. -1. Make sure the contents of the repo have what you want to release. +1. Make sure the contents of the repo have what you want to release and match a nightly CI run. 1. Create a git tag for the release. ```console >git fetch origin # Where origin is whichever remote points to microsoft/vcpkg - >git switch -d origin/master - >git tag 2023.10.19 # Replace this with the correct date of course :) + >git switch -d + >git tag 2023.10.19 # Replace this with the date of that SHA >git push origin 2023.10.19 ``` -1. Submit a full CI rebuild ( https://dev.azure.com/vcpkg/public/_build?definitionId=29 ) for the tag. e.g. `refs/tags/2023.10.19` -1. Checkout the tag 1. Run vcpkg z-changelog `` > `path/to/results.md` 1. Create a new GitHub release in the registry repo on the tag. 1. Run 'auto generate release notes' @@ -19,6 +17,6 @@ This document describes the acceptance criteria / process we use when doing a vc 1. Copy the contents to the end of `path/to/results.md` (the `#### New Contributors` part should line up) 1. Change the link to the full rebuild. 1. Fill out the block about tool release changes. -1. Copy `path/to/results.md` into the github release and publish it. (You can delete `path/to/results.md` now :)) -1. After the full rebuild submission completes, change all the 'Building...'s to actual counts in the release. +1. Fill out the number of ports per platform from the matching rebuild. +1. Copy `path/to/results.md` into the GitHub release and publish it. (You can delete `path/to/results.md` now :)) 1. After a blog post for that release is authored, add a link to the blog post to the release. diff --git a/docs/vcpkg_tool_release_process.md b/docs/vcpkg_tool_release_process.md index ab516e1a75..dfcd66d863 100644 --- a/docs/vcpkg_tool_release_process.md +++ b/docs/vcpkg_tool_release_process.md @@ -21,23 +21,18 @@ such as https://github.com/microsoft/vcpkg/pull/23757 1. Clean up a machine for the following tests: * Delete `VCPKG_DOWNLOADS/artifacts` (which forces artifacts to be reacquired) * Delete `LOCALAPPDATA/vcpkg` (which forces registries to be reacquired) -1. Smoke test the 'one liner' installer: (Where 2024-06-10 is replaced with the right release name) +1. Smoke test the 'one liner' installer: (Where 2024-12-09 is replaced with the right release name) * Powershell: - `iex (iwr https://github.com/microsoft/vcpkg-tool/releases/download/2024-06-10/vcpkg-init.ps1)` + `iex (iwr https://github.com/microsoft/vcpkg-tool/releases/download/2024-12-09/vcpkg-init.ps1)` * Batch: - `curl -L -o vcpkg-init.cmd https://github.com/microsoft/vcpkg-tool/releases/download/2024-06-10/vcpkg-init.ps1 && .\vcpkg-init.cmd` + `curl -L -o vcpkg-init.cmd https://github.com/microsoft/vcpkg-tool/releases/download/2024-12-09/vcpkg-init.ps1 && .\vcpkg-init.cmd` * Bash: - `. <(curl https://github.com/microsoft/vcpkg-tool/releases/download/2024-06-10/vcpkg-init -L)` + `. <(curl https://github.com/microsoft/vcpkg-tool/releases/download/2024-12-09/vcpkg-init -L)` (and test that `vcpkg use microsoft:cmake` works from each of these) -1. Create a new task in the DevDiv VS instance for this release. (PRs into VS Code and VS require an associated work +1. Create a new task in the DevDiv VS instance for this release. (PRs into VS require an associated work item in order to be merged.) -1. In the vcpkg repo, run `\scripts\update-vcpkg-tool-metadata.ps1 -Date 2024-06-10` - with the new release date, which updates SHAs as appropriate. It will also emit a code block for - the next vscode-embedded-tools repo step. Commit these changes and submit as a PR. -1. In the DevDiv vscode-embedded-tools repo, follow the - [update instructions](https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_git/vscode-embedded-tools?path=/docs/updating-vcpkg.md&_a=preview) - to make a VS Code update PR. Don't forget to attach the work item created in the previous step. - Example: https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_git/vscode-embedded-tools/pullrequest/498107 +1. In the vcpkg repo, run `\scripts\update-vcpkg-tool-metadata.ps1 -Date 2024-12-09` + with the new release date, which updates SHAs as appropriate. Commit these changes and submit as a PR. 1. If changes in this release that might affect ports, submit a new full tree rebuild by microsoft.vcpkg.ci (https://dev.azure.com/vcpkg/public/_build?definitionId=29 as of this writing) targeting `refs/pull/NUMBER/head` @@ -50,13 +45,12 @@ such as https://github.com/microsoft/vcpkg/pull/23757 in a comment in `Program.cs` 1. Download the VS-insertion .nupkg. 1. Run `src\vc\projbld\Vcpkg\VcpkgInsertionUtility\Program.exe path-to-nupkg` -1. Go to the root of the VS repo and run `init.cmd -CoreXTProfileName VSPartners` 1. Submit this as a change to the VS repo. Example: https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_git/VS/pullrequest/498110 Don't forget to attach the work item number from the previous step. 1. Smoke test the copy of vcpkg inserted into VS. See smoke test steps below. The prototype copy is at "CloudBuild - PR -> Extensions\VS Enterprise\Release Channel" as of 2023-10-19 but this UI changes frequently. -1. (After all tests have passed, at the same time) Merge all 3 PRs, and change the github release +1. (After all tests have passed, at the same time) Merge both PRs, and change the github release in vcpkg-tool from "prerelease" to "release". (This automatically updates the aka.ms links) 1. Mark any `requires:vcpkg-tool-release` issues as fixed by the tool release. @@ -91,13 +85,6 @@ flowchart TD smoke_test_cmd{Smoke Test vcpkg-init.cmd} smoke_test_ps1{Smoke Test vcpkg-init.ps1} smoke_test_bash{Smoke Test vcpkg-init.sh} - subgraph vs_code_update_pr [Visual Studio Code Update PR] - direction LR - package_json[(package.json)] - changelog_md[(CHANGELOG.md)] - vs_embedded_tools_repo[(vs_embedded_tools Repo)] - end - create_vs_code_update_pr{Create Visual Studio Code Update PR} symweb[(//symweb, etc.)] %% Build the Release @@ -123,13 +110,6 @@ flowchart TD run_insertion --> vs_repo vs_update_pr --> create_vs_pr - %% VS Code Update - update_vcpkg_tool_metadata_ps1 --> package_json - release_version --> changelog_md - package_json --> vs_embedded_tools_repo - changelog_md --> vs_embedded_tools_repo - vs_code_update_pr --> create_vs_code_update_pr - %% Smoke Testing create_vs_pr --> smoke_test_vs vcpkg_tool_releases --> smoke_test_cmd @@ -142,16 +122,12 @@ flowchart TD smoke_test_bash --> merge smoke_test_vs --> merge run_full_tree_rebuild --> merge - create_vs_code_update_pr --> merge ``` * [vcpkg Signed Binaries (from GitHub)](https://devdiv.visualstudio.com/DevDiv/_build?definitionId=17772&_a=summary) Uses the azure-pipelines/signing.yml file in the vcpkg-tool repo. * [devdiv/VS NuGet Feed](https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_artifacts/feed/VS/NuGet/VS.Redist.Vcpkg.amd64/) * [devdiv/VS-CoreXtFeeds NuGet Feed](https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_artifacts/feed/VS-CoreXtFeeds/NuGet/VS.Redist.Vcpkg.amd64/) * [devdiv VS Repo](https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_git/VS) - * Run VcpkgInsertionUtility at `$/src/vc/projbld/Vcpkg/VcpkgInsertionUtility/run.cmd` -* [vscode-embedded-tools Repo](https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_git/vscode-embedded-tools) - * `package.json` and `CHANGELOG.md` are in `$/app/vscode-embedded-tools` * Run Full Rebuild: Queue a [microsoft.vcpkg.ci](https://dev.azure.com/vcpkg/public/_build?definitionId=29) run for `refs/pull/NUMBER/head` * Example: https://dev.azure.com/vcpkg/public/_build/results?buildId=73664&view=results diff --git a/include/vcpkg/archives.h b/include/vcpkg/archives.h index dbecf5a84d..aeb9b7a832 100644 --- a/include/vcpkg/archives.h +++ b/include/vcpkg/archives.h @@ -9,6 +9,8 @@ #include #include +#include +#include #include namespace vcpkg @@ -21,7 +23,8 @@ namespace vcpkg SevenZip, Nupkg, Msi, - Exe + Exe, + SelfExtracting7z }; // Extract `archive` to `to_path` using `tar_tool`. @@ -53,22 +56,20 @@ namespace vcpkg struct ZipTool { - static ExpectedL make(const ToolCache& tools, MessageSink& status_sink); + void setup(const ToolCache& tools, MessageSink& status_sink); - private: - ZipTool() = default; - -#if defined _WIN32 - Path seven_zip; -#endif - - public: // Compress the source directory into the destination file. - ExpectedL compress_directory_to_zip(const Filesystem& fs, - const Path& source, - const Path& destination) const; + bool compress_directory_to_zip(DiagnosticContext& context, + const Filesystem& fs, + const Path& source, + const Path& destination) const; Command decompress_zip_archive_cmd(const Path& dst, const Path& archive_path) const; + + private: +#if defined _WIN32 + Optional seven_zip; +#endif }; std::vector> decompress_in_parallel(View jobs); diff --git a/include/vcpkg/base/api-stable-format.h b/include/vcpkg/base/api-stable-format.h index 17094f5058..ae61b87ac9 100644 --- a/include/vcpkg/base/api-stable-format.h +++ b/include/vcpkg/base/api-stable-format.h @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include #include #include @@ -10,21 +11,22 @@ namespace vcpkg namespace details { template - void api_stable_format_cb(void* f, std::string& s, StringView sv) + bool api_stable_format_cb(void* f, std::string& s, StringView sv) { - (*(F*)(f))(s, sv); + return (*(F*)(f))(s, sv); } - ExpectedL api_stable_format_impl(StringView fmtstr, - void (*cb)(void*, std::string&, StringView), - void* data); + Optional api_stable_format_impl(DiagnosticContext& context, + StringView fmtstr, + bool (*cb)(void*, std::string&, StringView), + void* data); } // This function exists in order to provide an API-stable formatting function similar to `std::format()` that does // not depend on the feature set of fmt or the C++ standard library and thus can be contractual for user interfaces. template - ExpectedL api_stable_format(StringView fmtstr, F&& handler) + Optional api_stable_format(DiagnosticContext& context, StringView fmtstr, F&& handler) { - return details::api_stable_format_impl(fmtstr, &details::api_stable_format_cb, &handler); + return details::api_stable_format_impl(context, fmtstr, &details::api_stable_format_cb, &handler); } } diff --git a/include/vcpkg/base/background-work-queue.h b/include/vcpkg/base/background-work-queue.h new file mode 100644 index 0000000000..9a775b3e51 --- /dev/null +++ b/include/vcpkg/base/background-work-queue.h @@ -0,0 +1,51 @@ +#pragma once + +#include +#include +#include + +template +struct BackgroundWorkQueue +{ + template + void push(Args&&... args) + { + std::lock_guard lock(m_mtx); + m_tasks.emplace_back(std::forward(args)...); + m_cv.notify_one(); + } + + bool get_work(std::vector& out) + { + std::unique_lock lock(m_mtx); + for (;;) + { + if (!m_tasks.empty()) + { + out.clear(); + swap(out, m_tasks); + return true; + } + + if (!m_running) + { + return false; + } + + m_cv.wait(lock); + } + } + + void stop() + { + std::lock_guard lock(m_mtx); + m_running = false; + m_cv.notify_all(); + } + +private: + std::mutex m_mtx; + std::condition_variable m_cv; + std::vector m_tasks; + bool m_running = true; +}; diff --git a/include/vcpkg/base/contractual-constants.h b/include/vcpkg/base/contractual-constants.h index 4f11d11e41..d48cc5c090 100644 --- a/include/vcpkg/base/contractual-constants.h +++ b/include/vcpkg/base/contractual-constants.h @@ -12,9 +12,11 @@ namespace vcpkg inline constexpr StringLiteral JsonIdAcquiredArtifacts = "acquired-artifacts"; inline constexpr StringLiteral JsonIdActivatedArtifacts = "activated-artifacts"; inline constexpr StringLiteral JsonIdAlgorithm = "algorithm"; + inline constexpr StringLiteral JsonIdArchive = "archive"; inline constexpr StringLiteral JsonIdAllCapsSHA256 = "SHA256"; inline constexpr StringLiteral JsonIdAllCapsSHA512 = "SHA512"; inline constexpr StringLiteral JsonIdApply = "apply"; + inline constexpr StringLiteral JsonIdArch = "arch"; inline constexpr StringLiteral JsonIdArchiveCapitalLocation = "archiveLocation"; inline constexpr StringLiteral JsonIdArtifact = "artifact"; inline constexpr StringLiteral JsonIdBaseline = "baseline"; @@ -46,6 +48,7 @@ namespace vcpkg inline constexpr StringLiteral JsonIdDollarSchema = "$schema"; inline constexpr StringLiteral JsonIdDownloads = "downloads"; inline constexpr StringLiteral JsonIdError = "error"; + inline constexpr StringLiteral JsonIdExecutable = "executable"; inline constexpr StringLiteral JsonIdFeatures = "features"; inline constexpr StringLiteral JsonIdFiles = "files"; inline constexpr StringLiteral JsonIdFilesystem = "filesystem"; @@ -68,6 +71,7 @@ namespace vcpkg inline constexpr StringLiteral JsonIdMessage = "message"; inline constexpr StringLiteral JsonIdMicrosoft = "microsoft"; inline constexpr StringLiteral JsonIdName = "name"; + inline constexpr StringLiteral JsonIdOS = "os"; inline constexpr StringLiteral JsonIdOverlayPorts = "overlay-ports"; inline constexpr StringLiteral JsonIdOverlayTriplets = "overlay-triplets"; inline constexpr StringLiteral JsonIdOverrides = "overrides"; @@ -87,8 +91,10 @@ namespace vcpkg inline constexpr StringLiteral JsonIdRequires = "requires"; inline constexpr StringLiteral JsonIdResolved = "resolved"; inline constexpr StringLiteral JsonIdScanned = "scanned"; + inline constexpr StringLiteral JsonIdSchemaVersion = "schema-version"; inline constexpr StringLiteral JsonIdSettings = "settings"; inline constexpr StringLiteral JsonIdSha = "sha"; + inline constexpr StringLiteral JsonIdSha512 = "sha512"; inline constexpr StringLiteral JsonIdState = "state"; inline constexpr StringLiteral JsonIdSummary = "summary"; inline constexpr StringLiteral JsonIdSupports = "supports"; @@ -290,6 +296,7 @@ namespace vcpkg inline constexpr StringLiteral SwitchTargetX86 = "target:x86"; inline constexpr StringLiteral SwitchTLogFile = "tlog-file"; inline constexpr StringLiteral SwitchTools = "tools"; + inline constexpr StringLiteral SwitchToolDataFile = "tool-data-file"; inline constexpr StringLiteral SwitchTriplet = "triplet"; inline constexpr StringLiteral SwitchUrl = "url"; inline constexpr StringLiteral SwitchVcpkgRoot = "vcpkg-root"; @@ -314,7 +321,6 @@ namespace vcpkg inline constexpr StringLiteral SwitchXProhibitBackcompatFeatures = "x-prohibit-backcompat-features"; inline constexpr StringLiteral SwitchXRandomize = "x-randomize"; inline constexpr StringLiteral SwitchXTransitive = "x-transitive"; - inline constexpr StringLiteral SwitchXUseAria2 = "x-use-aria2"; inline constexpr StringLiteral SwitchXVersionSuffix = "x-version-suffix"; inline constexpr StringLiteral SwitchXWriteNuGetPackagesConfig = "x-write-nuget-packages-config"; inline constexpr StringLiteral SwitchXXUnit = "x-xunit"; @@ -332,6 +338,7 @@ namespace vcpkg inline constexpr StringLiteral FileBaselineDotJson = "baseline.json"; inline constexpr StringLiteral FileBin = "bin"; inline constexpr StringLiteral FileControl = "CONTROL"; + inline constexpr StringLiteral FileCompilerFileHashCacheDotJson = "compiler-file-hash-cache.json"; inline constexpr StringLiteral FileCopying = "COPYING"; inline constexpr StringLiteral FileCopyright = "copyright"; inline constexpr StringLiteral FileDebug = "debug"; @@ -340,13 +347,13 @@ namespace vcpkg inline constexpr StringLiteral FileInclude = "include"; inline constexpr StringLiteral FileIncomplete = "incomplete"; inline constexpr StringLiteral FileInfo = "info"; + inline constexpr StringLiteral FileIssueBodyMD = "issue_body.md"; inline constexpr StringLiteral FileLicense = "LICENSE"; inline constexpr StringLiteral FileLicenseDotTxt = "LICENSE.txt"; inline constexpr StringLiteral FilePortfileDotCMake = "portfile.cmake"; inline constexpr StringLiteral FileShare = "share"; inline constexpr StringLiteral FileStatus = "status"; inline constexpr StringLiteral FileStatusNew = "status-new"; - inline constexpr StringLiteral FileStatusOld = "status-old"; inline constexpr StringLiteral FileTools = "tools"; inline constexpr StringLiteral FileUpdates = "updates"; inline constexpr StringLiteral FileUsage = "usage"; @@ -356,6 +363,7 @@ namespace vcpkg inline constexpr StringLiteral FileVcpkgConfigurationDotJson = "vcpkg-configuration.json"; inline constexpr StringLiteral FileVcpkgDotJson = "vcpkg.json"; inline constexpr StringLiteral FileVcpkgLock = "vcpkg-lock.json"; + inline constexpr StringLiteral FileManifestInfo = "manifest-info.json"; inline constexpr StringLiteral FileVcpkgPathTxt = "vcpkg.path.txt"; inline constexpr StringLiteral FileVcpkgPortConfig = "vcpkg-port-config.cmake"; inline constexpr StringLiteral FileVcpkgSpdxJson = "vcpkg.spdx.json"; @@ -371,6 +379,7 @@ namespace vcpkg inline constexpr StringLiteral CMakeVariableCMakeSystemName = "VCPKG_CMAKE_SYSTEM_NAME"; inline constexpr StringLiteral CMakeVariableCMakeSystemVersion = "VCPKG_CMAKE_SYSTEM_VERSION"; inline constexpr StringLiteral CMakeVariableCmd = "CMD"; + inline constexpr StringLiteral CMakeVariableCompilerCacheFile = "VCPKG_COMPILER_CACHE_FILE"; inline constexpr StringLiteral CMakeVariableConcurrency = "VCPKG_CONCURRENCY"; inline constexpr StringLiteral CMakeVariableCurrentBuildtreesDir = "CURRENT_BUILDTREES_DIR"; inline constexpr StringLiteral CMakeVariableCurrentPackagesDir = "CURRENT_PACKAGES_DIR"; @@ -378,13 +387,13 @@ namespace vcpkg inline constexpr StringLiteral CMakeVariableDisableCompilerTracking = "VCPKG_DISABLE_COMPILER_TRACKING"; inline constexpr StringLiteral CMakeVariableDownloadMode = "VCPKG_DOWNLOAD_MODE"; inline constexpr StringLiteral CMakeVariableDownloads = "DOWNLOADS"; - inline constexpr StringLiteral CMakeVariableDownloadTool = "_VCPKG_DOWNLOAD_TOOL"; inline constexpr StringLiteral CMakeVariableEditable = "_VCPKG_EDITABLE"; inline constexpr StringLiteral CMakeVariableEnvPassthrough = "VCPKG_ENV_PASSTHROUGH"; inline constexpr StringLiteral CMakeVariableEnvPassthroughUntracked = "VCPKG_ENV_PASSTHROUGH_UNTRACKED"; inline constexpr StringLiteral CMakeVariableFeatures = "FEATURES"; inline constexpr StringLiteral CMakeVariableFilename = "FILENAME"; inline constexpr StringLiteral CMakeVariableGit = "GIT"; + inline constexpr StringLiteral CMakeVariableGitlabUrl = "GITLAB_URL"; inline constexpr StringLiteral CMakeVariableHashAdditionalFiles = "VCPKG_HASH_ADDITIONAL_FILES"; inline constexpr StringLiteral CMakeVariableHostTriplet = "_HOST_TRIPLET"; inline constexpr StringLiteral CMakeVariableLoadVcvarsEnv = "VCPKG_LOAD_VCVARS_ENV"; diff --git a/include/vcpkg/base/diagnostics.h b/include/vcpkg/base/diagnostics.h new file mode 100644 index 0000000000..f5f5415109 --- /dev/null +++ b/include/vcpkg/base/diagnostics.h @@ -0,0 +1,403 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace vcpkg +{ + enum class DiagKind + { + None, // foo.h: localized + Message, // foo.h: message: localized + Error, // foo.h: error: localized + Warning, // foo.h: warning: localized + Note, // foo.h: note: localized + COUNT + }; + + struct TextRowCol + { + // '0' indicates that line and column information is unknown; '1' is the first row/column + int row = 0; + int column = 0; + }; + + struct DiagnosticLine + { + template, int> = 0> + DiagnosticLine(DiagKind kind, MessageLike&& message) + : m_kind(kind), m_origin(), m_position(), m_message(std::forward(message)) + { + } + + template, int> = 0> + DiagnosticLine(DiagKind kind, StringView origin, MessageLike&& message) + : m_kind(kind), m_origin(origin.to_string()), m_position(), m_message(std::forward(message)) + { + if (origin.empty()) + { + Checks::unreachable(VCPKG_LINE_INFO, "origin must not be empty"); + } + } + + template, int> = 0> + DiagnosticLine(DiagKind kind, StringView origin, TextRowCol position, MessageLike&& message) + : m_kind(kind) + , m_origin(origin.to_string()) + , m_position(position) + , m_message(std::forward(message)) + { + if (origin.empty()) + { + Checks::unreachable(VCPKG_LINE_INFO, "origin must not be empty"); + } + } + + // Prints this diagnostic to the supplied sink. + void print_to(MessageSink& sink) const; + // Converts this message into a string + // Prefer print() if possible because it applies color + std::string to_string() const; + void to_string(std::string& target) const; + + MessageLine to_message_line() const; + + LocalizedString to_json_reader_string(const std::string& path, const LocalizedString& type) const; + + DiagKind kind() const noexcept { return m_kind; } + // Returns this DiagnosticLine with kind == Error reduced to Warning. + DiagnosticLine reduce_to_warning() const&; + DiagnosticLine reduce_to_warning() &&; + + private: + DiagnosticLine(DiagKind kind, + const Optional& origin, + TextRowCol position, + const LocalizedString& message); + DiagnosticLine(DiagKind kind, Optional&& origin, TextRowCol position, LocalizedString&& message); + + DiagKind m_kind; + Optional m_origin; + TextRowCol m_position; + LocalizedString m_message; + }; + + struct DiagnosticContext + { + // The `report` family are used to report errors or warnings that may result in a function failing + // to do what it is intended to do. Data sent to the `report` family is expected to not be printed + // to the console if a caller decides to handle an error. + virtual void report(const DiagnosticLine& line) = 0; + virtual void report(DiagnosticLine&& line); + + void report_error(const LocalizedString& message) { report(DiagnosticLine{DiagKind::Error, message}); } + void report_error(LocalizedString&& message) { report(DiagnosticLine{DiagKind::Error, std::move(message)}); } + template + void report_error(VCPKG_DECL_MSG_ARGS) + { + LocalizedString message; + msg::format_to(message, VCPKG_EXPAND_MSG_ARGS); + this->report_error(std::move(message)); + } + + template + void report_error_with_log(StringView log_content, VCPKG_DECL_MSG_ARGS) + { + LocalizedString message; + msg::format_to(message, VCPKG_EXPAND_MSG_ARGS); + message.append_raw('\n'); + message.append_raw(log_content); + this->report_error(std::move(message)); + } + + void report_system_error(StringLiteral system_api_name, int error_value); + + // The `status` family are used to report status or progress information that callers are expected + // to show on the console, even if it would decide to handle errors or warnings itself. + // Examples: + // * "Downloading file..." + // * "Building package 1 of 47..." + // + // Some implementations of DiagnosticContext may buffer these messages *anyway* if that makes sense, + // for example, if the work is happening on a background thread. + virtual void statusln(const LocalizedString& message) = 0; + virtual void statusln(LocalizedString&& message) = 0; + virtual void statusln(const MessageLine& message) = 0; + virtual void statusln(MessageLine&& message) = 0; + + protected: + ~DiagnosticContext() = default; + }; + + struct PrintingDiagnosticContext final : DiagnosticContext + { + PrintingDiagnosticContext(MessageSink& sink) : sink(sink) { } + + virtual void report(const DiagnosticLine& line) override; + + virtual void statusln(const LocalizedString& message) override; + virtual void statusln(LocalizedString&& message) override; + virtual void statusln(const MessageLine& message) override; + virtual void statusln(MessageLine&& message) override; + + private: + MessageSink& sink; + }; + + // Stores all diagnostics into a vector, while passing through status lines to an underlying MessageSink. + struct BufferedDiagnosticContext final : DiagnosticContext + { + BufferedDiagnosticContext(MessageSink& status_sink) : status_sink(status_sink) { } + + virtual void report(const DiagnosticLine& line) override; + virtual void report(DiagnosticLine&& line) override; + + virtual void statusln(const LocalizedString& message) override; + virtual void statusln(LocalizedString&& message) override; + virtual void statusln(const MessageLine& message) override; + virtual void statusln(MessageLine&& message) override; + + MessageSink& status_sink; + std::vector lines; + + // Prints all diagnostics to the supplied sink. + void print_to(MessageSink& sink) const; + // Converts this message into a string + // Prefer print() if possible because it applies color + std::string to_string() const; + void to_string(std::string& target) const; + + bool any_errors() const noexcept; + bool empty() const noexcept; + }; + + // Stores all diagnostics and status messages into a vector. This is generally used for background thread or similar + // scenarios where even status messages can't be immediately printed. + struct FullyBufferedDiagnosticContext final : DiagnosticContext + { + virtual void report(const DiagnosticLine& line) override; + virtual void report(DiagnosticLine&& line) override; + + virtual void statusln(const LocalizedString& message) override; + virtual void statusln(LocalizedString&& message) override; + virtual void statusln(const MessageLine& message) override; + virtual void statusln(MessageLine&& message) override; + + std::vector lines; + + // Prints all diagnostics to the supplied sink. + void print_to(MessageSink& sink) const; + // Converts this message into a string + // Prefer print() if possible because it applies color + std::string to_string() const; + void to_string(std::string& target) const; + + bool empty() const noexcept; + }; + + // DiagnosticContext for attempted operations that may be recovered. + // Stores all diagnostics and passes through all status messages. Afterwards, call commit() to report all + // diagnostics to the outer DiagnosticContext, or handle() to forget them. + struct AttemptDiagnosticContext final : DiagnosticContext + { + AttemptDiagnosticContext(DiagnosticContext& inner_context) : inner_context(inner_context) { } + + virtual void report(const DiagnosticLine& line) override; + virtual void report(DiagnosticLine&& line) override; + + virtual void statusln(const LocalizedString& message) override; + virtual void statusln(LocalizedString&& message) override; + virtual void statusln(const MessageLine& message) override; + virtual void statusln(MessageLine&& message) override; + + void commit(); + void handle(); + + ~AttemptDiagnosticContext(); + + DiagnosticContext& inner_context; + std::vector lines; + }; + + // Wraps another DiagnosticContext and reduces the severity of any reported diagnostics to warning from error. + struct WarningDiagnosticContext final : DiagnosticContext + { + WarningDiagnosticContext(DiagnosticContext& inner_context) : inner_context(inner_context) { } + + virtual void report(const DiagnosticLine& line) override; + virtual void report(DiagnosticLine&& line) override; + + virtual void statusln(const LocalizedString& message) override; + virtual void statusln(LocalizedString&& message) override; + virtual void statusln(const MessageLine& message) override; + virtual void statusln(MessageLine&& message) override; + + DiagnosticContext& inner_context; + }; + + extern DiagnosticContext& console_diagnostic_context; + extern DiagnosticContext& status_only_diagnostic_context; + extern DiagnosticContext& null_diagnostic_context; + + // The following overloads are implementing + // adapt_context_to_expected(Fn functor, Args&&... args) + // + // Given: + // Optional functor(DiagnosticContext&, args...), adapts functor to return ExpectedL + // Optional& functor(DiagnosticContext&, args...), adapts functor to return ExpectedL + // Optional&& functor(DiagnosticContext&, args...), adapts functor to return ExpectedL + // std::unique_ptr functor(DiagnosticContext&, args...), adapts functor to return ExpectedL> + + // If Ty is an Optional, typename AdaptContextUnwrapOptional::type is the type necessary to return U, and fwd + // is the type necessary to forward U. Otherwise, there are no members ::type or ::fwd + template + struct AdaptContextUnwrapOptional + { + // no member ::type, SFINAEs out when the input type is: + // * not Optional + // * volatile + }; + + template + struct AdaptContextUnwrapOptional> + { + // prvalue, move from the optional into the expected + using type = Wrapped; + using fwd = Wrapped&&; + }; + + template + struct AdaptContextUnwrapOptional> + { + // const prvalue + using type = Wrapped; + using fwd = const Wrapped&&; + }; + + template + struct AdaptContextUnwrapOptional&> + { + // lvalue, return an expected referencing the Wrapped inside the optional + using type = Wrapped&; + using fwd = Wrapped&; + }; + + template + struct AdaptContextUnwrapOptional&> + { + // const lvalue + using type = const Wrapped&; + using fwd = const Wrapped&; + }; + + template + struct AdaptContextUnwrapOptional&&> + { + // xvalue, move from the optional into the expected + using type = Wrapped; + using fwd = Wrapped&&; + }; + + template + struct AdaptContextUnwrapOptional&&> + { + // const xvalue + using type = Wrapped; + using fwd = const Wrapped&&; + }; + + // The overload for functors that return Optional + template + auto adapt_context_to_expected(Fn functor, Args&&... args) + -> ExpectedL< + typename AdaptContextUnwrapOptional>::type> + { + using Unwrapper = AdaptContextUnwrapOptional>; + using ReturnType = ExpectedL; + BufferedDiagnosticContext bdc{out_sink}; + decltype(auto) maybe_result = functor(bdc, std::forward(args)...); + if (auto result = maybe_result.get()) + { + // N.B.: This may be a move + return ReturnType{static_cast(*result), expected_left_tag}; + } + + return ReturnType{LocalizedString::from_raw(bdc.to_string()), expected_right_tag}; + } + + // If Ty is a std::unique_ptr, typename AdaptContextDetectUniquePtr::type is the type necessary to return + template + struct AdaptContextDetectUniquePtr + { + // no member ::type, SFINAEs out when the input type is: + // * not unique_ptr + // * volatile + }; + + template + struct AdaptContextDetectUniquePtr> + { + // prvalue, move into the Expected + using type = std::unique_ptr; + }; + + template + struct AdaptContextDetectUniquePtr> + { + // const prvalue (not valid, can't be moved from) + // no members + }; + + template + struct AdaptContextDetectUniquePtr&> + { + // lvalue, reference the unique_ptr itself + using type = std::unique_ptr&; + }; + + template + struct AdaptContextDetectUniquePtr&> + { + // const lvalue + using type = const std::unique_ptr&; + }; + + template + struct AdaptContextDetectUniquePtr&&> + { + // xvalue, move into the Expected + using type = std::unique_ptr; + }; + + template + struct AdaptContextDetectUniquePtr&&> + { + // const xvalue (not valid, can't be moved from) + // no members + }; + + // The overload for functors that return std::unique_ptr + template + auto adapt_context_to_expected(Fn functor, Args&&... args) + -> ExpectedL< + typename AdaptContextDetectUniquePtr>::type> + { + using ReturnType = ExpectedL< + typename AdaptContextDetectUniquePtr>::type>; + BufferedDiagnosticContext bdc{out_sink}; + decltype(auto) maybe_result = functor(bdc, std::forward(args)...); + if (maybe_result) + { + return ReturnType{static_cast(maybe_result), expected_left_tag}; + } + + return ReturnType{LocalizedString::from_raw(bdc.to_string()), expected_right_tag}; + } +} diff --git a/include/vcpkg/base/downloads.h b/include/vcpkg/base/downloads.h index 93b4163ee5..6349177a90 100644 --- a/include/vcpkg/base/downloads.h +++ b/include/vcpkg/base/downloads.h @@ -15,7 +15,17 @@ namespace vcpkg { - struct SplitURIView + struct SanitizedUrl + { + SanitizedUrl() = default; + SanitizedUrl(StringView raw_url, View secrets); + const std::string& to_string() const noexcept { return m_sanitized_url; } + + private: + std::string m_sanitized_url; + }; + + struct SplitUrlView { StringView scheme; Optional authority; @@ -23,39 +33,45 @@ namespace vcpkg }; // e.g. {"https","//example.org", "/index.html"} - ExpectedL split_uri_view(StringView uri); - - void verify_downloaded_file_hash(const ReadOnlyFilesystem& fs, - StringView sanitized_url, - const Path& downloaded_path, - StringView sha512); + Optional parse_split_url_view(StringView raw_url); View azure_blob_headers(); - std::vector download_files(View> url_pairs, - View headers, - View secrets); - - bool send_snapshot_to_api(const std::string& github_token, - const std::string& github_repository, - const Json::Object& snapshot); - ExpectedL put_file(const ReadOnlyFilesystem&, - StringView url, - const std::vector& secrets, - View headers, - const Path& file, - StringView method = "PUT"); - - ExpectedL invoke_http_request(StringView method, - View headers, - StringView url, - StringView data = {}); + // Parses a curl output line for curl invoked with + // -w "PREFIX%{http_code} %{exitcode} %{errormsg}" + // with specific handling for curl version < 7.75.0 which does not understand %{exitcode} %{errormsg} + // If the line is malformed for any reason, no entry to http_codes is added. + // Returns: true if the new version of curl's output with exitcode and errormsg was parsed; otherwise, false. + bool parse_curl_status_line(DiagnosticContext& context, + std::vector& http_codes, + StringLiteral prefix, + StringView this_line); + + std::vector download_files_no_cache(DiagnosticContext& context, + View> url_pairs, + View headers, + View secrets); + + bool submit_github_dependency_graph_snapshot(DiagnosticContext& context, + const Optional& maybe_github_server_url, + const std::string& github_token, + const std::string& github_repository, + const Json::Object& snapshot); + + Optional invoke_http_request(DiagnosticContext& context, + StringLiteral method, + View headers, + StringView url, + StringView data = {}); std::string format_url_query(StringView base_url, View query_params); - std::vector url_heads(View urls, View headers, View secrets); + std::vector url_heads(DiagnosticContext& context, + View urls, + View headers, + View secrets); - struct DownloadManagerConfig + struct AssetCachingSettings { Optional m_read_url_template; std::vector m_read_headers; @@ -67,37 +83,35 @@ namespace vcpkg }; // Handles downloading and uploading to a content addressable mirror - struct DownloadManager - { - DownloadManager() = default; - explicit DownloadManager(const DownloadManagerConfig& config) : m_config(config) { } - explicit DownloadManager(DownloadManagerConfig&& config) : m_config(std::move(config)) { } - - void download_file(const Filesystem& fs, - const std::string& url, - View headers, - const Path& download_path, - const Optional& sha512, - MessageSink& progress_sink) const; - - // Returns url that was successfully downloaded from - std::string download_file(const Filesystem& fs, - View urls, - View headers, - const Path& download_path, - const Optional& sha512, - MessageSink& progress_sink) const; - - ExpectedL put_file_to_mirror(const ReadOnlyFilesystem& fs, - const Path& file_to_put, - StringView sha512) const; - - bool get_block_origin() const; - bool asset_cache_configured() const; + bool download_file_asset_cached(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const AssetCachingSettings& asset_cache_settings, + const Filesystem& fs, + const std::string& url, + View headers, + const Path& download_path, + const Optional& maybe_sha512); + + bool download_file_asset_cached(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const AssetCachingSettings& asset_cache_settings, + const Filesystem& fs, + View urls, + View headers, + const Path& download_path, + const Optional& maybe_sha512); - private: - DownloadManagerConfig m_config; - }; + bool store_to_asset_cache(DiagnosticContext& context, + StringView raw_url, + const SanitizedUrl& sanitized_url, + StringLiteral method, + View headers, + const Path& file); + + bool store_to_asset_cache(DiagnosticContext& context, + const AssetCachingSettings& asset_cache_settings, + const Path& file_to_put, + StringView sha512); Optional try_parse_curl_max5_size(StringView sv); @@ -105,8 +119,8 @@ namespace vcpkg { unsigned int total_percent; unsigned long long total_size; - unsigned int recieved_percent; - unsigned long long recieved_size; + unsigned int received_percent; + unsigned long long received_size; unsigned int transfer_percent; unsigned long long transfer_size; unsigned long long average_download_speed; // bytes per second @@ -127,3 +141,5 @@ namespace vcpkg // is likely to contain query parameters or similar. std::string url_encode_spaces(StringView url); } + +VCPKG_FORMAT_WITH_TO_STRING(vcpkg::SanitizedUrl); diff --git a/include/vcpkg/base/file_sink.h b/include/vcpkg/base/file_sink.h index 7f2c20c9ed..ef1730104b 100644 --- a/include/vcpkg/base/file_sink.h +++ b/include/vcpkg/base/file_sink.h @@ -14,6 +14,7 @@ namespace vcpkg : m_log_file(log_file), m_out_file(fs.open_for_write(m_log_file, append_to_file, VCPKG_LINE_INFO)) { } - void print(Color c, StringView sv) override; + void println(const MessageLine& line) override; + void println(MessageLine&& line) override; }; } diff --git a/include/vcpkg/base/fwd/downloads.h b/include/vcpkg/base/fwd/downloads.h index 1f7a59ca3a..c51accb232 100644 --- a/include/vcpkg/base/fwd/downloads.h +++ b/include/vcpkg/base/fwd/downloads.h @@ -2,8 +2,8 @@ namespace vcpkg { - struct SplitURIView; - struct DownloadManager; - struct DownloadManagerConfig; + struct SanitizedUrl; + struct SplitUrlView; + struct AssetCachingSettings; struct CurlProgressData; } diff --git a/include/vcpkg/base/fwd/message_sinks.h b/include/vcpkg/base/fwd/message_sinks.h index 541fa35e6a..f0c8d94fbd 100644 --- a/include/vcpkg/base/fwd/message_sinks.h +++ b/include/vcpkg/base/fwd/message_sinks.h @@ -2,6 +2,8 @@ namespace vcpkg { + struct MessageLineSegment; + struct MessageLine; struct MessageSink; extern MessageSink& null_sink; @@ -10,5 +12,6 @@ namespace vcpkg extern MessageSink& stderr_sink; struct FileSink; - struct CombiningSink; + struct TeeSink; + struct BGMessageSink; } diff --git a/include/vcpkg/base/hash.h b/include/vcpkg/base/hash.h index f8a5f71e69..baedbd2b97 100644 --- a/include/vcpkg/base/hash.h +++ b/include/vcpkg/base/hash.h @@ -4,12 +4,26 @@ #include #include +#include #include #include namespace vcpkg::Hash { + enum class HashPrognosis + { + Success, + FileNotFound, + OtherError, + }; + + struct HashResult + { + HashPrognosis prognosis = HashPrognosis::Success; + std::string hash; + }; + enum class Algorithm { Sha256, @@ -33,5 +47,28 @@ namespace vcpkg::Hash std::string get_bytes_hash(const void* first, const void* last, Algorithm algo); std::string get_string_hash(StringView s, Algorithm algo); std::string get_string_sha256(StringView s); - ExpectedL get_file_hash(const ReadOnlyFilesystem& fs, const Path& target, Algorithm algo); + + // Tries to open `path` for reading, and hashes the contents using the requested algorithm. + // Returns a HashResult with the following outcomes: + // HashPrognosis::Success: The entire file was read and hashed. The result hash is stored in `hash`. + // HashPrognosis::FileNotFound: The file does not exist. `hash` is empty string. + // HashPrognosis::OtherError: An error occurred while reading the file. `hash` is empty string. + HashResult get_file_hash(DiagnosticContext& context, + const ReadOnlyFilesystem& fs, + const Path& path, + Algorithm algo); + + // Tries to open `path` for reading, and hashes the contents using the requested algorithm. + // If the file exists and could be completely read, returns an engaged optional with the stringized hash. + // Otherwise, returns an disengaged optional. + // Note that the file not existing is interpreted as an error that will be reported to `context`. + Optional get_file_hash_required(DiagnosticContext& context, + const ReadOnlyFilesystem& fs, + const Path& path, + Algorithm algo); + + // Tries to open `path` for reading, and hashes the contents using the requested algorithm. + // If the file exists and could be completely read, returns an engaged optional with the stringized hash. + // Otherwise, returns the read operation error. + ExpectedL get_file_hash(const ReadOnlyFilesystem& fs, const Path& path, Algorithm algo); } diff --git a/include/vcpkg/base/jsonreader.h b/include/vcpkg/base/jsonreader.h index e4c3522ed7..b9ecb816ec 100644 --- a/include/vcpkg/base/jsonreader.h +++ b/include/vcpkg/base/jsonreader.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -17,12 +18,8 @@ namespace vcpkg::Json using type = Type; virtual LocalizedString type_name() const = 0; - private: - friend struct Reader; Optional visit(Reader&, const Value&) const; Optional visit(Reader&, const Object&) const; - - public: virtual Optional visit_null(Reader&) const; virtual Optional visit_boolean(Reader&, bool) const; virtual Optional visit_integer(Reader& r, int64_t i) const; @@ -30,16 +27,13 @@ namespace vcpkg::Json virtual Optional visit_string(Reader&, StringView) const; virtual Optional visit_array(Reader&, const Array&) const; virtual Optional visit_object(Reader&, const Object&) const; - virtual View valid_fields() const; - - virtual ~IDeserializer() = default; + virtual View valid_fields() const noexcept; protected: IDeserializer() = default; - IDeserializer(const IDeserializer&) = default; - IDeserializer& operator=(const IDeserializer&) = default; - IDeserializer(IDeserializer&&) = default; - IDeserializer& operator=(IDeserializer&&) = default; + IDeserializer(const IDeserializer&) = delete; + IDeserializer& operator=(const IDeserializer&) = delete; + ~IDeserializer() = default; }; struct Reader @@ -63,9 +57,6 @@ namespace vcpkg::Json StringView origin() const noexcept; private: - template - friend struct IDeserializer; - std::vector m_errors; std::vector m_warnings; struct JsonPathElement @@ -100,7 +91,7 @@ namespace vcpkg::Json // * are not in `valid_fields` // if known_fields.empty(), then it's treated as if all field names are valid void check_for_unexpected_fields(const Object& obj, - View valid_fields, + View valid_fields, const LocalizedString& type_name); template @@ -167,19 +158,8 @@ namespace vcpkg::Json } } - template - Optional visit(const Value& value, const IDeserializer& visitor) - { - return visitor.visit(*this, value); - } - template - Optional visit(const Object& value, const IDeserializer& visitor) - { - return visitor.visit(*this, value); - } - - template - Optional> array_elements(const Array& arr, const IDeserializer& visitor) + template + Optional> array_elements_fn(const Array& arr, const IDeserializer& visitor, Fn callback) { Optional> result{std::vector()}; auto& result_vec = *result.get(); @@ -188,7 +168,7 @@ namespace vcpkg::Json for (size_t i = 0; i < arr.size(); ++i) { m_path.back().index = static_cast(i); - auto opt = visitor.visit(*this, arr[i]); + auto opt = callback(*this, visitor, arr[i]); if (auto parsed = opt.get()) { if (success) @@ -207,6 +187,15 @@ namespace vcpkg::Json return result; } + template + Optional> array_elements(const Array& arr, const IDeserializer& visitor) + { + return array_elements_fn( + arr, visitor, [](Reader& this_, const IDeserializer& visitor, const Json::Value& value) { + return visitor.visit(this_, value); + }); + } + static uint64_t get_reader_stats(); private: @@ -238,7 +227,7 @@ namespace vcpkg::Json } template - View IDeserializer::valid_fields() const + View IDeserializer::valid_fields() const noexcept { return {}; } @@ -361,4 +350,18 @@ namespace vcpkg::Json virtual Optional visit_string(Json::Reader&, StringView sv) const override; static const FeatureNameDeserializer instance; }; + + struct ArchitectureDeserializer final : Json::IDeserializer> + { + virtual LocalizedString type_name() const override; + virtual Optional> visit_string(Json::Reader&, StringView sv) const override; + static const ArchitectureDeserializer instance; + }; + + struct Sha512Deserializer final : Json::IDeserializer + { + virtual LocalizedString type_name() const override; + virtual Optional visit_string(Json::Reader&, StringView sv) const override; + static const Sha512Deserializer instance; + }; } diff --git a/include/vcpkg/base/message-args.inc.h b/include/vcpkg/base/message-args.inc.h index f49356c401..a84a36ab91 100644 --- a/include/vcpkg/base/message-args.inc.h +++ b/include/vcpkg/base/message-args.inc.h @@ -47,7 +47,7 @@ DECLARE_MSG_ARG(sha, DECLARE_MSG_ARG(supports_expression, "windows & !static") DECLARE_MSG_ARG(system_api, "CreateProcessW") DECLARE_MSG_ARG(system_name, "Darwin") -DECLARE_MSG_ARG(tool_name, "aria2") +DECLARE_MSG_ARG(tool_name, "signtool") DECLARE_MSG_ARG(triplet, "x64-windows") DECLARE_MSG_ARG(upper, "42") DECLARE_MSG_ARG(url, "https://github.com/microsoft/vcpkg") diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 06a1125224..be9ca8e802 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -4,6 +4,7 @@ DECLARE_MESSAGE(ADefaultFeature, (), "", "a default feature") DECLARE_MESSAGE(ABoolean, (), "", "a boolean") DECLARE_MESSAGE(ABuiltinRegistry, (), "", "a builtin registry") DECLARE_MESSAGE(AConfigurationObject, (), "", "a configuration object") +DECLARE_MESSAGE(ACpuArchitecture, (), "", "a CPU architecture") DECLARE_MESSAGE(ADependency, (), "", "a dependency") DECLARE_MESSAGE(ADependencyFeature, (), "", "a feature of a dependency") DECLARE_MESSAGE(ADemandObject, @@ -11,6 +12,7 @@ DECLARE_MESSAGE(ADemandObject, "'demands' are a concept in the schema of a JSON file the user can edit", "a demand object") DECLARE_MESSAGE(AString, (), "", "a string") +DECLARE_MESSAGE(ASha512, (), "", "a SHA-512 hash") DECLARE_MESSAGE(ADateVersionString, (), "", "a date version string") DECLARE_MESSAGE(AddArtifactOnlyOne, (msg::command_line), "", "'{command_line}' can only add one artifact at a time.") DECLARE_MESSAGE(AddCommandFirstArg, (), "", "The first parameter to add must be 'artifact' or 'port'.") @@ -241,24 +243,70 @@ DECLARE_MESSAGE(ArtifactsSwitchOsx, (), "", "Forces host detection to MacOS when DECLARE_MESSAGE(ArtifactsSwitchX64, (), "", "Forces host detection to x64 when acquiring artifacts") DECLARE_MESSAGE(ArtifactsSwitchX86, (), "", "Forces host detection to x86 when acquiring artifacts") DECLARE_MESSAGE(ArtifactsSwitchWindows, (), "", "Forces host detection to Windows when acquiring artifacts") -DECLARE_MESSAGE(AssetCacheHit, (msg::path, msg::url), "", "Asset cache hit for {path}; downloaded from: {url}") -DECLARE_MESSAGE(AssetCacheMiss, (msg::url), "", "Asset cache miss; downloading from {url}") +DECLARE_MESSAGE(AssetCacheConsult, (msg::path, msg::url), "", "Trying to download {path} using asset cache {url}") +DECLARE_MESSAGE(AssetCacheConsultScript, (msg::path), "", "Trying to download {path} using asset cache script") +DECLARE_MESSAGE(AssetCacheHit, (), "", "Download successful! Asset cache hit.") +DECLARE_MESSAGE(AssetCacheHitUrl, + (msg::url), + "", + "Download successful! Asset cache hit, did not try authoritative source {url}") +DECLARE_MESSAGE(AssetCacheMiss, (msg::url), "", "Asset cache miss; trying authoritative source {url}") DECLARE_MESSAGE(AssetCacheMissBlockOrigin, - (msg::path), + (msg::url), "x-block-origin is a vcpkg term. Do not translate", - "Asset cache miss for {path} and downloads are blocked by x-block-origin.") -DECLARE_MESSAGE(DownloadSuccesful, (msg::path), "", "Successfully downloaded {path}.") -DECLARE_MESSAGE(DownloadingUrl, (msg::url), "", "Downloading {url}") + "there were no asset cache hits, and x-block-origin blocks trying the authoritative source {url}") +DECLARE_MESSAGE(AssetCacheMissNoUrls, + (msg::sha), + "", + "Asset cache missed looking for {sha} and no authoritative URL is known") DECLARE_MESSAGE(AssetCacheProviderAcceptsNoArguments, (msg::value), "{value} is a asset caching provider name such as azurl, clear, or x-block-origin", "unexpected arguments: '{value}' does not accept arguments") -DECLARE_MESSAGE(AssetCacheSuccesfullyStored, (msg::path, msg::url), "", "Successfully stored {path} to {url}.") +DECLARE_MESSAGE(AssetCacheScriptBadVariable, + (msg::value, msg::list), + "{value} is the script template passed to x-script, {list} is the name of the unknown replacement", + "the script template {value} contains unknown replacement {list}") +DECLARE_MESSAGE(AssetCacheScriptBadVariableHint, + (msg::list), + "{list} is the name of the unknown replacement", + "if you want this on the literal command line, use {{{{{list}}}}}") +DECLARE_MESSAGE(AssetCacheScriptCommandLine, (), "", "the full script command line was") +DECLARE_MESSAGE(AssetCacheScriptNeedsSha, + (msg::value, msg::url), + "{value} is the script template the user supplied to x-script", + "the script template {value} requires a SHA, but no SHA is known for attempted download of {url}") +DECLARE_MESSAGE(AssetCacheScriptNeedsUrl, + (msg::value, msg::sha), + "{value} is the script template the user supplied to x-script", + "the script template {value} requires a URL, but no URL is known for attempted download of {sha}") +DECLARE_MESSAGE(AssetCacheScriptFailed, + (msg::exit_code), + "", + "the asset cache script returned nonzero exit code {exit_code}") +DECLARE_MESSAGE(AssetCacheScriptFailedToWriteFile, + (), + "", + "the asset cache script returned success but did not create expected result file") +DECLARE_MESSAGE(AssetCacheScriptFailedToWriteCorrectHash, + (), + "", + "the asset cache script returned success but the resulting file has an unexpected hash") +DECLARE_MESSAGE(AssetCacheSuccesfullyStored, (), "", "Store success") DECLARE_MESSAGE(AssetSourcesArg, (), "", "Asset caching sources. See 'vcpkg help assetcaching'") DECLARE_MESSAGE(ASemanticVersionString, (), "", "a semantic version string") DECLARE_MESSAGE(ASetOfFeatures, (), "", "a set of features") DECLARE_MESSAGE(AStringOrArrayOfStrings, (), "", "a string or array of strings") DECLARE_MESSAGE(AStringStringDictionary, (), "", "a \"string\": \"string\" dictionary") +DECLARE_MESSAGE(AToolDataObject, (), "", "tool metadata") +DECLARE_MESSAGE(AToolDataArray, (), "", "an array of tool metadata") +DECLARE_MESSAGE(AToolDataFile, (), "", "a tool data file") +DECLARE_MESSAGE(AToolDataOS, (), "", "a tool data operating system") +DECLARE_MESSAGE(AToolDataVersion, (), "", "a tool data version") +DECLARE_MESSAGE(ToolDataFileSchemaVersionNotSupported, + (msg::version), + "", + "document schema version {version} is not supported by this version of vcpkg") DECLARE_MESSAGE(AttemptingToSetBuiltInBaseline, (), "", @@ -865,15 +913,8 @@ DECLARE_MESSAGE(CommandFailed, "command:\n" "{command_line}\n" "failed with the following output:") -DECLARE_MESSAGE(CommandFailedCode, - (msg::command_line, msg::exit_code), - "", - "command:\n" - "{command_line}\n" - "failed with exit code {exit_code} and the following output:") DECLARE_MESSAGE(CommunityTriplets, (), "", "Community Triplets:") DECLARE_MESSAGE(CompilerPath, (msg::path), "", "Compiler found: {path}") -DECLARE_MESSAGE(CompressFolderFailed, (msg::path), "", "Failed to compress folder \"{path}\":") DECLARE_MESSAGE(ComputingInstallPlan, (), "", "Computing installation plan...") DECLARE_MESSAGE(ConfigurationErrorRegistriesWithoutBaseline, (msg::path, msg::url), @@ -925,10 +966,6 @@ DECLARE_MESSAGE(CouldNotFindGitTreeAtCommit, (msg::package_name, msg::commit_sha), "", "could not find the git tree for `versions` in repo {package_name} at commit {commit_sha}") -DECLARE_MESSAGE(CouldNotFindToolVersion, - (msg::version, msg::path), - "", - "Could not find in {path}") DECLARE_MESSAGE(CouldNotFindVersionDatabaseFile, (msg::path), "", "Couldn't find the versions database file: {path}") DECLARE_MESSAGE(CreatedNuGetPackage, (msg::path), "", "Created nupkg: {path}") DECLARE_MESSAGE(CreateFailureLogsDir, (msg::path), "", "Creating failure logs output directory {path}.") @@ -936,6 +973,10 @@ DECLARE_MESSAGE(Creating7ZipArchive, (), "", "Creating 7zip archive...") DECLARE_MESSAGE(CreatingNugetPackage, (), "", "Creating NuGet package...") DECLARE_MESSAGE(CreatingZipArchive, (), "", "Creating zip archive...") DECLARE_MESSAGE(CreationFailed, (msg::path), "", "Creating {path} failed.") +DECLARE_MESSAGE(CurlFailedGeneric, + (msg::exit_code), + "curl is the name of a program, see curl.se.", + "curl operation failed with error code {exit_code}.") DECLARE_MESSAGE(CurlFailedToPut, (msg::exit_code, msg::url), "curl is the name of a program, see curl.se", @@ -944,15 +985,13 @@ DECLARE_MESSAGE(CurlFailedToPutHttp, (msg::exit_code, msg::url, msg::value), "curl is the name of a program, see curl.se. {value} is an HTTP status code", "curl failed to put file to {url} with exit code {exit_code} and http code {value}.") -DECLARE_MESSAGE(CurlResponseTruncatedRetrying, - (msg::value), - "{value} is the number of milliseconds for which we are waiting this time", - "curl returned a partial response; waiting {value} milliseconds and trying again") -DECLARE_MESSAGE(CurlTimeout, - (msg::command_line), - "", - "curl was unable to perform all requested HTTP operations, even after timeout and retries. The last " - "command line was: {command_line}") +DECLARE_MESSAGE( + CurlFailedToReturnExpectedNumberOfExitCodes, + (msg::exit_code, msg::command_line), + "", + "curl failed to return the expected number of exit codes; this can happen if something terminates curl " + "before it has finished. curl exited with {exit_code} which is normally the result code for the last operation, " + "but may be the result of a crash. The command line was {command_line}, and all output is below:") DECLARE_MESSAGE(CurrentCommitBaseline, (msg::commit_sha), "", @@ -1027,53 +1066,65 @@ DECLARE_MESSAGE(DownloadAvailable, "", "A downloadable copy of this tool is available and can be used by unsetting {env_var}.") DECLARE_MESSAGE(DownloadedSources, (msg::spec), "", "Downloaded sources for {spec}") -DECLARE_MESSAGE(DownloadFailedCurl, - (msg::url, msg::exit_code), - "", - "{url}: curl failed to download with exit code {exit_code}") -DECLARE_MESSAGE(DownloadFailedHashMismatch, - (msg::url, msg::path, msg::expected, msg::actual), - "{expected} and {actual} are SHA512 hashes in hex format.", - "File does not have the expected hash:\n" - "url: {url}\n" - "File: {path}\n" - "Expected hash: {expected}\n" - "Actual hash: {actual}") +DECLARE_MESSAGE(DownloadFailedHashMismatch, (msg::url), "", "download from {url} had an unexpected hash") +DECLARE_MESSAGE(DownloadFailedHashMismatchActualHash, (msg::sha), "", "Actual : {sha}") +DECLARE_MESSAGE(DownloadFailedHashMismatchExpectedHash, (msg::sha), "", "Expected: {sha}") +DECLARE_MESSAGE( + DownloadFailedHashMismatchZero, + (msg::sha), + "", + "failing download because the expected SHA512 was all zeros, please change the expected SHA512 to: {sha}") DECLARE_MESSAGE(DownloadFailedRetrying, - (msg::value), + (msg::value, msg::url), "{value} is a number of milliseconds", - "Download failed -- retrying after {value}ms") + "Download {url} failed -- retrying after {value}ms") DECLARE_MESSAGE(DownloadFailedStatusCode, (msg::url, msg::value), "{value} is an HTTP status code", "{url}: failed: status code {value}") -DECLARE_MESSAGE(DownloadFailedProxySettings, - (msg::path, msg::url), - "", - "Failed to download {path}.\nIf you are using a proxy, please ensure your proxy settings are " - "correct.\nPossible causes are:\n" - "1. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable " - "to `https//address:port`.\nThis is not correct, because `https://` prefix " - "claims the proxy is an HTTPS proxy, while your proxy (v2ray, shadowsocksr, etc...) is an HTTP proxy.\n" - "Try setting `http://address:port` to both HTTP_PROXY and HTTPS_PROXY instead.\n" - "2. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings " - "set by your proxy software. See, {url}\n" - "The value set by your proxy might be wrong, or have same `https://` prefix issue.\n" - "3. Your proxy's remote server is our of service.\n" - "If you've tried directly download the link, and believe this is not a temporay download server " - "failure, please submit an issue at https://github.com/Microsoft/vcpkg/issues\n" - "to report this upstream download server failure.") +DECLARE_MESSAGE( + DownloadFailedProxySettings, + (), + "", + "If you are using a proxy, please ensure your proxy settings are correct.\n" + "Possible causes are:\n" + "1. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to " + "`https//address:port`.\nThis is not correct, because `https://` prefix claims the proxy is an HTTPS " + "proxy, while your proxy (v2ray, shadowsocksr, etc...) is an HTTP proxy.\n" + "Try setting `http://address:port` to both HTTP_PROXY and HTTPS_PROXY instead.\n" + "2. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your " + "proxy software. See: https://github.com/microsoft/vcpkg-tool/pull/77\n" + "The value set by your proxy might be wrong, or have same `https://` prefix issue.\n" + "3. Your proxy's remote server is our of service.\n" + "If you believe this is not a temporary download server failure and vcpkg needs to be changed to download this " + "file from a different location, please submit an issue to https://github.com/Microsoft/vcpkg/issues") DECLARE_MESSAGE(DownloadingPortableToolVersionX, (msg::tool_name, msg::version), "", "A suitable version of {tool_name} was not found (required v{version}).") -DECLARE_MESSAGE(DownloadWinHttpError, - (msg::system_api, msg::exit_code, msg::url), - "", - "{url}: {system_api} failed with exit code {exit_code}") +DECLARE_MESSAGE(DownloadingAssetShaToFile, (msg::sha, msg::path), "", "Downloading asset cache entry {sha} -> {path}") +DECLARE_MESSAGE(DownloadingAssetShaWithoutAssetCache, + (msg::sha, msg::path), + "", + "requested download of asset cache entry {sha} -> {path}, but no asset caches are configured") +DECLARE_MESSAGE(DownloadingFile, (msg::path), "", "Downloading {path}") +DECLARE_MESSAGE(DownloadingFileFirstAuthoritativeSource, (msg::path, msg::url), "", "Downloading {path}, trying {url}") +DECLARE_MESSAGE(DownloadingUrlToFile, (msg::url, msg::path), "", "Downloading {url} -> {path}") DECLARE_MESSAGE(DownloadingVcpkgStandaloneBundle, (msg::version), "", "Downloading standalone bundle {version}.") DECLARE_MESSAGE(DownloadingVcpkgStandaloneBundleLatest, (), "", "Downloading latest standalone bundle.") +DECLARE_MESSAGE(DownloadOrUrl, (msg::url), "", "or {url}") +DECLARE_MESSAGE(DownloadTryingAuthoritativeSource, (msg::url), "", "Trying {url}") DECLARE_MESSAGE(DownloadRootsDir, (msg::env_var), "", "Downloads directory (default: {env_var})") +DECLARE_MESSAGE(DownloadSuccesful, (msg::path), "", "Successfully downloaded {path}") +DECLARE_MESSAGE(DownloadSuccesfulUploading, + (msg::path, msg::url), + "", + "Successfully downloaded {path}, storing to {url}") +DECLARE_MESSAGE(DownloadWinHttpError, + (msg::system_api, msg::exit_code, msg::url), + "", + "{url}: {system_api} failed with exit code {exit_code}.") +DECLARE_MESSAGE(DuplicateDependencyOverride, (msg::package_name), "", "{package_name} already has an override") DECLARE_MESSAGE(DuplicatedKeyInObj, (msg::value), "{value} is a json property/object", @@ -1116,6 +1167,15 @@ DECLARE_MESSAGE(ErrorInvalidManifestModeOption, (msg::option), "", "The option --{option} is not supported in manifest mode.") +DECLARE_MESSAGE(ErrorManifestMustDifferFromOverlay, + (msg::path), + "", + "The manifest directory ({path}) cannot be the same as a directory configured in overlay-ports.") +DECLARE_MESSAGE(ErrorManifestMustDifferFromOverlayDot, + (), + "", + "The manifest directory cannot be the same as a directory configured in overlay-ports, so " + "\"overlay-ports\" values cannot be \".\".") DECLARE_MESSAGE( ErrorMissingVcpkgRoot, (), @@ -1249,10 +1309,6 @@ DECLARE_MESSAGE(FailedToDeleteInsideDueToFile, "printed after this", "failed to remove_all_inside({value}) due to {path}: ") DECLARE_MESSAGE(FailedToDetermineCurrentCommit, (), "", "Failed to determine the current commit:") -DECLARE_MESSAGE(MissingAssetBlockOrigin, - (msg::path), - "x-block-origin is a vcpkg term. Do not translate", - "Missing {path} and downloads are blocked by x-block-origin.") DECLARE_MESSAGE(MissingShaVariable, (), "{{sha}} should not be translated", @@ -1296,10 +1352,6 @@ DECLARE_MESSAGE(FailedToParseSerializedBinParagraph, "[sanity check] Failed to parse a serialized binary paragraph.\nPlease open an issue at " "https://github.com/microsoft/vcpkg, " "with the following output:\n{error_msg}\nSerialized Binary Paragraph:") -DECLARE_MESSAGE(FailedToParseVersionXML, - (msg::tool_name, msg::version), - "", - "Could not parse version for tool {tool_name}. Version string was: {version}") DECLARE_MESSAGE(FailedToRunToolToDetermineVersion, (msg::tool_name, msg::path), "Additional information, such as the command line output, if any, will be appended on " @@ -1344,7 +1396,7 @@ DECLARE_MESSAGE(FetchingRegistryInfo, (msg::url, msg::value), "{value} is a reference", "Fetching registry information from {url} ({value})...") -DECLARE_MESSAGE(FileNotFound, (msg::path), "", "{path}: file not found") +DECLARE_MESSAGE(FileNotFound, (), "", "file not found") DECLARE_MESSAGE(FileReadFailed, (msg::path, msg::byte_offset, msg::count), "", @@ -1419,10 +1471,6 @@ DECLARE_MESSAGE(GraphCycleDetected, (msg::package_name), "A list of package names comprising the cycle will be printed after this message.", "Cycle detected within graph at {package_name}:") -DECLARE_MESSAGE(HashFileFailureToRead, - (msg::path), - "Printed after ErrorMessage and before the specific failing filesystem operation (like file not found)", - "failed to read file \"{path}\" for hashing: ") DECLARE_MESSAGE(HashPortManyFiles, (msg::package_name, msg::count), "", @@ -1687,7 +1735,6 @@ DECLARE_MESSAGE(HelpTxtOptNoUsage, (), "", "Does not print CMake usage informati DECLARE_MESSAGE(HelpTxtOptOnlyBinCache, (), "", "Fails if cached binaries are not available") DECLARE_MESSAGE(HelpTxtOptOnlyDownloads, (), "", "Makes best-effort attempt to download sources without building") DECLARE_MESSAGE(HelpTxtOptRecurse, (), "", "Allows removal of packages as part of installation") -DECLARE_MESSAGE(HelpTxtOptUseAria2, (), "", "Uses aria2 to perform download tasks") DECLARE_MESSAGE(HelpTxtOptUseHeadVersion, (), "", @@ -1829,10 +1876,11 @@ DECLARE_MESSAGE( "Please open an issue at " "https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug " "with detailed steps to reproduce the problem.") -DECLARE_MESSAGE(InvalidArchitecture, - (msg::value), - "{value} is what the user entered that we did not understand", - "invalid architecture: {value}") +DECLARE_MESSAGE( + InvalidArchitectureValue, + (msg::value, msg::expected), + "{value} is an unknown CPU architecture type, {expected} is the list of accepted CPU architecture values", + "Invalid architecture: {value}. Expected one of: {expected}") DECLARE_MESSAGE(InvalidArgument, (), "", "invalid argument") DECLARE_MESSAGE( InvalidArgumentRequiresAbsolutePath, @@ -1955,12 +2003,26 @@ DECLARE_MESSAGE(InvalidOptionForRemove, "'remove' is a command that should not be changed.", "'remove' accepts either libraries or '--outdated'") DECLARE_MESSAGE(InvalidPortVersonName, (msg::path), "", "Found invalid port version file name: `{path}`.") +DECLARE_MESSAGE(InvalidSha512, + (msg::sha), + "", + "invalid SHA-512 hash: {sha}\n" + "SHA-512 hash must be 128 characters long and contain only hexadecimal digits") DECLARE_MESSAGE(InvalidSharpInVersion, (), "", "invalid character '#' in version text") DECLARE_MESSAGE(InvalidSharpInVersionDidYouMean, (msg::value), "{value} is an integer. `\"port-version\":' is JSON syntax and should be unlocalized", "invalid character '#' in version text. Did you mean \"port-version\": {value}?") DECLARE_MESSAGE(InvalidString, (), "", "Invalid utf8 passed to Value::string(std::string)") +DECLARE_MESSAGE(InvalidToolOSValue, + (msg::value, msg::expected), + "{value} is an unknown operating system, {expected} is the list of accepted operating system values", + "Invalid tool operating system: {value}. Expected one of: {expected}") +DECLARE_MESSAGE( + InvalidToolVersion, + (), + "", + "Invalid tool version; expected a string containing a substring of between 1 and 3 numbers separated by dots.") DECLARE_MESSAGE(InvalidTriplet, (msg::triplet), "", "Invalid triplet: {triplet}") DECLARE_MESSAGE(InvalidValueHashAdditionalFiles, (msg::path), @@ -2091,7 +2153,8 @@ DECLARE_MESSAGE(MismatchedManifestAfterReserialize, DECLARE_MESSAGE(MismatchedNames, (msg::package_name, msg::actual), "{actual} is the port name found", - "names did not match: '{package_name}' != '{actual}'") + "the port name declared in the metadata file did not match the directory. Expected the port to be " + "named {package_name}, but the file declares {actual}.") DECLARE_MESSAGE(MismatchedSpec, (msg::path, msg::expected, msg::actual), "{expected} and {actual} are package specs like 'zlib:x64-windows'", @@ -2198,7 +2261,6 @@ DECLARE_MESSAGE(NonZeroRemainingArgs, "the command '{command_name}' does not accept any additional arguments") DECLARE_MESSAGE(NoOutdatedPackages, (), "", "There are no outdated packages.") DECLARE_MESSAGE(NoRegistryForPort, (msg::package_name), "", "no registry configured for port {package_name}") -DECLARE_MESSAGE(NoUrlsAndHashSpecified, (msg::sha), "", "No urls specified to download SHA: {sha}") DECLARE_MESSAGE(NoUrlsAndNoHashSpecified, (), "", "No urls specified and no hash specified.") DECLARE_MESSAGE(NugetOutputNotCapturedBecauseInteractiveSpecified, (), @@ -2230,8 +2292,11 @@ DECLARE_MESSAGE(OptionRequiresOption, DECLARE_MESSAGE(Options, (), "Printed just before a list of options for a command", "Options") DECLARE_MESSAGE(OriginalBinParagraphHeader, (), "", "\nOriginal Binary Paragraph") DECLARE_MESSAGE(OtherCommandsHeader, (), "", "Other") -DECLARE_MESSAGE(OverlayPatchDir, (msg::path), "", "Overlay path \"{path}\" must exist and must be a directory.") -DECLARE_MESSAGE(OverlayPortsDirectoriesHelp, (msg::env_var), "", "Directories of overlay ports (also: {env_var})") +DECLARE_MESSAGE(OverlayPatchDir, (msg::path), "", "Overlay path \"{path}\" must be an existing directory.") +DECLARE_MESSAGE(OverlayPortsHelp, + (msg::env_var), + "", + "Overlay-port directories, or directories containing overlay-port directories (also: {env_var})") DECLARE_MESSAGE(OverlayTripletDirectoriesHelp, (msg::env_var), "", "Directories of overlay triplets (also: {env_var})") DECLARE_MESSAGE(OverlayTriplets, (msg::path), "", "Overlay Triplets from \"{path}\":") DECLARE_MESSAGE(OverwritingFile, (msg::path), "", "File {path} was already present and will be overwritten") @@ -2607,6 +2672,7 @@ DECLARE_MESSAGE(ProgramReturnedNonzeroExitCode, (msg::tool_name, msg::exit_code), "The program's console output is appended after this.", "{tool_name} failed with exit code: ({exit_code}).") +DECLARE_MESSAGE(ProgramPathReturnedNonzeroExitCode, (msg::exit_code), "", "failed with exit code {exit_code}") DECLARE_MESSAGE( ProvideExportType, (), @@ -2723,11 +2789,15 @@ DECLARE_MESSAGE(SpecifyTargetArch, "'vcpkg help triplet' is a command line that should not be localized", "Target triplet. See 'vcpkg help triplet' (default: {env_var})") DECLARE_MESSAGE(StartCodeUnitInContinue, (), "", "found start code unit in continue position") -DECLARE_MESSAGE(StoredBinariesToDestinations, - (msg::count, msg::elapsed), - "", - "Stored binaries in {count} destinations in {elapsed}.") DECLARE_MESSAGE(StoreOptionMissingSha, (), "", "--store option is invalid without a sha512") +DECLARE_MESSAGE(SubmittingBinaryCacheBackground, + (msg::spec, msg::count), + "", + "Starting submission of {spec} to {count} binary cache(s) in the background") +DECLARE_MESSAGE(SubmittingBinaryCacheComplete, + (msg::spec, msg::count, msg::elapsed), + "", + "Completed submission of {spec} to {count} binary cache(s) in {elapsed}") DECLARE_MESSAGE(SuccessfulyExported, (msg::package_name, msg::path), "", "Exported {package_name} to {path}") DECLARE_MESSAGE(SuggestGitPull, (), "", "The result may be outdated. Run `git pull` to get the latest results.") DECLARE_MESSAGE(SuggestStartingBashShell, @@ -2746,6 +2816,11 @@ DECLARE_MESSAGE(SystemRootMustAlwaysBePresent, "", "Expected the SystemRoot environment variable to be always set on Windows.") DECLARE_MESSAGE(SystemTargetsInstallFailed, (msg::path), "", "failed to install system targets file to {path}") +DECLARE_MESSAGE( + ToolHashMismatch, + (msg::tool_name, msg::expected, msg::actual), + "{expected} and {actual} are SHA512 hashes in hex format.", + "{tool_name} appears to be already downloaded, but has an incorrect hash. Expected {expected} but was {actual}") DECLARE_MESSAGE(ToolFetchFailed, (msg::tool_name), "", "Could not fetch {tool_name}.") DECLARE_MESSAGE(ToolInWin10, (), "", "This utility is bundled with Windows 10 or later.") DECLARE_MESSAGE(ToolOfVersionXNotFound, @@ -2972,7 +3047,7 @@ DECLARE_MESSAGE( DECLARE_MESSAGE(UploadingBinariesToVendor, (msg::spec, msg::vendor, msg::path), "", - "Uploading binaries for '{spec}' to '{vendor}' source \"{path}\".") + "Uploading binaries for {spec} to {vendor} from {path}") DECLARE_MESSAGE(UsageTextHere, (), "", "the usage file is here") DECLARE_MESSAGE(UsageInstallInstructions, (), "", "you can install the usage file with the following CMake") DECLARE_MESSAGE(UseEnvVar, @@ -3043,11 +3118,6 @@ DECLARE_MESSAGE(VersionCommandHeader, (msg::version), "", "vcpkg package management program version {version}\n\nSee LICENSE.txt for license information.") -DECLARE_MESSAGE( - VersionConflictXML, - (msg::path, msg::expected_version, msg::actual_version), - "", - "Expected {path} version: [{expected_version}], but was [{actual_version}]. Please re-run bootstrap-vcpkg.") DECLARE_MESSAGE(VersionConstraintNotInDatabase1, (msg::package_name, msg::version), "", @@ -3225,6 +3295,10 @@ DECLARE_MESSAGE(VSExaminedPaths, (), "", "The following paths were examined for DECLARE_MESSAGE(VSNoInstances, (), "", "Could not locate a complete Visual Studio instance") DECLARE_MESSAGE(WaitingForChildrenToExit, (), "", "Waiting for child processes to exit...") DECLARE_MESSAGE(WaitingToTakeFilesystemLock, (msg::path), "", "waiting to take filesystem lock on {path}...") +DECLARE_MESSAGE(WaitUntilPackagesUploaded, + (msg::count), + "", + "Waiting for {count} remaining binary cache submissions...") DECLARE_MESSAGE(WarningsTreatedAsErrors, (), "", "previous warnings being interpreted as errors") DECLARE_MESSAGE(WarnOnParseConfig, (msg::path), "", "Found the following warnings in configuration {path}:") DECLARE_MESSAGE(WhileCheckingOutBaseline, (msg::commit_sha), "", "while checking out baseline {commit_sha}") @@ -3243,6 +3317,7 @@ DECLARE_MESSAGE(WhileParsingVersionsForPort, (msg::package_name, msg::path), "", "while parsing versions for {package_name} from {path}") +DECLARE_MESSAGE(WhileRunningAssetCacheScriptCommandLine, (), "", "while running asset cache script command line") DECLARE_MESSAGE(WhileValidatingVersion, (msg::version), "", "while validating version: {version}") DECLARE_MESSAGE(WindowsOnlyCommand, (), "", "This command only supports Windows.") DECLARE_MESSAGE(WroteNuGetPkgConfInfo, (msg::path), "", "Wrote NuGet package config information to {path}") diff --git a/include/vcpkg/base/message_sinks.h b/include/vcpkg/base/message_sinks.h index 4d854364a0..342f9e5672 100644 --- a/include/vcpkg/base/message_sinks.h +++ b/include/vcpkg/base/message_sinks.h @@ -4,56 +4,55 @@ #include +#include +#include +#include + namespace vcpkg { + struct MessageLineSegment + { + Color color; + std::string text; + }; + + struct MessageLine + { + MessageLine() = default; + MessageLine(const MessageLine&) = default; + MessageLine(MessageLine&&) = default; + + explicit MessageLine(const LocalizedString& ls); + explicit MessageLine(LocalizedString&& ls); + + void print(Color color, StringView text); + void print(StringView text); + const std::vector& get_segments() const noexcept; + + std::string to_string() const; + void to_string(std::string& target) const; + + private: + std::vector segments; + }; struct MessageSink { - virtual void print(Color c, StringView sv) = 0; + virtual void println(const MessageLine& line) = 0; + virtual void println(MessageLine&& line) = 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"); - } - inline void println(Color c, LocalizedString&& s) { this->print(c, s.append_raw('\n')); } - inline void println(LocalizedString&& s) { this->print(Color::none, s.append_raw('\n')); } - void println_warning(const LocalizedString& s); - void println_error(const LocalizedString& s); + virtual void println(const LocalizedString& s); + virtual void println(LocalizedString&& s); + + virtual void println(Color c, const LocalizedString& s); + virtual void println(Color c, LocalizedString&& s); - template - void print(VCPKG_DECL_MSG_ARGS) - { - this->print(msg::format(VCPKG_EXPAND_MSG_ARGS)); - } template void println(VCPKG_DECL_MSG_ARGS) { this->println(msg::format(VCPKG_EXPAND_MSG_ARGS)); } - template - void println_warning(VCPKG_DECL_MSG_ARGS) - { - this->println_warning(msg::format(VCPKG_EXPAND_MSG_ARGS)); - } - template - void println_error(VCPKG_DECL_MSG_ARGS) - { - this->println_error(msg::format(VCPKG_EXPAND_MSG_ARGS)); - } - template - void print(Color c, VCPKG_DECL_MSG_ARGS) - { - this->print(c, msg::format(VCPKG_EXPAND_MSG_ARGS)); - } template void println(Color c, VCPKG_DECL_MSG_ARGS) { @@ -68,11 +67,39 @@ namespace vcpkg ~MessageSink() = default; }; - struct CombiningSink : MessageSink + struct TeeSink final : MessageSink { MessageSink& m_first; MessageSink& m_second; - CombiningSink(MessageSink& first, MessageSink& second) : m_first(first), m_second(second) { } - void print(Color c, StringView sv) override; + TeeSink(MessageSink& first, MessageSink& second) : m_first(first), m_second(second) { } + + virtual void println(const MessageLine& line) override; + virtual void println(MessageLine&& line) override; + virtual void println(const LocalizedString& line) override; + virtual void println(LocalizedString&& line) override; + virtual void println(Color color, const LocalizedString& line) override; + virtual void println(Color color, LocalizedString&& line) override; + }; + + struct BGMessageSink final : MessageSink + { + BGMessageSink(MessageSink& out_sink) : out_sink(out_sink) { } + ~BGMessageSink() { publish_directly_to_out_sink(); } + // must be called from producer + virtual void println(const MessageLine& line) override; + virtual void println(MessageLine&& line) override; + using MessageSink::println; + + // must be called from consumer (synchronizer of out) + void print_published(); + + void publish_directly_to_out_sink(); + + private: + MessageSink& out_sink; + + std::mutex m_published_lock; + std::vector m_published; + bool m_print_directly_to_out_sink = false; }; } diff --git a/include/vcpkg/base/parse.h b/include/vcpkg/base/parse.h index bf01590697..0e7e4c3106 100644 --- a/include/vcpkg/base/parse.h +++ b/include/vcpkg/base/parse.h @@ -2,13 +2,12 @@ #include +#include #include #include #include #include -#include - #include namespace vcpkg @@ -44,7 +43,7 @@ namespace vcpkg struct ParserBase { - ParserBase(StringView text, Optional origin, TextRowCol init_rowcol = {}); + ParserBase(StringView text, Optional origin, TextRowCol init_rowcol); static constexpr bool is_whitespace(char32_t ch) { return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n'; } static constexpr bool is_lower_alpha(char32_t ch) { return ch >= 'a' && ch <= 'z'; } diff --git a/include/vcpkg/base/strings.h b/include/vcpkg/base/strings.h index 2d27d27b29..a596d04738 100644 --- a/include/vcpkg/base/strings.h +++ b/include/vcpkg/base/strings.h @@ -122,7 +122,7 @@ namespace vcpkg::Strings const char* case_insensitive_ascii_search(StringView s, StringView pattern); bool case_insensitive_ascii_contains(StringView s, StringView pattern); - bool case_insensitive_ascii_equals(StringView left, StringView right); + bool case_insensitive_ascii_equals(StringView left, StringView right) noexcept; bool case_insensitive_ascii_less(StringView left, StringView right); void inplace_ascii_to_lowercase(char* first, char* last); @@ -198,6 +198,8 @@ namespace vcpkg::Strings const char* find_first_of(StringView searched, StringView candidates); + [[nodiscard]] std::string::size_type find_last(StringView searched, char c); + [[nodiscard]] std::vector find_all_enclosed(StringView input, StringView left_delim, StringView right_delim); diff --git a/include/vcpkg/base/system.h b/include/vcpkg/base/system.h index 1d1c334845..aaa4ec8b04 100644 --- a/include/vcpkg/base/system.h +++ b/include/vcpkg/base/system.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -44,9 +45,11 @@ namespace vcpkg long get_process_id(); - Optional to_cpu_architecture(StringView arch); + Optional to_cpu_architecture(StringView arch) noexcept; - ZStringView to_zstring_view(CPUArchitecture arch) noexcept; + StringLiteral to_string_literal(CPUArchitecture arch) noexcept; + + LocalizedString all_comma_separated_cpu_architectures(); CPUArchitecture get_host_processor(); @@ -62,3 +65,5 @@ namespace vcpkg Optional guess_visual_studio_prompt_target_architecture(); } + +VCPKG_FORMAT_WITH_TO_STRING_LITERAL_NONMEMBER(vcpkg::CPUArchitecture); diff --git a/include/vcpkg/base/system.process.h b/include/vcpkg/base/system.process.h index e362dd997c..198d2e1f3f 100644 --- a/include/vcpkg/base/system.process.h +++ b/include/vcpkg/base/system.process.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -119,8 +120,23 @@ namespace vcpkg std::string stdin_content; }; - ExpectedL cmd_execute(const Command& cmd); - ExpectedL cmd_execute(const Command& cmd, const ProcessLaunchSettings& settings); + Optional cmd_execute(DiagnosticContext& context, const Command& cmd); + inline ExpectedL cmd_execute(const Command& cmd) + { + return adapt_context_to_expected( + static_cast (*)(DiagnosticContext&, const Command&)>(cmd_execute), cmd); + } + Optional cmd_execute(DiagnosticContext& context, + const Command& cmd, + const ProcessLaunchSettings& settings); + inline ExpectedL cmd_execute(const Command& cmd, const ProcessLaunchSettings& settings) + { + return adapt_context_to_expected( + static_cast (*)( + DiagnosticContext&, const Command&, const ProcessLaunchSettings&)>(cmd_execute), + cmd, + settings); + } #if defined(_WIN32) Environment cmd_execute_and_capture_environment(const Command& cmd, const Environment& env); @@ -128,25 +144,97 @@ namespace vcpkg void cmd_execute_background(const Command& cmd_line); - ExpectedL cmd_execute_and_capture_output(const Command& cmd); - ExpectedL cmd_execute_and_capture_output(const Command& cmd, - const RedirectedProcessLaunchSettings& settings); + Optional cmd_execute_and_capture_output(DiagnosticContext& context, const Command& cmd); + inline ExpectedL cmd_execute_and_capture_output(const Command& cmd) + { + return adapt_context_to_expected( + static_cast (*)(DiagnosticContext&, const Command&)>( + cmd_execute_and_capture_output), + cmd); + } + Optional cmd_execute_and_capture_output(DiagnosticContext& context, + const Command& cmd, + const RedirectedProcessLaunchSettings& settings); + inline ExpectedL cmd_execute_and_capture_output(const Command& cmd, + const RedirectedProcessLaunchSettings& settings) + { + return adapt_context_to_expected( + static_cast (*)( + DiagnosticContext&, const Command&, const RedirectedProcessLaunchSettings&)>( + cmd_execute_and_capture_output), + cmd, + settings); + } std::vector> cmd_execute_and_capture_output_parallel(View commands); std::vector> cmd_execute_and_capture_output_parallel( View commands, const RedirectedProcessLaunchSettings& settings); - ExpectedL cmd_execute_and_stream_lines(const Command& cmd, - const std::function& per_line_cb); - ExpectedL cmd_execute_and_stream_lines(const Command& cmd, - const RedirectedProcessLaunchSettings& settings, - const std::function& per_line_cb); - - ExpectedL cmd_execute_and_stream_data(const Command& cmd, - const std::function& data_cb); - ExpectedL cmd_execute_and_stream_data(const Command& cmd, + Optional cmd_execute_and_stream_lines(DiagnosticContext& context, + const Command& cmd, + const std::function& per_line_cb); + inline ExpectedL cmd_execute_and_stream_lines(const Command& cmd, + const std::function& per_line_cb) + { + return adapt_context_to_expected( + static_cast (*)( + DiagnosticContext&, const Command&, const std::function&)>( + cmd_execute_and_stream_lines), + cmd, + per_line_cb); + } + Optional cmd_execute_and_stream_lines(DiagnosticContext& context, + const Command& cmd, const RedirectedProcessLaunchSettings& settings, - const std::function& data_cb); + const std::function& per_line_cb); + inline ExpectedL cmd_execute_and_stream_lines(const Command& cmd, + const RedirectedProcessLaunchSettings& settings, + const std::function& per_line_cb) + { + return adapt_context_to_expected( + static_cast (*)(DiagnosticContext&, + const Command&, + const RedirectedProcessLaunchSettings&, + const std::function&)>( + cmd_execute_and_stream_lines), + cmd, + settings, + per_line_cb); + } + + Optional cmd_execute_and_stream_data(DiagnosticContext& context, + const Command& cmd, + const std::function& data_cb); + inline ExpectedL cmd_execute_and_stream_data(const Command& cmd, + const std::function& data_cb) + { + return adapt_context_to_expected( + static_cast (*)( + DiagnosticContext&, const Command&, const std::function&)>( + cmd_execute_and_stream_data), + cmd, + data_cb); + } + + Optional cmd_execute_and_stream_data(DiagnosticContext& context, + const Command& cmd, + const RedirectedProcessLaunchSettings& settings, + const std::function& data_cb); + + inline ExpectedL cmd_execute_and_stream_data(const Command& cmd, + const RedirectedProcessLaunchSettings& settings, + const std::function& data_cb) + { + return adapt_context_to_expected( + static_cast (*)(DiagnosticContext&, + const Command&, + const RedirectedProcessLaunchSettings&, + const std::function&)>( + cmd_execute_and_stream_data), + cmd, + settings, + data_cb); + } uint64_t get_subproccess_stats(); @@ -170,9 +258,15 @@ namespace vcpkg // If exit code is 0, returns a 'success' ExpectedL. // Otherwise, returns an ExpectedL containing error text - ExpectedL flatten(const ExpectedL&, StringView tool_name); + ExpectedL flatten(const ExpectedL& maybe_exit, StringView tool_name); // If exit code is 0, returns a 'success' ExpectedL containing the output // Otherwise, returns an ExpectedL containing error text - ExpectedL flatten_out(ExpectedL&&, StringView tool_name); + ExpectedL flatten_out(ExpectedL&& maybe_exit, StringView tool_name); + + // Checks that `maybe_exit` implies a process that returned 0. If so, returns a pointer to the process' output. + // Otherwise, records an error in `context` and returns nullptr. + std::string* check_zero_exit_code(DiagnosticContext& context, + Optional& maybe_exit, + StringView exe_path); } diff --git a/include/vcpkg/binarycaching.h b/include/vcpkg/binarycaching.h index f9057847df..82328008c1 100644 --- a/include/vcpkg/binarycaching.h +++ b/include/vcpkg/binarycaching.h @@ -8,8 +8,10 @@ #include #include +#include #include #include +#include #include #include @@ -20,6 +22,7 @@ #include #include #include +#include #include #include @@ -186,7 +189,8 @@ namespace vcpkg struct ReadOnlyBinaryCache { ReadOnlyBinaryCache() = default; - ReadOnlyBinaryCache(BinaryProviders&& providers); + ReadOnlyBinaryCache(const ReadOnlyBinaryCache&) = delete; + ReadOnlyBinaryCache& operator=(const ReadOnlyBinaryCache&) = delete; /// Gives the IBinaryProvider an opportunity to batch any downloading or server communication for /// executing `actions`. @@ -194,6 +198,8 @@ namespace vcpkg bool is_restored(const InstallPlanAction& ipa) const; + void install_read_provider(std::unique_ptr&& provider); + /// Checks whether the `actions` are present in the cache, without restoring them. Used by CI to determine /// missing packages. /// Returns a vector where each index corresponds to the matching index in `actions`. @@ -205,27 +211,86 @@ namespace vcpkg std::unordered_map m_status; }; + struct BinaryCacheSyncState; + struct BinaryCacheSynchronizer + { + using backing_uint_t = std::conditional_t; + using counter_uint_t = std::conditional_t; + static constexpr backing_uint_t SubmissionCompleteBit = static_cast(1) + << (sizeof(backing_uint_t) * 8 - 1); + static constexpr backing_uint_t UpperShift = sizeof(counter_uint_t) * 8; + static constexpr backing_uint_t SubmittedMask = + static_cast(static_cast(-1) >> 1u); + static constexpr backing_uint_t CompletedMask = SubmittedMask << UpperShift; + static constexpr backing_uint_t OneCompleted = static_cast(1) << UpperShift; + + void add_submitted() noexcept; + BinaryCacheSyncState fetch_add_completed() noexcept; + counter_uint_t fetch_incomplete_mark_submission_complete() noexcept; + + private: + // This is morally: + // struct State { + // counter_uint_t jobs_submitted; + // bool unused; + // counter_uint_t_minus_one_bit jobs_completed; + // bool submission_complete; + // }; + std::atomic m_state = 0; + }; + + struct BinaryCacheSyncState + { + BinaryCacheSynchronizer::counter_uint_t jobs_submitted; + BinaryCacheSynchronizer::counter_uint_t jobs_completed; + bool submission_complete; + }; + + // compression and upload of binary cache entries happens on a single 'background' thread, `m_push_thread` + // Thread safety is achieved within the binary cache providers by: + // 1. Only using one thread in the background for this work. + // 2. Forming a queue of work for that thread to consume in `m_actions_to_push`, which maintains its own thread + // safety + // 3. Sending any replies from the background thread through `m_bg_msg_sink` + // 4. Ensuring any supporting data, such as tool exes, is provided before the background thread is started. + // 5. Ensuring that work is not submitted to the background thread until the corresponding `packages` directory to + // upload is no longer being actively written by the foreground thread. struct BinaryCache : ReadOnlyBinaryCache { - static ExpectedL make(const VcpkgCmdArguments& args, const VcpkgPaths& paths, MessageSink& sink); + bool install_providers(const VcpkgCmdArguments& args, const VcpkgPaths& paths, MessageSink& status_sink); - BinaryCache(const Filesystem& fs); + explicit BinaryCache(const Filesystem& fs); BinaryCache(const BinaryCache&) = delete; - BinaryCache(BinaryCache&&) = default; - + BinaryCache& operator=(const BinaryCache&) = delete; + ~BinaryCache(); /// Called upon a successful build of `action` to store those contents in the binary cache. void push_success(CleanPackages clean_packages, const InstallPlanAction& action); + void print_updates(); + void wait_for_async_complete_and_join(); + private: - BinaryCache(BinaryProviders&& providers, const Filesystem& fs); + struct ActionToPush + { + BinaryPackageWriteInfo request; + CleanPackages clean_after_push; + }; - const Filesystem& m_fs; - Optional m_zip_tool; + ZipTool m_zip_tool; bool m_needs_nuspec_data = false; bool m_needs_zip_file = false; + + const Filesystem& m_fs; + + BGMessageSink m_bg_msg_sink; + BackgroundWorkQueue m_actions_to_push; + BinaryCacheSynchronizer m_synchronizer; + std::thread m_push_thread; + + void push_thread_main(); }; - ExpectedL parse_download_configuration(const Optional& arg); + ExpectedL parse_download_configuration(const Optional& arg); std::string generate_nuget_packages_config(const ActionPlan& action, StringView prefix); diff --git a/include/vcpkg/commands.build.h b/include/vcpkg/commands.build.h index 7dd6481a0c..31d391fb69 100644 --- a/include/vcpkg/commands.build.h +++ b/include/vcpkg/commands.build.h @@ -59,9 +59,6 @@ namespace vcpkg Triplet default_triplet, Triplet host_triplet); - StringLiteral to_string_view(DownloadTool tool); - std::string to_string(DownloadTool tool); - struct BuildPackageOptions { BuildMissing build_missing; @@ -70,7 +67,6 @@ namespace vcpkg CleanBuildtrees clean_buildtrees; CleanPackages clean_packages; CleanDownloads clean_downloads; - DownloadTool download_tool; BackcompatFeatures backcompat_features; KeepGoing keep_going; }; @@ -94,13 +90,18 @@ namespace vcpkg StringLiteral to_string_locale_invariant(const BuildResult build_result); LocalizedString to_string(const BuildResult build_result); LocalizedString create_user_troubleshooting_message(const InstallPlanAction& action, + CIKind detected_ci, const VcpkgPaths& paths, - const Optional& issue_body); + const std::vector& error_logs, + const Optional& maybe_issue_body); inline void print_user_troubleshooting_message(const InstallPlanAction& action, + CIKind detected_ci, const VcpkgPaths& paths, - Optional&& issue_body) + const std::vector& error_logs, + Optional&& maybe_issue_body) { - msg::println(Color::error, create_user_troubleshooting_message(action, paths, issue_body)); + msg::println(Color::error, + create_user_troubleshooting_message(action, detected_ci, paths, error_logs, maybe_issue_body)); } /// diff --git a/include/vcpkg/commands.find.h b/include/vcpkg/commands.find.h index f363f60ab0..ed6baac1c1 100644 --- a/include/vcpkg/commands.find.h +++ b/include/vcpkg/commands.find.h @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -15,7 +16,7 @@ namespace vcpkg bool full_description, bool enable_json, Optional filter, - View overlay_ports); + const OverlayPortPaths& overlay_ports); extern const CommandMetadata CommandFindMetadata; void command_find_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); } diff --git a/include/vcpkg/configuration.h b/include/vcpkg/configuration.h index 79d4d0fe9f..2530c3d954 100644 --- a/include/vcpkg/configuration.h +++ b/include/vcpkg/configuration.h @@ -89,7 +89,7 @@ namespace vcpkg Optional config; }; - Json::IDeserializer& get_configuration_deserializer(); + extern const Json::IDeserializer& configuration_deserializer; // Parse configuration from a file containing a valid vcpkg-configuration.json file Optional parse_configuration(StringView contents, StringView origin, diff --git a/include/vcpkg/configure-environment.h b/include/vcpkg/configure-environment.h index 74807999f6..3f53416a30 100644 --- a/include/vcpkg/configure-environment.h +++ b/include/vcpkg/configure-environment.h @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include @@ -16,9 +18,10 @@ namespace vcpkg { - ExpectedL download_vcpkg_standalone_bundle(const DownloadManager& download_manager, - const Filesystem& fs, - const Path& download_root); + Optional download_vcpkg_standalone_bundle(DiagnosticContext& context, + const AssetCachingSettings& asset_cache_settings, + const Filesystem& fs, + const Path& download_root); int run_configure_environment_command(const VcpkgPaths& paths, View args); diff --git a/include/vcpkg/fwd/build.h b/include/vcpkg/fwd/build.h index ee0fe89f08..085b2fed9e 100644 --- a/include/vcpkg/fwd/build.h +++ b/include/vcpkg/fwd/build.h @@ -57,12 +57,6 @@ namespace vcpkg Release, }; - enum class DownloadTool - { - Builtin, - Aria2, - }; - enum class Editable { No = 0, diff --git a/include/vcpkg/fwd/portfileprovider.h b/include/vcpkg/fwd/portfileprovider.h index 22869bb90e..2c93a1b66e 100644 --- a/include/vcpkg/fwd/portfileprovider.h +++ b/include/vcpkg/fwd/portfileprovider.h @@ -2,9 +2,18 @@ namespace vcpkg { + struct OverlayPortPaths; + struct OverlayPortIndexEntry; struct PortFileProvider; struct PathsPortFileProvider; struct IVersionedPortfileProvider; struct IBaselineProvider; struct IOverlayProvider; + + enum class OverlayPortKind + { + Unknown, // We have not tested yet + Port, // The overlay directory is itself a port + Directory, // The overlay directory itself contains port directories + }; } diff --git a/include/vcpkg/fwd/vcpkgcmdarguments.h b/include/vcpkg/fwd/vcpkgcmdarguments.h index 1c827c6f74..bbf195ae56 100644 --- a/include/vcpkg/fwd/vcpkgcmdarguments.h +++ b/include/vcpkg/fwd/vcpkgcmdarguments.h @@ -20,4 +20,20 @@ namespace vcpkg struct VcpkgCmdArguments; struct FeatureFlagSettings; struct PortApplicableSetting; + + enum class CIKind + { + None, + GithubActions, + GitLabCI, + AzurePipelines, + AppVeyor, + AwsCodeBuild, + CircleCI, + HerokuCI, + JenkinsCI, + TeamCityCI, + TravisCI, + Generic + }; } diff --git a/include/vcpkg/installedpaths.h b/include/vcpkg/installedpaths.h index 08349eb24f..2dcb673362 100644 --- a/include/vcpkg/installedpaths.h +++ b/include/vcpkg/installedpaths.h @@ -21,6 +21,7 @@ namespace vcpkg Path vcpkg_dir_status_file() const { return vcpkg_dir() / FileStatus; } Path vcpkg_dir_info() const { return vcpkg_dir() / FileInfo; } Path vcpkg_dir_updates() const { return vcpkg_dir() / FileUpdates; } + Path compiler_hash_cache_file() const { return vcpkg_dir() / FileCompilerFileHashCacheDotJson; } Path lockfile_path() const { return vcpkg_dir() / FileVcpkgLock; } Path triplet_dir(Triplet t) const { return m_root / t.canonical_name(); } Path share_dir(const PackageSpec& p) const { return triplet_dir(p.triplet()) / FileShare / p.name(); } diff --git a/include/vcpkg/paragraphparser.h b/include/vcpkg/paragraphparser.h index e2a395c13d..97fefb5e1e 100644 --- a/include/vcpkg/paragraphparser.h +++ b/include/vcpkg/paragraphparser.h @@ -2,13 +2,13 @@ #include +#include #include #include #include #include #include -#include #include #include diff --git a/include/vcpkg/paragraphs.h b/include/vcpkg/paragraphs.h index bdb7e9b5de..4770f65b8a 100644 --- a/include/vcpkg/paragraphs.h +++ b/include/vcpkg/paragraphs.h @@ -27,8 +27,6 @@ namespace vcpkg::Paragraphs void append_paragraph_field(StringView name, StringView field, std::string& out_str); - bool is_port_directory(const ReadOnlyFilesystem& fs, const Path& maybe_directory); - struct PortLoadResult { ExpectedL maybe_scfl; @@ -63,7 +61,4 @@ namespace vcpkg::Paragraphs LoadResults try_load_all_registry_ports(const RegistrySet& registries); std::vector load_all_registry_ports(const RegistrySet& registries); - - LoadResults try_load_overlay_ports(const ReadOnlyFilesystem& fs, const Path& dir); - std::vector load_overlay_ports(const ReadOnlyFilesystem& fs, const Path& dir); } diff --git a/include/vcpkg/portfileprovider.h b/include/vcpkg/portfileprovider.h index 25a87ebff7..cc4a9fd8bc 100644 --- a/include/vcpkg/portfileprovider.h +++ b/include/vcpkg/portfileprovider.h @@ -5,12 +5,66 @@ #include #include +#include #include -#include +#include + +#include +#include +#include +#include namespace vcpkg { + struct OverlayPortPaths + { + Optional builtin_overlay_port_dir; + std::vector overlay_ports; + + bool empty() const noexcept; + }; + + struct OverlayPortIndexEntry + { + OverlayPortIndexEntry(OverlayPortKind kind, const Path& directory); + OverlayPortIndexEntry(const OverlayPortIndexEntry&) = delete; + OverlayPortIndexEntry(OverlayPortIndexEntry&&); + + const ExpectedL* try_load_port(const ReadOnlyFilesystem& fs, + StringView port_name); + + ExpectedL try_load_all_ports(const ReadOnlyFilesystem& fs, + std::map& out); + + void check_directory(const ReadOnlyFilesystem& fs) const; + + private: + OverlayPortKind m_kind; + Path m_directory; + + using MapT = std::map, std::less<>>; + // If kind == OverlayPortKind::Unknown, empty + // Otherwise, if kind == OverlayPortKind::Port, + // upon load success, contains exactly one entry with the loaded name of the port + // upon load failure, contains exactly one entry with a key of empty string, value being the load error + // Otherwise, if kind == OverlayPortKind::Directory, contains an entry for each loaded overlay-port in the + // directory + MapT m_loaded_ports; + + OverlayPortKind determine_kind(const ReadOnlyFilesystem& fs); + const ExpectedL* try_load_port_cached_port(StringView port_name); + + MapT::iterator try_load_port_subdirectory_uncached(MapT::iterator hint, + const ReadOnlyFilesystem& fs, + StringView port_name); + + ExpectedL load_all_port_subdirectories(const ReadOnlyFilesystem& fs); + + const ExpectedL* try_load_port_subdirectory_with_cache( + const ReadOnlyFilesystem& fs, StringView port_name); + }; + struct PortFileProvider { virtual ~PortFileProvider() = default; @@ -32,7 +86,6 @@ namespace vcpkg struct IVersionedPortfileProvider { - virtual View get_port_versions(StringView port_name) const = 0; virtual ~IVersionedPortfileProvider() = default; virtual ExpectedL get_control_file( @@ -76,9 +129,10 @@ namespace vcpkg std::unique_ptr make_baseline_provider(const RegistrySet& registry_set); std::unique_ptr make_versioned_portfile_provider(const RegistrySet& registry_set); - std::unique_ptr make_overlay_provider(const ReadOnlyFilesystem& fs, View overlay_ports); + std::unique_ptr make_overlay_provider(const ReadOnlyFilesystem& fs, + const OverlayPortPaths& overlay_ports); std::unique_ptr make_manifest_provider(const ReadOnlyFilesystem& fs, - View overlay_ports, + const OverlayPortPaths& overlay_ports, const Path& manifest_path, std::unique_ptr&& manifest_scf); } diff --git a/include/vcpkg/registries-parsing.h b/include/vcpkg/registries-parsing.h new file mode 100644 index 0000000000..9b34ccedb7 --- /dev/null +++ b/include/vcpkg/registries-parsing.h @@ -0,0 +1,43 @@ +#pragma once +#include + +#include + +namespace vcpkg +{ + struct FilesystemVersionDbEntryDeserializer final : Json::IDeserializer + { + LocalizedString type_name() const override; + View valid_fields() const noexcept override; + Optional visit_object(Json::Reader& r, const Json::Object& obj) const override; + FilesystemVersionDbEntryDeserializer(const Path& root) : registry_root(root) { } + + private: + Path registry_root; + }; + + struct FilesystemVersionDbEntryArrayDeserializer final : Json::IDeserializer> + { + virtual LocalizedString type_name() const override; + virtual Optional> visit_array(Json::Reader& r, + const Json::Array& arr) const override; + FilesystemVersionDbEntryArrayDeserializer(const Path& root) : underlying{root} { } + + private: + FilesystemVersionDbEntryDeserializer underlying; + }; + + struct GitVersionDbEntryDeserializer final : Json::IDeserializer + { + LocalizedString type_name() const override; + View valid_fields() const noexcept override; + Optional visit_object(Json::Reader& r, const Json::Object& obj) const override; + }; + + struct GitVersionDbEntryArrayDeserializer final : Json::IDeserializer> + { + virtual LocalizedString type_name() const override; + virtual Optional> visit_array(Json::Reader& r, + const Json::Array& arr) const override; + }; +} diff --git a/include/vcpkg/registries.h b/include/vcpkg/registries.h index 66d8886623..7a67507da4 100644 --- a/include/vcpkg/registries.h +++ b/include/vcpkg/registries.h @@ -56,8 +56,6 @@ namespace vcpkg struct RegistryEntry { - virtual ExpectedL> get_port_versions() const = 0; - virtual ExpectedL try_load_port(const Version& version) const = 0; virtual ~RegistryEntry() = default; @@ -217,8 +215,4 @@ namespace vcpkg // No match is 0, exact match is SIZE_MAX, wildcard match is the length of the pattern. // Note that the * is included in the match size to distinguish from 0 == no match. size_t package_pattern_match(StringView name, StringView pattern); - - std::unique_ptr>> make_git_version_db_deserializer(); - std::unique_ptr>> make_filesystem_version_db_deserializer( - const Path& root); } diff --git a/include/vcpkg/spdx.h b/include/vcpkg/spdx.h index 480bf4374a..aeef881d41 100644 --- a/include/vcpkg/spdx.h +++ b/include/vcpkg/spdx.h @@ -14,6 +14,10 @@ namespace vcpkg { + StringView extract_first_cmake_invocation_args(StringView content, StringView command); + StringView extract_arg_from_cmake_invocation_args(StringView invocation_args, StringView target_arg); + std::string replace_cmake_var(StringView text, StringView var, StringView value); + /// Generate an SDPX 2.2.1 manifest (https://spdx.github.io/spdx-spec) /// @param action Install action to be represented by this manifest /// @param relative_paths Must contain relative paths of all files in the port directory (from the port directory) @@ -32,5 +36,5 @@ namespace vcpkg Optional read_spdx_license(StringView text, StringView origin); - Json::Object run_resource_heuristics(StringView contents, StringView portRawVersion); + Json::Object run_resource_heuristics(StringView contents, StringView version_text); } diff --git a/include/vcpkg/textrowcol.h b/include/vcpkg/textrowcol.h deleted file mode 100644 index d7e216d852..0000000000 --- a/include/vcpkg/textrowcol.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -namespace vcpkg -{ - struct TextRowCol - { - constexpr TextRowCol() noexcept = default; - constexpr TextRowCol(int row, int column) noexcept : row(row), column(column) { } - /// '0' indicates uninitialized; '1' is the first row. - int row = 0; - /// '0' indicates uninitialized; '1' is the first column. - int column = 0; - - constexpr int row_or(int def) const noexcept { return row ? row : def; } - constexpr int column_or(int def) const noexcept { return column ? column : def; } - }; -} diff --git a/include/vcpkg/tools.h b/include/vcpkg/tools.h index 80c64c1100..214254a05e 100644 --- a/include/vcpkg/tools.h +++ b/include/vcpkg/tools.h @@ -29,7 +29,6 @@ namespace vcpkg static constexpr StringLiteral NINJA = "ninja"; static constexpr StringLiteral POWERSHELL_CORE = "powershell-core"; static constexpr StringLiteral NUGET = "nuget"; - static constexpr StringLiteral ARIA2 = "aria2"; static constexpr StringLiteral NODE = "node"; static constexpr StringLiteral IFW_INSTALLER_BASE = "ifw_installerbase"; // This duplicate of CMake should only be used as a fallback to unpack @@ -60,9 +59,9 @@ namespace vcpkg ExpectedL find_system_cmake(const ReadOnlyFilesystem& fs); std::unique_ptr get_tool_cache(const Filesystem& fs, - std::shared_ptr downloader, + const AssetCachingSettings& asset_cache_settings, Path downloads, - Path xml_config, + Path config_path, Path tools, RequireExactVersions abiToolVersionHandling); } diff --git a/include/vcpkg/tools.test.h b/include/vcpkg/tools.test.h index 212d41ba65..5ed07a6f12 100644 --- a/include/vcpkg/tools.test.h +++ b/include/vcpkg/tools.test.h @@ -1,9 +1,12 @@ #pragma once #include +#include #include #include +#include +#include #include #include @@ -11,6 +14,12 @@ namespace vcpkg { + struct ToolVersion + { + std::array cooked; // e.g. 24.8 or 2.7.4 or 1.0.0 + std::string raw; // e.g. 24.08 or 2.7.4 or 1.0 + }; + struct ToolData { std::string name; @@ -29,7 +38,69 @@ namespace vcpkg Path exe_path(const Path& tools_base_path) const { return tools_base_path / tool_dir_subpath / exe_subpath; } }; - Optional parse_tool_data_from_xml(StringView XML, StringView XML_PATH, StringView tool, StringView os); - Optional> parse_tool_version_string(StringView string_version); + + enum class ToolOs + { + Windows, + Osx, + Linux, + FreeBsd, + OpenBsd, + }; + + Optional to_tool_os(StringView os) noexcept; + StringLiteral to_string_literal(ToolOs os) noexcept; + LocalizedString all_comma_separated_tool_oses(); + + struct ToolDataEntry + { + std::string tool; + ToolOs os; + Optional arch; + ToolVersion version; + std::string exeRelativePath; + std::string url; + std::string sha512; + std::string archiveName; + }; + + ExpectedL> parse_tool_data(StringView contents, StringView origin); + + const ToolDataEntry* get_raw_tool_data(const std::vector& tool_data_table, + StringView toolname, + const CPUArchitecture arch, + const ToolOs os); + + struct ToolDataFileDeserializer final : Json::IDeserializer> + { + virtual LocalizedString type_name() const override; + + virtual View valid_fields() const noexcept override; + + virtual Optional> visit_object(Json::Reader& r, + const Json::Object& obj) const override; + + static const ToolDataFileDeserializer instance; + }; + + struct ToolOsDeserializer final : Json::IDeserializer + { + virtual LocalizedString type_name() const override; + + virtual Optional visit_string(Json::Reader& r, StringView str) const override; + + static const ToolOsDeserializer instance; + }; + + struct ToolVersionDeserializer final : Json::IDeserializer + { + virtual LocalizedString type_name() const override; + + virtual Optional visit_string(Json::Reader& r, StringView str) const override; + + static const ToolVersionDeserializer instance; + }; } + +VCPKG_FORMAT_WITH_TO_STRING_LITERAL_NONMEMBER(vcpkg::ToolOs); diff --git a/include/vcpkg/vcpkgcmdarguments.h b/include/vcpkg/vcpkgcmdarguments.h index 37109d3056..40ec39181d 100644 --- a/include/vcpkg/vcpkgcmdarguments.h +++ b/include/vcpkg/vcpkgcmdarguments.h @@ -223,6 +223,7 @@ namespace vcpkg Optional builtin_ports_root_dir; Optional builtin_registry_versions_dir; Optional registries_cache_dir; + Optional tools_data_file; Optional default_visual_studio_path; @@ -297,7 +298,8 @@ namespace vcpkg f.dependency_graph = dependency_graph_enabled(); return f; } - const Optional& detected_ci_environment() const { return m_detected_ci_environment; } + const Optional& detected_ci_environment_name() const { return m_detected_ci_environment_name; } + CIKind detected_ci() const { return m_detected_ci_environment_type; } const std::string& get_command() const noexcept { return command; } @@ -332,7 +334,8 @@ namespace vcpkg std::string command; - Optional m_detected_ci_environment; + Optional m_detected_ci_environment_name; + CIKind m_detected_ci_environment_type = CIKind::None; friend LocalizedString usage_for_command(const CommandMetadata& command_metadata); CmdParser parser; diff --git a/include/vcpkg/vcpkglib.h b/include/vcpkg/vcpkglib.h index 6eeffbf4c3..4d0fc8c6ac 100644 --- a/include/vcpkg/vcpkglib.h +++ b/include/vcpkg/vcpkglib.h @@ -13,9 +13,12 @@ namespace vcpkg { + // Read the status database StatusParagraphs database_load(const ReadOnlyFilesystem& fs, const InstalledPaths& installed); + // Read the status database, and collapse update records into the current status file StatusParagraphs database_load_collapse(const Filesystem& fs, const InstalledPaths& installed); + // Adds an update record void write_update(const Filesystem& fs, const InstalledPaths& installed, const StatusParagraph& p); struct StatusParagraphAndAssociatedFiles @@ -25,9 +28,13 @@ namespace vcpkg }; std::vector get_installed_ports(const StatusParagraphs& status_db); + + // Reads the installed files from the status database. std::vector get_installed_files(const ReadOnlyFilesystem& fs, const InstalledPaths& installed, const StatusParagraphs& status_db); + // Reads the installed files from the status database, converting installed file lists to the current version if + // necessary. std::vector get_installed_files_and_upgrade(const Filesystem& fs, const InstalledPaths& installed, const StatusParagraphs& status_db); diff --git a/include/vcpkg/vcpkgpaths.h b/include/vcpkg/vcpkgpaths.h index 0639a5b8cc..c764a418dc 100644 --- a/include/vcpkg/vcpkgpaths.h +++ b/include/vcpkg/vcpkgpaths.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -21,9 +22,10 @@ #include #include +#include + #include #include -#include #include namespace vcpkg @@ -101,12 +103,12 @@ namespace vcpkg std::vector overlay_triplets; public: - std::vector overlay_ports; + OverlayPortPaths overlay_ports; std::string get_toolver_diagnostics() const; const Filesystem& get_filesystem() const; - const DownloadManager& get_download_manager() const; + const AssetCachingSettings& get_asset_cache_settings() const; const ToolCache& get_tool_cache() const; const Path& get_tool_exe(StringView tool, MessageSink& status_messages) const; const std::string& get_tool_version(StringView tool, MessageSink& status_messages) const; diff --git a/include/vcpkg/versiondeserializers.h b/include/vcpkg/versiondeserializers.h index 82a5e8d29d..c68951ed25 100644 --- a/include/vcpkg/versiondeserializers.h +++ b/include/vcpkg/versiondeserializers.h @@ -4,6 +4,7 @@ #include +#include #include #include @@ -23,7 +24,8 @@ namespace vcpkg Json::Reader& r, const Json::Object& obj); - View schemed_deserializer_fields(); +#define VCPKG_SCHEMED_DESERIALIZER_FIELDS \ + JsonIdVersion, JsonIdVersionSemver, JsonIdVersionString, JsonIdVersionDate, JsonIdPortVersion void serialize_schemed_version(Json::Object& out_obj, VersionScheme scheme, const Version& version); diff --git a/include/vcpkg/versions.h b/include/vcpkg/versions.h index 8a54cbf0bc..8fabe50428 100644 --- a/include/vcpkg/versions.h +++ b/include/vcpkg/versions.h @@ -28,8 +28,8 @@ namespace vcpkg // If the port-version can't be parsed as a nonnegative integer, returns nullopt. static Optional parse(StringView content); - friend bool operator==(const Version& left, const Version& right); - friend bool operator!=(const Version& left, const Version& right); + friend bool operator==(const Version& left, const Version& right) noexcept; + friend bool operator!=(const Version& left, const Version& right) noexcept; // Version has no operator< because without a scheme it is not necessarily semantically comparable; // VersionMapLess is provided as a less than comparison for use in std::map. @@ -70,8 +70,8 @@ namespace vcpkg SchemedVersion(VersionScheme scheme, std::string&& value, int port_version) noexcept; SchemedVersion(VersionScheme scheme, StringView value, int port_version); - friend bool operator==(const SchemedVersion& lhs, const SchemedVersion& rhs); - friend bool operator!=(const SchemedVersion& lhs, const SchemedVersion& rhs); + friend bool operator==(const SchemedVersion& lhs, const SchemedVersion& rhs) noexcept; + friend bool operator!=(const SchemedVersion& lhs, const SchemedVersion& rhs) noexcept; }; StringLiteral to_string_literal(VersionScheme scheme); diff --git a/locales/messages.cs.json b/locales/messages.cs.json index 06b1bb5d32..afdeadad0a 100644 --- a/locales/messages.cs.json +++ b/locales/messages.cs.json @@ -4,6 +4,7 @@ "ABoolean": "logická hodnota", "ABuiltinRegistry": "integrovaný registr", "AConfigurationObject": "objekt konfigurace", + "ACpuArchitecture": "architektura procesoru", "ADateVersionString": "řetězec verze data", "ADefaultFeature": "výchozí funkce", "ADemandObject": "objekt poptávky", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "uvolněný řetězec verze", "ASemanticVersionString": "řetězec sémantické verze", "ASetOfFeatures": "sada funkcí", + "ASha512": "hodnota hash SHA-512", "AString": "řetězec", "AStringOrArrayOfStrings": "řetězec nebo pole řetězců", "AStringStringDictionary": "„řetězec“: slovník „řetězců“", + "AToolDataArray": "pole metadat nástroje", + "AToolDataFile": "datový soubor nástroje", + "AToolDataOS": "datový operační systém nástroje", + "AToolDataObject": "metadata nástroje", + "AToolDataVersion": "verze dat nástroje", "AUrl": "adresa URL", "AVcpkgRepositoryCommit": "potvrzení úložiště vcpkg", "AVersionConstraint": "omezení verze", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "Vynutí detekci hostitele na Windows při získávání artefaktů", "ArtifactsSwitchX64": "Vynutí detekci hostitele na x64 při získávání artefaktů", "ArtifactsSwitchX86": "Vynutí detekci hostitele na x86 při získávání artefaktů", - "AssetCacheHit": "Přístup do mezipaměti prostředků pro {path}; staženo z: {url}", - "AssetCacheMiss": "Neúspěšné přístupy do mezipaměti prostředků; stahování z adresy {url}.", - "AssetCacheMissBlockOrigin": "Neúspěšné přístupy do mezipaměti prostředků pro {path} a x-block-origin blokuje stahování.", + "AssetCacheConsult": "Probíhá pokus o stažení {path} pomocí {url} mezipaměti prostředků.", + "AssetCacheConsultScript": "Probíhá pokus o stažení {path} pomocí skriptu mezipaměti prostředků.", + "AssetCacheHit": "Stahování bylo úspěšné! Úspěšné přístupy do mezipaměti prostředků", + "AssetCacheHitUrl": "Stahování bylo úspěšné! Přístup do mezipaměti prostředků, nepokusil se autoritativní zdrojový {url}", + "AssetCacheMiss": "Neúspěšné přístupy do mezipaměti prostředků; pokus o autoritativní zdrojový {url}", + "AssetCacheMissBlockOrigin": "nebyly nalezeny žádné přístupy do mezipaměti prostředků a bloky x-block-origin při pokusu o autoritativní zdrojový {url}", + "AssetCacheMissNoUrls": "Mezipaměť prostředků nenalezla {sha} a není známá žádná autoritativní adresa URL.", "AssetCacheProviderAcceptsNoArguments": "Neočekávané argumenty: {value} nepřijímá argumenty.", - "AssetCacheSuccesfullyStored": "Cesta {path} se úspěšně uložila na adresu {url}.", + "AssetCacheScriptBadVariable": "{value} šablony skriptu obsahuje neznámé náhradní {list}", + "AssetCacheScriptBadVariableHint": "pokud to chcete na příkazovém řádku literálu, použijte {{{{{list}}}}}", + "AssetCacheScriptCommandLine": "celý příkazový řádek skriptu byl", + "AssetCacheScriptFailed": "skript mezipaměti prostředku vrátil nenulový ukončovací kód {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "skript mezipaměti prostředku vrátil úspěch, ale výsledný soubor má neočekávanou hodnotu hash", + "AssetCacheScriptFailedToWriteFile": "skript mezipaměti prostředku vrátil úspěch, ale nevytvořil očekávaný soubor výsledků.", + "AssetCacheScriptNeedsSha": "šablona skriptu {value} vyžaduje SHA, ale žádný algoritmus SHA není známý pro pokus o stažení {url}", + "AssetCacheScriptNeedsUrl": "šablona skriptu {value} vyžaduje adresu URL, ale pro pokus o stažení {sha} není známa žádná adresa URL.", + "AssetCacheSuccesfullyStored": "Úspěšné uložení", "AssetSourcesArg": "Zdroje ukládání prostředků do mezipaměti. Viz nvcpkg help assetcaching", "AttemptingToSetBuiltInBaseline": "při pokusu o nastavení předdefinovaného směrného plánu v souboru vcpkg.json při přepsání výchozího registru v souboru vcpkg-configuration.json.\nse použije výchozí registr z vcpkg-configuration.json.", "AuthenticationMayRequireManualAction": "Nejméně jeden poskytovatel přihlašovacích údajů {vendor} požádal o ruční akci. Pokud chcete povolit interaktivitu, přidejte binární zdroj interactive.", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "Počet úvodních adresářů, které se mají odstranit ze všech cest", "CommandEnvExample2": "vcpkg env \"ninja -C \" --triplet x64-windows", "CommandFailed": "příkaz:\n{command_line}\nselhalo s následujícím výstupem:", - "CommandFailedCode": "příkaz:\n{command_line}\nselhalo s ukončovacím kódem {exit_code} a následujícím výstupem:", "CommunityTriplets": "Trojčata komunity:", "CompilerPath": "Nalezen kompilátor: {path}", - "CompressFolderFailed": "Nepovedlo se zkomprimovat složku „{path}“:", "ComputingInstallPlan": "Počítá se plán instalace…", "ConfigurationErrorRegistriesWithoutBaseline": "Konfigurace definovaná v cestě {path} je neplatná.\n\n Použití registrů vyžaduje, aby byl pro výchozí registr nastaven směrný plán nebo aby výchozí registr byl null.\n\n Další podrobnosti najdete na adrese {url}.", "ConfigurationNestedDemands": "[\"{json_field}\"] obsahuje vnořený objekt demands (vnořené demands nemají žádný účinek).", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "Nepovedlo se odvodit ID a verzi NuGet z názvu souboru: {path}", "CouldNotFindBaselineInCommit": "Nepovedlo se najít směrný plán v adrese {url} na {commit_sha} pro {package_name}.", "CouldNotFindGitTreeAtCommit": "Nepovedlo se najít strom Git pro „versions“ v úložišti {package_name} při potvrzení {commit_sha}.", - "CouldNotFindToolVersion": "V {path} se nepovedlo najít v {path}.", "CouldNotFindVersionDatabaseFile": "Nepovedlo se najít soubor databáze verzí: {path}", "CreateFailureLogsDir": "Vytváří se výstupní adresář protokolů chyb {path}.", "CreatedNuGetPackage": "Vytvořen nupkg: {path}", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "Vytváří se balíček NuGet...", "CreatingZipArchive": "Vytváří se archiv zip...", "CreationFailed": "Nepovedlo se vytvořit cestu {path}.", + "CurlFailedGeneric": "Operace curl se nezdařila s kódem chyby {exit_code}.", "CurlFailedToPut": "Nástroji curl se nepodařilo vložit soubor na adresu {url} s ukončovacím kódem {exit_code}.", "CurlFailedToPutHttp": "Nástroji curl se nepodařilo vložit soubor na adresu {url} s ukončovacím kódem {exit_code} a kódem HTTP {value}.", - "CurlResponseTruncatedRetrying": "Příkaz curl vrátil částečnou odpověď; počká se {value} milisekund a pak se to zkusí znovu.", - "CurlTimeout": "Příkaz curl nemohl provést všechny požadované operace HTTP, a to ani po vypršení časového limitu a opakovaných pokusech. Poslední příkazový řádek byl: {command_line}.", + "CurlFailedToReturnExpectedNumberOfExitCodes": "Curl nevrátil očekávaný počet ukončovacích kódů; k tomu může dojít, pokud se něco zahodí před dokončením. Curl se ukončil s {exit_code}, což je obvykle kód výsledku poslední operace, ale může to být důsledek chybového ukončení. Příkazový řádek byl {command_line} a veškerý výstup je níže:", "CurrentCommitBaseline": "Aktuální potvrzení můžete použít jako směrný plán, což je:\n„builtin-baseline“: „{commit_sha}“", "CycleDetectedDuring": "cyklus zjištěný během specifikace {spec}:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "Proměnná prostředí VCPKG_DEFAULT_BINARY_CACHE musí být adresář (byla: {path}).", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "knihovny DLL jsou tady relativní vzhledem k ${{CURRENT_PACKAGES_DIR}}", "DocumentedFieldsSuggestUpdate": "Pokud se jedná o zdokumentovaná pole, která by se měla rozpoznat, zkuste aktualizovat nástroj vcpkg.", "DownloadAvailable": "Kopie nástroje je k dispozici ke stažení a dá se využít při změně nastavení hodnoty {env_var}.", - "DownloadFailedCurl": "{url}: Nástroji curl se nepodařilo stáhnout s ukončovacím kódem {exit_code}.", - "DownloadFailedHashMismatch": "Soubor nemá očekávanou hodnotu hash:\nurl: {url}\nSoubor: {path}\nOčekávaná hodnota hash: {expected}\nSkutečná hodnota hash: {actual}", - "DownloadFailedProxySettings": "Nepodařilo se stáhnout {path}.\nPokud používáte proxy server, ujistěte se, že máte správné nastavení proxy serveru.\nMožné příčiny:\n1. Ve skutečnosti používáte proxy server HTTP, ale nastavujete proměnnou HTTPS_PROXY na https//address:port.\nTo není správné, protože předpona „https://“ označuje, že proxy server je typu HTTPS, zatímco váš proxy server (v2ray, shadowsocksr atd...) je proxy server HTTP.\nZkuste místo toho nastavit „http://address:port“ na HTTP_PROXY i HTTPS_PROXY.\n2. Pokud používáte Windows, bude vcpkg automaticky používat nastavení proxy serveru Windows IE nastavená vaším proxy softwarem. Viz {url}\nHodnota nastavená proxy serverem může být chybná nebo může mít stejný problém s předponou „https://“.\n3. Vzdálený server vašeho proxy serveru je mimo provoz.\nPokud jste se pokusili odkaz stáhnout přímo a domníváte se, že se nejedná o dočasné selhání serveru pro stahování, odešlete problém na adrese https://github.com/Microsoft/vcpkg/issues\na ohlaste selhání serveru pro stahování.", - "DownloadFailedRetrying": "Stahování se nezdařilo – opakuje se pokus za {value}ms.", + "DownloadFailedHashMismatch": "stáhnout z {url} měl neočekávanou hodnotu hash", + "DownloadFailedHashMismatchActualHash": "Skutečnost: {sha}", + "DownloadFailedHashMismatchExpectedHash": "Očekáváno: {sha}", + "DownloadFailedHashMismatchZero": "stahování se nezdařilo, protože očekávaný algoritmus SHA512 měl všechny nuly. Změňte očekávaný algoritmus SHA512 na: {sha}", + "DownloadFailedProxySettings": "Pokud používáte proxy server, ujistěte se, že je nastavení proxy serveru správné.\nMožné příčiny:\n1. Ve skutečnosti používáte proxy server HTTP, ale nastavujete proměnnou HTTPS_PROXY na https//address:port.\nTo není správné, protože předpona „https://“ označuje, že proxy server je typu HTTPS, zatímco váš proxy server (v2ray, shadowsocksr atd...) je proxy server HTTP.\nZkuste místo toho nastavit „http://address:port“ u HTTP_PROXY i HTTPS_PROXY.\n2. Pokud používáte Windows, bude vcpkg automaticky používat nastavení proxy serveru Windows IE nastavená vaším proxy softwarem. Viz: https://github.com/microsoft/vcpkg-tool/pull/77\nHodnota nastavená proxy serverem může být chybná nebo může mít stejný problém s předponou „https://“.\n3. Vzdálený server vašeho proxy serveru je mimo provoz.\nPokud se domníváte, že se nejedná o dočasné selhání stahovacího serveru a že je třeba změnit vcpkg tak, aby stahoval tento soubor z jiného umístění, nahlaste prosím problém na adrese https://github.com/Microsoft/vcpkg/issues", + "DownloadFailedRetrying": "Stažení z adresy {url} se nezdařilo – pokus se zopakuje za {value} ms.", "DownloadFailedStatusCode": "{url}: neúspěšné: stavový kód {value}", + "DownloadOrUrl": "nebo {url}", "DownloadRootsDir": "Stáhne adresář (výchozí: {env_var})", - "DownloadSuccesful": "Úspěšné stažení z cesty {path}.", + "DownloadSuccesful": "Úspěšné stažení z cesty {path}", + "DownloadSuccesfulUploading": "{path} se úspěšně stáhlo, ukládání do {url}", + "DownloadTryingAuthoritativeSource": "Probíhá pokus o {url}", "DownloadWinHttpError": "{url}: {system_api} selhalo s ukončovacím kódem {exit_code}.", "DownloadedSources": "Stažené zdroje pro {spec}", + "DownloadingAssetShaToFile": "Stahování položky mezipaměti prostředků {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "požadované stažení položky mezipaměti prostředků {sha} -> {path}, ale nejsou nakonfigurované žádné mezipaměti prostředků.", + "DownloadingFile": "Stahování {path}", + "DownloadingFileFirstAuthoritativeSource": "Stahuje se {path}, zkouší se to {url}.", "DownloadingPortableToolVersionX": "Nenašla se vhodná verze {tool_name} (požadovaná verze je {version}).", - "DownloadingUrl": "Stahuje se adresa {url}.", + "DownloadingUrlToFile": "Stahování {url} -> {path}", "DownloadingVcpkgStandaloneBundle": "Stahuje se samostatná sada {version}.", "DownloadingVcpkgStandaloneBundleLatest": "Stahuje se nejnovější samostatná sada.", + "DuplicateDependencyOverride": "{package_name} už má přepsání.", "DuplicatePackagePattern": "{package_name} balíčku je duplicitní.", "DuplicatePackagePatternFirstOcurrence": "První deklarované v:", "DuplicatePackagePatternIgnoredLocations": "Následující změny deklarace budou ignorovány:", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "Možnost --{option} se klasickém režimu podporuje a nenašel se žádný manifest.", "ErrorInvalidExtractOption": "Parametr --{option} musí být nastaven na nezáporné celé číslo nebo hodnotu „AUTO“.", "ErrorInvalidManifestModeOption": "Možnost --{option} se v režimu manifestu nepodporuje.", + "ErrorManifestMustDifferFromOverlay": "Adresář manifestu ({path}) nemůže být stejný jako adresář nakonfigurovaný v překryvných portech.", + "ErrorManifestMustDifferFromOverlayDot": "Adresář manifestu nemůže být stejný jako adresář nakonfigurovaný v překryvných portech, takže hodnoty overlay-ports nemůžou být ..", "ErrorMissingVcpkgRoot": "Nepovedlo se zjistit vcpkg-root. Pokud se pokoušíte použít kopii vcpkg, kterou jste vytvořili, musíte definovat proměnnou prostředí VCPKG_ROOT tak, aby odkazovala na klonovanou kopii https://github.com/Microsoft/vcpkg.", "ErrorNoVSInstance": "v trojitém {triplet}: Nepovedlo se najít platnou instanci Visual Studio.", "ErrorNoVSInstanceAt": "v „{path}“", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "Nepovedlo se parsovat {path}, očekávalo se pole „versions“.", "FailedToParseSerializedBinParagraph": "[kontrola správnosti] Nepovedlo se parsovat serializovaný binární odstavec.\nOtevřete prosím problém na https://github.com/microsoft/vcpkg s následujícím výstupem:\n{error_msg}\nSerializovaný binární odstavec:", "FailedToParseVersionFile": "Nepovedlo se parsovat soubor verze: {path}", - "FailedToParseVersionXML": "Nepovedlo se parsovat verzi nástroje {tool_name}. Řetězec verze byl: {version}", "FailedToRunToolToDetermineVersion": "Nepodařilo se spustit {path} s cílem zjistit verzi {tool_name}.", "FailedToStoreBackToMirror": "Nepovedlo se uložit {path} na adresu {url}.", "FailedToStoreBinaryCache": "Nepovedlo se uložit binární mezipaměť {path}.", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "Načítá se informace registru z adresy {url} ({value})...", "FieldKindDidNotHaveExpectedValue": "„druh“ neměl očekávanou hodnotu: (očekávala se jedna z těchto hodnot: {expected}; nalezená hodnota: {actual})", "FileIsNotExecutable": "zdá se, že tento soubor není spustitelný.", - "FileNotFound": "{path}: Soubor se nenašel.", + "FileNotFound": "soubor nenalezen", "FileReadFailed": "Čtení {count} bajtů z cesty {path} na posunu {byte_offset} se nezdařilo.", "FileSeekFailed": "Nepodařilo se vyhledat umístění pro {byte_offset} v cestě {path}.", "FilesContainAbsolutePath1": "V nainstalovaném balíčku by neměly být žádné absolutní cesty, jako jsou následující. Pokud chcete tuto zprávu potlačit, přidejte set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "neznámý stav souboru: {value}", "GitUnexpectedCommandOutputCmd": "Git vytvořil neočekávaný výstup při spuštění {command_line}.", "GraphCycleDetected": "V grafu byl zjištěn cyklus v {package_name}:", - "HashFileFailureToRead": "Nepodařilo se přečíst soubor {path} pro hashování: ", "HashPortManyFiles": "{package_name} obsahuje tento počet souborů: {count}. Použití algoritmů hash u tohoto obsahu při určování hodnoty hash ABI pro ukládání binárních dat do mezipaměti může trvat dlouho. Zvažte snížení počtu souborů. Častou příčinou je náhodné rezervování zdrojových nebo buildovacích souborů do adresáře portu.", "HeaderOnlyUsage": "{package_name} je jenom hlavička a dá se použít z CMake přes:", "HelpAssetCaching": "**Experimentální funkce: může se změnit nebo odebrat bez upozornění.**\n\nVcpkg může ukládat stažené prostředky do mezipaměti pomocí zrcadlení a zajistit tak plynulý provoz i v případě, že se původní zdroj změní nebo zmizí.\n\nUkládání prostředků do mezipaměti je možné nakonfigurovat buď nastavením proměnné prostředí X_VCPKG_ASSET_SOURCES na seznam zdrojů oddělený středníky, nebo předáním posloupnosti možností příkazového řádku --x-asset-sources=. Zdroje příkazového řádku se interpretují po zdrojích prostředí. Čárky, středníky a obrácené čárky je možné uvozovat pomocí obrácené čárky (`).\n\nVolitelný parametr pro určité řetězce určuje, jak se k nim bude přistupovat. Je možné ho zadat jako read, write nebo readwrite s výchozí hodnotou read.\n\nPlatné zdroje:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "Selže, pokud nejsou k dispozici binární soubory uložené v mezipaměti", "HelpTxtOptOnlyDownloads": "Pokusí se co nejlépe stáhnout zdroje bez sestavení", "HelpTxtOptRecurse": "Povoluje odebrání balíčků v rámci instalace", - "HelpTxtOptUseAria2": "Používá aria2 k provádění úloh stahování", "HelpTxtOptUseHeadVersion": "Nainstaluje knihovny na příkazový řádek pomocí nejnovějších zdrojů pro odesílání dat (klasický režim)", "HelpTxtOptWritePkgConfig": "Zapíše soubor ve formátu NuGet packages.config pro použití s externí binární mezipamětí. Další informace najdete v vcpkg help binarycaching", "HelpUpdateBaseline": "Nejlepší způsob, jak udržovat knihovny v aktualizovaném stavu, je aktualizovat základní referenční informace. Tím se zajistí, že se aktualizují všechny balíčky, včetně přenositelných. Pokud ale potřebujete balíček aktualizovat nezávisle, můžete použít omezení version>=.", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "Integrace nebyla použita pro Visual Studio 2015.", "InternalCICommand": "vcpkg ci je interní příkaz, který se změní nekompatibilně nebo se kdykoli odebere.", "InternalErrorMessageContact": "Otevřete prosím problém na adrese https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug, kde uveďte podrobný postup, jak problém vyvolat.", - "InvalidArchitecture": "neplatná architektura: {value}", + "InvalidArchitectureValue": "Neplatná architektura: {value}. Očekávala se jedna z těchto hodnot: {expected}", "InvalidArgument": "neplatný argument", "InvalidArgumentRequiresAbsolutePath": "Neplatný argument: argumenty cesty binární konfigurace {binary_source} pro binární konfigurační řetězce musí být absolutní.", "InvalidArgumentRequiresBaseUrl": "Neplatný argument: binární konfigurace {binary_source} vyžaduje jako první argument základní adresu URL {base_url}.", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "neplatný logický výraz, použijte | místo operátoru or", "InvalidOptionForRemove": "Příkaz remove přijímá buď knihovny, nebo --outdated.", "InvalidPortVersonName": "Našel se neplatný název souboru verze portu: {path}.", + "InvalidSha512": "neplatná hodnota hash SHA-512: {sha}\nHodnota hash SHA-512 musí mít délku 128 znaků a obsahovat pouze šestnáctkové číslice.", "InvalidSharpInVersion": "Neplatný znak # v textu verze", "InvalidSharpInVersionDidYouMean": "Neplatný znak # v textu verze. Měli jste na mysli „port-version“: {value}?", "InvalidString": "Do value::string(std::string) se předala neplatná hodnota utf8.", + "InvalidToolOSValue": "Neplatný operační systém nástroje: {value}. Očekávala se jedna z těchto hodnot: {expected}", + "InvalidToolVersion": "Neplatná verze nástroje; Očekával se řetězec obsahující podřetězec mezi 1 a 3 čísly oddělenými tečkami.", "InvalidTriplet": "Neplatný triplet: {triplet}", "InvalidUri": "Nejde parsovat identifikátor URI: {value}", "InvalidValueHashAdditionalFiles": "Proměnná VCPKG_HASH_ADDITIONAL_FILES obsahuje neplatnou cestu k souboru: {path}. Hodnota musí být absolutní cesta k existujícímu souboru.", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "Serializovaný binární odstavec se lišil od původního binárního odstavce. Otevřete prosím problém na https://github.com/microsoft/vcpkg s následujícím výstupem:", "MismatchedFiles": "Soubor, který se má uložit, neodpovídá hodnotě hash.", "MismatchedManifestAfterReserialize": "Serializovaný manifest se lišil od původního manifestu. Otevřete problém na https://github.com/microsoft/vcpkg s následujícím výstupem:", - "MismatchedNames": "Názvy se neshodovaly: {package_name}! = {actual}", + "MismatchedNames": "název portu deklarovaný v souboru metadat neodpovídal adresáři. Očekával se název portu {package_name}, ale soubor deklaruje {actual}.", "MismatchedSpec": "Neshoda specifikace v portu {path}: očekávalo se {expected}, našlo {actual}", "MismatchedType": "{json_field}: neshodný typ: očekáván typ {json_type}", "Missing7zHeader": "Nepodařilo se najít hlavičku 7z.", "MissingAndroidEnv": "chybí proměnná prostředí ANDROID_NDK_HOME", "MissingAndroidHomeDir": "ANDROID_NDK_HOME adresář neexistuje: {path}", "MissingArgFormatManifest": "format-manifest se předal --convert-control bez --all.\nToto nic nedělá: řídicí soubory, které se předají explicitně, se automaticky převedou.", - "MissingAssetBlockOrigin": "Chybí cesta {path} a x-block-origin blokuje stahování.", "MissingClosingParen": "chybí uzavírací závorka )", "MissingDependency": "Balíček {spec} je nainstalovaný, ale závislost {package_name} není.", "MissingExtension": "Chybí přípona {extension}.", @@ -814,7 +841,6 @@ "NoInstalledPackages": "Nejsou nainstalované žádné balíčky. Měli jste na mysli „hledat“?", "NoOutdatedPackages": "Neexistují žádné zastaralé balíčky.", "NoRegistryForPort": "pro port {package_name} není nakonfigurovaný žádný registr", - "NoUrlsAndHashSpecified": "Nejsou zadané žádné adresy URL pro stažení SHA: {sha}", "NoUrlsAndNoHashSpecified": "Nebyly zadány žádné adresy URL a nebyla zadána žádná hodnota hash.", "NonExactlyArgs": "příkaz {command_name} vyžaduje přesně tento počet argumentů: {expected}, ale zadal se tento počet argumentů: {actual}", "NonOneRemainingArgs": "příkaz {command_name} vyžaduje přesně jeden argument", @@ -834,8 +860,8 @@ "Options": "Možnosti", "OriginalBinParagraphHeader": "\nPůvodní binární odstavec", "OtherCommandsHeader": "Ostatní", - "OverlayPatchDir": "Překryvná cesta „{path}“ musí existovat a musí to být adresář.", - "OverlayPortsDirectoriesHelp": "Adresáře překryvných portů (také: {env_var})", + "OverlayPatchDir": "Překryvná cesta \"{path}\" musí být existující adresář.", + "OverlayPortsHelp": "Adresáře překryvného portu nebo adresáře obsahující adresáře překryvného portu (také: {env_var})", "OverlayTripletDirectoriesHelp": "Adresáře překryvných tripletů (také: {env_var})", "OverlayTriplets": "Překryvné trojčata z {path}:", "OverwritingFile": "Soubor {path} už existuje a přepíše se.", @@ -927,6 +953,7 @@ "PortsUpdated": "Aktualizovaly se tyto porty (celkem {count}):", "PrebuiltPackages": "Existují balíčky, které nebyly sestaveny. Pokud je chcete sestavit, spusťte:", "PreviousIntegrationFileRemains": "Předchozí integrační soubor nebyl odebrán.", + "ProgramPathReturnedNonzeroExitCode": "selhalo s ukončovacím kódem {exit_code}", "ProgramReturnedNonzeroExitCode": "Nástroj {tool_name} selhal s ukončovacím kódem {exit_code}.", "ProvideExportType": "Vyžaduje se aspoň jedna z následujících možností: --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "Nepodařilo se nasdílet změny {vendor} do cesty {path}. Pro další informace použijte --debug.", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "Cílová trojčata. Viz vcpkg help triplet (výchozí: {env_var})", "StartCodeUnitInContinue": "našla se jednotka počátečního kódu na pozici pro pokračování", "StoreOptionMissingSha": "Možnost --store je bez sha512 neplatná.", - "StoredBinariesToDestinations": "Uložené binární soubory v(e) {count} cílech v {elapsed}.", + "SubmittingBinaryCacheBackground": "Zahajuje se odesílání {spec} do {count} binárních mezipamětí na pozadí.", + "SubmittingBinaryCacheComplete": "Odeslání {spec} do {count} binárních mezipamětí v {elapsed} bylo dokončeno.", "SuccessfulyExported": "{package_name} se exportoval do cesty {path}.", "SuggestGitPull": "Výsledek může být zastaralý. Nejnovější výsledky získáte spuštěním příkazu git pull.", "SuggestStartingBashShell": "Tato změna se projeví až po spuštění nového prostředí Bash.", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "nepodařilo se nainstalovat soubor systémových cílů do {path}", "ToRemovePackages": "Pokud chcete odebrat jenom zastaralé balíčky, spusťte\n{command_name} odeberte --outdated.", "ToUpdatePackages": "Pokud chcete aktualizovat tyto balíčky a všechny závislosti, spusťte\n{command_name} upgrade.", + "ToolDataFileSchemaVersionNotSupported": "verze schématu dokumentu {version} není podporována touto verzí vcpkg.", "ToolFetchFailed": "Nepovedlo se načíst {tool_name}.", + "ToolHashMismatch": "{tool_name} se zdá být již stažen, ale má nesprávnou hodnotu hash. Očekával se {expected}, ale byl {actual}", "ToolInWin10": "Tento nástroj je součástí sady Windows 10 nebo novější.", "ToolOfVersionXNotFound": "Nebyla nalezena vhodná verze {tool_name} (požadovaná verze v{version}) a nelze automaticky stáhnout přenosnou verzi. Nainstalujte prosím novější verzi {tool_name}.", "TotalInstallTime": "Celková doba instalace: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "aktualizovala se '{url}' registru: směrný plán '{old_value}' -> '{new_value}'", "UpgradeInManifest": "Upgrade upgraduje instalaci klasického režimu, a proto nepodporuje režim manifestu. Zvažte aktualizaci závislostí aktualizací směrného plánu na aktuální hodnotu pomocí vcpkg x-update-baseline a spuštěním instalace vcpkg.", "UpgradeRunWithNoDryRun": "Pokud jste si jistí, že chcete výše uvedené balíčky znovu sestavit, spusťte tento příkaz s možností --no-dry-run.", - "UploadingBinariesToVendor": "Binární soubory pro {spec} se nahrávají do zdroje {vendor} {path}.", + "UploadingBinariesToVendor": "Nahrávají se binární soubory pro {spec} do {vendor} z {path}.", "UsageInstallInstructions": "pomocí následujícího příkazu CMake můžete nainstalovat soubor usage", "UsageTextHere": "tady je soubor usage", "UseEnvVar": "-- Používání {env_var} v proměnných prostředí.", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "{package_name} má přiřazený port {actual}, ale místní port je {expected}", "VersionBuiltinPortTreeEntryMissing": "žádná položka databáze verzí pro {package_name} v {expected}; pomocí verze stromové struktury rezervovaných portů ({actual}).", "VersionCommandHeader": "Verze {version} programu pro správu balíčků vcpkg\n\nInformace o licenci najdete v LICENSE.txt.", - "VersionConflictXML": "Byla očekávána verze {path}: [{expected_version}], ale byla [{actual_version}]. Spusťte prosím znovu bootstrap-vcpkg.", "VersionConstraintNotInDatabase1": "omezení \"version>=\" pro {package_name} uvádí verzi {version}, která v databázi verzí neexistuje. Všechny verze musí existovat v databázi verzí, aby je vcpkg mohl interpretovat.", "VersionConstraintNotInDatabase2": "zvažte odebrání omezení verze nebo zvolte zde deklarovanou hodnotu", "VersionConstraintOk": "všechna omezení verze jsou konzistentní s databází verzí", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "Za # musí v textu verze následovat verze portu (nezáporné celé číslo)", "VersionSpecMismatch": "Nepodařilo se načíst port, protože verze jsou nekonzistentní. Soubor „{path}“ obsahuje verzi {actual_version}, ale databáze verzí uvádí, že by to měla být {expected_version}.", "VersionVerifiedOK": "{version_spec} je správně ve verzi databáze ({git_tree_sha}).", + "WaitUntilPackagesUploaded": "Čeká se na {count} zbývající odeslání binární mezipaměti...", "WaitingForChildrenToExit": "Čeká se na ukončení podřízených procesů…", "WaitingToTakeFilesystemLock": "čeká se na uzamčení systému souborů na {path}…", "WarnOnParseConfig": "V konfiguraci {path} se našla následující upozornění:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "při načítání {version_spec}", "WhileLookingForSpec": "při hledání {spec}:", "WhileParsingVersionsForPort": "při parsování verzí pro {package_name} z {path}", + "WhileRunningAssetCacheScriptCommandLine": "při spuštění příkazového řádku skriptu mezipaměti prostředků", "WhileValidatingVersion": "při ověřování verze: {version}", "WindowsOnlyCommand": "Tento příkaz podporuje jenom Windows.", "WroteNuGetPkgConfInfo": "Do {path} se zapsaly informace o konfiguraci balíčku NuGet", diff --git a/locales/messages.de.json b/locales/messages.de.json index 497e7e52cd..9a5a577820 100644 --- a/locales/messages.de.json +++ b/locales/messages.de.json @@ -4,6 +4,7 @@ "ABoolean": "ein boolescher Wert", "ABuiltinRegistry": "eine integrierte Registrierung", "AConfigurationObject": "ein Konfigurationsobjekt", + "ACpuArchitecture": "eine CPU-Architektur", "ADateVersionString": "eine Datumsversionszeichenfolge", "ADefaultFeature": "ein Standardfeature", "ADemandObject": "ein Anforderungsobjekt", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "eine gelockerte Versionszeichenfolge", "ASemanticVersionString": "eine semantische Versionszeichenfolge", "ASetOfFeatures": "eine Reihe von Features", + "ASha512": "ein SHA-512-Hash", "AString": "eine Zeichenfolge", "AStringOrArrayOfStrings": "eine Zeichenfolge oder ein Array von Zeichenfolgen", "AStringStringDictionary": "ein \"string\": \"string\"-Wörterbuch", + "AToolDataArray": "ein Array von Toolmetadaten", + "AToolDataFile": "eine Tooldatendatei", + "AToolDataOS": "Ein Tooldatenbetriebssystem", + "AToolDataObject": "Toolmetadaten", + "AToolDataVersion": "eine Tooldatenversion", "AUrl": "eine URL", "AVcpkgRepositoryCommit": "ein vcpkg-Repositorycommit", "AVersionConstraint": "eine Versionseinschränkung", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "Erzwingt die Hosterkennung auf Windows beim Abrufen von Artefakten.", "ArtifactsSwitchX64": "Erzwingt die Hosterkennung auf x64 beim Abrufen von Artefakten.", "ArtifactsSwitchX86": "Erzwingt die Hosterkennung auf x86 beim Abrufen von Artefakten.", - "AssetCacheHit": "Ressourcencachetreffer für {path}; heruntergeladen von: {url}", - "AssetCacheMiss": "Ressourcencachefehler; Download von {url}", - "AssetCacheMissBlockOrigin": "Ressourcencachefehler für {path} und Downloads werden durch x-block-origin blockiert.", + "AssetCacheConsult": "Es wird versucht, {path} mithilfe der {url} des Ressourcencaches herunterzuladen.", + "AssetCacheConsultScript": "Es wird versucht, {path} mithilfe des Ressourcencacheskripts herunterzuladen.", + "AssetCacheHit": "Download erfolgreich! Ressourcencachetreffer.", + "AssetCacheHitUrl": "Download erfolgreich! Ressourcencachetreffer, autoritative Quelle {url} nicht versucht", + "AssetCacheMiss": "Ressourcencachefehler; Autoritative Quell-{url} wird versucht", + "AssetCacheMissBlockOrigin": "es gab keine Ressourcencachetreffer, und x-block-origin-Blöcke versuchen, die autoritative Quelle {url}", + "AssetCacheMissNoUrls": "Der Ressourcencache hat die Suche nach {sha} verpasst, und es ist keine autoritative URL bekannt.", "AssetCacheProviderAcceptsNoArguments": "Unerwartete Argumente: \"{value}\" akzeptiert keine Argumente.", - "AssetCacheSuccesfullyStored": "Der {path} wurden erfolgreich in {url} gespeichert.", + "AssetCacheScriptBadVariable": "Die Skriptvorlage {value} enthält unbekannte Ersetzungs-{list}", + "AssetCacheScriptBadVariableHint": "verwenden Sie {{{{{list}}}}, wenn Sie dies in der Literalbefehlszeile wünschen.", + "AssetCacheScriptCommandLine": "die vollständige Skriptbefehlszeile", + "AssetCacheScriptFailed": "Das Ressourcencacheskript hat einen Exitcode zurückgegeben, der nicht null ist {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "Das Ressourcencacheskript hat erfolgreich zurückgegeben, aber die resultierende Datei weist einen unerwarteten Hash auf.", + "AssetCacheScriptFailedToWriteFile": "Das Ressourcencacheskript hat erfolgreich zurückgegeben, aber keine erwartete Ergebnisdatei erstellt.", + "AssetCacheScriptNeedsSha": "Die Skriptvorlage {value} erfordert sha, es ist jedoch kein SHA für den Downloadversuch von {url} bekannt.", + "AssetCacheScriptNeedsUrl": "Die Skriptvorlage {value} erfordert eine URL, es ist jedoch keine URL für den Downloadversuch von {sha} bekannt.", + "AssetCacheSuccesfullyStored": "Store erfolgreich", "AssetSourcesArg": "Objekt-Cachequellen. Siehe „vcpkg-Hilfe zum Objekt-Zwischenspeichern“", "AttemptingToSetBuiltInBaseline": "Es wird versucht, die integrierte Baseline in \"vcpkg.json\" festzulegen, während die Standardregistrierung in \"vcpkg-configuration.json\" überschrieben wird.\ndie Standardregistrierung aus \"vcpkg-configuration.json\" wird verwendet.", "AuthenticationMayRequireManualAction": "Mindestens ein {vendor}-Anmeldeinformationsanbieter hat eine manuelle Aktion angefordert. Fügen Sie die binäre Quelle \"interactive\" hinzu, um Interaktivität zuzulassen.", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "Die Anzahl der führenden Verzeichnisse, die aus allen Pfaden entfernt werden sollen.", "CommandEnvExample2": "vcpkg env „ninja -C “ --triplet x64-windows", "CommandFailed": "Befehl:\n{command_line}\nFehler bei der folgenden Ausgabe:", - "CommandFailedCode": "Befehl:\n{command_line}\nFehler mit Exitcode {exit_code} und der folgenden Ausgabe:", "CommunityTriplets": "Community-Triplets:", "CompilerPath": "Compiler gefunden: {path}", - "CompressFolderFailed": "Fehler beim Komprimieren des Ordners \"{path}\":", "ComputingInstallPlan": "Installationsplan wird berechnet...", "ConfigurationErrorRegistriesWithoutBaseline": "Die in {path} definierte Konfiguration ist ungültig.\n\nDie Verwendung von Registrierungen erfordert, dass eine Baseline für die Standardregistrierung festgelegt ist, oder dass die Standardregistrierung NULL ist.\n\nWeitere Informationen finden Sie unter {url}.", "ConfigurationNestedDemands": "[\"{json_field}\"] enthält ein geschachteltes \"demands\"-Objekt (geschachtelte \"Anforderungen\" haben keine Auswirkungen)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "Die NuGet-ID und die Version konnten nicht aus dem Dateinamen abgeleitet werden: {path}", "CouldNotFindBaselineInCommit": "Die Baseline wurde in {url} unter {commit_sha} für {package_name} nicht gefunden.", "CouldNotFindGitTreeAtCommit": "Die Git-Struktur für \"Versionen\" wurde im Repository \"{package_name}\" beim Commit \"{commit_sha}\" nicht gefunden.", - "CouldNotFindToolVersion": " in {path} nicht gefunden", "CouldNotFindVersionDatabaseFile": "Die Versionsdatenbankdatei wurde nicht gefunden: {path}", "CreateFailureLogsDir": "Ausgabeverzeichnis für Fehlerprotokolle wird erstellt: {path}.", "CreatedNuGetPackage": "Nupkg wurde erstellt: {path}", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "NuGet-Paket wird erstellt...", "CreatingZipArchive": "ZIP-Archiv wird erstellt...", "CreationFailed": "Fehler beim Erstellen von {path}.", + "CurlFailedGeneric": "Fehler beim curl-Vorgang. Fehlercode: {exit_code}.", "CurlFailedToPut": "CURL konnte die Datei nicht unter {url} mit Exitcode {exit_code} ablegen.", "CurlFailedToPutHttp": "CURL konnte die Datei nicht unter {url} mit dem Exitcode {exit_code} und dem HTTP-Code {value} ablegen.", - "CurlResponseTruncatedRetrying": "curl hat eine partielle Antwort zurückgegeben; warten Sie {value} Millisekunden, und wiederholen Sie den Vorgang.", - "CurlTimeout": "Curl konnte nicht alle angeforderten HTTP-Vorgänge ausführen, auch nach Timeout und Wiederholungen. Letzte Befehlszeile: {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "curl konnte die erwartete Anzahl von Exitcodes nicht zurückgeben. dies kann vorkommen, wenn etwas beendet wird, bevor es abgeschlossen ist. curl wurde mit {exit_code} beendet. Dies ist normalerweise der Ergebniscode für den letzten Vorgang, kann aber das Ergebnis eines Absturzes sein. Die Befehlszeile wurde {command_line}, und die gesamte Ausgabe ist unten:", "CurrentCommitBaseline": "Sie können den aktuellen Commit als Baseline verwenden, d. h.:\n \"builtin-baseline\": \"{commit_sha}\"", "CycleDetectedDuring": "Zyklus während {spec} erkannt:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "Die Umgebungsvariable VCPKG_DEFAULT_BINARY_CACHE muss ein Verzeichnis sein (war: {path}).", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "die DLLs sind hier relativ zu ${{CURRENT_PACKAGES_DIR}}", "DocumentedFieldsSuggestUpdate": "Wenn es sich um dokumentierte Felder handelt, die erkannt werden sollen, aktualisieren Sie das vcpkg-Tool.", "DownloadAvailable": "Eine herunterladbare Kopie dieses Tools ist verfügbar und kann verwendet werden, indem {env_var} zurückgesetzt wird.", - "DownloadFailedCurl": "{url}: CURL konnte nicht heruntergeladen werden. Exitcode: {exit_code}", - "DownloadFailedHashMismatch": "Die Datei weist nicht den erwarteten Hash auf:\nURL: {url}\nDatei: {path}\nErwarteter Hash: {expected}\nTatsächlicher Hash: {actual}", - "DownloadFailedProxySettings": "Fehler beim Herunterladen von {path}.\nWenn Sie einen Proxy verwenden, stellen Sie sicher, dass Ihre Proxyeinstellungen korrekt sind.\nMögliche Ursachen sind:\n1. Sie verwenden tatsächlich einen HTTP-Proxy, legen HTTPS_PROXY Variable jedoch auf \"https://address:port\" fest.\nDies ist nicht korrekt, weil das Präfix \"https://\" den Anspruch auf einen HTTPS-Proxy hat, während Ihr Proxy (v2ray, shadowsocksr usw.) ein HTTP-Proxy ist.\nVersuchen Sie stattdessen, \"http://address:port\" sowohl auf HTTP_PROXY als auch auf HTTPS_PROXY festzulegen.\n2. Wenn Sie Windows verwenden, verwendet vcpkg automatisch die von Ihrer Proxysoftware festgelegten Windows IE-Proxyeinstellungen. Siehe {url}\nDer von Ihrem Proxy festgelegte Wert ist möglicherweise falsch oder weist dasselbe \"https://\"-Präfixproblem auf.\n3. Der Remoteserver Ihres Proxys ist außer Dienst.\nWenn Sie versucht haben, den Link direkt herunterzuladen, und der Meinung sind, dass es sich nicht um einen temporären Fehler des Downloadserver handelt, reichen Sie ein Problem unter https://github.com/Microsoft/vcpkg/issues ein,\num diesen Upstream-Downloadserverfehler zu melden.", - "DownloadFailedRetrying": "Fehler beim Herunterladen. Der Vorgang wird nach {value} ms wiederholt.", + "DownloadFailedHashMismatch": "Der Download von {url} wies einen unerwarteten Hash auf.", + "DownloadFailedHashMismatchActualHash": "Tatsächlich : {sha}", + "DownloadFailedHashMismatchExpectedHash": "Erwartet: {sha}", + "DownloadFailedHashMismatchZero": "Fehler beim Download, weil sha512 null war. Ändern Sie das erwartete SHA512 in: {sha}", + "DownloadFailedProxySettings": "Wenn Sie einen Proxy verwenden, stellen Sie sicher, dass Ihre Proxyeinstellungen korrekt sind.\nMögliche Ursachen sind:\n1. Sie verwenden tatsächlich einen HTTP-Proxy, legen die „HTTPS_PROXY“-Variable jedoch auf „https://address:port“ fest.\nDies ist nicht korrekt, weil das Präfix „https://“ den Anspruch auf einen HTTPS-Proxy hat, während Ihr Proxy (v2ray, shadowsocksr usw.) ein HTTP-Proxy ist.\nVersuchen Sie stattdessen, „http://address:port“ sowohl auf HTTP_PROXY als auch auf HTTPS_PROXY festzulegen.\n2. Wenn Sie Windows verwenden, verwendet vcpkg automatisch die von Ihrer Proxysoftware festgelegten Windows IE-Proxyeinstellungen. Siehe: https://github.com/microsoft/vcpkg-tool/pull/77\nDer von Ihrem Proxy festgelegte Wert ist möglicherweise falsch oder weist dasselbe „https://“-Präfixproblem auf.\n3. Der Remoteserver Ihres Proxys ist außer Betrieb.\nWenn Sie der Meinung sind, dass es sich nicht um einen temporären Downloadserverfehler handelt und vcpkg geändert werden muss, um diese Datei von einem anderen Speicherort herunterzuladen, melden Sie ein Problem unter „https://github.com/Microsoft/vcpkg/issues“", + "DownloadFailedRetrying": "Fehler beim Herunterladen von {url}. Der Versuch wird nach {value} Min. wiederholt.", "DownloadFailedStatusCode": "{url}: Fehler: Statuscode {value}", + "DownloadOrUrl": "oder {url}", "DownloadRootsDir": "Downloadverzeichnis (Standard: {env_var})", - "DownloadSuccesful": "{path} erfolgreich heruntergeladenen.", - "DownloadWinHttpError": "{url}: Fehler bei {system_api} mit Exitcode {exit_code}", + "DownloadSuccesful": "{path} wurde erfolgreich heruntergeladen.", + "DownloadSuccesfulUploading": "Die {path} wurde erfolgreich heruntergeladen und in {url} gespeichert.", + "DownloadTryingAuthoritativeSource": "Es wird versucht, {url}", + "DownloadWinHttpError": "{url}: Fehler bei {system_api}. Exitcode: {exit_code}.", "DownloadedSources": "Heruntergeladene Quellen für {spec}", + "DownloadingAssetShaToFile": "Der Ressourcencacheeintrag {sha} -> {path} wird heruntergeladen.", + "DownloadingAssetShaWithoutAssetCache": "hat den Download des Ressourcencacheeintrags {sha} -> {path} angefordert, es sind jedoch keine Ressourcencaches konfiguriert.", + "DownloadingFile": "{path} wird heruntergeladen", + "DownloadingFileFirstAuthoritativeSource": "{path} wird heruntergeladen, {url} wird versucht.", "DownloadingPortableToolVersionX": "Eine geeignete Version von {tool_name} wurde nicht gefunden (v{version} erforderlich).", - "DownloadingUrl": "{url} wird herunterladen", + "DownloadingUrlToFile": "{url} -> {path} wird heruntergeladen", "DownloadingVcpkgStandaloneBundle": "Das eigenständige Paket \"{version}\" wird heruntergeladen.", "DownloadingVcpkgStandaloneBundleLatest": "Das neueste eigenständige Paket wird heruntergeladen.", + "DuplicateDependencyOverride": "{package_name} hat bereits eine Außerkraftsetzung.", "DuplicatePackagePattern": "Paket „{package_name}“ ist dupliziert.", "DuplicatePackagePatternFirstOcurrence": "Zuerst deklariert in:", "DuplicatePackagePatternIgnoredLocations": "Die folgenden Neudeklarationen werden ignoriert:", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "Die Option --{option} wird im klassischen Modus nicht unterstützt, und es wurde kein Manifest gefunden.", "ErrorInvalidExtractOption": "--{option} muss auf eine nicht negative ganze Zahl oder auf \"AUTO\" festgelegt werden.", "ErrorInvalidManifestModeOption": "Die Option --{option} wird im Manifestmodus nicht unterstützt.", + "ErrorManifestMustDifferFromOverlay": "Das Manifestverzeichnis ({path}) darf nicht mit einem Verzeichnis identisch sein, das in Überlagerungsports konfiguriert ist.", + "ErrorManifestMustDifferFromOverlayDot": "Das Manifestverzeichnis darf nicht mit einem Verzeichnis identisch sein, das in Überlagerungsports konfiguriert ist. Daher dürfen die Werte für \"overlay-ports\" nicht \".\" sein.", "ErrorMissingVcpkgRoot": "„vcpkg-root“ konnte nicht erkannt werden. Wenn Sie versuchen, eine Kopie von „vcpkg“ zu verwenden, die Sie erstellt haben, müssen Sie die VCPKG_ROOT-Umgebungsvariable definieren, um auf eine geklonte Kopie von „https://github.com/Microsoft/vcpkg“ zu verweisen.", "ErrorNoVSInstance": "in Triplet {triplet}: Es wurde keine gültige Visual Studio-Instanz gefunden", "ErrorNoVSInstanceAt": "unter „{path}“", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "Fehler beim Parsen von {path}. Es wurde ein „Versionen“-Array erwartet.", "FailedToParseSerializedBinParagraph": "[Integritätsprüfung] Fehler beim Analysieren eines serialisierten binären Absatzes.\nÖffnen Sie ein Problem unter https://github.com/microsoft/vcpkg, und geben Sie folgende Ausgabe an:\n{error_msg}\nSerialisierter binärer Absatz:", "FailedToParseVersionFile": "Fehler beim Parsen der Versionsdatei: {path}", - "FailedToParseVersionXML": "Die Version für das Tool \"{tool_name}\" konnte nicht analysiert werden. Versionszeichenfolge: {version}", "FailedToRunToolToDetermineVersion": "Fehler beim Ausführen von „{path}“ zum Bestimmen der {tool_name}-Version.", "FailedToStoreBackToMirror": "Fehler beim Speichern von {path} in {url}.", "FailedToStoreBinaryCache": "Fehler beim Speichern des binären Caches {path}", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "Registrierungsinformationen werden von {url} ({value}) abgerufen...", "FieldKindDidNotHaveExpectedValue": "\"kind\" wies keinen erwarteten Wert auf: (erwarteter Wert: {expected}; gefunden: {actual})", "FileIsNotExecutable": "Diese Datei scheint nicht ausführbar zu sein", - "FileNotFound": "{path}: Datei nicht gefunden", + "FileNotFound": "Datei nicht gefunden", "FileReadFailed": "Fehler beim Lesen von {count} Bytes aus {path} bei Offset {byte_offset}.", "FileSeekFailed": "Fehler beim Suchen nach der Position von {byte_offset} in {path}.", "FilesContainAbsolutePath1": "In einem installierten Paket sollten keine absoluten Pfade, wie die folgenden, vorhanden sein. Um diese Meldung zu unterdrücken, fügen Sie set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled) hinzu.", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "Unbekannter Dateistatus: {value}", "GitUnexpectedCommandOutputCmd": "Git hat beim Ausführen von {command_line} eine unerwartete Ausgabe erzeugt.", "GraphCycleDetected": "Zyklische Abhängigkeit im Graphen erkannt bei {package_name}:", - "HashFileFailureToRead": "Fehler beim Lesen der Datei „{Pfad}“ zum Hashen: ", "HashPortManyFiles": "{package_name} enthält {count} Dateien. Das Hashen dieser Inhalte kann lange dauern, wenn der ABI-Hash für die binäre Zwischenspeicherung bestimmt wird. Erwägen Sie, die Anzahl der Dateien zu verringern. Häufige Ursachen hierfür sind das versehentliche Auschecken von Quell- oder Builddateien in das Verzeichnis eines Ports.", "HeaderOnlyUsage": "„{package_name}“ ist Header-only und kann von CMake aus verwendet werden über:", "HelpAssetCaching": "**Experimentelles Feature: Kann jederzeit geändert oder entfernt werden**\n\nvcpkg kann Spiegelungen verwenden, um heruntergeladene Ressourcen zwischenzuspeichern, wodurch ein ununterbrochener Betrieb sichergestellt wird, auch wenn sich die ursprüngliche Quelle ändert oder verschwindet.\n\nDie Asset-Zwischenspeicherung kann konfiguriert werden, indem Sie entweder die Umgebungsvariable „X_VCPKG_ASSET_SOURCES“ auf eine durch Semikolons getrennte Liste von Quellen festlegen oder eine Sequenz von „--x-asset-sources=“-Befehlszeilenoptionen übergeben. Befehlszeilenquellen werden nach Umgebungsquellen interpretiert. Kommas, Semikolons und Anführungszeichen (') können als Escapezeichen verwendet werden.\n\nDer optionale Parameter steuert für bestimmte Zeichenfolgen, wie auf sie zugegriffen wird. Sie können „read“, „write“ oder „readwrite“ angeben. Standardmäßig wird der Parameter auf „read“ festgelegt.\n\nGültige Quellen:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "Fehler, wenn zwischengespeicherte Binärdateien nicht verfügbar sind", "HelpTxtOptOnlyDownloads": "Führt Best-Effort-Versuch aus, Quellen ohne Erstellung herunterzuladen.", "HelpTxtOptRecurse": "Ermöglicht das Entfernen von Paketen im Rahmen der Installation.", - "HelpTxtOptUseAria2": "Verwendet aria2 zum Ausführen von Downloadaufgaben", "HelpTxtOptUseHeadVersion": "Installiert die Bibliotheken in der Befehlszeile mithilfe der neuesten Upstreamquellen (klassischer Modus).", "HelpTxtOptWritePkgConfig": "Schreibt eine Datei im NuGet packages.config-Format für die Verwendung mit externem binärem Zwischenspeichern. Weitere Informationen finden Sie unter \"vcpkg-Hilfe zu binärem Zwischenspeichern\".", "HelpUpdateBaseline": "Der beste Ansatz, um Ihre Bibliotheken auf dem neuesten Stand zu halten, besteht im Aktualisieren Ihres Baselineverweises. Hierdurch wird sichergestellt, dass alle Pakete, einschließlich transitiver Pakete, aktualisiert werden. Wenn Sie jedoch ein Paket unabhängig aktualisieren müssen, können Sie eine „version>=“-Einschränkung verwenden.", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "Die Integration wurde für Visual Studio 2015 nicht angewendet.", "InternalCICommand": "vcpkg ci ist ein interner Befehl, der sich inkompatibel ändert oder jederzeit entfernt wird.", "InternalErrorMessageContact": "Geben Sie unter „https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug“ das Problem mit detaillierten Schritten an, um das Problem zu reproduzieren.", - "InvalidArchitecture": "Ungültige Architektur: {value}", + "InvalidArchitectureValue": "Ungültige Architektur: {value}. Erwartet: {expected}", "InvalidArgument": "Ungültiges Argument.", "InvalidArgumentRequiresAbsolutePath": "Ungültiges Argument: Die binäre Konfiguration '{binary_source}' Pfadargumente für binäre Konfigurationszeichenfolgen müssen absolut sein.", "InvalidArgumentRequiresBaseUrl": "Ungültiges Argument: Für die binäre Konfiguration '{binary_source}' ist eine {base_url} Basis-URL als erstes Argument erforderlich.", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "Ungültiger Logikausdruck. Verwenden Sie \"|\" anstelle von \"or\".", "InvalidOptionForRemove": "„remove“ akzeptiert entweder Bibliotheken oder „--outdated“", "InvalidPortVersonName": "Ungültiger Dateiname der Portversion gefunden: {path}.", + "InvalidSha512": "Ungültiger SHA-512-Hash: {sha}\nDer SHA-512-Hash muss 128 Zeichen lang sein und darf nur Hexadezimalziffern enthalten.", "InvalidSharpInVersion": "Ungültiges Zeichen \"#\" im Versionstext", "InvalidSharpInVersionDidYouMean": "Ungültiges Zeichen \"#\" im Versionstext. Meinten Sie \"port-version\": {value}?", "InvalidString": "An Value::string(std::string) wurde ungültiger UTF8-Code übergeben.", + "InvalidToolOSValue": "Ungültiges Toolbetriebssystem: {value}. Erwartet: {expected}", + "InvalidToolVersion": "Ungültige Toolversion; Es wurde eine Zeichenfolge erwartet, die eine Teilzeichenfolge zwischen 1 und 3 Zahlen enthält, die durch Punkte getrennt sind.", "InvalidTriplet": "Ungültiges Triplet: {triplet}", "InvalidUri": "URI kann nicht geparst werden: {value}", "InvalidValueHashAdditionalFiles": "Die Variable VCPKG_HASH_ADDITIONAL_FILES enthält einen ungültigen Dateipfad: \"{path}\". Der Wert muss ein absoluter Pfad zu einer vorhandenen Datei sein.", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "Der serialisierte binäre Absatz unterscheidet sich vom ursprünglichen binären Absatz. Öffnen Sie unter https://github.com/microsoft/vcpkg ein Problem mit der folgenden Ausgabe:", "MismatchedFiles": "Die zu speichernde Datei stimmt nicht mit dem Hash überein.", "MismatchedManifestAfterReserialize": "Das serialisierte Manifest unterscheidet sich vom ursprünglichen Manifest. Öffnen Sie unter https://github.com/microsoft/vcpkg einen Sachverhalt mit der folgenden Ausgabe:", - "MismatchedNames": "Namen stimmten nicht überein: '{package_name}' != '{actual}'", + "MismatchedNames": "Der in der Metadatendatei deklarierte Portname stimmte nicht mit dem Verzeichnis überein. Es wurde erwartet, dass der Port {package_name} wird, aber die Datei deklariert {actual}.", "MismatchedSpec": "Nicht übereinstimmende Spezifikation im Port {path}: erwartete {expected}, tatsächliche {actual}", "MismatchedType": "{json_field}: Nicht übereinstimmender Typ: {json_type} erwartet", "Missing7zHeader": "Der 7z-Header wurde nicht gefunden.", "MissingAndroidEnv": "ANDROID_NDK_HOME Umgebungsvariable fehlt", "MissingAndroidHomeDir": "ANDROID_NDK_HOME Verzeichnis ist nicht vorhanden: {path}", "MissingArgFormatManifest": "format-manifest wurde ohne \"--all\" an \"--convert-control\" übergeben.\nDies führt keine Aktion aus: Explizit übergebene Steuerdateien werden automatisch konvertiert.", - "MissingAssetBlockOrigin": "Fehlender {path} und Downloads werden durch x-block-origin blockiert.", "MissingClosingParen": "Schließende geschweifte Klammer „)“ fehlt.", "MissingDependency": "Das Paket {spec} ist installiert, die Abhängigkeit {package_name} jedoch nicht.", "MissingExtension": "Die Erweiterung „{extension}“ fehlt.", @@ -814,7 +841,6 @@ "NoInstalledPackages": "Es sind keine Pakete installiert. Meinten Sie „Suchen“?", "NoOutdatedPackages": "Es sind keine veralteten Pakete vorhanden.", "NoRegistryForPort": "für Port {package_name} ist keine Registrierung konfiguriert", - "NoUrlsAndHashSpecified": "Es wurden keine URLs zum Herunterladen des SHA angegeben: {sha}", "NoUrlsAndNoHashSpecified": "Es wurden keine URLs und kein Hash angegeben.", "NonExactlyArgs": "Der Befehl \"{command_name}\" erfordert genau {expected} Argumente, aber {actual} wurden angegeben.", "NonOneRemainingArgs": "Der Befehl \"{command_name}\" erfordert genau ein Argument.", @@ -834,8 +860,8 @@ "Options": "Optionen", "OriginalBinParagraphHeader": "\nUrsprünglicher binärer Absatz", "OtherCommandsHeader": "Andere", - "OverlayPatchDir": "Der Überlagerungspfad „{path}“ muss vorhanden sein und muss ein Verzeichnis sein.", - "OverlayPortsDirectoriesHelp": "Verzeichnisse von Überlagerungsports (auch: {env_var})", + "OverlayPatchDir": "Der Überlagerungspfad \"{path}\" muss ein vorhandenes Verzeichnis sein.", + "OverlayPortsHelp": "Überlagerungsportverzeichnisse oder Verzeichnisse mit Überlagerungsportverzeichnissen (auch: {env_var})", "OverlayTripletDirectoriesHelp": "Verzeichnisse von Überlagerungstriplets (auch: {env_var})", "OverlayTriplets": "Überlagerungstriplets aus „{path}“:", "OverwritingFile": "Die Datei {path} war bereits vorhanden und wird überschrieben", @@ -927,6 +953,7 @@ "PortsUpdated": "Die folgenden {count} Ports wurden entfernt:", "PrebuiltPackages": "Es gibt Pakete, die nicht erstellt wurden. Führen Sie die folgenden Ausführungen aus, um sie zu erstellen:", "PreviousIntegrationFileRemains": "Die vorherige Integrationsdatei wurde nicht entfernt.", + "ProgramPathReturnedNonzeroExitCode": "Fehler bei Exitcode „{exit_code}“.", "ProgramReturnedNonzeroExitCode": "Fehler bei {tool_name}. Exitcode: ({exit_code}).", "ProvideExportType": "Mindestens eine der folgenden Optionen ist erforderlich: --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "Fehler beim Pushen von {vendor} nach „{path}“. Verwenden Sie „--debug“, um weitere Informationen zu erhalten.", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "Ziel-Triplet. Siehe „vcpkg-Hilfe zu Triplets“ (Standard: {env_var})", "StartCodeUnitInContinue": "Startcodeeinheit in Fortsetzungsposition gefunden", "StoreOptionMissingSha": "Die Option \"--store\" ist ohne sha512 ungültig.", - "StoredBinariesToDestinations": "Gespeicherte Binärdateien in {count} Zielen in {elapsed}.", + "SubmittingBinaryCacheBackground": "Die Übermittlung von {spec} an {count} Binärcache(s) im Hintergrund wird gestartet.", + "SubmittingBinaryCacheComplete": "Übermittlung von {spec} an {count} Binärcache(s) in {elapsed} abgeschlossen", "SuccessfulyExported": "{package_name} nach {path} exportiert", "SuggestGitPull": "Das Ergebnis ist möglicherweise veraltet. Führen Sie \"git pull\" aus, um die neuesten Ergebnisse zu erhalten.", "SuggestStartingBashShell": "Stellen Sie sicher, dass Sie eine neue Bash-Shell gestartet haben, damit die Änderung wirksam wird.", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "Fehler beim Installieren der Systemzieldatei {path}", "ToRemovePackages": "Um nur veraltete Pakete zu entfernen, führen Sie\n{command_name} \"–veraltet entfernen\" aus.", "ToUpdatePackages": "Führen Sie \n{command_name}-Upgrade aus, um diese Pakete und alle Abhängigkeiten zu aktualisieren.", + "ToolDataFileSchemaVersionNotSupported": "Die Dokumentschemaversion {version} wird von dieser Version von vcpkg nicht unterstützt.", "ToolFetchFailed": "{tool_name} konnte nicht abgerufen werden.", + "ToolHashMismatch": "{tool_name} scheint bereits heruntergeladen zu sein, hat aber einen falschen Hash. {expected} erwartet, wurde jedoch {actual}.", "ToolInWin10": "Dieses Hilfsprogramm ist mit Windows 10 oder höher gebündelt.", "ToolOfVersionXNotFound": "Eine geeignete Version von {tool_name} wurde nicht gefunden (v{version} erforderlich) und portierbare Version kann automatisch herunterladen werden. Installieren Sie eine neuere Version von {tool_name}.", "TotalInstallTime": "Gesamtinstallationszeit: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "aktualisierte Registry „{url}“: Baseline „{old_value}“ -> „{new_value}“", "UpgradeInManifest": "Upgrade aktualisiert eine Installation im klassischen Modus und unterstützt daher keinen Manifestmodus. Erwägen Sie, Ihre Abhängigkeiten zu aktualisieren, indem Sie Ihre Baseline mit vcpkg x-update-baseline auf einen aktuellen Wert aktualisieren und die vcpkg-Installation ausführen.", "UpgradeRunWithNoDryRun": "Wenn Sie sicher sind, dass Sie die obigen Pakete neu erstellen möchten, führen Sie diesen Befehl mit der Option \"--no-dry-run\" aus.", - "UploadingBinariesToVendor": "Binärdateien für „{spec}“ werden in „{vendor}“-Quellpfad „{path}“ hochgeladen.", + "UploadingBinariesToVendor": "Binärdateien für {spec} werden aus {path} in {vendor} hochgeladen.", "UsageInstallInstructions": "Sie können die Nutzungsdatei mit dem folgenden CMake installieren", "UsageTextHere": "die Nutzungsdatei ist vorhanden", "UseEnvVar": "-- Verwendung von {env_var} in Umgebungsvariablen.", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "„{package_name}“ ist „{actual}“ zugewiesen, aber der lokale Port ist „{expected}“", "VersionBuiltinPortTreeEntryMissing": "kein Versionsdatenbankeintrag für das Paket {package_name} bei {expected}; mithilfe der Strukturversion der ausgecheckten Ports ({actual}).", "VersionCommandHeader": "Version des vcpkg-Paketverwaltungsprogramms {version}\n\nLizenzinformationen finden Sie unter LICENSE.txt.", - "VersionConflictXML": "{path}-Version erwartet: [{expected_version}], war aber [{actual_version}]. Führen Sie bootstrap-vcpkg erneut aus.", "VersionConstraintNotInDatabase1": "Die Einschränkung „version>=“ für „{package_name}“ nennt Version „{version}, die in der Versionsdatenbank nicht vorhanden ist. Alle Versionen müssen in der Versionsdatenbank vorhanden sein, damit sie von vcpkg interpretiert werden können.", "VersionConstraintNotInDatabase2": "Erwägen Sie, die Versionseinschränkung zu entfernen oder einen hier deklarierten Wert auszuwählen.", "VersionConstraintOk": "Alle Versionseinschränkungen sind mit der Versionsdatenbank konsistent.", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "Auf \"#\" im Versionstext muss eine Portversion folgen (eine nicht negative ganze Zahl).", "VersionSpecMismatch": "Fehler beim Laden des Ports, da die Versionen inkonsistent sind. Die Datei „{path}“ enthält die Version {actual_version}, aber die Versionsdatenbank gibt an, dass sie {expected_version} sein soll.", "VersionVerifiedOK": "{version_spec} befindet sich ordnungsgemäß in der Versionsdatenbank ({git_tree_sha}).", + "WaitUntilPackagesUploaded": "Warten auf {count} verbleibenden binären Cacheübermittlungen...", "WaitingForChildrenToExit": "Es wird auf das Beenden untergeordneter Prozesse gewartet...", "WaitingToTakeFilesystemLock": "Es wird auf die Sperre des Dateisystems für „{path}“ gewartet...", "WarnOnParseConfig": "In der Konfiguration {path} wurden die folgenden Warnungen gefunden:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "beim Laden von {version_spec}", "WhileLookingForSpec": "bei der Suche nach {spec}:", "WhileParsingVersionsForPort": "beim Parsen von Versionen für das Paket {package_name} aus {path}", + "WhileRunningAssetCacheScriptCommandLine": "während der Ausführung der Skriptbefehlszeile für den Ressourcencache", "WhileValidatingVersion": "beim Überprüfen der Version: {version}", "WindowsOnlyCommand": "Dieser Befehl unterstützt nur Windows.", "WroteNuGetPkgConfInfo": "NuGet-Paketkonfigurationsinformationen wurden in {path} geschrieben.", diff --git a/locales/messages.es.json b/locales/messages.es.json index 9d7bd3c430..ce6d9e17e4 100644 --- a/locales/messages.es.json +++ b/locales/messages.es.json @@ -4,6 +4,7 @@ "ABoolean": "un booleano", "ABuiltinRegistry": "un registro integrado", "AConfigurationObject": "un objeto de configuración", + "ACpuArchitecture": "una arquitectura de CPU", "ADateVersionString": "una cadena de versión de fecha", "ADefaultFeature": "una característica por defecto", "ADemandObject": "un objeto a petición", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "una cadena de versión relajada", "ASemanticVersionString": "una cadena de versión semántica", "ASetOfFeatures": "un conjunto de características", + "ASha512": "un hash SHA-512", "AString": "una cadena", "AStringOrArrayOfStrings": "una cadena o matriz de cadenas", "AStringStringDictionary": "una \"cadena\": diccionario :\"cadena\"", + "AToolDataArray": "una matriz de metadatos de herramienta", + "AToolDataFile": "un archivo de datos de herramienta", + "AToolDataOS": "un sistema operativo de datos de herramienta", + "AToolDataObject": "metadatos de la herramienta", + "AToolDataVersion": "una versión de datos de herramienta", "AUrl": "una dirección URL", "AVcpkgRepositoryCommit": "una confirmación de repositorio vcpkg", "AVersionConstraint": "restricción de versión", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "Fuerza la detección de host en Windows al adquirir artefactos", "ArtifactsSwitchX64": "Fuerza la detección de host a x64 al adquirir artefactos", "ArtifactsSwitchX86": "Fuerza la detección de host a x86 al adquirir artefactos", - "AssetCacheHit": "Acierto de caché de recursos para {path}; descargado de: {url}", - "AssetCacheMiss": "Error de caché de recursos; descargando desde {url}", - "AssetCacheMissBlockOrigin": "Error de caché de recursos para {path} y las descargas están bloqueadas por x-block-origin.", + "AssetCacheConsult": "Intentando descargar {path} con la {url} de caché de recursos", + "AssetCacheConsultScript": "Intentando descargar {path} con el script de caché de recursos", + "AssetCacheHit": "La descarga se realizó correctamente. Acierto de caché de recursos.", + "AssetCacheHitUrl": "La descarga se realizó correctamente. Acierto de caché de recursos, no se intentó el origen autoritativo {url}", + "AssetCacheMiss": "Error de caché de recursos; intentando {url} de origen autoritativo", + "AssetCacheMissBlockOrigin": "no hubo aciertos de caché de recursos y bloques de origen de bloque x que intentan el origen autoritativo {url}", + "AssetCacheMissNoUrls": "La caché de recursos no encontró {sha} y no se conoce ninguna dirección URL autoritativa", "AssetCacheProviderAcceptsNoArguments": "argumentos inesperados: \"{value}\" no acepta argumentos", - "AssetCacheSuccesfullyStored": "{path} se almacenó correctamente en {url}.", + "AssetCacheScriptBadVariable": "la plantilla de script {value} contiene un {list} de reemplazo desconocido", + "AssetCacheScriptBadVariableHint": "si lo desea en la línea de comandos literal, use {{{{{list}}}}}", + "AssetCacheScriptCommandLine": "la línea de comandos del script completo era", + "AssetCacheScriptFailed": "el script de caché de recursos devolvió un código de salida distinto de cero {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "el script de caché de recursos devolvió un resultado correcto, pero el archivo resultante tiene un hash inesperado", + "AssetCacheScriptFailedToWriteFile": "el script de caché de recursos devolvió un resultado correcto pero no creó el archivo de resultados esperado", + "AssetCacheScriptNeedsSha": "la plantilla de script {value} requiere un SHA, pero no se conoce ningún SHA por el intento de descarga de {url}", + "AssetCacheScriptNeedsUrl": "la plantilla de script {value} requiere una dirección URL, pero no se conoce ninguna dirección URL para el intento de descarga de {sha}", + "AssetCacheSuccesfullyStored": "Almacén correcto", "AssetSourcesArg": "Orígenes de almacenamiento en caché de recursos. Consulte \"vcpkg help assetcaching\"", "AttemptingToSetBuiltInBaseline": "intentando establecer builtin-baseline en vcpkg.json al invalidar default-registry en vcpkg-configuration.json.\nse usará default-registry de vcpkg-configuration.json.", "AuthenticationMayRequireManualAction": "Uno o más proveedores de credenciales de {vendor} solicitaron una acción manual. Agregue el origen binario \"interactivo\" para permitir la interactividad.", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "El número de directorios principales a eliminar de todas las rutas", "CommandEnvExample2": "vcpkg env \"ninja -C \" --triplet x64-windows", "CommandFailed": "comando:\n{command_line}\nerror con la salida siguiente:", - "CommandFailedCode": "comando:\n{command_line}\nerror con el código de salida {exit_code} y la salida siguiente:", "CommunityTriplets": "Tripletes de la comunidad:", "CompilerPath": "Se encontró el compilador: {path}", - "CompressFolderFailed": "No se pudo comprimir la carpeta \"{path}\":", "ComputingInstallPlan": "Calculando plan de instalación...", "ConfigurationErrorRegistriesWithoutBaseline": "La configuración definida en {path} no es válida.\n\nEl uso de registros requiere que se establezca una línea base para el registro predeterminado o que el registro predeterminado sea null.\n\nConsulte {url} para obtener más detalles.", "ConfigurationNestedDemands": "[\"{json_field}\"] contiene un objeto `demands` anidado (las `demands` anidadas no tienen ningún efecto)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "No se pudo deducir el id. y la versión de NuGet del nombre de archivo: {path}", "CouldNotFindBaselineInCommit": "No se pudo encontrar la línea base en {url} en {commit_sha} para {package_name}.", "CouldNotFindGitTreeAtCommit": "no se pudo encontrar el árbol git para \"versiones\" en el repositorio {package_name} en el comando {commit_sha}", - "CouldNotFindToolVersion": "No se encontró en {path}", "CouldNotFindVersionDatabaseFile": "No se pudo encontrar el archivo de base de datos de las versiones: {path}", "CreateFailureLogsDir": "Creando {path} de directorio de salida de registros de errores.", "CreatedNuGetPackage": "Nupkg creado: \"{path}\"", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "Creando paquete NuGet...", "CreatingZipArchive": "Creando archivo ZIP...", "CreationFailed": "Error al crear {path}.", + "CurlFailedGeneric": "Error en la operación curl con el código de error {exit_code}.", "CurlFailedToPut": "cURL no pudo colocar el archivo en {url} con el código de salida {exit_code}.", "CurlFailedToPutHttp": "cURL no pudo colocar el archivo en {url} con el código de salida {exit_code} y el código HTTP {value}.", - "CurlResponseTruncatedRetrying": "curl devolvió una respuesta parcial; espere {value} milisegundos e inténtelo de nuevo", - "CurlTimeout": "curl no pudo realizar todas las operaciones HTTP solicitadas, incluso después del tiempo de espera y los reintentos. La última línea de comandos fue: {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "curl no pudo devolver el número esperado de códigos de salida; esto puede ocurrir si algo termina el rizo antes de que termine. Curl se cerró con {exit_code} que normalmente es el código de resultado de la última operación, pero puede ser el resultado de un bloqueo. Se {command_line} la línea de comandos y todas las salidas están a continuación:", "CurrentCommitBaseline": "Puede usar la confirmación actual como línea base, que es:\n\t\"builtin-baseline\": \"{commit_sha}\"", "CycleDetectedDuring": "ciclo detectado durante {spec}:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "La variable de entorno VCPKG_DEFAULT_BINARY_CACHE debe ser un directorio (era: {path})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "las DLL son relativas a ${{CURRENT_PACKAGES_DIR}} aquí", "DocumentedFieldsSuggestUpdate": "Si se trata de campos documentados que deben reconocerse, intente actualizar la herramienta vcpkg.", "DownloadAvailable": "Hay disponible una copia descargable de esta herramienta que se puede usar al anular la configuración {env_var}.", - "DownloadFailedCurl": "{url}: cURL no se pudo descargar con el código de salida {exit_code}", - "DownloadFailedHashMismatch": "El archivo no tiene el hash esperado:\nURL: {url}\nArchivo: {path}\nHash esperado: {expected}\nHash real: {actual}", - "DownloadFailedProxySettings": "Error al descargar {path}.\nSi usa un proxy, asegúrese de que la configuración sea correcta.\nLas causas posibles son:\n1. Está usando realmente un proxy HTTP, pero estableciendo la variable HTTPS_PROXY en \"https//address:port\".\nEsto no es correcto, porque el prefijo \"https://\" indica que el proxy es un proxy HTTPS, mientras que su proxy (v2ray, shadowsocksr, etc.) es un proxy HTTP.\nIntente establecer \"http://address:port\" en HTTP_PROXY y HTTPS_PROXY en su lugar.\n2. Si usa Windows, vcpkg usará automáticamente la configuración de proxy de Windows IE establecida por el software para proxy. Ver, {url}\nEl valor establecido por el proxy podría ser incorrecto o tener el mismo problema de prefijo \"https://\".\n3. El servidor remoto del proxy es nuestro servicio.\nSi ha intentado descargar directamente el vínculo y cree que no se trata de un error temporal del servidor de descarga, envíe una incidencia a https://github.com/Microsoft/vcpkg/issues\npara notificar este error ascendente del servidor de descarga.", - "DownloadFailedRetrying": "Error de descarga: reintentar después de {value}ms", + "DownloadFailedHashMismatch": "la descarga de {url} tenía un hash inesperado", + "DownloadFailedHashMismatchActualHash": "Real: {sha}", + "DownloadFailedHashMismatchExpectedHash": "Se esperaba: {sha}", + "DownloadFailedHashMismatchZero": "error en la descarga porque el sha512 esperado era todos ceros. Cambie el SHA512 esperado a: {sha}", + "DownloadFailedProxySettings": "Si usa un proxy, asegúrese de que la configuración del proxy es correcta.\nLas causas posibles son:\n1. Está usando realmente un proxy HTTP, pero estableciendo HTTPS_PROXY variable en \"https//address:port\".\nEsto no es correcto, porque el prefijo \"https://\" indica que el proxy es un proxy HTTPS, mientras que el proxy (v2ray, shadowsocksr, etc.) es un proxy HTTP.\nIntente establecer \"http://address:port\" en HTTP_PROXY y HTTPS_PROXY en su lugar.\n2. Si usa Windows, vcpkg usará automáticamente la configuración de proxy de Windows IE establecida por el software proxy. Consulte: https://github.com/microsoft/vcpkg-tool/pull/77\nEl valor establecido por el proxy podría ser incorrecto o tener el mismo problema de prefijo \"https://\".\n3. El servidor remoto del proxy es nuestro servicio.\nSi cree que no se trata de un error temporal del servidor de descarga y vcpkg debe cambiarse para descargar este archivo desde otra ubicación, envíe un problema a https://github.com/Microsoft/vcpkg/issues", + "DownloadFailedRetrying": "Error al descargar {url}: reintentar después de {value} ms", "DownloadFailedStatusCode": "{url}: error: código de estado {value}", + "DownloadOrUrl": "o {url}", "DownloadRootsDir": "Descarga el directorio (predeterminado: {env_var})", - "DownloadSuccesful": "Descargado correctamente {path}.", - "DownloadWinHttpError": "{url}: error de {system_api} con el código de salida {exit_code}", + "DownloadSuccesful": "Descargado correctamente {path}", + "DownloadSuccesfulUploading": "La {path} se descargó correctamente y se almacena en {url}", + "DownloadTryingAuthoritativeSource": "Intentando {url}", + "DownloadWinHttpError": "{url}: error de {system_api} con el código de salida {exit_code}.", "DownloadedSources": "Orígenes descargados para {spec}", + "DownloadingAssetShaToFile": "Descargando la entrada de caché de recursos {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "se solicitó la descarga de la entrada de caché de recursos {sha} -> {path}, pero no hay ninguna caché de recursos configurada", + "DownloadingFile": "Descargando {path}", + "DownloadingFileFirstAuthoritativeSource": "Descargando {path}, intentando {url}", "DownloadingPortableToolVersionX": "No se encontró una versión adecuada de {tool_name} (se requiere v{version}).", - "DownloadingUrl": "Descargando {url}", + "DownloadingUrlToFile": "Descargando {url} -> {path}", "DownloadingVcpkgStandaloneBundle": "Descargando el paquete independiente {version}.", "DownloadingVcpkgStandaloneBundleLatest": "Descargando el paquete independiente más reciente.", + "DuplicateDependencyOverride": "{package_name} ya tiene una invalidación", "DuplicatePackagePattern": "El paquete \"{package_name}\" está duplicado.", "DuplicatePackagePatternFirstOcurrence": "Declarado por primera vez en:", "DuplicatePackagePatternIgnoredLocations": "Se omitirán las siguientes declaraciones:", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "La opción --{option} no se admite en el modo clásico y no se encontró ningún manifiesto.", "ErrorInvalidExtractOption": "--{option} debe establecerse en un entero no negativo o “AUTO”.", "ErrorInvalidManifestModeOption": "La opción --{option} no se admite en modo de manifiesto.", + "ErrorManifestMustDifferFromOverlay": "El directorio de manifiesto ({path}) no puede ser el mismo que el directorio configurado en los puertos superpuestos.", + "ErrorManifestMustDifferFromOverlayDot": "El directorio de manifiesto no puede ser el mismo que un directorio configurado en los puertos superpuestos, por lo que los valores de \"overlay-ports\" no pueden ser \".\".", "ErrorMissingVcpkgRoot": "No se pudo detectar vcpkg-root. Si está intentando usar una copia de vcpkg que ha compilado, debe definir la variable de entorno VCPKG_ROOT para que apunte a una copia clonada de https://github.com/Microsoft/vcpkg.", "ErrorNoVSInstance": "en el triplete {triplet}: no se encuentra una instancia de Visual Studio válida", "ErrorNoVSInstanceAt": "en \"{path}\"", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "No se pudo analizar {path}. Se esperaba una matriz \"versions\".", "FailedToParseSerializedBinParagraph": "[comprobación de integridad] No se pudo analizar un párrafo binario serializado.\nAbra una incidencia en https://github.com/microsoft/vcpkg, con la siguiente salida:\n{error_msg}\n Párrafo binario serializado:", "FailedToParseVersionFile": "No se pudo analizar el archivo de versión: {path}", - "FailedToParseVersionXML": "No se pudo analizar la versión de la herramienta {tool_name}. La cadena de versión fue: {version}", "FailedToRunToolToDetermineVersion": "No se pudo ejecutar \"{path}\" para determinar la versión de {tool_name}.", "FailedToStoreBackToMirror": "No se pudo almacenar {path} en {url}.", "FailedToStoreBinaryCache": "No se pudo almacenar la caché binaria {path}", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "Obteniendo información del registro de {url} ({valor})...", "FieldKindDidNotHaveExpectedValue": "\"kind\" no tenía un valor esperado: (se esperaba uno de: {expected}; se encontró {actual})", "FileIsNotExecutable": "este archivo no parece ser ejecutable", - "FileNotFound": "{path}: no se encontró el archivo", + "FileNotFound": "archivo no encontrado", "FileReadFailed": "No se pudieron leer {count} bytes de {path} en el desplazamiento {byte_offset}.", "FileSeekFailed": "No se pudo buscar la posición {byte_offset} en {path}.", "FilesContainAbsolutePath1": "No debe haber rutas de acceso absolutas, como las siguientes, en un paquete instalado. Para suprimir este mensaje, agregue set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "estado de archivo desconocido: {value}", "GitUnexpectedCommandOutputCmd": "Git generó una salida inesperada al ejecutar {command_line}", "GraphCycleDetected": "Ciclo detectado en el gráfico en {package_name}:", - "HashFileFailureToRead": "no se pudo leer el \"{path}\" de archivo para el algoritmo hash: ", "HashPortManyFiles": "{package_name} contiene {count} archivos. El hash de este contenido puede tardar mucho tiempo al determinar el hash de ABI para el almacenamiento en caché binario. Considera la posibilidad de reducir el número de archivos. Las causas comunes de esto son extraer accidentalmente los archivos de origen o de compilación en el directorio de un puerto.", "HeaderOnlyUsage": "{package_name} es de solo encabezado y se puede usar desde CMake a través de:", "HelpAssetCaching": "**Característica experimental: esto puede cambiar o quitarse en cualquier momento**\n\nvcpkg puede usar reflejos para almacenar en caché los recursos descargados, lo que garantiza una operación continua aunque el origen original cambie o desaparezca.\n\nEl almacenamiento en caché de recursos se puede configurar estableciendo la variable de entorno X_VCPKG_ASSET_SOURCES en una lista de orígenes delimitada por punto y coma o pasando una secuencia de opciones de línea de comando --x-asset-sources=. Los orígenes de línea de comandos se interpretan después de los orígenes de entorno. Las comas, los puntos y comas, y los acentos graves pueden escaparse utilizando el acento grave (`).\n\nEl parámetro opcional para determinadas cadenas controla cómo se tendrá acceso a las cadenas. Se puede especificar como \"read\", \"write\" o \"readwrite\" y el valor predeterminado es \"read\".\n\nOrígenes válidos:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "Se produce un error si los archivos binarios almacenados en caché no están disponibles", "HelpTxtOptOnlyDownloads": "Realiza el mejor esfuerzo al intentar descargar orígenes sin crear", "HelpTxtOptRecurse": "Permite la eliminación de paquetes como parte de la instalación", - "HelpTxtOptUseAria2": "Usa aria2 para realizar tareas de descarga", "HelpTxtOptUseHeadVersion": "Instala las bibliotecas en la línea de comandos con los orígenes ascendentes más recientes (modo clásico)", "HelpTxtOptWritePkgConfig": "Escribe un archivo con formato packages.config de NuGet para usarlo con almacenamiento en caché binario externo. Consulte \"vcpkg help binarycaching\" para obtener más información", "HelpUpdateBaseline": "El mejor enfoque para mantener actualizadas las bibliotecas es actualizar la referencia de línea base. Esto garantizará que se actualicen todos los paquetes, incluidos los transitivos. Sin embargo, si necesita actualizar un paquete de forma independiente, puede usar una restricción \"versión>=\".", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "No se aplicó la integración para Visual Studio 2015.", "InternalCICommand": "vcpkg ci es un comando interno que cambiará de forma incompatible o se quitará en cualquier momento.", "InternalErrorMessageContact": "Abra un problema en https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug con los pasos detallados para reproducir el problema.", - "InvalidArchitecture": "arquitectura no válida: {value}", + "InvalidArchitectureValue": "Arquitectura no válida: {value}. Se esperaba uno de: {expected}", "InvalidArgument": "argumento no válido", "InvalidArgumentRequiresAbsolutePath": "argumento no válido: los argumentos de la ruta de acceso de '{binary_source}' de configuración binaria para las cadenas de configuración binarias deben ser absolutos", "InvalidArgumentRequiresBaseUrl": "argumento no válido: '{binary_source}' de configuración binaria requiere una dirección URL base de {base_url} como primer argumento", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "expresión lógica no válida, use \"|\" en lugar de \"or\"", "InvalidOptionForRemove": "'remove' acepta bibliotecas o '--outdated'", "InvalidPortVersonName": "Se ha encontrado un nombre de archivo de versión de puerto no válido: \"{path}\".", + "InvalidSha512": "hash SHA-512 no válido: {sha}\nEl hash SHA-512 debe tener una longitud de 128 caracteres y contener solo dígitos hexadecimales", "InvalidSharpInVersion": "carácter no válido \"#\" en el texto de la versión", "InvalidSharpInVersionDidYouMean": "carácter no válido \"#\" en el texto de la versión. ¿Quería decir \"port-version\": {value}?", "InvalidString": "Se ha pasado un utf8 inválido a Value::string(std::string)", + "InvalidToolOSValue": "Sistema operativo de herramienta no válido: {value}. Se esperaba uno de: {expected}", + "InvalidToolVersion": "Versión de herramienta no válida; se esperaba una cadena que contiene una subcadena de entre 1 y 3 números separados por puntos.", "InvalidTriplet": "Triplete no válido: {triplet}", "InvalidUri": "no se puede analizar el URI: {value}", "InvalidValueHashAdditionalFiles": "La variable VCPKG_HASH_ADDITIONAL_FILES contiene una ruta de acceso de archivo no válida: \"{path}\". El valor debe ser una ruta de acceso absoluta a un archivo existente.", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "El párrafo binario serializado era diferente del párrafo binario original. Abra una incidencia en https://github.com/microsoft/vcpkg con la siguiente salida:", "MismatchedFiles": "el archivo que se va a almacenar no coincide con el hash", "MismatchedManifestAfterReserialize": "El manifiesto serializado era diferente del manifiesto original. Abra una incidencia en https://github.com/microsoft/vcpkg con la siguiente salida:", - "MismatchedNames": "los nombres no coinciden: '{package_name}' != '{actual}'", + "MismatchedNames": "el nombre de puerto declarado en el archivo de metadatos no coincide con el directorio. Se esperaba que el puerto se llamara {package_name}, pero el archivo declara {actual}.", "MismatchedSpec": "Especificación no coincidente en el puerto {path}: se esperaba {expected}, real {actual}", "MismatchedType": "{json_field}: tipo no coincidente: se esperaba {json_type}", "Missing7zHeader": "No se encuentra el encabezado 7z.", "MissingAndroidEnv": "Falta la variable de entorno ANDROID_NDK_HOME", "MissingAndroidHomeDir": "El directorio ANDROID_NDK_HOME no existe: {path}", "MissingArgFormatManifest": "format-manifest se pasó a --convert-control sin \"--all\".\nEsto no hace nada: los archivos de control pasados explícitamente se convierten automáticamente.", - "MissingAssetBlockOrigin": "Falta {path} y las descargas están bloqueadas por x-block-origin.", "MissingClosingParen": "falta el cierre )", "MissingDependency": "El paquete {spec} está instalado, pero la dependencia {package_name} no lo está.", "MissingExtension": "Falta la extensión '{extension}'.", @@ -814,7 +841,6 @@ "NoInstalledPackages": "No hay paquetes instalados. ¿Quiso decir \"buscar\"?", "NoOutdatedPackages": "No hay paquetes obsoletos.", "NoRegistryForPort": "no hay ningún registro configurado para el puerto {package_name}", - "NoUrlsAndHashSpecified": "No se ha especificado ninguna dirección URL para descargar SHA: {sha}", "NoUrlsAndNoHashSpecified": "No se ha especificado ninguna dirección URL ni hash.", "NonExactlyArgs": "el comando '{command_name}' requiere exactamente {expected} argumentos, pero se proporcionaron {actual}.", "NonOneRemainingArgs": "el comando '{command_name}' requiere exactamente un argumento", @@ -834,8 +860,8 @@ "Options": "Opciones", "OriginalBinParagraphHeader": "\nPárrafo binario original", "OtherCommandsHeader": "Otro", - "OverlayPatchDir": "La ruta de acceso de superposición \"{path}\" debe existir y debe ser un directorio.", - "OverlayPortsDirectoriesHelp": "Directorios de puertos superpuestos (también: {env_var})", + "OverlayPatchDir": "La ruta de acceso de superposición \"{path}\" debe ser un directorio existente.", + "OverlayPortsHelp": "Directorios de puerto superpuesto o directorios que contienen directorios de puerto superpuesto (también: {env_var})", "OverlayTripletDirectoriesHelp": "Directorios de tripletes superpuestos (también: {env_var})", "OverlayTriplets": "Tripletes superpuestos de \"{path}\":", "OverwritingFile": "El archivo {path} ya estaba presente y se sobrescribirá", @@ -927,6 +953,7 @@ "PortsUpdated": "Se actualizaron los siguientes {count} puertos:", "PrebuiltPackages": "Hay paquetes que no se han compilado. Para compilarlos, ejecute:", "PreviousIntegrationFileRemains": "No se quitó el archivo de integración anterior.", + "ProgramPathReturnedNonzeroExitCode": "error con el código de salida {exit_code}", "ProgramReturnedNonzeroExitCode": "Error de {tool_name} con código de salida: ({exit_code})", "ProvideExportType": "Se requiere al menos una de las siguientes opciones: --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "Error al insertar {vendor} en \"{path}\". Use --debug para obtener más información.", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "Triplete de destino. Consulte \"vcpkg help triplet\" (valor predeterminado: {env_var})", "StartCodeUnitInContinue": "se encontró la unidad de código de inicio en la posición de continuación", "StoreOptionMissingSha": "La opción --store no es válida sin sha512", - "StoredBinariesToDestinations": "Archivos binarios almacenados en {count} destinos en {elapsed}.", + "SubmittingBinaryCacheBackground": "Iniciando el envío de {spec} a {count} cachés binarias en segundo plano", + "SubmittingBinaryCacheComplete": "Envío de {spec} completado a {count} cachés binarias en {elapsed}", "SuccessfulyExported": "Se exportó {package_name} a {path}", "SuggestGitPull": "El resultado puede estar obsoleto. Ejecute `git pull` para obtener los resultados más recientes.", "SuggestStartingBashShell": "Asegúrese de que ha iniciado un nuevo shell de Bash para que el cambio surta efecto.", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "no se pudo instalar el archivo de destinos del sistema en {path}", "ToRemovePackages": "Para quitar solo los paquetes obsoletos, ejecute\n{command_name} remove --outdated", "ToUpdatePackages": "Para actualizar estos paquetes y todas las dependencias, ejecute\n{command_name} upgrade”", + "ToolDataFileSchemaVersionNotSupported": "la versión de esquema de documento {version} no es compatible con esta versión de vcpkg", "ToolFetchFailed": "No se pudo capturar {tool_name}.", + "ToolHashMismatch": "{tool_name} parece que ya se ha descargado, pero tiene un hash incorrecto. Se esperaba {expected} pero se {actual}", "ToolInWin10": "Esta utilidad se incluye con Windows 10 o posterior.", "ToolOfVersionXNotFound": "No se encontró la versión adecuada de {tool_name} (se requiere v{version}) y no se pudo descargar automáticamente ninguna portable. Instale una versión más reciente de {tool_name}", "TotalInstallTime": "Tiempo total de instalación: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "se actualizó el registro \"{url}\": línea base \"{old_value}\" -> \"{new_value}\"", "UpgradeInManifest": "La actualización actualiza una instalación en modo clásico y, por tanto, no es compatible con el modo manifiesto. Considere la posibilidad de actualizar las dependencias actualizando la línea base a un valor actual con vcpkg x-update-baseline y ejecutando la instalación de vcpkg.", "UpgradeRunWithNoDryRun": "Si está seguro de que desea recompilar los paquetes anteriores, ejecute este comando con la opción --no-dry-run.", - "UploadingBinariesToVendor": "Cargando archivos binarios para \"{spec}\" en \"{vendor}\" con origen \"{path}\".", + "UploadingBinariesToVendor": "Cargando archivos binarios para {spec} en {vendor} desde {path}", "UsageInstallInstructions": "puede instalar el archivo de uso con el siguiente CMake", "UsageTextHere": "el archivo de uso está aquí", "UseEnvVar": "-- Uso de {env_var} en variables de entorno.", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "{package_name} está asignado {actual}, pero el puerto local es {expected}", "VersionBuiltinPortTreeEntryMissing": "no hay ninguna entrada de base de datos de versión para {package_name} en {expected}; usando la versión del árbol de puertos restaurada ({actual}).", "VersionCommandHeader": "versión del programa de administración de paquetes vcpkg {version}\n\nConsulte LICENSE.txt para obtener información sobre la licencia.", - "VersionConflictXML": "Se esperaba {path} versión: [{expected_version}], pero fue [{actual_version}]. Vuelva a ejecutar bootstrap-vcpkg.", "VersionConstraintNotInDatabase1": "la restricción \"version>=\" a {package_name} nombres versión {version} que no existe en la base de datos de versión. Todas las versiones deben existir en la base de datos de versiones para que vcpkg las interprete.", "VersionConstraintNotInDatabase2": "considere la posibilidad de quitar la restricción de versión o elegir un valor declarado aquí", "VersionConstraintOk": "todas las restricciones de versión son coherentes con la base de datos de versión", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "\"#\" en el texto de la versión debe ir seguido de una versión de puerto (un número entero no negativo)", "VersionSpecMismatch": "No se pudo cargar el puerto porque las versiones no coinciden. El archivo \"{path}\" contiene la versión {actual_version}, pero la base de datos de versión indica que debe ser {expected_version}.", "VersionVerifiedOK": "{version_spec} está correctamente en la base de datos de la versión ({git_tree_sha})", + "WaitUntilPackagesUploaded": "Esperando {count} envíos de caché binaria restantes...", "WaitingForChildrenToExit": "Esperando a que se cierren los procesos secundarios...", "WaitingToTakeFilesystemLock": "esperando para realizar el bloqueo del sistema de archivos en {path}...", "WarnOnParseConfig": "Se encontraron las siguientes advertencias en la configuración {path}:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "al cargar {version_spec}", "WhileLookingForSpec": "mientras busca {spec}:", "WhileParsingVersionsForPort": "al analizar las versiones de {package_name} desde {path}", + "WhileRunningAssetCacheScriptCommandLine": "al ejecutar la línea de comandos del script de caché de recursos", "WhileValidatingVersion": "al validar la versión: {version}", "WindowsOnlyCommand": "Este comando solo admite Windows.", "WroteNuGetPkgConfInfo": "Se escribió la información de configuración del paquete NuGet en {path}", diff --git a/locales/messages.fr.json b/locales/messages.fr.json index ac524458c4..764ca1f83f 100644 --- a/locales/messages.fr.json +++ b/locales/messages.fr.json @@ -4,6 +4,7 @@ "ABoolean": "valeur booléenne", "ABuiltinRegistry": "registre intégré", "AConfigurationObject": "objet de configuration", + "ACpuArchitecture": "une architecture d’UC", "ADateVersionString": "chaîne de version de date", "ADefaultFeature": "une fonctionnalité par défaut", "ADemandObject": "objet de demande", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "chaîne de version souple", "ASemanticVersionString": "chaîne de version sémantique", "ASetOfFeatures": "jeu de fonctionnalités", + "ASha512": "hachage SHA-512", "AString": "chaîne", "AStringOrArrayOfStrings": "chaîne ou tableau de chaînes", "AStringStringDictionary": "une « chaîne » : dictionnaire « chaîne »", + "AToolDataArray": "tableau de métadonnées d’outil", + "AToolDataFile": "un fichier de données d’outil", + "AToolDataOS": "un système d’exploitation de données d’outil", + "AToolDataObject": "métadonnées de l’outil", + "AToolDataVersion": "une version de données d’outil", "AUrl": "URL", "AVcpkgRepositoryCommit": "validation de référentiel vcpkg", "AVersionConstraint": "une contrainte de version", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "Force la détection de l’hôte à Windows lors de l’acquisition d’artefacts", "ArtifactsSwitchX64": "Force la détection de l’hôte à x64 lors de l’acquisition d’artefacts", "ArtifactsSwitchX86": "Force la détection de l’hôte à x86 lors de l’acquisition d’artefacts", - "AssetCacheHit": "Accès au cache des ressources pour {path}; téléchargé à partir de : {url}", - "AssetCacheMiss": "Échec dans le cache des ressources; téléchargement à partir de {url}", - "AssetCacheMissBlockOrigin": "Le cache des actifs a été manqué pour {chemin} et les téléchargements sont bloqués par x-block-origin.", + "AssetCacheConsult": "Tentative de téléchargement de {path} à l’aide de l'{url} de cache de ressources", + "AssetCacheConsultScript": "Tentative de téléchargement de {path} à l’aide du script de cache de ressources", + "AssetCacheHit": "Téléchargement réussi ! Accès au cache d’actifs multimédias.", + "AssetCacheHitUrl": "Téléchargement réussi ! Accès au cache des ressources, n’a pas essayé d'{url} source faisant autorité", + "AssetCacheMiss": "Échec dans le cache des ressources ; tentative d'{url} source faisant autorité", + "AssetCacheMissBlockOrigin": "aucun accès au cache d’actifs et des blocs x-block-origin n’ont pas essayé le {url} source faisant autorité", + "AssetCacheMissNoUrls": "Le cache de ressources n’a pas recherché {sha} et aucune URL faisant autorité n’est connue", "AssetCacheProviderAcceptsNoArguments": "arguments inattendus : ’{value}’ n’accepte pas les arguments", - "AssetCacheSuccesfullyStored": "La {path} a été stockée dans {url}.", + "AssetCacheScriptBadVariable": "le modèle de script {value} contient des {list} de remplacement inconnus", + "AssetCacheScriptBadVariableHint": "si vous le souhaitez sur la ligne de commande littérale, utilisez {{{{{list}}}}}", + "AssetCacheScriptCommandLine": "la ligne de commande de script complet était", + "AssetCacheScriptFailed": "le script du cache de ressources a retourné un code de sortie différent de zéro {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "le script du cache de ressources a renvoyé une réussite, mais le fichier résultant a un hachage inattendu", + "AssetCacheScriptFailedToWriteFile": "le script du cache de ressources a renvoyé une réussite mais n’a pas créé le fichier de résultats attendu", + "AssetCacheScriptNeedsSha": "le modèle de script {value} requiert un sha, mais aucun sha n’est connu pour la tentative de téléchargement de {url}", + "AssetCacheScriptNeedsUrl": "le modèle de script {value} requiert une URL, mais aucune URL n’est connue pour la tentative de téléchargement de {sha}", + "AssetCacheSuccesfullyStored": "Store réussi", "AssetSourcesArg": "Sources de mise en cache des ressources. Voir « mise en cache des ressources d’aide vcpkg »", "AttemptingToSetBuiltInBaseline": "tentative de définition d’une ligne de base intégrée dans vcpkg.json lors du remplacement du default-registry dans vcpkg-configuration.json.\nLe default-registry de vcpkg-configuration.json sera utilisé.", "AuthenticationMayRequireManualAction": "Un ou plusieurs fournisseurs d’informations d’identification {vendor} ont demandé une action manuelle. Ajoutez la source binaire « interactive » pour autoriser l’interactivité.", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "Nombre de répertoires de début à supprimer de tous les chemins d’accès", "CommandEnvExample2": "vcpkg env \"ninja -C \" --triplet x64-windows", "CommandFailed": "commande :\n{command_line}\néchec avec la sortie suivante :", - "CommandFailedCode": "commande :\n{command_line}\néchec avec le code de sortie {exit_code} et la sortie suivante :", "CommunityTriplets": "Triplets de la communauté :", "CompilerPath": "Compilateur trouvé : {path}", - "CompressFolderFailed": "Échec de la compression du dossier « {path} » :", "ComputingInstallPlan": "Calcul du plan d’installation...", "ConfigurationErrorRegistriesWithoutBaseline": "La configuration définie dans {path} n’est pas valide.\n\nL’utilisation de registres nécessite qu’une ligne de base soit définie pour le Registre par défaut ou que le Registre par défaut soit null.\n\nPour plus d’informations, consultez {url}.", "ConfigurationNestedDemands": "[\"{json_field}\"] contient un objet `demands` imbriqué (les `demands` imbriqués n’ont aucun effet)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "Impossible de déduire l’ID nuget et la version à partir du nom de fichier : {path}", "CouldNotFindBaselineInCommit": "Base de référence introuvable dans {url} à {commit_sha} pour {package_name}.", "CouldNotFindGitTreeAtCommit": "impossible de trouver l’arborescence Git pour « versions » dans le dépôt {package_name} à la validation {commit_sha}", - "CouldNotFindToolVersion": "Impossible de trouver dans {path}", "CouldNotFindVersionDatabaseFile": "Fichier de base de données de versions introuvable : {path}", "CreateFailureLogsDir": "Création du répertoire de sortie des journaux d’échecs {path}.", "CreatedNuGetPackage": "Nupkg créé : {path}", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "Création du package NuGet...", "CreatingZipArchive": "Création de l’archive zip...", "CreationFailed": "Échec de la création de {path}.", + "CurlFailedGeneric": "Échec de l’opération curl avec le code d’erreur {exit_code}.", "CurlFailedToPut": "Curl n’a pas pu placer le fichier dans {url} avec le code de sortie {exit_code}.", "CurlFailedToPutHttp": "Curl n’a pas pu placer le fichier dans {url} avec le code de sortie {exit_code} et le code http {value}.", - "CurlResponseTruncatedRetrying": "curl a renvoyé une réponse partielle, en attente de {value} millisecondes et réessayer", - "CurlTimeout": "curl n’a pas pu effectuer toutes les opérations HTTP demandées, même après les nouvelles tentatives et délai d’expiration. La dernière ligne de commande était : {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "curl n’a pas pu retourner le nombre attendu de codes de sortie ; cela peut se produire si une boucle se termine avant la fin de l’opération. Curl s’est arrêté avec {exit_code} qui est normalement le code de résultat de la dernière opération, mais peut être le résultat d’un incident. La ligne de commande a été {command_line} et toutes les sorties sont ci-dessous :", "CurrentCommitBaseline": "Vous pouvez utiliser la commit actuelle comme ligne de base, c’est-à-dire :\n\t« builtin-baseline » : « {commit_sha} »", "CycleDetectedDuring": "cycle détecté pendant {spec} :", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "La variable d’environnement VCPKG_DEFAULT_BINARY_CACHE doit être un répertoire (était : {path})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "les DLL sont relatives à ${{CURRENT_PACKAGES_DIR}} ici", "DocumentedFieldsSuggestUpdate": "S’il s’agit de champs documentés qui doivent être reconnus, essayez de mettre à jour l’outil vcpkg.", "DownloadAvailable": "Une copie téléchargeable de cet outil est disponible et peut être utilisée en désépinglant {env_var}.", - "DownloadFailedCurl": "{url} : échec du téléchargement de curl avec le code de sortie {exit_code}", - "DownloadFailedHashMismatch": "Le fichier n’a pas le hachage attendu :\nURL : {url}\nFichier : {path}\nHachage attendu : {expected}\nHachage réel : {actual}", - "DownloadFailedProxySettings": "Nous n’avons pas pu télécharger {path}.\nSi vous utilisez un proxy, veuillez vérifier que vos paramètres de proxy sont corrects.\nLes causes possibles sont les suivantes :\n1. Vous utilisez en fait un proxy HTTP, mais vous avez défini la variable HTTPS_PROXY sur `https//address:port`.\nCeci n’est pas correct, car le préfixe `https://` demande que le proxy soit un proxy HTTPS, alors que votre proxy (v2ray, shadowsocksr, etc.) est un proxy HTTP.\nEssayez plutôt de définir `http://address:port` sur HTTP_PROXY et sur HTTPS_PROXY.\n2. Si vous utilisez Windows, vcpkg utilise automatiquement vos paramètres de proxy Windows IE définis par votre logiciel de proxy. Voir, {url}\nIl est possible que la valeur définie par votre proxy soit incorrecte ou a le même problème de préfixe `https://`.\n3. Le serveur distant de votre proxy est hors service.\nSi vous avez essayé de télécharger directement le lien et que vous pensez qu’il ne s’agit pas d’une défaillance du serveur de téléchargement temporaire, soumettez un problème à https://github.com/Microsoft/vcpkg/issues\npour signaler cette défaillance du serveur de téléchargement en amont.", - "DownloadFailedRetrying": "Échec du téléchargement – nouvelle tentative après {value} ms", + "DownloadFailedHashMismatch": "le téléchargement à partir de {url} a un hachage inattendu", + "DownloadFailedHashMismatchActualHash": "Réel : {sha}", + "DownloadFailedHashMismatchExpectedHash": "Attendu : {sha}", + "DownloadFailedHashMismatchZero": "échec du téléchargement, car le SHA512 attendu était tous les zéros. Remplacez le SHA512 attendu par : {sha}", + "DownloadFailedProxySettings": "Si vous utilisez un proxy, veuillez vérifier que vos paramètres de proxy sont corrects.\nLes causes possibles sont les suivantes :\n1. Vous utilisez en fait un proxy HTTP, mais vous avez défini la variable HTTPS_PROXY sur `https//address:port`.\nCela n’est pas correct, car le préfixe `https://` indique que le proxy est HTTPS, alors que votre proxy (v2ray, shadowsocksr, etc.) est HTTP.\nEssayez plutôt de définir `http://address:port` sur HTTP_PROXY et HTTPS_PROXY.\n2. Si vous utilisez Windows, vcpkg utilise automatiquement vos paramètres de proxy Windows IE définis par votre logiciel de proxy. Consultez : https://github.com/microsoft/vcpkg-tool/pull/77\nIl est possible que la valeur définie par votre proxy soit incorrecte ou a le même problème de préfixe `https://`.\n3. Le serveur distant de votre proxy est hors service.\nSi vous pensez qu’il ne s’agit pas d’une défaillance temporaire du serveur de téléchargement et que vcpkg doit être modifié pour télécharger ce fichier à partir d’un autre emplacement, veuillez soumettre le problème sur la page https://github.com/Microsoft/vcpkg/issues", + "DownloadFailedRetrying": "Échec du téléchargement de {url} -- nouvelle tentative après {value} ms", "DownloadFailedStatusCode": "{url} : échec : code d’état {value}", + "DownloadOrUrl": "ou {url}", "DownloadRootsDir": "Répertoire de téléchargements (par défaut : {env_var})", - "DownloadSuccesful": "Le chargement de {path} est correct.", - "DownloadWinHttpError": "{url} : {system_api} a échoué avec le code de sortie {exit_code}", + "DownloadSuccesful": "Le téléchargement de {path} est correct", + "DownloadSuccesfulUploading": "Téléchargement réussi {path}, stockage dans {url}", + "DownloadTryingAuthoritativeSource": "Tentative de {url}", + "DownloadWinHttpError": "{url} : {system_api} a échoué avec le code de sortie {exit_code}.", "DownloadedSources": "Sources téléchargées pour {spec}", + "DownloadingAssetShaToFile": "Téléchargement de l’entrée de cache de ressources {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "demande de téléchargement de l’entrée de cache de ressources {sha} -> {path}, mais aucun cache de ressources n’est configuré", + "DownloadingFile": "Téléchargement de {path}", + "DownloadingFileFirstAuthoritativeSource": "Téléchargement de {path}, tentative {url}", "DownloadingPortableToolVersionX": "Une version appropriée de {tool_name} est introuvable (version requise v{version}).", - "DownloadingUrl": "Téléchargement de {url}", + "DownloadingUrlToFile": "Téléchargement de {url} -> {path}", "DownloadingVcpkgStandaloneBundle": "Téléchargement de l’offre groupée autonome {version}.", "DownloadingVcpkgStandaloneBundleLatest": "Téléchargement de la dernière offre groupée autonome.", + "DuplicateDependencyOverride": "{package_name} a déjà un remplacement", "DuplicatePackagePattern": "Le package « {package_name} » est dupliqué.", "DuplicatePackagePatternFirstOcurrence": "Première déclaration dans :", "DuplicatePackagePatternIgnoredLocations": "Les redéclarations suivantes seront ignorées :", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "L’option --{option} n’est pas prise en charge en mode classique et aucun manifeste n’a été trouvé.", "ErrorInvalidExtractOption": "--{option} doit être défini sur un entier non négatif ou 'AUTO'.", "ErrorInvalidManifestModeOption": "L’option --{option} n’est pas prise en charge en mode manifeste.", + "ErrorManifestMustDifferFromOverlay": "Le répertoire du manifeste ({path}) ne peut pas être identique à un répertoire configuré dans des ports de superposition.", + "ErrorManifestMustDifferFromOverlayDot": "Le répertoire du manifeste ne peut pas être le même qu’un répertoire configuré dans les ports de superposition. Par conséquent, les valeurs « overlay-ports » ne peuvent pas être « . ».", "ErrorMissingVcpkgRoot": "Impossible de détecter vcpkg-root. Si vous essayez d’utiliser une copie de vcpkg que vous avez créée, vous devez définir la variable d’environnement VCPKG_ROOT pour qu’elle pointe vers une copie clonée de https://github.com/Microsoft/vcpkg.", "ErrorNoVSInstance": "Dans le {triplet} triplet : l’instance de Visual Studio valide est introuvable.", "ErrorNoVSInstanceAt": "à \"{path}\"", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "Échec de l’analyse de {path}, tableau « versions » attendu.", "FailedToParseSerializedBinParagraph": "[vérification de l’intégrité] Échec de l’analyse d’un paragraphe binaire sérialisé.\nOuvrez un problème à https://github.com/microsoft/vcpkg, avec la sortie suivante :\n{error_msg}\nparagraphe binaire sérialisé :", "FailedToParseVersionFile": "Échec de l’analyse du fichier de version : {chemin}", - "FailedToParseVersionXML": "Impossible d’analyser la version de l’outil {tool_name}. La chaîne de version était : {version}", "FailedToRunToolToDetermineVersion": "Impossible d’exécuter {path} pour déterminer la version {tool_name}.", "FailedToStoreBackToMirror": "Échec du stockage de {path} dans {url}.", "FailedToStoreBinaryCache": "Échec du stockage du cache binaire {path}", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "Récupération des informations de Registre à partir de {url} ({value})...", "FieldKindDidNotHaveExpectedValue": "« genre » n’a pas de valeur attendue : (valeur attendue : {expected} ; trouvé {actual})", "FileIsNotExecutable": "ce fichier ne semble pas exécutable", - "FileNotFound": "{path} : fichier introuvable", + "FileNotFound": "fichier introuvable", "FileReadFailed": "Échec de la lecture de {count} octets à partir de {path} au décalage {byte_offset}.", "FileSeekFailed": "Échec de la recherche de la position {byte_offset} dans {path}.", "FilesContainAbsolutePath1": "Il ne doit y avoir aucun chemin absolu, tel que le suivant, dans un package installé : Pour supprimer ce message, ajoutez set (VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK activé)", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "état de fichier inconnu : {value}", "GitUnexpectedCommandOutputCmd": "git a produit une sortie inattendue lors de l’exécution de {command_line}", "GraphCycleDetected": "Cycle détecté dans le graphique à {package_name} :", - "HashFileFailureToRead": "échec de la lecture du fichier « {chemin} »pour le hachage : ", "HashPortManyFiles": "{package_name} contient {count} fichiers. Le hachage de ces contenus peut prendre beaucoup de temps lors de la détermination du hachage ABI pour la mise en cache binaire. Envisagez de réduire le nombre de fichiers. Les causes courantes de cette erreur sont l’extraction accidentelle de fichiers sources ou de builds dans le répertoire d’un port.", "HeaderOnlyUsage": "{package_name} est en-tête uniquement et peut être utilisé à partir de CMake via :", "HelpAssetCaching": "**Fonctionnalité expérimentale : peut changer ou être supprimée à tout moment**\n\nvcpkg peut utiliser des miroirs pour mettre en cache les ressources téléchargées, ce qui garantit la poursuite de l’opération même si la source d’origine change ou disparaît.\n\nLa mise en cache des ressources peut être configurée en définissant la variable d’environnement X_VCPKG_ASSET_SOURCES sur une liste de sources délimitée par des points-virgules ou en passant une séquence d’options de ligne de commande --x-asset-sources=. Les sources de ligne de commande sont interprétées après les sources d’environnement. Les virgules, les points-virgules et les apostrophes inverses peuvent être placés dans une séquence d’échappement à l’aide d’un backtick (').\n\nLe paramètre facultatif pour certaines chaînes contrôle la manière dont elles sont accessibles. Il peut être spécifié en tant que « read », « write » ou « readwrite » et sa valeur par défaut est « read ».\n\nSources valides :", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "Échoue si les fichiers binaires mis en cache ne sont pas disponibles", "HelpTxtOptOnlyDownloads": "Fait le meilleur effort pour essayer de télécharger des sources sans générer", "HelpTxtOptRecurse": "Autorise la suppression des packages dans le cadre de l’installation", - "HelpTxtOptUseAria2": "Utilise aria2 pour effectuer des tâches de téléchargement", "HelpTxtOptUseHeadVersion": "Installe les bibliothèques sur la ligne de commande à l’aide des dernières sources en amont (mode classique)", "HelpTxtOptWritePkgConfig": "Écrit un fichier nuGet au format packages.config à utiliser avec la mise en cache binaire externe. Pour plus d’informations, consultez « fichier binaire d’aide vcpkg »", "HelpUpdateBaseline": "La meilleure approche pour maintenir vos bibliothèques à jour consiste à mettre à jour votre référence de base. Cela garantira que tous les packages, y compris les packages transitifs, sont mis à jour. Cependant, si vous avez besoin de mettre à jour un package indépendamment, vous pouvez utiliser une contrainte \"version>=\".", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "L’intégration n’a pas été appliquée pour Visual Studio 2015.", "InternalCICommand": "vcpkg ci est une commande interne qui change de façon incompatible ou est supprimée à tout moment.", "InternalErrorMessageContact": "Ouvrez un problème à https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug avec des étapes détaillées pour reproduire le problème.", - "InvalidArchitecture": "architecture non valide : {value}", + "InvalidArchitectureValue": "Architecture non valide : {value}. L’un des éléments attendus est : {expected}", "InvalidArgument": "argument non valide", "InvalidArgumentRequiresAbsolutePath": "argument non valide : les arguments de chemin de la configuration binaire '{binary_source}' pour les chaînes de configuration binaires doivent être absolus", "InvalidArgumentRequiresBaseUrl": "argument non valide : la configuration binaire '{binary_source}' nécessite une URL de base {base_url} comme premier argument", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "expression logique non valide, utilisez « | » plutôt que « or »", "InvalidOptionForRemove": "'remove' accepte les bibliothèques ou '--outdated'", "InvalidPortVersonName": "Nom de fichier de version de port non valide trouvé : '{path}'.", + "InvalidSha512": "hachage SHA-512 non valide : {sha}\nLe hachage SHA-512 doit comporter 128 caractères et contenir uniquement des chiffres hexadécimals", "InvalidSharpInVersion": "caractère « # » non valide dans le texte de version", "InvalidSharpInVersionDidYouMean": "caractère « # » non valide dans le texte de version. Vouliez-vous dire « port-version » : {value} ?", "InvalidString": "Utf8 non valide passé à Value::string(std::string)", + "InvalidToolOSValue": "Système d’exploitation d’outil non valide : {value}. L’un des éléments attendus est : {expected}", + "InvalidToolVersion": "Version d’outil non valide ; chaîne contenant une sous-chaîne comprise entre 1 et 3 nombres séparés par des points.", "InvalidTriplet": "Triplet non valide : {triplet}", "InvalidUri": "Impossible d’analyser l’uri : {valeur}.", "InvalidValueHashAdditionalFiles": "La variable VCPKG_HASH_ADDITIONAL_FILES contient un chemin d’accès au fichier non valide : « {path} ». La valeur doit être un chemin d’accès absolu vers un fichier existant.", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "Le paragraphe binaire sérialisé était différent du paragraphe binaire d’origine. Veuillez ouvrir un problème à https://github.com/microsoft/vcpkg avec la sortie suivante :", "MismatchedFiles": "le fichier à stocker ne correspond pas au hachage.", "MismatchedManifestAfterReserialize": "Le manifeste sérialisé était différent du manifeste d’origine. Ouvrez un problème à l’adresse https://github.com/microsoft/vcpkg, avec la sortie suivante :", - "MismatchedNames": "les noms ne correspondent pas : '{package_name}' != '{actual}'", + "MismatchedNames": "le nom de port déclaré dans le fichier de métadonnées ne correspondait pas au répertoire. Le port doit être nommé {package_name}, mais le fichier déclare {actual}.", "MismatchedSpec": "Spécifications incompatibles dans le port {path} : {expected} attendu, {actual} réel", "MismatchedType": "{json_field} : type incompatible : {json_type} attendu", "Missing7zHeader": "En-tête 7z introuvable.", "MissingAndroidEnv": "Variable d’environnement ANDROID_NDK_HOME manquante", "MissingAndroidHomeDir": "Le répertoire ANDROID_NDK_HOME n’existe pas : {path}", "MissingArgFormatManifest": "--convert-control a été transmis à format-manifest sans « --all ».\nCela n’est pas nécessaire : les fichiers de contrôle transmis explicitement sont convertis automatiquement.", - "MissingAssetBlockOrigin": "Les {path} manquants et les téléchargements sont bloqués par x-block-origin.", "MissingClosingParen": "fermeture manquante )", "MissingDependency": "Le package {spec} est installé, mais la dépendance {package_name} ne l’est pas.", "MissingExtension": "Extension de '{extension}' manquante.", @@ -814,7 +841,6 @@ "NoInstalledPackages": "Aucun package n’est installé. Voulez-vous dire `search` ?", "NoOutdatedPackages": "Il n’existe aucun package obsolète.", "NoRegistryForPort": "aucun registre configuré pour le port {package_name}", - "NoUrlsAndHashSpecified": "Aucune URL spécifiée pour télécharger SHA : {sha}", "NoUrlsAndNoHashSpecified": "Aucune URL spécifiée et aucun hachage spécifié.", "NonExactlyArgs": "la commande '{command_name}' requiert exactement {expected} arguments, mais {actual} ont été fournis", "NonOneRemainingArgs": "la commande '{command_name}' requiert exactement un argument", @@ -834,8 +860,8 @@ "Options": "Options", "OriginalBinParagraphHeader": "\nParagraphe binaire d’origine", "OtherCommandsHeader": "Autre", - "OverlayPatchDir": "Le chemin de superposition \"{path}\" doit exister et doit être un répertoire.", - "OverlayPortsDirectoriesHelp": "Répertoires des ports de superposition (également : {env_var})", + "OverlayPatchDir": "Le chemin de superposition \"{path}\" doit être un répertoire existant.", + "OverlayPortsHelp": "Répertoires de port de superposition ou répertoires contenant des répertoires de port de superposition (également : {env_var})", "OverlayTripletDirectoriesHelp": "Répertoires des triplets de superposition (également : {env_var})", "OverlayTriplets": "Superposer les triplets à partir de {path} :", "OverwritingFile": "Le fichier {path} était déjà présent et sera remplacé", @@ -927,6 +953,7 @@ "PortsUpdated": "Les {count} ports suivants ont été mis à jour :", "PrebuiltPackages": "Certains packages n’ont pas été générés. Pour les générer, exécutez :", "PreviousIntegrationFileRemains": "Le fichier d’intégration précédent n’a pas été supprimé.", + "ProgramPathReturnedNonzeroExitCode": "échec avec le code de sortie {exit_code}", "ProgramReturnedNonzeroExitCode": "Échec de {tool_name} avec le code de sortie : ({exit_code}).", "ProvideExportType": "Au moins une des options suivantes est requise : --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "Échec de l’envoi de {vendor} à '{path}'. Utilisez --debug pour plus d’informations.", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "Triplet cible. Voir « vcpkg help triplet » (valeur par défaut : {env_var})", "StartCodeUnitInContinue": "unité de code de démarrage trouvée en position continue", "StoreOptionMissingSha": "L’option --store n’est pas valide sans sha512.", - "StoredBinariesToDestinations": "Fichiers binaires stockés dans {count} destinations dans {elapsed}.", + "SubmittingBinaryCacheBackground": "Début de l’envoi de {spec} à {count} cache(s) binaire(s) en arrière-plan", + "SubmittingBinaryCacheComplete": "Fin de l’envoi de {spec} à {count} cache(s) binaire(s) dans {elapsed}", "SuccessfulyExported": "{package_name} exporté vers {path}", "SuggestGitPull": "Le résultat peut être obsolète. Exécutez « git pull » pour obtenir les derniers résultats.", "SuggestStartingBashShell": "Vérifiez que vous avez démarré un nouvel interpréteur de commandes Bash pour que la modification prenne effet.", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "échec de l’installation du fichier de cibles système sur {path}", "ToRemovePackages": "Pour supprimer uniquement les packages obsolètes, exécutez\n{command_name} supprimer --outdated", "ToUpdatePackages": "Pour mettre à jour ces packages et toutes les dépendances, exécutez\n{command_name} la mise à niveau'", + "ToolDataFileSchemaVersionNotSupported": "version de schéma de document {version} n’est pas prise en charge par cette version de vcpkg", "ToolFetchFailed": "Impossible de récupérer les {tool_name}.", + "ToolHashMismatch": "{tool_name} semble être déjà téléchargé, mais son hachage est incorrect. {expected} attendu mais {actual}", "ToolInWin10": "Cet utilitaire est fourni avec Windows 10 ou une version ultérieure.", "ToolOfVersionXNotFound": "Une version appropriée de {tool_name} est introuvable (v{version} requise) et ne peut pas télécharger automatiquement une version portable. Installez une version plus récente de {tool_name}", "TotalInstallTime": "Temps total de l’installation : {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "Registre '{url}' mis à jour : base de référence '{old_value}' -> '{new_value}'", "UpgradeInManifest": "La mise à niveau met à niveau une installation en mode classique et ne prend donc pas en charge le mode manifeste. Envisagez de mettre à jour vos dépendances en mettant à jour votre base de référence avec une valeur actuelle avec vcpkg x-update-baseline et en exécutant l’installation de vcpkg.", "UpgradeRunWithNoDryRun": "Si vous voulez vraiment régénérer les packages ci-dessus, exécutez cette commande avec l’option --no-dry-run.", - "UploadingBinariesToVendor": "Chargement des fichiers binaires de '{spec}' vers '{vendor}' '{path}' source.", + "UploadingBinariesToVendor": "Chargement des fichiers binaires pour {spec} à {vendor} à partir de {path}", "UsageInstallInstructions": "vous pouvez installer le fichier d’utilisation avec le fichier CMake suivant", "UsageTextHere": "le fichier d’utilisation est ici", "UseEnvVar": "-- Utilisation de {env_var} dans les variables d’environnement.", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "{package_name} est affecté {actual}, mais le port local est {expected}", "VersionBuiltinPortTreeEntryMissing": "aucune entrée de base de données de version pour {package_name} à {expected} ; à l’aide de la version extraite de l’arborescence des ports ({actual}).", "VersionCommandHeader": "version du programme de gestion de package vcpkg {version}\n\nPour plus d’informations sur la licence, consultez LICENSE.txt.", - "VersionConflictXML": "La version {path} devait être : [{expected_version}], mais elle était [{actual_version}]. Veuillez réexécuter bootstrap-vcpkg.", "VersionConstraintNotInDatabase1": "la contrainte \"version>=\" vers {package_name} nomme la version {version} qui n’existe pas dans la base de données des versions. Toutes les versions doivent exister dans la base de données de versions pour être interprétées par vcpkg.", "VersionConstraintNotInDatabase2": "supprimez la contrainte de version ou choisissez une valeur déclarée ici", "VersionConstraintOk": "toutes les contraintes de version sont cohérentes avec la base de données de versions", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "« # » dans le texte de version doit être suivi d’une version de port (entier non négatif)", "VersionSpecMismatch": "Échec du chargement du port, car les versions sont incohérentes. Le fichier \"{path}\" contient la version {actual_version}, mais la base de données de versions indique qu’il doit être {expected_version}.", "VersionVerifiedOK": "{version_spec} est correctement dans la base de données de versions ({git_tree_sha})", + "WaitUntilPackagesUploaded": "En attente de {count} soumissions restantes du cache binaire...", "WaitingForChildrenToExit": "En attente de la fermeture des processus enfants...", "WaitingToTakeFilesystemLock": "en attente du verrouillage du système de fichiers sur {path}...", "WarnOnParseConfig": "J'ai trouvé les avertissements suivants dans la configuration {path} :", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "pendant le chargement {version_spec}", "WhileLookingForSpec": "lors de la recherche de {spec} :", "WhileParsingVersionsForPort": "lors de l’analyse des versions de {package_name} à partir de {path}", + "WhileRunningAssetCacheScriptCommandLine": "lors de l’exécution de la ligne de commande du script du cache de ressources", "WhileValidatingVersion": "lors de la validation de la version : {version}", "WindowsOnlyCommand": "Cette commande prend uniquement en charge Windows.", "WroteNuGetPkgConfInfo": "A écrit les informations de configuration du package NuGet dans {path}", diff --git a/locales/messages.it.json b/locales/messages.it.json index 60c4299f3d..637366d28a 100644 --- a/locales/messages.it.json +++ b/locales/messages.it.json @@ -4,6 +4,7 @@ "ABoolean": "un valore booleano", "ABuiltinRegistry": "un registro incorporato", "AConfigurationObject": "un oggetto di configurazione", + "ACpuArchitecture": "un'architettura CPU", "ADateVersionString": "una stringa versione della data", "ADefaultFeature": "una funzionalità predefinita", "ADemandObject": "un oggetto richiesta", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "una stringa versione rilassata", "ASemanticVersionString": "una stringa versione semantica", "ASetOfFeatures": "un set di funzionalità", + "ASha512": "hash SHA-512", "AString": "una stringa", "AStringOrArrayOfStrings": "una stringa di array di stringhe", "AStringStringDictionary": "una \"stringa\": dizionario \"stringa\"", + "AToolDataArray": "una matrice di metadati dello strumento", + "AToolDataFile": "un file di dati dello strumento", + "AToolDataOS": "un sistema operativo per i dati degli strumenti", + "AToolDataObject": "metadati dello strumento", + "AToolDataVersion": "una versione dei dati dello strumento", "AUrl": "un url", "AVcpkgRepositoryCommit": "un commit del repository vcpkg", "AVersionConstraint": "un vincolo di versione", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "Forza il rilevamento host in Windows durante l'acquisizione di artefatti", "ArtifactsSwitchX64": "Forza il rilevamento dell'host su x64 durante l'acquisizione di artefatti", "ArtifactsSwitchX86": "Forza il rilevamento host su x86 durante l'acquisizione di artefatti", - "AssetCacheHit": "Riscontro nella cache degli asset per {path}; è stato eseguito il download da: {url}", - "AssetCacheMiss": "Mancato riscontro nella cache degli asset; è in corso il download da {url}", - "AssetCacheMissBlockOrigin": "Mancato riscontro nella cache degli asset per {path} e i download sono stati bloccati da x-block-origin.", + "AssetCacheConsult": "Tentativo di scaricare {path} usando la cache degli asset {url}", + "AssetCacheConsultScript": "Tentativo di scaricare {path} usando lo script della cache degli asset", + "AssetCacheHit": "Download completato. Riscontro nella cache degli asset.", + "AssetCacheHitUrl": "Download completato. Riscontro nella cache degli asset. L'origine autorevole non è stata provata {url}", + "AssetCacheMiss": "Mancati riscontri nella cache degli asset; tentativo di {url} di origine autorevole", + "AssetCacheMissBlockOrigin": "non sono stati rilevati riscontri nella cache degli asset e i blocchi x-block-origin stanno tentando l'origine autorevole {url}", + "AssetCacheMissNoUrls": "La cache degli asset non ha cercato {sha} e non è noto alcun URL autorevole", "AssetCacheProviderAcceptsNoArguments": "argomenti imprevisti: '{value}' non accetta argomenti", - "AssetCacheSuccesfullyStored": "L’archiviazione di {path} in {url} è stata completata.", + "AssetCacheScriptBadVariable": "il modello di script {value} contiene {list} di sostituzione sconosciute", + "AssetCacheScriptBadVariableHint": "se lo si desidera nella riga di comando del valore letterale, usare {{{{{list}}}}}", + "AssetCacheScriptCommandLine": "la riga di comando per lo script completo è stata", + "AssetCacheScriptFailed": "lo script della cache degli asset ha restituito codice di uscita diverso da zero {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "lo script della cache degli asset ha restituito esito positivo, ma il file risultante ha un hash imprevisto", + "AssetCacheScriptFailedToWriteFile": "lo script della cache degli asset ha restituito esito positivo ma non ha creato il file di risultati previsto", + "AssetCacheScriptNeedsSha": "il modello di script {value} richiede un SHA, ma nessun sha è noto per il tentativo di download di {url}", + "AssetCacheScriptNeedsUrl": "il modello di script {value} richiede un URL, ma nessun URL è noto per il tentativo di download di {sha}", + "AssetCacheSuccesfullyStored": "Store riuscito", "AssetSourcesArg": "Origini di memorizzazione nella cache degli asset. Vedere \"memorizzazione nella cache asset guida vcpkg\"", "AttemptingToSetBuiltInBaseline": "tentativo di impostare builtin-baseline in vcpkg.json durante l'override del registro di sistema predefinito in vcpkg-configuration.json.\nVerrà usato il registro di sistema predefinito da vcpkg-configuration.json.", "AuthenticationMayRequireManualAction": "Uno o più provider di credenziali {vendor} hanno richiesto un'azione manuale. Aggiungere l'origine binaria 'interactive' per consentire l'interattività.", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "Numero di directory iniziali da rimuovere da tutti i percorsi", "CommandEnvExample2": "vcpkg env \"ninja -C \" --triplet x64-windows", "CommandFailed": "comando:\n{command_line}\nnon riuscito con l'output seguente:", - "CommandFailedCode": "comando:\n{command_line}\nnon riuscito con codice di uscita {exit_code} e l'output seguente:", "CommunityTriplets": "Triplette della community:", "CompilerPath": "Compilatore trovato: {path}", - "CompressFolderFailed": "Impossibile comprimere la cartella “{path}”:", "ComputingInstallPlan": "Elaborazione del piano di installazione in corso...", "ConfigurationErrorRegistriesWithoutBaseline": "La configurazione definita in {path} non è valida.\n\nL'uso dei registri richiede che sia impostata una baseline per il Registro di sistema predefinito o che il Registro di sistema predefinito sia Null.\n\nPer altri dettagli, vedere {url}.", "ConfigurationNestedDemands": "[\"{json_field}\"] contiene un oggetto 'demands' annidato (gli oggetti 'demands' annidati non hanno effetto)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "Non è stato possibile dedurre l'ID NuGet e la versione dal nome file: {path}", "CouldNotFindBaselineInCommit": "Non è stato possibile trovare la baseline in {url} alle {commit_sha} per {package_name}.", "CouldNotFindGitTreeAtCommit": "non è stato possibile trovare l'albero GIT per 'versions' nel repository {package_name} nel commit {commit_sha}", - "CouldNotFindToolVersion": "Non è stato possibile trovare in {path}", "CouldNotFindVersionDatabaseFile": "Non è statp possibile trovare il file di database delle versioni: {path}", "CreateFailureLogsDir": "Creazione della directory di output {path} dei log degli errori.", "CreatedNuGetPackage": "Nupkg creato: \"{path}”", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "Creazione del pacchetto NuGet in corso...", "CreatingZipArchive": "Creazione dell'archivio ZIP in corso...", "CreationFailed": "Non è stato possibile completare la creazione di {path}.", + "CurlFailedGeneric": "Operazione curl non riuscita con codice di errore {exit_code}.", "CurlFailedToPut": "curl non è riuscito a inserire il file in {url} con il codice di uscita {exit_code}.", "CurlFailedToPutHttp": "curl non è riuscito a inserire il file in {url} con il codice di uscita {exit_code} e codice HTTP {value}.", - "CurlResponseTruncatedRetrying": "curl ha restituito una risposta parziale; in attesa di {value} millisecondi e riprovare", - "CurlTimeout": "curl non è riuscito a eseguire tutte le operazioni HTTP richieste, anche dopo timeout e tentativi. Ultima riga di comando: {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "curl non è riuscito a restituire il numero previsto di codici di uscita; questo problema può verificarsi se un elemento termina arricciato prima del completamento. curl chiuso con {exit_code} che è in genere il codice risultato per l'ultima operazione, ma potrebbe essere il risultato di un arresto anomalo del sistema. La riga di comando è stata {command_line} e l'output è riportato di seguito:", "CurrentCommitBaseline": "È possibile usare il commit corrente come baseline, ovvero:\n\t\"builtin-baseline\": \"{commit_sha}\"", "CycleDetectedDuring": "ciclo rilevato durante {spec}:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "La variabile di ambiente VCPKG_DEFAULT_BINARY_CACHE deve essere una directory (è: {path})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "le DLL sono relative a ${{CURRENT_PACKAGES_DIR}} qui", "DocumentedFieldsSuggestUpdate": "Se si tratta di campi documentati che devono essere riconosciuti, provare ad aggiornare lo strumento vcpkg.", "DownloadAvailable": "Una copia scaricabile di questo strumento è disponibile e può essere usata annullando {env_var}.", - "DownloadFailedCurl": "{url}: curl non è riuscito a eseguire il download. Codice di uscita: {exit_code}", - "DownloadFailedHashMismatch": "Il file non ha l'hash previsto:\nURL: {url}\nFile: {path}\nHash previsto: {expected}\nHash effettivo: {actual}", - "DownloadFailedProxySettings": "Non è stato possibile scaricare {path}.\nSe si usa un proxy, assicurarsi che le impostazioni del proxy siano corrette.\nLe possibili cause sono:\n1. Si sta effettivamente usando un proxy HTTP, ma si sta impostando la variabile HTTPS_PROXY su 'https//address:port'.\nQuesto non è corretto perché il prefisso 'https://' richiede che il proxy sia un proxy HTTPS, mentre il proxy (v2ray, shadowsocksr e così via) è un proxy HTTP.\nProvare a impostare 'http://address:port’ sia su HTTP_PROXY che su HTTPS_PROXY.\n2. Se si usa Windows, vcpkg userà automaticamente le impostazioni proxy di Internet Explorer di Windows impostate dal software proxy. Vedere {url}\nIl valore impostato dal proxy potrebbe essere errato o avere lo stesso problema con il prefisso 'https://'.\n3. Il server remoto del proxy è il nostro servizio.\nSe si è provato a scaricare direttamente il collegamento e si ritiene che non si tratti di un errore temporaneo nel server di download, inviare un ticket all'indirizzo https://github.com/Microsoft/vcpkg/issues\nal fine di segnalare questo errore del server di download upstream.", - "DownloadFailedRetrying": "Download non riuscito. Nuovo tentativo dopo {value}ms", + "DownloadFailedHashMismatch": "il download da {url} ha un hash imprevisto", + "DownloadFailedHashMismatchActualHash": "Effettivo : {sha}", + "DownloadFailedHashMismatchExpectedHash": "Previsto: {sha}", + "DownloadFailedHashMismatchZero": "il download non è riuscito perché l'sha512 previsto era tutti zeri. Modificare l'sha512 previsto in: {sha}", + "DownloadFailedProxySettings": "Se si usa un proxy, assicurarsi che le impostazioni del proxy siano corrette.\nLe cause possibili sono:\n1. Si usa effettivamente un proxy HTTP, ma si imposta la variabile HTTPS_PROXY su 'https//address:port'.\nCiò non è corretto perché il prefisso 'https://' richiede che il proxy sia un proxy HTTPS, mentre il proxy (v2ray, shadowsocksr e così via) è un proxy HTTP.\nProvare a impostare 'http://address:port’ sia su HTTP_PROXY che su HTTPS_PROXY.\n2. Se si usa Windows, vcpkg userà automaticamente le impostazioni proxy di Internet Explorer di Windows impostate dal software proxy. Vedere: https://github.com/microsoft/vcpkg-tool/pull/77\nIl valore impostato dal proxy potrebbe essere errato o avere lo stesso problema con il prefisso 'https://'.\n3. Il server remoto del proxy è fuori servizio.\nSe si ritiene che non si tratti di un errore temporaneo del server di download e vcpkg deve essere modificato per scaricare questo file da un percorso diverso, inviare un problema a https://github.com/Microsoft/vcpkg/issues", + "DownloadFailedRetrying": "Download {url} non riuscito -- nuovo tentativo dopo {value} ms", "DownloadFailedStatusCode": "{url}: non riuscito: codice di stato {value}", + "DownloadOrUrl": "o {url}", "DownloadRootsDir": "Scarica la directory (impostazione predefinita: {env_var})", - "DownloadSuccesful": "Download completato di {path}.", - "DownloadWinHttpError": "{url}: {system_api} non riuscito con codice di uscita {exit_code}", + "DownloadSuccesful": "Download completato {path}", + "DownloadSuccesfulUploading": "Download {path} completato. Archiviazione in {url}", + "DownloadTryingAuthoritativeSource": "Tentativo di {url}", + "DownloadWinHttpError": "{url}: {system_api} non riuscito con codice di uscita {exit_code}.", "DownloadedSources": "Origini scaricate per {spec}", + "DownloadingAssetShaToFile": "Download della voce della cache degli asset {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "è stato richiesto il download della voce della cache degli asset {sha} -> {path}, ma non sono configurate cache degli asset", + "DownloadingFile": "Download {path}", + "DownloadingFileFirstAuthoritativeSource": "Download {path}, tentativo di {url}", "DownloadingPortableToolVersionX": "Non è stata trovata una versione appropriata di {tool_name} (versione richiesta v{version}).", - "DownloadingUrl": "Download di {url}", + "DownloadingUrlToFile": "Download di {url} -> {path}", "DownloadingVcpkgStandaloneBundle": "Download del bundle autonomo {version}.", "DownloadingVcpkgStandaloneBundleLatest": "Download del bundle autonomo più recente.", + "DuplicateDependencyOverride": "{package_name} ha già un override", "DuplicatePackagePattern": "Il pacchetto \"{package_name}\" è duplicato.", "DuplicatePackagePatternFirstOcurrence": "Primo elemento dichiarato in:", "DuplicatePackagePatternIgnoredLocations": "Le dichiarazioni seguenti verranno ignorate:", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "L'opzione --{option} non è supportata nella modalità classica e non è stato trovato alcun manifesto.", "ErrorInvalidExtractOption": "--{option} deve essere impostato su un numero intero non negativo o su 'AUTO'.", "ErrorInvalidManifestModeOption": "L'opzione --{option} non è supportata nella modalità manifesto.", + "ErrorManifestMustDifferFromOverlay": "La directory del manifesto ({path}) non può essere uguale a una directory configurata nelle porte di sovrapposizione.", + "ErrorManifestMustDifferFromOverlayDot": "La directory del manifesto non può essere uguale a una directory configurata nelle porte di overlay, quindi i valori \"overlay-ports\" non possono essere \".\".", "ErrorMissingVcpkgRoot": "Impossibile rilevare vcpkg-root. Se si sta tentando di usare una copia di vcpkg che si ha creato, è necessario definire la variabile di ambiente VCPKG_ROOT in modo che punti a una copia clonata di https://github.com/Microsoft/vcpkg.", "ErrorNoVSInstance": "nella tripla {triplet}: non è possibile trovare un'istanza di Visual Studio valida", "ErrorNoVSInstanceAt": "in \"{path}\"", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "Non è stato possibile analizzare {path}, previsto un array 'versions'.", "FailedToParseSerializedBinParagraph": "[controllo integrità] Non è stato possibile analizzare un paragrafo binario serializzato.\nAprire un problema in https://github.com/microsoft/vcpkg con l'output seguente:\n{error_msg}\nParagrafo binario serializzato:", "FailedToParseVersionFile": "Non è possibile analizzare il file di versione: {path}", - "FailedToParseVersionXML": "Non è stato possibile analizzare la versione per lo strumento {tool_name}. Stringa della versione: {version}", "FailedToRunToolToDetermineVersion": "Non è stato possibile eseguire {path} per determinare la versione {tool_name}.", "FailedToStoreBackToMirror": "Non è stato possibile archiviare {path} in {url}.", "FailedToStoreBinaryCache": "Non è stato possibile archiviare la cache binaria {path}", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "Recupero delle informazioni del Registro di sistema da {url} ({value})...", "FieldKindDidNotHaveExpectedValue": "\"kind\" non contiene un valore previsto: (valore previsto: {expected}; trovato {actual})", "FileIsNotExecutable": "questo file non sembra essere eseguibile", - "FileNotFound": "{path}: file non trovato", + "FileNotFound": "file non trovato", "FileReadFailed": "Non è stato possibile leggere {count} byte da {path} all'offset {byte_offset}.", "FileSeekFailed": "Impossibile scorrere alla posizione {byte_offset} in {path}.", "FilesContainAbsolutePath1": "In un pacchetto installato non deve essere presente alcun percorso assoluto, ad esempio il seguente. Per eliminare questo messaggio, aggiungere set (VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK abilitato)", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "stato file sconosciuto: {value}", "GitUnexpectedCommandOutputCmd": "git ha prodotto un output imprevisto durante l'esecuzione di {command_line}", "GraphCycleDetected": "Ciclo rilevato nel grafico in {package_name}:", - "HashFileFailureToRead": "non è stato possibile leggere il file \"{path}\" per l'hashing: ", "HashPortManyFiles": "Il pacchetto {package_name} contiene {count} file. L'hashing di questi contenuti può richiedere molto tempo quando si determina l'hash ABI per la memorizzazione nella cache binaria. Provare a ridurre il numero di file. Cause comuni di questo errore sono l'estrazione accidentale dei file di origine o di compilazione nella directory di una porta.", "HeaderOnlyUsage": "{package_name} è di sola intestazione e può essere usato da CMake tramite:", "HelpAssetCaching": "**Funzionalità sperimentale: questa opzione può essere modificata o rimossa in qualsiasi momento**\n\nvcpkg può usare i mirror per memorizzare nella cache le risorse scaricate, garantendo un funzionamento continuo anche se l'origine originale cambia o scompare.\n\nÈ possibile configurare la memorizzazione nella cache delle risorse impostando la variabile di ambiente X_VCPKG_ASSET_SOURCES su un elenco di origini delimitate da punti e virgola o passando una sequenza di opzioni --x-asset-sources= della riga di comando. Le origini della riga di comando vengono interpretate dopo le origini dell'ambiente. Le virgole, i punti e virgola e i backtick possono essere preceduti da un carattere di escape con backtick (').\n\nIl parametro facoltativo per alcune stringhe controlla la modalità di accesso. Può essere specificato come \"read\", \"write\" o \"readwrite\" e il valore predefinito è \"read\".\n\nOrigini valide:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "Non riesce se i file binari memorizzati nella cache non sono disponibili", "HelpTxtOptOnlyDownloads": "Effettua il massimo tentativo di scaricare le origini senza creare", "HelpTxtOptRecurse": "Consente la rimozione dei pacchetti come parte dell'installazione", - "HelpTxtOptUseAria2": "Usa aria2 per eseguire attività di download", "HelpTxtOptUseHeadVersion": "Installa le librerie nella riga di comando usando le origini upstream più recenti (modalità classica)", "HelpTxtOptWritePkgConfig": "Scrive un file in formato NuGet packages.config da usare con la memorizzazione nella cache binaria esterna. Per altre informazioni, vedere 'vcpkg help binarycaching'", "HelpUpdateBaseline": "L'approccio migliore per mantenere aggiornate le librerie consiste nell'aggiornare il riferimento della baseline. In questo modo tutti i pacchetti, inclusi quelli transitivi, verranno aggiornati. Tuttavia, se è necessario aggiornare un pacchetto in modo indipendente, è possibile usare un vincolo \"version>=\".", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "L'integrazione non è stata applicata per Visual Studio 2015.", "InternalCICommand": "vcpkg ci è un comando interno che cambia in modo incompatibile o viene rimosso in qualsiasi momento.", "InternalErrorMessageContact": "Apri un problema in https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug con passaggi dettagliati per riprodurre il problema.", - "InvalidArchitecture": "architettura non valida: {value}", + "InvalidArchitectureValue": "Architettura non valida: {value}. È previsto uno dei valori seguenti: {expected}", "InvalidArgument": "argomento non valido", "InvalidArgumentRequiresAbsolutePath": "argomento non valido: gli argomenti del percorso di configurazione binaria '{binary_source}' per le stringhe di configurazione binarie devono essere assoluti", "InvalidArgumentRequiresBaseUrl": "argomento non valido: la configurazione binaria '{binary_source}' richiede un URL di base {base_url} come primo argomento", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "espressione logica non valida. Usare '|' anziché 'or'", "InvalidOptionForRemove": "'remove' accetta librerie o '--outdated'", "InvalidPortVersonName": "Trovato nome file della versione della porta non valido: '{path}'.", + "InvalidSha512": "hash SHA-512 non valido: {sha}\nL'hash SHA-512 deve avere una lunghezza di 128 caratteri e contenere solo cifre esadecimali", "InvalidSharpInVersion": "carattere '#' non valido nel testo della versione", "InvalidSharpInVersionDidYouMean": "carattere '#' non valido nel testo della versione. Si intendeva \"port-version\": {value}?", "InvalidString": "Passato utf8 non valido a Value::string(std::string)", + "InvalidToolOSValue": "Il sistema operativo dello strumento non è valido: {value}. È previsto uno dei valori seguenti: {expected}", + "InvalidToolVersion": "Versione dello strumento non valida; è prevista una stringa contenente una sottostringa con una lunghezza compresa tra 1 e 3 numeri separati da punti.", "InvalidTriplet": "Triplet non valido: {triplet}", "InvalidUri": "impossibile analizzare l'URI: {value}", "InvalidValueHashAdditionalFiles": "La variabile VCPKG_HASH_ADDITIONAL_FILES contiene un percorso di file non valido: '{path}'. Il valore deve essere un percorso assoluto di un file esistente.", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "[controllo integrità] Il paragrafo binario serializzato è diverso dal paragrafo binario originale. Aprire un problema in https://github.com/microsoft/vcpkg con l'output seguente:", "MismatchedFiles": "il file da archiviare non corrisponde all'hash", "MismatchedManifestAfterReserialize": "Il manifesto serializzato è diverso dal manifesto originale. Aprire un problema su https://github.com/microsoft/vcpkg, con l’output seguente:", - "MismatchedNames": "nomi non corrispondenti: '{package_name}' != '{actual}'", + "MismatchedNames": "il nome della porta dichiarato nel file di metadati non corrisponde alla directory. È previsto che la porta sia denominata {package_name}, ma il file dichiara {actual}.", "MismatchedSpec": "Specifiche non corrispondenti nella porta {path}: previsto {expected}, effettivo {actual}", "MismatchedType": "{json_field}: tipo non corrispondente: previsto {json_type}", "Missing7zHeader": "Impossibile trovare l'intestazione 7z.", "MissingAndroidEnv": "variabile di ambiente ANDROID_NDK_HOME mancante", "MissingAndroidHomeDir": "La directory ANDROID_NDK_HOME non esiste: {path}", "MissingArgFormatManifest": "format-manifest è stato passato in --convert-control senza '--all'.\nNon viene eseguita alcuna operazione: i file di controllo passati in modo esplicito vengono convertiti automaticamente.", - "MissingAssetBlockOrigin": "{path} e i download mancanti sono stati bloccati da x-block-origin.", "MissingClosingParen": ") di chiusura mancante", "MissingDependency": "Il pacchetto {spec} è installato, ma la dipendenza {package_name} non lo è.", "MissingExtension": "Estensione '{extension}' mancante.", @@ -814,7 +841,6 @@ "NoInstalledPackages": "Nessun pacchetto installato. Si intendeva \"cerca\"?", "NoOutdatedPackages": "Non sono presenti pacchetti obsoleti.", "NoRegistryForPort": "nessun Registro di sistema configurato per la porta {package_name}", - "NoUrlsAndHashSpecified": "Nessun URL specificato per scaricare SHA: {sha}", "NoUrlsAndNoHashSpecified": "Nessun URL specificato e nessun hash specificato.", "NonExactlyArgs": "il comando '{command_name}' richiede esattamente '{expected}' argomenti, ma ne sono stati specificati {actual}", "NonOneRemainingArgs": "il comando '{command_name}' richiede esattamente un argomento", @@ -834,8 +860,8 @@ "Options": "Opzioni", "OriginalBinParagraphHeader": "\nParagrafo binario originale", "OtherCommandsHeader": "Altro", - "OverlayPatchDir": "Il percorso di sovrapposizione \"{path}\" deve esistere e deve essere una directory.", - "OverlayPortsDirectoriesHelp": "Directory delle porte di sovrapposizione (anche: {env_var})", + "OverlayPatchDir": "Il percorso dell'overlay \"{path}\" deve essere una directory esistente.", + "OverlayPortsHelp": "Directory overlay-port o directory contenenti directory overlay-port (anche: {env_var})", "OverlayTripletDirectoriesHelp": "Directory di triplette di sovrimpressione (anche: {env_var})", "OverlayTriplets": "Tripletta di sovrapposizione da “{path}”:", "OverwritingFile": "Il file {path} era già presente e verrà sovrascritto", @@ -927,6 +953,7 @@ "PortsUpdated": "Le porte {count} seguenti sono state aggiornate:", "PrebuiltPackages": "Sono presenti pacchetti che non sono stati compilati. Per compilarli, eseguire:", "PreviousIntegrationFileRemains": "Il file di integrazione precedente non è stato rimosso.", + "ProgramPathReturnedNonzeroExitCode": "non riuscito con codice di uscita: {exit_code}", "ProgramReturnedNonzeroExitCode": "{tool_name} non riuscito con codice di uscita: ({exit_code}).", "ProvideExportType": "È necessaria almeno una delle opzioni seguenti: --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "Il push di {vendor} in \"{path}\" non è riuscito. Per altre informazioni, usare --debug.", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "Tripletta di destinazione. Vedere 'tripletta guida vcpkg' (impostazione predefinita: {env_var})", "StartCodeUnitInContinue": "è stata trovata un'unità di codice iniziale in posizione continua", "StoreOptionMissingSha": "L'opzione --store non è valida senza sha512", - "StoredBinariesToDestinations": "File binari archiviati in {count} destinazioni in {elapsed}.", + "SubmittingBinaryCacheBackground": "Avvio dell'invio di {spec} a {count} cache binarie in background", + "SubmittingBinaryCacheComplete": "L'invio di {spec} a {count} cache binarie in {elapsed} è stato completato", "SuccessfulyExported": "{package_name} esportato in {path}", "SuggestGitPull": "Il risultato potrebbe essere obsoleto. Eseguire 'git pull' per ottenere i risultati più recenti.", "SuggestStartingBashShell": "Assicurarsi di aver avviato una nuova shell Bash per rendere effettiva la modifica.", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "non è stato possibile installare il file di destinazioni del sistema in {path}", "ToRemovePackages": "Per rimuovere solo i pacchetti obsoleti, eseguire\n{command_name} remove --outdated", "ToUpdatePackages": "Per aggiornare questi pacchetti e tutte le dipendenze, eseguire\n'aggiornamento di {command_name}'", + "ToolDataFileSchemaVersionNotSupported": "la versione dello schema del documento {version} non è supportata da questa versione di vcpkg", "ToolFetchFailed": "Impossibile recuperare {tool_name}.", + "ToolHashMismatch": "{tool_name} è già stato scaricato, ma ha un hash non corretto. Previsto {expected} ma {actual}", "ToolInWin10": "Questa utilità è fornita in bundle con Windows 10 o versioni successive.", "ToolOfVersionXNotFound": "Non è stata trovata una versione appropriata di {tool_name} (versione richiesta v{version}) e non è possibile scaricarne automaticamente una portabile. Installare una versione più recente di {tool_name}", "TotalInstallTime": "Tempo di installazione totale: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "registro aggiornato '{url}': baseline '{old_value}' -> '{new_value}'", "UpgradeInManifest": "L'aggiornamento aggiorna un'installazione in modalità classica e pertanto non supporta la modalità manifesto. È consigliabile aggiornare le dipendenze aggiornando la baseline a un valore corrente con vcpkg x-update-baseline ed eseguendo l'installazione di vcpkg.", "UpgradeRunWithNoDryRun": "Se si è certi di voler ricompilare i pacchetti precedenti, eseguire il comando con l'opzione --nessun test-controllato.", - "UploadingBinariesToVendor": "Caricamento dei file binari per '{spec}' nell'origine '{vendor}' \"{path}\".", + "UploadingBinariesToVendor": "Caricamento dei file binari per {spec} in {vendor} da {path}", "UsageInstallInstructions": "è possibile installare il file di utilizzo con il seguente CMake", "UsageTextHere": "il file di utilizzo è qui", "UseEnvVar": "-- Utilizzo di {env_var} nelle variabili di ambiente.", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "A {package_name} è assegnata {actual}, ma la porta locale è {expected}", "VersionBuiltinPortTreeEntryMissing": "nessuna voce del database delle versioni per {package_name} in {expected}; usare la versione dell'albero delle porte estratta ({actual}).", "VersionCommandHeader": "vcpkg versione del programma di gestione pacchetti {version}\n\nPer informazioni sulla licenza, vedere LICENSE.txt.", - "VersionConflictXML": "Previsto {path} versione: [{expected_version}], attuale [{actual_version}]. Eseguire di nuovo bootstrap-vcpkg.", "VersionConstraintNotInDatabase1": "il vincolo \"version>=\" a {package_name} nomi versione {version} che non esiste nel database delle versioni. Tutte le versioni devono essere presenti nel database delle versioni per essere interpretate da vcpkg.", "VersionConstraintNotInDatabase2": "provare a rimuovere il vincolo di versione o a scegliere un valore dichiarato qui", "VersionConstraintOk": "tutti i vincoli di versione sono coerenti con il database della versione", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "'#' nel testo della versione deve essere seguito dalla versione della porta (un numero intero non negativo)", "VersionSpecMismatch": "Non è stato possibile caricare la porta perché le versioni sono incoerenti. Il file \"{path}\" contiene la versione {actual_version}, ma il database della versione indica che deve essere {expected_version}.", "VersionVerifiedOK": "{version_spec} è correttamente nel database della versione ({git_tree_sha})", + "WaitUntilPackagesUploaded": "In attesa di {count} invii alla cache binaria rimanenti...", "WaitingForChildrenToExit": "In attesa della chiusura dei processi figlio...", "WaitingToTakeFilesystemLock": "in attesa del blocco del file system su {path}...", "WarnOnParseConfig": "Sono stati trovati i seguenti avvisi nel percorso di configurazione {path}:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "durante il caricamento di {version_spec}", "WhileLookingForSpec": "durante la ricerca di {spec}:", "WhileParsingVersionsForPort": "durante l'analisi delle versioni per {package_name} da {path}", + "WhileRunningAssetCacheScriptCommandLine": "durante l'esecuzione della riga di comando dello script della cache degli asset", "WhileValidatingVersion": "durante la convalida della versione: {version}", "WindowsOnlyCommand": "Questo comando supporta solo Windows.", "WroteNuGetPkgConfInfo": "Le informazioni di configurazione del pacchetto NuGet sono stata scritte in {path}.", diff --git a/locales/messages.ja.json b/locales/messages.ja.json index 0b6cc0d431..9468f12a52 100644 --- a/locales/messages.ja.json +++ b/locales/messages.ja.json @@ -4,6 +4,7 @@ "ABoolean": "ブール値", "ABuiltinRegistry": "ビルトイン レジストリ", "AConfigurationObject": "構成オブジェクト", + "ACpuArchitecture": "CPU アーキテクチャ", "ADateVersionString": "日付バージョン文字列", "ADefaultFeature": "既定の機能", "ADemandObject": "要求オブジェクト", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "緩和されたバージョン文字列", "ASemanticVersionString": "セマンティック バージョン文字列", "ASetOfFeatures": "機能のセット", + "ASha512": "SHA-512 ハッシュ", "AString": "文字列", "AStringOrArrayOfStrings": "文字列または文字列の配列", "AStringStringDictionary": "\"string\": \"string\" ディクショナリ", + "AToolDataArray": "ツール メタデータの配列", + "AToolDataFile": "ツール データ ファイル", + "AToolDataOS": "ツール データ オペレーティング システム", + "AToolDataObject": "ツール メタデータ", + "AToolDataVersion": "ツール データ バージョン", "AUrl": "URL", "AVcpkgRepositoryCommit": "vcpkg リポジトリ コミット", "AVersionConstraint": "バージョン制約", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "成果物を取得するときにホストの検出を Windows に強制します", "ArtifactsSwitchX64": "成果物を取得するときにホストの検出を x64 に強制します", "ArtifactsSwitchX86": "成果物を取得するときにホストの検出を x86 に強制します", - "AssetCacheHit": "{path} のアセット キャッシュ ヒット; {url} からダウンロードしました", - "AssetCacheMiss": "アセット キャッシュ ミス; {url} からダウンロードしています", - "AssetCacheMissBlockOrigin": "{path} のアセット キャッシュ ミスです。ダウンロードは、x-block-origin によってブロックされています。", + "AssetCacheConsult": "アセット キャッシュ {url} を使用して {path} をダウンロードしようとしています", + "AssetCacheConsultScript": "アセット キャッシュ スクリプトを使用して {path} をダウンロードしようとしています", + "AssetCacheHit": "正常にダウンロードされました。資産キャッシュ ヒット。", + "AssetCacheHitUrl": "正常にダウンロードされました。資産キャッシュ ヒット、権限のあるソース {url} を試行しませんでした", + "AssetCacheMiss": "資産キャッシュ ミス;権限のあるソース {url} を試行しています", + "AssetCacheMissBlockOrigin": "アセット キャッシュヒットはありませんでした。権限のあるソース {url} を試行している x ブロック オリジン ブロック", + "AssetCacheMissNoUrls": "資産キャッシュで {sha} を検索できませんでした。権限のある URL は不明です", "AssetCacheProviderAcceptsNoArguments": "予期しない引数: '{value}' は引数を受け付けませんでした", - "AssetCacheSuccesfullyStored": "{url} への {path} を正常に保存しました。", + "AssetCacheScriptBadVariable": "スクリプト テンプレート {value} に不明な置換 {list} が含まれています", + "AssetCacheScriptBadVariableHint": "これをリテラル コマンド ラインで使用する場合は、{{{{{list}}}} を使用します", + "AssetCacheScriptCommandLine": "スクリプトの完全なコマンド ラインが", + "AssetCacheScriptFailed": "資産キャッシュ スクリプトから 0 以外の終了コードが返されました {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "資産キャッシュ スクリプトから成功が返されましたが、結果ファイルに予期しないハッシュが含まれています", + "AssetCacheScriptFailedToWriteFile": "資産キャッシュ スクリプトから成功が返されましたが、予期された結果ファイルが作成されませんでした", + "AssetCacheScriptNeedsSha": "スクリプト テンプレート {value} には SHA が必要ですが、{url} のダウンロードが試行された SHA は不明です", + "AssetCacheScriptNeedsUrl": "スクリプト テンプレート {value} には URL が必要ですが、{sha} のダウンロードを試行した URL は不明です", + "AssetCacheSuccesfullyStored": "ストアの成功", "AssetSourcesArg": "資産キャッシュ ソース。'vcpkg help assetcaching' を参照してください", "AttemptingToSetBuiltInBaseline": "vcpkg-configuration.json で default-registry をオーバーライドしながら、vcpkg.json で builtin-baseline を設定しようとしています。\nvcpkg-configuration.json の default-registry が使用されます。", "AuthenticationMayRequireManualAction": "1 つ以上の {vendor} 資格情報プロバイダーが手動操作を要求しました。対話機能を許可するには、バイナリ ソース 'interactive' を追加します。", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "すべてのパスから削除する先頭ディレクトリの数", "CommandEnvExample2": "vcpkg env \"ninja -C \" --triplet x64-windows", "CommandFailed": "コマンド:\n{command_line}\n次の出力で失敗しました:", - "CommandFailedCode": "コマンド:\n{command_line}\n終了コード {exit_code} と次の出力で失敗しました:", "CommunityTriplets": "コミュニティ トリプレット:", "CompilerPath": "コンパイラが見つかりました: {path}", - "CompressFolderFailed": "フォルダー \"{path}\":を圧縮できませんでした:", "ComputingInstallPlan": "インストール プランを計算しています...", "ConfigurationErrorRegistriesWithoutBaseline": "{path} で定義されている構成が無効です。\n\nレジストリを使用するには、既定のレジストリにベースラインが設定されているか、既定のレジストリが null である必要があります。\n\n詳細については、{url} を参照してください。", "ConfigurationNestedDemands": "[\"{json_field}\"] に入れ子になった 'demands' オブジェクトが含まれています (入れ子になった 'demands' には効果がありません)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "ファイル名 {path} から nuget ID とバージョンを推測できませんでした", "CouldNotFindBaselineInCommit": "{package_name} の {commit_sha} で {url} にベースラインが見つかりませんでした。", "CouldNotFindGitTreeAtCommit": "コミット {commit_sha} でリポジトリ {package_name} に `versions` の Git ツリーが見つかりませんでした", - "CouldNotFindToolVersion": "{path} に が見つかりませんでした", "CouldNotFindVersionDatabaseFile": "バージョン データベース ファイルが見つかりませんでした: {path}", "CreateFailureLogsDir": "エラー ログ出力ディレクトリ {path} を作成しています。", "CreatedNuGetPackage": "作成された nupkg: {path}", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "NuGet パッケージを作成しています...", "CreatingZipArchive": "zip アーカイブを作成しています...", "CreationFailed": "{path} を作成できませんでした。", + "CurlFailedGeneric": "curl 操作がエラー コード {exit_code} で失敗しました。", "CurlFailedToPut": "curl は終了コード {exit_code} でファイルを {url} に配置できませんでした。", "CurlFailedToPutHttp": "curl は終了コード {exit_code} と http コード {value} でファイルを {url} に配置できませんでした。", - "CurlResponseTruncatedRetrying": "curl が部分的な応答を返しました。{value} ミリ秒待ってから、もう一度お試しください", - "CurlTimeout": "curl は、タイムアウトおよび再試行後であっても、要求されたすべての HTTP 操作を実行できませんでした。最後のコマンド ライン: {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "curl は予期された数の終了コードを返せませんでした;これは、終了する前に何かがカールを終了した場合に発生する可能性があります。curl は前回の操作の結果コードである {exit_code} で終了しましたが、クラッシュの結果である可能性があります。コマンド ラインが {command_line} されました。すべての出力は次のとおりです:", "CurrentCommitBaseline": "現在のコミットをベースラインとして使用できます。これは次のとおりです。\n\t\"builtin-baseline\": \"{commit_sha}\"", "CycleDetectedDuring": "サイクルが {spec} 中に検出されました:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "環境変数 VCPKG_DEFAULT_BINARY_CACHE はディレクトリである必要があります (旧: {path})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "DLL は ${{CURRENT_PACKAGES_DIR}} に対して相対的です", "DocumentedFieldsSuggestUpdate": "これらのフィールドを認識する必要がある場合は、vcpkg ツールの更新をお試しください。", "DownloadAvailable": "このツールのダウンロード可能なコピーを使用でき、{env_var} の設定を解除すると使用できます。", - "DownloadFailedCurl": "{url}: curl は終了コード {exit_code} でダウンロードできませんでした", - "DownloadFailedHashMismatch": "ファイルに必要なハッシュがありません:\nurl: {url}\nファイル: {path}\n必要なハッシュ: {expected}実際の\nハッシュ: {actual}", - "DownloadFailedProxySettings": "{path} をダウンロードできませんでした。\nプロキシを使用している場合は、プロキシ設定が正しいことを確認してください。\n考えられる原因:\n1. 実際には HTTP プロキシを使用していますが、HTTPS_PROXY 変数を `https//address:port` に設定しています。\n`https://` というプレフィックスはプロキシが HTTPS プロキシであることを指しますが、ご使用のプロキシ (v2ray、shadow rectangler など) は HTTP プロキシであるため、これは正しくありません。\n代わりに、`http://address:port` をHTTP_PROXYとHTTPS_PROXYの両方に設定してみてください。\n2. Windows を使用している場合、vcpkg はプロキシ ソフトウェアによって設定された Windows IE プロキシ設定を自動的に使用します。参照、{url}\nプロキシによって設定された値が間違っているか、同様の `https://` プレフィックスの問題が発生している可能性があります。\n3. プロキシのリモート サーバーのサービスが停止しています。\nリンクを直接ダウンロードしようとしたが、これがダウンロード サーバーの一時的な問題ではないと考えられる場合は、https://github.com/Microsoft/vcpkg/issues で問題を送信してください\nこのダウンロード サーバーのエラーを上流に報告してください。", - "DownloadFailedRetrying": "ダウンロードに失敗しました -- {value}ミリ秒後に再試行しています", + "DownloadFailedHashMismatch": "{url} からのダウンロードに予期しないハッシュがありました", + "DownloadFailedHashMismatchActualHash": "実績 : {sha}", + "DownloadFailedHashMismatchExpectedHash": "必要な値: {sha}", + "DownloadFailedHashMismatchZero": "予期された SHA512 がすべてゼロであったため、ダウンロードに失敗しました。必要な SHA512 を次に変更してください: {sha}", + "DownloadFailedProxySettings": "プロキシを使用している場合は、プロキシ設定が正しいことを確認してください。\n考えられる原因:\n1. 実際に HTTP プロキシを使用していますが、HTTPS_PROXY 変数を `https//address:port` に設定しています。\n`https://` というプレフィックスはプロキシが HTTPS プロキシであることを指しますが、使用しているプロキシ (v2ray、shadowsocksr など) は HTTP プロキシであるため、これは正しくありません。\n代わりに、`http://address:port` を HTTP_PROXY と HTTPS_PROXY の両方に設定してみてください。\n2. Windows を使用している場合、vcpkg はプロキシ ソフトウェアによって設定された Windows IE プロキシ設定を自動的に使用します。参照: https://github.com/microsoft/vcpkg-tool/pull/77\nプロキシによって設定された値が間違っているか、同様の `https://` プレフィックスの問題が発生している可能性があります。\n3. プロキシのリモート サーバーが故障しています。\nこれが一時的なダウンロード サーバーエラーではなく、別の場所からこのファイルをダウンロードするために vcpkg を変更する必要がある場合は、問題を https://github.com/Microsoft/vcpkg/issues に送信してください", + "DownloadFailedRetrying": "{url} のダウンロードに失敗しました -- {value} ミリ秒後に再試行しています", "DownloadFailedStatusCode": "{url}: 失敗しました: 状態コード {value}", + "DownloadOrUrl": "または {url}", "DownloadRootsDir": "ディレクトリをダウンロードします (既定値: {env_var})", - "DownloadSuccesful": "{path} が正常にダウンロードされました。", - "DownloadWinHttpError": "{url}: {system_api} が終了コード {exit_code} で失敗しました", + "DownloadSuccesful": "{path} が正常にダウンロードされました", + "DownloadSuccesfulUploading": "{path} が正常にダウンロードされ、{url} に保存されました", + "DownloadTryingAuthoritativeSource": "{url} しようとしています", + "DownloadWinHttpError": "{url}: {system_api} が終了コード {exit_code} で失敗しました。", "DownloadedSources": "{spec} 用にダウンロードされたソース", + "DownloadingAssetShaToFile": "資産キャッシュ エントリをダウンロードしています {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "-> {path} {sha} アセット キャッシュ エントリのダウンロードを要求しましたが、資産キャッシュが構成されていません", + "DownloadingFile": "{path} をダウンロードしています", + "DownloadingFileFirstAuthoritativeSource": "{path} をダウンロードしています。{url} 試しています", "DownloadingPortableToolVersionX": "適切なバージョンの {tool_name} が見つかりませんでした (v{version} が必須)。", - "DownloadingUrl": "{url} をダウンロードしています", + "DownloadingUrlToFile": "{url} -> {path} をダウンロードしています", "DownloadingVcpkgStandaloneBundle": "スタンドアロン バンドル {version} をダウンロードしています。", "DownloadingVcpkgStandaloneBundleLatest": "最新のスタンドアロン バンドルをダウンロードしています。", + "DuplicateDependencyOverride": "{package_name} は既に上書きされています", "DuplicatePackagePattern": "パッケージ \"{package_name}\" が重複しています。", "DuplicatePackagePatternFirstOcurrence": "最初の宣言:", "DuplicatePackagePatternIgnoredLocations": "次の再宣言は無視されます:", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "オプション --{option}はクラシック モードではサポートされていません。マニフェストが見つかりませんでした。", "ErrorInvalidExtractOption": "--{option} は、負でない整数または 'AUTO' に設定する必要があります。", "ErrorInvalidManifestModeOption": "オプション --{option}はマニフェスト モードではサポートされていません。", + "ErrorManifestMustDifferFromOverlay": "マニフェスト ディレクトリ ({path}) をオーバーレイ ポートで構成されたディレクトリと同じにすることはできません。", + "ErrorManifestMustDifferFromOverlayDot": "マニフェスト ディレクトリをオーバーレイ ポートで構成されたディレクトリと同じにすることはできません。そのため、\"overlay-ports\" の値を \".\" にすることはできません。", "ErrorMissingVcpkgRoot": "vcpkg-root を検出できませんでした。作成した vcpkg のコピーを使用する場合は、VCPKG_ROOT 環境変数を定義して、https://github.com/Microsoft/vcpkg の複製されたコピーを指すようにする必要があります。", "ErrorNoVSInstance": "トリプレット内 {triplet}: 有効な Visual Studio インスタンスが見つかりません", "ErrorNoVSInstanceAt": "「{path}」で", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "{path} を解析できませんでした。'versions' 配列が必要です。", "FailedToParseSerializedBinParagraph": "[サニティ チェック] シリアル化されたバイナリ段落を解析できませんでした。\nhttps://github.com/microsoft/vcpkg でイシューを開き、次の出力を含めてください。\n{error_msg}\nシリアル化されたバイナリ段落:", "FailedToParseVersionFile": "バージョン ファイル {path} を解析できませんでした", - "FailedToParseVersionXML": "ツール {tool_name} のバージョンを解析できませんでした。バージョン文字列: {version}", "FailedToRunToolToDetermineVersion": "\"{path}\" を実行して {tool_name} バージョンを特定できませんでした。", "FailedToStoreBackToMirror": "{url} への {path} を保存できませんでした。", "FailedToStoreBinaryCache": "バイナリ キャッシュ {path} を格納できませんでした", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "{url} ({value}) からレジストリ情報をフェッチしています...", "FieldKindDidNotHaveExpectedValue": "\"kind\" に必要な値がありませんでした: (次のいずれかが必要です: {expected}; {actual} が見つかりました)", "FileIsNotExecutable": "このファイルは実行可能ではないようです", - "FileNotFound": "{path}: ファイルが見つかりません", + "FileNotFound": "ファイルが見つかりません", "FileReadFailed": "オフセット {byte_offset} の {path} から {count} バイトを読み取れませんでした。", "FileSeekFailed": "{path}内の位置{byte_offset}を検索できませんでした。", "FilesContainAbsolutePath1": "インストールされているパッケージには、次のような絶対パスを指定しないでください。このメッセージを非表示にするには、set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled) を追加します", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "不明なファイルの状態: {value}", "GitUnexpectedCommandOutputCmd": "Git が {command_line} の実行中に予期しない出力を生成しました", "GraphCycleDetected": "{package_name} のグラフ内で循環が検出されました:", - "HashFileFailureToRead": "ハッシュのためにファイル \"{path}\" を読み取れませんでした: ", "HashPortManyFiles": "{package_name} には {count} 個のファイルが含まれています。バイナリ キャッシュの ABI ハッシュを決定するときに、これらのコンテンツのハッシュ化に時間がかかることがあります。ファイル数を減らすことを検討してください。この一般的な原因は、ソース ファイルまたはビルド ファイルをポートのディレクトリに誤ってチェックアウトすることです。", "HeaderOnlyUsage": "{package_name} はヘッダーのみであり、CMake から次の方法で使用できます:", "HelpAssetCaching": "**実験的な機能: これはいつでも変更または削除される可能性があります**\n\nvcpkg はミラーを使用してダウンロードしたアセットをキャッシュし、元のソースが変更または消失した場合でも操作を継続できるようにします。\n\n資産キャッシュは、環境変数 X_VCPKG_ASSET_SOURCES をセミコロンで区切られたソースのリストに設定するか、一連の --x-asset-sources= コマンド ライン オプションを渡すことによって構成できます。コマンド ライン ソースは、環境ソースの後に解釈されます。コンマ、セミコロン、およびバックティックは、バックティック (`) を使用してエスケープできます。\n\n特定の文字列の オプション パラメーターは、それらへのアクセス方法を制御します。\"read\"、\"write\"、または \"readwrite\" として指定でき、既定値は \"read\" です。\n\n有効なソース:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "キャッシュされたバイナリが使用できない場合は失敗します", "HelpTxtOptOnlyDownloads": "ビルドせずにソースをダウンロードするよう最善を尽くします", "HelpTxtOptRecurse": "インストールの一部としてパッケージの削除を許可します", - "HelpTxtOptUseAria2": "aria2 を使用してダウンロード タスクを実行します", "HelpTxtOptUseHeadVersion": "最新のアップストリーム ソース (クラシック モード) を使用して、コマンド ラインにライブラリをインストールします", "HelpTxtOptWritePkgConfig": "外部バイナリ キャッシュで使用するために NuGet packages.config 形式のファイルを書き込みます。詳細については、`vcpkg help binarycaching` を参照してください", "HelpUpdateBaseline": "ライブラリを最新の状態に保つ最善の方法は、ベースライン参照を更新することです。これにより、推移的なパッケージを含むすべてのパッケージが更新されます。ただし、パッケージを個別に更新する必要がある場合は、\"version>=\" 制約を使用できます。", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "Visual Studio 2015 には統合が適用されませんでした。", "InternalCICommand": "vcpkg CI は、非互換性に変更されるか、いつでも削除できる内部コマンドです。", "InternalErrorMessageContact": "https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug で問題を開き、問題を再現するための詳細な手順を確認してください。", - "InvalidArchitecture": "アーキテクチャが無効です: {value}", + "InvalidArchitectureValue": "アーキテクチャが無効です: {value}。次のいずれかが必要です: {expected}", "InvalidArgument": "無効な引数です", "InvalidArgumentRequiresAbsolutePath": "無効な引数: バイナリ構成文字列のバイナリ構成 '{binary_source}' パス引数は絶対である必要があります", "InvalidArgumentRequiresBaseUrl": "無効な引数: バイナリ構成 '{binary_source}' には、最初の引数として {base_url} ベース URL が必要です", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "論理式が無効です。'or' の代わりに '|' を使用してください", "InvalidOptionForRemove": "'remove' はライブラリまたは '--outdated' のいずれかを受け入れます", "InvalidPortVersonName": "無効なポート バージョン ファイル名が見つかりました: '{path}'。", + "InvalidSha512": "SHA-512 ハッシュが無効です: {sha}\nSHA-512 ハッシュは 128 文字で、16 進数のみを含む必要があります", "InvalidSharpInVersion": "バージョン テキストに無効な文字 '#' があります", "InvalidSharpInVersionDidYouMean": "バージョン テキストに無効な文字 '#' があります。\"port-version\" を意図していましたか: {value}?", "InvalidString": "無効な utf8 が Value::string(std::string) に渡されました", + "InvalidToolOSValue": "無効なツール オペレーティング システム: {value}。次のいずれかが必要です: {expected}", + "InvalidToolVersion": "ツールのバージョンが無効です。ドットで区切られた 1 ~ 3 個の数値の部分文字列を含む文字列が必要です。", "InvalidTriplet": "無効なトリプレット: {triplet}", "InvalidUri": "URI を解析できません: {value}", "InvalidValueHashAdditionalFiles": "変数VCPKG_HASH_ADDITIONAL_FILESに無効なファイル パスが含まれています: '{path}'。値は、存在するファイルへの絶対パスである必要があります。", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "シリアル化されたバイナリ段落が、元のバイナリ段落と異なっていました。https://github.com/microsoft/vcpkg でイシューを開き、次の出力を含めてください。", "MismatchedFiles": "格納するファイルがハッシュと一致しません", "MismatchedManifestAfterReserialize": "シリアル化されたマニフェストは元のマニフェストとは異なります。次の出力を使用して、https://github.com/microsoft/vcpkg で問題を開いてください。", - "MismatchedNames": "名前が一致しませんでした: '{package_name}' != '{actual}'", + "MismatchedNames": "メタデータ ファイルで宣言されたポート名がディレクトリと一致しませんでした。ポートの名前は {package_name} である必要がありますが、ファイルで {actual} 宣言されています。", "MismatchedSpec": "ポート {path} の仕様が一致しません: {expected} が予期された、実際は {actual}", "MismatchedType": "{json_field}: 型が一致しません: {json_type} が必要です", "Missing7zHeader": "7z ヘッダーが見つかりません。", "MissingAndroidEnv": "ANDROID_NDK_HOME 環境変数がありません", "MissingAndroidHomeDir": "ANDROID_NDK_HOME ディレクトリが存在しません: {path}", "MissingArgFormatManifest": "format-manifest に '--all' を指定せずに --convert-control が渡されました。\nこれでは何も実行されません。明示的に渡されたコントロール ファイルは自動的に変換されます。", - "MissingAssetBlockOrigin": "{path} が見つかりません。ダウンロードは x-block-origin によってブロックされています。", "MissingClosingParen": "右かっこ ) がありません。", "MissingDependency": "パッケージ {spec} はインストールされていますが、依存関係 {package_name} はインストールされていません。", "MissingExtension": "'{extension}' 拡張子がありません。", @@ -814,7 +841,6 @@ "NoInstalledPackages": "パッケージがインストールされていません。'検索' ということですか?", "NoOutdatedPackages": "期限切れのパッケージはありません。", "NoRegistryForPort": "ポート {package_name} に対してレジストリが構成されていません", - "NoUrlsAndHashSpecified": "SHA をダウンロードするための URL が指定されていません: {sha}", "NoUrlsAndNoHashSpecified": "URL が指定されておらず、ハッシュも指定されていません。", "NonExactlyArgs": "コマンド '{command_name}' には正確に {expected} 個の引数が必要ですが、{actual} 個が指定されました", "NonOneRemainingArgs": "コマンド '{command_name}' には正確に 1 個の引数が必要です", @@ -834,8 +860,8 @@ "Options": "オプション", "OriginalBinParagraphHeader": "\n元のバイナリ段落", "OtherCommandsHeader": "その他", - "OverlayPatchDir": "オーバーレイ パス \"{path}\" が存在し、ディレクトリである必要があります。", - "OverlayPortsDirectoriesHelp": "オーバーレイ ポートのディレクトリ ({env_var} も含む)", + "OverlayPatchDir": "オーバーレイ パス \"{path}\" は既存のディレクトリである必要があります。", + "OverlayPortsHelp": "オーバーレイ ポート ディレクトリ、またはオーバーレイ ポート ディレクトリを含むディレクトリ ({env_var} も含む)", "OverlayTripletDirectoriesHelp": "オーバーレイ トリプレットのディレクトリ ({env_var} も含む)", "OverlayTriplets": "\"{path}\" からのトリプレットのオーバーレイ:", "OverwritingFile": "ファイル {path} はすでに存在しているため、上書きされます", @@ -927,6 +953,7 @@ "PortsUpdated": "次の {count} 個のポートが更新されました。", "PrebuiltPackages": "ビルドされていないパッケージがあります。ビルドするには、次のコマンドを実行します:", "PreviousIntegrationFileRemains": "以前の統合ファイルは削除されませんでした。", + "ProgramPathReturnedNonzeroExitCode": "終了コード ({exit_code}) で失敗しました", "ProgramReturnedNonzeroExitCode": "{tool_name} が終了コード: ({exit_code}) で失敗しました。", "ProvideExportType": "次のオプションのうち少なくとも 1 つが必要です: --raw --nuget --ifw --zip --7zip --chocolatey --prefab。", "PushingVendorFailed": "{vendor} を \"{path}\" にプッシュできませんでした。詳細については、--debug を使用してください。", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "ターゲット トリプレット。'vcpkg help triplet' を参照してください (既定値: {env_var})", "StartCodeUnitInContinue": "続行位置で開始コード単位が見つかりました", "StoreOptionMissingSha": "--store オプションは sha512 なしでは無効です", - "StoredBinariesToDestinations": "{elapsed} の {count} 件の宛先にバイナリを格納しました。", + "SubmittingBinaryCacheBackground": "バックグラウンドで {count} バイナリ キャッシュへの {spec} の送信を開始しています", + "SubmittingBinaryCacheComplete": "{elapsed} のバイナリ キャッシュへの {spec} {count} 送信が完了しました", "SuccessfulyExported": "{package_name} を {path} にエクスポートしました", "SuggestGitPull": "結果は古い可能性があります。'git pull' を実行して最新の結果を取得してください。", "SuggestStartingBashShell": "変更を有効にするには、新しい bash シェルを開始したことをご確認ください。", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "システム ターゲット ファイルを {path} にインストールできませんでした", "ToRemovePackages": "古いパッケージのみを削除するには、\n{command_name} remove --outdated を実行します", "ToUpdatePackages": "これらのパッケージとすべての依存関係を更新するには、\n{command_name} upgrade' を実行します", + "ToolDataFileSchemaVersionNotSupported": "ドキュメント スキーマのバージョン {version} は、このバージョンの vcpkg ではサポートされていません", "ToolFetchFailed": "{tool_name} をフェッチできませんでした。", + "ToolHashMismatch": "{tool_name} は既にダウンロードされているようですが、ハッシュが正しくありません。{expected} が必要ですが、{actual} されました", "ToolInWin10": "このユーティリティは、Windows 10 以降にバンドルされています。", "ToolOfVersionXNotFound": "{tool_name} の適切なバージョンが見つからず (v{version} が必要)、ポータブル バージョンを自動的にダウンロードできません。{tool_name} の新しいバージョンをインストールしてください", "TotalInstallTime": "合計インストール時間: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "レジストリ '{url}' を更新しました。ベースライン '{old_value}' -> '{new_value}'", "UpgradeInManifest": "アップグレードでは、クラシック モードのインストールがアップグレードされるため、マニフェスト モードはサポートされていません。vcpkg x-update-baseline を使用してベースラインを現在の値に更新し、vcpkg インストールを実行して、依存関係を更新することを検討してください。", "UpgradeRunWithNoDryRun": "上記のパッケージを再構築する場合は、--no-dry-run オプションを使用してこのコマンドを実行します。", - "UploadingBinariesToVendor": "'{spec}' のバイナリを '{vendor}' ソース \"{path}\" にアップロードしています。", + "UploadingBinariesToVendor": "{path} から {vendor} に {spec} のバイナリをアップロードしています", "UsageInstallInstructions": "次の CMake を使用して使用状況ファイルをインストールできます。", "UsageTextHere": "使用状況ファイルはここにあります", "UseEnvVar": "-- 環境変数で {env_var} を使用しています。", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "{package_name} には {actual} が割り当てられていますが、ローカル ポートは {expected} です", "VersionBuiltinPortTreeEntryMissing": "{expected} で {package_name} のバージョン データベース エントリがありません。チェックアウトされたポートのツリー バージョン ({actual}) を使用しています。", "VersionCommandHeader": "vcpkg パッケージ管理プログラムのバージョン {version}\n\nライセンス情報については、LICENSE.txt を参照してください。", - "VersionConflictXML": "{path} バージョン: [{expected_version}] が必要でしたが、[{actual_version}] でした。 bootstrap-vcpkg を再実行してください。", "VersionConstraintNotInDatabase1": "{package_name} への \"version>=\" 制約により、バージョン データベースに存在しないバージョン {version} が指定されます。vcpkg で解釈するには、すべてのバージョンがバージョン データベースに存在する必要があります。", "VersionConstraintNotInDatabase2": "バージョン制約を削除するか、ここで宣言されている値を選択することを検討してください", "VersionConstraintOk": "すべてのバージョン制約がバージョン データベースと一致しています", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "バージョン テキスト内の '#' の後にはポート バージョン (負でない整数) を指定する必要があります", "VersionSpecMismatch": "バージョンに一貫性がないため、ポートを読み込めませんでした。ファイル「{path}」にはバージョン {actual_version} が含まれていますが、バージョン データベースは {expected_version} であることを示しています。", "VersionVerifiedOK": "{version_spec} がバージョン データベースに正しく存在します ({git_tree_sha})", + "WaitUntilPackagesUploaded": "残りのバイナリ キャッシュの送信 {count} 待機しています...", "WaitingForChildrenToExit": "子プロセスの終了を待機しています...", "WaitingToTakeFilesystemLock": "{path} でファイルシステムのロックを取得するのを待機しています...", "WarnOnParseConfig": "構成 {path} で次の警告が見つかりました:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "{version_spec} の読み込み中", "WhileLookingForSpec": "{spec} の検索中:", "WhileParsingVersionsForPort": "{path} からの {package_name} のバージョンの解析中", + "WhileRunningAssetCacheScriptCommandLine": "資産キャッシュ スクリプトコマンド ラインの実行中", "WhileValidatingVersion": "バージョンの検証中に: {version}", "WindowsOnlyCommand": "このコマンドは Windows のみをサポートします。", "WroteNuGetPkgConfInfo": "NuGet パッケージ構成情報を {path} に書き込みました", diff --git a/locales/messages.json b/locales/messages.json index 81d13e7372..f65a872a52 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -4,6 +4,7 @@ "ABoolean": "a boolean", "ABuiltinRegistry": "a builtin registry", "AConfigurationObject": "a configuration object", + "ACpuArchitecture": "a CPU architecture", "ADateVersionString": "a date version string", "ADefaultFeature": "a default feature", "ADemandObject": "a demand object", @@ -36,9 +37,15 @@ "ARelaxedVersionString": "a relaxed version string", "ASemanticVersionString": "a semantic version string", "ASetOfFeatures": "a set of features", + "ASha512": "a SHA-512 hash", "AString": "a string", "AStringOrArrayOfStrings": "a string or array of strings", "AStringStringDictionary": "a \"string\": \"string\" dictionary", + "AToolDataArray": "an array of tool metadata", + "AToolDataFile": "a tool data file", + "AToolDataOS": "a tool data operating system", + "AToolDataObject": "tool metadata", + "AToolDataVersion": "a tool data version", "AUrl": "a url", "AVcpkgRepositoryCommit": "a vcpkg repository commit", "AVersionConstraint": "a version constraint", @@ -167,16 +174,35 @@ "ArtifactsSwitchWindows": "Forces host detection to Windows when acquiring artifacts", "ArtifactsSwitchX64": "Forces host detection to x64 when acquiring artifacts", "ArtifactsSwitchX86": "Forces host detection to x86 when acquiring artifacts", - "AssetCacheHit": "Asset cache hit for {path}; downloaded from: {url}", - "_AssetCacheHit.comment": "An example of {path} is /foo/bar. An example of {url} is https://github.com/microsoft/vcpkg.", - "AssetCacheMiss": "Asset cache miss; downloading from {url}", + "AssetCacheConsult": "Trying to download {path} using asset cache {url}", + "_AssetCacheConsult.comment": "An example of {path} is /foo/bar. An example of {url} is https://github.com/microsoft/vcpkg.", + "AssetCacheConsultScript": "Trying to download {path} using asset cache script", + "_AssetCacheConsultScript.comment": "An example of {path} is /foo/bar.", + "AssetCacheHit": "Download successful! Asset cache hit.", + "AssetCacheHitUrl": "Download successful! Asset cache hit, did not try authoritative source {url}", + "_AssetCacheHitUrl.comment": "An example of {url} is https://github.com/microsoft/vcpkg.", + "AssetCacheMiss": "Asset cache miss; trying authoritative source {url}", "_AssetCacheMiss.comment": "An example of {url} is https://github.com/microsoft/vcpkg.", - "AssetCacheMissBlockOrigin": "Asset cache miss for {path} and downloads are blocked by x-block-origin.", - "_AssetCacheMissBlockOrigin.comment": "x-block-origin is a vcpkg term. Do not translate An example of {path} is /foo/bar.", + "AssetCacheMissBlockOrigin": "there were no asset cache hits, and x-block-origin blocks trying the authoritative source {url}", + "_AssetCacheMissBlockOrigin.comment": "x-block-origin is a vcpkg term. Do not translate An example of {url} is https://github.com/microsoft/vcpkg.", + "AssetCacheMissNoUrls": "Asset cache missed looking for {sha} and no authoritative URL is known", + "_AssetCacheMissNoUrls.comment": "An example of {sha} is eb32643dd2164c72b8a660ef52f1e701bb368324ae461e12d70d6a9aefc0c9573387ee2ed3828037ed62bb3e8f566416a2d3b3827a3928f0bff7c29f7662293e.", "AssetCacheProviderAcceptsNoArguments": "unexpected arguments: '{value}' does not accept arguments", "_AssetCacheProviderAcceptsNoArguments.comment": "{value} is a asset caching provider name such as azurl, clear, or x-block-origin", - "AssetCacheSuccesfullyStored": "Successfully stored {path} to {url}.", - "_AssetCacheSuccesfullyStored.comment": "An example of {path} is /foo/bar. An example of {url} is https://github.com/microsoft/vcpkg.", + "AssetCacheScriptBadVariable": "the script template {value} contains unknown replacement {list}", + "_AssetCacheScriptBadVariable.comment": "{value} is the script template passed to x-script, {list} is the name of the unknown replacement", + "AssetCacheScriptBadVariableHint": "if you want this on the literal command line, use {{{{{list}}}}}", + "_AssetCacheScriptBadVariableHint.comment": "{list} is the name of the unknown replacement", + "AssetCacheScriptCommandLine": "the full script command line was", + "AssetCacheScriptFailed": "the asset cache script returned nonzero exit code {exit_code}", + "_AssetCacheScriptFailed.comment": "An example of {exit_code} is 127.", + "AssetCacheScriptFailedToWriteCorrectHash": "the asset cache script returned success but the resulting file has an unexpected hash", + "AssetCacheScriptFailedToWriteFile": "the asset cache script returned success but did not create expected result file", + "AssetCacheScriptNeedsSha": "the script template {value} requires a SHA, but no SHA is known for attempted download of {url}", + "_AssetCacheScriptNeedsSha.comment": "{value} is the script template the user supplied to x-script An example of {url} is https://github.com/microsoft/vcpkg.", + "AssetCacheScriptNeedsUrl": "the script template {value} requires a URL, but no URL is known for attempted download of {sha}", + "_AssetCacheScriptNeedsUrl.comment": "{value} is the script template the user supplied to x-script An example of {sha} is eb32643dd2164c72b8a660ef52f1e701bb368324ae461e12d70d6a9aefc0c9573387ee2ed3828037ed62bb3e8f566416a2d3b3827a3928f0bff7c29f7662293e.", + "AssetCacheSuccesfullyStored": "Store success", "AssetSourcesArg": "Asset caching sources. See 'vcpkg help assetcaching'", "AttemptingToSetBuiltInBaseline": "attempting to set builtin-baseline in vcpkg.json while overriding the default-registry in vcpkg-configuration.json.\nthe default-registry from vcpkg-configuration.json will be used.", "AuthenticationMayRequireManualAction": "One or more {vendor} credential providers requested manual action. Add the binary source 'interactive' to allow interactivity.", @@ -499,13 +525,9 @@ "_CommandEnvExample2.comment": "This is a command line, only the part should be localized", "CommandFailed": "command:\n{command_line}\nfailed with the following output:", "_CommandFailed.comment": "An example of {command_line} is vcpkg install zlib.", - "CommandFailedCode": "command:\n{command_line}\nfailed with exit code {exit_code} and the following output:", - "_CommandFailedCode.comment": "An example of {command_line} is vcpkg install zlib. An example of {exit_code} is 127.", "CommunityTriplets": "Community Triplets:", "CompilerPath": "Compiler found: {path}", "_CompilerPath.comment": "An example of {path} is /foo/bar.", - "CompressFolderFailed": "Failed to compress folder \"{path}\":", - "_CompressFolderFailed.comment": "An example of {path} is /foo/bar.", "ComputingInstallPlan": "Computing installation plan...", "ConfigurationErrorRegistriesWithoutBaseline": "The configuration defined in {path} is invalid.\n\nUsing registries requires that a baseline is set for the default registry or that the default registry is null.\n\nSee {url} for more details.", "_ConfigurationErrorRegistriesWithoutBaseline.comment": "An example of {path} is /foo/bar. An example of {url} is https://github.com/microsoft/vcpkg.", @@ -528,8 +550,6 @@ "_CouldNotFindBaselineInCommit.comment": "An example of {url} is https://github.com/microsoft/vcpkg. An example of {commit_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949. An example of {package_name} is zlib.", "CouldNotFindGitTreeAtCommit": "could not find the git tree for `versions` in repo {package_name} at commit {commit_sha}", "_CouldNotFindGitTreeAtCommit.comment": "An example of {package_name} is zlib. An example of {commit_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", - "CouldNotFindToolVersion": "Could not find in {path}", - "_CouldNotFindToolVersion.comment": "An example of {version} is 1.3.8. An example of {path} is /foo/bar.", "CouldNotFindVersionDatabaseFile": "Couldn't find the versions database file: {path}", "_CouldNotFindVersionDatabaseFile.comment": "An example of {path} is /foo/bar.", "CreateFailureLogsDir": "Creating failure logs output directory {path}.", @@ -541,14 +561,14 @@ "CreatingZipArchive": "Creating zip archive...", "CreationFailed": "Creating {path} failed.", "_CreationFailed.comment": "An example of {path} is /foo/bar.", + "CurlFailedGeneric": "curl operation failed with error code {exit_code}.", + "_CurlFailedGeneric.comment": "curl is the name of a program, see curl.se. An example of {exit_code} is 127.", "CurlFailedToPut": "curl failed to put file to {url} with exit code {exit_code}.", "_CurlFailedToPut.comment": "curl is the name of a program, see curl.se An example of {exit_code} is 127. An example of {url} is https://github.com/microsoft/vcpkg.", "CurlFailedToPutHttp": "curl failed to put file to {url} with exit code {exit_code} and http code {value}.", "_CurlFailedToPutHttp.comment": "curl is the name of a program, see curl.se. {value} is an HTTP status code An example of {exit_code} is 127. An example of {url} is https://github.com/microsoft/vcpkg.", - "CurlResponseTruncatedRetrying": "curl returned a partial response; waiting {value} milliseconds and trying again", - "_CurlResponseTruncatedRetrying.comment": "{value} is the number of milliseconds for which we are waiting this time", - "CurlTimeout": "curl was unable to perform all requested HTTP operations, even after timeout and retries. The last command line was: {command_line}", - "_CurlTimeout.comment": "An example of {command_line} is vcpkg install zlib.", + "CurlFailedToReturnExpectedNumberOfExitCodes": "curl failed to return the expected number of exit codes; this can happen if something terminates curl before it has finished. curl exited with {exit_code} which is normally the result code for the last operation, but may be the result of a crash. The command line was {command_line}, and all output is below:", + "_CurlFailedToReturnExpectedNumberOfExitCodes.comment": "An example of {exit_code} is 127. An example of {command_line} is vcpkg install zlib.", "CurrentCommitBaseline": "You can use the current commit as a baseline, which is:\n\t\"builtin-baseline\": \"{commit_sha}\"", "_CurrentCommitBaseline.comment": "An example of {commit_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", "CycleDetectedDuring": "cycle detected during {spec}:", @@ -588,31 +608,50 @@ "DocumentedFieldsSuggestUpdate": "If these are documented fields that should be recognized try updating the vcpkg tool.", "DownloadAvailable": "A downloadable copy of this tool is available and can be used by unsetting {env_var}.", "_DownloadAvailable.comment": "An example of {env_var} is VCPKG_DEFAULT_TRIPLET.", - "DownloadFailedCurl": "{url}: curl failed to download with exit code {exit_code}", - "_DownloadFailedCurl.comment": "An example of {url} is https://github.com/microsoft/vcpkg. An example of {exit_code} is 127.", - "DownloadFailedHashMismatch": "File does not have the expected hash:\nurl: {url}\nFile: {path}\nExpected hash: {expected}\nActual hash: {actual}", - "_DownloadFailedHashMismatch.comment": "{expected} and {actual} are SHA512 hashes in hex format. An example of {url} is https://github.com/microsoft/vcpkg. An example of {path} is /foo/bar.", - "DownloadFailedProxySettings": "Failed to download {path}.\nIf you are using a proxy, please ensure your proxy settings are correct.\nPossible causes are:\n1. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to `https//address:port`.\nThis is not correct, because `https://` prefix claims the proxy is an HTTPS proxy, while your proxy (v2ray, shadowsocksr, etc...) is an HTTP proxy.\nTry setting `http://address:port` to both HTTP_PROXY and HTTPS_PROXY instead.\n2. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your proxy software. See, {url}\nThe value set by your proxy might be wrong, or have same `https://` prefix issue.\n3. Your proxy's remote server is our of service.\nIf you've tried directly download the link, and believe this is not a temporay download server failure, please submit an issue at https://github.com/Microsoft/vcpkg/issues\nto report this upstream download server failure.", - "_DownloadFailedProxySettings.comment": "An example of {path} is /foo/bar. An example of {url} is https://github.com/microsoft/vcpkg.", - "DownloadFailedRetrying": "Download failed -- retrying after {value}ms", - "_DownloadFailedRetrying.comment": "{value} is a number of milliseconds", + "DownloadFailedHashMismatch": "download from {url} had an unexpected hash", + "_DownloadFailedHashMismatch.comment": "An example of {url} is https://github.com/microsoft/vcpkg.", + "DownloadFailedHashMismatchActualHash": "Actual : {sha}", + "_DownloadFailedHashMismatchActualHash.comment": "An example of {sha} is eb32643dd2164c72b8a660ef52f1e701bb368324ae461e12d70d6a9aefc0c9573387ee2ed3828037ed62bb3e8f566416a2d3b3827a3928f0bff7c29f7662293e.", + "DownloadFailedHashMismatchExpectedHash": "Expected: {sha}", + "_DownloadFailedHashMismatchExpectedHash.comment": "An example of {sha} is eb32643dd2164c72b8a660ef52f1e701bb368324ae461e12d70d6a9aefc0c9573387ee2ed3828037ed62bb3e8f566416a2d3b3827a3928f0bff7c29f7662293e.", + "DownloadFailedHashMismatchZero": "failing download because the expected SHA512 was all zeros, please change the expected SHA512 to: {sha}", + "_DownloadFailedHashMismatchZero.comment": "An example of {sha} is eb32643dd2164c72b8a660ef52f1e701bb368324ae461e12d70d6a9aefc0c9573387ee2ed3828037ed62bb3e8f566416a2d3b3827a3928f0bff7c29f7662293e.", + "DownloadFailedProxySettings": "If you are using a proxy, please ensure your proxy settings are correct.\nPossible causes are:\n1. You are actually using an HTTP proxy, but setting HTTPS_PROXY variable to `https//address:port`.\nThis is not correct, because `https://` prefix claims the proxy is an HTTPS proxy, while your proxy (v2ray, shadowsocksr, etc...) is an HTTP proxy.\nTry setting `http://address:port` to both HTTP_PROXY and HTTPS_PROXY instead.\n2. If you are using Windows, vcpkg will automatically use your Windows IE Proxy Settings set by your proxy software. See: https://github.com/microsoft/vcpkg-tool/pull/77\nThe value set by your proxy might be wrong, or have same `https://` prefix issue.\n3. Your proxy's remote server is our of service.\nIf you believe this is not a temporary download server failure and vcpkg needs to be changed to download this file from a different location, please submit an issue to https://github.com/Microsoft/vcpkg/issues", + "DownloadFailedRetrying": "Download {url} failed -- retrying after {value}ms", + "_DownloadFailedRetrying.comment": "{value} is a number of milliseconds An example of {url} is https://github.com/microsoft/vcpkg.", "DownloadFailedStatusCode": "{url}: failed: status code {value}", "_DownloadFailedStatusCode.comment": "{value} is an HTTP status code An example of {url} is https://github.com/microsoft/vcpkg.", + "DownloadOrUrl": "or {url}", + "_DownloadOrUrl.comment": "An example of {url} is https://github.com/microsoft/vcpkg.", "DownloadRootsDir": "Downloads directory (default: {env_var})", "_DownloadRootsDir.comment": "An example of {env_var} is VCPKG_DEFAULT_TRIPLET.", - "DownloadSuccesful": "Successfully downloaded {path}.", + "DownloadSuccesful": "Successfully downloaded {path}", "_DownloadSuccesful.comment": "An example of {path} is /foo/bar.", - "DownloadWinHttpError": "{url}: {system_api} failed with exit code {exit_code}", + "DownloadSuccesfulUploading": "Successfully downloaded {path}, storing to {url}", + "_DownloadSuccesfulUploading.comment": "An example of {path} is /foo/bar. An example of {url} is https://github.com/microsoft/vcpkg.", + "DownloadTryingAuthoritativeSource": "Trying {url}", + "_DownloadTryingAuthoritativeSource.comment": "An example of {url} is https://github.com/microsoft/vcpkg.", + "DownloadWinHttpError": "{url}: {system_api} failed with exit code {exit_code}.", "_DownloadWinHttpError.comment": "An example of {system_api} is CreateProcessW. An example of {exit_code} is 127. An example of {url} is https://github.com/microsoft/vcpkg.", "DownloadedSources": "Downloaded sources for {spec}", "_DownloadedSources.comment": "An example of {spec} is zlib:x64-windows.", + "DownloadingAssetShaToFile": "Downloading asset cache entry {sha} -> {path}", + "_DownloadingAssetShaToFile.comment": "An example of {sha} is eb32643dd2164c72b8a660ef52f1e701bb368324ae461e12d70d6a9aefc0c9573387ee2ed3828037ed62bb3e8f566416a2d3b3827a3928f0bff7c29f7662293e. An example of {path} is /foo/bar.", + "DownloadingAssetShaWithoutAssetCache": "requested download of asset cache entry {sha} -> {path}, but no asset caches are configured", + "_DownloadingAssetShaWithoutAssetCache.comment": "An example of {sha} is eb32643dd2164c72b8a660ef52f1e701bb368324ae461e12d70d6a9aefc0c9573387ee2ed3828037ed62bb3e8f566416a2d3b3827a3928f0bff7c29f7662293e. An example of {path} is /foo/bar.", + "DownloadingFile": "Downloading {path}", + "_DownloadingFile.comment": "An example of {path} is /foo/bar.", + "DownloadingFileFirstAuthoritativeSource": "Downloading {path}, trying {url}", + "_DownloadingFileFirstAuthoritativeSource.comment": "An example of {path} is /foo/bar. An example of {url} is https://github.com/microsoft/vcpkg.", "DownloadingPortableToolVersionX": "A suitable version of {tool_name} was not found (required v{version}).", - "_DownloadingPortableToolVersionX.comment": "An example of {tool_name} is aria2. An example of {version} is 1.3.8.", - "DownloadingUrl": "Downloading {url}", - "_DownloadingUrl.comment": "An example of {url} is https://github.com/microsoft/vcpkg.", + "_DownloadingPortableToolVersionX.comment": "An example of {tool_name} is signtool. An example of {version} is 1.3.8.", + "DownloadingUrlToFile": "Downloading {url} -> {path}", + "_DownloadingUrlToFile.comment": "An example of {url} is https://github.com/microsoft/vcpkg. An example of {path} is /foo/bar.", "DownloadingVcpkgStandaloneBundle": "Downloading standalone bundle {version}.", "_DownloadingVcpkgStandaloneBundle.comment": "An example of {version} is 1.3.8.", "DownloadingVcpkgStandaloneBundleLatest": "Downloading latest standalone bundle.", + "DuplicateDependencyOverride": "{package_name} already has an override", + "_DuplicateDependencyOverride.comment": "An example of {package_name} is zlib.", "DuplicatePackagePattern": "Package \"{package_name}\" is duplicated.", "_DuplicatePackagePattern.comment": "An example of {package_name} is zlib.", "DuplicatePackagePatternFirstOcurrence": "First declared in:", @@ -647,6 +686,9 @@ "_ErrorInvalidExtractOption.comment": "The keyword 'AUTO' should not be localized An example of {option} is editable.", "ErrorInvalidManifestModeOption": "The option --{option} is not supported in manifest mode.", "_ErrorInvalidManifestModeOption.comment": "An example of {option} is editable.", + "ErrorManifestMustDifferFromOverlay": "The manifest directory ({path}) cannot be the same as a directory configured in overlay-ports.", + "_ErrorManifestMustDifferFromOverlay.comment": "An example of {path} is /foo/bar.", + "ErrorManifestMustDifferFromOverlayDot": "The manifest directory cannot be the same as a directory configured in overlay-ports, so \"overlay-ports\" values cannot be \".\".", "ErrorMissingVcpkgRoot": "Could not detect vcpkg-root. If you are trying to use a copy of vcpkg that you've built, you must define the VCPKG_ROOT environment variable to point to a cloned copy of https://github.com/Microsoft/vcpkg.", "ErrorNoVSInstance": "in triplet {triplet}: Unable to find a valid Visual Studio instance", "_ErrorNoVSInstance.comment": "An example of {triplet} is x64-windows.", @@ -721,7 +763,7 @@ "_ExtendedDocumentationAtUrl.comment": "An example of {url} is https://github.com/microsoft/vcpkg.", "ExtractHelp": "Extracts an archive.", "ExtractingTool": "Extracting {tool_name}...", - "_ExtractingTool.comment": "An example of {tool_name} is aria2.", + "_ExtractingTool.comment": "An example of {tool_name} is signtool.", "FailedPostBuildChecks": "Found {count} post-build check problem(s). These are usually caused by bugs in portfile.cmake or the upstream build system. Please correct these before submitting this port to the curated registry.", "_FailedPostBuildChecks.comment": "An example of {count} is 42.", "FailedToAcquireMutant": "failed to acquire mutant {path}", @@ -763,10 +805,8 @@ "_FailedToParseSerializedBinParagraph.comment": "'{error_msg}' is the error message for failing to parse the Binary Paragraph. An example of {error_msg} is File Not Found.", "FailedToParseVersionFile": "Failed to parse version file: {path}", "_FailedToParseVersionFile.comment": "An example of {path} is /foo/bar.", - "FailedToParseVersionXML": "Could not parse version for tool {tool_name}. Version string was: {version}", - "_FailedToParseVersionXML.comment": "An example of {tool_name} is aria2. An example of {version} is 1.3.8.", "FailedToRunToolToDetermineVersion": "Failed to run \"{path}\" to determine the {tool_name} version.", - "_FailedToRunToolToDetermineVersion.comment": "Additional information, such as the command line output, if any, will be appended on the line after this message An example of {tool_name} is aria2. An example of {path} is /foo/bar.", + "_FailedToRunToolToDetermineVersion.comment": "Additional information, such as the command line output, if any, will be appended on the line after this message An example of {tool_name} is signtool. An example of {path} is /foo/bar.", "FailedToStoreBackToMirror": "Failed to store {path} to {url}.", "_FailedToStoreBackToMirror.comment": "An example of {path} is /foo/bar. An example of {url} is https://github.com/microsoft/vcpkg.", "FailedToStoreBinaryCache": "Failed to store binary cache {path}", @@ -781,8 +821,7 @@ "FieldKindDidNotHaveExpectedValue": "\"kind\" did not have an expected value: (expected one of: {expected}; found {actual})", "_FieldKindDidNotHaveExpectedValue.comment": "{expected} is a list of literal kinds the user must type, separated by commas, {actual} is what the user supplied", "FileIsNotExecutable": "this file does not appear to be executable", - "FileNotFound": "{path}: file not found", - "_FileNotFound.comment": "An example of {path} is /foo/bar.", + "FileNotFound": "file not found", "FileReadFailed": "Failed to read {count} bytes from {path} at offset {byte_offset}.", "_FileReadFailed.comment": "An example of {path} is /foo/bar. An example of {byte_offset} is 42. An example of {count} is 42.", "FileSeekFailed": "Failed to seek to position {byte_offset} in {path}.", @@ -843,8 +882,6 @@ "_GitUnexpectedCommandOutputCmd.comment": "An example of {command_line} is vcpkg install zlib.", "GraphCycleDetected": "Cycle detected within graph at {package_name}:", "_GraphCycleDetected.comment": "A list of package names comprising the cycle will be printed after this message. An example of {package_name} is zlib.", - "HashFileFailureToRead": "failed to read file \"{path}\" for hashing: ", - "_HashFileFailureToRead.comment": "Printed after ErrorMessage and before the specific failing filesystem operation (like file not found) An example of {path} is /foo/bar.", "HashPortManyFiles": "{package_name} contains {count} files. Hashing these contents may take a long time when determining the ABI hash for binary caching. Consider reducing the number of files. Common causes of this are accidentally checking out source or build files into a port's directory.", "_HashPortManyFiles.comment": "An example of {package_name} is zlib. An example of {count} is 42.", "HeaderOnlyUsage": "{package_name} is header-only and can be used from CMake via:", @@ -931,7 +968,6 @@ "HelpTxtOptOnlyBinCache": "Fails if cached binaries are not available", "HelpTxtOptOnlyDownloads": "Makes best-effort attempt to download sources without building", "HelpTxtOptRecurse": "Allows removal of packages as part of installation", - "HelpTxtOptUseAria2": "Uses aria2 to perform download tasks", "HelpTxtOptUseHeadVersion": "Installs the libraries on the command line using the latest upstream sources (classic mode)", "HelpTxtOptWritePkgConfig": "Writes a NuGet packages.config-formatted file for use with external binary caching. See `vcpkg help binarycaching` for more information", "_HelpTxtOptWritePkgConfig.comment": "'vcpkg help binarycaching' is a command line and should not be localized.", @@ -999,8 +1035,8 @@ "IntegrationFailedVS2015": "Integration was not applied for Visual Studio 2015.", "InternalCICommand": "vcpkg ci is an internal command which will change incompatibly or be removed at any time.", "InternalErrorMessageContact": "Please open an issue at https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug with detailed steps to reproduce the problem.", - "InvalidArchitecture": "invalid architecture: {value}", - "_InvalidArchitecture.comment": "{value} is what the user entered that we did not understand", + "InvalidArchitectureValue": "Invalid architecture: {value}. Expected one of: {expected}", + "_InvalidArchitectureValue.comment": "{value} is an unknown CPU architecture type, {expected} is the list of accepted CPU architecture values", "InvalidArgument": "invalid argument", "InvalidArgumentRequiresAbsolutePath": "invalid argument: binary config '{binary_source}' path arguments for binary config strings must be absolute", "_InvalidArgumentRequiresAbsolutePath.comment": "An example of {binary_source} is azblob.", @@ -1068,10 +1104,15 @@ "_InvalidOptionForRemove.comment": "'remove' is a command that should not be changed.", "InvalidPortVersonName": "Found invalid port version file name: `{path}`.", "_InvalidPortVersonName.comment": "An example of {path} is /foo/bar.", + "InvalidSha512": "invalid SHA-512 hash: {sha}\nSHA-512 hash must be 128 characters long and contain only hexadecimal digits", + "_InvalidSha512.comment": "An example of {sha} is eb32643dd2164c72b8a660ef52f1e701bb368324ae461e12d70d6a9aefc0c9573387ee2ed3828037ed62bb3e8f566416a2d3b3827a3928f0bff7c29f7662293e.", "InvalidSharpInVersion": "invalid character '#' in version text", "InvalidSharpInVersionDidYouMean": "invalid character '#' in version text. Did you mean \"port-version\": {value}?", "_InvalidSharpInVersionDidYouMean.comment": "{value} is an integer. `\"port-version\":' is JSON syntax and should be unlocalized", "InvalidString": "Invalid utf8 passed to Value::string(std::string)", + "InvalidToolOSValue": "Invalid tool operating system: {value}. Expected one of: {expected}", + "_InvalidToolOSValue.comment": "{value} is an unknown operating system, {expected} is the list of accepted operating system values", + "InvalidToolVersion": "Invalid tool version; expected a string containing a substring of between 1 and 3 numbers separated by dots.", "InvalidTriplet": "Invalid triplet: {triplet}", "_InvalidTriplet.comment": "An example of {triplet} is x64-windows.", "InvalidUri": "unable to parse uri: {value}", @@ -1095,7 +1136,7 @@ "JsonValueNotObject": "json value is not an object", "JsonValueNotString": "json value is not a string", "LaunchingProgramFailed": "Launching {tool_name}:", - "_LaunchingProgramFailed.comment": "A platform API call failure message is appended after this An example of {tool_name} is aria2.", + "_LaunchingProgramFailed.comment": "A platform API call failure message is appended after this An example of {tool_name} is signtool.", "LibraryArchiveMemberTooSmall": "A library archive member was too small to contain the expected data type.", "LibraryFirstLinkerMemberMissing": "Could not find first linker member name.", "LicenseExpressionContainsExtraPlus": "SPDX license expression contains an extra '+'. These are only allowed directly after a license identifier.", @@ -1141,7 +1182,7 @@ "MismatchedFiles": "file to store does not match hash", "MismatchedManifestAfterReserialize": "The serialized manifest was different from the original manifest. Please open an issue at https://github.com/microsoft/vcpkg, with the following output:", "_MismatchedManifestAfterReserialize.comment": "The original file output and generated output are printed after this line, in English as it's intended to be used in the issue submission and read by devs. This message indicates an internal error in vcpkg.", - "MismatchedNames": "names did not match: '{package_name}' != '{actual}'", + "MismatchedNames": "the port name declared in the metadata file did not match the directory. Expected the port to be named {package_name}, but the file declares {actual}.", "_MismatchedNames.comment": "{actual} is the port name found An example of {package_name} is zlib.", "MismatchedSpec": "Mismatched spec in port {path}: expected {expected}, actual {actual}", "_MismatchedSpec.comment": "{expected} and {actual} are package specs like 'zlib:x64-windows' An example of {path} is /foo/bar.", @@ -1152,8 +1193,6 @@ "MissingAndroidHomeDir": "ANDROID_NDK_HOME directory does not exist: {path}", "_MissingAndroidHomeDir.comment": "An example of {path} is /foo/bar.", "MissingArgFormatManifest": "format-manifest was passed --convert-control without '--all'.\nThis doesn't do anything: control files passed explicitly are converted automatically.", - "MissingAssetBlockOrigin": "Missing {path} and downloads are blocked by x-block-origin.", - "_MissingAssetBlockOrigin.comment": "x-block-origin is a vcpkg term. Do not translate An example of {path} is /foo/bar.", "MissingClosingParen": "missing closing )", "MissingDependency": "Package {spec} is installed, but dependency {package_name} is not.", "_MissingDependency.comment": "An example of {spec} is zlib:x64-windows. An example of {package_name} is zlib.", @@ -1192,8 +1231,6 @@ "NoOutdatedPackages": "There are no outdated packages.", "NoRegistryForPort": "no registry configured for port {package_name}", "_NoRegistryForPort.comment": "An example of {package_name} is zlib.", - "NoUrlsAndHashSpecified": "No urls specified to download SHA: {sha}", - "_NoUrlsAndHashSpecified.comment": "An example of {sha} is eb32643dd2164c72b8a660ef52f1e701bb368324ae461e12d70d6a9aefc0c9573387ee2ed3828037ed62bb3e8f566416a2d3b3827a3928f0bff7c29f7662293e.", "NoUrlsAndNoHashSpecified": "No urls specified and no hash specified.", "NonExactlyArgs": "the command '{command_name}' requires exactly {expected} arguments, but {actual} were provided", "_NonExactlyArgs.comment": "{expected} and {actual} are integers An example of {command_name} is install.", @@ -1227,10 +1264,10 @@ "_Options.comment": "Printed just before a list of options for a command", "OriginalBinParagraphHeader": "\nOriginal Binary Paragraph", "OtherCommandsHeader": "Other", - "OverlayPatchDir": "Overlay path \"{path}\" must exist and must be a directory.", + "OverlayPatchDir": "Overlay path \"{path}\" must be an existing directory.", "_OverlayPatchDir.comment": "An example of {path} is /foo/bar.", - "OverlayPortsDirectoriesHelp": "Directories of overlay ports (also: {env_var})", - "_OverlayPortsDirectoriesHelp.comment": "An example of {env_var} is VCPKG_DEFAULT_TRIPLET.", + "OverlayPortsHelp": "Overlay-port directories, or directories containing overlay-port directories (also: {env_var})", + "_OverlayPortsHelp.comment": "An example of {env_var} is VCPKG_DEFAULT_TRIPLET.", "OverlayTripletDirectoriesHelp": "Directories of overlay triplets (also: {env_var})", "_OverlayTripletDirectoriesHelp.comment": "An example of {env_var} is VCPKG_DEFAULT_TRIPLET.", "OverlayTriplets": "Overlay Triplets from \"{path}\":", @@ -1360,8 +1397,10 @@ "_PortsUpdated.comment": "An example of {count} is 42.", "PrebuiltPackages": "There are packages that have not been built. To build them run:", "PreviousIntegrationFileRemains": "Previous integration file was not removed.", + "ProgramPathReturnedNonzeroExitCode": "failed with exit code {exit_code}", + "_ProgramPathReturnedNonzeroExitCode.comment": "An example of {exit_code} is 127.", "ProgramReturnedNonzeroExitCode": "{tool_name} failed with exit code: ({exit_code}).", - "_ProgramReturnedNonzeroExitCode.comment": "The program's console output is appended after this. An example of {tool_name} is aria2. An example of {exit_code} is 127.", + "_ProgramReturnedNonzeroExitCode.comment": "The program's console output is appended after this. An example of {tool_name} is signtool. An example of {exit_code} is 127.", "ProvideExportType": "At least one of the following options are required: --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "Pushing {vendor} to \"{path}\" failed. Use --debug for more information.", "_PushingVendorFailed.comment": "An example of {vendor} is Azure. An example of {path} is /foo/bar.", @@ -1420,8 +1459,10 @@ "_SpecifyTargetArch.comment": "'vcpkg help triplet' is a command line that should not be localized An example of {env_var} is VCPKG_DEFAULT_TRIPLET.", "StartCodeUnitInContinue": "found start code unit in continue position", "StoreOptionMissingSha": "--store option is invalid without a sha512", - "StoredBinariesToDestinations": "Stored binaries in {count} destinations in {elapsed}.", - "_StoredBinariesToDestinations.comment": "An example of {count} is 42. An example of {elapsed} is 3.532 min.", + "SubmittingBinaryCacheBackground": "Starting submission of {spec} to {count} binary cache(s) in the background", + "_SubmittingBinaryCacheBackground.comment": "An example of {spec} is zlib:x64-windows. An example of {count} is 42.", + "SubmittingBinaryCacheComplete": "Completed submission of {spec} to {count} binary cache(s) in {elapsed}", + "_SubmittingBinaryCacheComplete.comment": "An example of {spec} is zlib:x64-windows. An example of {count} is 42. An example of {elapsed} is 3.532 min.", "SuccessfulyExported": "Exported {package_name} to {path}", "_SuccessfulyExported.comment": "An example of {package_name} is zlib. An example of {path} is /foo/bar.", "SuggestGitPull": "The result may be outdated. Run `git pull` to get the latest results.", @@ -1441,11 +1482,15 @@ "_ToRemovePackages.comment": "An example of {command_name} is install.", "ToUpdatePackages": "To update these packages and all dependencies, run\n{command_name} upgrade'", "_ToUpdatePackages.comment": "An example of {command_name} is install.", + "ToolDataFileSchemaVersionNotSupported": "document schema version {version} is not supported by this version of vcpkg", + "_ToolDataFileSchemaVersionNotSupported.comment": "An example of {version} is 1.3.8.", "ToolFetchFailed": "Could not fetch {tool_name}.", - "_ToolFetchFailed.comment": "An example of {tool_name} is aria2.", + "_ToolFetchFailed.comment": "An example of {tool_name} is signtool.", + "ToolHashMismatch": "{tool_name} appears to be already downloaded, but has an incorrect hash. Expected {expected} but was {actual}", + "_ToolHashMismatch.comment": "{expected} and {actual} are SHA512 hashes in hex format. An example of {tool_name} is signtool.", "ToolInWin10": "This utility is bundled with Windows 10 or later.", "ToolOfVersionXNotFound": "A suitable version of {tool_name} was not found (required v{version}) and unable to automatically download a portable one. Please install a newer version of {tool_name}", - "_ToolOfVersionXNotFound.comment": "An example of {tool_name} is aria2. An example of {version} is 1.3.8.", + "_ToolOfVersionXNotFound.comment": "An example of {tool_name} is signtool. An example of {version} is 1.3.8.", "TotalInstallTime": "Total install time: {elapsed}", "_TotalInstallTime.comment": "An example of {elapsed} is 3.532 min.", "TotalInstallTimeSuccess": "All requested installations completed successfully in: {elapsed}", @@ -1506,7 +1551,7 @@ "UnexpectedSwitch": "unexpected switch: {option}", "_UnexpectedSwitch.comment": "Switch is a command line switch like --switch An example of {option} is editable.", "UnexpectedToolOutput": "{tool_name} ({path}) produced unexpected output when attempting to determine the version:", - "_UnexpectedToolOutput.comment": "The actual command line output will be appended after this message. An example of {tool_name} is aria2. An example of {path} is /foo/bar.", + "_UnexpectedToolOutput.comment": "The actual command line output will be appended after this message. An example of {tool_name} is signtool. An example of {path} is /foo/bar.", "UnexpectedWindowsArchitecture": "unexpected Windows host architecture: {actual}", "_UnexpectedWindowsArchitecture.comment": "{actual} is the CPU kind we observed like ARM or MIPS", "UnknownBaselineFileContent": "unrecognizable baseline entry; expected 'port:triplet=(fail|skip|pass)'", @@ -1559,7 +1604,7 @@ "UpgradeInManifest": "Upgrade upgrades a classic mode installation and thus does not support manifest mode. Consider updating your dependencies by updating your baseline to a current value with vcpkg x-update-baseline and running vcpkg install.", "_UpgradeInManifest.comment": "'vcpkg x-update-baseline' and 'vcpkg install' are command lines and should not be localized.", "UpgradeRunWithNoDryRun": "If you are sure you want to rebuild the above packages, run this command with the --no-dry-run option.", - "UploadingBinariesToVendor": "Uploading binaries for '{spec}' to '{vendor}' source \"{path}\".", + "UploadingBinariesToVendor": "Uploading binaries for {spec} to {vendor} from {path}", "_UploadingBinariesToVendor.comment": "An example of {spec} is zlib:x64-windows. An example of {vendor} is Azure. An example of {path} is /foo/bar.", "UsageInstallInstructions": "you can install the usage file with the following CMake", "UsageTextHere": "the usage file is here", @@ -1603,8 +1648,6 @@ "_VersionBuiltinPortTreeEntryMissing.comment": "{expected} and {actual} are versions like 1.0. An example of {package_name} is zlib.", "VersionCommandHeader": "vcpkg package management program version {version}\n\nSee LICENSE.txt for license information.", "_VersionCommandHeader.comment": "An example of {version} is 1.3.8.", - "VersionConflictXML": "Expected {path} version: [{expected_version}], but was [{actual_version}]. Please re-run bootstrap-vcpkg.", - "_VersionConflictXML.comment": "An example of {path} is /foo/bar. An example of {expected_version} is 1.3.8. An example of {actual_version} is 1.3.8.", "VersionConstraintNotInDatabase1": "the \"version>=\" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.", "_VersionConstraintNotInDatabase1.comment": "An example of {package_name} is zlib. An example of {version} is 1.3.8.", "VersionConstraintNotInDatabase2": "consider removing the version constraint or choosing a value declared here", @@ -1683,6 +1726,8 @@ "_VersionSpecMismatch.comment": "An example of {path} is /foo/bar. An example of {expected_version} is 1.3.8. An example of {actual_version} is 1.3.8.", "VersionVerifiedOK": "{version_spec} is correctly in the version database ({git_tree_sha})", "_VersionVerifiedOK.comment": "An example of {version_spec} is zlib:x64-windows@1.0.0. An example of {git_tree_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", + "WaitUntilPackagesUploaded": "Waiting for {count} remaining binary cache submissions...", + "_WaitUntilPackagesUploaded.comment": "An example of {count} is 42.", "WaitingForChildrenToExit": "Waiting for child processes to exit...", "WaitingToTakeFilesystemLock": "waiting to take filesystem lock on {path}...", "_WaitingToTakeFilesystemLock.comment": "An example of {path} is /foo/bar.", @@ -1702,6 +1747,7 @@ "_WhileLookingForSpec.comment": "An example of {spec} is zlib:x64-windows.", "WhileParsingVersionsForPort": "while parsing versions for {package_name} from {path}", "_WhileParsingVersionsForPort.comment": "An example of {package_name} is zlib. An example of {path} is /foo/bar.", + "WhileRunningAssetCacheScriptCommandLine": "while running asset cache script command line", "WhileValidatingVersion": "while validating version: {version}", "_WhileValidatingVersion.comment": "An example of {version} is 1.3.8.", "WindowsOnlyCommand": "This command only supports Windows.", diff --git a/locales/messages.ko.json b/locales/messages.ko.json index 9970ba3c6d..a92c58d05c 100644 --- a/locales/messages.ko.json +++ b/locales/messages.ko.json @@ -4,6 +4,7 @@ "ABoolean": "부울", "ABuiltinRegistry": "기본 제공 레지스트리", "AConfigurationObject": "구성 개체", + "ACpuArchitecture": "CPU 아키텍처", "ADateVersionString": "날짜 버전 문자열", "ADefaultFeature": "기본 기능", "ADemandObject": "수요 대상", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "편안한 버전 문자열", "ASemanticVersionString": "의미론적 버전 문자열", "ASetOfFeatures": "일련의 기능", + "ASha512": "SHA-512 해시", "AString": "문자열", "AStringOrArrayOfStrings": "문자열 또는 문자열 배열", "AStringStringDictionary": "\"string\": \"string\" 사전", + "AToolDataArray": "도구 메타데이터 배열", + "AToolDataFile": "도구 데이터 파일", + "AToolDataOS": "도구 데이터 운영 체제", + "AToolDataObject": "도구 메타데이터", + "AToolDataVersion": "도구 데이터 버전", "AUrl": "URL", "AVcpkgRepositoryCommit": "vcpkg 리포지토리 커밋", "AVersionConstraint": "버전 제약 조건", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "아티팩트 획득 시 Windows에 호스트 감지 강제 적용", "ArtifactsSwitchX64": "아티팩트 획득 시 x64에 호스트 감지 강제 적용", "ArtifactsSwitchX86": "아티팩트 획득 시 x86에 호스트 감지 강제 적용", - "AssetCacheHit": "{path}에 대한 자산 캐시; 다음으로 부터 다운로드함: {url}", - "AssetCacheMiss": "자산 캐시 누락; {url}에서 다운로드하는 중", - "AssetCacheMissBlockOrigin": "{path} 및 다운로드에 대한 자산 캐시 누락이 x-block-origin에 의해 차단됩니다.", + "AssetCacheConsult": "자산 캐시 {url} 사용하여 {path} 다운로드하려고 합니다.", + "AssetCacheConsultScript": "자산 캐시 스크립트를 사용하여 {path} 다운로드하는 중", + "AssetCacheHit": "다운로드 성공! 자산 캐시 적중.", + "AssetCacheHitUrl": "다운로드 성공! 자산 캐시 적중, 신뢰할 수 있는 원본 {url} 시도하지 않음", + "AssetCacheMiss": "자산 캐시 누락; 신뢰할 수 있는 원본 {url} 시도 중", + "AssetCacheMissBlockOrigin": "자산 캐시 적중 횟수 및 신뢰할 수 있는 원본 {url} 시도하는 x 블록 원본 블록이 없습니다.", + "AssetCacheMissNoUrls": "자산 캐시에서 {sha} 찾지 못했으며 신뢰할 수 있는 URL을 알 수 없습니다.", "AssetCacheProviderAcceptsNoArguments": "예기치 않은 인수: '{value}'에는 인수가 허용되지 않음", - "AssetCacheSuccesfullyStored": "{path}을(를) {url}에 저장했습니다.", + "AssetCacheScriptBadVariable": "스크립트 템플릿 {value} 알 수 없는 대체 {list} 포함되어 있습니다.", + "AssetCacheScriptBadVariableHint": "리터럴 명령줄에서 원하는 경우 {{{{{list}}}}}을(를) 사용하세요.", + "AssetCacheScriptCommandLine": "전체 스크립트 명령줄이", + "AssetCacheScriptFailed": "자산 캐시 스크립트가 0이 아닌 종료 코드 {exit_code} 반환했습니다.", + "AssetCacheScriptFailedToWriteCorrectHash": "자산 캐시 스크립트가 성공을 반환했지만 결과 파일에 예기치 않은 해시가 있습니다.", + "AssetCacheScriptFailedToWriteFile": "자산 캐시 스크립트가 성공을 반환했지만 필요한 결과 파일을 만들지 못했습니다.", + "AssetCacheScriptNeedsSha": "스크립트 템플릿 {value} SHA가 필요하지만 {url} 다운로드를 시도하는 것으로 알려진 SHA가 없습니다.", + "AssetCacheScriptNeedsUrl": "스크립트 템플릿 {value} URL이 필요하지만 {sha} 다운로드를 시도하는 것으로 알려진 URL이 없습니다.", + "AssetCacheSuccesfullyStored": "저장소 성공", "AssetSourcesArg": "자산 캐싱 원본. 'vcpkg help assetcaching' 참조", "AttemptingToSetBuiltInBaseline": "vcpkg-configuration.json.에서 기본 레지스트리를 재정의하는 동안 vcpkg.json에서 기본 제공 기준을 설정하려고 합니다.\nvcpkg-configuration.json의 기본 레지스트리가 사용됩니다.", "AuthenticationMayRequireManualAction": "하나 이상의 {vendor} 자격 증명 제공자가 직접 조치를 요청했습니다. 상호 작용을 허용하려면 이진 파일 원본 'interactive'를 추가하세요.", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "모든 경로에서 제거할 선행 디렉터리 수", "CommandEnvExample2": "vcpkg env \"ninja -C <경로>\" --triplet x64-windows", "CommandFailed": "명령:\n{command_line}\n다음 출력으로 실패했습니다.", - "CommandFailedCode": "명령:\n{command_line}\n종료 코드 {exit_code} 및 다음 출력으로 실패했습니다.", "CommunityTriplets": "커뮤니티 Triplets:", "CompilerPath": "컴파일러 찾음: {path}", - "CompressFolderFailed": "폴더 \"{path}\"을(를) 압축하지 못했습니다.", "ComputingInstallPlan": "설치 계획을 계산하는 중...", "ConfigurationErrorRegistriesWithoutBaseline": "{path}에 정의된 구성이 잘못되었습니다.\n\n레지스트리를 사용하려면 기본 레지스트리에 대한 기준이 설정되어 있거나 기본 레지스트리가 null여야 합니다.\n\n자세한 내용은 {url}을(를) 참조하세요.", "ConfigurationNestedDemands": "[\"{json_field}\"]에 중첩된 'demands' 개체가 포함되어 있습니다(중첩된 'demands'는 효과가 없음).", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "파일 이름에서 nuget ID 및 버전을 추론할 수 없음: {path}", "CouldNotFindBaselineInCommit": "{package_name} 관련 {commit_sha}의 {url}에서 기준을 찾을 수 없습니다.", "CouldNotFindGitTreeAtCommit": "{commit_sha} 커밋의 리포지토리 {package_name}에서 '버전'에 대한 git 트리를 찾을 수 없습니다.", - "CouldNotFindToolVersion": "{path}에서 을(를) 찾을 수 없습니다.", "CouldNotFindVersionDatabaseFile": "버전 데이터베이스 파일을 찾을 수 없습니다. {path}", "CreateFailureLogsDir": "오류 로그 출력 디렉터리 {path}을(를) 만드는 중입니다.", "CreatedNuGetPackage": "생성된 nupkg: {path}", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "NuGet 패키지 생성 중...", "CreatingZipArchive": "zip 보관함 생성 중...", "CreationFailed": "{path} 생성에 실패했습니다.", + "CurlFailedGeneric": "오류 코드 {exit_code} 때문에 curl 작업이 실패했습니다.", "CurlFailedToPut": "curl이 종료 코드 {exit_code}(으)로 파일을 {url}에 넣지 못했습니다.", "CurlFailedToPutHttp": "curl이 종료 코드 {exit_code} 및 http 코드 {value}(으)로 파일을 {url}에 넣지 못했습니다.", - "CurlResponseTruncatedRetrying": "curl이 부분 응답을 반환했습니다. {value}밀리초를 기다린 후 다시 시도", - "CurlTimeout": "시간 제한 및 다시 시도 후에도 curl에서 요청된 모든 HTTP 작업을 수행할 수 없습니다. 마지막 명령줄은 {command_line}입니다.", + "CurlFailedToReturnExpectedNumberOfExitCodes": "curl이 예상 종료 코드 수를 반환하지 못했습니다. 이 문제는 완료되기 전에 말린 항목이 종료될 경우 발생할 수 있습니다. 일반적으로 마지막 작업의 결과 코드인 {exit_code} 포함된 curl이 종료되었지만 충돌의 결과일 수 있습니다. 명령줄이 {command_line} 모든 출력이 아래와 같습니다.", "CurrentCommitBaseline": "현재 커밋을 기준으로 사용할 수 있음:\n\t\"builtin-baseline\": \"{commit_sha}\"", "CycleDetectedDuring": "{spec} 동안 검색된 주기:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "환경 변수 VCPKG_DEFAULT_BINARY_CACHE는 디렉터리여야 함(이전: {path})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "DLL은 여기서 ${{CURRENT_PACKAGES_DIR}}에 상대적입니다.", "DocumentedFieldsSuggestUpdate": "인식되어야 하는 문서화된 필드인 경우 vcpkg 도구를 업데이트해 보세요.", "DownloadAvailable": "이 도구의 다운로드 가능한 사본을 사용할 수 있으며 {env_var} 설정을 해제하여 사용할 수 있습니다.", - "DownloadFailedCurl": "{url}: curl이 종료 코드 {exit_code}(으)로 다운로드하지 못함", - "DownloadFailedHashMismatch": "파일에 필요한 해시가 없습니다.\nURL: {url}\n파일: {path}\n필요한 해시: {expected}\n실제 해시: {actual}", - "DownloadFailedProxySettings": "{path}을(를) 다운로드하지 못했습니다.\n프록시를 사용하는 경우 프록시 설정이 올바른지 확인하세요.\n가능한 원인:\n1. 실제로 HTTP 프록시를 사용하지만 HTTPS_PROXY 변수를 'https//address:port'로 설정합니다.\n'https://' 접두사는 프록시가 HTTPS 프록시라고 클레임하고 프록시(v2ray, shadowsocksr 등...)는 HTTP 프록시이기 때문에 올바르지 않습니다.\n대신 'http://address:port'를 HTTP_PROXY와 HTTPS_PROXY 모두로 설정해 보세요.\n2. Windows를 사용하는 경우 vcpkg는 프록시 소프트웨어에서 설정한 Windows IE 프록시 설정을 자동으로 사용합니다. 참조, {url}\n프록시에서 설정한 값이 잘못되었거나 동일한 'https://' 접두사 문제가 있을 수 있습니다.\n3. 프록시의 원격 서버는 사용할 수 없습니다.\n링크를 직접 다운로드하려고 해보았고 일시적인 다운로드 서버 오류가 아닌 것으로 생각되면 https://github.com/Microsoft/vcpkg/issues로 문제를 제출하여\n이 업스트림 다운로드 서버 오류를 보고하세요.", - "DownloadFailedRetrying": "다운로드 실패 -- {value}ms 후에 다시 시도 중", + "DownloadFailedHashMismatch": "예기치 않은 해시가 {url} 다운로드", + "DownloadFailedHashMismatchActualHash": "실제 : {sha}", + "DownloadFailedHashMismatchExpectedHash": "예상: {sha}", + "DownloadFailedHashMismatchZero": "예상 SHA512가 모두 0이므로 다운로드에 실패했습니다. 필요한 SHA512를 다음으로 변경하세요. {sha}", + "DownloadFailedProxySettings": "프록시를 사용하는 경우 프록시 설정이 올바른지 확인하세요.\n가능한 원인:\n1. 실제로 HTTP 프록시를 사용하지만 HTTPS_PROXY 변수를 'https//address:port'로 설정합니다.\n'https://' 접두사는 프록시가 HTTPS 프록시라고 클레임하고 프록시(v2ray, shadowsocksr 등...)는 HTTP 프록시이므로 올바르지 않습니다.\n대신 `http://address:port`를 HTTP_PROXY 및 HTTPS_PROXY 둘 다로 설정해 보세요.\n2. Windows를 사용하는 경우 vcpkg는 프록시 소프트웨어에서 설정한 Windows IE 프록시 설정을 자동으로 사용합니다. 참조: https://github.com/microsoft/vcpkg-tool/pull/77\n프록시에서 설정한 값이 잘못되었거나 동일한 'https://' 접두사 문제가 있을 수 있습니다.\n3. 프록시의 원격 서버는 사용할 수 없습니다.\n일시적인 다운로드 서버 오류가 아니고 다른 위치에서 이 파일을 다운로드하기 위해 vcpkg를 변경해야 한다고 생각되면 https://github.com/Microsoft/vcpkg/issues에 문제를 제출하세요.", + "DownloadFailedRetrying": "{url} 다운로드 실패 -- {value}ms 후 다시 시도 중", "DownloadFailedStatusCode": "{url}: 실패: 상태 코드 {value}", + "DownloadOrUrl": "또는 {url}", "DownloadRootsDir": "디렉터리 다운로드(기본값: {env_var})", "DownloadSuccesful": "{path}을(를) 다운로드했습니다.", + "DownloadSuccesfulUploading": "{path} 다운로드하여 {url}", + "DownloadTryingAuthoritativeSource": "{url} 시도 중", "DownloadWinHttpError": "{url}: 종료 코드 {exit_code}(으)로 {system_api}이(가) 실패했습니다.", "DownloadedSources": "{spec}에 대한 다운로드 소스", + "DownloadingAssetShaToFile": "자산 캐시 항목 다운로드 {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "-> {path} {sha} 자산 캐시 항목의 다운로드를 요청했지만 자산 캐시가 구성되지 않았습니다.", + "DownloadingFile": "{path} 다운로드 중", + "DownloadingFileFirstAuthoritativeSource": "{path} 다운로드 중, {url} 시도 중", "DownloadingPortableToolVersionX": "적합한 버전의 {tool_name}을(를) 찾을 수 없습니다(v{version} 필요).", - "DownloadingUrl": "{url} 다운로드 중", + "DownloadingUrlToFile": "{url} 다운로드 중 -> {path}", "DownloadingVcpkgStandaloneBundle": "독립 실행형 번들 {version}을(를) 다운로드하는 중입니다.", "DownloadingVcpkgStandaloneBundleLatest": "최신 독립 실행형 번들을 다운로드하는 중입니다.", + "DuplicateDependencyOverride": "{package_name} 이미 재정의가 있습니다.", "DuplicatePackagePattern": "패키지 \"{package_name}\"이(가) 중복되었습니다.", "DuplicatePackagePatternFirstOcurrence": "첫 번째 선언 위치:", "DuplicatePackagePatternIgnoredLocations": "다음 다시 선언은 무시됩니다.", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "--{option} 옵션은 클래식 모드에서 지원되지 않으며 매니페스트를 찾을 수 없습니다.", "ErrorInvalidExtractOption": "--{option}은(는) 음이 아닌 정수 또는 'AUTO'로 설정해야 합니다.", "ErrorInvalidManifestModeOption": "--{option} 옵션은 매니페스트 모드에서 지원되지 않습니다.", + "ErrorManifestMustDifferFromOverlay": "매니페스트 디렉터리({path})는 오버레이 포트에 구성된 디렉터리와 같을 수 없습니다.", + "ErrorManifestMustDifferFromOverlayDot": "매니페스트 디렉터리는 오버레이 포트에 구성된 디렉터리와 같을 수 없으므로 \"overlay-ports\" 값은 \".\"일 수 없습니다.", "ErrorMissingVcpkgRoot": "vcpkg-root를 감지할 수 없습니다. 빌드한 vcpkg 복사본을 사용하려는 경우 https://github.com/Microsoft/vcpkg의 복제된 복사본을 가리키도록 VCPKG_ROOT 환경 변수를 정의해야 합니다.", "ErrorNoVSInstance": "삼중항 {triplet}에서: 유효한 Visual Studio 인스턴스를 찾을 수 없습니다.", "ErrorNoVSInstanceAt": "\"{path}\"에서", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "{path}을(를) 구문 분석하지 못했습니다. 'version' 배열이 필요합니다.", "FailedToParseSerializedBinParagraph": "[정상 검사] 직렬화된 이진 단락을 구문 분석하지 못했습니다.\nhttps://github.com/microsoft/vcpkg에서 다음 출력과 함께 문제를 여세요.\n{error_msg}\n직렬화된 이진 단락:", "FailedToParseVersionFile": "버전 파일을 구문 분석하지 못했습니다. {path}", - "FailedToParseVersionXML": "{tool_name} 도구의 버전을 구문 분석할 수 없습니다. 버전 문자열: {version}", "FailedToRunToolToDetermineVersion": "{tool_name} 버전을 확인하기 위해 “{path}:을(를) 실행하지 못했습니다.", "FailedToStoreBackToMirror": "{url}을(를) {path}에 저장하지 못했습니다.", "FailedToStoreBinaryCache": "이진 캐시 {path}을(를) 저장하지 못함", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "{url}({value})에서 레지스트리 정보를 가져오는 중...", "FieldKindDidNotHaveExpectedValue": "\"kind\"에 필요한 값이 없습니다(필요한 값: {expected} 중 하나, 찾은 값 {actual})", "FileIsNotExecutable": "이 파일은 실행 파일이 아닌 것 같습니다.", - "FileNotFound": "{path}: 파일을 찾을 수 없습니다.", + "FileNotFound": "파일을 찾을 수 없음", "FileReadFailed": "오프셋 {byte_offset}의 {path}에서 {count}바이트를 읽지 못했습니다.", "FileSeekFailed": "{path}에서 {byte_offset} 위치를 찾지 못했습니다.", "FilesContainAbsolutePath1": "설치된 패키지에는 다음과 같은 절대 경로가 없어야 합니다. 이 메시지를 표시하지 않도록 설정하려면 set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)을 추가합니다.", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "알 수 없는 파일 상태: {value}", "GitUnexpectedCommandOutputCmd": "{command_line}을(를) 실행할 때 git에서 예기치 않은 출력이 생성되었음", "GraphCycleDetected": "{package_name}의 그래프 내에서 감지된 주기:", - "HashFileFailureToRead": "해시에 대한 파일 \"{path}\"을(를) 읽지 못했습니다. ", "HashPortManyFiles": "{package_name}에 {count}개의 파일이 포함되어 있습니다. 이진 캐싱에 대한 ABI 해시를 확인할 때 이러한 콘텐츠를 해시하는 데 시간이 오래 걸릴 수 있습니다. 파일 수를 줄이는 것이 좋습니다. 일반적인 원인은 포트의 디렉터리에 소스 또는 빌드 파일을 실수로 체크 아웃하는 것입니다.", "HeaderOnlyUsage": "{package_name}은 헤더 전용이며 다음을 통해 CMake에서 사용할 수 있습니다.", "HelpAssetCaching": "**실험적 기능: 이 기능은 언제든지 변경되거나 제거될 수 있습니다**\n\nvcpkg는 미러를 사용하여 다운로드한 자산을 캐시할 수 있으므로 원본 원본이 변경되거나 사라지더라도 계속 작동할 수 있습니다.\n\n자산 캐싱은 환경 변수 X_VCPKG_ASSET_SOURCES를 세미콜론으로 구분된 원본 목록으로 설정하거나 일련의 --x-asset-sources= 명령줄 옵션을 전달하여 구성할 수 있습니다. 명령줄 원본은 환경 원본 다음에 해석됩니다. 쉼표, 세미콜론 및 백틱은 백틱(`)을 사용하여 이스케이프 처리할 수 있습니다.\n\n특정 문자열에 대한 선택적 매개 변수는 액세스 방법을 제어합니다. \"읽기\", \"쓰기\" 또는 \"읽기쓰기\"로 지정할 수 있으며 기본값은 \"읽기\"입니다.\n\n유효한 원본:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "캐시된 이진 파일을 사용할 수 없는 경우 실패", "HelpTxtOptOnlyDownloads": "빌드하지 않고 원본을 다운로드하기 위해 최선을 다함", "HelpTxtOptRecurse": "설치의 일부로 패키지 제거 허용", - "HelpTxtOptUseAria2": "aria2를 사용하여 다운로드 작업 수행합", "HelpTxtOptUseHeadVersion": "최신 업스트림 원본(클래식 모드)를 사용하여 명령줄에 라이브러리 설치", "HelpTxtOptWritePkgConfig": "외부 이진 캐싱에 사용할 NuGet packages.config 형식 파일을 작성합니다. 자세한 내용은 `vcpkg help binarycaching` 참조", "HelpUpdateBaseline": "라이브러리를 최신 상태로 유지하는 가장 좋은 방법은 기준 참조를 업데이트하는 것입니다. 이렇게 하면 전이 패키지를 포함한 모든 패키지가 업데이트됩니다. 하지만 패키지를 독립적으로 업데이트해야 하는 경우 \"version>=\" 제약 조건을 사용할 수 있습니다.", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "Visual Studio 2015에 통합이 적용되지 않았습니다.", "InternalCICommand": "vcpkg ci는 호환되지 않는 방식으로 변경되거나 언제든지 제거될 내부 명령입니다.", "InternalErrorMessageContact": "https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug에서 문제를 재현하기 위한 자세한 단계와 함께 문제를 여세요.", - "InvalidArchitecture": "잘못된 아키텍처: {value}", + "InvalidArchitectureValue": "잘못된 아키텍처: {value}. 다음 중 하나가 필요합니다. {expected}", "InvalidArgument": "잘못된 인수", "InvalidArgumentRequiresAbsolutePath": "잘못된 인수: 이진 구성 문자열의 이진 구성 '{binary_source}' 경로 인수는 절대 인수여야 함", "InvalidArgumentRequiresBaseUrl": "잘못된 인수: 이진 구성 '{binary_source}'에는 첫 번째 인수로 {base_url} 기본 URL이 필요함", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "논리 식이 잘못되었습니다. 'or' 대신 '|'를 사용하세요.", "InvalidOptionForRemove": "'remove'는 라이브러리 또는 '--outdated'를 수락합니다.", "InvalidPortVersonName": "잘못된 포트 버전 파일 이름 '{path}'을(를) 찾았습니다.", + "InvalidSha512": "잘못된 SHA-512 해시: {sha}\nSHA-512 해시는 128자여야 하며 16진수만 포함해야 합니다.", "InvalidSharpInVersion": "버전 텍스트에 잘못된 문자 '#'", "InvalidSharpInVersionDidYouMean": "버전 텍스트에 잘못된 문자 '#'이 있습니다. \"port-version\" 값이 {value}임을 의미하나요?", "InvalidString": "Value::string(std::string)에 잘못된 utf8이 전달되었습니다.", + "InvalidToolOSValue": "도구 운영 체제가 잘못되었습니다. {value}. 다음 중 하나가 필요합니다. {expected}", + "InvalidToolVersion": "도구 버전이 잘못되었습니다. 점으로 구분된 1~007E;3개의 하위 문자열을 포함하는 문자열이 필요합니다.", "InvalidTriplet": "유효하지 않은 삼중자: {triplet}", "InvalidUri": "URI를 구문 분석할 수 없음: {value}", "InvalidValueHashAdditionalFiles": "변수 VCPKG_HASH_ADDITIONAL_FILES는 잘못된 파일 경로 '{path}'을(를) 포함합니다. 값은 기존 파일의 절대 경로여야 합니다.", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "직렬화된 이진 단락이 원래 이진 단락과 다릅니다. https://github.com/microsoft/vcpkg에서 다음 출력으로 문제를 여세요.", "MismatchedFiles": "저장할 파일이 해시와 일치하지 않습니다.", "MismatchedManifestAfterReserialize": "직렬화된 매니페스트가 원래 매니페스트와 다릅니다. https://github.com/microsoft/vcpkg에서 다음 출력으로 문제를 보고하세요.", - "MismatchedNames": "이름이 일치하지 않습니다. '{package_name}' != '{actual}'", + "MismatchedNames": "메타데이터 파일에 선언된 포트 이름이 디렉터리와 일치하지 않습니다. 이름이 {package_name} 포트가 필요한데 파일이 {actual} 선언합니다.", "MismatchedSpec": "포트 {path}의 사양이 일치하지 않습니다. {expected} 필요, 실제 {actual}", "MismatchedType": "{json_field}: 일치하지 않는 유형: 예상 {json_type}", "Missing7zHeader": "7z 헤더를 찾을 수 없습니다.", "MissingAndroidEnv": "ANDROID_NDK_HOME 환경 변수가 없음", "MissingAndroidHomeDir": "ANDROID_NDK_HOME 디렉터리가 존재하지 않습니다: {path}", "MissingArgFormatManifest": "format-manifest가 '--all' 없이 --convert-control로 전달되었습니다.\n아무 작업도 수행하지 않습니다: 명시적으로 전달된 제어 파일은 자동으로 변환됩니다.", - "MissingAssetBlockOrigin": "{path}이(가) 누락되고 다운로드가 x-block-origin에 의해 차단됩니다.", "MissingClosingParen": "닫는 )가 없습니다.", "MissingDependency": "패키지 {spec}이(가) 설치되었지만 종속성 {package_name}이(가) 없습니다.", "MissingExtension": "'{extension}' 확장이 없습니다.", @@ -814,7 +841,6 @@ "NoInstalledPackages": "패키지가 설치되어 있지 않습니다. 의도한 명령이 `search`인가요?", "NoOutdatedPackages": "오래된 패키지가 없습니다.", "NoRegistryForPort": "{package_name} 포트에 대해 구성된 레지스트리가 없습니다.", - "NoUrlsAndHashSpecified": "SHA를 다운로드하도록 지정된 URL이 없습니다. {sha}", "NoUrlsAndNoHashSpecified": "URL이 지정되지 않았으며 해시가 지정되지 않았습니다.", "NonExactlyArgs": "'{command_name}' 명령에는 인수가 정확히 {expected}개 필요하지만, {actual}개가 제공되었습니다.", "NonOneRemainingArgs": "'{command_name}' 명령에는 정확히 인수가 1개 필요합니다.", @@ -834,8 +860,8 @@ "Options": "옵션", "OriginalBinParagraphHeader": "\n원래 이진 단락", "OtherCommandsHeader": "기타", - "OverlayPatchDir": "오버레이 경로 \"{path}\" 는 존재해야 하며 디렉터리여야 합니다.", - "OverlayPortsDirectoriesHelp": "오버레이 포트의 디렉터리(또한: {env_var})", + "OverlayPatchDir": "오버레이 경로 \"{path}\" 기존 디렉터리여야 합니다.", + "OverlayPortsHelp": "오버레이 포트 디렉터리 또는 오버레이 포트 디렉터리가 포함된 디렉터리({env_var})", "OverlayTripletDirectoriesHelp": "오버레이 삼중 항목의 디렉터리(또한: {env_var})", "OverlayTriplets": "{path}의 오버레이 Triplets", "OverwritingFile": "파일 {path}이(가) 이미 있으며 덮어쓰여집니다.", @@ -927,6 +953,7 @@ "PortsUpdated": "다음 {count}개 포트가 업데이트되었습니다.", "PrebuiltPackages": "빌드되지 않은 패키지가 있습니다. 빌드하려면 다음을 실행하세요.", "PreviousIntegrationFileRemains": "이전 통합 파일이 제거되지 않았습니다.", + "ProgramPathReturnedNonzeroExitCode": "종료 코드 {exit_code}(으)로 실패했습니다.", "ProgramReturnedNonzeroExitCode": "{tool_name}이(가) 종료 코드 ({exit_code})과(와) 함께 실패했습니다.", "ProvideExportType": "--raw --nuget --ifw --zip --7zip --chocolatey --prefab 옵션 중 하나 이상이 필요합니다.", "PushingVendorFailed": "{vendor}를 \"{path}\"(으)로 푸시하지 못했습니다. 자세한 내용은 --debug를 사용하세요.", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "대상 triplet. 'vcpkg help triplet'(기본값: {env_var}) 참조", "StartCodeUnitInContinue": "계속 위치에서 시작 코드 단위를 찾았습니다.", "StoreOptionMissingSha": "--store 옵션이 sha512 없어 유효하지 않습니다.", - "StoredBinariesToDestinations": "{elapsed} 후 대상 {count}개에 이진 파일이 저장됨.", + "SubmittingBinaryCacheBackground": "백그라운드에서 이진 캐시를 {count} {spec} 제출을 시작하는 중", + "SubmittingBinaryCacheComplete": "{elapsed} {count} 이진 캐시에 {spec} 제출을 완료했습니다.", "SuccessfulyExported": "{package_name}을(를) {path}(으)로 내보냄", "SuggestGitPull": "결과가 오래되었을 수 있습니다. 'git pull'을 실행하여 최신 결과를 가져옵니다.", "SuggestStartingBashShell": "변경 내용을 적용하려면 새 bash 셸을 시작했는지 확인하세요.", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "{path}에 시스템 대상 파일을 설치하지 못했습니다.", "ToRemovePackages": "오래된 패키지만 제거하려면 \n{command_name}을(를) 실행하고 오래된 버전을 제거하세요.", "ToUpdatePackages": "이러한 패키지 및 모든 종속성을 업데이트하려면 \n{command_name} 업그레이드'를 실행합니다.", + "ToolDataFileSchemaVersionNotSupported": "이 버전의 vcpkg에서는 문서 스키마 버전 {version} 지원되지 않습니다.", "ToolFetchFailed": "{tool_name}을(를) 가져올 수 없습니다.", + "ToolHashMismatch": "{tool_name} 이미 다운로드되었지만 잘못된 해시가 있습니다. 필요한 {expected} {actual}", "ToolInWin10": "이 유틸리티는 Windows 10 이상과 함께 번들로 제공됩니다.", "ToolOfVersionXNotFound": "적합한 버전의 {tool_name}을(를) 찾을 수 없으며(v{version} 필요) 이식 가능한 버전을 자동으로 다운로드할 수 없습니다. 최신 버전의 {tool_name}을(를) 설치하세요.", "TotalInstallTime": "총 설치 시간: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "업데이트된 레지스트리 '{url}': 기준 '{old_value}' -> '{new_value}'", "UpgradeInManifest": "업그레이드하면 클래식 모드 설치가 업그레이드되므로 매니페스트 모드를 지원하지 않습니다. vcpkg x-update-baseline을 사용하여 기준을 현재 값으로 업데이트하고 vcpkg 설치를 실행하여 종속성을 업데이트하는 것이 좋습니다.", "UpgradeRunWithNoDryRun": "위의 패키지를 다시 빌드하려는 경우 --no-dry-run 옵션을 사용하여 이 명령을 실행합니다.", - "UploadingBinariesToVendor": "\"{spec}\"에 대한 이진 파일을 \"{vendor}\" 원본 \"{path}\"에 업로드하는 중입니다.", + "UploadingBinariesToVendor": "{spec} 대한 이진 파일을 {path} {vendor} 업로드하는 중", "UsageInstallInstructions": "다음 CMake를 사용하여 사용 현황 파일을 설치할 수 있습니다.", "UsageTextHere": "사용 현황 파일이 여기에 있습니다.", "UseEnvVar": "-- 환경 변수에서 {env_var} 사용.", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "{package_name}에 {actual}이(가) 할당되었지만 로컬 포트는 {expected}입니다.", "VersionBuiltinPortTreeEntryMissing": "{expected}에서 {package_name}에 대한 버전 데이터베이스 항목이 없습니다. 체크 아웃된 포트 트리 버전({actual})을 사용합니다.", "VersionCommandHeader": "vcpkg 패키지 관리 프로그램 버전 {version}\n\n라이선스 정보는 LICENSE.txt를 참조하세요.", - "VersionConflictXML": "{path} 버전이 필요([{expected_version}])하지만 [{actual_version}]입니다. bootstrap-vcpkg를 다시 실행하세요.", "VersionConstraintNotInDatabase1": "버전 데이터베이스에 없는 {package_name version} 이름 버전 {version}의 \"version>=\" 제약 조건입니다. vcpkg에서 해석하려면 모든 버전이 버전 데이터베이스에 있어야 합니다.", "VersionConstraintNotInDatabase2": "버전 제약 조건을 제거하거나 여기에 선언된 값을 선택하는 것이 좋습니다.", "VersionConstraintOk": "모든 버전 제약 조건은 버전 데이터베이스와 일치합니다.", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "버전 텍스트의 '#' 다음에는 포트 버전(음이 아닌 정수)이 와야 합니다.", "VersionSpecMismatch": "버전이 일치하지 않아 포트를 로드하지 못했습니다. 파일 \"{path}\"에 {actual_version} 버전이 포함되어 있지만 버전 데이터베이스는 {expected_version}이어야 한다고 표시합니다.", "VersionVerifiedOK": "{version_spec}이(가) 버전 데이터베이스({git_tree_sha})에 올바르게 있습니다.", + "WaitUntilPackagesUploaded": "{count} 남은 이진 캐시 제출을 기다리는 중...", "WaitingForChildrenToExit": "자식 프로세스가 종료되기를 기다리는 중...", "WaitingToTakeFilesystemLock": "{path}에 대한 파일 시스템 잠금을 기다리는 중...", "WarnOnParseConfig": "구성 {path}에서 다음 경고가 발견되었습니다.", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "{version_spec}을(를) 로드하는 동안", "WhileLookingForSpec": "{spec}을(를) 찾는 동안:", "WhileParsingVersionsForPort": "{path}에서 {package_name}의 버전을 구문 분석하는 동안", + "WhileRunningAssetCacheScriptCommandLine": "자산 캐시 스크립트 명령줄을 실행하는 동안", "WhileValidatingVersion": "{version} 버전 유효성을 검사하는 동안", "WindowsOnlyCommand": "이 명령은 Windows만 지원합니다.", "WroteNuGetPkgConfInfo": "NuGet 패키지 구성 정보를 {path}에 기록함", diff --git a/locales/messages.pl.json b/locales/messages.pl.json index b26d462e82..fe1d7e9d65 100644 --- a/locales/messages.pl.json +++ b/locales/messages.pl.json @@ -4,6 +4,7 @@ "ABoolean": "wartość logiczna", "ABuiltinRegistry": "wbudowany rejestr", "AConfigurationObject": "obiekt konfiguracji", + "ACpuArchitecture": "architektura procesora CPU", "ADateVersionString": "ciąg wersji daty", "ADefaultFeature": "funkcja domyślna", "ADemandObject": "obiekt żądania", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "swobodny ciąg wersji", "ASemanticVersionString": "ciąg wersji semantycznej", "ASetOfFeatures": "zestaw funkcji", + "ASha512": "skrót SHA-512", "AString": "ciąg", "AStringOrArrayOfStrings": "ciąg lub tablica ciągów", "AStringStringDictionary": "słownik „string”: „string”", + "AToolDataArray": "tablica metadanych narzędzia", + "AToolDataFile": "plik danych narzędzia", + "AToolDataOS": "system operacyjny danych narzędzia", + "AToolDataObject": "metadane narzędzia", + "AToolDataVersion": "wersja danych narzędzia", "AUrl": "adres URL", "AVcpkgRepositoryCommit": "zatwierdzenie repozytorium vcpkg", "AVersionConstraint": "ograniczenie wersji", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "Wymusza wykrywanie hosta na system Windows podczas uzyskiwania artefaktów", "ArtifactsSwitchX64": "Wymusza wykrywanie hosta na architekturę x64 podczas uzyskiwania artefaktów", "ArtifactsSwitchX86": "Wymusza wykrywanie hosta na architekturze x86 podczas uzyskiwania artefaktów", - "AssetCacheHit": "Trafienie pamięci podręcznej zasobów dla {path}; pobrano z: {url}", - "AssetCacheMiss": "Pominięta pamięć podręczna zasobów; pobieranie z adresu {url}", - "AssetCacheMissBlockOrigin": "Pominięcie pamięci podręcznej zasobów dla {path}, a pobieranie jest blokowane przez element x-block-origin.", + "AssetCacheConsult": "Próba pobrania {path} przy użyciu {url} pamięci podręcznej zasobów", + "AssetCacheConsultScript": "Próba pobrania {path} przy użyciu skryptu pamięci podręcznej zasobów", + "AssetCacheHit": "Pobieranie powiodło się! Trafienie w pamięci podręcznej zasobów.", + "AssetCacheHitUrl": "Pobieranie powiodło się! Trafienie w pamięci podręcznej zasobów nie spowodowało próby autorytatywnego {url} źródłowego", + "AssetCacheMiss": "Chybienia w pamięci podręcznej zasobów; próba autorytatywnego {url} źródłowego", + "AssetCacheMissBlockOrigin": "nie było trafień w pamięci podręcznej zasobów i bloków x-block-origin próbujących autorytatywnego źródła {url}", + "AssetCacheMissNoUrls": "Pominięto wyszukiwanie {sha} w pamięci podręcznej zasobów i nie jest znany autorytatywny adres URL", "AssetCacheProviderAcceptsNoArguments": "nieoczekiwane argumenty: „{value}” nie akceptuje argumentów", - "AssetCacheSuccesfullyStored": "Pomyślnie zapisano {path} na adres {url}.", + "AssetCacheScriptBadVariable": "szablon skryptu {value} zawiera nieznaną {list} zastępczą", + "AssetCacheScriptBadVariableHint": "jeśli chcesz tego użyć w wierszu polecenia literału, użyj {{{{{list}}}}", + "AssetCacheScriptCommandLine": "pełny wiersz polecenia skryptu był", + "AssetCacheScriptFailed": "skrypt pamięci podręcznej zasobów zwrócił niezerowy kod zakończenia {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "skrypt pamięci podręcznej zasobów zwrócił sukces, ale wynikowy plik ma nieoczekiwany skrót", + "AssetCacheScriptFailedToWriteFile": "skrypt pamięci podręcznej zasobów zwrócił sukces, ale nie utworzył oczekiwanego pliku wyników", + "AssetCacheScriptNeedsSha": "szablon skryptu {value} wymaga sha, ale nie jest znany z próby pobrania {url}", + "AssetCacheScriptNeedsUrl": "szablon skryptu {value} wymaga adresu URL, ale żaden adres URL nie jest znany z próby pobrania {sha}", + "AssetCacheSuccesfullyStored": "Powodzenie sklepu Store", "AssetSourcesArg": "Źródła buforowania zasobów. Zobacz „vcpkg help assetcaching”", "AttemptingToSetBuiltInBaseline": "próba ustawienia wbudowanego punktu odniesienia w pliku vcpkg.json podczas zastępowania rejestru domyślnego w pliku vcpkg-configuration.json.\n zostanie użyty rejestr domyślny z pliku vcpkg-configuration.json.", "AuthenticationMayRequireManualAction": "Co najmniej jeden dostawca poświadczeń {vendor} zażądał wykonania akcji ręcznej. Dodaj źródło binarne „interactive”, aby zezwolić na interakcyjność.", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "Liczba wiodących katalogów do usunięcia ze wszystkich ścieżek", "CommandEnvExample2": "vcpkg env „ninja -C ” --triplet x64-windows", "CommandFailed": "polecenie:\n{command_line}\nniepowodzenie z następującymi danymi wyjściowymi:", - "CommandFailedCode": "polecenie:\n{command_line}\nniepowodzenie z kodem zakończenia {exit_code} i następującymi danymi wyjściowymi:", "CommunityTriplets": "Trójki społeczności:", "CompilerPath": "Znaleziono kompilator: {path}", - "CompressFolderFailed": "Nie można skompresować folderu „{path}”:", "ComputingInstallPlan": "Trwa obliczanie planu instalacji...", "ConfigurationErrorRegistriesWithoutBaseline": "Konfiguracja zdefiniowana w ścieżce {path} jest nieprawidłowa.\n\nKorzystanie z rejestrów wymaga ustawienia punktu odniesienia dla rejestru domyślnego lub domyślnego rejestru o wartości null.\n\nZobacz {url}, aby uzyskać więcej szczegółów.", "ConfigurationNestedDemands": "[\"{json_field}\"] zawiera zagnieżdżony obiekt „demands” (zagnieżdżony obiekt „demands” nie ma żadnego efektu)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "Nie można wywnioskować identyfikatora NuGet i wersji z nazwy pliku: {path}", "CouldNotFindBaselineInCommit": "Nie można odnaleźć punktu odniesienia w adresie {url} w lokalizacji {commit_sha} dla elementu {package_name}.", "CouldNotFindGitTreeAtCommit": "Nie można odnaleźć drzewa GIT dla `versions` w repozytorium {package_name} przy zatwierdzeniu {commit_sha}", - "CouldNotFindToolVersion": "Nie można odnaleźć narzędzi w ścieżce {path}", "CouldNotFindVersionDatabaseFile": "Nie można odnaleźć pliku bazy danych wersji: {path}", "CreateFailureLogsDir": "Tworzenie katalogu wyjściowego dzienników błędów {path}.", "CreatedNuGetPackage": "Utworzono pakiet nupkg: {path}", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "Trwa tworzenie pakietu NuGet...", "CreatingZipArchive": "Trwa tworzenie archiwum zip...", "CreationFailed": "Tworzenie ścieżki {path} nie powiodło się.", + "CurlFailedGeneric": "operacja curl nie powiodła się. Kod błędu {exit_code}.", "CurlFailedToPut": "Narzędzie curl nie może umieścić pliku w adresie {url} za pomocą kodu zakończenia {exit_code}.", "CurlFailedToPutHttp": "Narzędzie curl nie może umieścić pliku w adresie {url} za pomocą kodu zakończenia {exit_code} i kodu http {value}.", - "CurlResponseTruncatedRetrying": "polecenie curl zwróciło częściową odpowiedź; oczekiwanie {value} ms i ponowna próba", - "CurlTimeout": "Polecenie curl nie mogło wykonać wszystkich żądanych operacji HTTP, nawet po przekroczenia limitu czasu i ponownych próbach. Ostatni wiersz polecenia: {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "funkcja curl nie może zwrócić oczekiwanej liczby kodów zakończenia; może się tak zdarzyć, jeśli coś zakończy zawijanie przed jego zakończeniem. curl zakończył się z {exit_code}, co zwykle jest kodem wyniku dla ostatniej operacji, ale może być wynikiem awarii. Wiersz polecenia został {command_line}, a wszystkie dane wyjściowe są poniżej:", "CurrentCommitBaseline": "Bieżące zatwierdzenie można używać jako punktu odniesienia, który jest \n\t„wbudowanym punktem odniesienia”: „{commit_sha}”", "CycleDetectedDuring": "cykl wykryty podczas {spec}:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "Zmienna środowiskowa VCPKG_DEFAULT_BINARY_CACHE musi być katalogiem (była: {path})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "biblioteki DLL są względne względem wartości ${{CURRENT_PACKAGES_DIR}} w tym miejscu", "DocumentedFieldsSuggestUpdate": "Jeśli są to udokumentowane pola, które powinny zostać rozpoznane, spróbuj zaktualizować narzędzie vcpkg.", "DownloadAvailable": "Dostępna jest kopia tego narzędzia do pobrania, której można użyć przez zresetowanie elementu {env_var}.", - "DownloadFailedCurl": "{url}: narzędzie curl nie może pobrać za pomocą kodu zakończenia: {exit_code}", - "DownloadFailedHashMismatch": "Plik nie ma oczekiwanego skrótu:\nAdres URL: {url}\nPlik: {path}\nOczekiwany skrót: {expected}\nRzeczywisty skrót: {actual}", - "DownloadFailedProxySettings": "Nie można pobrać ścieżki {path}.\nJeśli korzystasz z serwera proxy, upewnij się, że jego ustawienia są prawidłowo skonfigurowane.\nMożliwe przyczyny to:\n1. W rzeczywistości używasz proxy protokołu HTTP, ale ustawiasz zmienną HTTPS_PROXY na `https//address:port`.\nNie jest to poprawne, ponieważ prefiks `https://` twierdzi, że proxy jest serwerem proxy HTTPS, podczas gdy Twoje proxy (v2ray, shadowsocksr, itp.) jest serwerem proxy HTTP.\nSpróbuj zamiast tego ustawić `http://address:port` na wartości zarówno HTTP_PROXY, jak i HTTPS_PROXY.\n2. Jeśli korzystasz z systemu Windows, aplikacja vcpkg automatycznie użyje ustawień serwera proxy dla przeglądarki Windows IE ustawionych przez oprogramowanie serwera proxy. Zobacz, {url}\nWartość ustawiona przez serwer proxy może być nieprawidłowa lub mieć ten sam prefiks `https://`.\n3. Twój zdalny serwer proxy nie działa.\nJeśli podjęto próbę bezpośredniego pobrania linku i uważasz, że nie jest to tymczasowa awaria serwera pobierania, prześlij zgłoszenie na adres https://github.com/Microsoft/vcpkg/issues.\nw celu zgłoszenia błędu tego nadrzędnego serwera pobierania.", - "DownloadFailedRetrying": "Pobieranie nie powiodło się — ponawianie próby po {value}ms", + "DownloadFailedHashMismatch": "pobieranie z {url} miało nieoczekiwany skrót", + "DownloadFailedHashMismatchActualHash": "Wartość rzeczywista: {sha}", + "DownloadFailedHashMismatchExpectedHash": "Oczekiwano: {sha}", + "DownloadFailedHashMismatchZero": "pobieranie nie powiodło się, ponieważ oczekiwany algorytm SHA512 miał wszystkie zera. Zmień oczekiwany algorytm SHA512 na: {sha}", + "DownloadFailedProxySettings": "Jeśli korzystasz z serwera proxy, upewnij się, że jego ustawienia są prawidłowo skonfigurowane.\nMożliwe przyczyny to:\n1. W rzeczywistości używasz proxy protokołu HTTP, ale ustawiasz zmienną HTTPS_PROXY na „https//address:port”.\nNie jest to poprawne, ponieważ prefiks „https://” twierdzi, że proxy jest serwerem proxy HTTPS, podczas gdy Twoje proxy (v2ray, shadowsocksr, itp.) jest serwerem proxy HTTP.\nSpróbuj zamiast tego ustawić „http://address:port” na wartości zarówno HTTP_PROXY, jak i HTTPS_PROXY.\n2. Jeśli korzystasz z systemu Windows, aplikacja vcpkg automatycznie użyje ustawień serwera proxy dla przeglądarki Windows IE ustawionych przez oprogramowanie serwera proxy. Zobacz: https://github.com/microsoft/vcpkg-tool/pull/77\nWartość ustawiona przez serwer proxy może być nieprawidłowa lub mieć ten sam prefiks „https://”.\n3. Twój zdalny serwer proxy nie działa.\nJeśli uważasz, że nie jest to tymczasowa awaria serwera pobierania i należy zmienić plik vcpkg, aby pobrać ten plik z innej lokalizacji, prześlij problem do https://github.com/Microsoft/vcpkg/issues", + "DownloadFailedRetrying": "Pobieranie {url} nie powiodło się — ponowienie próby po {wartość} ms", "DownloadFailedStatusCode": "{url}: niepowodzenie: kodu stanu {value}", + "DownloadOrUrl": "lub {url}", "DownloadRootsDir": "Katalog pobierania (domyślnie: {env_var})", - "DownloadSuccesful": "Pomyślnie pobrano {path}.", - "DownloadWinHttpError": "{url}: niepowodzenie interfejsu {system_api} za pomocą kodu zakończenia:{exit_code}", + "DownloadSuccesful": "Pomyślnie pobrano {path}", + "DownloadSuccesfulUploading": "Pomyślnie pobrano {path}, przechowywanie w {url}", + "DownloadTryingAuthoritativeSource": "Próba {url}", + "DownloadWinHttpError": "{url}: {system_api} nie powiodło się z kodem wyjścia {exit_code}.", "DownloadedSources": "Pobrane źródła dla {spec}", + "DownloadingAssetShaToFile": "Pobieranie wpisu pamięci podręcznej zasobów {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "zażądano pobrania wpisu pamięci podręcznej zasobów {sha} -> {path}, ale nie skonfigurowano żadnych pamięci podręcznych zasobów", + "DownloadingFile": "Pobieranie {path}", + "DownloadingFileFirstAuthoritativeSource": "Pobieranie {path}, próba {url}", "DownloadingPortableToolVersionX": "Nie znaleziono odpowiedniej wersji produktu {tool_name} (wymagana wersja: v{version}).", - "DownloadingUrl": "Pobieranie adresu {ulr}", + "DownloadingUrlToFile": "Pobieranie {url} -> {path}", "DownloadingVcpkgStandaloneBundle": "Pobieranie pakietu autonomicznego {version}.", "DownloadingVcpkgStandaloneBundleLatest": "Pobieranie najnowszego pakietu autonomicznego.", + "DuplicateDependencyOverride": "{package_name} ma już zastąpienie", "DuplicatePackagePattern": "Pakiet „{package_name}” jest zduplikowany.", "DuplicatePackagePatternFirstOcurrence": "Po raz pierwszy zadeklarowano w:", "DuplicatePackagePatternIgnoredLocations": "Następujące ponowne deklaracje zostaną zignorowane:", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "Opcja --{option} nie jest obsługiwana w trybie klasycznym i nie znaleziono manifestu.", "ErrorInvalidExtractOption": "--{option} musi być ustawiona na nieujemną liczbę całkowitą lub „AUTO”.", "ErrorInvalidManifestModeOption": "Opcja --{option} nie jest obsługiwana w trybie manifestu.", + "ErrorManifestMustDifferFromOverlay": "Katalog manifestu ({path}) nie może być taki sam jak katalog skonfigurowany w portach nakładki.", + "ErrorManifestMustDifferFromOverlayDot": "Katalog manifestu nie może być taki sam jak katalog skonfigurowany w portach nakładek, więc wartości \"overlay-ports\" nie mogą być równe \".\".", "ErrorMissingVcpkgRoot": "Nie można wykryć elementu vcpkg-root. Jeśli próbujesz użyć kopii skompilowanego elementu vcpkg, musisz zdefiniować zmienną środowiskową VCPKG_ROOT, aby wskazać sklonowaną kopię adresu https://github.com/Microsoft/vcpkg.", "ErrorNoVSInstance": "W potrójnym pliku {triplet}: nie można odnaleźć prawidłowego wystąpienia programu Visual Studio", "ErrorNoVSInstanceAt": "w ścieżce „{path}”", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "Nie można przeanalizować ścieżki {path}. Oczekiwano tablicy „versions”.", "FailedToParseSerializedBinParagraph": "[sanity check] Nie można przeanalizować serializowanego akapitu binarnego.\nZgłoś problem na stronie https://github.com/microsoft/vcpkg z następującymi danymi wyjściowymi:\n{error_msg}\nserializowany akapit binarny:", "FailedToParseVersionFile": "Nie można przeanalizować pliku wersji: {path}", - "FailedToParseVersionXML": "Nie można przeanalizować wersji narzędzia {tool_name}. Ciąg wersji: {version}", "FailedToRunToolToDetermineVersion": "Nie można uruchomić \"{path}\" w celu określenia wersji narzędzia {tool_name}.", "FailedToStoreBackToMirror": "Nie można zapisać {path} na adres {url}.", "FailedToStoreBinaryCache": "Nie można zapisać binarnej pamięci podręcznej {path}", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "Trwa pobieranie informacji rejestru z adresu {url} ({value})...", "FieldKindDidNotHaveExpectedValue": "Element „kind” nie miał oczekiwanej wartości: (oczekiwano jednej z: {expected}; znaleziono {actual})", "FileIsNotExecutable": "ten plik prawdopodobnie nie jest wykonywalny", - "FileNotFound": "{path}: nie znaleziono pliku", + "FileNotFound": "nie znaleziono pliku", "FileReadFailed": "Nie można odczytać {count} bajtów z {path} z przesunięciem {byte_offset}.", "FileSeekFailed": "Nie można poszukać pozycji {byte_offset} w ścieżce {path}.", "FilesContainAbsolutePath1": "W zainstalowanym pakiecie nie powinny istnieć ścieżki bezwzględne, takie jak następujące. Aby pominąć ten komunikat, dodaj element set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "nieznany stan pliku: {value}", "GitUnexpectedCommandOutputCmd": "git wygenerował nieoczekiwane dane wyjściowe podczas uruchamiania {command_line}", "GraphCycleDetected": "Wykryto cykl w grafie przy pakiecie {package_name}:", - "HashFileFailureToRead": "nie można odczytać pliku \"{path}\" dla haszowania: ", "HashPortManyFiles": "Pakiet {package_name} zawiera następującą liczbę plików: {count}. Utworzenie skrótu tej zawartości może zająć dużo czasu podczas określania skrótu instrukcji ABI dla buforowania binarnego. Rozważ zmniejszenie liczby plików. Typowe przyczyny tego problemu to przypadkowe wyewidencjonowanie plików źródłowych lub plików kompilacji w katalogu portu.", "HeaderOnlyUsage": "Element {package_name} jest tylko w nagłówku i może być używany z narzędzia CMake za pośrednictwem:", "HelpAssetCaching": "**Funkcja eksperymentalna: ta funkcja może ulec zmianie lub zostać usunięta w dowolnym momencie**\n\nProgram vcpkg może używać duplikatów do buforowania pobranych zasobów, zapewniając kontynuowanie działania, nawet jeśli oryginalne źródło zmieni się lub zniknie.\n\nBuforowanie zasobów można skonfigurować, ustawiając zmienną środowiskową X_VCPKG_ASSET_SOURCES na rozdzielaną średnikami listę źródeł lub przekazując sekwencję opcji wiersza polecenia --x-asset-sources=. Źródła wiersza polecenia są interpretowane po źródłach środowiska. Przecinki, średniki i znaki backtick można oznaczyć znakami ucieczki backtick (`).\n\nOpcjonalny parametr dla niektórych ciągów kontroluje sposób uzyskiwania do nich dostępu. Można go określić jako „read”, „write” lub „readwrite”, a wartość domyślna to „read”.\n\nPrawidłowe źródła:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "Niepowodzenie, jeśli buforowane pliki binarne są niedostępne", "HelpTxtOptOnlyDownloads": "Podejmij najlepszą próbę pobrania źródeł bez kompilowania", "HelpTxtOptRecurse": "Zezwalaj na usuwanie pakietów w ramach instalacji", - "HelpTxtOptUseAria2": "Użyj narzędzia aria2 do wykonywania zadań pobierania", "HelpTxtOptUseHeadVersion": "Instaluje biblioteki w wierszu poleceń przy użyciu najnowszych źródeł (tryb klasyczny)", "HelpTxtOptWritePkgConfig": "Zapisuje sformatowany plik NuGet packages.config do użytku z zewnętrznym buforowaniem binarnym. Zobacz `vcpkg help binarycaching`, aby uzyskać więcej informacji", "HelpUpdateBaseline": "Najlepszym podejściem do utrzymania aktualnych bibliotek jest aktualizacja odniesienia do linii bazowej. Zapewni to, że wszystkie pakiety, w tym te przechodnie, zostaną zaktualizowane. Jeśli jednak musisz zaktualizować pakiet niezależnie, możesz użyć ograniczenia „wersja>=”.", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "Integracja nie została zastosowana dla programu Visual Studio 2015.", "InternalCICommand": "vcpkg CI to polecenie wewnętrzne, które zmieni się niezgodnie lub zostanie usunięte w dowolnym momencie.", "InternalErrorMessageContact": "Należy otworzyć problem na stronie https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug, podając szczegółowe kroki w celu odtworzenia problemu.", - "InvalidArchitecture": "nieprawidłowa architektura: {value}", + "InvalidArchitectureValue": "Nieprawidłowa architektura: {value}. Oczekiwano jednego z: {expected}", "InvalidArgument": "nieprawidłowy argument", "InvalidArgumentRequiresAbsolutePath": "nieprawidłowy argument: argumenty ścieżki konfiguracji binarnej \"{binary_source}\" dla binarnych ciągów konfiguracji muszą być bezwzględne", "InvalidArgumentRequiresBaseUrl": "nieprawidłowy argument: konfiguracja binarna \"{binary_source}\" wymaga podstawowego adresu URL {base_url} jako pierwszego argumentu", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "nieprawidłowe wyrażenie logiki, użyj znaku „|”, a nie znaku „or”", "InvalidOptionForRemove": "Element „usuń” akceptuje biblioteki lub „--outdated”", "InvalidPortVersonName": "Znaleziono nieprawidłową nazwę pliku wersji portu: `{path}`.", + "InvalidSha512": "nieprawidłowy skrót SHA-512: {sha}\nSkrót SHA-512 musi mieć 128 znaków i zawierać tylko cyfry szesnastkowe", "InvalidSharpInVersion": "nieprawidłowy znak „#” w tekście wersji", "InvalidSharpInVersionDidYouMean": "nieprawidłowy znak „#” w tekście wersji. Czy chodziło Ci o „wersję-portu”: {value}?", "InvalidString": "Przekazano nieprawidłowy kod utf8 do elementu Value::string(std::string)", + "InvalidToolOSValue": "Nieprawidłowy system operacyjny narzędzia: {value}. Oczekiwano jednego z: {expected}", + "InvalidToolVersion": "Nieprawidłowa wersja narzędzia; oczekiwano ciągu zawierającego podciąg z zakresu od 1 do 3 liczb rozdzielonych kropkami.", "InvalidTriplet": "Nieprawidłowy triplet: {triplet}", "InvalidUri": "nie można przeanalizować identyfikatora uri: {value}", "InvalidValueHashAdditionalFiles": "Zmienna VCPKG_HASH_ADDITIONAL_FILES zawiera nieprawidłową ścieżkę pliku: „{path}”. Wartość musi być ścieżką bezwzględną do istniejącego pliku.", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "Serializowany akapit binarny różnił się od oryginalnego akapitu binarnego. Zgłoś problem na stronie https://github.com/microsoft/vcpkg z następującymi danymi wyjściowymi:", "MismatchedFiles": "plik do przechowywania jest niezgodny z skrótem", "MismatchedManifestAfterReserialize": "Serializowany manifest różnił się od oryginalnego manifestu. Otwórz problem na stronie https://github.com/microsoft/vcpkg, korzystając z następujących danych wyjściowych:", - "MismatchedNames": "nazwy nie są zgodne: „{package_name}” != „{actual}”", + "MismatchedNames": "nazwa portu zadeklarowana w pliku metadanych nie jest zgodna z katalogiem. Oczekiwano, że port będzie miał nazwę {package_name}, ale plik deklaruje {actual}.", "MismatchedSpec": "Niezgodna specyfikacja w ścieżce {path} portu: oczekiwana {expected}, rzeczywista {actual}", "MismatchedType": "{json_field}: niezgodny typ: oczekiwano typu {json_type}", "Missing7zHeader": "Nie można odnaleźć nagłówka 7z.", "MissingAndroidEnv": "Brak zmiennej środowiskowe ANDROID_NDK_HOME", "MissingAndroidHomeDir": "Katalog ANDROID_NDK_HOME nie istnieje: {path}", "MissingArgFormatManifest": "Przekazano polecenie format-manifest --convert-control bez znaku „--all”.\nNie jest to konieczne: przekazywane jawnie pliki sterujące są konwertowane automatycznie.", - "MissingAssetBlockOrigin": "Brak ścieżki {path} i pobieranie jest blokowane przez element x-block-origin.", "MissingClosingParen": "Brakuje zamykającego nawiasu klamrowego )", "MissingDependency": "Pakiet {spec} jest zainstalowany, ale zależność {package_name} nie jest.", "MissingExtension": "Brak rozszerzenia \"{extension}\".", @@ -814,7 +841,6 @@ "NoInstalledPackages": "Nie zainstalowano żadnych pakietów. Czy chodziło Ci o `search`?", "NoOutdatedPackages": "Brak nieaktualnych pakietów.", "NoRegistryForPort": "nie skonfigurowano rejestru dla portu {package_name}", - "NoUrlsAndHashSpecified": "Nie określono żadnych adresów URL do pobrania SHA: {sha}", "NoUrlsAndNoHashSpecified": "Nie określono żadnych adresów URL i nie określono żadnego skrótu.", "NonExactlyArgs": "polecenie '{command_name}' wymaga dokładnie {expected} argumentów, a podano {actual}", "NonOneRemainingArgs": "polecenie '{command_name}' wymaga dokładnie jednego argumentu", @@ -834,8 +860,8 @@ "Options": "Opcje", "OriginalBinParagraphHeader": "\nOryginalny akapit binarny", "OtherCommandsHeader": "Inne", - "OverlayPatchDir": "Ścieżka nakładki „{path}” musi istnieć i musi być katalogiem.", - "OverlayPortsDirectoriesHelp": "Katalogi portów nakładki (również: {env_var})", + "OverlayPatchDir": "Ścieżka nakładki \"{path}\" musi być istniejącym katalogiem.", + "OverlayPortsHelp": "Katalogi portów nakładek lub katalogi zawierające katalogi overlay-port (również: {env_var})", "OverlayTripletDirectoriesHelp": "Katalogi trójek nakładek (również: {env_var})", "OverlayTriplets": "Nałóż trójki ze ścieżki „{path}”:", "OverwritingFile": "Plik {path} był już obecny i zostanie zastąpiony", @@ -927,6 +953,7 @@ "PortsUpdated": "Aktualizowano następujące porty ({count}):", "PrebuiltPackages": "Istnieją pakiety, które nie zostały skompilowane. Aby je skompilować, uruchom:", "PreviousIntegrationFileRemains": "Poprzedni plik integracji nie został usunięty.", + "ProgramPathReturnedNonzeroExitCode": "nie powiodło się z kodem wyjścia {exit_code}", "ProgramReturnedNonzeroExitCode": "Operacja {tool_name} nie powiodła się. Kod zakończenia: ({exit_code}).", "ProvideExportType": "Wymagana jest co najmniej jedna z następujących opcji: --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "Wypychanie dostawcy {vendor} do lokalizacji \"{path}\" nie powiodło się. Aby uzyskać więcej informacji, użyj parametru --debug.", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "Potrójna wartość docelowa. Zobacz „vcpkg help triplet” (domyślnie: {env_var})", "StartCodeUnitInContinue": "znaleziono jednostkę kodu początkowego w pozycji kontynuuj", "StoreOptionMissingSha": "Opcja --store jest nieprawidłowa bez zestawu sha512", - "StoredBinariesToDestinations": "Przechowywane dane binarne w {count} lokalizacjach docelowych w ciągu {elapsed}.", + "SubmittingBinaryCacheBackground": "Rozpoczynanie przesyłania {spec} do {count} binarnych pamięci podręcznych w tle", + "SubmittingBinaryCacheComplete": "Zakończono przesyłanie {spec} do {count} binarnych pamięci podręcznych w {elapsed}", "SuccessfulyExported": "Wyeksportowano {package_name} do {path}", "SuggestGitPull": "Wynik może być nieaktualny. Uruchom polecenie `git pull`, aby uzyskać najnowsze wyniki.", "SuggestStartingBashShell": "Aby zmiana została wprowadzona, upewnij się, że została uruchomiona nowa powłoka bash.", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "nie można zainstalować systemowego pliku obiektów docelowych w ścieżce {path}", "ToRemovePackages": "Aby usunąć tylko nieaktualne pakiety, uruchom polecenie \n{command_name} remove --outdated", "ToUpdatePackages": "Aby zaktualizować te pakiety i wszystkie zależności, uruchom\n{command_name} uaktualnienie\"", + "ToolDataFileSchemaVersionNotSupported": "wersja schematu dokumentu {version} nie jest obsługiwana przez tę wersję programu vcpkg", "ToolFetchFailed": "Nie można pobrać elementu {tool_name}.", + "ToolHashMismatch": "{tool_name} prawdopodobnie została już pobrana, ale ma niepoprawny skrót. Oczekiwano {expected}, ale {actual}", "ToolInWin10": "To narzędzie jest powiązane z systemem Windows 10 lub nowszym.", "ToolOfVersionXNotFound": "Nie znaleziono odpowiedniej wersji produktu {tool_name} (wymagana wersja v{version}) i nie można automatycznie pobrać wersji przenośnej. Zainstaluj nowszą wersję produktu {tool_name}", "TotalInstallTime": "Całkowity czas instalacji: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "zaktualizowany rejestr „{url}”: punkt odniesienia „{old_value}” -> „{new_value}”", "UpgradeInManifest": "Uaktualnienie uaktualnia instalację w trybie klasycznym i w związku z tym nie obsługuje trybu manifestu. Rozważ zaktualizowanie zależności, aktualizując punkt odniesienia do bieżącej wartości za pomocą polecenia vcpkg x-update-baseline i uruchamiając instalację programu vcpkg.", "UpgradeRunWithNoDryRun": "Jeśli chcesz ponownie skompilować powyższe pakiety, uruchom polecenie z opcją --no-dry-run.", - "UploadingBinariesToVendor": "Przekazywanie danych binarnych dla \"{spec}” do ścieżki źródłowej dostawcy \"{vendor}\": \"{path}\".", + "UploadingBinariesToVendor": "Przekazywanie plików binarnych {spec} do {vendor} z {path}", "UsageInstallInstructions": "możesz zainstalować plik użycia za pomocą następującego narzędzia CMake", "UsageTextHere": "plik użycia jest tutaj", "UseEnvVar": "-- Używanie elementu {env_var} w zmiennych środowiskowych.", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "Pakiet {package_name} ma przypisany {actual}, ale port lokalny to {expected}", "VersionBuiltinPortTreeEntryMissing": "brak wpisu bazy danych wersji dla pakietu {package_name} w {expected}; używanie wersji wyewidencjonowanego drzewa portów ({actual}).", "VersionCommandHeader": "wersja programu do zarządzania pakietami vcpkg {version}\n\nZobacz plik LICENSE.txt, aby uzyskać informacje o licencji.", - "VersionConflictXML": "Oczekiwano wersji {path}: [{expected_version}], ale była [{actual_version}]. Uruchom ponownie polecenie bootstrap-vcpkg.", "VersionConstraintNotInDatabase1": "ograniczenie „version>=” do wersji {version} nazw pakietu {package_name}, która nie istnieje w bazie danych wersji. Wszystkie wersje muszą istnieć w bazie danych wersji, aby mogły być interpretowane przez program vcpkg.", "VersionConstraintNotInDatabase2": "rozważ usunięcie ograniczenia wersji lub wybranie wartości zadeklarowanej w tym miejscu", "VersionConstraintOk": "wszystkie ograniczenia wersji są spójne z bazą danych wersji", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "Po znaku „#” w tekście wersji musi następować wersja portu (nieujemna liczba całkowita)", "VersionSpecMismatch": "Nie można załadować portu, ponieważ wersje są niespójne. Plik „{path}” zawiera wersję {actual_version}, ale baza danych wskazuje, że powinna to być wersja {expected_version}.", "VersionVerifiedOK": "{version_spec} jest poprawnie w bazie danych wersji ({git_tree_sha})", + "WaitUntilPackagesUploaded": "Trwa oczekiwanie na {count} pozostałych żądań przesłania binarnej pamięci podręcznej...", "WaitingForChildrenToExit": "Trwa oczekiwanie na zakończenie procesów podrzędnych...", "WaitingToTakeFilesystemLock": "trwa oczekiwanie na zablokowanie systemu plików na ścieżce {path}...", "WarnOnParseConfig": "Znaleziono następujące ostrzeżenia w konfiguracji {path}:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "podczas ładowania wersji {version_spec}", "WhileLookingForSpec": "podczas wyszukiwania elementu {spec}:", "WhileParsingVersionsForPort": "podczas analizowania wersji dla pakietu {package_name} ze ścieżki {path}", + "WhileRunningAssetCacheScriptCommandLine": "podczas uruchamiania wiersza polecenia skryptu pamięci podręcznej zasobów", "WhileValidatingVersion": "podczas walidacji wersji: {version}", "WindowsOnlyCommand": "To polecenie obsługuje tylko system Windows.", "WroteNuGetPkgConfInfo": "Zapisano informacje o konfiguracji pakietu NuGet w ścieżce {path}", diff --git a/locales/messages.pt-BR.json b/locales/messages.pt-BR.json index 749ec6ecc4..5d4bba5c45 100644 --- a/locales/messages.pt-BR.json +++ b/locales/messages.pt-BR.json @@ -4,6 +4,7 @@ "ABoolean": "um booliano", "ABuiltinRegistry": "um registro interno", "AConfigurationObject": "um objeto de configuração", + "ACpuArchitecture": "uma arquitetura de CPU", "ADateVersionString": "uma cadeia de caracteres de versão de data", "ADefaultFeature": "um recurso padrão", "ADemandObject": "um objeto de demanda", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "uma cadeia de caracteres de versão reduzida", "ASemanticVersionString": "uma cadeia de caracteres de versão semântica", "ASetOfFeatures": "um conjunto de recursos", + "ASha512": "um hash SHA-512", "AString": "uma cadeia de caracteres", "AStringOrArrayOfStrings": "uma cadeia de caracteres ou uma matriz de cadeias de caracteres", "AStringStringDictionary": "a \"string\": dicionário \"string\"", + "AToolDataArray": "uma matriz de metadados de ferramenta", + "AToolDataFile": "um arquivo de dados de ferramenta", + "AToolDataOS": "um sistema operacional de dados de ferramenta", + "AToolDataObject": "metadados da ferramenta", + "AToolDataVersion": "uma versão de dados da ferramenta", "AUrl": "uma URL", "AVcpkgRepositoryCommit": "uma confirmação de repositório vcpkg", "AVersionConstraint": "uma restrição de versão", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "Força a detecção de host para o Windows ao adquirir artefatos", "ArtifactsSwitchX64": "Força a detecção de host para x64 ao adquirir artefatos", "ArtifactsSwitchX86": "Força a detecção de host para x86 ao adquirir artefatos", - "AssetCacheHit": "Ocorrência no cache de ativos para {path}; baixado de: {url}", - "AssetCacheMiss": "Perda no cache de ativos; baixando de {url}", - "AssetCacheMissBlockOrigin": "Perda no cache de ativos para {path} e downloads são bloqueados por x-block-origin.", + "AssetCacheConsult": "Tentando baixar dados {path} cache de ativos {url}", + "AssetCacheConsultScript": "Tentando baixar os dados {path} script de cache de ativos", + "AssetCacheHit": "Download bem-sucedido! Acerto do cache de ativos.", + "AssetCacheHitUrl": "Download bem-sucedido! Ocorrência no cache de ativos, não foi possível tentar a origem autoritativa {url}", + "AssetCacheMiss": "Perda no cache de ativos; tentando a fonte autoritativa {url}", + "AssetCacheMissBlockOrigin": "não houve acertos no cache de ativos e blocos x-block-origin tentando a fonte autoritativa {url}", + "AssetCacheMissNoUrls": "O cache de ativos não está procurando {sha} e nenhuma URL autoritativa é conhecida", "AssetCacheProviderAcceptsNoArguments": "argumentos inesperados: '{value}' não aceita argumentos", - "AssetCacheSuccesfullyStored": "{path} armazenado com sucesso em {url}.", + "AssetCacheScriptBadVariable": "o modelo de script {value} contém opções de substituição {list}", + "AssetCacheScriptBadVariableHint": "se desejar isso na linha de comando literal, use {{{{list}}}}}", + "AssetCacheScriptCommandLine": "a linha de comando de script completa foi", + "AssetCacheScriptFailed": "o script de cache de ativos retornou um código de saída diferente de zero {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "o script de cache de ativos retornou êxito, mas o arquivo resultante tem um hash inesperado", + "AssetCacheScriptFailedToWriteFile": "o script de cache de ativos retornou êxito, mas não criou o arquivo de resultado esperado", + "AssetCacheScriptNeedsSha": "o modelo de script {value} requer um SHA, mas nenhum SHA é conhecido pela tentativa de download {url}", + "AssetCacheScriptNeedsUrl": "o modelo de script {value} requer uma URL, mas nenhuma URL é conhecida pela tentativa de download {sha}", + "AssetCacheSuccesfullyStored": "Sucesso na Store", "AssetSourcesArg": "Fontes do cache de ativos. Consulte 'vcpkg help assetcaching'", "AttemptingToSetBuiltInBaseline": "tentativa de definir a linha de base interna em vcpkg.json ao substituir o registro padrão em vcpkg-configuration.json.\no registro padrão de vcpkg-configuration.json será usado.", "AuthenticationMayRequireManualAction": "Um ou mais provedores de credenciais do {vendor} solicitaram ação manual. Adicione a fonte binária 'interativa' para permitir a interatividade.", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "O número de diretórios principais a serem removidos de todos os caminhos", "CommandEnvExample2": "vcpkg env \"ninja -C \" --triplet x64-windows", "CommandFailed": "comando:\n{command_line}\nfalhou com a seguinte saída:", - "CommandFailedCode": "comando:\n{command_line}\nfalha com o código de saída {exit_code} e a seguinte saída:", "CommunityTriplets": "Tripletos da comunidade:", "CompilerPath": "Compilador encontrado: {path}", - "CompressFolderFailed": "Falha ao compactar a pasta \"{path}\":", "ComputingInstallPlan": "Plano de instalação de computação...", "ConfigurationErrorRegistriesWithoutBaseline": "A configuração definida em {path} é inválida.\n\nO uso de registros exige que uma linha de base seja definida para o registro padrão ou que o registro padrão seja nulo.\n\nConsulte {url} para obter mais detalhes.", "ConfigurationNestedDemands": "[\"{json_field}\"] contém um objeto aninhado `demands` (`demands` aninhadas não têm efeito)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "Não foi possível deduzir a ID e a versão do nuget do nome de arquivo: {path}", "CouldNotFindBaselineInCommit": "Não foi possível localizar a linha de base {url} em {commit_sha} para {package_name}.", "CouldNotFindGitTreeAtCommit": "não foi possível encontrar a árvore git para `versions` no repositório {package_name} no commit {commit_sha}", - "CouldNotFindToolVersion": "Não foi possível localizar em {path}", "CouldNotFindVersionDatabaseFile": "Não foi possível encontrar o arquivo de banco de dados de versões: {path}", "CreateFailureLogsDir": "Criando diretório de saída de logs de falha {path}.", "CreatedNuGetPackage": "Nupkg criado: {path}", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "Criando o pacote NuGet...", "CreatingZipArchive": "Criando arquivo zip...", "CreationFailed": "Falha ao criar {path}.", + "CurlFailedGeneric": "falha na operação de curvação com o código de {exit_code}.", "CurlFailedToPut": "o curl não pôde colocar o arquivo em {url} com o código de saída {exit_code}.", "CurlFailedToPutHttp": "O curl não pôde colocar o arquivo em {url} com o código de saída {exit_code} e o código http {value}.", - "CurlResponseTruncatedRetrying": "o curl retornou uma resposta parcial; após {value} milissegundos a tentativa será repetida", - "CurlTimeout": "o curl não pôde executar todas as operações HTTP solicitadas, mesmo após o tempo limite e as repetições. A última linha de comando foi: {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "curl falhou ao retornar o número esperado de códigos de saída; isso pode acontecer se algo terminar enroscar antes de terminar. curl encerrado com {exit_code} que normalmente é o código de resultado para a última operação, mas pode ser o resultado de uma falha. A linha de comando foi {command_line} e todas as saídas estão abaixo:", "CurrentCommitBaseline": "Você pode usar a confirmação atual como uma linha de base, que é:\n\t\"builtin-baseline\": \"{commit_sha}\"", "CycleDetectedDuring": "ciclo detectado durante {spec}:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "A variável de ambiente VCPKG_DEFAULT_BINARY_CACHE deve ser um diretório (era: {path})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "as DLLs são relativas a ${{CURRENT_PACKAGES_DIR}} aqui", "DocumentedFieldsSuggestUpdate": "Se estes forem campos documentados que devem ser reconhecidos, tente atualizar a ferramenta vcpkg.", "DownloadAvailable": "Uma cópia para download desta ferramenta está disponível e pode ser usada desativando {env_var}.", - "DownloadFailedCurl": "{url}: falha ao baixar o curl com o código de saída {exit_code}", - "DownloadFailedHashMismatch": "O arquivo não tem o hash esperado:\nurl: {url}\nArquivo: {path}\nHash esperado: {expected}\nHash real: {actual}", - "DownloadFailedProxySettings": "Falha ao baixar {path}.\nSe você estiver usando um proxy, verifique se as configurações do proxy estão corretas.\nAs possíveis causas são:\n1. Na verdade, você está usando um proxy HTTP, mas definindo a variável HTTPS_PROXY como 'https//address:port'.\nIsso não está correto, porque o prefixo 'https://' declara que o proxy é um proxy HTTPS, enquanto o proxy (v2ray, shadowsocksr etc...) é um proxy HTTP.\nTente definir 'http://address:port' como HTTP_PROXY e HTTPS_PROXY, em vez disso.\n2. Se você estiver usando o Windows, o vcpkg usará automaticamente as Configurações de Proxy do Windows IE definidas pelo seu software proxy. Veja, {url}\nÉ possível que o valor definido pelo proxy esteja errado ou tenha o mesmo problema de prefixo 'https://'.\n3. O servidor remoto do proxy é nosso serviço.\nSe você tentou fazer o download direto do link e acredita que não se trata de uma falha temporária do servidor de download, envie um problema para https://github.com/Microsoft/vcpkg/issues\npara relatar essa falha do servidor de download upstream.", - "DownloadFailedRetrying": "Falha no download – tentando novamente após {value}ms", + "DownloadFailedHashMismatch": "download de {url} teve um hash inesperado", + "DownloadFailedHashMismatchActualHash": "Real : {sha}", + "DownloadFailedHashMismatchExpectedHash": "Esperado: {sha}", + "DownloadFailedHashMismatchZero": "falha no download porque o SHA512 esperado era zeros. Altere o SHA512 esperado para: {sha}", + "DownloadFailedProxySettings": "Se você estiver usando um proxy, verifique se as configurações do proxy estão corretas.\nAs possíveis causas são:\n1. Você está realmente usando um proxy HTTP, mas definindo a variável HTTPS_PROXY como `https//address:port`.\nIsso não está correto, pois o prefixo `https://` indica que o proxy é um proxy HTTPS, enquanto seu proxy (v2ray, shadowsocksr etc.) é um proxy HTTP.\nTente definir `http://address:port` para HTTP_PROXY e HTTPS_PROXY.\n2. Se você estiver usando o Windows, o vcpkg usará automaticamente as configurações de proxy do IE do Windows definidas pelo software de proxy. Confira: https://github.com/microsoft/vcpkg-tool/pull/77\nO valor definido pelo seu proxy pode estar incorreto ou ter o mesmo problema de prefixo \"https://\".\n3. O servidor remoto do seu proxy está fora de serviço.\nSe você acredita que essa não é uma falha temporária do servidor de download e o vcpkg precisa ser alterado para baixar esse arquivo de um local diferente, envie um problema para https://github.com/Microsoft/vcpkg/issues", + "DownloadFailedRetrying": "Falha ao baixar {url} – tentando novamente após {value}ms", "DownloadFailedStatusCode": "{url}: falha: código de status {value}", + "DownloadOrUrl": "ou {url}", "DownloadRootsDir": "Baixa o diretório (padrão: {env_var})", - "DownloadSuccesful": "{path} baixado com sucesso.", - "DownloadWinHttpError": "{url}: {system_api} falhou com o código de saída {exit_code}", + "DownloadSuccesful": "Baicou com sucesso o {path}", + "DownloadSuccesfulUploading": "Êxito ao baixar {path}, armazenando para {url}", + "DownloadTryingAuthoritativeSource": "Tentando {url}", + "DownloadWinHttpError": "{url}: {system_api} falhou com o código de saída {exit_code}.", "DownloadedSources": "Fontes baixadas para {spec}", + "DownloadingAssetShaToFile": "Baixando entrada de cache de ativos {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "o download solicitado da entrada do cache de ativos {sha} -> {path}, mas nenhum cache de ativos está configurado", + "DownloadingFile": "Baixando {path}", + "DownloadingFileFirstAuthoritativeSource": "Baixando {path}, tentando {url}", "DownloadingPortableToolVersionX": "Não foi encontrada uma versão adequada de {tool_name} (necessário v{version}).", - "DownloadingUrl": "Baixando {url}", + "DownloadingUrlToFile": "Baixando {url} -> {path}", "DownloadingVcpkgStandaloneBundle": "Baixando o pacote autônomo {version}.", "DownloadingVcpkgStandaloneBundleLatest": "Baixando o pacote autônomo mais recente.", + "DuplicateDependencyOverride": "{package_name} já tem uma substituição", "DuplicatePackagePattern": "O pacote \"{Package_name}\" está duplicado.", "DuplicatePackagePatternFirstOcurrence": "Declarado pela primeira vez em:", "DuplicatePackagePatternIgnoredLocations": "As seguintes declarações serão ignoradas:", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "A opção --{option} não é suportada no modo clássico e nenhum manifesto foi encontrado.", "ErrorInvalidExtractOption": "--{option} deve ser definido como um inteiro não negativo ou \"AUTO\".", "ErrorInvalidManifestModeOption": "Não há suporte para a opção --{option} no modo de manifesto.", + "ErrorManifestMustDifferFromOverlay": "O diretório de manifesto ({path}) não pode ser igual a um diretório configurado em portas de sobreposição.", + "ErrorManifestMustDifferFromOverlayDot": "O diretório de manifesto não pode ser igual a um diretório configurado em portas de sobreposição, portanto, os valores de \"overlay-ports\" não podem ser \".\".", "ErrorMissingVcpkgRoot": "Não foi possível detectar vcpkg-root. Se você estiver tentando usar uma cópia do vcpkg criada, defina a variável de ambiente VCPKG_ROOT para apontar para uma cópia clonada do https://github.com/Microsoft/vcpkg.", "ErrorNoVSInstance": "no triplo {triplet}: Não é possível encontrar uma instância válida do Visual Studio", "ErrorNoVSInstanceAt": "em \"{path}\"", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "Falha ao analisar {path}, esperava uma matriz 'versions'.", "FailedToParseSerializedBinParagraph": "[verificação de integridade] Falha ao analisar um parágrafo binário serializado.\nAbra um problema em https://github.com/microsoft/vcpkg, com a seguinte saída:\n{error_msg}\nParágrafo Binário Serializado:", "FailedToParseVersionFile": "Falha ao analisar o arquivo da versão: {path}", - "FailedToParseVersionXML": "Não foi possível analisar a versão da ferramenta {tool_name}. A cadeia de caracteres de versão era: {version}", "FailedToRunToolToDetermineVersion": "Falha ao executar \"{path}\" para determinar a versão de {tool_name}.", "FailedToStoreBackToMirror": "Falha ao armazenar {path} para {url}.", "FailedToStoreBinaryCache": "Falha ao armazenar o cache binário {path}", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "Buscando informações de registro de {url} ({value})...", "FieldKindDidNotHaveExpectedValue": "\"kind\" não tinha um valor esperado: (esperado um de: {expected}; encontrado {actual})", "FileIsNotExecutable": "este arquivo não parece ser executável", - "FileNotFound": "{path}: arquivo não encontrado", + "FileNotFound": "Arquivo não encontrado", "FileReadFailed": "Falha ao ler {count} bytes de {path} no deslocamento {byte_offset}.", "FileSeekFailed": "Falha ao buscar a posição {byte_offset} em {path}.", "FilesContainAbsolutePath1": "Não deve haver caminhos absolutos, como os seguintes, em um pacote instalado. Para suprimir esta mensagem, adicione set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "status de arquivo desconhecido: {value}", "GitUnexpectedCommandOutputCmd": "o git produziu uma saída inesperada ao executar {command_line}", "GraphCycleDetected": "Ciclo detectado no gráfico em {package_name}:", - "HashFileFailureToRead": "falha ao ler o arquivo \"{path}\" para hash: ", "HashPortManyFiles": "O {package_name} contém {count} arquivos. O hash desses conteúdos pode levar muito tempo ao determinar o hash da ABI para cache binário. Considere reduzir o número de arquivos. Causas comuns são fazer check-out acidental de arquivos de origem ou build no diretório de uma porta.", "HeaderOnlyUsage": "{package_name} é somente de cabeçalho e pode ser usado da CMake via:", "HelpAssetCaching": "**Recurso experimental: isso pode ser alterado ou ser removido a qualquer momento**\n\nO vcpkg pode usar espelhos para armazenar em cache os ativos baixados, garantindo a operação contínua mesmo se a fonte original mudar ou desaparecer.\n\nO cache de ativos pode ser configurado definindo a variável de ambiente X_VCPKG_ASSET_SOURCES para uma lista de origens delimitada por ponto-e-vírgula ou passando uma sequência de --x-asset-sources= opções de linha de comando. As fontes da linha de comando são interpretadas após as fontes do ambiente. Vírgulas, ponto e vírgula e acentos graves podem ser escapados usando crase (`).\n\nO parâmetro opcional para certas cadeia de caracteres controla como elas serão acessadas. Ele pode ser especificado como \"read\", \"write\" ou \"readwrite\" e o padrão é \"read\".\n\nFontes válidas:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "Falha se os binários armazenados em cache não estiverem disponíveis", "HelpTxtOptOnlyDownloads": "Faz a melhor tentativa de download de fontes sem criar", "HelpTxtOptRecurse": "Permite a remoção de pacotes como parte da instalação", - "HelpTxtOptUseAria2": "Usa aria2 para executar tarefas de download", "HelpTxtOptUseHeadVersion": "Instala as bibliotecas na linha de comando usando as fontes upstream mais recentes (modo clássico)", "HelpTxtOptWritePkgConfig": "Grava um arquivo formatado em packages.config NuGet para uso com cache binário externo. Consulte 'vcpkg help binarycaching' para obter mais informações", "HelpUpdateBaseline": "A melhor abordagem para manter suas bibliotecas atualizadas é atualizar sua referência de linha de base. Isso garantirá que todos os pacotes, incluindo os transitivos, sejam atualizados. No entanto, se você precisar atualizar um pacote independentemente, poderá usar uma restrição \"version>=\".", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "A integração não foi aplicada para o Visual Studio 2015.", "InternalCICommand": "vcpkg ci é um comando interno que será alterado incompatibilidade ou removido a qualquer momento.", "InternalErrorMessageContact": "Abra um problema no https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug com etapas detalhadas para reproduzir o problema.", - "InvalidArchitecture": "arquitetura inválida: {value}", + "InvalidArchitectureValue": "Arquitetura inválida: {value}. Esperado um de: {expected}", "InvalidArgument": "argumento Inválido", "InvalidArgumentRequiresAbsolutePath": "argumento inválido: os argumentos de caminho da configuração binária '{binary_source}' para cadeias de caracteres de configuração binária devem ser absolutos", "InvalidArgumentRequiresBaseUrl": "argumento inválido: a configuração binária '{binary_source}' requer uma URL base {base_url} como o primeiro argumento", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "expressão lógica inválida, use '|' em vez de 'ou'", "InvalidOptionForRemove": "'remove' aceita bibliotecas ou '--outdated'", "InvalidPortVersonName": "Nome de arquivo de versão de porta inválido encontrado: `{path}`.", + "InvalidSha512": "hash SHA-512 inválido: {sha}\nO hash SHA-512 deve ter 128 caracteres e conter apenas dígitos hexadecimais", "InvalidSharpInVersion": "caractere inválido \"#\" no texto da versão", "InvalidSharpInVersionDidYouMean": "caractere inválido \"#\" no texto da versão. Você quis dizer \"port-version\": {value}?", "InvalidString": "Utf8 inválido passado para Value::string(std::string)", + "InvalidToolOSValue": "Sistema operacional de ferramenta inválido: {value}. Esperado um de: {expected}", + "InvalidToolVersion": "Versão de ferramenta inválida; esperada uma cadeia de caracteres contendo uma subcadeia de 1 a 3 números separados por pontos.", "InvalidTriplet": "Tripleto inválido: {triplet}", "InvalidUri": "não é possível analisar o URI: {value}", "InvalidValueHashAdditionalFiles": "O VCPKG_HASH_ADDITIONAL_FILES variável contém um caminho de arquivo inválido: ''{path}''. O valor deve ser um caminho absoluto para um arquivo existente.", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "O parágrafo binário serializado era diferente do parágrafo binário original. Abra um problema em https://github.com/microsoft/vcpkg com a seguinte saída:", "MismatchedFiles": "o arquivo a ser armazenado não corresponde ao hash", "MismatchedManifestAfterReserialize": "O manifesto serializado era diferente do manifesto original. Abra um problema em https://github.com/microsoft/vcpkg com a seguinte saída:", - "MismatchedNames": "nomes não correspondiam: '{package_name}' != '{actual}'", + "MismatchedNames": "o nome da porta declarado no arquivo de metadados não correspondeu ao diretório. Esperava-se que a porta {package_name}, mas o arquivo declara {actual}.", "MismatchedSpec": "Especificação incompatível na porta {path}: esperado {expected}, real {actual}", "MismatchedType": "{json_field}: tipo incompatível: esperado {json_type}", "Missing7zHeader": "Não é possível localizar o cabeçalho 7z.", "MissingAndroidEnv": "ANDROID_NDK_HOME variável de ambiente ausente", "MissingAndroidHomeDir": "O diretório ANDROID_NDK_HOME não existe: {path}", "MissingArgFormatManifest": "format-manifest foi passado --convert-control sem '--all'.\nIsso não faz nada: os arquivos de controle passados explicitamente são convertidos automaticamente.", - "MissingAssetBlockOrigin": "{path} ausente e downloads são bloqueados por x-block-origin.", "MissingClosingParen": "faltou fechar )", "MissingDependency": "O pacote {spec} está instalado, mas a dependência {package_name} não.", "MissingExtension": "Extensão \"{extension}\" ausente.", @@ -814,7 +841,6 @@ "NoInstalledPackages": "Nenhum pacote está instalado. Você quis dizer 'pesquisar'?", "NoOutdatedPackages": "Não há pacotes desatualizados.", "NoRegistryForPort": "nenhum registro configurado para porta {package_name}", - "NoUrlsAndHashSpecified": "Nenhuma URL especificada para baixar SHA: {sha}", "NoUrlsAndNoHashSpecified": "Nenhuma URL especificada e nenhum hash especificado.", "NonExactlyArgs": "o comando “{command_name}” requer exatamente {expected} argumentos, mas {actual} foram fornecidos.", "NonOneRemainingArgs": "o comando “{command_name}” requer exatamente um argumento", @@ -834,8 +860,8 @@ "Options": "Opções", "OriginalBinParagraphHeader": "\nParágrafo Binário Original", "OtherCommandsHeader": "Outro", - "OverlayPatchDir": "O caminho de sobreposição \"{path}\" deve existir e deve ser um diretório.", - "OverlayPortsDirectoriesHelp": "Diretórios de portas de sobreposição (também: {env_var})", + "OverlayPatchDir": "O caminho de \"{path}\" deve ser um diretório existente.", + "OverlayPortsHelp": "Diretórios de porta sobreposição ou diretórios contendo diretórios de portas de sobreposição (também: {env_var})", "OverlayTripletDirectoriesHelp": "Diretórios de trigêmeos sobrepostos (também: {env_var})", "OverlayTriplets": "Sobreposição de triplos de {path}:", "OverwritingFile": "O arquivo {path} já estava presente e será substituído", @@ -927,6 +953,7 @@ "PortsUpdated": "As seguintes portas {count} foram atualizadas:", "PrebuiltPackages": "Existem pacotes que não foram construídos. Para construí-los execute:", "PreviousIntegrationFileRemains": "O arquivo de integração anterior não foi removido.", + "ProgramPathReturnedNonzeroExitCode": "falhou com o código de saída {exit_code}", "ProgramReturnedNonzeroExitCode": "{tool_name} falhou com o código de saída: ({exit_code}).", "ProvideExportType": "Pelo menos uma das seguintes opções é necessária: --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "Falha ao enviar {vendor} para \"{path}\". Use --debug para mais informações.", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "Tripleto do destino. Consulte 'vcpkg help triplet' (padrão: {env_var})", "StartCodeUnitInContinue": "unidade de código inicial encontrada na posição continuar", "StoreOptionMissingSha": "--store opção é inválida sem um sha512", - "StoredBinariesToDestinations": "Binários armazenados em {count} destinos em {elapsed}.", + "SubmittingBinaryCacheBackground": "Iniciando envio de {spec} para {count} cache(s) binário(s) em segundo plano", + "SubmittingBinaryCacheComplete": "Envio de {spec} para {count} cache(s) binário(s) em {elapsed}", "SuccessfulyExported": "Exportou {package_name} para {path}", "SuggestGitPull": "O resultado pode estar desatualizado. Execute `git pull` para obter os resultados mais recentes.", "SuggestStartingBashShell": "Verifique se você iniciou um novo shell de bash para que a alteração entre em vigor.", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "falha ao instalar o arquivo de destinos do sistema em {path}", "ToRemovePackages": "Para remover somente pacotes desatualizados, execute\n{command_name} remove --outdated", "ToUpdatePackages": "Para atualizar esses pacotes e todas as dependências, execute\n {command_name} upgrade'", + "ToolDataFileSchemaVersionNotSupported": "versão do esquema de {version} não tem suporte nesta versão do vcpkg", "ToolFetchFailed": "Não foi possível buscar {tool_name}.", + "ToolHashMismatch": "{tool_name} parece já ter sido baixado, mas tem um hash incorreto. Esperado {expected} mas foi {actual}", "ToolInWin10": "Este utilitário é fornecido com o Windows 10 ou posterior.", "ToolOfVersionXNotFound": "Uma versão adequada de {tool_name} não foi encontrada (v{version} exigida) e não é possível baixar automaticamente uma versão portátil. Instale uma versão mais recente de {tool_name}", "TotalInstallTime": "Tempo total de instalação: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "registro atualizado '{url}': linha de base '{old_value}' -> '{new_value}'", "UpgradeInManifest": "A atualização atualiza uma instalação no modo clássico e, portanto, não oferece suporte ao modo manifesto. Considere atualizar suas dependências atualizando sua linha de base para um valor atual com vcpkg x-update-baseline e executando a instalação vcpkg.", "UpgradeRunWithNoDryRun": "Se você tiver certeza de que deseja reconstruir os pacotes acima, execute este comando com a opção --no-dry-run.", - "UploadingBinariesToVendor": "Carregando binários de \"{spec}\" para o \"{vendor}\" na origem \"{path}\".", + "UploadingBinariesToVendor": "Carregando binários para {spec} para {vendor} de {path}", "UsageInstallInstructions": "você pode instalar o arquivo de uso com o CMake a seguir", "UsageTextHere": "o arquivo de uso está aqui", "UseEnvVar": "-- Usando {env_var} nas variáveis de ambiente.", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "{actual} foi atribuída ao {package_name}, mas a porta local é {expected}", "VersionBuiltinPortTreeEntryMissing": "nenhuma entrada de banco de dados de versão para {package_name} em {expected}; usando a versão da árvore de portas verificada ({actual}).", "VersionCommandHeader": "versão do programa de gerenciamento de pacotes vcpkg {version}\n\nConsulte LICENSE.txt para obter informações de licença.", - "VersionConflictXML": "Versão {path} esperada: [{expected_version}], mas era [{actual_version}]. Execute bootstrap-vcpkg novamente.", "VersionConstraintNotInDatabase1": "a restrição \"version>=\" para a versão {version} dos nomes do {package_name}, que não existe no banco de dados da versão. Todas as versões precisam existir no banco de dados da versão para serem interpretadas pelo vcpkg.", "VersionConstraintNotInDatabase2": "pense em remover a restrição da versão ou em escolher um valor declarado aqui", "VersionConstraintOk": "todas as restrições da versão são consistentes com o banco de dados da versão", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "\"#\" no texto da versão deve ser seguido por uma versão de porta (um inteiro não negativo)", "VersionSpecMismatch": "Falha ao carregar a porta porque as versões são inconsistentes. O arquivo \"{path}\" contém a versão {actual_version}, mas o banco de dados de versões indica que deve ser {expected_version}.", "VersionVerifiedOK": "{version_spec} está corretamente no banco de dados de versão ({git_tree_sha})", + "WaitUntilPackagesUploaded": "Aguardando envios {count} cache binário restante...", "WaitingForChildrenToExit": "Aguardando a saída dos processos filhos...", "WaitingToTakeFilesystemLock": "esperando para ativar o bloqueio do sistema de arquivos {path}...", "WarnOnParseConfig": "Os seguintes avisos foram encontrados na configuração {path}:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "ao carregar {version_spec}", "WhileLookingForSpec": "ao procurar {spec}:", "WhileParsingVersionsForPort": "ao analisar versões para {package_name} de {path}", + "WhileRunningAssetCacheScriptCommandLine": "ao executar a linha de comando do script do cache de ativos", "WhileValidatingVersion": "ao validar a versão: {version}", "WindowsOnlyCommand": "Este comando oferece suporte apenas ao Windows.", "WroteNuGetPkgConfInfo": "Escreveu as informações de configuração do pacote NuGet para {path}", diff --git a/locales/messages.ru.json b/locales/messages.ru.json index e75f2dfd3b..549983fb3a 100644 --- a/locales/messages.ru.json +++ b/locales/messages.ru.json @@ -4,6 +4,7 @@ "ABoolean": "логическое значение", "ABuiltinRegistry": "встроенный реестр", "AConfigurationObject": "объект конфигурации", + "ACpuArchitecture": "архитектура ЦП", "ADateVersionString": "строка версии даты", "ADefaultFeature": "компонент по умолчанию", "ADemandObject": "объект требования", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "строка нестрогой версии", "ASemanticVersionString": "строка семантической версии", "ASetOfFeatures": "набор функций", + "ASha512": "хэш SHA-512", "AString": "строка", "AStringOrArrayOfStrings": "строка или массив строк", "AStringStringDictionary": "\"string\": словарь \"string\"", + "AToolDataArray": "массив метаданных инструмента", + "AToolDataFile": "файл данных инструмента", + "AToolDataOS": "операционная система данных инструмента", + "AToolDataObject": "метаданные инструмента", + "AToolDataVersion": "версия данных инструмента", "AUrl": "URL-адрес", "AVcpkgRepositoryCommit": "фиксация репозитория vcpkg", "AVersionConstraint": "ограничение версии", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "Принудительно обнаруживает узел в Windows при получении артефактов", "ArtifactsSwitchX64": "Принудительно обнаруживает узел в x64 при получении артефактов", "ArtifactsSwitchX86": "Принудительно обнаруживает узел на x86 при получении артефактов", - "AssetCacheHit": "Попадание в кэше для ресурса по пути {path}; скачано с адреса {url}.", - "AssetCacheMiss": "Промах кэша для ресурса; выполняется скачивание с адреса {url}.", - "AssetCacheMissBlockOrigin": "Промах кэша для ресурса по пути {path}, и загрузки заблокированы x-block-origin.", + "AssetCacheConsult": "Попытка скачать {path} с помощью кэша ресурсов {url}", + "AssetCacheConsultScript": "Попытка скачать {path} с помощью сценария кэша ресурсов", + "AssetCacheHit": "Скачивание выполнено успешно! Попадание в кэш ресурсов.", + "AssetCacheHitUrl": "Скачивание выполнено успешно! Попадание в кэш ресурсов, не выполнена попытка авторизованного исходного {url}", + "AssetCacheMiss": "Промах кэша ресурсов; выполняется попытка принудительного {url}", + "AssetCacheMissBlockOrigin": "не обнаружено попаданий в кэш ресурсов, а блоки X-block-origin пытается использовать заслуживающий доверия источник {url}", + "AssetCacheMissNoUrls": "Кэш ресурсов пропущен при поиске {sha} и неизвестен заслуживающий доверия URL-адрес", "AssetCacheProviderAcceptsNoArguments": "непредвиденные аргументы: \"{value}\" не принимает аргументы", - "AssetCacheSuccesfullyStored": "Путь {path} для URL-адреса {url} сохранен.", + "AssetCacheScriptBadVariable": "шаблон скрипта {value} содержит неизвестные заменяемые {list}", + "AssetCacheScriptBadVariableHint": "если это необходимо в командной строке литерала, используйте {{{{{list}}}}", + "AssetCacheScriptCommandLine": "командная строка полного сценария:", + "AssetCacheScriptFailed": "сценарий кэша ресурсов вернул ненулевой код завершения {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "скрипт кэша ресурсов вернул успешное выполнение, но полученный файл имеет непредвиденный хэш", + "AssetCacheScriptFailedToWriteFile": "скрипт кэша ресурсов вернул успешное выполнение, но не вернул ожидаемый файл результатов", + "AssetCacheScriptNeedsSha": "для шаблона {value} требуется SHA, но sha не известен для попытки скачивания {url}", + "AssetCacheScriptNeedsUrl": "для шаблона {value} требуется URL-адрес, но ни один URL-адрес неизвестен для попытки скачивания {sha}", + "AssetCacheSuccesfullyStored": "Магазин успешно сохранен", "AssetSourcesArg": "Источники для кэширования ресурсов. См. \"vcpkg help assetcaching\"", "AttemptingToSetBuiltInBaseline": "попытка задать встроенный базовый план в vcpkg.json при переопределения default-registry в vcpkg-configuration.json.\nБудет использоваться default-registry из vcpkg-configuration.json.", "AuthenticationMayRequireManualAction": "Один или несколько поставщиков учетных данных {vendor} запросили действие вручную. Добавьте двоичный источник «интерактивный», чтобы обеспечить интерактивность.", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "Количество начальных каталогов, которые нужно удалить из всех путей", "CommandEnvExample2": "vcpkg env \"ninja -C <путь>\" --triplet x64-windows", "CommandFailed": "следующую команду:\n{command_line}\nвыполнить не удалось. Выдано сообщение об ошибке:", - "CommandFailedCode": "следующую команду:\n{command_line}\nвыполнить не удалось. Возвращен код выхода {exit_code} и следующее сообщение:", "CommunityTriplets": "Триплеты сообщества:", "CompilerPath": "Найден компилятор: {path}", - "CompressFolderFailed": "Сбой сжатия папки \"{path}\":", "ComputingInstallPlan": "Вычисление плана установки...", "ConfigurationErrorRegistriesWithoutBaseline": "Конфигурация, определенная в {path}, недопустима..\n\nПри использовании реестров необходимо, чтобы для стандартного реестра были настроены базовые показатели или чтобы стандартному реестру было присвоено значение NULL.\n\nДополнительные сведения: {url}.", "ConfigurationNestedDemands": "[\"{json_field}\"] содержит вложенный объект \"demands\" (вложенный объект \"demands\" не оказывает влияния)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "Не удалось определить идентификатор nuget и версию по имени файла: {path}", "CouldNotFindBaselineInCommit": "Не удалось найти базовый показатель в ссылке {url} в {commit_sha} для {package_name}.", "CouldNotFindGitTreeAtCommit": "не удалось найти дерево Git для \"versions\" в репозитории {package_name} фиксации {commit_sha}", - "CouldNotFindToolVersion": "Не удалось найти в {path}", "CouldNotFindVersionDatabaseFile": "Не удалось найти файл базы данных версий: {path}", "CreateFailureLogsDir": "Создание выходного каталога для журналов сбоев: {path}.", "CreatedNuGetPackage": "Создан пакет nupkg: {path}", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "Создание пакета NuGet...", "CreatingZipArchive": "Создание архива Zip...", "CreationFailed": "Не удалось создать {path}.", + "CurlFailedGeneric": "Операция завитка завершилась сбоем, код ошибки {exit_code}.", "CurlFailedToPut": "curl не удалось поместить файл в {url} с кодом завершения {exit_code}.", "CurlFailedToPutHttp": "curl не удалось поместить файл в {url} с кодом завершения {exit_code} и HTTP-кодом {value}.", - "CurlResponseTruncatedRetrying": "Вызов curl возвратил частичный ответ; через {value} миллисекунд попытка будет повторена", - "CurlTimeout": "Вызову curl не удалось выполнить все запрашиваемые операции HTTP даже после ожидания и повторного выполнения. Последняя командная строка: {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "Не удалось вернуть ожидаемое число кодов завершения. это может произойти, если что-то завершает завиток до его завершения. Завиток завершился {exit_code} что обычно является кодом результата последней операции, но может быть результатом сбоя. Командная строка {command_line}, и все выходные данные приведены ниже:", "CurrentCommitBaseline": "Текущую фиксацию можно использовать в качестве базового плана, а именно:\n\t\"builtin-baseline\": \"{commit_sha}\"", "CycleDetectedDuring": "обнаружен цикл во время {spec}:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "Переменная среды VCPKG_DEFAULT_BINARY_CACHE должна быть каталогом (было: {path})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "библиотеки DLL здесь относятся к ${{CURRENT_PACKAGES_DIR}}", "DocumentedFieldsSuggestUpdate": "Если это задокументированные поля, которые следует распознать, попробуйте обновить средство VCPKG.", "DownloadAvailable": "Доступна загружаемая копия этого инструмента, которую можно использовать, отключив {env_var}.", - "DownloadFailedCurl": "{url}: не удалось скачать curl с кодом завершения {exit_code}", - "DownloadFailedHashMismatch": "Файл не содержит ожидаемого хэша:\nURL-адрес: {url}\nФайл: {path}\nОжидаемый хэш: {expected}\nФактический хэш: {actual}", - "DownloadFailedProxySettings": "Не удалось скачать {path}.\nЕсли вы используете прокси-сервер, проверьте правильность его настроек.\nВозможные причины:\n1. Фактически вы используете HTTP-прокси, но устанавливаете переменную HTTPS_PROXY на `https//address:port`.\nЭто неправильно, поскольку префикс `https://` утверждает, что прокси-сервер является HTTPS-прокси, в то время как этот прокси-сервер (v2ray, shadowsocksr и т. д.) является HTTP-прокси.\nПопробуйте вместо \"http://address:port\" задать значение HTTP_PROXY и HTTPS_PROXY.\n2. Если вы используете Windows, vcpkg автоматически будет использовать настройки прокси-сервера Windows IE, установленные программным обеспечением прокси-сервера. См. {url}\nЗначение, установленное прокси-сервером, может быть неправильным или содержать тот же префикс \"https://\".\n3. Удаленный сервер этого прокси-сервера не обслуживается.\nЕсли вы попытались напрямую скачать ссылку и считаете, что это не временный сбой сервера загрузки, отправьте сообщение о проблеме по адресу https://github.com/Microsoft/vcpkg/issues\nчтобы сообщить об этом сбое сервера загрузки восходящего потока данных.", - "DownloadFailedRetrying": "Сбой скачивания — повторная попытка через {value} мс", + "DownloadFailedHashMismatch": "скачивание из {url} имеет непредвиденный хэш", + "DownloadFailedHashMismatchActualHash": "Фактически: {sha}", + "DownloadFailedHashMismatchExpectedHash": "Ожидается: {sha}", + "DownloadFailedHashMismatchZero": "не удалось скачать, так как ожидаемый SHA512 был нулевым. Измените ожидаемое значение SHA512 на: {sha}", + "DownloadFailedProxySettings": "Если вы используете прокси-сервер, проверьте правильность параметров прокси-сервера.\nВозможные причины:\n1. Вы действительно используете HTTP-прокси, но HTTPS_PROXY переменную \"https//address:port\".\nЭто неправильно, так как префикс \"https://\" утверждает, что прокси-сервер является HTTPS-прокси, а прокси-сервер (v2ray, shadowsocksr и т. д.) является HTTP-прокси.\nПопробуйте задатьhttp://address:port` для HTTP_PROXY и HTTPS_PROXY.\n2. Если вы используете Windows, vcpkg автоматически использует параметры прокси-сервера Windows IE, заданные программным обеспечением прокси-сервера. Просмотреть: https://github.com/microsoft/vcpkg-tool/pull/77\nЗначение, заданное прокси-сервером, может быть неправильным или иметь одну и ту же https:// префикса \"https://\".\n3. Удаленный сервер вашего прокси-сервера является нашим службой.\nЕсли вы считаете, что это не временная ошибка сервера загрузки и необходимо изменить VCPKG для скачивания этого файла из другого расположения, отправьте проблему в https://github.com/Microsoft/vcpkg/issues", + "DownloadFailedRetrying": "Сбой скачивания {url} — повторная попытка через {value} мс", "DownloadFailedStatusCode": "{url}: сбой: код состояния {value}", + "DownloadOrUrl": "или {url}", "DownloadRootsDir": "Скачивает каталог (по умолчанию: {env_var})", - "DownloadSuccesful": "Скачан {path}.", - "DownloadWinHttpError": "{url}: сбой {system_api} с кодом завершения {exit_code}", + "DownloadSuccesful": "Успешно загружено {path}", + "DownloadSuccesfulUploading": "Успешно загружена {path}, сохранена в {url}", + "DownloadTryingAuthoritativeSource": "Попытка {url}", + "DownloadWinHttpError": "{url}: сбой {system_api} с кодом завершения {exit_code}.", "DownloadedSources": "Скачанные источники для {spec}", + "DownloadingAssetShaToFile": "Скачивание записи кэша ресурсов {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "запрошено скачивание записи кэша ресурсов {sha} -> {path}, но кэши ресурсов не настроены", + "DownloadingFile": "Скачивание {path}", + "DownloadingFileFirstAuthoritativeSource": "Скачивание {path}, попытка {url}", "DownloadingPortableToolVersionX": "Подходящая версия инструмента {tool_name} не найдена (требуется версия {version}).", - "DownloadingUrl": "Выполняется скачивание {url}", + "DownloadingUrlToFile": "Скачивание {url} -> {path}", "DownloadingVcpkgStandaloneBundle": "Скачивание изолированного пакета {version}.", "DownloadingVcpkgStandaloneBundleLatest": "Скачивание новейшего изолированного пакета.", + "DuplicateDependencyOverride": "{package_name} уже имеет переопределение", "DuplicatePackagePattern": "Пакет \"{package_name}\" дублируется.", "DuplicatePackagePatternFirstOcurrence": "Первое объявление в:", "DuplicatePackagePatternIgnoredLocations": "Следующие повторные объявления будут пропущены.", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "Параметр --{option} не поддерживается в классическом режиме, и манифест не найден.", "ErrorInvalidExtractOption": "В качестве параметра --{option} должно быть установлено неотрицательное целое число или значение \"AUTO\".", "ErrorInvalidManifestModeOption": "Параметр --{option} не поддерживается в режиме манифеста.", + "ErrorManifestMustDifferFromOverlay": "Каталог манифеста ({path}) не может совпадать с каталогом, настроенным в наложенных портах.", + "ErrorManifestMustDifferFromOverlayDot": "Каталог манифеста не может совпадать с каталогом, настроенным в наложенных портах, поэтому значения \"overlay-ports\" не могут иметь значение \".\".", "ErrorMissingVcpkgRoot": "Не удалось обнаружить vcpkg-root. Если вы пытаетесь использовать созданную копию VCPKG, необходимо определить переменную среду VCPKG_ROOT, чтобы она указывала на клонированную копию https://github.com/Microsoft/vcpkg.", "ErrorNoVSInstance": "в триплете {triplet}: Не удается найти допустимый экземпляр Visual Studio", "ErrorNoVSInstanceAt": "в \"{path}\"", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "Не удалось проанализировать {path}, ожидался массив \"versions\".", "FailedToParseSerializedBinParagraph": "[проверка работоспособности] Не удалось проанализировать абзац сериализованного двоичного файла.\nОткройте проблему на странице https://github.com/microsoft/vcpkg со следующими выходными данными:\n{error_msg}\nАбзац сериализованного двоичного файла:", "FailedToParseVersionFile": "Не удалось проанализировать файл версии: {path}", - "FailedToParseVersionXML": "Не удалось проанализировать версию инструмента {tool_name}. Строка версии: {version}", "FailedToRunToolToDetermineVersion": "Сбой запуска \"{path}\" для определения версии {tool_name}.", "FailedToStoreBackToMirror": "Не удалось сохранить путь {path} для URL-адреса {url}.", "FailedToStoreBinaryCache": "Сбой сохранения двоичного кэша {path}", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "Получение сведений реестра из {url} ({value})...", "FieldKindDidNotHaveExpectedValue": "неожиданное значение \"kind\": (ожидалось одно из следующих значений: {expected}; найдено {actual})", "FileIsNotExecutable": "этот файл не похож на исполняемый", - "FileNotFound": "{path}: файл не найден", + "FileNotFound": "файл не найден", "FileReadFailed": "Не удалось прочитать {count} байт из {path} по смещению {byte_offset}.", "FileSeekFailed": "Не удалось найти расположение {byte_offset} в {path}.", "FilesContainAbsolutePath1": "В установленном пакете не должно быть абсолютных путей, таких как следующие. Чтобы скрыть это сообщение, добавьте set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "неизвестное состояние файла: {value}", "GitUnexpectedCommandOutputCmd": "Git создал непредвиденные выходные данные при выполнении {command_line}", "GraphCycleDetected": "Обнаружен цикл в графе в {package_name}:", - "HashFileFailureToRead": "сбой при чтении файла \"{path}\" для хеширования: ", "HashPortManyFiles": "{package_name} содержит несколько файлов ({count}). Хэширование этого содержимого может занять много времени при определении хэша ABI для двоичного кэширования. Рассмотрите возможность уменьшения количества файлов. Распространенные причины: случайное извлечение исходных файлов или файлов сборки в каталог порта.", "HeaderOnlyUsage": "{package_name} является заголовочным и может использоваться из CMake через:", "HelpAssetCaching": "**Экспериментальная функция: она может быть изменена или удалена в любое время**\n\nvcpkg может использовать зеркала для кэширования скачанных ресурсов, что гарантирует продолжение операции, даже если исходный источник изменяется или исчезает.\n\nКэширование ресурсов можно настроить, задав для переменной среды X_VCPKG_ASSET_SOURCES список источников с разделителями-точками с запятой или передав последовательность параметров командной строки --x-asset-sources=. Источники командной строки интерпретируются после источников среды. Запятые, точки с запятой и обратные апострофы можно экранировать с помощью обратного апострофа (`).\n\nНеобязательный параметр для определенных строк управляет способом получения к ним доступа. Для него можно указать значения \"read\", \"write\" или \"readwrite\". По умолчанию используется \"read\".\n\nДопустимые источники:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "Завершает работу сбоем, если кэшированные двоичные файлы недоступны.", "HelpTxtOptOnlyDownloads": "Делает все возможное, чтобы скачать исходники без сборки", "HelpTxtOptRecurse": "Разрешает удалять пакеты в рамках установки.", - "HelpTxtOptUseAria2": "Использует aria2 для выполнения задач скачивания", "HelpTxtOptUseHeadVersion": "Устанавливает библиотеки из командной строки, используя последние исходные коды (классический режим).", "HelpTxtOptWritePkgConfig": "Записывает файл в формате NuGet packages.config для использования с внешним двоичным кэшированием. Дополнительные сведения см. в `vcpkg helpbinarcaching`.", "HelpUpdateBaseline": "Лучший способ поддержания библиотек в актуальном состоянии — обновление базового эталона. Это обеспечит обновление всех пакетов, включая транзитивные. Но если вам нужно обновить пакет независимо, вы можете использовать ограничение \"version>=\".", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "Интеграция не была применена для Visual Studio 2015.", "InternalCICommand": "vcpkg ci — внутренняя команда, она может измениться несовместимым образом или может быть удалена в любое время.", "InternalErrorMessageContact": "Откройте проблему на странице https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug с подробными инструкциями по ее воспроизведению.", - "InvalidArchitecture": "недопустимая архитектура: {value}", + "InvalidArchitectureValue": "Недопустимая архитектура: {value}. Ожидается одно из следующих: {expected}", "InvalidArgument": "недопустимый аргумент.", "InvalidArgumentRequiresAbsolutePath": "недопустимый аргумент: аргументы пути двоичной config \"{binary_source}\" для двоичных строк config должны быть абсолютными", "InvalidArgumentRequiresBaseUrl": "недопустимый аргумент: для двоичной config \"{binary_source}\" в качестве первого аргумента требуется базовый URL-адрес {base_url}", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "недопустимое логическое выражение, используйте \"|\", а не \"или\"", "InvalidOptionForRemove": "\"remove\" принимает библиотеки или \"--outdated\"", "InvalidPortVersonName": "Обнаружено недопустимое имя файла версии порта: \"{path}\".", + "InvalidSha512": "недопустимый хэш SHA-512: {sha}\nХэш SHA-512 должен содержать 128 символов и содержать только шестнадцатеричные цифры", "InvalidSharpInVersion": "недопустимый символ \"#\" в тексте версии", "InvalidSharpInVersionDidYouMean": "недопустимый символ \"#\" в тексте версии. Вы имели в виду \"port-version\": {value}?", "InvalidString": "Недопустимый utf8 передается значению Value::string(std::string)", + "InvalidToolOSValue": "Недопустимая операционная система средства: {value}. Ожидается одно из следующих: {expected}", + "InvalidToolVersion": "Недопустимая версия средства; требуется строка, содержащая подстроку от 1 до 3 чисел, разделенных точками.", "InvalidTriplet": "Недопустимая триада: {triplet}", "InvalidUri": "не удалось проанализировать URI: {value}", "InvalidValueHashAdditionalFiles": "Переменная VCPKG_HASH_ADDITIONAL_FILES содержит недопустимый путь к файлу: \"{path}\". Значение должно быть абсолютным путем к существующему файлу.", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "Абзац сериализованного двоичного файла отличался от абзаца исходного двоичного файла. Откройте проблему на странице https://github.com/microsoft/vcpkg со следующими выходными данными:", "MismatchedFiles": "файл для хранения не соответствует хэшу", "MismatchedManifestAfterReserialize": "Сериализованный манифест отличался от исходного манифеста. Откройте проблему на странице https://github.com/microsoft/vcpkg со следующими выходными данными:", - "MismatchedNames": "имена не совпадают: \"{package_name}\" != \"{actual}\"", + "MismatchedNames": "имя порта, объявленное в файле метаданных, не соответствует каталогу. Ожидался порт с именем {package_name}, но файл объявляет {actual}.", "MismatchedSpec": "Несоответствие спецификации в порту {path}: ожидается {expected}, фактический {actual}", "MismatchedType": "{json_field}: несоответствующий тип: ожидается {json_type}", "Missing7zHeader": "Не удалось найти заголовок 7z.", "MissingAndroidEnv": "Отсутствует переменная среды ANDROID_NDK_HOME", "MissingAndroidHomeDir": "Каталог ANDROID_NDK_HOME не существует: {path}", "MissingArgFormatManifest": "манифест формата был передан --convert-control без '--all'.\nЭто ничего не делает: явно переданные управляющие файлы преобразуются автоматически.", - "MissingAssetBlockOrigin": "Путь {path} отсутствует, и загрузки заблокированы x-block-origin.", "MissingClosingParen": "отсутствует закрывающая скобка )", "MissingDependency": "Пакет {spec} установлен, но зависимость {package_name} не установлена.", "MissingExtension": "Отсутствует расширение \"{extension}\".", @@ -814,7 +841,6 @@ "NoInstalledPackages": "Нет установленных пакетов. Вы имели в виду \"search\"?", "NoOutdatedPackages": "Нет устаревших пакетов.", "NoRegistryForPort": "Не настроен реестр для порта {package_name}.", - "NoUrlsAndHashSpecified": "Не указаны URL-адреса для скачивания SHA: {sha}", "NoUrlsAndNoHashSpecified": "URL-адреса и хэш не указаны.", "NonExactlyArgs": "команда \"{command_name}\" требует ровно {expected} аргументов, но указано {actual}", "NonOneRemainingArgs": "команда \"{command_name}\" требует ровно один аргумент", @@ -834,8 +860,8 @@ "Options": "Параметры", "OriginalBinParagraphHeader": "\nАбзац исходного двоичного файла", "OtherCommandsHeader": "Другое", - "OverlayPatchDir": "Путь наложения \"{path}\" должен существовать и быть каталогом.", - "OverlayPortsDirectoriesHelp": "Каталоги портов наложения (также: {env_var})", + "OverlayPatchDir": "Путь наложения \"{path}\" должен быть существующим каталогом.", + "OverlayPortsHelp": "Каталоги наложения портов или каталоги, содержащие каталоги наложения портов (также: {env_var})", "OverlayTripletDirectoriesHelp": "Каталоги триплетов наложения (также: {env_var})", "OverlayTriplets": "Триплеты наложения из \"{path}\":", "OverwritingFile": "Файл {path} уже существует и будет перезаписан", @@ -927,6 +953,7 @@ "PortsUpdated": "Обновлены следующие порты ({count}):", "PrebuiltPackages": "Существуют несобранные пакеты. Чтобы собрать их, выполните:", "PreviousIntegrationFileRemains": "Предыдущий файл интеграции не был удален.", + "ProgramPathReturnedNonzeroExitCode": "сбой с кодом завершения {exit_code}", "ProgramReturnedNonzeroExitCode": "Сбой средства {tool_name} с кодом завершения {exit_code}.", "ProvideExportType": "Требуется хотя бы один из следующих параметров: --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "Сбой отправки {vendor} в \"{path}\". Для получения дополнительных сведений, используйте --debug.", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "Триплет целевого объекта. См. \"vcpkg help triplet\" (по умолчанию: {env_var})", "StartCodeUnitInContinue": "найдена единица начального кода в позиции продолжения", "StoreOptionMissingSha": "Параметр --store недопустим без sha512", - "StoredBinariesToDestinations": "Двоичные файлы сохранены в нескольких ({count}) назначениях за {elapsed}.", + "SubmittingBinaryCacheBackground": "Начинается отправка {spec} в {count} двоичных кэшах в фоновом режиме", + "SubmittingBinaryCacheComplete": "Завершена отправка {spec} в {count} двоичных кэшах в {elapsed}", "SuccessfulyExported": "Пакет {package_name} экспортирован в папку {path}", "SuggestGitPull": "Результат может быть устаревшим. Чтобы получить последние результаты, запустите \"git pull\".", "SuggestStartingBashShell": "Чтобы изменения вступили в силу, пожалуйста, проверьте, запустили ли вы новую оболочку bash,", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "не удалось установить файл целей построения в {path}", "ToRemovePackages": "Чтобы удалить только устаревшие пакеты, запустите команду\n{command_name} remove --outdated", "ToUpdatePackages": "Чтобы обновить эти пакеты и все зависимости, запустите команду обновления\n{command_name}", + "ToolDataFileSchemaVersionNotSupported": "версия схемы {version} не поддерживается данной версией vcpkg", "ToolFetchFailed": "Не удалось получить {tool_name}.", + "ToolHashMismatch": "{tool_name} уже скачан, но имеет неправильный хэш. Ожидалось {expected}, но {actual}", "ToolInWin10": "Эта служебная программа поставляется в комплекте с Windows 10 и более поздней версии.", "ToolOfVersionXNotFound": "Подходящая версия {tool_name} не найдена (требуется v{version}) и не может автоматически загрузить портативную версию. Установите более новую версию {tool_name}", "TotalInstallTime": "Общее время установки: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "обновленный реестр \"{url}\": базовый план \"{old_value}\" -> \"{new_value}\"", "UpgradeInManifest": "Обновление обновляет установку в классическом режиме и поэтому не поддерживает режим манифеста. Попробуйте обновить зависимости, обновив базовый план до текущего значения с помощью vcpkg x-update-baseline и запустив установку vcpkg.", "UpgradeRunWithNoDryRun": "Если вы действительно хотите повторно собрать перечисленные выше пакеты, запустите эту команду с параметром --no-dry-run.", - "UploadingBinariesToVendor": "Загрузка двоичных файлов для \"{spec}\" в источник \"{vendor}\" \"{path}\".", + "UploadingBinariesToVendor": "Отправка двоичных файлов для {spec} в {vendor} из {path}", "UsageInstallInstructions": "файл использования можно установить с помощью следующего CMake", "UsageTextHere": "файл использования находится здесь", "UseEnvVar": "-- Использование {env_var} в переменных окружения.", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "Для {package_name} назначено {actual}, но локальный порт: {expected}", "VersionBuiltinPortTreeEntryMissing": "отсутствует запись базы данных версий для {package_name} в {expected}; с использованием извлеченной версией дерева портов ({actual}).", "VersionCommandHeader": "Версия программы управления пакетами vcpkg {version}\n\nСм. LICENSE.txt для получения сведений о лицензии.", - "VersionConflictXML": "Ожидаемая версия {path}: [{expected_version}], но была [{actual_version}]. Повторно запустите bootstrap-vcpkg.", "VersionConstraintNotInDatabase1": "ограничение \"version>=\" версии {version} имен {package_name}, которая не существует в базе данных версий. Все версии должны существовать в базе данных версий для интерпретации с помощью vcpkg.", "VersionConstraintNotInDatabase2": "рассмотрите возможность удалить ограничение версии или выбрать значение, объявленное здесь", "VersionConstraintOk": "все ограничения версий согласованы с базой данных версий", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "после \"#\" в тексте версии должна следовать версия порта (неотрицательное целое число)", "VersionSpecMismatch": "Не удалось загрузить порт, так как версии не согласованы. Файл \"{path}\" содержит версию {actual_version}, но база данных версий указывает, что она должна быть {expected_version}.", "VersionVerifiedOK": "параметр {version_spec} правильно указан в базе данных версий ({git_tree_sha})", + "WaitUntilPackagesUploaded": "Ожидание {count} отправки двоичного кэша...", "WaitingForChildrenToExit": "Ожидание завершения дочерних процессов...", "WaitingToTakeFilesystemLock": "ожидание блокировки файловой системы в {path}...", "WarnOnParseConfig": "Обнаружены следующие предупреждения в конфигурации {path}:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "при загрузке {version_spec}", "WhileLookingForSpec": "при поиске {spec}:", "WhileParsingVersionsForPort": "при анализе версий для {package_name} из {path}", + "WhileRunningAssetCacheScriptCommandLine": "при выполнении командной строки сценария кэша ресурсов", "WhileValidatingVersion": "при проверке версии: {version}", "WindowsOnlyCommand": "Эта команда поддерживает только Windows.", "WroteNuGetPkgConfInfo": "Сведения о конфигурации пакета NuGet записаны в {path}", diff --git a/locales/messages.tr.json b/locales/messages.tr.json index d80d0e1959..6bbabd6c3c 100644 --- a/locales/messages.tr.json +++ b/locales/messages.tr.json @@ -4,6 +4,7 @@ "ABoolean": "boole", "ABuiltinRegistry": "yerleşik kayıt defteri", "AConfigurationObject": "yapılandırma nesnesi", + "ACpuArchitecture": "CPU mimarisi", "ADateVersionString": "tarih sürümü dizesi", "ADefaultFeature": "varsayılan bir özellik", "ADemandObject": "istek nesnesi", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "esnek sürüm dizesi", "ASemanticVersionString": "anlamsal sürüm dizesi", "ASetOfFeatures": "özellikler kümesi", + "ASha512": "SHA-512 karması", "AString": "dize", "AStringOrArrayOfStrings": "dize veya dizeler dizisi", "AStringStringDictionary": "\"string\": \"string\" sözlüğü", + "AToolDataArray": "araç meta verileri dizisi", + "AToolDataFile": "araç veri dosyası", + "AToolDataOS": "bir araç verisi işletim sistemi", + "AToolDataObject": "araç meta verileri", + "AToolDataVersion": "araç verisi sürümü", "AUrl": "URL", "AVcpkgRepositoryCommit": "vcpkg depo işlemesi", "AVersionConstraint": "bir sürüm kısıtlaması", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "Yapıtlar alınırken Windows için konak algılamayı zorlar", "ArtifactsSwitchX64": "Yapıtlar alınırken x64 için konak algılamayı zorlar", "ArtifactsSwitchX86": "Yapıtlar alınırken x86 için konak algılamayı zorlar", - "AssetCacheHit": "{path} için varlık önbelleğine erişildi; {url} adresinden indiriliyor", - "AssetCacheMiss": "Varlık önbelleğine erişilemedi; {url} adresinden indiriliyor", - "AssetCacheMissBlockOrigin": "{path} için varlık önbelleğine erişilemedi ve indirmeler x blok kaynağı tarafından engellendi.", + "AssetCacheConsult": "Varlık önbelleği {path} indirmeye {url}", + "AssetCacheConsultScript": "Varlık önbelleği betiği {path} indirmeye çalışılıyor", + "AssetCacheHit": "İndirme başarılı! Varlık önbelleği isabeti.", + "AssetCacheHitUrl": "İndirme başarılı! Varlık önbelleği isabeti, yetkili kaynak isabeti {url}", + "AssetCacheMiss": "Varlık önbelleği isabetsizliği; yetkili kaynak {url}", + "AssetCacheMissBlockOrigin": "varlık önbelleği isabeti yok ve yetkili kaynak isabeti alınmaya çalışılırken x bloğu başlangıç {url}", + "AssetCacheMissNoUrls": "Varlık önbelleğinde eksik arama {sha} ve yetkili URL bilinmiyor", "AssetCacheProviderAcceptsNoArguments": "beklenmeyen bağımsız değişkenler: '{value}', bağımsız değişkenleri kabul etmiyor", - "AssetCacheSuccesfullyStored": "{path} yolu {url} adresine başarıyla depolandı.", + "AssetCacheScriptBadVariable": "betik şablonu {value} bilinmeyen bir değişiklik {list}", + "AssetCacheScriptBadVariableHint": "bunu sabit komut satırında istiyorsanız {{{{list}}}} kullanın", + "AssetCacheScriptCommandLine": "tam betik komut satırı", + "AssetCacheScriptFailed": "varlık önbelleği betiği sıfır olmayan çıkış kodu döndürdü{exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "varlık önbellek betiği başarı döndürdü, ancak sonuç dosyasında beklenmeyen bir karma var", + "AssetCacheScriptFailedToWriteFile": "varlık önbellek betiği başarılı oldu ancak beklenen sonuç dosyasını oluşturmadı", + "AssetCacheScriptNeedsSha": "betik şablonu {value} SHA gerektiriyor, ancak bu şablonun indirilmesi denenen sha {url}", + "AssetCacheScriptNeedsUrl": "betik şablonu {value} URL gerektiriyor, ancak bu şablonun indirilmesi denenen URL {sha}", + "AssetCacheSuccesfullyStored": "Mağaza başarılı", "AssetSourcesArg": "Varlık önbelleğe alma kaynakları. Bkz. 'vcpkg help assetcaching'", "AttemptingToSetBuiltInBaseline": "vcpkg-configuration.json içindeki varsayılan kayıt defteri geçersiz kılınırken vcpkg.json içinde yerleşik taban çizgisi ayarlanmaya çalışılıyor.\nvcpkg-configuration.json dosyasındaki varsayılan kayıt defteri kullanılacak.", "AuthenticationMayRequireManualAction": "Bir veya daha {vendor} kimlik bilgisi sağlayıcısı el ile eylem isteğinde bulundu. Etkileşime izin vermek için 'interactive' ikili kaynağı ekleyin.", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "Tüm yollardan kaldırılacak olan baştaki dizinlerin sayısı", "CommandEnvExample2": "vcpkg env \"ninja -C \" --triplet x64-windows", "CommandFailed": "komut:\n{command_line}\nkomutu aşağıdaki çıkışla başarısız oldu:", - "CommandFailedCode": "komut:\n{command_line}\nçıkış kodu {exit_code} ve aşağıdaki çıkış ile başarısız oldu:", "CommunityTriplets": "Topluluk Üçlüleri:", "CompilerPath": "Derleyici bulundu: {path}", - "CompressFolderFailed": "\"{path}\" klasörü sıkıştırılamadı:", "ComputingInstallPlan": "Yükleme planı işleniyor...", "ConfigurationErrorRegistriesWithoutBaseline": "{path} yolunda tanımlanan yapılandırma geçersiz.\n\nKayıt defterlerini kullanmak, varsayılan kayıt defteri için bir taban çizgisinin ayarlanmış veya varsayılan kayıt defterinin null olmasını gerektirir.\n\nDaha fazla ayrıntı için {url} adresine gidin.", "ConfigurationNestedDemands": "[\"{json_field}\"], iç içe geçmiş bir `demands` nesnesi içeriyor (iç içe geçmiş `demands`in hiçbir etkisi yoktur)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "{path} dosya adından NuGet kimliği ve sürümü çıkarılamadı", "CouldNotFindBaselineInCommit": "{package_name} için {commit_sha} konumunda {url} içinde temel bulunamadı.", "CouldNotFindGitTreeAtCommit": "{commit_sha} işleminde {package_name} deposundaki \"sürümler\" için git ağacı bulunamadı", - "CouldNotFindToolVersion": "{path} içinde bulunamadı", "CouldNotFindVersionDatabaseFile": "Sürümler veritabanı dosyası bulunamadı: {path}", "CreateFailureLogsDir": "Hata günlükleri çıkış dizini {path} oluşturuluyor.", "CreatedNuGetPackage": "Nupkg oluşturuldu: \"{path}\"", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "NuGet paketi oluşturuluyor...", "CreatingZipArchive": "Zip arşivi oluşturuluyor...", "CreationFailed": "{path} oluşturulamadı.", + "CurlFailedGeneric": "curl işlemi hata koduyla başarısız {exit_code}.", "CurlFailedToPut": "curl, {exit_code} çıkış koduyla dosyayı {url} URL’sine yerleştiremedi.", "CurlFailedToPutHttp": "curl, {exit_code} çıkış kodu ve {value} http kodu ile dosyayı {url} URL’sine yerleştiremedi.", - "CurlResponseTruncatedRetrying": "curl kısmi bir yanıt döndürdü; {value} milisaniye beklenip yeniden denenecek", - "CurlTimeout": "curl, zaman aşımı ve yeniden denemeler sonrasında bile istenen tüm HTTP işlemlerini gerçekleştiremedi. Son komut satırı: {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "curl beklenen sayıda çıkış kodu döndüremedi; bu durum, bir şey bitmeden önce kıvrımı sonlandırılırsa oluşabilir. curl, {exit_code} işlem için normalde sonuç kodu olan bir hatayla çıkıldı, ancak kilitlenme sonucu olabilir. Komut satırı {command_line} ve tüm çıkışlar aşağıdadır:", "CurrentCommitBaseline": "Mevcut işlemeyi temel olarak kullanabilirsiniz, yani:\n\"builtin-baseline\": \"{commit_sha}\"", "CycleDetectedDuring": "{spec} işlemi sırasında algılanan döngü:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "VCPKG_DEFAULT_BINARY_CACHE ortam değişkeni bir dizin olmalıdır (önceden: {yol})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "DLL’ler burada ${{CURRENT_PACKAGES_DIR}} ile görelidir", "DocumentedFieldsSuggestUpdate": "Bunlar, tanınması gereken belgelenmiş alanlarsa, vcpkg aracını güncellemeyi deneyin.", "DownloadAvailable": "Bu aracın indirilebilir bir kopyası var ve {env_var} ayarı kaldırılarak kullanılabilir.", - "DownloadFailedCurl": "{url} cURL’si {exit_code} çıkış koduyla indirilemedi", - "DownloadFailedHashMismatch": "Dosya beklenen karmayı içermiyor:\nURL: {url}\nDosya: {path}\nBeklenen karma: {expected}\nGerçek karma: {actual}", - "DownloadFailedProxySettings": "{path} indirilemedi.\nAra sunucu kullanıyorsanız lütfen ara sunucu ayarlarınızın doğru olduğundan emin olun.\nOlası nedenler şunlardır:\n1. Aslında bir HTTP proxy'si kullanıyorsunuz, ancak HTTPS_PROXY değişkeni 'https//address:port' olarak tanımlanmış.\nBu yanlış, çünkü `https://` öneki ara sunucunun bir HTTPS ara sunucusu olduğunu ileri sürer, oysa sizin ara sunucunuz (v2ray, shadowsocksr, vb...) bir HTTP ara sunucudur.\nBunun yerine HTTP_PROXY ve HTTPS_PROXY için 'http://address:port' ifadesini deneyin.\n2. Windows kullanıyorsanız vcpkg, ara sunucu yazılımınız tarafından ayarlanmış Windows IE Ara Sunucu Ayarlarınızı otomatik olarak kullanır. {url} bağlantısına bakın\nAra sunucunuz tarafından ayarlanmış değer yanlış olabilir veya yukarıdaki 'https://' önek sorununu yaşıyor olabilirsinz.\n3. Ara sunucunuzun uzak sunucusu çalışmıyor.\nBağlantıyı doğrudan indirmeyi denediyseniz ve bunun geçici bir indirme sunucusu hatası olmadığına inanıyorsanız lütfen https://github.com/Microsoft/vcpkg/issues adresine giderek\nbu yukarı akış indirme sunucusunun başarısız olduğu sorununu bildirin.", - "DownloadFailedRetrying": "İndirme başarısız - {value} ms sonra yeniden denenecek", + "DownloadFailedHashMismatch": "karşıdan {url} beklenmeyen bir karmaya sahip", + "DownloadFailedHashMismatchActualHash": "Gerçek : {sha}", + "DownloadFailedHashMismatchExpectedHash": "Beklenen: {sha}", + "DownloadFailedHashMismatchZero": "beklenen SHA512 sıfır olduğundan indirme başarısız oldu, lütfen beklenen SHA512'i şu şekilde {sha}", + "DownloadFailedProxySettings": "Ara sunucu kullanıyorsanız lütfen ara sunucu ayarlarınızın doğru olduğundan emin olun.\nOlası nedenler şunlardır:\n1. Aslında bir HTTP ara sunucusu kullanıyorsunuz ancak HTTPS_PROXY değişkeni 'https//address:port' olarak tanımlanmış.\nBu hatalı bir tanımlamadır çünkü `https://` ön eki ara sunucunun bir HTTPS ara sunucusu olduğunu ileri sürer oysa sizin ara sunucunuz (v2ray, shadowsocksr, vb...) bir HTTP ara sunucusudur.\nBunun yerine hem HTTP_PROXY hem de HTTPS_PROXY için ayarı 'http://address:port' olarak belirlemeyi deneyin.\n2. Windows kullanıyorsanız vcpkg otomatik olarak, ara sunucu yazılımınız tarafından ayarlanmış olan Windows IE Ara Sunucu Ayarlarınızı kullanır. Bkz: https://github.com/microsoft/vcpkg-tool/pull/77\nAra sunucunuz tarafından ayarlanmış olan değer yanlış olabilir veya aynı 'https://' ön ek sorununu yaşıyor olabilirsiniz.\n3. Ara sunucunuzun uzak sunucusu çalışmıyor.\nBunun geçici bir indirme sunucusu hatası olmadığını ve bu dosyayı farklı bir konumdan indirmek için vcpkg’nin değiştirilmesi gerektiğini düşünüyorsanız lütfen şuradan sorun bildirin: https://github.com/Microsoft/vcpkg/issues", + "DownloadFailedRetrying": "{url} indirme başarısız - {value} ms sonra yeniden denenecek", "DownloadFailedStatusCode": "{url} URL’si {value} durum koduyla başarısız oldu", + "DownloadOrUrl": "veya {url}", "DownloadRootsDir": "Dizini indirir (default: {env_var})", - "DownloadSuccesful": "{path} başarıyla indirildi.", - "DownloadWinHttpError": "{system_api} {url} URL’si {exit_code} çıkış koduyla başarısız oldu", + "DownloadSuccesful": "{path} başarıyla indirildi", + "DownloadSuccesfulUploading": "{path} başarıyla indirildi, {url}", + "DownloadTryingAuthoritativeSource": "{url}", + "DownloadWinHttpError": "{url}: {system_api} {exit_code} çıkış koduyla başarısız oldu.", "DownloadedSources": "{spec} için indirilen kaynaklar", + "DownloadingAssetShaToFile": "-> {path} için varlık {sha} girdisi indiriliyor", + "DownloadingAssetShaWithoutAssetCache": "-> {path} varlık önbelleği girdisi {sha} istendi, ancak varlık önbelleği yapılandırılmadı", + "DownloadingFile": "{path}", + "DownloadingFileFirstAuthoritativeSource": "{path} indiriliyor, {url}", "DownloadingPortableToolVersionX": "Uygun bir {tool_name} sürümü bulunamadı (v{version} gerekiyor).", - "DownloadingUrl": "{url} URL’si indiriliyor", + "DownloadingUrlToFile": "-> {path} {url} -{url} indiriliyor", "DownloadingVcpkgStandaloneBundle": "Tek başına paket {version} indiriliyor.", "DownloadingVcpkgStandaloneBundleLatest": "En son tek başına paket indiriliyor.", + "DuplicateDependencyOverride": "{package_name} zaten geçersiz kılmaya sahip", "DuplicatePackagePattern": "Paket \"{package_name}\" yineleniyor.", "DuplicatePackagePatternFirstOcurrence": "İlk bildirildiği yer:", "DuplicatePackagePatternIgnoredLocations": "Şu yeniden bildirimler yok sayılacak:", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "--{option} seçeneği klasik modda desteklenmiyor ve bildirim bulunamadı.", "ErrorInvalidExtractOption": "--{option} negatif olmayan bir tamsayıya veya 'AUTO' değerine ayarlanmalıdır.", "ErrorInvalidManifestModeOption": "--{option} seçeneği bildirim modunda desteklenmiyor.", + "ErrorManifestMustDifferFromOverlay": "Bildirim dizini ({path}) yer paylaşımı bağlantı noktalarında yapılandırılan bir dizinle aynı olamaz.", + "ErrorManifestMustDifferFromOverlayDot": "Bildirim dizini, yer paylaşımı bağlantı noktalarında yapılandırılan bir dizinle aynı olamaz, bu nedenle \"overlay-ports\" değerleri \".\" olamaz.", "ErrorMissingVcpkgRoot": "vcpkg-root algılanamadı. Oluşturduğunuz vcpkg'nin bir kopyasını kullanmaya çalışıyorsanız VCPKG_ROOT ortam değişkenini, klonlanan kopyasına işaret edecek şekilde tanımlamanız gerekir.", "ErrorNoVSInstance": "{triplet} üçlüsünde: Geçerli bir Visual Studio örneği bulunamıyor", "ErrorNoVSInstanceAt": "\"{path}\" konumunda", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "{path} ayrıştırılamadı, bir 'versions' dizisi bekleniyor.", "FailedToParseSerializedBinParagraph": "[sağlamlık kontrolü] Seri hale getirilmiş ikili paragraf ayrıştırılamadı.\nLütfen https://github.com/microsoft/vcpkg adresine giderek aşağıdaki çıkışla bir sorun açın:\n{error_msg}\nSeri Hale Getirilmiş İkili Paragraf:", "FailedToParseVersionFile": "Sürüm dosyası ayrıştırılamadı: {path}", - "FailedToParseVersionXML": "{tool_name} aracı için sürüm ayrıştırılamadı. Sürüm dizesi şuydu: {version}", "FailedToRunToolToDetermineVersion": "{tool_name} sürümünü belirlemek için \"{path}\" çalıştırılamadı.", "FailedToStoreBackToMirror": "{path} yolu {url} adresine depolanamadı.", "FailedToStoreBinaryCache": "{path} ikili önbelleği depolanamadı", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "{url}'dan ({value}) kayıt defteri bilgileri alınıyor...", "FieldKindDidNotHaveExpectedValue": "\"tip\" beklenen değer değildi: (beklenen değer: {expected}; gerçek değer: {actual})", "FileIsNotExecutable": "görünüşe göre bu dosya yürütülebilir değil", - "FileNotFound": "{path}: Dosya bulunamadı.", + "FileNotFound": "dosya bulunamadı", "FileReadFailed": "{byte_offset} uzaklığında {path} yolundan {count} bayt okunamadı.", "FileSeekFailed": "{path} içinde {byte_offset} konumlandırma aranamadı.", "FilesContainAbsolutePath1": "Yüklü bir pakette aşağıdaki gibi mutlak yol olmamalıdır. Bu iletiyi gizlemek için set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled) ekleyin", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "bilinmeyen dosya durumu: {value}", "GitUnexpectedCommandOutputCmd": "git, {command_line} çalıştırırken beklenmeyen çıktı üretti", "GraphCycleDetected": "{package_name} paketindeki grafik içinde döngü algılandı:", - "HashFileFailureToRead": "karma için \"{path}\" dosyası okunamadı: ", "HashPortManyFiles": "{package_name}, {count} dosya içeriyor. İkili önbelleğe alma için ABI karmasını belirlerken bu içeriklerin karma hale getirilmesi uzun zaman alabilir. Dosya sayısını azaltmayı düşünün. Bunun yaygın nedenleri, yanlışlıkla kaynak veya derleme dosyalarını bir bağlantı noktasının dizinine teslim etmektir.", "HeaderOnlyUsage": "{package_name} yalnızca üst bilgidir ve CMake'ten şu şekilde kullanılabilir:", "HelpAssetCaching": "**Deneysel özellik: bu herhangi bir zamanda değişebilir veya kaldırılabilir**\n\nvcpkg, indirilen varlıkları önbelleğe almak için aynaları kullanabilir ve orijinal kaynak değişse veya kaybolsa bile çalışmaya devam etmesini sağlar.\n\nVarlık önbelleğe alma, X_VCPKG_ASSET_SOURCES ortam değişkenini noktalı virgülle ayrılmış bir kaynak listesine ayarlayarak veya bir dizi --x-asset-sources= komut satırı seçeneği geçirerek yapılandırılabilir. Komut satırı kaynakları, ortam kaynaklarından sonra yorumlanır. Virgüller, noktalı virgüller ve ters tikler, ters tik (`) kullanılarak kaçılabilir.\n\nBelirli dizeler için isteğe bağlı parametresi, bunlara nasıl erişileceğini denetler. \"Read\", \"write\" veya \"readwrite\" olarak belirtilebilir ve varsayılan olarak \"read\" şeklindedir.\n\nGeçerli kaynaklar:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "Önbelleğe alınan ikili dosyalar kullanılamıyorsa işlem başarısız olur", "HelpTxtOptOnlyDownloads": "Kaynakları derlemeden indirmek için en yüksek eforlu denemeyi gerçekleştirir", "HelpTxtOptRecurse": "Yüklemenin parçası olarak paketlerin kaldırılmasına izin verir", - "HelpTxtOptUseAria2": "İndirme görevlerini gerçekleştirmek için aria2 kullanır", "HelpTxtOptUseHeadVersion": "Komut satırındaki kitaplıkları en son yukarı akış kaynaklarını kullanarak yükler (klasik mod)", "HelpTxtOptWritePkgConfig": "Dış ikili önbelleğe alma ile kullanılmak üzere NuGet packages.config ile biçimlendirilmiş bir dosya yazar. Daha fazla bilgi için bkz. `vcpkg help binarycaching`.", "HelpUpdateBaseline": "Kitaplıklarınızı güncel tutmak için en iyi yaklaşım, temel başvuru kaynağınızı güncellemektir. Bu, geçişli olanlar da dahil olmak üzere tüm paketlerin güncellenmesini sağlayacaktır. Ancak bir paketi bağımsız olarak güncellemeniz gerekiyorsa, bir \"version>=\" kısıtlaması kullanabilirsiniz.", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "Visual Studio 2015 için tümleştirme uygulanmadı.", "InternalCICommand": "vcpkg ci, uyumsuz bir şekilde değişebilecek veya herhangi bir zamanda kaldırılabilecek bir iç komuttur.", "InternalErrorMessageContact": "Sorunu yeniden oluşturmak için https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug sayfasındaki ayrıntılı adımları izleyerek bir sorun açın.", - "InvalidArchitecture": "geçersiz mimari: {value}", + "InvalidArchitectureValue": "Geçersiz mimari: {value}. Beklenen: {expected}", "InvalidArgument": "geçersiz değişken", "InvalidArgumentRequiresAbsolutePath": "geçersiz bağımsız değişken: ikili yapılandırma “{binary_source}” ikili yapılandırma dizeleri için yol bağımsız değişkenleri mutlak olmalıdır", "InvalidArgumentRequiresBaseUrl": "geçersiz bağımsız değişken: ikili yapılandırma “{binary_source}”, ilk bağımsız değişken olarak bir {base_url} temel url'sini gerektirir", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "geçersiz mantıksal ifade, 'or' yerine '|' kullanılmalı", "InvalidOptionForRemove": "'remove' kitaplıkları veya '--outdated' seçeneğini kabul ediyor", "InvalidPortVersonName": "Geçersiz bağlantı noktası sürümü dosya adı bulundu: `{path}`.", + "InvalidSha512": "geçersiz SHA-512 karması: {sha}\nSHA-512 karması 128 karakter uzunluğunda olmalı ve yalnızca onaltılık basamaklar içermelidir", "InvalidSharpInVersion": "sürüm metninde geçersiz '#' karakteri", "InvalidSharpInVersionDidYouMean": "sürüm metninde geçersiz '#' karakteri. \"port-version\": {value} mı demek istediniz?", "InvalidString": "Value::string(std::string) öğesine geçersiz utf8 iletildi", + "InvalidToolOSValue": "Geçersiz araç işletim sistemi: {value}. Beklenen: {expected}", + "InvalidToolVersion": "Geçersiz araç sürümü; noktalarla ayrılmış 1 ile 3 arasında sayıda alt dize içeren bir dize bekleniyordu.", "InvalidTriplet": "Geçersiz üçlü: {triplet}", "InvalidUri": "{value} URI’si ayrıştırılamıyor", "InvalidValueHashAdditionalFiles": "Değişken VCPKG_HASH_ADDITIONAL_FILES geçersiz dosya yolu içeriyor: '{path}'. Değer, var olan bir dosyanın mutlak yolu olmalıdır.", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "Seri hale getirilmiş ikili paragraf, özgün ikili paragraftan farklı. Lütfen {url} konumunda, aşağıdaki çıkışla bir sorun açın:", "MismatchedFiles": "depolanacak dosya karma ile eşleşmiyor", "MismatchedManifestAfterReserialize": "Seri hale getirilmiş bildirim, özgün bildirimden farklıydı. Lütfen https://github.com/microsoft/vcpkg adresinde aşağıdaki çıkışla bir sorun açın:", - "MismatchedNames": "adlar eşleşmedi: '{package_name}' != '{actual}'", + "MismatchedNames": "meta veri dosyasında bildirilen bağlantı noktası adı dizinle eşleşmedi. Bağlantı noktasının adlandırılmış olması {package_name}, ancak dosya {actual}.", "MismatchedSpec": "{path} bağlantı noktasında eşleşmeyen belirtim: beklenen {expected}, gerçek {actual}", "MismatchedType": "{json_field}: eşleşmeyen tür: beklenen {json_type} türü", "Missing7zHeader": "7z üstbilgisi bulunamadı.", "MissingAndroidEnv": "ANDROID_NDK_HOME ortam değişkeni eksik", "MissingAndroidHomeDir": "ANDROID_NDK_HOME dizini mevcut değil: {path}", "MissingArgFormatManifest": "format-manifest '--all' olmadan --convert-control’den geçirildi.\nBu işlem hiçbir şey yapmaz: Açıkça geçirilen kontrol dosyaları otomatik olarak dönüştürülür.", - "MissingAssetBlockOrigin": "Eksik {path} ve indirmeler x blok kaynağı tarafından engellendi.", "MissingClosingParen": "kapatma ayracı eksik", "MissingDependency": "Paket {spec} yüklü, ancak bağımlılık {package_name} değil.", "MissingExtension": "'{extension}' uzantısı eksik.", @@ -814,7 +841,6 @@ "NoInstalledPackages": "Yüklü paket yok. \"Ara\" mı demek istiyorsunuz?", "NoOutdatedPackages": "Güncel olmayan paket yok.", "NoRegistryForPort": "{package_name} bağlantı noktası için yapılandırılmış kayıt yok", - "NoUrlsAndHashSpecified": "{sha} SHA bileşenini indirmek için URL belirtilmedi", "NoUrlsAndNoHashSpecified": "URL belirtilmedi ve karma belirtilmedi.", "NonExactlyArgs": "'{command_name}' komutu tam olarak {expected} bağımsız değişken gerektirir ancak {actual} bağımsız değişken sağlandı", "NonOneRemainingArgs": "'{command_name}' komutu, tam olarak bir bağımsız değişken gerektirir", @@ -834,8 +860,8 @@ "Options": "Seçenekler", "OriginalBinParagraphHeader": "\nÖzgün İkili Paragraf", "OtherCommandsHeader": "Diğer", - "OverlayPatchDir": "Katman yolu \"{path}\" mevcut ve bir dizin olmalıdır.", - "OverlayPortsDirectoriesHelp": "Katman bağlantı noktaları dizinleri (ayrıca: {env_var})", + "OverlayPatchDir": "Katman yolu \"{path}\" dizin olmalıdır.", + "OverlayPortsHelp": "Yer paylaşımı bağlantı noktası dizinleri veya yer paylaşımı bağlantı noktası dizinlerini içeren dizinler (ayrıca: {env_var})", "OverlayTripletDirectoriesHelp": "Katman üçlüleri dizinleri (ayrıca: {env_var})", "OverlayTriplets": "\"{path}\" yolundaki Katman Üçlüleri:", "OverwritingFile": "Dosya {path} zaten var ve üzerine yazılacak", @@ -927,6 +953,7 @@ "PortsUpdated": "Aşağıdaki {count} bağlantı noktası güncelleştirildi:", "PrebuiltPackages": "Oluşturulmamış paketler var. Bunları oluşturmak için çalıştırın:", "PreviousIntegrationFileRemains": "Önceki integral alma dosyası kaldırılamadı.", + "ProgramPathReturnedNonzeroExitCode": "{exit_code} çıkış koduyla başarısız oldu", "ProgramReturnedNonzeroExitCode": "{tool_name}, şu çıkış koduyla başarısız oldu: ({exit_code}).", "ProvideExportType": "Aşağıdaki seçeneklerden en az biri gereklidir: --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "\"{path}\" yoluna {vendor} gönderimi yapılamadı. Daha fazla bilgi için --debug kullanın.", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "Hedef üçlüsü. Bkz. 'vcpkg help triplet' (varsayılan: {env_var})", "StartCodeUnitInContinue": "devam konumunda başlangıç kodu birimi bulundu", "StoreOptionMissingSha": "--store seçeneği sha512 olmadan geçersiz", - "StoredBinariesToDestinations": "İkili dosyalar {elapsed} içinde {count} hedefte depolandı.", + "SubmittingBinaryCacheBackground": "Arka planda {spec} {count} önbelleklere dosya gönderimi başlatılıyor", + "SubmittingBinaryCacheComplete": "Dosyanın {spec} ikili {count}/önbelleklere gönderimi {elapsed}", "SuccessfulyExported": "{package_name}, {path} paketine aktarıldı", "SuggestGitPull": "Sonuç eski olabilir. En son sonuçları almak için `git pull` komutunu çalıştırın.", "SuggestStartingBashShell": "Değişikliğin yürürlüğe girmesi için lütfen yeni bir bash kabuğu başlattığınızdan emin olun.", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "{path} öğesine sistem hedefleri dosyası yüklenemedi", "ToRemovePackages": "Yalnızca süresi geçmiş paketleri kaldırmak için\n{command_name} remove --outdated çalıştırın", "ToUpdatePackages": "Bu paketleri ve tüm bağımlılıkları güncelleştirmek için\n{command_name} upgrade' çalıştırın", + "ToolDataFileSchemaVersionNotSupported": "belge şeması {version} bu vcpkg sürümü tarafından desteklenmiyor", "ToolFetchFailed": "{tool_name} getirilemedi.", + "ToolHashMismatch": "{tool_name} zaten indirildi gibi görünüyor, ancak karma yanlış. Beklenen {expected} ancak {actual}", "ToolInWin10": "Bu yardımcı program Windows 10 veya üstü ile birlikte gelir.", "ToolOfVersionXNotFound": "Uygun bir {tool_name} sürümü bulunamadı (gerekli v{version}) ve taşınabilir bir sürüm otomatik olarak indirilemiyor. Lütfen daha yeni bir {tool_name} sürümünü yükleyin", "TotalInstallTime": "Toplam yükleme süresi: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "'{url}' kayıt defteri güncellendi: taban çizgisi '{old_value}' -> '{new_value}'", "UpgradeInManifest": "Yükseltme, klasik mod yüklemesini yükseltir ve bu nedenle bildirim modunu desteklemez. Vcpkg x-update-baseline ile temel değerinizi geçerli bir değere güncelleştirerek ve vcpkg yüklemesini çalıştırarak bağımlılıklarınızı güncelleştirmeyi deneyin.", "UpgradeRunWithNoDryRun": "Yukarıdaki paketleri yeniden derlemek istediğinizden eminseniz bu komutu --no-dry-run seçeneğiyle çalıştırın.", - "UploadingBinariesToVendor": "'{spec}' için ikili dosyalar şuraya yükleniyor: '{vendor}' kaynak \"{path}\".", + "UploadingBinariesToVendor": "{spec} ikili dosyaları {vendor} {path}", "UsageInstallInstructions": "kullanım dosyasını aşağıdaki CMake ile yükleyebilirsiniz", "UsageTextHere": "kullanım dosyası burada", "UseEnvVar": "-- {env_var} ortam değişkenlerini kullanma.", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "{package_name}, {actual} olarak atandı, ancak yerel bağlantı noktası {expected}", "VersionBuiltinPortTreeEntryMissing": "({actual}) kullanıma alınmış bağlantı noktaları ağacı sürümü kullanan {expected} öğesinde {package_name} için sürüm veritabanı girişi yok.", "VersionCommandHeader": "vcpkg paket yönetimi programı sürüm {version}\n\nLisans bilgileri için bkz. LICENSE.txt.", - "VersionConflictXML": "{path} sürümü: [{expected_version}] bekleniyordu, ancak sürüm şuydu: [{actual_version}]. Lütfen bootstrap-vcpkg'yi yeniden çalıştırın.", "VersionConstraintNotInDatabase1": "{package_name}'in geçersiz kılınması, sürüm veritabanında mevcut olmayan {version} sürümünü adlandırır. Tüm sürümlerin vcpkg tarafından yorumlanabilmesi için sürüm veritabanında mevcut olması gerekir.", "VersionConstraintNotInDatabase2": "sürüm kısıtlamasını kaldırmayı veya burada bildirilen bir değeri seçmeyi düşünün", "VersionConstraintOk": "tüm sürüm kısıtlamaları sürüm veritabanıyla tutarlıdır", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "Sürüm metnindeki '#' karakterinden sonra bir bağlantı noktası sürümü (negatif olmayan bir tamsayı) gelmelidir", "VersionSpecMismatch": "Sürümler tutarsız olduğundan bağlantı noktası yüklenemedi. Dosya \"{path}\" {actual_version} sürümünü içeriyor, ancak sürüm veritabanı onun {expected_version} olması gerektiğini belirtiyor.", "VersionVerifiedOK": "{version_spec}, sürüm veritabanında ({git_tree_sha}) doğru", + "WaitUntilPackagesUploaded": "Kalan {count} önbellek gönderimleri bekleniyor...", "WaitingForChildrenToExit": "Alt işlemlerin çıkışı bekleniyor...", "WaitingToTakeFilesystemLock": "{path} yolunda dosya sistemi kilidi almak için bekleniyor...", "WarnOnParseConfig": "{path} yapılandırmasında aşağıdaki uyarılar bulundu:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "{version_spec} yüklenirken", "WhileLookingForSpec": "{spec} aranırken:", "WhileParsingVersionsForPort": "{path} öğesinden {package_name} için sürümler ayrıştırılırken", + "WhileRunningAssetCacheScriptCommandLine": "varlık önbelleği betiği komut satırı çalıştırılırken", "WhileValidatingVersion": "sürüm doğrulanırken: {version}", "WindowsOnlyCommand": "Bu komut yalnızca Windows'u destekler.", "WroteNuGetPkgConfInfo": "NuGet paketi yapılandırma bilgilerini {path} öğesine yazdı", diff --git a/locales/messages.zh-Hans.json b/locales/messages.zh-Hans.json index f056848a14..ec903b96b6 100644 --- a/locales/messages.zh-Hans.json +++ b/locales/messages.zh-Hans.json @@ -4,6 +4,7 @@ "ABoolean": "布尔值", "ABuiltinRegistry": "内置注册表", "AConfigurationObject": "配置对象", + "ACpuArchitecture": "CPU 体系结构", "ADateVersionString": "日期版本字符串", "ADefaultFeature": "默认功能", "ADemandObject": "请求对象", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "宽松的版本字符串", "ASemanticVersionString": "语义版本字符串", "ASetOfFeatures": "一组功能", + "ASha512": "SHA-512 哈希", "AString": "字符串", "AStringOrArrayOfStrings": "字符串或字符串数组", "AStringStringDictionary": "\"string\": \"string\" 字典", + "AToolDataArray": "工具元数据的数组", + "AToolDataFile": "工具数据文件", + "AToolDataOS": "工具数据操作系统", + "AToolDataObject": "工具元数据", + "AToolDataVersion": "工具数据版本", "AUrl": "URL", "AVcpkgRepositoryCommit": "vcpkg 存储库提交", "AVersionConstraint": "版本约束", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "获取项目时强制对 Windows 进行主机检测", "ArtifactsSwitchX64": "获取项目时强制对 x64 进行主机检测", "ArtifactsSwitchX86": "获取项目时强制对 x86 进行主机检测", - "AssetCacheHit": "{path} 的资产缓存命中;已从 {url} 下载", - "AssetCacheMiss": "资产缓存失误;正在从 {url} 下载", - "AssetCacheMissBlockOrigin": "{path} 的资产缓存失误,x-block-origin 阻止下载。", + "AssetCacheConsult": "正在尝试使用资产缓存 {url} 下载 {path}", + "AssetCacheConsultScript": "正在尝试使用资产缓存脚本下载 {path}", + "AssetCacheHit": "下载成功!资产缓存命中。", + "AssetCacheHitUrl": "下载成功!资产缓存命中,未尝试权威源 {url}", + "AssetCacheMiss": "资产缓存未命中;正在尝试权威源 {url}", + "AssetCacheMissBlockOrigin": "没有资产缓存命中,以及尝试权威源 {url} 的 x 块原点块", + "AssetCacheMissNoUrls": "资产缓存缺少查找 {sha},并且没有已知的权威 URL", "AssetCacheProviderAcceptsNoArguments": "意外参数:“{value}”不接受参数", - "AssetCacheSuccesfullyStored": "已成功将 {path} 存储到 {url}。", + "AssetCacheScriptBadVariable": "脚本模板 {value} 包含未知的替换 {list}", + "AssetCacheScriptBadVariableHint": "如果希望在文本命令行上使用此项,请使用 {{list}}}}}", + "AssetCacheScriptCommandLine": "完整脚本命令行是", + "AssetCacheScriptFailed": "资产缓存脚本返回非零退出代码 {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "资产缓存脚本返回成功,但生成的文件具有意外的哈希", + "AssetCacheScriptFailedToWriteFile": "资产缓存脚本返回成功,但未创建预期结果文件", + "AssetCacheScriptNeedsSha": "脚本模板 {value} 需要 SHA,但已知没有 SHA 尝试下载 {url}", + "AssetCacheScriptNeedsUrl": "脚本模板 {value} 需要 URL,但是没有 URL 可用于尝试下载 {sha}", + "AssetCacheSuccesfullyStored": "Microsoft Store 成功", "AssetSourcesArg": "缓存添加源。请参阅“vcpkg 帮助 assetcaching”。", "AttemptingToSetBuiltInBaseline": "尝试在 vcpkg.json 中设置内置基线,同时重写 vcpkg-configuration.json 中的 default-registry。\n系统将使用 vcpkg-configuration.json 中的 default-registry。", "AuthenticationMayRequireManualAction": "一个或多个 {vendor} 凭据提供程序请求手动操作。添加二进制源 “interactive” 以允许交互。", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "要从所有路径中去除的前导目录数", "CommandEnvExample2": "vcpkg env \"ninja -C \" --triplet x64-windows", "CommandFailed": "命令:\n{command_line}\n失败,输出如下:", - "CommandFailedCode": "命令:\n{command_line}\n已失败,退出代码 {exit_code},输出如下:", "CommunityTriplets": "社区三元组:", "CompilerPath": "已找到编译器: {path}", - "CompressFolderFailed": "无法压缩文件夹“{path}”:", "ComputingInstallPlan": "正在计算安装计划...", "ConfigurationErrorRegistriesWithoutBaseline": "{path} 中定义的配置无效。\n\n使用注册表需要为默认注册表设置基线,或者默认注册表为 null。\n\n有关更多详细信息,请参阅 {url}。", "ConfigurationNestedDemands": "[\"{json_field}\"] 包含嵌套的'需求'对象(嵌套的'需求'不起作用)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "无法从文件名推导出 nuget ID 和版本: {path}", "CouldNotFindBaselineInCommit": "在 {url} 的 {commit_sha} 中找不到 {package_name} 的基线。", "CouldNotFindGitTreeAtCommit": "在提交 {commit_sha} 的存储库 {package_name} 中找不到 `versions` 的 git 树", - "CouldNotFindToolVersion": "在 {path} 中找不到 版", "CouldNotFindVersionDatabaseFile": "找不到版本数据库文件: {path}", "CreateFailureLogsDir": "正在创建失败日志输出目录 {path}。", "CreatedNuGetPackage": "已创建 nupkg: {path}", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "正在创建 NuGet 包...", "CreatingZipArchive": "正在创建 zip 存档...", "CreationFailed": "创建 {path} 失败。", + "CurlFailedGeneric": "curl 操作失败,错误代码 {exit_code}。", "CurlFailedToPut": "curl 无法将文件放入 {url},退出代码为 {exit_code}。", "CurlFailedToPutHttp": "curl 无法将文件放入 {url},退出代码为 {exit_code},http 代码为 {value}。", - "CurlResponseTruncatedRetrying": "curl 返回了部分响应;正在等待 {value} 毫秒,然后重试", - "CurlTimeout": "curl 无法执行所有请求的 HTTP 操作,即使在超时和重试之后也是如此。最后一个命令行是: {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "curl 未能返回预期数量的退出代码;如果某些内容在卷曲完成之前终止,则可能会发生这种情况。curl 已退出,{exit_code} 这通常是上一个操作的结果代码,但可能是故障的结果。命令行已 {command_line},并且所有输出如下:", "CurrentCommitBaseline": "可以将当前提交用作基线,即:\n\t\"builtin-baseline\": \"{commit_sha}\"", "CycleDetectedDuring": "在 {spec} 期间检测到循环:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "环境变量 VCPKG_DEFAULT_BINARY_CACHE 必须是目录(曾为: {path})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "DLL 相对于此处的 ${{CURRENT_PACKAGES_DIR}}", "DocumentedFieldsSuggestUpdate": "如果这些是应识别的文档字段,请尝试更新 vcpkg 工具。", "DownloadAvailable": "此工具的可下载副本可用,可通过取消设置 {env_var} 使用它。", - "DownloadFailedCurl": "{url}: curl 下载失败,退出代码为 {exit_code}", - "DownloadFailedHashMismatch": "文件没有预期的哈希: \nurl: {url}\n文件: {path}\n预期哈希: {expected}\n实际哈希: {actual}", - "DownloadFailedProxySettings": "未能下载 {path}。\n如果使用的是代理,请确保代理设置正确无误。\n可能的原因如下:\n1. 实际上使用的是 HTTP 代理,但 HTTPS_PROXY 变量设置为“https//address:port”。\n这是不正确的,因为“https://”前缀声明代理是 HTTPS 代理,而你的代理 (v2ray、shadowsocksr 等)是 HTTP 代理。\n请尝试将“http://address:port”设置为 HTTP_PROXY 和 HTTPS_PROXY。\n2. 如果使用的是 Windows,vcpkg 将自动使用代理软件设置的 Windows IE 代理设置。请参阅 {url}\n代理设置的值可能错误,或者出现相同的“https://”前缀问题。\n3. 代理的远程服务器是我们的服务。\n如果已尝试直接下载链接,并且认为这不是下载服务器的临时故障,请在 https://github.com/Microsoft/vcpkg/issues 提交问题,\n以报告此上游下载服务器故障。", - "DownloadFailedRetrying": "下载失败 -- 将在 {value}ms 后重试", + "DownloadFailedHashMismatch": "下载自 {url} 具有意外的哈希", + "DownloadFailedHashMismatchActualHash": "实际: {sha}", + "DownloadFailedHashMismatchExpectedHash": "应为: {sha}", + "DownloadFailedHashMismatchZero": "下载失败,因为预期的 SHA512 全部为零,请将预期 SHA512 更改为: {sha}", + "DownloadFailedProxySettings": "如果使用的是代理,请确保代理设置正确无误。\n可能的原因为:\n1. 实际上使用的是 HTTP 代理,但 HTTPS_PROXY 变量设置为 `https//address:port`。\n这是不正确的,因为 `https://` 前缀声明了代理是 HTTPS 代理,而你的代理(v2ray、shadowsocksr 等)是 HTTP 代理。\n请尝试改为将 `http://address:port` 设置为 HTTP_PROXY 和 HTTPS_PROXY。\n2. 如果使用的是 Windows,则 vcpkg 将自动使用代理软件设置的 Windows IE 代理设置。请参阅: https://github.com/microsoft/vcpkg-tool/pull/77\n代理设置的值可能错误,或者出现相同的 `https://` 前缀问题。\n3. 代理的远程服务器已停止服务。\n如果认为这不是临时下载服务器故障,并且需要更改 vcpkg 才能从其他位置下载此文件,请向 https://github.com/Microsoft/vcpkg/issues 提交问题", + "DownloadFailedRetrying": "下载 {url} 失败 - 将在 {value} 毫秒后重试", "DownloadFailedStatusCode": "{url}: 失败: 状态代码为 {value}", + "DownloadOrUrl": "或 {url}", "DownloadRootsDir": "下载目录(默认值: {env_var})", - "DownloadSuccesful": "已成功下载 {path}。", - "DownloadWinHttpError": "{url}: {system_api} 失败,退出代码为 {exit_code}", + "DownloadSuccesful": "已成功下载 {path}", + "DownloadSuccesfulUploading": "已成功下载 {path},存储到 {url}", + "DownloadTryingAuthoritativeSource": "正在尝试 {url}", + "DownloadWinHttpError": "{url}: {system_api} 失败,退出代码为 {exit_code}。", "DownloadedSources": "已下载的 {spec} 源", + "DownloadingAssetShaToFile": "正在下载资产缓存项 {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "已请求下载资产缓存条目 {sha} -> {path},但未配置任何资产缓存", + "DownloadingFile": "正在下载 {path}", + "DownloadingFileFirstAuthoritativeSource": "正在下载 {path},正在尝试 {url}", "DownloadingPortableToolVersionX": "找不到合适的 {tool_name} 版本(所需的 v{version})。", - "DownloadingUrl": "正在下载 {url}", + "DownloadingUrlToFile": "正在下载 {url} -> {path}", "DownloadingVcpkgStandaloneBundle": "正在下载独立捆绑包 {version}。", "DownloadingVcpkgStandaloneBundleLatest": "正在下载最新的独立捆绑包。", + "DuplicateDependencyOverride": "{package_name} 已有替代", "DuplicatePackagePattern": "包“{package_name}”重复。", "DuplicatePackagePatternFirstOcurrence": "首次声明位置:", "DuplicatePackagePatternIgnoredLocations": "系统将忽略以下重新声明:", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "在经典模式下不支持选项 --{option},并且未找到任何清单。", "ErrorInvalidExtractOption": "--{option} 必须设置为非负整数或 \"AUTO\"。", "ErrorInvalidManifestModeOption": "清单模式下不支持选项 --{option}。", + "ErrorManifestMustDifferFromOverlay": "清单目录 ({path}) 不能与覆盖端口中配置的目录相同。", + "ErrorManifestMustDifferFromOverlayDot": "清单目录不能与在覆盖端口中配置的目录相同,因此“覆盖端口”值不能为“.”。", "ErrorMissingVcpkgRoot": "无法检测 vcpkg-root。如果尝试使用已生成的 vcpkg 的副本,则必须定义 VCPKG_ROOT 环境变量,以指向 https://github.com/Microsoft/vcpkg 的克隆副本。", "ErrorNoVSInstance": "在三元组 {triplet} 中: 无法找到有效的 Visual Studio 实例", "ErrorNoVSInstanceAt": "位于“{path}”", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "无法分析 {path},应为 \"versions\" 数组。", "FailedToParseSerializedBinParagraph": "[健全性检查]无法分析序列化二进制段落。\n请在 https://github.com/microsoft/vcpkg 提出问题,附加以下输出: \n{error_msg}\n序列化二进制段落:", "FailedToParseVersionFile": "未能分析版本文件: {path}", - "FailedToParseVersionXML": "无法分析工具{tool_name}的版本。版本字符串为: {version}", "FailedToRunToolToDetermineVersion": "无法运行“{path}”以确定 {tool_name} 版本。", "FailedToStoreBackToMirror": "未能将 {path} 存储到 {url}。", "FailedToStoreBinaryCache": "无法存储二进制缓存 {path}", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "正在从 {url} ({value}) 提取注册表信息...", "FieldKindDidNotHaveExpectedValue": "\"kind\" 没有预期值: (应为以下值之一: {expected}; 找到的是 {actual})", "FileIsNotExecutable": "此文件似乎不是可执行文件", - "FileNotFound": "{path}: 未找到文件", + "FileNotFound": "未找到文件", "FileReadFailed": "未能从 {path} 的 {byte_offset} 偏移处读取 {count} 个字节。", "FileSeekFailed": "未能在 {path} 中找到位置 {byte_offset}。", "FilesContainAbsolutePath1": "安装的包中不得有绝对路径,如下所示。若要抑制此消息,请添加 set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "未知文件状态: {value}", "GitUnexpectedCommandOutputCmd": "git 在运行 {command_line} 时生成了意外输出", "GraphCycleDetected": "在 {package_name} 的图形中检测到循环:", - "HashFileFailureToRead": "无法读取用于哈希的文件“{path}”: ", "HashPortManyFiles": "{package_name} 包含 {count} 个文件。确定二进制缓存的 ABI 哈希时,对这些内容进行哈希处理可能需要较长时间。请考虑减少文件数。出现此问题的常见原因是,将源或生成文件意外签出到端口的目录。", "HeaderOnlyUsage": "{package_name} 是仅限标头的,可通过以下方式从 CMake 使用:", "HelpAssetCaching": "**试验性功能: 此功能可能会随时更改或删除**\n\nvcpkg 可以使用镜像来缓存下载的资产,确保即使原始源更改或消失,也能继续操作。\n\n可以通过将环境变量 X_VCPKG_ASSET_SOURCES 设置为以分号分隔的源列表或传递 --x-asset-sources= 命令行选项序列来配置资产缓存。命令行源在环境源之后进行解释。可以使用反引号(`)转义逗号、分号和反引号。\n\n某些字符串的 可选参数控制如何访问它们。可将其指定为 \"read、\"write\" 或 \"readwrite\",默认为 \"read\"。\n\n有效源:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "如果缓存的二进制文件不可用,则失败", "HelpTxtOptOnlyDownloads": "尽量尝试在不生成的情况下下载源", "HelpTxtOptRecurse": "允许在安装过程中移除包", - "HelpTxtOptUseAria2": "使用 aria2 执行下载任务", "HelpTxtOptUseHeadVersion": "使用最新的上游源在命令行上安装库(经典模式)", "HelpTxtOptWritePkgConfig": "写入 NuGet packages.config 格式的文件以用于外部二进制缓存。有关详细信息,请参阅 `vcpkg help binarycaching`。", "HelpUpdateBaseline": "使库保持最新的最佳方法是更新基线引用。这将确保更新所有包 (包括可传递包)。但是,如果需要单独更新包,则可以使用“version>=”约束。", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "集成未应用于 Visual Studio 2015。", "InternalCICommand": "vcpkg ci 是一个内部命令,它将发生不兼容更改或随时被删除。", "InternalErrorMessageContact": "请在 https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug 打开一个包含重现问题的详细步骤的问题。", - "InvalidArchitecture": "体系结构无效: {value}", + "InvalidArchitectureValue": "体系结构无效: {value}。应为其中之一: {expected}", "InvalidArgument": "参数无效", "InvalidArgumentRequiresAbsolutePath": "参数无效: 二进制配置字符串的二进制配置“{binary_source}”路径参数必须是绝对参数", "InvalidArgumentRequiresBaseUrl": "参数无效: 二进制配置“{binary_source}”要求将 {base_url} 基 URL 作为第一个参数", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "逻辑表达式无效,请使用 \"|\" 而不是 \"or\"", "InvalidOptionForRemove": "“remove” 接受库或 “--outdated”", "InvalidPortVersonName": "找到无效的端口版本文件名: `{path}`。", + "InvalidSha512": "SHA-512 哈希无效: {sha}\nSHA-512 哈希的长度必须为 128 个字符,并且只能包含十六进制数字", "InvalidSharpInVersion": "版本文本中的字符 \"#\" 无效", "InvalidSharpInVersionDidYouMean": "版本文本中的字符 \"#\" 无效。你的意思是 \"port-version\": {value} 吗?", "InvalidString": "传递给 Value::string(std::string) 的 utf8 无效", + "InvalidToolOSValue": "工具操作系统无效: {value}。应为其中之一: {expected}", + "InvalidToolVersion": "工具版本无效;应为包含由点分隔的介于 1 到 3 个数字之间的子字符串的字符串。", "InvalidTriplet": "三元组 {triplet} 无效", "InvalidUri": "无法分析 URI: {value}", "InvalidValueHashAdditionalFiles": "变量 VCPKG_HASH_ADDITIONAL_FILES 包含无效的文件路径:“{path}”。该值必须是已存在文件的绝对路径。", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "序列化二进制段落不同于原始二进制段落。请在 https://github.com/microsoft/vcpkg 提出问题,附加以下输出:", "MismatchedFiles": "要存储的文件与哈希不匹配", "MismatchedManifestAfterReserialize": "序列化清单不同于原始清单。请在 https://github.com/microsoft/vcpkg 打开一个问题,输出如下:", - "MismatchedNames": "名称不匹配:“{package_name}”!=“{actual}”", + "MismatchedNames": "元数据文件中声明的端口名称与目录不匹配。端口应命名 {package_name},但文件声明 {actual}。", "MismatchedSpec": "端口 {path} 中的规范不匹配: 应为 {expected},实际为 {actual}", "MismatchedType": "{json_field}: 类型不匹配: 应为 {json_type}", "Missing7zHeader": "找不到 7z 标头。", "MissingAndroidEnv": "缺少 ANDROID_NDK_HOME 环境变量", "MissingAndroidHomeDir": "ANDROID_NDK_HOME 目录不存在: {path}", "MissingArgFormatManifest": "已传递 format-manifest --convert-control 而不使用 “--all”。\n这不执行任何操作: 显式传递的控件文件将自动转换。", - "MissingAssetBlockOrigin": "{path} 缺失,x-block-origin 阻止下载。", "MissingClosingParen": "缺少右括号 )", "MissingDependency": "已安装包 {spec},但未安装依赖项 {package_name}。", "MissingExtension": "缺少“{extension}”扩展名。", @@ -814,7 +841,6 @@ "NoInstalledPackages": "未安装任何包。你指的是“search”吗?", "NoOutdatedPackages": "没有过时的包。", "NoRegistryForPort": "没有为端口 {package_name} 配置注册表", - "NoUrlsAndHashSpecified": "未指定用于下载 SHA 的 URL: {sha}", "NoUrlsAndNoHashSpecified": "未指定 URL 且未指定哈希。", "NonExactlyArgs": "命令“{command_name}”只需要 {expected} 个参数,但提供了 {actual} 个", "NonOneRemainingArgs": "命令“{command_name}”只需要一个参数", @@ -834,8 +860,8 @@ "Options": "选项", "OriginalBinParagraphHeader": "\n原始二进制段落", "OtherCommandsHeader": "其他", - "OverlayPatchDir": "覆盖路径“{path}”必须存在并且必须为目录。", - "OverlayPortsDirectoriesHelp": "覆盖端口的目录(也是: {env_var})", + "OverlayPatchDir": "覆盖路径 \"{path}\" 必须是现有目录。", + "OverlayPortsHelp": "覆盖端口目录或包含覆盖端口目录的目录也 (: {env_var})", "OverlayTripletDirectoriesHelp": "覆盖三元组的目录(也是: {env_var})", "OverlayTriplets": "覆盖“{path}”中的三元组:", "OverwritingFile": "文件 {path} 已存在,并将被覆盖", @@ -927,6 +953,7 @@ "PortsUpdated": "以下 {count} 个端口已更新:", "PrebuiltPackages": "存在尚未生成的包。如果要生成它们,请运行:", "PreviousIntegrationFileRemains": "未删除以前的集成文件。", + "ProgramPathReturnedNonzeroExitCode": "失败,退出代码为 {exit_code}", "ProgramReturnedNonzeroExitCode": "{tool_name} 失败,退出代码: {exit_code}。", "ProvideExportType": "至少需要以下选项之一: --raw --nuget --ifw --zip --7zip --chocolatey --prefab。", "PushingVendorFailed": "将 {vendor} 推送到“{path}”失败。请使用 --debug 获取详细信息。", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "目标三元组。请参阅“vcpkg 帮助三元组”(默认值:“{env_var}”)", "StartCodeUnitInContinue": "在“继续”位置找到了起始代码单元", "StoreOptionMissingSha": "--store 选项无效,没有 sha512", - "StoredBinariesToDestinations": "{elapsed} 后在 {count} 个目标中存储了二进制文件。", + "SubmittingBinaryCacheBackground": "正在开始将 {spec} 提交到后台 {count} 二进制缓存()", + "SubmittingBinaryCacheComplete": "已完成向 {elapsed} 中的 {count} 二进制缓存() 提交 {spec}", "SuccessfulyExported": "已将 {package_name} 导出到 {path}", "SuggestGitPull": "结果可能已过时。运行 `git pull` 以获取最新结果。", "SuggestStartingBashShell": "请确保已启动新的 bash shell 以使更改生效。", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "无法将系统目标文件安装到 {path}", "ToRemovePackages": "若要仅删除过时的包,请运行\n{command_name} remove --outdated", "ToUpdatePackages": "若要更新这些包和所有依赖项,请运行\n{command_name} upgrade'", + "ToolDataFileSchemaVersionNotSupported": "此版本的 vcpkg 不支持文档架构版本 {version}", "ToolFetchFailed": "无法提取 {tool_name}。", + "ToolHashMismatch": "{tool_name} 似乎已下载,但哈希不正确。应为 {expected},但已 {actual}", "ToolInWin10": "此实用工具与 Windows 10 或更高版本捆绑。", "ToolOfVersionXNotFound": "找不到合适的{tool_name}版本(所需版本为 {version}),而且无法自动下载可移植版本。请安装较新版本的{tool_name}", "TotalInstallTime": "总安装时间: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "已更新注册表“{url}”: 基线“{old_value}”->“{new_value}”", "UpgradeInManifest": "升级 升级经典模式安装,因此不支持清单模式。请考虑通过使用 vcpkg x-update-baseline 将基线更新为当前值,并运行 vcpkg 安装来更新依赖项。", "UpgradeRunWithNoDryRun": "如果确实要重新生成上述包,请使用 --no-dry-run 选项运行此命令。", - "UploadingBinariesToVendor": "正在将“{spec}”的二进制文件上传到“{vendor}”源“{path}”。", + "UploadingBinariesToVendor": "正在将 {spec} 的二进制文件上传到 {path} {vendor}", "UsageInstallInstructions": "可使用以下 CMake 安装 usage 文件", "UsageTextHere": "usage 文件位于此处", "UseEnvVar": "-- 正在使用环境变量中的 {env_var}。", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "{package_name} 已分配 {actual},但本地端口为 {expected}", "VersionBuiltinPortTreeEntryMissing": "{expected} 处没有 {package_name} 的版本数据库条目;使用签出的端口树版本 ({actual})。", "VersionCommandHeader": "vcpkg 包管理程序版本 {version}\n\n查看 LICENSE.txt 获取许可证信息。", - "VersionConflictXML": "{path} 版本应为 [{expected_version}],但实际为 [{actual_version}]。请重新运行 bootstrap-vcpkg。", "VersionConstraintNotInDatabase1": "版本数据库中不存在的 {package_name} 名称版本 {version} 的 \"version>=\" 约束。所有版本都必须存在于版本数据库中才能由 vcpkg 进行解释。", "VersionConstraintNotInDatabase2": "考虑移除版本约束或选择此处声明的值", "VersionConstraintOk": "所有版本约束都与版本数据库一致", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "版本文本中的 \"#\" 后面必须跟端口版本(非负整数)", "VersionSpecMismatch": "无法加载端口,因为版本不一致。文件“{path}”包含版本 {actual_version},但版本数据库指示它应为 {expected_version}。", "VersionVerifiedOK": "{version_spec} 正确位于版本数据库({git_tree_sha})中", + "WaitUntilPackagesUploaded": "正在等待剩余 {count} 二进制缓存提交...", "WaitingForChildrenToExit": "正在等待子进程退出...", "WaitingToTakeFilesystemLock": "正在等待锁定 {path} 上的文件系统...", "WarnOnParseConfig": "在配置 {path} 中发现以下警告:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "加载 {version_spec} 时", "WhileLookingForSpec": "查找 {spec} 时:", "WhileParsingVersionsForPort": "分析来自 {path} 的 {package_name} 版本时", + "WhileRunningAssetCacheScriptCommandLine": "运行资产缓存脚本命令行时", "WhileValidatingVersion": "验证版本: {version} 时", "WindowsOnlyCommand": "此命令仅支持 Windows。", "WroteNuGetPkgConfInfo": "已将 NuGet 包配置信息写入 {path}", diff --git a/locales/messages.zh-Hant.json b/locales/messages.zh-Hant.json index e34b0006f4..614f9f53c7 100644 --- a/locales/messages.zh-Hant.json +++ b/locales/messages.zh-Hant.json @@ -4,6 +4,7 @@ "ABoolean": "布林值", "ABuiltinRegistry": "內建登錄", "AConfigurationObject": "設定物件", + "ACpuArchitecture": "CPU 架構", "ADateVersionString": "日期版本字串", "ADefaultFeature": "預設功能", "ADemandObject": "需求物件", @@ -35,9 +36,15 @@ "ARelaxedVersionString": "寬鬆的版本字串", "ASemanticVersionString": "語意版本字串", "ASetOfFeatures": "一組功能", + "ASha512": "SHA-512 哈希", "AString": "字串", "AStringOrArrayOfStrings": "字串或字串陣列", "AStringStringDictionary": "\"string\": \"string\" 字典", + "AToolDataArray": "工具元數據的陣列", + "AToolDataFile": "工具數據檔", + "AToolDataOS": "工具數據作業系統", + "AToolDataObject": "工具元數據", + "AToolDataVersion": "工具數據版本", "AUrl": "URL", "AVcpkgRepositoryCommit": "vcpkg 存放庫認可", "AVersionConstraint": "版本條件約束", @@ -132,11 +139,23 @@ "ArtifactsSwitchWindows": "取得成品時強制主機偵測為 Windows", "ArtifactsSwitchX64": "取得成品時強制主機偵測為 x64", "ArtifactsSwitchX86": "取得成品時強制主機偵測為 x86", - "AssetCacheHit": "{path} 的資產快取命中; 已從 {url} 下載", - "AssetCacheMiss": "資產快取遺漏; 正在從 {url} 下載", - "AssetCacheMissBlockOrigin": "{path} 資產快取遺漏且 x-block-origin 封鎖了下載。", + "AssetCacheConsult": "嘗試使用資產快取 {url} 下載 {path}", + "AssetCacheConsultScript": "正在嘗試使用資產快取腳本下載 {path}", + "AssetCacheHit": "下載成功!資產快取點擊。", + "AssetCacheHitUrl": "下載成功!資產快取點擊,未嘗試授權來源 {url}", + "AssetCacheMiss": "資產快取遺漏;正在嘗試授權來源 {url}", + "AssetCacheMissBlockOrigin": "沒有資產快取命中,以及嘗試授權來源的 x 區塊原始區塊 {url}", + "AssetCacheMissNoUrls": "尋找 {sha} 時遺漏資產快取,且沒有已知的授權 URL", "AssetCacheProviderAcceptsNoArguments": "非預期的引數: '{value}' 不接受引數", - "AssetCacheSuccesfullyStored": "已成功將 {path} 儲存到 {url}。", + "AssetCacheScriptBadVariable": "腳本範本 {value} 包含未知的取代 {list}", + "AssetCacheScriptBadVariableHint": "如果您想要在常值命令行執行此動作,請使用 {{{{list}}}}}", + "AssetCacheScriptCommandLine": "完整腳本命令行是", + "AssetCacheScriptFailed": "資產快取腳本傳回非零的結束代碼 {exit_code}", + "AssetCacheScriptFailedToWriteCorrectHash": "資產快取腳本傳回成功,但產生的檔案有未預期的哈希", + "AssetCacheScriptFailedToWriteFile": "資產快取腳本傳回成功,但未建立預期的結果檔案", + "AssetCacheScriptNeedsSha": "腳本範本 {value} 需要 SHA,但是沒有已知的 SHA 可嘗試下載 {url}", + "AssetCacheScriptNeedsUrl": "腳本範本 {value} 需要 URL,但是沒有已知的 URL 會嘗試下載 {sha}", + "AssetCacheSuccesfullyStored": "Microsoft Store 成功", "AssetSourcesArg": "資產快取來源。請參閱 'vcpkg help assetcaching'", "AttemptingToSetBuiltInBaseline": "嘗試在 vcpkg.json 中設定 builtin-baseline,同時會使用 vcpkg-configuration.json.\n使用 vcpkg-configuration.json 中的 default-registry。", "AuthenticationMayRequireManualAction": "一或多個 {vendor} 認證提供者要求手動動作。新增二進位來源 'interactive' 以允許互動。", @@ -368,10 +387,8 @@ "CmdZExtractOptStrip": "從所有路徑中移除前置目錄的數目。", "CommandEnvExample2": "vcpkg env \"ninja -C <路徑>\" --triplet x64-windows", "CommandFailed": "命令:\n{command_line}\n失敗,輸出如下:", - "CommandFailedCode": "命令:\n{command_line}\n失敗,結束代碼為 {exit_code},輸出如下:", "CommunityTriplets": "社群三元組:", "CompilerPath": "已找到編譯器: {path}", - "CompressFolderFailed": "無法壓縮資料夾 \"{path}\":", "ComputingInstallPlan": "正在計算安裝計畫...", "ConfigurationErrorRegistriesWithoutBaseline": "{path} 中定義的設定無效。\n\n使用登錄需要為預設登錄設定基準,或預設登錄為 Null。\n\n如需詳細資料,請參閱 {url}。", "ConfigurationNestedDemands": "[\"{json_field}\"] 包含巢狀 `demands` 物件 (巢狀 `demands` 沒有作用)", @@ -387,7 +404,6 @@ "CouldNotDeduceNugetIdAndVersion": "無法從檔案名推斷 nuget 識別碼和版本: {path}", "CouldNotFindBaselineInCommit": "無法為 {package_name} 在 {commit_sha} 的 {url} 中找到基準。", "CouldNotFindGitTreeAtCommit": "在位於認可 {commit_sha} 的存放庫 {package_name} 中找不到 `versions` 的 git 樹狀結構", - "CouldNotFindToolVersion": "在 {path} 中找不到 ", "CouldNotFindVersionDatabaseFile": "找不到版本資料庫檔案: {path}", "CreateFailureLogsDir": "正在建立失敗記錄輸出目錄 {path}。", "CreatedNuGetPackage": "已建立 nupkg: {path}", @@ -395,10 +411,10 @@ "CreatingNugetPackage": "正在建立 NuGet 套件...", "CreatingZipArchive": "正在建立 zip 保存...", "CreationFailed": "建立 {path} 失敗。", + "CurlFailedGeneric": "捲曲操作失敗,錯誤碼為 {exit_code}。", "CurlFailedToPut": "Curl 無法將檔案置於 {url},結束代碼為 {exit_code}。", "CurlFailedToPutHttp": "Curl 無法將檔案置於 {url},結束代碼為 {exit_code},HTTP 代碼為{value}。", - "CurlResponseTruncatedRetrying": "curl 傳回部分回應; 等待 {value} 毫秒後再試一次", - "CurlTimeout": "curl 無法執行所有要求的 HTTP 作業,即使在逾時後重試也一樣。最後一個命令列為: {command_line}", + "CurlFailedToReturnExpectedNumberOfExitCodes": "捲曲無法傳回預期的結束代碼數目;如果某些專案在完成前終止捲曲,就可能發生這種情況。捲曲已結束,{exit_code} 這通常是上一個操作的結果碼,但可能是當機的結果。命令行已 {command_line},且所有輸出都如下:", "CurrentCommitBaseline": "您可以使用目前的提交做為基準,即:\n\t\"builtin-baseline\": \"{commit_sha}\"", "CycleDetectedDuring": "在 {spec} 期間偵測到循環:", "DefaultBinaryCachePlatformCacheRequiresAbsolutePath": "環境變數 VCPKG_DEFAULT_BINARY_CACHE 必須是目錄 (是: {path})", @@ -423,19 +439,29 @@ "DllsRelativeToThePackageDirectoryHere": "DLL 是相對於這裡的 ${{CURRENT_PACKAGES_DIR}}", "DocumentedFieldsSuggestUpdate": "如果這些是應被辨識的已記錄欄位,請嘗試更新 vcpkg 工具。", "DownloadAvailable": "此工具的可下載複本可用,而且可以透過取消設定 {env_var} 使用。", - "DownloadFailedCurl": "{url}: Curl 無法下載,結束代碼為 {exit_code}", - "DownloadFailedHashMismatch": "檔案沒有預期的雜湊:\nURL: {url}\n檔案: {path}\n預期的雜湊: {expected}\n實際雜湊: {actual}", - "DownloadFailedProxySettings": "無法下載 {path}。\n如果您使用 Proxy,請確定您的 Proxy 設定正確。\n可能的原因為:\n1. 您實際上使用的是 HTTP Proxy,但卻將 HTTPS_PROXY 變數設定為 `https//address:port`。\n這不正確,因為 `https://` 前置詞會宣告 Proxy 是 HTTPS Proxy,但您的 Proxy (v2ray、shadowsocksr 等...) 是 HTTP Proxy。\n請嘗試改將 `http://address:port` 設定為 HTTP_PROXY 和 HTTPS_PROXY。\n2. 如果您使用 Windows,vcpkg 會自動使用您的 Proxy 軟體所設定的 Windows IE Proxy 設定。請參閱 {url}\n您的 Proxy 所設定的值可能錯誤,或具有相同的 `https://` 前置詞問題。\n3. 您的 Proxy 的遠端伺服器是我們的服務。\n如果您已經嘗試直接下載連結,而且認為這不是暫時性的下載伺服器失敗,請於 https://github.com/Microsoft/vcpkg/issues 提交問題,\n以回報此上游下載伺服器失敗。", - "DownloadFailedRetrying": "下載失敗 -- {value} 毫秒後重試", + "DownloadFailedHashMismatch": "從 {url} 下載有未預期的哈希", + "DownloadFailedHashMismatchActualHash": "實際: {sha}", + "DownloadFailedHashMismatchExpectedHash": "預期: {sha}", + "DownloadFailedHashMismatchZero": "下載失敗,因為預期的SHA512全部為零,請將預期的SHA512變更為: {sha}", + "DownloadFailedProxySettings": "如果您使用 Proxy,請確定您的 Proxy 設定正確。\n可能的原因為:\n1. 您實際上使用的是 HTTP Proxy,但卻將 HTTPS_PROXY 變數設定為 `https//address:port`。\n這不正確,因為 `https://` 前置詞會宣告 Proxy 是 HTTPS Proxy,但您的 Proxy (v2ray、shadowsocksr 等...) 是 HTTP Proxy。\n請嘗試改將 `http://address:port` 設定為 HTTP_PROXY 和 HTTPS_PROXY。\n2. 如果您使用 Windows,vcpkg 會自動使用您的 Proxy 軟體所設定的 Windows IE Proxy 設定。請參閱: https://github.com/microsoft/vcpkg-tool/pull/77\n您的 Proxy 所設定的值可能錯誤,或具有相同的 `https://` 前置詞問題。\n3. 您的 Proxy 的遠端伺服器是我們的服務。\n如果您認為這不是暫時性的下載伺服器失敗,且 vcpkg 需要變更,以從不同位置下載此檔案,請提交問題至 https://github.com/Microsoft/vcpkg/issues", + "DownloadFailedRetrying": "下載 {url} 失敗 -- {value} 毫秒後重試", "DownloadFailedStatusCode": "{url}: 失敗: 狀態代碼 {value}", + "DownloadOrUrl": "或 {url}", "DownloadRootsDir": "下載目錄 (預設值: {env_var})", - "DownloadSuccesful": "已成功下載 {path}。", - "DownloadWinHttpError": "{url}: {system_api} 失敗,結束代碼為 {exit_code}", + "DownloadSuccesful": "已成功下載 {path}", + "DownloadSuccesfulUploading": "已成功下載 {path},正在儲存至 {url}", + "DownloadTryingAuthoritativeSource": "正在嘗試 {url}", + "DownloadWinHttpError": "{url}: {system_api} 失敗,結束代碼為 {exit_code}。", "DownloadedSources": "已下載 {spec} 的來源", + "DownloadingAssetShaToFile": "正在下載資產快取專案 {sha} -> {path}", + "DownloadingAssetShaWithoutAssetCache": "已要求下載資產快取專案 {sha} -> {path},但未設定任何資產快取", + "DownloadingFile": "正在下載 {path}", + "DownloadingFileFirstAuthoritativeSource": "正在下載 {path},正在嘗試 {url}", "DownloadingPortableToolVersionX": "找不到合適版本的 {tool_name},需要第 {version} 版。", - "DownloadingUrl": "正在下載 {url}", + "DownloadingUrlToFile": "正在下載 {url} -> {path}", "DownloadingVcpkgStandaloneBundle": "正在下載獨立搭售方案 {version}。", "DownloadingVcpkgStandaloneBundleLatest": "正在下載最新的獨立搭售方案。", + "DuplicateDependencyOverride": "{package_name} 已經有覆寫", "DuplicatePackagePattern": "套件 \"{package_name}\" 已複製。", "DuplicatePackagePatternFirstOcurrence": "第一次宣告於:", "DuplicatePackagePatternIgnoredLocations": "會略過下列重新宣告:", @@ -457,6 +483,8 @@ "ErrorInvalidClassicModeOption": "傳統模式不支援選項 --{option},且找不到任何資訊清單。", "ErrorInvalidExtractOption": "--{option} 必須設定為非負整數或 'AUTO'。", "ErrorInvalidManifestModeOption": "資訊清單模式不支援選項 --{option}。", + "ErrorManifestMustDifferFromOverlay": "指令清單目錄 ({path}) 不能與重疊埠中設定的目錄相同。", + "ErrorManifestMustDifferFromOverlayDot": "指令清單目錄不能與重迭埠中設定的目錄相同,所以 「overlay-ports」 值不能是 “.”。", "ErrorMissingVcpkgRoot": "無法偵測 vcpkg-root。如果您嘗試使用所建的 vcpkg 複本,您必須定義 VCPKG_ROOT 環境變數,以指向 https://github.com/Microsoft/vcpkg 的複製複本。", "ErrorNoVSInstance": "在三個二進制元素位元組 {triplet} 中: 找不到有效的 Visual Studio 執行個體", "ErrorNoVSInstanceAt": "於 \"{path}\"", @@ -530,7 +558,6 @@ "FailedToParseNoVersionsArray": "無法剖析 {path},必須要有 'versions' 陣列。", "FailedToParseSerializedBinParagraph": "[例行性檢查] 無法剖析序列化二進位段落。\n請於 https://github.com/microsoft/vcpkg 開啟具有下列輸出的問題:\n{error_msg}\n序列化二進位段落:", "FailedToParseVersionFile": "無法剖析版本檔案:{path}", - "FailedToParseVersionXML": "無法剖析工具 {tool_name} 的版本。版本字串為: {version}", "FailedToRunToolToDetermineVersion": "無法執行 \"{path}\" 以判斷 {tool_name} 版本。", "FailedToStoreBackToMirror": "無法將 {path} 儲存到 {url}。", "FailedToStoreBinaryCache": "無法儲存二進位快取 {path}", @@ -540,7 +567,7 @@ "FetchingRegistryInfo": "正在從 {url} ({value}) 擷取註冊資訊...", "FieldKindDidNotHaveExpectedValue": "\"kind\" 沒有預期的值: (預期為下列其中之一: {expected}; 但找到 {actual})", "FileIsNotExecutable": "此檔案似乎不是可執行檔", - "FileNotFound": "{path}: 找不到檔案", + "FileNotFound": "找不到檔案", "FileReadFailed": "無法從位移 {byte_offset} 的 {path} 讀取 {count} 位元組。", "FileSeekFailed": "無法在 {path} 中搜尋至位置 {byte_offset}。", "FilesContainAbsolutePath1": "在安裝的套件中不應該有絕對路徑,例如下列路徑。若要隱藏此訊息,請新增 set(VCPKG_POLICY_SKIP_ABSOLUTE_PATHS_CHECK enabled)", @@ -578,7 +605,6 @@ "GitStatusUnknownFileStatus": "未知的檔案狀態: {value}", "GitUnexpectedCommandOutputCmd": "Git 執行 {command_line} 時產生未預期的輸出", "GraphCycleDetected": "在圖形中偵測到循環,於 {package_name}:", - "HashFileFailureToRead": "無法讀取檔案 \"{path}\" 進行雜湊: ", "HashPortManyFiles": "{package_name} 包含 {count} 個檔案。判斷二進位快取的 ABI 雜湊時,雜湊這些內容可能需要很長的時間。請考慮減少檔案數目。常見的原因是意外簽出來源或將檔案建置到連接埠的目錄。", "HeaderOnlyUsage": "{package_name} 為僅標頭,可透過下列方式從 CMake 使用:", "HelpAssetCaching": "**實驗性功能: 這可能會隨時變更或移除**\n\nvcpkg 可以使用鏡像來快取已下載的資產,以確保即使原始來源變更或消失,仍可繼續作業。\n\n資產快取可透過將環境變數 X_VCPKG_ASSET_SOURCES 設為以分號分隔的來源清單,或傳遞一連串 --x-asset-sources= 命令列選項來設定。命令列來源會在環境來源之後解譯。可以使用 backtick (') 逸出逗號、分號和反引號。\n\n特定字串的選擇性參數可控制其存取方式。可以指定為「read」、「write」或「readwrite」,並預設為「read」。\n\n有效來源:", @@ -641,7 +667,6 @@ "HelpTxtOptOnlyBinCache": "如果快取的二進位檔無法使用則失敗", "HelpTxtOptOnlyDownloads": "在不組建的情況下,盡可能嘗試下載來源", "HelpTxtOptRecurse": "允許在安裝時移除套件", - "HelpTxtOptUseAria2": "使用 aria2 執行下載工作", "HelpTxtOptUseHeadVersion": "使用最新的上游來源在命令列上安裝程式庫 (傳統模式)", "HelpTxtOptWritePkgConfig": "寫入 NuGet packages.config-formatted 檔案,以搭配外部二進位快取使用。如需詳細資訊,請參閱 `vcpkg help binarycaching`。", "HelpUpdateBaseline": "將程式庫保持在最新的最佳做法是更新您的基準參考。這可確保所有套件 (包括可轉移套件) 都會更新。不過,如果您需要單獨更新套件,您可以使用 \"version>=\" 限制式。", @@ -689,7 +714,7 @@ "IntegrationFailedVS2015": "整合並不適用 Visual Studio 2015。", "InternalCICommand": "vcpkg ci 是內部命令,會隨時以不相容的方式變更或遭移除。", "InternalErrorMessageContact": "請在 https://github.com/microsoft/vcpkg/issues/new?template=other-type-of-bug-report.md&labels=category:vcpkg-bug 開啟問題,並提供詳細步驟以重現問題。", - "InvalidArchitecture": "結構無效: {value}", + "InvalidArchitectureValue": "架構無效: {value}。必須要有下列其中一項: {expected}", "InvalidArgument": "引數無效", "InvalidArgumentRequiresAbsolutePath": "引數無效: 二進位 config 字串的二進位 config '{binary_source}' 路徑引數必須是絕對", "InvalidArgumentRequiresBaseUrl": "引數無效: 二進位 config '{binary_source}' 需要 {base_url} 基底 URL 做為第一個引數", @@ -731,9 +756,12 @@ "InvalidLogicExpressionUsePipe": "邏輯運算式無效,請使用 '|' 而非 'or'", "InvalidOptionForRemove": "'remove' 接受程式庫或 '--outdated'", "InvalidPortVersonName": "發現無效的連接埠版本檔案名稱: `{path}`。", + "InvalidSha512": "無效的 SHA-512 哈希: {sha}\nSHA-512 哈希長度必須為 128 個字元,且只包含十六進位數位", "InvalidSharpInVersion": "版本文字中有無效字元 '#'", "InvalidSharpInVersionDidYouMean": "版本文字中有無效字元 '#'。您指的是 \"port-version\": {value}?", "InvalidString": "傳遞至 Value::string(std::string) 的 utf8 無效", + "InvalidToolOSValue": "工具操作系統無效: {value}。必須要有下列其中一項: {expected}", + "InvalidToolVersion": "工具版本無效;必須是包含介於 1 到 3 個數位之間以點分隔之子字串的字串。", "InvalidTriplet": "無效的三元組: {triplet}", "InvalidUri": "無法剖析 URI: {value}", "InvalidValueHashAdditionalFiles": "變數 VCPKG_HASH_ADDITIONAL_FILES 包含的檔案路徑無效: '{path}'。值必須是現存檔案的絕對路徑。", @@ -782,14 +810,13 @@ "MismatchedBinParagraphs": "序列化二進位段落與原始二進位段落不同。請在 https://github.com/microsoft/vcpkg 開啟具有下列輸出的問題:", "MismatchedFiles": "要儲存的檔案與雜湊不相符", "MismatchedManifestAfterReserialize": "序列化資訊清單與原始資訊清單不同。請在 https://github.com/microsoft/vcpkg 開啟具有下列輸出的問題:", - "MismatchedNames": "名稱不相符: '{package_name}' != '{actual}'", + "MismatchedNames": "元數據檔案中宣告的埠名稱與目錄不符。埠必須命名為 {package_name},但檔案宣告 {actual}。", "MismatchedSpec": "連接埠 {path} 中的規格不符: 必須要有 {expected}、實際 {actual}", "MismatchedType": "{json_field}: 類型不符: 預期 {json_type}", "Missing7zHeader": "找不到 7z 標頭。", "MissingAndroidEnv": "ANDROID_NDK_HOME 環境變數遺失", "MissingAndroidHomeDir": "ANDROID_NDK_HOME 目錄不存在: {path}", "MissingArgFormatManifest": "已傳遞 format-manifest --convert-control 但沒有 '--all'。\n這不會執行任何動作: 明確傳遞的控制檔案會自動轉換。", - "MissingAssetBlockOrigin": "缺少 {path} 且 x-block-origin 封鎖了下載。", "MissingClosingParen": "遺漏右括弧 )", "MissingDependency": "套件 {spec} 已安装,但相依性 {package_name} 沒有安裝。", "MissingExtension": "缺少 '{extension}' 延伸模組", @@ -814,7 +841,6 @@ "NoInstalledPackages": "未安裝任何套件。您是要「搜尋」的意思?", "NoOutdatedPackages": "沒有過期的套件。", "NoRegistryForPort": "未設定連接埠 {package_name} 的登錄", - "NoUrlsAndHashSpecified": "未指定要下載 SHA 的 URL: {sha}", "NoUrlsAndNoHashSpecified": "未指定任何 URL 和雜湊。", "NonExactlyArgs": "命令 '{command_name}' 需要只有 '{expected}' 個引數,但提供了 '{actual}'。", "NonOneRemainingArgs": "命令 '{command_name}' 需要只有 1 個引數", @@ -834,8 +860,8 @@ "Options": "選項", "OriginalBinParagraphHeader": "\n原始二進位段落", "OtherCommandsHeader": "其他", - "OverlayPatchDir": "重疊路徑「{path}」必須存在且必須是目錄。", - "OverlayPortsDirectoriesHelp": "重疊連接埠的目錄 (也是: {env_var})", + "OverlayPatchDir": "重疊路徑 \"{path}\" 必須是現有的目錄。", + "OverlayPortsHelp": "重迭埠目錄或包含重迭埠目錄的目錄也 (: {env_var})", "OverlayTripletDirectoriesHelp": "重疊三元組的目錄 (也是: {env_var})", "OverlayTriplets": "來自 \"{path}\" 的重疊三元組:", "OverwritingFile": "檔案 {path} 已存在且將被覆寫", @@ -927,6 +953,7 @@ "PortsUpdated": "已更新下列 {count} 個連接埠:", "PrebuiltPackages": "有些套件尚未建置。若要建置,請執行:", "PreviousIntegrationFileRemains": "未移除先前的整合檔案。", + "ProgramPathReturnedNonzeroExitCode": "失敗,結束代碼為 {exit_code}", "ProgramReturnedNonzeroExitCode": "{tool_name} 失敗,結束代碼: ({exit_code})。", "ProvideExportType": "至少需要下列其中一個選項: --raw --nuget --ifw --zip --7zip --chocolatey --prefab。", "PushingVendorFailed": "將 {vendor} 推送到 \"{path}\" 失敗。如需詳細資訊,請使用 --debug。", @@ -962,7 +989,8 @@ "SpecifyTargetArch": "目標三元組。請參閱 'vcpkg help triplet' (預設值: {env_var})", "StartCodeUnitInContinue": "在繼續位置找到開始字碼單位", "StoreOptionMissingSha": "--store 選項無效,沒有 sha512", - "StoredBinariesToDestinations": "已將二進位檔儲存在 {elapsed} 中的 {count} 個目的地。", + "SubmittingBinaryCacheBackground": "開始在背景提交 {spec} 至 {count} 二進位快取()", + "SubmittingBinaryCacheComplete": "已完成提交 {spec} 至 {elapsed} 中 {count} 二進位快取()", "SuccessfulyExported": "已將 {package_name} 匯出至 {path}", "SuggestGitPull": "結果可能已過期。執行 `git pull` 以取得最新結果。", "SuggestStartingBashShell": "請確定您已啟動新的 Bash 殼層,才能讓變更生效。", @@ -974,7 +1002,9 @@ "SystemTargetsInstallFailed": "無法將系統目標檔案安裝到 {path}", "ToRemovePackages": "若要僅移除過時的套件,請執行\n{command_name} remove --outdated", "ToUpdatePackages": "若要更新這些套件及所有相依性,請執行\n{command_name} upgrade'", + "ToolDataFileSchemaVersionNotSupported": "此版本的 vcpkg 不支援文件架構版本 {version}", "ToolFetchFailed": "無法擷取 {tool_name}。", + "ToolHashMismatch": "{tool_name} 似乎已下載,但哈希不正確。預期 {expected} 但 {actual}", "ToolInWin10": "此公用程式與 Windows 10 或更新版本配套。", "ToolOfVersionXNotFound": "找不到適合的 {tool_name} 版本 (需要 v{version}),因此無法自動下載可攜式版本。請安裝更新版本的 {tool_name}", "TotalInstallTime": "總安裝時間: {elapsed}", @@ -1049,7 +1079,7 @@ "UpdateBaselineUpdatedBaseline": "已更新登錄 '{url}': 比較基準 '{old_value}' -> '{new_value}'", "UpgradeInManifest": "升級會升級傳統模式安裝,因此不支援資訊清單模式。請考慮使用 vcpkg x-update-baseline 將基準更新為目前的值,並執行 vcpkg 安裝,以更新您的相依性。", "UpgradeRunWithNoDryRun": "如果您確定要重建上述套件,請以 --no-dry-run 選項執行此命令。", - "UploadingBinariesToVendor": "正在將 '{spec}' 的二進位檔上傳到 '{vendor} '來源 \"{path}\"。", + "UploadingBinariesToVendor": "正在將 {spec} 二進位檔上傳到 {path} {vendor}", "UsageInstallInstructions": "您可以使用下列 CMake 來安裝 usage 檔案", "UsageTextHere": "usage 檔案在這裡", "UseEnvVar": "-- 正在環境變數中使用 {env_var}。", @@ -1077,7 +1107,6 @@ "VersionBaselineMismatch": "{package_name} 已獲指派 {actual},但本機連接埠為 {expected}", "VersionBuiltinPortTreeEntryMissing": "沒有 {package_name} 為 {expected} 的版本資料庫項目; 請使用簽出的連接埠樹狀版本 ({actual})。", "VersionCommandHeader": "vcpkg 套件管理程式版本 {version}\n\n請參閱 LICENSE.txt 以尋找授權資訊。", - "VersionConflictXML": "預期的 {path} 版本: [{expected_version}],但為 [{actual_version}]。請重新執行 bootstrap-vcpkg。", "VersionConstraintNotInDatabase1": "對 {package_name} 名稱版本 {version} 的 \"version>=\" 限制式覆寫不存在於版本資料庫中。所有版本都必須存在於版本資料庫中,才能由 vcpkg 進行解譯。", "VersionConstraintNotInDatabase2": "請考慮移除版本限制式,或選擇一個在這裡宣告的值", "VersionConstraintOk": "所有版本條件約束都與版本資料庫一致", @@ -1124,6 +1153,7 @@ "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "版本文字中的 '#' 後面必須接連接埠版本 (非負整數)", "VersionSpecMismatch": "無法載入連接埠,因為版本不一致。檔案 \"{path}\" 包含版本{actual_version},但版本資料庫指出應該為版本 {expected_version}。", "VersionVerifiedOK": "{version_spec} 在版本資料庫 ({git_tree_sha}) 中正確", + "WaitUntilPackagesUploaded": "正在等候 {count} 剩餘的二進位快取提交...", "WaitingForChildrenToExit": "正在等待子行程離開...", "WaitingToTakeFilesystemLock": "正在等候 {path} 上的檔案系統鎖定...", "WarnOnParseConfig": "在設定 {path} 中發現下列警告:", @@ -1135,6 +1165,7 @@ "WhileLoadingPortVersion": "當載入 {version_spec} 時", "WhileLookingForSpec": "尋找 {spec} 時:", "WhileParsingVersionsForPort": "當剖析來自 {path} 的 {package_name} 版本時", + "WhileRunningAssetCacheScriptCommandLine": "執行資產快取腳本命令行時", "WhileValidatingVersion": "驗證版本時: {version}", "WindowsOnlyCommand": "這個命令只支援 Windows。", "WroteNuGetPkgConfInfo": "已將 NuGet 套件設定資訊寫入 {path}。", diff --git a/scripts/posh-vcpkg.psd1 b/scripts/posh-vcpkg.psd1 index 3fb94fe7dc..a71de30595 100644 --- a/scripts/posh-vcpkg.psd1 +++ b/scripts/posh-vcpkg.psd1 @@ -1,18 +1,18 @@ @{ # Script module or binary module file associated with this manifest. -ModuleToProcess = 'posh-vcpkg.psm1' +RootModule = 'posh-vcpkg.psm1' # Version number of this module. -ModuleVersion = '0.0.1' +ModuleVersion = '0.0.2' # ID used to uniquely identify this module GUID = '948f02ab-fc99-4a53-8335-b6556eef129b' -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '5.0' +# Minimum version of the PowerShell engine required by this module +PowerShellVersion = '5.1' -FunctionsToExport = @('TabExpansion') +FunctionsToExport = @() CmdletsToExport = @() VariablesToExport = @() AliasesToExport = @() @@ -24,7 +24,7 @@ PrivateData = PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. - Tags = @('vcpkg', 'tab', 'tab-completion', 'tab-expansion', 'tabexpansion') + Tags = @('vcpkg', 'tab', 'tab-completion', 'Register-ArgumentCompleter') } } diff --git a/scripts/posh-vcpkg.psm1 b/scripts/posh-vcpkg.psm1 index 25ef99609f..2ade751db1 100644 --- a/scripts/posh-vcpkg.psm1 +++ b/scripts/posh-vcpkg.psm1 @@ -1,39 +1,41 @@ -param() +Register-ArgumentCompleter -Native -CommandName vcpkg -ScriptBlock { + param( + [string]$wordToComplete, + [System.Management.Automation.Language.CommandAst]$commandAst, + [int]$cursorPosition + ) -if (Get-Module posh-vcpkg) { return } + if ($cursorPosition -lt $commandAst.CommandElements[0].Extent.EndOffset) { + return + } -if ($PSVersionTable.PSVersion.Major -lt 5) { - Write-Warning ("posh-vcpkg does not support PowerShell versions before 5.0.") - return -} + [string]$commandText = $commandAst.CommandElements[0].Value -if (Test-Path Function:\TabExpansion) { - Rename-Item Function:\TabExpansion VcpkgTabExpansionBackup -} + [string[]]$textsBeforeCursor = $commandAst.CommandElements | + Select-Object -Skip 1 | ForEach-Object { + if ($_.Extent.EndOffset -le $cursorPosition) { + $_.Extent.Text + } + elseif ($_.Extent.StartOffset -lt $cursorPosition) { + $_.Extent.Text.Substring(0, $cursorPosition - $_.Extent.StartOffset) + } + } -function TabExpansion($line, $lastWord) { - $lastBlock = [regex]::Split($line, '[|;]')[-1].TrimStart() + $spaceToComplete = if ($wordToComplete -ne '') { $null } + elseif ($PSNativeCommandArgumentPassing -in 'Standard', 'Windows') { '' } + else { '""' } - switch -regex ($lastBlock) { - "^(?(\./|\.\\|)vcpkg(\.exe|)) (?.*)$" - { - & $matches['vcpkgexe'] autocomplete $matches['remaining'] - return - } + [PowerShell]$cmd = [PowerShell]::Create().AddScript{ + Set-Location $args[0] + & $args[1] autocomplete @($args[2]) + }.AddParameters(($PWD, $commandText, @($textsBeforeCursor + $spaceToComplete))) - # Fall back on existing tab expansion - default { - if (Test-Path Function:\VcpkgTabExpansionBackup) { - VcpkgTabExpansionBackup $line $lastWord - } - } - } -} + [string[]]$completions = $cmd.Invoke() -$exportModuleMemberParams = @{ - Function = @( - 'TabExpansion' - ) + if ($cmd.HadErrors -or $completions.Count -eq 0) { + return + } + else { + return $completions + } } - -Export-ModuleMember @exportModuleMemberParams diff --git a/src/localization/cs/messages.json.lcl b/src/localization/cs/messages.json.lcl index 26744d183e..edc1548c75 100644 --- a/src/localization/cs/messages.json.lcl +++ b/src/localization/cs/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - v {path}.]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path}, ale nejsou nakonfigurované žádné mezipaměti prostředků.]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path}]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8563,15 +8833,6 @@ - - - - - - - - - @@ -8745,18 +9006,21 @@ - + - + + + + - + - + - + @@ -9736,6 +10000,15 @@ + + + + + + + + + @@ -10135,15 +10408,21 @@ - + - + - + + + + + + + + + + - - - @@ -10264,6 +10543,15 @@ + + + + + + + + + @@ -10273,6 +10561,15 @@ + + + + + + + + + @@ -11172,12 +11469,12 @@ - + - + - + @@ -11479,15 +11776,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11932,6 +12220,15 @@ + + + + + + + + + @@ -12052,6 +12349,15 @@ + + + + + + + + + diff --git a/src/localization/de/messages.json.lcl b/src/localization/de/messages.json.lcl index c451cf494b..df38d1e9ec 100644 --- a/src/localization/de/messages.json.lcl +++ b/src/localization/de/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - in {path} nicht gefunden]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path} wird heruntergeladen.]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path} angefordert, es sind jedoch keine Ressourcencaches konfiguriert.]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path} wird heruntergeladen]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8560,15 +8830,6 @@ - - - - - - - - - @@ -8742,18 +9003,21 @@ - + - + + + + - + - + - + @@ -9733,6 +9997,15 @@ + + + + + + + + + @@ -10132,15 +10405,21 @@ - + - + - + + + + + + + + + + - - - @@ -10261,6 +10540,15 @@ + + + + + + + + + @@ -10270,6 +10558,15 @@ + + + + + + + + + @@ -11169,12 +11466,12 @@ - + - + - + @@ -11476,15 +11773,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11929,6 +12217,15 @@ + + + + + + + + + @@ -12049,6 +12346,15 @@ + + + + + + + + + diff --git a/src/localization/es/messages.json.lcl b/src/localization/es/messages.json.lcl index 684c3b9e48..7a953c2d16 100644 --- a/src/localization/es/messages.json.lcl +++ b/src/localization/es/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - en {path}]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path}, pero no hay ninguna caché de recursos configurada]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path}]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8560,15 +8830,6 @@ - - - - - - - - - @@ -8742,18 +9003,21 @@ - + - + + + + - + - + - + @@ -9733,6 +9997,15 @@ + + + + + + + + + @@ -10132,15 +10405,21 @@ - + - + - + + + + + + + + + + - - - @@ -10261,6 +10540,15 @@ + + + + + + + + + @@ -10270,6 +10558,15 @@ + + + + + + + + + @@ -11169,12 +11466,12 @@ - + - + - + @@ -11476,15 +11773,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11929,6 +12217,15 @@ + + + + + + + + + @@ -12049,6 +12346,15 @@ + + + + + + + + + diff --git a/src/localization/fr/messages.json.lcl b/src/localization/fr/messages.json.lcl index f2c2e553cd..3c529cca17 100644 --- a/src/localization/fr/messages.json.lcl +++ b/src/localization/fr/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - dans {path}]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path}, mais aucun cache de ressources n’est configuré]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path}]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8560,15 +8830,6 @@ - - - - - - - - - @@ -8742,18 +9003,21 @@ - + - + + + + - + - + - + @@ -9733,6 +9997,15 @@ + + + + + + + + + @@ -10132,15 +10405,21 @@ - + - + - + + + + + + + + + + - - - @@ -10261,6 +10540,15 @@ + + + + + + + + + @@ -10270,6 +10558,15 @@ + + + + + + + + + @@ -11169,12 +11466,12 @@ - + - + - + @@ -11476,15 +11773,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11929,6 +12217,15 @@ + + + + + + + + + @@ -12049,6 +12346,15 @@ + + + + + + + + + diff --git a/src/localization/it/messages.json.lcl b/src/localization/it/messages.json.lcl index 07a17615d0..3a68721b3f 100644 --- a/src/localization/it/messages.json.lcl +++ b/src/localization/it/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - in {path}]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path}, ma non sono configurate cache degli asset]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path}]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8563,15 +8833,6 @@ - - - - - - - - - @@ -8745,18 +9006,21 @@ - + - + + + + - + - + - + @@ -9736,6 +10000,15 @@ + + + + + + + + + @@ -10135,15 +10408,21 @@ - + - + - + + + + + + + + + + - - - @@ -10264,6 +10543,15 @@ + + + + + + + + + @@ -10273,6 +10561,15 @@ + + + + + + + + + @@ -11172,12 +11469,12 @@ - + - + - + @@ -11479,15 +11776,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11932,6 +12220,15 @@ + + + + + + + + + @@ -12052,6 +12349,15 @@ + + + + + + + + + diff --git a/src/localization/ja/messages.json.lcl b/src/localization/ja/messages.json.lcl index 7590780d31..8cbf3ffcce 100644 --- a/src/localization/ja/messages.json.lcl +++ b/src/localization/ja/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - が見つかりませんでした]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path} {sha} アセット キャッシュ エントリのダウンロードを要求しましたが、資産キャッシュが構成されていません]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path} をダウンロードしています]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8563,15 +8833,6 @@ - - - - - - - - - @@ -8745,18 +9006,21 @@ - + - + + + + - + - + - + @@ -9736,6 +10000,15 @@ + + + + + + + + + @@ -10135,15 +10408,21 @@ - + - + - + + + + + + + + + + - - - @@ -10264,6 +10543,15 @@ + + + + + + + + + @@ -10273,6 +10561,15 @@ + + + + + + + + + @@ -11172,12 +11469,12 @@ - + - + - + @@ -11479,15 +11776,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11932,6 +12220,15 @@ + + + + + + + + + @@ -12052,6 +12349,15 @@ + + + + + + + + + diff --git a/src/localization/ko/messages.json.lcl b/src/localization/ko/messages.json.lcl index d1e24b337d..0905b9b641 100644 --- a/src/localization/ko/messages.json.lcl +++ b/src/localization/ko/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - 을(를) 찾을 수 없습니다.]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + + + + + + + + + + + + + + + + + + + + + + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path} {sha} 자산 캐시 항목의 다운로드를 요청했지만 자산 캐시가 구성되지 않았습니다.]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path}]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8560,15 +8830,6 @@ - - - - - - - - - @@ -8742,18 +9003,21 @@ - + - + + + + - + - + - + @@ -9733,6 +9997,15 @@ + + + + + + + + + @@ -10132,15 +10405,21 @@ - + - + - + + + + + + + + + + - - - @@ -10261,6 +10540,15 @@ + + + + + + + + + @@ -10270,6 +10558,15 @@ + + + + + + + + + @@ -11169,12 +11466,12 @@ - + - + - + @@ -11476,15 +11773,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11929,6 +12217,15 @@ + + + + + + + + + @@ -12049,6 +12346,15 @@ + + + + + + + + + diff --git a/src/localization/pl/messages.json.lcl b/src/localization/pl/messages.json.lcl index 7944da6a07..1bb3b35b97 100644 --- a/src/localization/pl/messages.json.lcl +++ b/src/localization/pl/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - w ścieżce {path}]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path}, ale nie skonfigurowano żadnych pamięci podręcznych zasobów]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path}]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8560,15 +8830,6 @@ - - - - - - - - - @@ -8742,18 +9003,21 @@ - + - + + + + - + - + - + @@ -9733,6 +9997,15 @@ + + + + + + + + + @@ -10132,15 +10405,21 @@ - + - + - + + + + + + + + + + - - - @@ -10261,6 +10540,15 @@ + + + + + + + + + @@ -10270,6 +10558,15 @@ + + + + + + + + + @@ -11169,12 +11466,12 @@ - + - + - + @@ -11476,15 +11773,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11929,6 +12217,15 @@ + + + + + + + + + @@ -12049,6 +12346,15 @@ + + + + + + + + + diff --git a/src/localization/pt-BR/messages.json.lcl b/src/localization/pt-BR/messages.json.lcl index f2cce33ccb..937b136df9 100644 --- a/src/localization/pt-BR/messages.json.lcl +++ b/src/localization/pt-BR/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - em {path}]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path}, mas nenhum cache de ativos está configurado]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path}]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8560,15 +8830,6 @@ - - - - - - - - - @@ -8742,18 +9003,21 @@ - + - + + + + - + - + - + @@ -9733,6 +9997,15 @@ + + + + + + + + + @@ -10132,15 +10405,21 @@ - + - + - + + + + + + + + + + - - - @@ -10261,6 +10540,15 @@ + + + + + + + + + @@ -10270,6 +10558,15 @@ + + + + + + + + + @@ -11169,12 +11466,12 @@ - + - + - + @@ -11476,15 +11773,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11929,6 +12217,15 @@ + + + + + + + + + @@ -12049,6 +12346,15 @@ + + + + + + + + + diff --git a/src/localization/ru/messages.json.lcl b/src/localization/ru/messages.json.lcl index 4435266401..16784371ba 100644 --- a/src/localization/ru/messages.json.lcl +++ b/src/localization/ru/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - в {path}]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path}, но кэши ресурсов не настроены]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path}]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8563,15 +8833,6 @@ - - - - - - - - - @@ -8745,18 +9006,21 @@ - + - + + + + - + - + - + @@ -9736,6 +10000,15 @@ + + + + + + + + + @@ -10135,15 +10408,21 @@ - + - + - + + + + + + + + + + - - - @@ -10264,6 +10543,15 @@ + + + + + + + + + @@ -10273,6 +10561,15 @@ + + + + + + + + + @@ -11172,12 +11469,12 @@ - + - + - + @@ -11479,15 +11776,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11932,6 +12220,15 @@ + + + + + + + + + @@ -12052,6 +12349,15 @@ + + + + + + + + + diff --git a/src/localization/tr/messages.json.lcl b/src/localization/tr/messages.json.lcl index b4ef0637e6..ac5a247f00 100644 --- a/src/localization/tr/messages.json.lcl +++ b/src/localization/tr/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - bulunamadı]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path} için varlık {sha} girdisi indiriliyor]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path} varlık önbelleği girdisi {sha} istendi, ancak varlık önbelleği yapılandırılmadı]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path} {url} -{url} indiriliyor]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8563,15 +8833,6 @@ - - - - - - - - - @@ -8745,18 +9006,21 @@ - + - + + + + - + - + - + @@ -9736,6 +10000,15 @@ + + + + + + + + + @@ -10135,15 +10408,21 @@ - + - + - + + + + + + + + + + - - - @@ -10264,6 +10543,15 @@ + + + + + + + + + @@ -10273,6 +10561,15 @@ + + + + + + + + + @@ -11172,12 +11469,12 @@ - + - + - + @@ -11479,15 +11776,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11932,6 +12220,15 @@ + + + + + + + + + @@ -12052,6 +12349,15 @@ + + + + + + + + + diff --git a/src/localization/zh-Hans/messages.json.lcl b/src/localization/zh-Hans/messages.json.lcl index f13d5d4fd9..0583aed870 100644 --- a/src/localization/zh-Hans/messages.json.lcl +++ b/src/localization/zh-Hans/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - 版]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path},但未配置任何资产缓存]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path}]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8563,15 +8833,6 @@ - - - - - - - - - @@ -8745,18 +9006,21 @@ - + - + + + + - + - + - + @@ -9736,6 +10000,15 @@ + + + + + + + + + @@ -10135,15 +10408,21 @@ - + - + - + + + + + + + + + + - - - @@ -10264,6 +10543,15 @@ + + + + + + + + + @@ -10273,6 +10561,15 @@ + + + + + + + + + @@ -11172,12 +11469,12 @@ - + - + - + @@ -11479,15 +11776,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11932,6 +12220,15 @@ + + + + + + + + + @@ -12052,6 +12349,15 @@ + + + + + + + + + diff --git a/src/localization/zh-Hant/messages.json.lcl b/src/localization/zh-Hant/messages.json.lcl index 9d7fd20c97..618984a010 100644 --- a/src/localization/zh-Hant/messages.json.lcl +++ b/src/localization/zh-Hant/messages.json.lcl @@ -130,6 +130,15 @@ + + + + + + + + + @@ -412,6 +421,15 @@ + + + + + + + + + @@ -439,6 +457,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1381,29 +1444,74 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + - + - + + + + + + + + + + + + + @@ -1417,15 +1525,93 @@ - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3820,15 +4006,6 @@ - - - - - - - - - @@ -3850,18 +4027,6 @@ - - - - - - - - - - - - @@ -4033,15 +4198,6 @@ - - - in {path}]]> - - ]]> - - - - @@ -4111,38 +4267,38 @@ - + - + - + - + - + - + - + - + - + - + - + - + @@ -4399,39 +4555,66 @@ - + - + - + + + + - + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + - + - + + + + @@ -4444,6 +4627,15 @@ + + + + + + + + + @@ -4458,19 +4650,43 @@ - + - + + + + + + + + + + + + + + + + + + + + + + - + - + + + + @@ -4501,6 +4717,42 @@ + + + {path}]]> + + {path}]]> + + + + + + + {path}, but no asset caches are configured]]> + + {path},但未設定任何資產快取]]> + + + + + + + + + + + + + + + + + + + + + + @@ -4513,11 +4765,11 @@ - + - + {path}]]> - + {path}]]> @@ -4567,6 +4819,15 @@ + + + + + + + + + @@ -4801,6 +5062,24 @@ + + + + + + + + + + + + + + + + + + @@ -5599,15 +5878,6 @@ - - - - - - - - - @@ -5737,12 +6007,15 @@ - + - + - + + + + @@ -6109,18 +6382,6 @@ - - - - - - - - - - - - @@ -6775,18 +7036,6 @@ - - - - - - - - - - - - @@ -7306,11 +7555,11 @@ - + - + - + @@ -7726,6 +7975,15 @@ + + + + + + + + + @@ -7753,6 +8011,24 @@ + + + + + + + + + + + + + + + + + + @@ -8208,10 +8484,13 @@ - + - + + + + @@ -8269,15 +8548,6 @@ - - - - - - - - - @@ -8563,15 +8833,6 @@ - - - - - - - - - @@ -8745,18 +9006,21 @@ - + - + + + + - + - + - + @@ -9736,6 +10000,15 @@ + + + + + + + + + @@ -10135,15 +10408,21 @@ - + - + - + + + + + + + + + + - - - @@ -10264,6 +10543,15 @@ + + + + + + + + + @@ -10273,6 +10561,15 @@ + + + + + + + + + @@ -11172,12 +11469,12 @@ - + - + - + @@ -11479,15 +11776,6 @@ - - - - - - - - - =" constraint to {package_name} names version {version} which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg.]]> @@ -11932,6 +12220,15 @@ + + + + + + + + + @@ -12052,6 +12349,15 @@ + + + + + + + + + diff --git a/src/test-script-asset-cache.c b/src/test-script-asset-cache.c index 0595ab13bb..389f54f3bd 100644 --- a/src/test-script-asset-cache.c +++ b/src/test-script-asset-cache.c @@ -5,6 +5,7 @@ #include static const char expected_uri[] = "https://example.com/hello-world.txt"; +// Note that this checks that the SHA is properly tolower'd static const char expected_sha[] = "09e1e2a84c92b56c8280f4a1203c7cffd61b162cfe987278d4d6be9afbf38c0e8934cdadf83751f4e99" "d111352bffefc958e5a4852c8a7a29c95742ce59288a8"; diff --git a/src/vcpkg-test/archives.cpp b/src/vcpkg-test/archives.cpp index 76338403b8..4879832caf 100644 --- a/src/vcpkg-test/archives.cpp +++ b/src/vcpkg-test/archives.cpp @@ -15,4 +15,5 @@ TEST_CASE ("Testing guess_extraction_type", "[z-extract]") REQUIRE(guess_extraction_type(Path("/path/to/archive.xz")) == ExtractionType::Tar); REQUIRE(guess_extraction_type(Path("/path/to/archive.exe")) == ExtractionType::Exe); REQUIRE(guess_extraction_type(Path("/path/to/archive.unknown")) == ExtractionType::Unknown); + REQUIRE(guess_extraction_type(Path("/path/to/archive.7z.exe")) == ExtractionType::SelfExtracting7z); } diff --git a/src/vcpkg-test/binarycaching.cpp b/src/vcpkg-test/binarycaching.cpp index a41fd6bb1a..914ab144dd 100644 --- a/src/vcpkg-test/binarycaching.cpp +++ b/src/vcpkg-test/binarycaching.cpp @@ -327,9 +327,8 @@ Features: a, b TEST_CASE ("Provider nullptr checks", "[BinaryCache]") { // create a binary cache to test - BinaryProviders providers; - providers.read.emplace_back(std::make_unique()); - ReadOnlyBinaryCache uut(std::move(providers)); + ReadOnlyBinaryCache uut; + uut.install_read_provider(std::make_unique()); // create an action plan with an action without a package ABI set auto pghs = Paragraphs::parse_paragraphs(R"( @@ -470,3 +469,60 @@ Description: a spiffy compression library wrapper )"); } + +TEST_CASE ("Synchronizer operations", "[BinaryCache]") +{ + { + BinaryCacheSynchronizer sync; + auto result = sync.fetch_add_completed(); + REQUIRE(result.jobs_submitted == 0); + REQUIRE(result.jobs_completed == 1); + REQUIRE_FALSE(result.submission_complete); + } + + { + BinaryCacheSynchronizer sync; + sync.add_submitted(); + sync.add_submitted(); + auto result = sync.fetch_add_completed(); + REQUIRE(result.jobs_submitted == 2); + REQUIRE(result.jobs_completed == 1); + REQUIRE_FALSE(result.submission_complete); + } + + { + BinaryCacheSynchronizer sync; + sync.add_submitted(); + REQUIRE(sync.fetch_incomplete_mark_submission_complete() == 1); + sync.add_submitted(); + REQUIRE(sync.fetch_incomplete_mark_submission_complete() == 2); + auto result = sync.fetch_add_completed(); + REQUIRE(result.jobs_submitted == 2); + REQUIRE(result.jobs_completed == 1); + REQUIRE(result.submission_complete); + result = sync.fetch_add_completed(); + REQUIRE(result.jobs_submitted == 2); + REQUIRE(result.jobs_completed == 2); + REQUIRE(result.submission_complete); + } + + { + BinaryCacheSynchronizer sync; + sync.add_submitted(); + sync.add_submitted(); + sync.add_submitted(); + auto result = sync.fetch_add_completed(); + REQUIRE(result.jobs_submitted == 3); + REQUIRE(result.jobs_completed == 1); + REQUIRE_FALSE(result.submission_complete); + REQUIRE(sync.fetch_incomplete_mark_submission_complete() == 2); + result = sync.fetch_add_completed(); + REQUIRE(result.jobs_submitted == 2); + REQUIRE(result.jobs_completed == 1); + REQUIRE(result.submission_complete); + result = sync.fetch_add_completed(); + REQUIRE(result.jobs_submitted == 2); + REQUIRE(result.jobs_completed == 2); + REQUIRE(result.submission_complete); + } +} diff --git a/src/vcpkg-test/configmetadata.cpp b/src/vcpkg-test/configmetadata.cpp index 57373bd03d..d9a7f67fb3 100644 --- a/src/vcpkg-test/configmetadata.cpp +++ b/src/vcpkg-test/configmetadata.cpp @@ -40,7 +40,7 @@ static Configuration parse_test_configuration(StringView text) auto object = Json::parse_object(text, origin).value_or_exit(VCPKG_LINE_INFO); Json::Reader reader(origin); - auto parsed_config_opt = reader.visit(object, get_configuration_deserializer()); + auto parsed_config_opt = configuration_deserializer.visit(reader, object); REQUIRE(reader.errors().empty()); return std::move(parsed_config_opt).value_or_exit(VCPKG_LINE_INFO); @@ -60,7 +60,7 @@ static void check_errors(const std::string& config_text, const std::string& expe auto object = Json::parse_object(config_text, origin).value_or_exit(VCPKG_LINE_INFO); Json::Reader reader(origin); - auto parsed_config_opt = reader.visit(object, get_configuration_deserializer()); + auto parsed_config_opt = configuration_deserializer.visit(reader, object); REQUIRE(!reader.errors().empty()); CHECK_LINES(Strings::join("\n", reader.errors()), expected_errors); diff --git a/src/vcpkg-test/configparser.cpp b/src/vcpkg-test/configparser.cpp index cc8832b344..8e1a60d367 100644 --- a/src/vcpkg-test/configparser.cpp +++ b/src/vcpkg-test/configparser.cpp @@ -614,19 +614,19 @@ TEST_CASE ("AssetConfigParser azurl provider", "[assetconfigparser]") CHECK(parse_download_configuration("x-azurl,ftp://magic,none")); { - DownloadManagerConfig empty; + AssetCachingSettings empty; CHECK(empty.m_write_headers.empty()); CHECK(empty.m_read_headers.empty()); } { - DownloadManagerConfig dm = + AssetCachingSettings dm = parse_download_configuration("x-azurl,https://abc/123,foo").value_or_exit(VCPKG_LINE_INFO); CHECK(dm.m_read_url_template == "https://abc/123/?foo"); CHECK(dm.m_read_headers.empty()); CHECK(dm.m_write_url_template == nullopt); } { - DownloadManagerConfig dm = + AssetCachingSettings dm = parse_download_configuration("x-azurl,https://abc/123/,foo").value_or_exit(VCPKG_LINE_INFO); CHECK(dm.m_read_url_template == "https://abc/123/?foo"); CHECK(dm.m_read_headers.empty()); @@ -634,7 +634,7 @@ TEST_CASE ("AssetConfigParser azurl provider", "[assetconfigparser]") CHECK(dm.m_secrets == std::vector{"foo"}); } { - DownloadManagerConfig dm = + AssetCachingSettings dm = parse_download_configuration("x-azurl,https://abc/123,?foo").value_or_exit(VCPKG_LINE_INFO); CHECK(dm.m_read_url_template == "https://abc/123/?foo"); CHECK(dm.m_read_headers.empty()); @@ -642,14 +642,14 @@ TEST_CASE ("AssetConfigParser azurl provider", "[assetconfigparser]") CHECK(dm.m_secrets == std::vector{"?foo"}); } { - DownloadManagerConfig dm = + AssetCachingSettings dm = parse_download_configuration("x-azurl,https://abc/123").value_or_exit(VCPKG_LINE_INFO); CHECK(dm.m_read_url_template == "https://abc/123/"); CHECK(dm.m_read_headers.empty()); CHECK(dm.m_write_url_template == nullopt); } { - DownloadManagerConfig dm = + AssetCachingSettings dm = parse_download_configuration("x-azurl,https://abc/123,,readwrite").value_or_exit(VCPKG_LINE_INFO); CHECK(dm.m_read_url_template == "https://abc/123/"); CHECK(dm.m_read_headers.empty()); @@ -657,7 +657,7 @@ TEST_CASE ("AssetConfigParser azurl provider", "[assetconfigparser]") Test::check_ranges(dm.m_write_headers, azure_blob_headers()); } { - DownloadManagerConfig dm = + AssetCachingSettings dm = parse_download_configuration("x-azurl,https://abc/123,foo,readwrite").value_or_exit(VCPKG_LINE_INFO); CHECK(dm.m_read_url_template == "https://abc/123/?foo"); CHECK(dm.m_read_headers.empty()); @@ -665,6 +665,16 @@ TEST_CASE ("AssetConfigParser azurl provider", "[assetconfigparser]") Test::check_ranges(dm.m_write_headers, azure_blob_headers()); CHECK(dm.m_secrets == std::vector{"foo"}); } + { + AssetCachingSettings dm = + parse_download_configuration("x-script,powershell {SHA} {URL}").value_or_exit(VCPKG_LINE_INFO); + CHECK(!dm.m_read_url_template.has_value()); + CHECK(dm.m_read_headers.empty()); + CHECK(!dm.m_write_url_template.has_value()); + CHECK(dm.m_write_headers.empty()); + CHECK(dm.m_secrets.empty()); + CHECK(dm.m_script.value_or_exit(VCPKG_LINE_INFO) == "powershell {SHA} {URL}"); + } } TEST_CASE ("AssetConfigParser clear provider", "[assetconfigparser]") @@ -679,7 +689,7 @@ TEST_CASE ("AssetConfigParser clear provider", "[assetconfigparser]") return std::move(v); }; - DownloadManagerConfig empty; + AssetCachingSettings empty; CHECK(value_or(parse_download_configuration("x-azurl,https://abc/123,foo;clear"), empty).m_read_url_template == nullopt); @@ -698,7 +708,7 @@ TEST_CASE ("AssetConfigParser x-block-origin provider", "[assetconfigparser]") return std::move(v); }; - DownloadManagerConfig empty; + AssetCachingSettings empty; CHECK(!value_or(parse_download_configuration({}), empty).m_block_origin); CHECK(value_or(parse_download_configuration("x-block-origin"), empty).m_block_origin); diff --git a/src/vcpkg-test/dependencies.cpp b/src/vcpkg-test/dependencies.cpp index d72a364e88..26888b9b06 100644 --- a/src/vcpkg-test/dependencies.cpp +++ b/src/vcpkg-test/dependencies.cpp @@ -55,8 +55,6 @@ struct MockVersionedPortfileProvider : IVersionedPortfileProvider return it2->second; } - virtual View get_port_versions(StringView) const override { Checks::unreachable(VCPKG_LINE_INFO); } - SourceControlFileAndLocation& emplace(std::string&& name, Version&& version, VersionScheme scheme = VersionScheme::String) diff --git a/src/vcpkg-test/downloads.cpp b/src/vcpkg-test/downloads.cpp index a3b2f9fd0a..31eef37073 100644 --- a/src/vcpkg-test/downloads.cpp +++ b/src/vcpkg-test/downloads.cpp @@ -5,57 +5,192 @@ using namespace vcpkg; -TEST_CASE ("split_uri_view", "[downloads]") +TEST_CASE ("parse_split_url_view", "[downloads]") { { - auto x = split_uri_view("https://github.com/Microsoft/vcpkg"); - REQUIRE(x.has_value()); - REQUIRE(x.get()->scheme == "https"); - REQUIRE(x.get()->authority.value_or("") == "//github.com"); - REQUIRE(x.get()->path_query_fragment == "/Microsoft/vcpkg"); + auto x = parse_split_url_view("https://github.com/Microsoft/vcpkg"); + if (auto v = x.get()) + { + REQUIRE(v->scheme == "https"); + REQUIRE(v->authority.value_or("") == "//github.com"); + REQUIRE(v->path_query_fragment == "/Microsoft/vcpkg"); + } + else + { + FAIL(); + } } { - auto x = split_uri_view(""); - REQUIRE(!x.has_value()); + REQUIRE(!parse_split_url_view("").has_value()); + REQUIRE(!parse_split_url_view("hello").has_value()); } { - auto x = split_uri_view("hello"); - REQUIRE(!x.has_value()); + auto x = parse_split_url_view("file:"); + if (auto y = x.get()) + { + REQUIRE(y->scheme == "file"); + REQUIRE(!y->authority.has_value()); + REQUIRE(y->path_query_fragment == ""); + } + else + { + FAIL(); + } } { - auto x = split_uri_view("file:"); - REQUIRE(x.has_value()); - REQUIRE(x.get()->scheme == "file"); - REQUIRE(!x.get()->authority.has_value()); - REQUIRE(x.get()->path_query_fragment == ""); + auto x = parse_split_url_view("file:path"); + if (auto y = x.get()) + { + REQUIRE(y->scheme == "file"); + REQUIRE(!y->authority.has_value()); + REQUIRE(y->path_query_fragment == "path"); + } + else + { + FAIL(); + } } { - auto x = split_uri_view("file:path"); - REQUIRE(x.has_value()); - REQUIRE(x.get()->scheme == "file"); - REQUIRE(!x.get()->authority.has_value()); - REQUIRE(x.get()->path_query_fragment == "path"); + auto x = parse_split_url_view("file:/path"); + if (auto y = x.get()) + { + REQUIRE(y->scheme == "file"); + REQUIRE(!y->authority.has_value()); + REQUIRE(y->path_query_fragment == "/path"); + } + else + { + FAIL(); + } } { - auto x = split_uri_view("file:/path"); - REQUIRE(x.has_value()); - REQUIRE(x.get()->scheme == "file"); - REQUIRE(!x.get()->authority.has_value()); - REQUIRE(x.get()->path_query_fragment == "/path"); + auto x = parse_split_url_view("file://user:pw@host"); + if (auto y = x.get()) + { + REQUIRE(y->scheme == "file"); + REQUIRE(y->authority.value_or("") == "//user:pw@host"); + REQUIRE(y->path_query_fragment == ""); + } + else + { + FAIL(); + } } { - auto x = split_uri_view("file://user:pw@host"); - REQUIRE(x.has_value()); - REQUIRE(x.get()->scheme == "file"); - REQUIRE(x.get()->authority.value_or({}) == "//user:pw@host"); - REQUIRE(x.get()->path_query_fragment == ""); + auto x = parse_split_url_view("ftp://host:port/"); + if (auto y = x.get()) + { + REQUIRE(y->scheme == "ftp"); + REQUIRE(y->authority.value_or("") == "//host:port"); + REQUIRE(y->path_query_fragment == "/"); + } + else + { + FAIL(); + } } { - auto x = split_uri_view("ftp://host:port/"); - REQUIRE(x.has_value()); - REQUIRE(x.get()->scheme == "ftp"); - REQUIRE(x.get()->authority.value_or({}) == "//host:port"); - REQUIRE(x.get()->path_query_fragment == "/"); + auto x = parse_split_url_view("file://D:\\work\\testing\\asset-cache/" + "562de7b577c99fe347b00437d14ce375a8e5a60504909cb67d2f73c372d39a2f76d2b42b69e4aeb3" + "1a4879e1bcf6f7c2d41f2ace12180ea83ba7af48879d40ab"); + if (auto y = x.get()) + { + REQUIRE(y->scheme == "file"); + REQUIRE(y->authority.value_or("") == "//D:\\work\\testing\\asset-cache"); + REQUIRE(y->path_query_fragment == "/562de7b577c99fe347b00437d14ce375a8e5a60504909cb67d2f73c372d39a2f76d2b42" + "b69e4aeb31a4879e1bcf6f7c2d41f2ace12180ea83ba7af48879d40ab"); + } + else + { + FAIL(); + } + } +} + +TEST_CASE ("parse_curl_status_line", "[downloads]") +{ + std::vector http_codes; + StringLiteral malformed_examples[] = { + "asdfasdf", // wrong prefix + "curl: unknown --write-out variable: 'exitcode'", // wrong prefixes, and also what old curl does + "curl: unknown --write-out variable: 'errormsg'", + "prefix", // missing spaces + "prefix42", // missing spaces + "prefix42 2", // missing space + "prefix42 2a", // non numeric exitcode + }; + + FullyBufferedDiagnosticContext bdc; + for (auto&& malformed : malformed_examples) + { + REQUIRE(!parse_curl_status_line(bdc, http_codes, "prefix", malformed)); + REQUIRE(http_codes.empty()); + REQUIRE(bdc.empty()); + } + + // old curl output + REQUIRE(!parse_curl_status_line(bdc, http_codes, "prefix", "prefix200 ")); + REQUIRE(http_codes == std::vector{200}); + REQUIRE(bdc.empty()); + http_codes.clear(); + + REQUIRE(!parse_curl_status_line(bdc, http_codes, "prefix", "prefix404 ")); + REQUIRE(http_codes == std::vector{404}); + REQUIRE(bdc.empty()); + http_codes.clear(); + + REQUIRE(!parse_curl_status_line(bdc, http_codes, "prefix", "prefix0 ")); // a failure, but we don't know that yet + REQUIRE(http_codes == std::vector{0}); + REQUIRE(bdc.empty()); + http_codes.clear(); + + // current curl output + REQUIRE(parse_curl_status_line(bdc, http_codes, "prefix", "prefix200 0 ")); + REQUIRE(http_codes == std::vector{200}); + REQUIRE(bdc.empty()); + http_codes.clear(); + + REQUIRE(parse_curl_status_line( + bdc, + http_codes, + "prefix", + "prefix0 60 schannel: SNI or certificate check failed: SEC_E_WRONG_PRINCIPAL (0x80090322) " + "- The target principal name is incorrect.")); + REQUIRE(http_codes == std::vector{0}); + REQUIRE(bdc.to_string() == + "error: curl operation failed with error code 60. schannel: SNI or certificate check failed: " + "SEC_E_WRONG_PRINCIPAL (0x80090322) - The target principal name is incorrect."); +} + +TEST_CASE ("download_files", "[downloads]") +{ + auto const dst = Test::base_temporary_directory() / "download_files"; + auto const url = [&](std::string l) -> auto { return std::pair(l, dst); }; + + FullyBufferedDiagnosticContext bdc; + std::vector headers; + std::vector secrets; + auto results = download_files_no_cache( + bdc, + std::vector{url("unknown://localhost:9/secret"), url("http://localhost:9/not-exists/secret")}, + headers, + secrets); + REQUIRE(results == std::vector{0, 0}); + auto all_errors = bdc.to_string(); + if (all_errors == "error: curl operation failed with error code 7.") + { + // old curl, this is OK! + } + else + { + // new curl + REQUIRE_THAT( + all_errors, + Catch::Matches("error: curl operation failed with error code 1\\. Protocol \"unknown\" not supported( or " + "disabled in libcurl)?\n" + "error: curl operation failed with error code 7\\. Failed to connect to localhost port 9 " + "after [0-9]+ ms: (Could not|Couldn't) connect to server", + Catch::CaseSensitive::Yes)); } } @@ -140,8 +275,8 @@ TEST_CASE ("try_parse_curl_progress_data", "[downloads]") .value_or_exit(VCPKG_LINE_INFO); REQUIRE(out.total_percent == 0); REQUIRE(out.total_size == 0); - REQUIRE(out.recieved_percent == 0); - REQUIRE(out.recieved_size == 0); + REQUIRE(out.received_percent == 0); + REQUIRE(out.received_size == 0); REQUIRE(out.transfer_percent == 0); REQUIRE(out.transfer_size == 0); REQUIRE(out.average_upload_speed == 0); @@ -155,8 +290,8 @@ TEST_CASE ("try_parse_curl_progress_data", "[downloads]") .value_or_exit(VCPKG_LINE_INFO); REQUIRE(out.total_percent == 2); REQUIRE(out.total_size == 190 * 1024 * 1024); - REQUIRE(out.recieved_percent == 2); - REQUIRE(out.recieved_size == 3935 * 1024); + REQUIRE(out.received_percent == 2); + REQUIRE(out.received_size == 3935 * 1024); REQUIRE(out.transfer_percent == 0); REQUIRE(out.transfer_size == 0); REQUIRE(out.average_upload_speed == 0); diff --git a/src/vcpkg-test/manifests.cpp b/src/vcpkg-test/manifests.cpp index bbb20e0712..9bb732a2b7 100644 --- a/src/vcpkg-test/manifests.cpp +++ b/src/vcpkg-test/manifests.cpp @@ -1326,14 +1326,14 @@ TEST_CASE ("license error messages", "[manifests][license]") ParseMessages messages; parse_spdx_license_expression("", messages); CHECK(messages.error.value_or_exit(VCPKG_LINE_INFO) == - LocalizedString::from_raw(R"(:1:1: error: SPDX license expression was empty. + LocalizedString::from_raw(R"(: error: SPDX license expression was empty. on expression: ^)")); parse_spdx_license_expression("MIT ()", messages); CHECK(messages.error.value_or_exit(VCPKG_LINE_INFO) == LocalizedString::from_raw( - R"(:1:5: error: Expected a compound or the end of the string, found a parenthesis. + R"(: error: Expected a compound or the end of the string, found a parenthesis. on expression: MIT () ^)")); @@ -1341,14 +1341,13 @@ TEST_CASE ("license error messages", "[manifests][license]") CHECK( messages.error.value_or_exit(VCPKG_LINE_INFO) == LocalizedString::from_raw( - R"(:1:5: error: SPDX license expression contains an extra '+'. These are only allowed directly after a license identifier. + R"(: error: SPDX license expression contains an extra '+'. These are only allowed directly after a license identifier. on expression: MIT + ^)")); parse_spdx_license_expression("MIT AND", messages); - CHECK( - messages.error.value_or_exit(VCPKG_LINE_INFO) == - LocalizedString::from_raw(R"(:1:8: error: Expected a license name, found the end of the string. + CHECK(messages.error.value_or_exit(VCPKG_LINE_INFO) == + LocalizedString::from_raw(R"(: error: Expected a license name, found the end of the string. on expression: MIT AND ^)")); @@ -1357,7 +1356,7 @@ TEST_CASE ("license error messages", "[manifests][license]") REQUIRE(messages.warnings.size() == 1); CHECK( test_format_parse_warning(messages.warnings[0]) == - R"(:1:9: warning: Unknown license identifier 'unknownlicense'. Known values are listed at https://spdx.org/licenses/ + R"(: warning: Unknown license identifier 'unknownlicense'. Known values are listed at https://spdx.org/licenses/ on expression: MIT AND unknownlicense ^)"); } diff --git a/src/vcpkg-test/messages.cpp b/src/vcpkg-test/messages.cpp index 842b354e08..c34a2e9bdf 100644 --- a/src/vcpkg-test/messages.cpp +++ b/src/vcpkg-test/messages.cpp @@ -1,5 +1,6 @@ #include +#include #include #include @@ -99,3 +100,387 @@ TEST_CASE ("generate message get_format_arg_mismatches", "[messages]") CHECK(res.arguments_without_comment == std::vector{"go", "ho"}); CHECK(res.comments_without_argument == std::vector{"blah"}); } + +namespace +{ + template + constexpr bool adapt_context_to_expected_invocable_with_impl = false; + + template + constexpr bool adapt_context_to_expected_invocable_with_impl< + std::void_t(), std::declval()...))>, + Test, + Args...> = true; + + template + constexpr bool adapt_context_to_expected_invocable_with = + adapt_context_to_expected_invocable_with_impl; + + static_assert(!adapt_context_to_expected_invocable_with, + "Callable needs to return optional or unique_ptr"); + + // The following tests are the cross product of: + // {prvalue, lvalue, xvalue} X {non-const, const} X {non-ref, ref} + + Optional returns_optional_prvalue(DiagnosticContext&, int val) { return val; } + static_assert(adapt_context_to_expected_invocable_with, "boom"); + static_assert(std::is_same_v, decltype(adapt_context_to_expected(returns_optional_prvalue, 42))>, + "boom"); + + const Optional returns_optional_const_prvalue(DiagnosticContext&, int val) { return val; } + static_assert(adapt_context_to_expected_invocable_with, "boom"); + static_assert( + std::is_same_v, decltype(adapt_context_to_expected(returns_optional_const_prvalue, 42))>, + "boom"); + + Optional& returns_optional_lvalue(DiagnosticContext&, Optional& val) { return val; } + static_assert(adapt_context_to_expected_invocable_with&>, "boom"); + static_assert( + std::is_same_v, + decltype(adapt_context_to_expected(returns_optional_lvalue, std::declval&>()))>, + "boom"); + + const Optional& returns_optional_const_lvalue(DiagnosticContext&, const Optional& val) { return val; } + static_assert( + adapt_context_to_expected_invocable_with&>, + "boom"); + static_assert(std::is_same_v, + decltype(adapt_context_to_expected(returns_optional_const_lvalue, + std::declval&>()))>, + "boom"); + + Optional&& returns_optional_xvalue(DiagnosticContext&, Optional&& val) { return std::move(val); } + static_assert(adapt_context_to_expected_invocable_with>, "boom"); + static_assert( + std::is_same_v, + decltype(adapt_context_to_expected(returns_optional_xvalue, std::declval>()))>, + "boom"); + + const Optional&& returns_optional_const_xvalue(DiagnosticContext&, Optional&& val) + { + return std::move(val); + } + static_assert(adapt_context_to_expected_invocable_with>, + "boom"); + static_assert(std::is_same_v, + decltype(adapt_context_to_expected(returns_optional_const_xvalue, + std::declval>()))>, + "boom"); + + Optional returns_optional_ref_prvalue(DiagnosticContext&, int& val) { return val; } + static_assert(adapt_context_to_expected_invocable_with, "boom"); + static_assert( + std::is_same_v, + decltype(adapt_context_to_expected(returns_optional_ref_prvalue, std::declval()))>, + "boom"); + + const Optional returns_optional_ref_const_prvalue(DiagnosticContext&, int& val) { return val; } + static_assert(adapt_context_to_expected_invocable_with, "boom"); + static_assert( + std::is_same_v, + decltype(adapt_context_to_expected(returns_optional_ref_const_prvalue, std::declval()))>, + "boom"); + + Optional& returns_optional_ref_lvalue(DiagnosticContext&, Optional& val) { return val; } + static_assert(adapt_context_to_expected_invocable_with&>, + "boom"); + static_assert(std::is_same_v, + decltype(adapt_context_to_expected(returns_optional_ref_lvalue, + std::declval&>()))>, + "boom"); + + const Optional& returns_optional_ref_const_lvalue(DiagnosticContext&, const Optional& val) + { + return val; + } + static_assert( + adapt_context_to_expected_invocable_with&>, + "boom"); + static_assert(std::is_same_v, + decltype(adapt_context_to_expected(returns_optional_ref_const_lvalue, + std::declval&>()))>, + "boom"); + + Optional&& returns_optional_ref_xvalue(DiagnosticContext&, Optional&& val) { return std::move(val); } + static_assert(adapt_context_to_expected_invocable_with>, + "boom"); + static_assert(std::is_same_v, + decltype(adapt_context_to_expected(returns_optional_ref_xvalue, + std::declval>()))>, + "boom"); + + const Optional&& returns_optional_ref_const_xvalue(DiagnosticContext&, Optional&& val) + { + return std::move(val); + } + static_assert(adapt_context_to_expected_invocable_with>, + "boom"); + static_assert(std::is_same_v, + decltype(adapt_context_to_expected(returns_optional_ref_const_xvalue, + std::declval>()))>, + "boom"); + + Optional returns_optional_fail(DiagnosticContext& context) + { + context.report({DiagKind::Error, LocalizedString::from_raw("something bad happened")}); + return nullopt; + } + + // The following tests are the cross product of: + // {prvalue, lvalue, xvalue} X {non-const, const} + std::unique_ptr returns_unique_ptr_prvalue(DiagnosticContext&, int val) + { + return std::unique_ptr{new int{val}}; + } + static_assert(adapt_context_to_expected_invocable_with, "boom"); + static_assert(std::is_same_v>, + decltype(adapt_context_to_expected(returns_unique_ptr_prvalue, 42))>, + "boom"); + + using returns_unique_ptr_const_prvalue_t = const std::unique_ptr (*)(DiagnosticContext&, int); + static_assert(!adapt_context_to_expected_invocable_with, "boom"); + + std::unique_ptr& returns_unique_ptr_lvalue(DiagnosticContext&, std::unique_ptr& ret) { return ret; } + static_assert(adapt_context_to_expected_invocable_with&>, + "boom"); + static_assert(std::is_same_v&>, + decltype(adapt_context_to_expected(returns_unique_ptr_lvalue, + std::declval&>()))>, + "boom"); + + const std::unique_ptr& returns_unique_ptr_const_lvalue(DiagnosticContext&, const std::unique_ptr& ret) + { + return ret; + } + static_assert(adapt_context_to_expected_invocable_with&>, + "boom"); + static_assert(std::is_same_v&>, + decltype(adapt_context_to_expected(returns_unique_ptr_const_lvalue, + std::declval&>()))>, + "boom"); + + std::unique_ptr&& returns_unique_ptr_xvalue(DiagnosticContext&, std::unique_ptr&& val) + { + return std::move(val); + } + static_assert(adapt_context_to_expected_invocable_with&&>, + "boom"); + static_assert(std::is_same_v>, + decltype(adapt_context_to_expected(returns_unique_ptr_xvalue, + std::declval>()))>, + "boom"); + + using returns_unique_ptr_const_xvalue_t = const std::unique_ptr && + (*)(DiagnosticContext&, const std::unique_ptr&&); + + static_assert( + !adapt_context_to_expected_invocable_with&&>, + "boom"); + + std::unique_ptr returns_unique_ptr_fail(DiagnosticContext& context) + { + context.report({DiagKind::Error, LocalizedString::from_raw("something bad happened")}); + return nullptr; + } + + struct CopyOnce + { + bool& m_copied; + + explicit CopyOnce(bool& copied) : m_copied(copied) { } + CopyOnce(const CopyOnce& other) : m_copied(other.m_copied) + { + REQUIRE(!m_copied); + m_copied = true; + } + + CopyOnce& operator=(const CopyOnce&) = delete; + }; + + struct MoveCounter + { + int& m_move_limit; + + explicit MoveCounter(int& move_limit) : m_move_limit(move_limit) { } + MoveCounter(const MoveCounter&) = delete; + MoveCounter(MoveCounter&& other) : m_move_limit(other.m_move_limit) + { + REQUIRE(m_move_limit > 0); + --m_move_limit; + } + + MoveCounter& operator=(const MoveCounter&) = delete; + MoveCounter& operator=(MoveCounter&&) = delete; + }; +} // unnamed namespace + +template +bool same_object(T& lhs, U& rhs) +{ + return &lhs == &rhs; +} + +TEST_CASE ("adapt DiagnosticContext to ExpectedL", "[diagnostics]") +{ + // returns_optional_prvalue + { + auto adapted = adapt_context_to_expected(returns_optional_prvalue, 42); + REQUIRE(adapted.value_or_exit(VCPKG_LINE_INFO) == 42); + } + { + int move_limit = 1; + auto adapted = adapt_context_to_expected( + [](DiagnosticContext&, int& move_limit) { + Optional ret; + ret.emplace(move_limit); + return ret; + }, + move_limit); + + REQUIRE(move_limit == 0); + } + // returns_optional_const_prvalue + { + auto adapted = adapt_context_to_expected(returns_optional_const_prvalue, 42); + REQUIRE(adapted.value_or_exit(VCPKG_LINE_INFO) == 42); + } + // returns_optional_lvalue + { + Optional the_lvalue = 42; + auto adapted = adapt_context_to_expected(returns_optional_lvalue, the_lvalue); + REQUIRE(same_object(adapted.value_or_exit(VCPKG_LINE_INFO), the_lvalue.value_or_exit(VCPKG_LINE_INFO))); + } + // returns_optional_const_lvalue + { + Optional the_lvalue = 42; + auto adapted = adapt_context_to_expected(returns_optional_const_lvalue, the_lvalue); + REQUIRE(same_object(adapted.value_or_exit(VCPKG_LINE_INFO), the_lvalue.value_or_exit(VCPKG_LINE_INFO))); + } + // returns_optional_xvalue + { + Optional an_lvalue = 42; + REQUIRE( + adapt_context_to_expected(returns_optional_xvalue, std::move(an_lvalue)).value_or_exit(VCPKG_LINE_INFO) == + 42); + } + { + int move_limit = 1; + Optional an_lvalue; + an_lvalue.emplace(move_limit); + auto adapted = adapt_context_to_expected( + [](DiagnosticContext&, Optional&& ret) -> Optional&& { return std::move(ret); }, + std::move(an_lvalue)); + + REQUIRE(move_limit == 0); + } + // returns_optional_const_xvalue + { + Optional an_lvalue = 42; + REQUIRE(adapt_context_to_expected(returns_optional_const_xvalue, std::move(an_lvalue)) + .value_or_exit(VCPKG_LINE_INFO) == 42); + } + { + bool copied = false; + Optional an_lvalue; + an_lvalue.emplace(copied); + auto adapted = adapt_context_to_expected( + [](DiagnosticContext&, const Optional&& ret) -> const Optional&& { + return std::move(ret); + }, + std::move(an_lvalue)); + + REQUIRE(copied); + } + // returns_optional_ref_prvalue + { + int the_lvalue = 42; + auto adapted = adapt_context_to_expected(returns_optional_ref_prvalue, the_lvalue); + REQUIRE(adapted.get() == &the_lvalue); + } + // returns_optional_ref_const_prvalue + { + int the_lvalue = 42; + auto adapted = adapt_context_to_expected(returns_optional_ref_const_prvalue, the_lvalue); + REQUIRE(adapted.get() == &the_lvalue); + } + // returns_optional_ref_lvalue + { + int the_inside_lvalue = 42; + Optional the_lvalue{the_inside_lvalue}; + auto adapted = adapt_context_to_expected(returns_optional_ref_lvalue, the_lvalue); + REQUIRE(adapted.get() == &the_inside_lvalue); + } + { + int move_limit = 0; + MoveCounter the_inside_lvalue{move_limit}; + Optional an_lvalue; + an_lvalue.emplace(the_inside_lvalue); + auto adapted = adapt_context_to_expected( + [](DiagnosticContext&, Optional&& ret) -> Optional { return std::move(ret); }, + std::move(an_lvalue)); + REQUIRE(adapted.get() == &the_inside_lvalue); + REQUIRE(move_limit == 0); + } + // returns_optional_ref_const_lvalue + { + int the_inside_lvalue = 42; + Optional the_lvalue{the_inside_lvalue}; + auto adapted = adapt_context_to_expected(returns_optional_ref_const_lvalue, the_lvalue); + REQUIRE(adapted.get() == &the_inside_lvalue); + } + // returns_optional_ref_xvalue + { + int the_inside_lvalue = 42; + Optional the_lvalue{the_inside_lvalue}; + auto adapted = adapt_context_to_expected(returns_optional_ref_xvalue, std::move(the_lvalue)); + REQUIRE(adapted.get() == &the_inside_lvalue); + } + // returns_optional_ref_const_xvalue + { + int the_inside_lvalue = 42; + Optional the_lvalue{the_inside_lvalue}; + auto adapted = adapt_context_to_expected(returns_optional_ref_const_xvalue, std::move(the_lvalue)); + REQUIRE(adapted.get() == &the_inside_lvalue); + } + + // returns_optional_prvalue_fail + { + auto adapted = adapt_context_to_expected(returns_optional_fail); + REQUIRE(!adapted.has_value()); + REQUIRE(adapted.error() == LocalizedString::from_raw("error: something bad happened")); + } + + // returns_unique_ptr_prvalue + { + auto adapted = adapt_context_to_expected(returns_unique_ptr_prvalue, 42); + REQUIRE(*(adapted.value_or_exit(VCPKG_LINE_INFO)) == 42); + } + // returns_unique_ptr_lvalue + { + auto an_lvalue = std::make_unique(42); + auto adapted = adapt_context_to_expected(returns_unique_ptr_lvalue, an_lvalue); + REQUIRE(same_object(adapted.value_or_exit(VCPKG_LINE_INFO), an_lvalue)); + } + // returns_unique_ptr_const_lvalue + { + auto an_lvalue = std::make_unique(42); + auto adapted = adapt_context_to_expected(returns_unique_ptr_const_lvalue, an_lvalue); + REQUIRE(same_object(adapted.value_or_exit(VCPKG_LINE_INFO), an_lvalue)); + } + // returns_unique_ptr_xvalue + { + auto an_lvalue = std::make_unique(42); + auto the_pointer = an_lvalue.get(); + auto adapted = adapt_context_to_expected(returns_unique_ptr_xvalue, std::move(an_lvalue)); + REQUIRE(!an_lvalue); // was moved into the adapted + REQUIRE(adapted.value_or_exit(VCPKG_LINE_INFO).get() == the_pointer); + } + + // returns_unique_ptr_fail + { + auto adapted = adapt_context_to_expected(returns_unique_ptr_fail); + REQUIRE(!adapted.has_value()); + REQUIRE(adapted.error() == LocalizedString::from_raw("error: something bad happened")); + } +} diff --git a/src/vcpkg-test/registries.cpp b/src/vcpkg-test/registries.cpp index 9525588415..75a9443d07 100644 --- a/src/vcpkg-test/registries.cpp +++ b/src/vcpkg-test/registries.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include using namespace vcpkg; @@ -276,7 +276,7 @@ static vcpkg::Optional visit_default_registry(Json::Reader& r, Js { Json::Object config; config.insert("default-registry", std::move(reg)); - return r.visit(config, get_configuration_deserializer()); + return configuration_deserializer.visit(r, config); } TEST_CASE ("registry_parsing", "[registries]") @@ -428,7 +428,7 @@ TEST_CASE ("registries report pattern errors", "[registries]") })json"); Json::Reader r{"test"}; - auto maybe_conf = r.visit(test_json, get_configuration_deserializer()); + auto maybe_conf = configuration_deserializer.visit(r, test_json); const auto& errors = r.errors(); CHECK(!errors.empty()); REQUIRE(errors.size() == 3); @@ -474,7 +474,7 @@ TEST_CASE ("registries ignored patterns warning", "[registries]") })json"); Json::Reader r{"test"}; - auto maybe_conf = r.visit(test_json, get_configuration_deserializer()); + auto maybe_conf = configuration_deserializer.visit(r, test_json); auto conf = maybe_conf.get(); REQUIRE(conf); @@ -550,7 +550,6 @@ TEST_CASE ("registries ignored patterns warning", "[registries]") TEST_CASE ("git_version_db_parsing", "[registries]") { - auto filesystem_version_db = make_git_version_db_deserializer(); Json::Reader r{"test"}; auto test_json = parse_json(R"json( [ @@ -572,7 +571,7 @@ TEST_CASE ("git_version_db_parsing", "[registries]") ] )json"); - auto results_opt = r.visit(test_json, *filesystem_version_db); + auto results_opt = GitVersionDbEntryArrayDeserializer().visit(r, test_json); auto& results = results_opt.value_or_exit(VCPKG_LINE_INFO); CHECK(results[0].version == SchemedVersion{VersionScheme::Date, {"2021-06-26", 0}}); CHECK(results[0].git_tree == "9b07f8a38bbc4d13f8411921e6734753e15f8d50"); @@ -585,7 +584,7 @@ TEST_CASE ("git_version_db_parsing", "[registries]") TEST_CASE ("filesystem_version_db_parsing", "[registries]") { - auto filesystem_version_db = make_filesystem_version_db_deserializer("a/b"); + FilesystemVersionDbEntryArrayDeserializer filesystem_version_db("a/b"); { Json::Reader r{"test"}; @@ -608,7 +607,7 @@ TEST_CASE ("filesystem_version_db_parsing", "[registries]") } ] )json"); - auto results_opt = r.visit(test_json, *filesystem_version_db); + auto results_opt = filesystem_version_db.visit(r, test_json); auto& results = results_opt.value_or_exit(VCPKG_LINE_INFO); CHECK(results[0].version == SchemedVersion{VersionScheme::String, {"puppies", 0}}); CHECK(results[0].p == "a/b" VCPKG_PREFERRED_SEPARATOR "c/d"); @@ -630,7 +629,7 @@ TEST_CASE ("filesystem_version_db_parsing", "[registries]") } ] )json"); - CHECK(r.visit(test_json, *filesystem_version_db).value_or_exit(VCPKG_LINE_INFO).empty()); + CHECK(filesystem_version_db.visit(r, test_json).value_or_exit(VCPKG_LINE_INFO).empty()); CHECK(!r.errors().empty()); } @@ -645,7 +644,7 @@ TEST_CASE ("filesystem_version_db_parsing", "[registries]") } ] )json"); - CHECK(r.visit(test_json, *filesystem_version_db).value_or_exit(VCPKG_LINE_INFO).empty()); + CHECK(filesystem_version_db.visit(r, test_json).value_or_exit(VCPKG_LINE_INFO).empty()); CHECK(!r.errors().empty()); } @@ -660,7 +659,7 @@ TEST_CASE ("filesystem_version_db_parsing", "[registries]") } ] )json"); - CHECK(r.visit(test_json, *filesystem_version_db).value_or_exit(VCPKG_LINE_INFO).empty()); + CHECK(filesystem_version_db.visit(r, test_json).value_or_exit(VCPKG_LINE_INFO).empty()); CHECK(!r.errors().empty()); } @@ -675,7 +674,7 @@ TEST_CASE ("filesystem_version_db_parsing", "[registries]") } ] )json"); - CHECK(r.visit(test_json, *filesystem_version_db).value_or_exit(VCPKG_LINE_INFO).empty()); + CHECK(filesystem_version_db.visit(r, test_json).value_or_exit(VCPKG_LINE_INFO).empty()); CHECK(!r.errors().empty()); } @@ -690,7 +689,7 @@ TEST_CASE ("filesystem_version_db_parsing", "[registries]") } ] )json"); - CHECK(r.visit(test_json, *filesystem_version_db).value_or_exit(VCPKG_LINE_INFO).empty()); + CHECK(filesystem_version_db.visit(r, test_json).value_or_exit(VCPKG_LINE_INFO).empty()); CHECK(!r.errors().empty()); } @@ -705,7 +704,7 @@ TEST_CASE ("filesystem_version_db_parsing", "[registries]") } ] )json"); - CHECK(r.visit(test_json, *filesystem_version_db).value_or_exit(VCPKG_LINE_INFO).empty()); + CHECK(filesystem_version_db.visit(r, test_json).value_or_exit(VCPKG_LINE_INFO).empty()); CHECK(!r.errors().empty()); } @@ -720,7 +719,7 @@ TEST_CASE ("filesystem_version_db_parsing", "[registries]") } ] )json"); - CHECK(r.visit(test_json, *filesystem_version_db).value_or_exit(VCPKG_LINE_INFO).empty()); + CHECK(filesystem_version_db.visit(r, test_json).value_or_exit(VCPKG_LINE_INFO).empty()); CHECK(!r.errors().empty()); } @@ -735,7 +734,7 @@ TEST_CASE ("filesystem_version_db_parsing", "[registries]") } ] )json"); - CHECK(r.visit(test_json, *filesystem_version_db).value_or_exit(VCPKG_LINE_INFO).empty()); + CHECK(filesystem_version_db.visit(r, test_json).value_or_exit(VCPKG_LINE_INFO).empty()); CHECK(!r.errors().empty()); } @@ -750,7 +749,7 @@ TEST_CASE ("filesystem_version_db_parsing", "[registries]") } ] )json"); - CHECK(r.visit(test_json, *filesystem_version_db).value_or_exit(VCPKG_LINE_INFO).empty()); + CHECK(filesystem_version_db.visit(r, test_json).value_or_exit(VCPKG_LINE_INFO).empty()); CHECK(!r.errors().empty()); } } diff --git a/src/vcpkg-test/spdx.cpp b/src/vcpkg-test/spdx.cpp index b6da7cfdce..73d0a59c4f 100644 --- a/src/vcpkg-test/spdx.cpp +++ b/src/vcpkg-test/spdx.cpp @@ -5,6 +5,99 @@ using namespace vcpkg; +TEST_CASE ("replace CMake variable", "[spdx]") +{ + static constexpr StringLiteral str{"lorem ip${VERSION}"}; + { + auto res = replace_cmake_var(str, "VERSION", "sum"); + REQUIRE(res == "lorem ipsum"); + } + { + auto res = replace_cmake_var(str, "VERSiON", "sum"); + REQUIRE(res == "lorem ip${VERSION}"); + } +} + +TEST_CASE ("extract first cmake invocation args", "[spdx]") +{ + { + auto res = extract_first_cmake_invocation_args("lorem_ipsum()", "lorem_ipsum"); + REQUIRE(res.empty()); + } + { + auto res = extract_first_cmake_invocation_args("lorem_ipsummmmm() lorem_ipsum(asdf)", "lorem_ipsum"); + REQUIRE(res == "asdf"); + } + { + auto res = extract_first_cmake_invocation_args("lorem_ipsum(abc)", "lorem_ipsu"); + REQUIRE(res.empty()); + } + { + auto res = extract_first_cmake_invocation_args("lorem_ipsum(abc", "lorem_ipsum"); + REQUIRE(res.empty()); + } + { + auto res = extract_first_cmake_invocation_args("lorem_ipsum (abc) ", "lorem_ipsum"); + REQUIRE(res == "abc"); + } + { + auto res = extract_first_cmake_invocation_args("lorem_ipsum x (abc) ", "lorem_ipsum"); + REQUIRE(res.empty()); + } + { + auto res = extract_first_cmake_invocation_args("lorem_ipum(abc)", "lorem_ipsum"); + REQUIRE(res.empty()); + } + { + auto res = extract_first_cmake_invocation_args("lorem_ipsum( )", "lorem_ipsum"); + REQUIRE(res == " "); + } + { + auto res = extract_first_cmake_invocation_args("lorem_ipsum_", "lorem_ipsum"); + REQUIRE(res.empty()); + } +} + +TEST_CASE ("extract arg from cmake invocation args", "[spdx]") +{ + { + auto res = extract_arg_from_cmake_invocation_args("loremipsum", "lorem"); + REQUIRE(res.empty()); + } + { + auto res = extract_arg_from_cmake_invocation_args("loremipsum lorem value", "lorem"); + REQUIRE(res == "value"); + } + { + auto res = extract_arg_from_cmake_invocation_args("loremipsum lorem value ", "lorem"); + REQUIRE(res == "value"); + } + { + auto res = extract_arg_from_cmake_invocation_args("lorem", "lorem"); + REQUIRE(res.empty()); + } + { + auto res = extract_arg_from_cmake_invocation_args("lorem \"", "lorem"); + REQUIRE(res.empty()); + } + { + auto res = extract_arg_from_cmake_invocation_args("lorem ", "lorem"); + REQUIRE(res.empty()); + } + { + auto res = extract_arg_from_cmake_invocation_args("lorem ipsum", "lorem"); + REQUIRE(res == "ipsum"); + } + { + auto res = extract_arg_from_cmake_invocation_args("lorem \"ipsum", "lorem"); + REQUIRE(res.empty()); + } + { + auto res = extract_arg_from_cmake_invocation_args("lorem \"ipsum\"", "lorem"); + REQUIRE(res == "ipsum"); + } +} + TEST_CASE ("spdx maximum serialization", "[spdx]") { PackageSpec spec{"zlib", Test::ARM_UWP}; diff --git a/src/vcpkg-test/strings.cpp b/src/vcpkg-test/strings.cpp index de6a284db9..da40928906 100644 --- a/src/vcpkg-test/strings.cpp +++ b/src/vcpkg-test/strings.cpp @@ -69,6 +69,14 @@ TEST_CASE ("find_first_of", "[strings]") REQUIRE(find_first_of("abcdefg", "gb") == std::string("bcdefg")); } +TEST_CASE ("find_last", "[strings]") +{ + using vcpkg::Strings::find_last; + REQUIRE(find_last("abcdefgabcdefg", 'a') == 7); + REQUIRE(find_last("abcdefgabcdefg", 'g') == 13); + REQUIRE(find_last("abcdefgabcdefg", 'z') == std::string::npos); +} + TEST_CASE ("contains_any_ignoring_c_comments", "[strings]") { using Strings::contains_any_ignoring_c_comments; @@ -204,36 +212,62 @@ TEST_CASE ("inplace_replace_all(char)", "[strings]") TEST_CASE ("api_stable_format(sv,append_f)", "[strings]") { - std::string target; - auto res = api_stable_format("{", [](std::string&, StringView) { CHECK(false); }); - REQUIRE(!res.has_value()); - res = api_stable_format("}", [](std::string&, StringView) { CHECK(false); }); - REQUIRE(!res.has_value()); - res = api_stable_format("{ {", [](std::string&, StringView) { CHECK(false); }); - REQUIRE(!res.has_value()); - res = api_stable_format("{ {}", [](std::string&, StringView) { CHECK(false); }); - REQUIRE(!res.has_value()); - - res = api_stable_format("}}", [](std::string&, StringView) { CHECK(false); }); - REQUIRE(*res.get() == "}"); - res = api_stable_format("{{", [](std::string&, StringView) { CHECK(false); }); - REQUIRE(*res.get() == "{"); - - res = api_stable_format("{x}{y}{z}", [](std::string& out, StringView t) { - CHECK((t == "x" || t == "y" || t == "z")); - Strings::append(out, t, t); - }); - REQUIRE(*res.get() == "xxyyzz"); - res = api_stable_format("{x}}}", [](std::string& out, StringView t) { - CHECK(t == "x"); - Strings::append(out, "hello"); - }); - REQUIRE(*res.get() == "hello}"); - res = api_stable_format("123{x}456", [](std::string& out, StringView t) { - CHECK(t == "x"); - Strings::append(out, "hello"); - }); - REQUIRE(*res.get() == "123hello456"); + for (auto&& invalid_format_string : {"{", "}", "{ {", "{ {}"}) + { + FullyBufferedDiagnosticContext bdc_invalid{}; + auto res = api_stable_format(bdc_invalid, invalid_format_string, [](std::string&, StringView) { + CHECK(false); + return true; + }); + REQUIRE(bdc_invalid.to_string() == fmt::format("error: invalid format string: {}", invalid_format_string)); + } + + FullyBufferedDiagnosticContext bdc{}; + { + auto res = api_stable_format(bdc, "}}", [](std::string&, StringView) { + CHECK(false); + return true; + }); + REQUIRE(bdc.empty()); + REQUIRE(res.value_or_exit(VCPKG_LINE_INFO) == "}"); + } + { + auto res = api_stable_format(bdc, "{{", [](std::string&, StringView) { + CHECK(false); + return true; + }); + REQUIRE(bdc.empty()); + REQUIRE(res.value_or_exit(VCPKG_LINE_INFO) == "{"); + } + { + auto res = api_stable_format(bdc, "{x}{y}{z}", [](std::string& out, StringView t) { + CHECK((t == "x" || t == "y" || t == "z")); + Strings::append(out, t, t); + return true; + }); + REQUIRE(bdc.empty()); + REQUIRE(res.value_or_exit(VCPKG_LINE_INFO) == "xxyyzz"); + } + { + auto res = api_stable_format(bdc, "{x}}}", [](std::string& out, StringView t) { + CHECK(t == "x"); + Strings::append(out, "hello"); + return true; + }); + + REQUIRE(bdc.empty()); + REQUIRE(res.value_or_exit(VCPKG_LINE_INFO) == "hello}"); + } + { + auto res = api_stable_format(bdc, "123{x}456", [](std::string& out, StringView t) { + CHECK(t == "x"); + Strings::append(out, "hello"); + return true; + }); + + REQUIRE(bdc.empty()); + REQUIRE(res.value_or_exit(VCPKG_LINE_INFO) == "123hello456"); + } } TEST_CASE ("lex compare less", "[strings]") diff --git a/src/vcpkg-test/system.cpp b/src/vcpkg-test/system.cpp index 4d0e771d87..9e50027d0c 100644 --- a/src/vcpkg-test/system.cpp +++ b/src/vcpkg-test/system.cpp @@ -78,7 +78,7 @@ TEST_CASE ("from_cpu_architecture", "[system]") for (auto&& instance : test_cases) { - CHECK(to_zstring_view(instance.input) == instance.expected); + CHECK(to_string_literal(instance.input) == instance.expected); } } diff --git a/src/vcpkg-test/tools.cpp b/src/vcpkg-test/tools.cpp index 431309af4c..a67d7da8e8 100644 --- a/src/vcpkg-test/tools.cpp +++ b/src/vcpkg-test/tools.cpp @@ -1,5 +1,7 @@ #include +#include + #include #include @@ -24,7 +26,7 @@ CMake suite maintained and supported by Kitware (kitware.com/cmake).)"); REQUIRE(result.has_value()); CHECK(*result.get() == std::array{3, 22, 2}); - result = parse_tool_version_string(R"(aria2 version 1.35.0 + result = parse_tool_version_string(R"(example version 1.35.0 Copyright (C) 2006, 2019 Tatsuhiro Tsujikawa)"); REQUIRE(result.has_value()); CHECK(*result.get() == std::array{1, 35, 0}); @@ -41,81 +43,6 @@ Copyright (C) 2006, 2019 Tatsuhiro Tsujikawa)"); CHECK_FALSE(result.has_value()); } -TEST_CASE ("parse_tool_data_from_xml", "[tools]") -{ - const StringView tool_doc = R"( - - - - 2.7.4 - - - - - - 5.11.0 - nuget.exe - https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe - 06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9ebfda83b64c03ce14c8f35ca9957a17a8c02b8c4b7 - - - 16.12.0 - node-v16.12.0-win-x64\node.exe - https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z - 0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023fb7068ed1f8a7678e446260c3db3537fa888 - node-v16.12.0-win-x64.7z - - -)"; - - { - auto data = parse_tool_data_from_xml(tool_doc, "vcpkgTools.xml", "tool1", "windows"); - REQUIRE(!data.has_value()); - } - { - auto data = parse_tool_data_from_xml(tool_doc, "vcpkgTools.xml", "node", "unknown"); - REQUIRE(!data.has_value()); - } - { - auto data = parse_tool_data_from_xml(tool_doc, "vcpkgTools.xml", "node", "windows"); - REQUIRE(data.has_value()); - auto& p = *data.get(); - CHECK(p.is_archive); - CHECK(p.version == decltype(p.version){16, 12, 0}); - CHECK(p.tool_dir_subpath == "node-16.12.0-windows"); - CHECK(p.exe_subpath == "node-v16.12.0-win-x64\\node.exe"); - CHECK(p.download_subpath == "node-v16.12.0-win-x64.7z"); - CHECK(p.sha512 == "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023" - "fb7068ed1f8a7678e446260c3db3537fa888"); - CHECK(p.url == "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z"); - } - { - auto data = parse_tool_data_from_xml(tool_doc, "vcpkgTools.xml", "nuget", "osx"); - REQUIRE(data.has_value()); - auto& p = *data.get(); - CHECK_FALSE(p.is_archive); - CHECK(p.version == decltype(p.version){5, 11, 0}); - CHECK(p.tool_dir_subpath == "nuget-5.11.0-osx"); - CHECK(p.exe_subpath == "nuget.exe"); - CHECK(p.download_subpath == "06a337c9-nuget.exe"); - CHECK(p.sha512 == "06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9ebfda8" - "3b64c03ce14c8f35ca9957a17a8c02b8c4b7"); - CHECK(p.url == "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe"); - } - { - auto data = parse_tool_data_from_xml(tool_doc, "vcpkgTools.xml", "git", "linux"); - REQUIRE(data.has_value()); - auto& p = *data.get(); - CHECK_FALSE(p.is_archive); - CHECK(p.version == decltype(p.version){2, 7, 4}); - CHECK(p.tool_dir_subpath == "git-2.7.4-linux"); - CHECK(p.exe_subpath == ""); - CHECK(p.download_subpath == ""); - CHECK(p.sha512 == ""); - CHECK(p.url == ""); - } -} - TEST_CASE ("extract_prefixed_nonwhitespace", "[tools]") { CHECK(extract_prefixed_nonwhitespace("fooutil version ", "fooutil", "fooutil version 1.2", "fooutil.exe") @@ -140,3 +67,240 @@ TEST_CASE ("extract_prefixed_nonquote", "[tools]") CHECK(error_result.error() == "error: fooutil (fooutil.exe) produced unexpected output when attempting to " "determine the version:\nmalformed output"); } + +TEST_CASE ("parse_tool_data", "[tools]") +{ + const StringView tool_doc = R"( +{ + "$comment": "This is a comment", + "schema-version": 1, + "tools": [ + { + "$comment": "This is a comment", + "name": "git", + "os": "linux", + "version": "2.7.4", + "executable": "git" + }, + { + "name": "git", + "os": "linux", + "arch": "arm64", + "version": "2.7.4", + "executable": "git-arm64" + }, + { + "name": "nuget", + "os": "osx", + "version": "5.11.0", + "executable": "nuget.exe", + "url": "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe", + "sha512": "06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9ebfda83b64c03ce14c8f35ca9957a17a8c02b8c4b7" + }, + { + "name": "node", + "os": "windows", + "version": "node version 16.12.0.windows.2", + "executable": "node-v16.12.0-win-x64\\node.exe", + "url": "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z", + "sha512": "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023fb7068ed1f8a7678e446260c3db3537fa888", + "archive": "node-v16.12.0-win-x64.7z" + } + ] +})"; + + auto maybe_data = parse_tool_data(tool_doc, "vcpkgTools.json"); + REQUIRE(maybe_data.has_value()); + + auto data = maybe_data.value_or_exit(VCPKG_LINE_INFO); + REQUIRE(data.size() == 4); + + auto& git_linux = data[0]; + CHECK(git_linux.tool == "git"); + CHECK(git_linux.os == ToolOs::Linux); + CHECK_FALSE(git_linux.arch.has_value()); + CHECK(git_linux.version.cooked == std::array{2, 7, 4}); + CHECK(git_linux.version.raw == "2.7.4"); + CHECK(git_linux.exeRelativePath == "git"); + CHECK(git_linux.url == ""); + CHECK(git_linux.sha512 == ""); + + auto& git_arm64 = data[1]; + CHECK(git_arm64.tool == "git"); + CHECK(git_arm64.os == ToolOs::Linux); + CHECK(git_arm64.arch.has_value()); + CHECK(*git_arm64.arch.get() == CPUArchitecture::ARM64); + CHECK(git_linux.version.cooked == std::array{2, 7, 4}); + CHECK(git_linux.version.raw == "2.7.4"); + CHECK(git_arm64.exeRelativePath == "git-arm64"); + CHECK(git_arm64.url == ""); + CHECK(git_arm64.sha512 == ""); + + auto& nuget_osx = data[2]; + CHECK(nuget_osx.tool == "nuget"); + CHECK(nuget_osx.os == ToolOs::Osx); + CHECK_FALSE(nuget_osx.arch.has_value()); + CHECK(nuget_osx.version.cooked == std::array{5, 11, 0}); + CHECK(nuget_osx.version.raw == "5.11.0"); + CHECK(nuget_osx.exeRelativePath == "nuget.exe"); + CHECK(nuget_osx.url == "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe"); + CHECK(nuget_osx.sha512 == "06a337c9404dec392709834ef2cdbdce611e104b510ef40201849595d46d242151749aef65bc2d7ce5ade9eb" + "fda83b64c03ce14c8f35ca9957a17a8c02b8c4b7"); + + auto& node_windows = data[3]; + CHECK(node_windows.tool == "node"); + CHECK(node_windows.os == ToolOs::Windows); + CHECK_FALSE(node_windows.arch.has_value()); + CHECK(node_windows.version.cooked == std::array{16, 12, 0}); + CHECK(node_windows.version.raw == "node version 16.12.0.windows.2"); + CHECK(node_windows.exeRelativePath == "node-v16.12.0-win-x64\\node.exe"); + CHECK(node_windows.url == "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z"); + CHECK(node_windows.sha512 == + "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023" + "fb7068ed1f8a7678e446260c3db3537fa888"); + CHECK(node_windows.archiveName == "node-v16.12.0-win-x64.7z"); + + auto* tool_git_linux = get_raw_tool_data(data, "git", CPUArchitecture::X64, ToolOs::Linux); + REQUIRE(tool_git_linux != nullptr); + CHECK(tool_git_linux->tool == "git"); + CHECK(tool_git_linux->os == ToolOs::Linux); + CHECK_FALSE(tool_git_linux->arch.has_value()); + CHECK(tool_git_linux->version.cooked == std::array{2, 7, 4}); + CHECK(tool_git_linux->version.raw == "2.7.4"); + CHECK(tool_git_linux->exeRelativePath == "git"); + CHECK(tool_git_linux->url == ""); + CHECK(tool_git_linux->sha512 == ""); + + auto* tool_git_arm64 = get_raw_tool_data(data, "git", CPUArchitecture::ARM64, ToolOs::Linux); + REQUIRE(tool_git_arm64 != nullptr); + CHECK(tool_git_arm64->tool == "git"); + CHECK(tool_git_arm64->os == ToolOs::Linux); + CHECK(tool_git_arm64->arch.has_value()); + CHECK(*tool_git_arm64->arch.get() == CPUArchitecture::ARM64); + CHECK(tool_git_arm64->version.cooked == std::array{2, 7, 4}); + CHECK(tool_git_arm64->version.raw == "2.7.4"); + CHECK(tool_git_arm64->exeRelativePath == "git-arm64"); + CHECK(tool_git_arm64->url == ""); + CHECK(tool_git_arm64->sha512 == ""); + + auto* tool_nuget_osx = get_raw_tool_data(data, "nuget", CPUArchitecture::X64, ToolOs::Osx); + REQUIRE(tool_nuget_osx != nullptr); + CHECK(tool_nuget_osx->tool == "nuget"); + CHECK(tool_nuget_osx->os == ToolOs::Osx); + CHECK_FALSE(tool_nuget_osx->arch.has_value()); + CHECK(tool_nuget_osx->version.cooked == std::array{5, 11, 0}); + CHECK(tool_nuget_osx->version.raw == "5.11.0"); + CHECK(tool_nuget_osx->exeRelativePath == "nuget.exe"); + CHECK(tool_nuget_osx->url == "https://dist.nuget.org/win-x86-commandline/v5.11.0/nuget.exe"); + + auto* tool_node_windows = get_raw_tool_data(data, "node", CPUArchitecture::X64, ToolOs::Windows); + REQUIRE(tool_node_windows != nullptr); + CHECK(tool_node_windows->tool == "node"); + CHECK(tool_node_windows->os == ToolOs::Windows); + CHECK_FALSE(tool_node_windows->arch.has_value()); + CHECK(tool_node_windows->version.cooked == std::array{16, 12, 0}); + CHECK(tool_node_windows->version.raw == "node version 16.12.0.windows.2"); + CHECK(tool_node_windows->exeRelativePath == "node-v16.12.0-win-x64\\node.exe"); + CHECK(tool_node_windows->url == "https://nodejs.org/dist/v16.12.0/node-v16.12.0-win-x64.7z"); + CHECK(tool_node_windows->sha512 == + "0bb793fce8140bd59c17f3ac9661b062eac0f611d704117774f5cb2453d717da94b1e8b17d021d47baff598dc023" + "fb7068ed1f8a7678e446260c3db3537fa888"); + CHECK(tool_node_windows->archiveName == "node-v16.12.0-win-x64.7z"); +} + +TEST_CASE ("parse_tool_data errors", "[tools]") +{ + auto empty = parse_tool_data("", "empty.json"); + REQUIRE(!empty.has_value()); + CHECK(Strings::starts_with(empty.error(), "empty.json:1:1: error: Unexpected EOF")); + + auto top_level_json = parse_tool_data("[]", "top_level.json"); + REQUIRE(!top_level_json.has_value()); + CHECK("Expected \"top_level.json\" to be an object." == top_level_json.error()); + + auto missing_required = + parse_tool_data(R"({ "schema-version": 1, "tools": [{ "executable": "git.exe" }]})", "missing_required.json"); + REQUIRE(!missing_required.has_value()); + CHECK("missing_required.json: error: $.tools[0] (tool metadata): missing required field 'name' (a string)\n" + "missing_required.json: error: $.tools[0] (tool metadata): missing required field 'os' (a tool data " + "operating system)\n" + "missing_required.json: error: $.tools[0] (tool metadata): missing required field 'version' (a tool data " + "version)" == missing_required.error()); + + auto uexpected_field = parse_tool_data(R"( +{ + "schema-version": 1, + "tools": [{ + "name": "git", + "os": "linux", + "version": "2.7.4", + "arc": "x64" + }] +})", + "uexpected_field.json"); + REQUIRE(!uexpected_field.has_value()); + CHECK("uexpected_field.json: error: $.tools[0] (tool metadata): unexpected field 'arc', did you mean 'arch'?" == + uexpected_field.error()); + + auto invalid_os = parse_tool_data(R"( +{ + "schema-version": 1, + "tools": [{ + "name": "git", + "os": "notanos", + "version": "2.7.4" + }] +})", + "invalid_os.json"); + REQUIRE(!invalid_os.has_value()); + CHECK( + "invalid_os.json: error: $.tools[0].os (a tool data operating system): Invalid tool operating system: notanos. " + "Expected one of: windows, osx, linux, freebsd, openbsd" == invalid_os.error()); + + auto invalid_version = parse_tool_data(R"( +{ + "schema-version": 1, + "tools": [{ + "name": "git", + "os": "windows", + "version": "abc" + }] +})", + "invalid_version.json"); + REQUIRE(!invalid_version.has_value()); + CHECK("invalid_version.json: error: $.tools[0].version (a tool data version): Invalid tool version; expected a " + "string containing a substring of between 1 and 3 numbers separated by dots." == invalid_version.error()); + + auto invalid_arch = parse_tool_data(R"( +{ + "schema-version": 1, + "tools": [{ + "name": "git", + "os": "linux", + "version": "2.7.4", + "arch": "notanarchitecture" + }] +})", + "invalid_arch.json"); + REQUIRE(!invalid_arch.has_value()); + CHECK("invalid_arch.json: error: $.tools[0].arch (a CPU architecture): Invalid architecture: notanarchitecture. " + "Expected one of: x86, x64, amd64, arm, arm64, arm64ec, s390x, ppc64le, riscv32, riscv64, loongarch32, " + "loongarch64, mips64" == invalid_arch.error()); + + auto invalid_sha512 = parse_tool_data(R"( +{ + "schema-version": 1, + "tools": [{ + "name": "git", + "os": "linux", + "version": "2.7.4", + "executable": "git", + "sha512": "notasha512" + }] +})", + "invalid_sha512.json"); + + REQUIRE(!invalid_sha512.has_value()); + CHECK("invalid_sha512.json: error: $.tools[0].sha512 (a SHA-512 hash): invalid SHA-512 hash: notasha512\n" + "SHA-512 hash must be 128 characters long and contain only hexadecimal digits" == invalid_sha512.error()); +} diff --git a/src/vcpkg-test/util.cpp b/src/vcpkg-test/util.cpp index 79a1e94504..a419f4ab2f 100644 --- a/src/vcpkg-test/util.cpp +++ b/src/vcpkg-test/util.cpp @@ -128,7 +128,7 @@ namespace vcpkg::Test std::vector parse_test_fspecs(StringView sv) { std::vector ret; - ParserBase parser(sv, "test"); + ParserBase parser(sv, "test", {0, 0}); while (!parser.at_eof()) { auto maybe_opt = parse_qualified_specifier( diff --git a/src/vcpkg.cpp b/src/vcpkg.cpp index 8b71440aa9..8691c5022d 100644 --- a/src/vcpkg.cpp +++ b/src/vcpkg.cpp @@ -93,6 +93,21 @@ namespace return false; } + template + static const CommandRegistrationKind* choose_command(const std::string& command_name, + View command_registrations) + { + for (const auto& command_registration : command_registrations) + { + if (Strings::case_insensitive_ascii_equals(command_registration.metadata.name, command_name)) + { + return &command_registration; + } + } + + return nullptr; + } + void inner(const Filesystem& fs, const VcpkgCmdArguments& args, const BundleSettings& bundle) { // track version on each invocation @@ -104,24 +119,9 @@ namespace Checks::exit_fail(VCPKG_LINE_INFO); } - static const auto find_command = [&](auto&& commands) { - auto it = Util::find_if(commands, [&](auto&& commandc) { - return Strings::case_insensitive_ascii_equals(commandc.metadata.name, args.get_command()); - }); - using std::end; - if (it != end(commands)) - { - return &*it; - } - else - { - return static_cast(nullptr); - } - }; - get_global_metrics_collector().track_bool(BoolMetric::DetectedContainer, detect_container(fs)); - if (const auto command_function = find_command(basic_commands)) + if (const auto command_function = choose_command(args.get_command(), basic_commands)) { get_global_metrics_collector().track_string(StringMetric::CommandName, command_function->metadata.name); return command_function->function(args, fs); @@ -133,7 +133,7 @@ namespace fs.current_path(paths.root, VCPKG_LINE_INFO); - if (const auto command_function = find_command(paths_commands)) + if (const auto command_function = choose_command(args.get_command(), paths_commands)) { get_global_metrics_collector().track_string(StringMetric::CommandName, command_function->metadata.name); return command_function->function(args, paths); @@ -141,7 +141,7 @@ namespace Triplet default_triplet = vcpkg::default_triplet(args, paths.get_triplet_db()); Triplet host_triplet = vcpkg::default_host_triplet(args, paths.get_triplet_db()); - if (const auto command_function = find_command(triplet_commands)) + if (const auto command_function = choose_command(args.get_command(), triplet_commands)) { get_global_metrics_collector().track_string(StringMetric::CommandName, command_function->metadata.name); return command_function->function(args, paths, default_triplet, host_triplet); @@ -270,7 +270,7 @@ int main(const int argc, const char* const* const argv) register_console_ctrl_handler(); -#if (defined(__aarch64__) || defined(__arm__) || defined(__s390x__) || defined(__riscv) || \ +#if (defined(__arm__) || defined(__s390x__) || defined(__riscv) || \ ((defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) && \ defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) || \ defined(_M_ARM) || defined(_M_ARM64)) && \ diff --git a/src/vcpkg/archives.cpp b/src/vcpkg/archives.cpp index 0aee082352..802d6b3f22 100644 --- a/src/vcpkg/archives.cpp +++ b/src/vcpkg/archives.cpp @@ -156,7 +156,16 @@ namespace vcpkg } else if (Strings::case_insensitive_ascii_equals(ext, ".exe")) { - return ExtractionType::Exe; + // Special case to differentiate between self-extracting 7z archives and other exe files + const auto stem = archive.stem(); + if (Strings::case_insensitive_ascii_equals(Path(stem).extension(), ".7z")) + { + return ExtractionType::SelfExtracting7z; + } + else + { + return ExtractionType::Exe; + } } else { @@ -188,6 +197,9 @@ namespace vcpkg extract_tar(tools.get_tool_path(Tools::TAR, status_sink), archive, to_path); break; case ExtractionType::Exe: + win32_extract_with_seven_zip(tools.get_tool_path(Tools::SEVEN_ZIP, status_sink), archive, to_path); + break; + case ExtractionType::SelfExtracting7z: const Path filename = archive.filename(); const Path stem = filename.stem(); const Path to_archive = Path(archive.parent_path()) / stem; @@ -248,7 +260,7 @@ namespace vcpkg Checks::msg_check_exit(VCPKG_LINE_INFO, Strings::case_insensitive_ascii_equals(subext, ".7z"), msg::format(msgPackageFailedtWhileExtracting, msg::value = "7zip", msg::path = archive) - .append(msgMissingExtension, msg::extension = ".7.exe")); + .append(msgMissingExtension, msg::extension = ".7z.exe")); auto contents = fs.read_contents(archive, VCPKG_LINE_INFO); @@ -310,50 +322,51 @@ namespace vcpkg fs.rename_with_retry(to_path_partial, to_path, VCPKG_LINE_INFO); } - ExpectedL ZipTool::compress_directory_to_zip(const Filesystem& fs, - const Path& source, - const Path& destination) const + bool ZipTool::compress_directory_to_zip(DiagnosticContext& context, + const Filesystem& fs, + const Path& source, + const Path& destination) const { fs.remove(destination, VCPKG_LINE_INFO); #if defined(_WIN32) RedirectedProcessLaunchSettings settings; settings.environment = get_clean_environment(); - return flatten(cmd_execute_and_capture_output( - Command{seven_zip}.string_arg("a").string_arg(destination).string_arg(source / "*")), - Tools::SEVEN_ZIP); + auto& seven_zip_path = seven_zip.value_or_exit(VCPKG_LINE_INFO); + auto output = cmd_execute_and_capture_output( + context, Command{seven_zip_path}.string_arg("a").string_arg(destination).string_arg(source / "*")); + return check_zero_exit_code(context, output, seven_zip_path) != nullptr; #else RedirectedProcessLaunchSettings settings; settings.working_directory = source; - return flatten(cmd_execute_and_capture_output(Command{"zip"} - .string_arg("--quiet") - .string_arg("-y") - .string_arg("-r") - .string_arg(destination) - .string_arg("*") - .string_arg("--exclude") - .string_arg(FileDotDsStore), - settings), - "zip"); + auto output = cmd_execute_and_capture_output(context, + Command{"zip"} + .string_arg("--quiet") + .string_arg("-y") + .string_arg("-r") + .string_arg(destination) + .string_arg("*") + .string_arg("--exclude") + .string_arg(FileDotDsStore), + settings); + return check_zero_exit_code(context, output, "zip") != nullptr; #endif } - ExpectedL ZipTool::make(const ToolCache& cache, MessageSink& status_sink) + void ZipTool::setup(const ToolCache& cache, MessageSink& status_sink) { - ZipTool ret; #if defined(_WIN32) - ret.seven_zip = cache.get_tool_path(Tools::SEVEN_ZIP, status_sink); + seven_zip.emplace(cache.get_tool_path(Tools::SEVEN_ZIP, status_sink)); #endif // Unused on non-Windows (void)cache; (void)status_sink; - return std::move(ret); } Command ZipTool::decompress_zip_archive_cmd(const Path& dst, const Path& archive_path) const { Command cmd; #if defined(_WIN32) - cmd.string_arg(seven_zip) + cmd.string_arg(seven_zip.value_or_exit(VCPKG_LINE_INFO)) .string_arg("x") .string_arg(archive_path) .string_arg("-o" + dst.native()) diff --git a/src/vcpkg/base/diagnostics.cpp b/src/vcpkg/base/diagnostics.cpp new file mode 100644 index 0000000000..81105ff425 --- /dev/null +++ b/src/vcpkg/base/diagnostics.cpp @@ -0,0 +1,338 @@ +#include +#include +#include +#include + +#include + +#include + +using namespace vcpkg; + +namespace +{ + static constexpr StringLiteral ColonSpace{": "}; + + void append_file_prefix(std::string& target, const Optional& maybe_origin, const TextRowCol& position) + { + // file:line:col: kind: message + if (auto origin = maybe_origin.get()) + { + target.append(*origin); + if (position.row) + { + target.push_back(':'); + fmt::format_to(std::back_inserter(target), FMT_COMPILE("{}"), position.row); + + if (position.column) + { + target.push_back(':'); + fmt::format_to(std::back_inserter(target), FMT_COMPILE("{}"), position.column); + } + } + + target.append(ColonSpace.data(), ColonSpace.size()); + } + } + + void append_kind_prefix(std::string& target, DiagKind kind) + { + static constexpr StringLiteral Empty{""}; + static constexpr const StringLiteral* prefixes[] = { + &Empty, &MessagePrefix, &ErrorPrefix, &WarningPrefix, &NotePrefix}; + static_assert(std::size(prefixes) == static_cast(DiagKind::COUNT)); + + const auto diag_index = static_cast(kind); + if (diag_index >= static_cast(DiagKind::COUNT)) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + const auto prefix = prefixes[diag_index]; + target.append(prefix->data(), prefix->size()); + } + + template + void joined_line_to_string(const std::vector& lines, std::string& target) + { + auto first = lines.begin(); + const auto last = lines.end(); + if (first == last) + { + return; + } + + for (;;) + { + first->to_string(target); + if (++first == last) + { + return; + } + + target.push_back('\n'); + } + } + + bool diagnostic_lines_any_errors(const std::vector& lines) + { + for (auto&& line : lines) + { + if (line.kind() == DiagKind::Error) + { + return true; + } + } + + return false; + } +} + +namespace vcpkg +{ + void DiagnosticContext::report(DiagnosticLine&& line) { report(line); } + + void DiagnosticContext::report_system_error(StringLiteral system_api_name, int error_value) + { + report_error(msgSystemApiErrorMessage, + msg::system_api = system_api_name, + msg::exit_code = error_value, + msg::error_msg = std::system_category().message(error_value)); + } + + void DiagnosticLine::print_to(MessageSink& sink) const { sink.println(to_message_line()); } + std::string DiagnosticLine::to_string() const + { + std::string result; + this->to_string(result); + return result; + } + void DiagnosticLine::to_string(std::string& target) const + { + append_file_prefix(target, m_origin, m_position); + append_kind_prefix(target, m_kind); + target.append(m_message.data()); + } + + MessageLine DiagnosticLine::to_message_line() const + { + MessageLine ret; + { + std::string file_prefix; + append_file_prefix(file_prefix, m_origin, m_position); + ret.print(file_prefix); + } + switch (m_kind) + { + case DiagKind::None: + // intentionally blank + break; + case DiagKind::Message: ret.print(MessagePrefix); break; + case DiagKind::Error: + { + ret.print(Color::error, "error"); + ret.print(ColonSpace); + } + break; + case DiagKind::Warning: + { + ret.print(Color::warning, "warning"); + ret.print(ColonSpace); + } + break; + case DiagKind::Note: ret.print(NotePrefix); break; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + + ret.print(m_message); + return ret; + } + + LocalizedString DiagnosticLine::to_json_reader_string(const std::string& path, const LocalizedString& type) const + { + std::string result; + append_file_prefix(result, m_origin, m_position); + append_kind_prefix(result, m_kind); + result.append(path); + result.append(" ("); + result.append(type.data()); + result.append(") "); + result.append(m_message.data()); + return LocalizedString::from_raw(result); + } + + DiagnosticLine DiagnosticLine::reduce_to_warning() const& + { + return DiagnosticLine{m_kind == DiagKind::Error ? DiagKind::Warning : m_kind, m_origin, m_position, m_message}; + } + DiagnosticLine DiagnosticLine::reduce_to_warning() && + { + return DiagnosticLine{m_kind == DiagKind::Error ? DiagKind::Warning : m_kind, + std::move(m_origin), + m_position, + std::move(m_message)}; + } + + DiagnosticLine::DiagnosticLine(DiagKind kind, + const Optional& origin, + TextRowCol position, + const LocalizedString& message) + : m_kind(kind), m_origin(origin), m_position(position), m_message(message) + { + } + DiagnosticLine::DiagnosticLine(DiagKind kind, + Optional&& origin, + TextRowCol position, + LocalizedString&& message) + : m_kind(kind), m_origin(std::move(origin)), m_position(position), m_message(std::move(message)) + { + } + + void PrintingDiagnosticContext::report(const DiagnosticLine& line) { line.print_to(sink); } + + void PrintingDiagnosticContext::statusln(const LocalizedString& message) { sink.println(message); } + void PrintingDiagnosticContext::statusln(LocalizedString&& message) { sink.println(std::move(message)); } + void PrintingDiagnosticContext::statusln(const MessageLine& message) { sink.println(message); } + void PrintingDiagnosticContext::statusln(MessageLine&& message) { sink.println(std::move(message)); } + + void BufferedDiagnosticContext::report(const DiagnosticLine& line) { lines.push_back(line); } + void BufferedDiagnosticContext::report(DiagnosticLine&& line) { lines.push_back(std::move(line)); } + void BufferedDiagnosticContext::print_to(MessageSink& sink) const + { + for (auto&& line : lines) + { + line.print_to(sink); + } + } + + // Converts this message into a string + // Prefer print() if possible because it applies color + // Not safe to use in the face of concurrent calls to report() + std::string BufferedDiagnosticContext::to_string() const { return adapt_to_string(*this); } + void BufferedDiagnosticContext::to_string(std::string& target) const { joined_line_to_string(lines, target); } + + bool BufferedDiagnosticContext::any_errors() const noexcept { return diagnostic_lines_any_errors(lines); } + bool BufferedDiagnosticContext::empty() const noexcept { return lines.empty(); } + + void BufferedDiagnosticContext::statusln(const LocalizedString& message) { status_sink.println(message); } + void BufferedDiagnosticContext::statusln(LocalizedString&& message) { status_sink.println(std::move(message)); } + void BufferedDiagnosticContext::statusln(const MessageLine& message) { status_sink.println(message); } + void BufferedDiagnosticContext::statusln(MessageLine&& message) { status_sink.println(std::move(message)); } + + void FullyBufferedDiagnosticContext::report(const DiagnosticLine& line) { lines.push_back(line.to_message_line()); } + void FullyBufferedDiagnosticContext::report(DiagnosticLine&& line) + { + lines.push_back(std::move(line).to_message_line()); + } + + void FullyBufferedDiagnosticContext::statusln(const LocalizedString& message) { lines.emplace_back(message); } + void FullyBufferedDiagnosticContext::statusln(LocalizedString&& message) { lines.emplace_back(std::move(message)); } + void FullyBufferedDiagnosticContext::statusln(const MessageLine& message) { lines.emplace_back(message); } + void FullyBufferedDiagnosticContext::statusln(MessageLine&& message) { lines.emplace_back(std::move(message)); } + + void FullyBufferedDiagnosticContext::print_to(MessageSink& sink) const + { + for (auto&& line : lines) + { + sink.println(line); + } + } + + std::string FullyBufferedDiagnosticContext::to_string() const { return adapt_to_string(*this); } + void FullyBufferedDiagnosticContext::to_string(std::string& target) const { joined_line_to_string(lines, target); } + + bool FullyBufferedDiagnosticContext::empty() const noexcept { return lines.empty(); } + + void AttemptDiagnosticContext::report(const DiagnosticLine& line) { lines.push_back(line); } + void AttemptDiagnosticContext::report(DiagnosticLine&& line) { lines.push_back(std::move(line)); } + + void AttemptDiagnosticContext::statusln(const LocalizedString& message) { inner_context.statusln(message); } + void AttemptDiagnosticContext::statusln(LocalizedString&& message) { inner_context.statusln(std::move(message)); } + void AttemptDiagnosticContext::statusln(const MessageLine& message) { inner_context.statusln(message); } + void AttemptDiagnosticContext::statusln(MessageLine&& message) { inner_context.statusln(std::move(message)); } + + void AttemptDiagnosticContext::commit() + { + for (auto& line : lines) + { + inner_context.report(std::move(line)); + } + + lines.clear(); + } + + void AttemptDiagnosticContext::handle() { lines.clear(); } + + AttemptDiagnosticContext::~AttemptDiagnosticContext() + { + if (!lines.empty()) + { +#if defined(NDEBUG) + for (auto& line : lines) + { + inner_context.report(std::move(line)); + } +#else // ^^^ NDEBUG // !NDEBUG vvv + Checks::unreachable(VCPKG_LINE_INFO, "Uncommitted diagnostics in ~AttemptDiagnosticContext"); +#endif // ^^^ !NDEBUG + } + } + + void WarningDiagnosticContext::report(const DiagnosticLine& line) + { + inner_context.report(line.reduce_to_warning()); + } + void WarningDiagnosticContext::report(DiagnosticLine&& line) + { + inner_context.report(std::move(line).reduce_to_warning()); + } + + void WarningDiagnosticContext::statusln(const LocalizedString& message) { inner_context.statusln(message); } + void WarningDiagnosticContext::statusln(LocalizedString&& message) { inner_context.statusln(std::move(message)); } + void WarningDiagnosticContext::statusln(const MessageLine& message) { inner_context.statusln(message); } + void WarningDiagnosticContext::statusln(MessageLine&& message) { inner_context.statusln(std::move(message)); } +} // namespace vcpkg + +namespace +{ + struct NullDiagnosticContext final : DiagnosticContext + { + // these are all intentionally empty + virtual void report(const DiagnosticLine&) override { } + virtual void statusln(const LocalizedString&) override { } + virtual void statusln(LocalizedString&&) override { } + virtual void statusln(const MessageLine&) override { } + virtual void statusln(MessageLine&&) override { } + }; + + NullDiagnosticContext null_diagnostic_context_instance; + + struct ConsoleDiagnosticContext final : DiagnosticContext + { + virtual void report(const DiagnosticLine& line) override { line.print_to(out_sink); } + virtual void statusln(const LocalizedString& message) override { out_sink.println(message); } + virtual void statusln(LocalizedString&& message) override { out_sink.println(std::move(message)); } + virtual void statusln(const MessageLine& message) override { out_sink.println(message); } + virtual void statusln(MessageLine&& message) override { out_sink.println(std::move(message)); } + }; + + ConsoleDiagnosticContext console_diagnostic_context_instance; + + struct StatusOnlyDiagnosticContext final : DiagnosticContext + { + virtual void report(const DiagnosticLine&) override { } + virtual void statusln(const LocalizedString& message) override { out_sink.println(message); } + virtual void statusln(LocalizedString&& message) override { out_sink.println(std::move(message)); } + virtual void statusln(const MessageLine& message) override { out_sink.println(message); } + virtual void statusln(MessageLine&& message) override { out_sink.println(std::move(message)); } + }; + + StatusOnlyDiagnosticContext status_only_diagnostic_context_instance; +} // unnamed namespace + +namespace vcpkg +{ + DiagnosticContext& null_diagnostic_context = null_diagnostic_context_instance; + DiagnosticContext& console_diagnostic_context = console_diagnostic_context_instance; + DiagnosticContext& status_only_diagnostic_context = status_only_diagnostic_context_instance; +} diff --git a/src/vcpkg/base/downloads.cpp b/src/vcpkg/base/downloads.cpp index 56e61316c5..dda736d530 100644 --- a/src/vcpkg/base/downloads.cpp +++ b/src/vcpkg/base/downloads.cpp @@ -4,9 +4,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -15,60 +17,103 @@ #include -namespace vcpkg +#include + +using namespace vcpkg; + +namespace { - static std::string replace_secrets(std::string input, View secrets) + constexpr StringLiteral vcpkg_curl_user_agent_header = + "User-Agent: vcpkg/" VCPKG_BASE_VERSION_AS_STRING "-" VCPKG_VERSION_AS_STRING " (curl)"; + + void add_curl_headers(Command& cmd, View headers) + { + cmd.string_arg("-H").string_arg(vcpkg_curl_user_agent_header); + for (auto&& header : headers) + { + cmd.string_arg("-H").string_arg(header); + } + } + + void replace_secrets(std::string& target, View secrets) { const auto replacement = msg::format(msgSecretBanner); for (const auto& secret : secrets) { - Strings::inplace_replace_all(input, secret, replacement); + Strings::inplace_replace_all(target, secret, replacement); } + } +} - return input; +namespace vcpkg +{ + SanitizedUrl::SanitizedUrl(StringView raw_url, View secrets) + : m_sanitized_url(raw_url.data(), raw_url.size()) + { + replace_secrets(m_sanitized_url, secrets); } #if defined(_WIN32) - struct WinHttpHandle + struct FormatMessageHLocalAlloc { - HINTERNET h; + LPWSTR buffer = nullptr; - WinHttpHandle() : h(0) { } - explicit WinHttpHandle(HINTERNET h_) : h(h_) { } - WinHttpHandle(const WinHttpHandle&) = delete; - WinHttpHandle(WinHttpHandle&& other) : h(other.h) { other.h = 0; } - WinHttpHandle& operator=(const WinHttpHandle&) = delete; - WinHttpHandle& operator=(WinHttpHandle&& other) + ~FormatMessageHLocalAlloc() { - auto cpy = std::move(other); - std::swap(h, cpy.h); - return *this; + if (buffer) + { + LocalFree(buffer); + } } + }; - ~WinHttpHandle() + static LocalizedString format_winhttp_last_error_message(StringLiteral api_name, + const SanitizedUrl& sanitized_url, + DWORD last_error) + { + const HMODULE winhttp_module = GetModuleHandleW(L"winhttp.dll"); + FormatMessageHLocalAlloc alloc; + DWORD tchars_excluding_terminating_null = 0; + if (winhttp_module) { - if (h) + tchars_excluding_terminating_null = + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE, + winhttp_module, + last_error, + 0, + reinterpret_cast(&alloc.buffer), + 0, + nullptr); + } + + auto result = msg::format( + msgDownloadWinHttpError, msg::system_api = api_name, msg::exit_code = last_error, msg::url = sanitized_url); + if (tchars_excluding_terminating_null && alloc.buffer) + { + while (tchars_excluding_terminating_null != 0 && + (alloc.buffer[tchars_excluding_terminating_null - 1] == L'\r' || + alloc.buffer[tchars_excluding_terminating_null - 1] == L'\n')) { - WinHttpCloseHandle(h); + --tchars_excluding_terminating_null; } + + tchars_excluding_terminating_null = static_cast( + std::remove(alloc.buffer, alloc.buffer + tchars_excluding_terminating_null, L'\r') - alloc.buffer); + result.append_raw(' ').append_raw(Strings::to_utf8(alloc.buffer, tchars_excluding_terminating_null)); } - }; - static LocalizedString format_winhttp_last_error_message(StringLiteral api_name, StringView url, DWORD last_error) - { - return msg::format_error( - msgDownloadWinHttpError, msg::system_api = api_name, msg::exit_code = last_error, msg::url = url); + return result; } - static LocalizedString format_winhttp_last_error_message(StringLiteral api_name, StringView url) + static LocalizedString format_winhttp_last_error_message(StringLiteral api_name, const SanitizedUrl& sanitized_url) { - return format_winhttp_last_error_message(api_name, url, GetLastError()); + return format_winhttp_last_error_message(api_name, sanitized_url, GetLastError()); } - static void maybe_emit_winhttp_progress(const Optional& maybe_content_length, + static void maybe_emit_winhttp_progress(MessageSink& machine_readable_progress, + const Optional& maybe_content_length, std::chrono::steady_clock::time_point& last_write, - unsigned long long total_downloaded_size, - MessageSink& progress_sink) + unsigned long long total_downloaded_size) { if (const auto content_length = maybe_content_length.get()) { @@ -77,174 +122,240 @@ namespace vcpkg { const double percent = (static_cast(total_downloaded_size) / static_cast(*content_length)) * 100; - progress_sink.print(Color::none, fmt::format("{:.2f}%\n", percent)); + machine_readable_progress.println(LocalizedString::from_raw(fmt::format("{:.2f}%", percent))); last_write = now; } } } - struct WinHttpRequest + struct WinHttpHandle { - static ExpectedL make(HINTERNET hConnect, - StringView url_path, - StringView sanitized_url, - bool https, - const wchar_t* method = L"GET") - { - WinHttpRequest ret; - ret.m_sanitized_url.assign(sanitized_url.data(), sanitized_url.size()); - // Create an HTTP request handle. - { - auto h = WinHttpOpenRequest(hConnect, - method, - Strings::to_utf16(url_path).c_str(), - nullptr, - WINHTTP_NO_REFERER, - WINHTTP_DEFAULT_ACCEPT_TYPES, - https ? WINHTTP_FLAG_SECURE : 0); - if (!h) - { - return format_winhttp_last_error_message("WinHttpOpenRequest", sanitized_url); - } + WinHttpHandle() = default; + WinHttpHandle(const WinHttpHandle&) = delete; + WinHttpHandle& operator=(const WinHttpHandle&) = delete; - ret.m_hRequest = WinHttpHandle{h}; + void require_null_handle() const + { + if (h) + { + Checks::unreachable(VCPKG_LINE_INFO, "WinHTTP handle type confusion"); } + } - // Send a request. - auto bResults = WinHttpSendRequest( - ret.m_hRequest.h, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); - - if (!bResults) + void require_created_handle() const + { + if (!h) { - return format_winhttp_last_error_message("WinHttpSendRequest", sanitized_url); + Checks::unreachable(VCPKG_LINE_INFO, "WinHTTP handle not created"); } + } - // End the request. - bResults = WinHttpReceiveResponse(ret.m_hRequest.h, NULL); - if (!bResults) + bool Connect(DiagnosticContext& context, + const WinHttpHandle& session, + StringView hostname, + INTERNET_PORT port, + const SanitizedUrl& sanitized_url) + { + require_null_handle(); + session.require_created_handle(); + h = WinHttpConnect(session.h, Strings::to_utf16(hostname).c_str(), port, 0); + if (h) { - return format_winhttp_last_error_message("WinHttpReceiveResponse", sanitized_url); + return true; } - return ret; + context.report_error(format_winhttp_last_error_message("WinHttpConnect", sanitized_url)); + return false; } - ExpectedL query_status() const + bool Open(DiagnosticContext& context, + const SanitizedUrl& sanitized_url, + _In_opt_z_ LPCWSTR pszAgentW, + _In_ DWORD dwAccessType, + _In_opt_z_ LPCWSTR pszProxyW, + _In_opt_z_ LPCWSTR pszProxyBypassW, + _In_ DWORD dwFlags) { - DWORD status_code; - DWORD size = sizeof(status_code); + require_null_handle(); + h = WinHttpOpen(pszAgentW, dwAccessType, pszProxyW, pszProxyBypassW, dwFlags); + if (h) + { + return true; + } + + context.report_error(format_winhttp_last_error_message("WinHttpOpen", sanitized_url)); + return false; + } - auto succeeded = WinHttpQueryHeaders(m_hRequest.h, - WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, - WINHTTP_HEADER_NAME_BY_INDEX, - &status_code, - &size, - WINHTTP_NO_HEADER_INDEX); - if (succeeded) + bool OpenRequest(DiagnosticContext& context, + const WinHttpHandle& hConnect, + const SanitizedUrl& sanitized_url, + IN LPCWSTR pwszVerb, + StringView path_query_fragment, + IN LPCWSTR pwszVersion, + IN LPCWSTR pwszReferrer OPTIONAL, + IN LPCWSTR FAR* ppwszAcceptTypes OPTIONAL, + IN DWORD dwFlags) + { + require_null_handle(); + h = WinHttpOpenRequest(hConnect.h, + pwszVerb, + Strings::to_utf16(path_query_fragment).c_str(), + pwszVersion, + pwszReferrer, + ppwszAcceptTypes, + dwFlags); + if (h) { - return status_code; + return true; } - return format_winhttp_last_error_message("WinHttpQueryHeaders", m_sanitized_url); + context.report_error(format_winhttp_last_error_message("WinHttpOpenRequest", sanitized_url)); + return false; } - ExpectedL> query_content_length() const + bool SendRequest(DiagnosticContext& context, + const SanitizedUrl& sanitized_url, + _In_reads_opt_(dwHeadersLength) LPCWSTR lpszHeaders, + IN DWORD dwHeadersLength, + _In_reads_bytes_opt_(dwOptionalLength) LPVOID lpOptional, + IN DWORD dwOptionalLength, + IN DWORD dwTotalLength, + IN DWORD_PTR dwContext) const { - static constexpr DWORD buff_characters = 21; // 18446744073709551615 - wchar_t buff[buff_characters]; - DWORD size = sizeof(buff); - auto succeeded = WinHttpQueryHeaders(m_hRequest.h, - WINHTTP_QUERY_CONTENT_LENGTH, - WINHTTP_HEADER_NAME_BY_INDEX, - buff, - &size, - WINHTTP_NO_HEADER_INDEX); - if (succeeded) + require_created_handle(); + if (WinHttpSendRequest( + h, lpszHeaders, dwHeadersLength, lpOptional, dwOptionalLength, dwTotalLength, dwContext)) { - return Strings::strto(Strings::to_utf8(buff, size >> 1)); + return true; } - const DWORD last_error = GetLastError(); - if (last_error == ERROR_WINHTTP_HEADER_NOT_FOUND) + context.report_error(format_winhttp_last_error_message("WinHttpSendRequest", sanitized_url)); + return false; + } + + bool ReceiveResponse(DiagnosticContext& context, const SanitizedUrl& url) + { + require_created_handle(); + if (WinHttpReceiveResponse(h, NULL)) { - return Optional{nullopt}; + return true; } - return format_winhttp_last_error_message("WinHttpQueryHeaders", m_sanitized_url, last_error); + context.report_error(format_winhttp_last_error_message("WinHttpReceiveResponse", url)); + return false; } - ExpectedL write_response_body(WriteFilePointer& file, MessageSink& progress_sink) + bool SetTimeouts(DiagnosticContext& context, + const SanitizedUrl& sanitized_url, + int nResolveTimeout, + int nConnectTimeout, + int nSendTimeout, + int nReceiveTimeout) const { - static constexpr DWORD buff_size = 65535; - std::unique_ptr buff{new char[buff_size]}; - Optional maybe_content_length; - auto last_write = std::chrono::steady_clock::now(); + require_created_handle(); + if (WinHttpSetTimeouts(h, nResolveTimeout, nConnectTimeout, nSendTimeout, nReceiveTimeout)) + { + return true; + } + + context.report_error(format_winhttp_last_error_message("WinHttpSetTimeouts", sanitized_url)); + return false; + } + bool SetOption(DiagnosticContext& context, + const SanitizedUrl& sanitized_url, + DWORD dwOption, + LPVOID lpBuffer, + DWORD dwBufferLength) const + { + require_created_handle(); + if (WinHttpSetOption(h, dwOption, lpBuffer, dwBufferLength)) { - auto maybe_maybe_content_length = query_content_length(); - if (const auto p = maybe_maybe_content_length.get()) - { - maybe_content_length = *p; - } - else - { - return std::move(maybe_maybe_content_length).error(); - } + return true; } - unsigned long long total_downloaded_size = 0; - for (;;) + context.report_error(format_winhttp_last_error_message("WinHttpSetOption", sanitized_url)); + return false; + } + + DWORD QueryHeaders(DiagnosticContext& context, + const SanitizedUrl& sanitized_url, + DWORD dwInfoLevel, + LPWSTR pwszName, + LPVOID lpBuffer, + LPDWORD lpdwBufferLength, + LPDWORD lpdwIndex) const + { + require_created_handle(); + if (WinHttpQueryHeaders(h, dwInfoLevel, pwszName, lpBuffer, lpdwBufferLength, lpdwIndex)) { - DWORD this_read; - if (!WinHttpReadData(m_hRequest.h, buff.get(), buff_size, &this_read)) - { - return format_winhttp_last_error_message("WinHttpReadData", m_sanitized_url); - } + return 0; + } - if (this_read == 0) - { - return Unit{}; - } + DWORD last_error = GetLastError(); + context.report_error(format_winhttp_last_error_message("WinHttpQueryHeaders", sanitized_url, last_error)); + return last_error; + } - do - { - const auto this_write = static_cast(file.write(buff.get(), 1, this_read)); - if (this_write == 0) - { - return format_winhttp_last_error_message("fwrite", m_sanitized_url); - } + bool ReadData(DiagnosticContext& context, + const SanitizedUrl& sanitized_url, + LPVOID buffer, + DWORD dwNumberOfBytesToRead, + DWORD* numberOfBytesRead) + { + require_created_handle(); + if (WinHttpReadData(h, buffer, dwNumberOfBytesToRead, numberOfBytesRead)) + { + return true; + } - maybe_emit_winhttp_progress(maybe_content_length, last_write, total_downloaded_size, progress_sink); - this_read -= this_write; - total_downloaded_size += this_write; - } while (this_read > 0); + context.report_error(format_winhttp_last_error_message("WinHttpReadData", sanitized_url)); + return false; + } + + ~WinHttpHandle() + { + if (h) + { + // intentionally ignore failures + (void)WinHttpCloseHandle(h); } } - WinHttpHandle m_hRequest; - std::string m_sanitized_url; + private: + HINTERNET h{}; + }; + + enum class WinHttpTrialResult + { + failed, + succeeded, + retry }; struct WinHttpSession { - static ExpectedL make(StringView sanitized_url) + bool open(DiagnosticContext& context, const SanitizedUrl& sanitized_url) { - WinHttpSession ret; + if (!m_hSession.Open(context, + sanitized_url, + L"vcpkg/1.0", + WINHTTP_ACCESS_TYPE_NO_PROXY, + WINHTTP_NO_PROXY_NAME, + WINHTTP_NO_PROXY_BYPASS, + 0)) { - auto h = WinHttpOpen( - L"vcpkg/1.0", WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); - if (!h) - { - return format_winhttp_last_error_message("WinHttpOpen", sanitized_url); - } - - ret.m_hSession = WinHttpHandle{h}; + return false; } // Increase default timeouts to help connections behind proxies // WinHttpSetTimeouts(HINTERNET hInternet, int nResolveTimeout, int nConnectTimeout, int nSendTimeout, int // nReceiveTimeout); - WinHttpSetTimeouts(ret.m_hSession.h, 0, 120000, 120000, 120000); + if (!m_hSession.SetTimeouts(context, sanitized_url, 0, 120000, 120000, 120000)) + { + return false; + } // If the environment variable HTTPS_PROXY is set // use that variable as proxy. This situation might exist when user is in a company network @@ -257,8 +368,10 @@ namespace vcpkg proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; proxy.lpszProxy = env_proxy_settings.data(); proxy.lpszProxyBypass = nullptr; - - WinHttpSetOption(ret.m_hSession.h, WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy)); + if (!m_hSession.SetOption(context, sanitized_url, WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy))) + { + return false; + } } // IE Proxy fallback, this works on Windows 10 else @@ -272,24 +385,36 @@ namespace vcpkg proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; proxy.lpszProxy = ieProxy.get()->server.data(); proxy.lpszProxyBypass = ieProxy.get()->bypass.data(); - WinHttpSetOption(ret.m_hSession.h, WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy)); + if (!m_hSession.SetOption(context, sanitized_url, WINHTTP_OPTION_PROXY, &proxy, sizeof(proxy))) + { + return false; + } } } // Use Windows 10 defaults on Windows 7 DWORD secure_protocols(WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2); - WinHttpSetOption( - ret.m_hSession.h, WINHTTP_OPTION_SECURE_PROTOCOLS, &secure_protocols, sizeof(secure_protocols)); + if (!m_hSession.SetOption(context, + sanitized_url, + WINHTTP_OPTION_SECURE_PROTOCOLS, + &secure_protocols, + sizeof(secure_protocols))) + { + return false; + } // Many open source mirrors such as https://download.gnome.org/ will redirect to http mirrors. // `curl.exe -L` does follow https -> http redirection. // Additionally, vcpkg hash checks the resulting archive. DWORD redirect_policy(WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS); - WinHttpSetOption( - ret.m_hSession.h, WINHTTP_OPTION_REDIRECT_POLICY, &redirect_policy, sizeof(redirect_policy)); + if (!m_hSession.SetOption( + context, sanitized_url, WINHTTP_OPTION_REDIRECT_POLICY, &redirect_policy, sizeof(redirect_policy))) + { + return false; + } - return ret; + return true; } WinHttpHandle m_hSession; @@ -297,181 +422,337 @@ namespace vcpkg struct WinHttpConnection { - static ExpectedL make(HINTERNET hSession, - StringView hostname, - INTERNET_PORT port, - StringView sanitized_url) + bool connect(DiagnosticContext& context, + const WinHttpSession& hSession, + StringView hostname, + INTERNET_PORT port, + const SanitizedUrl& sanitized_url) { // Specify an HTTP server. - auto h = WinHttpConnect(hSession, Strings::to_utf16(hostname).c_str(), port, 0); - if (!h) - { - return format_winhttp_last_error_message("WinHttpConnect", sanitized_url); - } - - return WinHttpConnection{WinHttpHandle{h}}; + return m_hConnect.Connect(context, hSession.m_hSession, hostname, port, sanitized_url); } WinHttpHandle m_hConnect; }; -#endif - ExpectedL split_uri_view(StringView uri) - { - auto sep = std::find(uri.begin(), uri.end(), ':'); - if (sep == uri.end()) return msg::format_error(msgInvalidUri, msg::value = uri); - - StringView scheme(uri.begin(), sep); - if (Strings::starts_with({sep + 1, uri.end()}, "//")) - { - auto path_start = std::find(sep + 3, uri.end(), '/'); - return SplitURIView{scheme, StringView{sep + 1, path_start}, {path_start, uri.end()}}; - } - // no authority - return SplitURIView{scheme, {}, {sep + 1, uri.end()}}; - } - - static ExpectedL try_verify_downloaded_file_hash(const ReadOnlyFilesystem& fs, - StringView sanitized_url, - const Path& downloaded_path, - StringView sha512) + struct WinHttpRequest { - std::string actual_hash = - vcpkg::Hash::get_file_hash(fs, downloaded_path, Hash::Algorithm::Sha512).value_or_exit(VCPKG_LINE_INFO); - if (!Strings::case_insensitive_ascii_equals(sha512, actual_hash)) + bool open(DiagnosticContext& context, + const WinHttpConnection& hConnect, + StringView path_query_fragment, + const SanitizedUrl& sanitized_url, + bool https, + const wchar_t* method = L"GET") { - return msg::format_error(msgDownloadFailedHashMismatch, - msg::url = sanitized_url, - msg::path = downloaded_path, - msg::expected = sha512, - msg::actual = actual_hash); - } + if (!m_hRequest.OpenRequest(context, + hConnect.m_hConnect, + sanitized_url, + method, + path_query_fragment, + nullptr, + WINHTTP_NO_REFERER, + WINHTTP_DEFAULT_ACCEPT_TYPES, + https ? WINHTTP_FLAG_SECURE : 0)) + { + return false; + } - return Unit{}; - } + // Send a request. + if (!m_hRequest.SendRequest( + context, sanitized_url, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0)) + { + return false; + } - void verify_downloaded_file_hash(const ReadOnlyFilesystem& fs, - StringView url, - const Path& downloaded_path, - StringView sha512) - { - try_verify_downloaded_file_hash(fs, url, downloaded_path, sha512).value_or_exit(VCPKG_LINE_INFO); - } + // End the request. + if (!m_hRequest.ReceiveResponse(context, sanitized_url)) + { + return false; + } - static ExpectedL check_downloaded_file_hash(const ReadOnlyFilesystem& fs, - const Optional& hash, - StringView sanitized_url, - const Path& download_part_path) - { - if (auto p = hash.get()) - { - return try_verify_downloaded_file_hash(fs, sanitized_url, download_part_path, *p); + return true; } - Debug::println("Skipping hash check because none was specified."); - return Unit{}; - } - - static std::vector curl_bulk_operation(View operation_args, - StringLiteral prefixArgs, - View headers, - View secrets) - { -#define GUID_MARKER "5ec47b8e-6776-4d70-b9b3-ac2a57bc0a1c" - static constexpr StringLiteral guid_marker = GUID_MARKER; - Command prefix_cmd{"curl"}; - if (!prefixArgs.empty()) + Optional query_status(DiagnosticContext& context, const SanitizedUrl& sanitized_url) const { - prefix_cmd.raw_arg(prefixArgs); - } - - prefix_cmd.string_arg("-L").string_arg("-w").string_arg(GUID_MARKER "%{http_code}\\n"); -#undef GUID_MARKER - - std::vector ret; - ret.reserve(operation_args.size()); + DWORD status_code; + DWORD size = sizeof(status_code); + DWORD last_error = m_hRequest.QueryHeaders(context, + sanitized_url, + WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, + WINHTTP_HEADER_NAME_BY_INDEX, + &status_code, + &size, + WINHTTP_NO_HEADER_INDEX); + if (last_error) + { + return nullopt; + } - for (auto&& header : headers) - { - prefix_cmd.string_arg("-H").string_arg(header); + return status_code; } - static constexpr auto initial_timeout_delay_ms = 100; - auto timeout_delay_ms = initial_timeout_delay_ms; - static constexpr auto maximum_timeout_delay_ms = 100000; - - while (ret.size() != operation_args.size()) + bool query_content_length(DiagnosticContext& context, + const SanitizedUrl& sanitized_url, + Optional& result) const { - // there's an edge case that we aren't handling here where not even one operation fits with the configured - // headers but this seems unlikely + static constexpr DWORD buff_characters = 21; // 18446744073709551615 + wchar_t buff[buff_characters]; + DWORD size = sizeof(buff); + AttemptDiagnosticContext adc{context}; + DWORD last_error = m_hRequest.QueryHeaders(adc, + sanitized_url, + WINHTTP_QUERY_CONTENT_LENGTH, + WINHTTP_HEADER_NAME_BY_INDEX, + buff, + &size, + WINHTTP_NO_HEADER_INDEX); + if (!last_error) + { + adc.commit(); + result = Strings::strto(Strings::to_utf8(buff, size >> 1)); + return true; + } - // form a maximum length command line of operations: - auto batch_cmd = prefix_cmd; - size_t last_try_op = ret.size(); - while (last_try_op != operation_args.size() && batch_cmd.try_append(operation_args[last_try_op])) + if (last_error == ERROR_WINHTTP_HEADER_NOT_FOUND) { - ++last_try_op; + adc.handle(); + return true; } - // actually run curl - auto this_batch_result = cmd_execute_and_capture_output(batch_cmd).value_or_exit(VCPKG_LINE_INFO); - if (this_batch_result.exit_code != 0) + adc.commit(); + return false; + } + + WinHttpTrialResult write_response_body(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const SanitizedUrl& sanitized_url, + const WriteFilePointer& file) + { + static constexpr DWORD buff_size = 65535; + std::unique_ptr buff{new char[buff_size]}; + Optional maybe_content_length; + auto last_write = std::chrono::steady_clock::now(); + if (!query_content_length(context, sanitized_url, maybe_content_length)) { - Checks::msg_exit_with_error(VCPKG_LINE_INFO, - msgCommandFailedCode, - msg::command_line = - replace_secrets(std::move(batch_cmd).extract(), secrets), - msg::exit_code = this_batch_result.exit_code); + return WinHttpTrialResult::retry; } - // extract HTTP response codes - for (auto&& line : Strings::split(this_batch_result.output, '\n')) + unsigned long long total_downloaded_size = 0; + for (;;) { - if (Strings::starts_with(line, guid_marker)) + DWORD this_read; + if (!m_hRequest.ReadData(context, sanitized_url, buff.get(), buff_size, &this_read)) { - ret.push_back(static_cast(std::strtol(line.data() + guid_marker.size(), nullptr, 10))); + return WinHttpTrialResult::retry; } - } - // check if we got a partial response, and, if so, issue a timed delay - if (ret.size() == last_try_op) - { - timeout_delay_ms = initial_timeout_delay_ms; - } - else - { - // curl stopped before finishing all operations; retry after some time - if (timeout_delay_ms >= maximum_timeout_delay_ms) + if (this_read == 0) { - Checks::msg_exit_with_error(VCPKG_LINE_INFO, - msgCurlTimeout, - msg::command_line = - replace_secrets(std::move(batch_cmd).extract(), secrets)); + return WinHttpTrialResult::succeeded; } - msg::println_warning(msgCurlResponseTruncatedRetrying, msg::value = timeout_delay_ms); - std::this_thread::sleep_for(std::chrono::milliseconds(timeout_delay_ms)); - timeout_delay_ms *= 10; + do + { + const auto this_write = static_cast(file.write(buff.get(), 1, this_read)); + if (this_write == 0) + { + context.report_error(format_filesystem_call_error( + std::error_code{errno, std::generic_category()}, "fwrite", {file.path()})); + return WinHttpTrialResult::failed; + } + + maybe_emit_winhttp_progress( + machine_readable_progress, maybe_content_length, last_write, total_downloaded_size); + this_read -= this_write; + total_downloaded_size += this_write; + } while (this_read > 0); } } - return ret; + WinHttpHandle m_hRequest; + }; +#endif + + Optional parse_split_url_view(StringView raw_url) + { + auto sep = std::find(raw_url.begin(), raw_url.end(), ':'); + if (sep == raw_url.end()) + { + return nullopt; + } + + StringView scheme(raw_url.begin(), sep); + if (Strings::starts_with({sep + 1, raw_url.end()}, "//")) + { + auto path_start = std::find(sep + 3, raw_url.end(), '/'); + return SplitUrlView{scheme, StringView{sep + 1, path_start}, StringView{path_start, raw_url.end()}}; + } + + // no authority + return SplitUrlView{scheme, {}, StringView{sep + 1, raw_url.end()}}; + } + + static bool check_downloaded_file_hash(DiagnosticContext& context, + const ReadOnlyFilesystem& fs, + const SanitizedUrl& sanitized_url, + const Path& downloaded_path, + StringView sha512, + std::string* out_sha512) + { + if (!std::all_of(sha512.begin(), sha512.end(), ParserBase::is_hex_digit_lower)) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + auto maybe_actual_hash = + vcpkg::Hash::get_file_hash_required(context, fs, downloaded_path, Hash::Algorithm::Sha512); + if (auto actual_hash = maybe_actual_hash.get()) + { + if (sha512 == *actual_hash) + { + if (out_sha512) + { + *out_sha512 = std::move(*actual_hash); + } + + return true; + } + + context.report(DiagnosticLine{DiagKind::Error, + downloaded_path, + msg::format(msgDownloadFailedHashMismatch, msg::url = sanitized_url)}); + context.report(DiagnosticLine{DiagKind::Note, + msg::format(msgDownloadFailedHashMismatchExpectedHash, msg::sha = sha512)}); + context.report(DiagnosticLine{ + DiagKind::Note, msg::format(msgDownloadFailedHashMismatchActualHash, msg::sha = *actual_hash)}); + + if (out_sha512) + { + *out_sha512 = std::move(*actual_hash); + } + } + + return false; } - std::vector url_heads(View urls, View headers, View secrets) + static bool check_downloaded_file_hash(DiagnosticContext& context, + const ReadOnlyFilesystem& fs, + const SanitizedUrl& sanitized_url, + const Path& downloaded_path, + const StringView* maybe_sha512, + std::string* out_sha512) + { + if (maybe_sha512) + { + return check_downloaded_file_hash(context, fs, sanitized_url, downloaded_path, *maybe_sha512, out_sha512); + } + + if (out_sha512) + { + auto maybe_actual_hash = + vcpkg::Hash::get_file_hash_required(context, fs, downloaded_path, Hash::Algorithm::Sha512); + if (auto actual_hash = maybe_actual_hash.get()) + { + *out_sha512 = std::move(*actual_hash); + } + } + + return true; + } + + static std::vector curl_bulk_operation(DiagnosticContext& context, + View operation_args, + StringLiteral prefixArgs, + View headers, + View secrets) + { +#define GUID_MARKER "5ec47b8e-6776-4d70-b9b3-ac2a57bc0a1c" + static constexpr StringLiteral guid_marker = GUID_MARKER; + Command prefix_cmd{"curl"}; + if (!prefixArgs.empty()) + { + prefix_cmd.raw_arg(prefixArgs); + } + + prefix_cmd.string_arg("--retry").string_arg("3").string_arg("-L").string_arg("-w").string_arg( + GUID_MARKER "%{http_code} %{exitcode} %{errormsg}\\n"); +#undef GUID_MARKER + + std::vector ret; + ret.reserve(operation_args.size()); + add_curl_headers(prefix_cmd, headers); + while (ret.size() != operation_args.size()) + { + // there's an edge case that we aren't handling here where not even one operation fits with the configured + // headers but this seems unlikely + + // form a maximum length command line of operations: + auto batch_cmd = prefix_cmd; + size_t last_try_op = ret.size(); + while (last_try_op != operation_args.size() && batch_cmd.try_append(operation_args[last_try_op])) + { + ++last_try_op; + } + + // actually run curl + bool new_curl_seen = false; + std::vector debug_lines; + auto maybe_this_batch_exit_code = cmd_execute_and_stream_lines(context, batch_cmd, [&](StringView line) { + debug_lines.emplace_back(line.data(), line.size()); + new_curl_seen |= parse_curl_status_line(context, ret, guid_marker, line); + }); + + if (auto this_batch_exit_code = maybe_this_batch_exit_code.get()) + { + if (!new_curl_seen) + { + // old version of curl, we only have the result code for the last operation + context.report_error(msgCurlFailedGeneric, msg::exit_code = *this_batch_exit_code); + } + + if (ret.size() != last_try_op) + { + // curl didn't process everything we asked of it; this usually means curl crashed + auto command_line = std::move(batch_cmd).extract(); + replace_secrets(command_line, secrets); + context.report_error_with_log(Strings::join("\n", debug_lines), + msgCurlFailedToReturnExpectedNumberOfExitCodes, + msg::exit_code = *this_batch_exit_code, + msg::command_line = command_line); + return ret; + } + } + else + { + // couldn't even launch curl, record this as the last fatal error and give up + return ret; + } + } + + return ret; + } + + std::vector url_heads(DiagnosticContext& context, + View urls, + View headers, + View secrets) { return curl_bulk_operation( + context, Util::fmap(urls, [](const std::string& url) { return Command{}.string_arg(url_encode_spaces(url)); }), "--head", headers, secrets); } - std::vector download_files(View> url_pairs, - View headers, - View secrets) + std::vector download_files_no_cache(DiagnosticContext& context, + View> url_pairs, + View headers, + View secrets) { - return curl_bulk_operation(Util::fmap(url_pairs, + return curl_bulk_operation(context, + Util::fmap(url_pairs, [](const std::pair& url_pair) { return Command{} .string_arg(url_encode_spaces(url_pair.first)) @@ -483,36 +764,51 @@ namespace vcpkg secrets); } - bool send_snapshot_to_api(const std::string& github_token, - const std::string& github_repository, - const Json::Object& snapshot) + bool submit_github_dependency_graph_snapshot(DiagnosticContext& context, + const Optional& maybe_github_server_url, + const std::string& github_token, + const std::string& github_repository, + const Json::Object& snapshot) { static constexpr StringLiteral guid_marker = "fcfad8a3-bb68-4a54-ad00-dab1ff671ed2"; + std::string uri; + if (auto github_server_url = maybe_github_server_url.get()) + { + uri = *github_server_url; + uri.append("/api/v3"); + } + else + { + uri = "https://api.github.com"; + } + + fmt::format_to( + std::back_inserter(uri), "/repos/{}/dependency-graph/snapshots", url_encode_spaces(github_repository)); + auto cmd = Command{"curl"}; cmd.string_arg("-w").string_arg("\\n" + guid_marker.to_string() + "%{http_code}"); cmd.string_arg("-X").string_arg("POST"); - cmd.string_arg("-H").string_arg("Accept: application/vnd.github+json"); + { + std::string headers[] = { + "Accept: application/vnd.github+json", + "Authorization: Bearer " + github_token, + "X-GitHub-Api-Version: 2022-11-28", + }; + add_curl_headers(cmd, headers); + } - std::string res = "Authorization: Bearer " + github_token; - cmd.string_arg("-H").string_arg(res); - cmd.string_arg("-H").string_arg("X-GitHub-Api-Version: 2022-11-28"); - cmd.string_arg(Strings::concat( - "https://api.github.com/repos/", url_encode_spaces(github_repository), "/dependency-graph/snapshots")); + cmd.string_arg(uri); cmd.string_arg("-d").string_arg("@-"); RedirectedProcessLaunchSettings settings; settings.stdin_content = Json::stringify(snapshot); int code = 0; - auto result = cmd_execute_and_stream_lines(cmd, settings, [&code](StringView line) { + auto result = cmd_execute_and_stream_lines(context, cmd, settings, [&code](StringView line) { if (Strings::starts_with(line, guid_marker)) { code = std::strtol(line.data() + guid_marker.size(), nullptr, 10); } - else - { - Debug::println(line); - } }); auto r = result.get(); @@ -523,93 +819,100 @@ namespace vcpkg return false; } - ExpectedL put_file(const ReadOnlyFilesystem&, - StringView url, - const std::vector& secrets, - View headers, - const Path& file, - StringView method) + static bool store_to_asset_cache_impl(DiagnosticContext& context, + StringView raw_url, + const SanitizedUrl& sanitized_url, + StringLiteral method, + View headers, + const Path& file) { static constexpr StringLiteral guid_marker = "9a1db05f-a65d-419b-aa72-037fb4d0672e"; - if (Strings::starts_with(url, "ftp://")) + if (Strings::starts_with(raw_url, "ftp://")) { // HTTP headers are ignored for FTP clients auto ftp_cmd = Command{"curl"}; - ftp_cmd.string_arg(url_encode_spaces(url)); + ftp_cmd.string_arg(url_encode_spaces(raw_url)); ftp_cmd.string_arg("-T").string_arg(file); - auto maybe_res = cmd_execute_and_capture_output(ftp_cmd); + auto maybe_res = cmd_execute_and_capture_output(context, ftp_cmd); if (auto res = maybe_res.get()) { if (res->exit_code == 0) { - return 0; + return true; } - Debug::print(res->output, '\n'); - return msg::format_error(msgCurlFailedToPut, - msg::exit_code = res->exit_code, - msg::url = replace_secrets(url.to_string(), secrets)); + context.report_error_with_log( + res->output, msgCurlFailedToPut, msg::exit_code = res->exit_code, msg::url = sanitized_url); + return false; } - return std::move(maybe_res).error(); + return false; } auto http_cmd = Command{"curl"}.string_arg("-X").string_arg(method); - for (auto&& header : headers) - { - http_cmd.string_arg("-H").string_arg(header); - } - + add_curl_headers(http_cmd, headers); http_cmd.string_arg("-w").string_arg("\\n" + guid_marker.to_string() + "%{http_code}"); - http_cmd.string_arg(url); + http_cmd.string_arg(raw_url); http_cmd.string_arg("-T").string_arg(file); int code = 0; - auto res = cmd_execute_and_stream_lines(http_cmd, [&code](StringView line) { + auto res = cmd_execute_and_stream_lines(context, http_cmd, [&code](StringView line) { if (Strings::starts_with(line, guid_marker)) { code = std::strtol(line.data() + guid_marker.size(), nullptr, 10); } }); - if (auto pres = res.get()) + auto pres = res.get(); + if (!pres) { - if (*pres != 0 || (code >= 100 && code < 200) || code >= 300) - { - return msg::format_error( - msgCurlFailedToPutHttp, msg::exit_code = *pres, msg::url = url, msg::value = code); - } + return false; + } + + if (*pres != 0 || (code >= 100 && code < 200) || code >= 300) + { + context.report_error(msg::format( + msgCurlFailedToPutHttp, msg::exit_code = *pres, msg::url = sanitized_url, msg::value = code)); + return false; } - msg::println(msgAssetCacheSuccesfullyStored, - msg::path = file.filename(), - msg::url = replace_secrets(url.to_string(), secrets)); - return 0; + + return true; + } + + bool store_to_asset_cache(DiagnosticContext& context, + StringView raw_url, + const SanitizedUrl& sanitized_url, + StringLiteral method, + View headers, + const Path& file) + { + if (store_to_asset_cache_impl(context, raw_url, sanitized_url, method, headers, file)) + { + context.statusln(msg::format(msgAssetCacheSuccesfullyStored)); + return true; + } + + return false; } std::string format_url_query(StringView base_url, View query_params) { - auto url = base_url.to_string(); if (query_params.empty()) { - return url; + return base_url.to_string(); } - return url + "?" + Strings::join("&", query_params); + return fmt::format(FMT_COMPILE("{}?{}"), base_url, fmt::join(query_params, "&")); } - ExpectedL invoke_http_request(StringView method, - View headers, - StringView url, - StringView data) + Optional invoke_http_request(DiagnosticContext& context, + StringLiteral method, + View headers, + StringView raw_url, + StringView data) { auto cmd = Command{"curl"}.string_arg("-s").string_arg("-L"); - cmd.string_arg("-H").string_arg( - fmt::format("User-Agent: vcpkg/{}-{} (curl)", VCPKG_BASE_VERSION_AS_STRING, VCPKG_VERSION_AS_STRING)); - - for (auto&& header : headers) - { - cmd.string_arg("-H").string_arg(header); - } + add_curl_headers(cmd, headers); cmd.string_arg("-X").string_arg(method); @@ -618,92 +921,78 @@ namespace vcpkg cmd.string_arg("--data-raw").string_arg(data); } - cmd.string_arg(url_encode_spaces(url)); + cmd.string_arg(url_encode_spaces(raw_url)); + + auto maybe_output = cmd_execute_and_capture_output(context, cmd); + if (auto output = check_zero_exit_code(context, maybe_output, "curl")) + { + return *output; + } - return flatten_out(cmd_execute_and_capture_output(cmd), "curl"); + return nullopt; } #if defined(_WIN32) - enum class WinHttpTrialResult - { - failed, - succeeded, - retry - }; - - static WinHttpTrialResult download_winhttp_trial(const Filesystem& fs, - WinHttpSession& s, + static WinHttpTrialResult download_winhttp_trial(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const Filesystem& fs, + const WinHttpSession& s, const Path& download_path_part_path, - SplitURIView split_uri, + SplitUrlView split_uri_view, StringView hostname, INTERNET_PORT port, - StringView sanitized_url, - std::vector& errors, - MessageSink& progress_sink) + const SanitizedUrl& sanitized_url) { - auto maybe_conn = WinHttpConnection::make(s.m_hSession.h, hostname, port, sanitized_url); - const auto conn = maybe_conn.get(); - if (!conn) + WinHttpConnection conn; + if (!conn.connect(context, s, hostname, port, sanitized_url)) { - errors.push_back(std::move(maybe_conn).error()); return WinHttpTrialResult::retry; } - auto maybe_req = WinHttpRequest::make( - conn->m_hConnect.h, split_uri.path_query_fragment, sanitized_url, split_uri.scheme == "https"); - const auto req = maybe_req.get(); - if (!req) + WinHttpRequest req; + if (!req.open( + context, conn, split_uri_view.path_query_fragment, sanitized_url, split_uri_view.scheme == "https")) { - errors.push_back(std::move(maybe_req).error()); return WinHttpTrialResult::retry; } - auto maybe_status = req->query_status(); + auto maybe_status = req.query_status(context, sanitized_url); const auto status = maybe_status.get(); if (!status) { - errors.push_back(std::move(maybe_status).error()); return WinHttpTrialResult::retry; } if (*status < 200 || *status >= 300) { - errors.push_back( - msg::format_error(msgDownloadFailedStatusCode, msg::url = sanitized_url, msg::value = *status)); + context.report_error(msgDownloadFailedStatusCode, msg::url = sanitized_url, msg::value = *status); return WinHttpTrialResult::failed; } - auto f = fs.open_for_write(download_path_part_path, VCPKG_LINE_INFO); - auto maybe_write = req->write_response_body(f, progress_sink); - const auto write = maybe_write.get(); - if (!write) - { - errors.push_back(std::move(maybe_write).error()); - return WinHttpTrialResult::retry; - } - - return WinHttpTrialResult::succeeded; + return req.write_response_body(context, + machine_readable_progress, + sanitized_url, + fs.open_for_write(download_path_part_path, VCPKG_LINE_INFO)); } /// /// Download a file using WinHTTP -- only supports HTTP and HTTPS /// - static bool download_winhttp(const Filesystem& fs, + static bool download_winhttp(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const Filesystem& fs, const Path& download_path_part_path, - SplitURIView split_uri, - const std::string& url, - const std::vector& secrets, - std::vector& errors, - MessageSink& progress_sink) + SplitUrlView split_url_view, + const SanitizedUrl& sanitized_url) { // `download_winhttp` does not support user or port syntax in authorities - auto hostname = split_uri.authority.value_or_exit(VCPKG_LINE_INFO).substr(2); + auto hostname = split_url_view.authority.value_or_exit(VCPKG_LINE_INFO).substr(2); INTERNET_PORT port; - if (split_uri.scheme == "https") + if (split_url_view.scheme == "https") { port = INTERNET_DEFAULT_HTTPS_PORT; } - else if (split_uri.scheme == "http") + else if (split_url_view.scheme == "http") { port = INTERNET_DEFAULT_HTTP_PORT; } @@ -716,39 +1005,106 @@ namespace vcpkg const auto dir = download_path_part_path.parent_path(); fs.create_directories(dir, VCPKG_LINE_INFO); - const auto sanitized_url = replace_secrets(url, secrets); - static auto s = WinHttpSession::make(sanitized_url).value_or_exit(VCPKG_LINE_INFO); - for (size_t trials = 0; trials < 4; ++trials) + WinHttpSession s; + if (!s.open(context, sanitized_url)) { - if (trials > 0) - { - // 1s, 2s, 4s - const auto trialMs = 500 << trials; - msg::println_warning(msgDownloadFailedRetrying, msg::value = trialMs); - std::this_thread::sleep_for(std::chrono::milliseconds(trialMs)); - } + return false; + } + + AttemptDiagnosticContext adc{context}; + switch (download_winhttp_trial(adc, + machine_readable_progress, + fs, + s, + download_path_part_path, + split_url_view, + hostname, + port, + sanitized_url)) + { + case WinHttpTrialResult::succeeded: adc.commit(); return true; + case WinHttpTrialResult::failed: adc.commit(); return false; + case WinHttpTrialResult::retry: break; + } - switch (download_winhttp_trial( - fs, s, download_path_part_path, split_uri, hostname, port, sanitized_url, errors, progress_sink)) + for (size_t trials = 1; trials < 4; ++trials) + { + // 1s, 2s, 4s + const auto trialMs = 500 << trials; + adc.handle(); + context.statusln( + DiagnosticLine(DiagKind::Warning, + msg::format(msgDownloadFailedRetrying, msg::value = trialMs, msg::url = sanitized_url)) + .to_message_line()); + std::this_thread::sleep_for(std::chrono::milliseconds(trialMs)); + switch (download_winhttp_trial(adc, + machine_readable_progress, + fs, + s, + download_path_part_path, + split_url_view, + hostname, + port, + sanitized_url)) { - case WinHttpTrialResult::failed: return false; - case WinHttpTrialResult::succeeded: return true; + case WinHttpTrialResult::succeeded: adc.commit(); return true; + case WinHttpTrialResult::failed: adc.commit(); return false; case WinHttpTrialResult::retry: break; } } + adc.commit(); return false; } #endif - static bool try_download_file(const Filesystem& fs, - const std::string& url, - View headers, - const Path& download_path, - const Optional& sha512, - const std::vector& secrets, - std::vector& errors, - MessageSink& progress_sink) + enum class DownloadPrognosis + { + Success, + OtherError, + NetworkErrorProxyMightHelp + }; + + static bool check_combine_download_prognosis(DownloadPrognosis& target, DownloadPrognosis individual_call) + { + switch (individual_call) + { + case DownloadPrognosis::Success: return true; + case DownloadPrognosis::OtherError: + if (target == DownloadPrognosis::Success) + { + target = DownloadPrognosis::OtherError; + } + + return false; + case DownloadPrognosis::NetworkErrorProxyMightHelp: + if (target == DownloadPrognosis::Success || target == DownloadPrognosis::OtherError) + { + target = DownloadPrognosis::NetworkErrorProxyMightHelp; + } + + return false; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + static void maybe_report_proxy_might_help(DiagnosticContext& context, DownloadPrognosis prognosis) + { + if (prognosis == DownloadPrognosis::NetworkErrorProxyMightHelp) + { + context.report(DiagnosticLine{DiagKind::Note, msg::format(msgDownloadFailedProxySettings)}); + } + } + + static DownloadPrognosis try_download_file(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const Filesystem& fs, + StringView raw_url, + const SanitizedUrl& sanitized_url, + View headers, + const Path& download_path, + const StringView* maybe_sha512, + std::string* out_sha512) { auto download_path_part_path = download_path; download_path_part_path += "."; @@ -762,119 +1118,144 @@ namespace vcpkg #if defined(_WIN32) auto maybe_https_proxy_env = get_environment_variable(EnvironmentVariableHttpsProxy); bool needs_proxy_auth = false; - if (maybe_https_proxy_env) + if (auto proxy_url = maybe_https_proxy_env.get()) { - const auto& proxy_url = maybe_https_proxy_env.value_or_exit(VCPKG_LINE_INFO); - needs_proxy_auth = proxy_url.find('@') != std::string::npos; + needs_proxy_auth = proxy_url->find('@') != std::string::npos; } if (headers.size() == 0 && !needs_proxy_auth) { - auto split_uri = split_uri_view(url).value_or_exit(VCPKG_LINE_INFO); - if (split_uri.scheme == "https" || split_uri.scheme == "http") + auto maybe_split_uri_view = parse_split_url_view(raw_url); + auto split_uri_view = maybe_split_uri_view.get(); + if (!split_uri_view) + { + context.report_error(msgInvalidUri, msg::value = sanitized_url); + return DownloadPrognosis::OtherError; + } + + if (split_uri_view->scheme == "https" || split_uri_view->scheme == "http") { - auto maybe_authority = split_uri.authority.get(); + auto maybe_authority = split_uri_view->authority.get(); if (!maybe_authority) { - Checks::msg_exit_with_error(VCPKG_LINE_INFO, msgInvalidUri, msg::value = url); + context.report_error(msg::format(msgInvalidUri, msg::value = sanitized_url)); + return DownloadPrognosis::OtherError; } - auto authority = maybe_authority->substr(2); - // This check causes complex URLs (non-default port, embedded basic auth) to be passed down to curl.exe + auto authority = StringView{*maybe_authority}.substr(2); + // This check causes complex URLs (non-default port, embedded basic auth) to be passed down to + // curl.exe if (Strings::find_first_of(authority, ":@") == authority.end()) { - if (download_winhttp(fs, download_path_part_path, split_uri, url, secrets, errors, progress_sink)) + if (!download_winhttp(context, + machine_readable_progress, + fs, + download_path_part_path, + *split_uri_view, + sanitized_url)) { - auto maybe_hash_check = check_downloaded_file_hash(fs, sha512, url, download_path_part_path); - if (maybe_hash_check.has_value()) - { - fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO); - return true; - } - else - { - errors.push_back(std::move(maybe_hash_check).error()); - } + return DownloadPrognosis::NetworkErrorProxyMightHelp; } - return false; + + if (!check_downloaded_file_hash( + context, fs, sanitized_url, download_path_part_path, maybe_sha512, out_sha512)) + { + return DownloadPrognosis::OtherError; + } + + fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO); + return DownloadPrognosis::Success; } } } #endif auto cmd = Command{"curl"} .string_arg("--fail") + .string_arg("--retry") + .string_arg("3") .string_arg("-L") - .string_arg(url_encode_spaces(url)) + .string_arg(url_encode_spaces(raw_url)) .string_arg("--create-dirs") .string_arg("--output") .string_arg(download_path_part_path); - for (auto&& header : headers) - { - cmd.string_arg("-H").string_arg(header); - } - - std::string non_progress_content; - auto maybe_exit_code = cmd_execute_and_stream_lines(cmd, [&](StringView line) { + add_curl_headers(cmd, headers); + bool seen_any_curl_errors = false; + // if seen_any_curl_errors, contains the curl error lines starting with "curl:" + // otherwise, contains all curl's output unless it is the machine readable output + std::vector likely_curl_errors; + auto maybe_exit_code = cmd_execute_and_stream_lines(context, cmd, [&](StringView line) { const auto maybe_parsed = try_parse_curl_progress_data(line); if (const auto parsed = maybe_parsed.get()) { - progress_sink.print(Color::none, fmt::format("{}%\n", parsed->total_percent)); - } - else - { - non_progress_content.append(line.data(), line.size()); - non_progress_content.push_back('\n'); + machine_readable_progress.println(Color::none, + LocalizedString::from_raw(fmt::format("{}%", parsed->total_percent))); + return; } - }); - const auto sanitized_url = replace_secrets(url, secrets); - if (const auto exit_code = maybe_exit_code.get()) - { - if (*exit_code != 0) + static constexpr StringLiteral WarningColon = "warning: "; + if (Strings::case_insensitive_ascii_starts_with(line, WarningColon)) { - errors.push_back( - msg::format_error(msgDownloadFailedCurl, msg::url = sanitized_url, msg::exit_code = *exit_code) - .append_raw('\n') - .append_raw(non_progress_content)); - return false; + context.statusln( + DiagnosticLine{DiagKind::Warning, LocalizedString::from_raw(line.substr(WarningColon.size()))} + .to_message_line()); + return; } - auto maybe_hash_check = check_downloaded_file_hash(fs, sha512, sanitized_url, download_path_part_path); - if (maybe_hash_check.has_value()) + // clang-format off + // example: + // 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: nonexistent.example.com + // clang-format on + static constexpr StringLiteral CurlColon = "curl:"; + auto curl_start = std::search(line.begin(), line.end(), CurlColon.begin(), CurlColon.end()); + if (curl_start == line.end()) { - fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO); - return true; + if (seen_any_curl_errors) + { + return; + } + + curl_start = line.begin(); } else { - errors.push_back(std::move(maybe_hash_check).error()); + if (!seen_any_curl_errors) + { + seen_any_curl_errors = true; + likely_curl_errors.clear(); + } } - } - else + + likely_curl_errors.emplace_back(curl_start, line.end()); + }); + + const auto exit_code = maybe_exit_code.get(); + if (!exit_code) { - errors.push_back(std::move(maybe_exit_code).error()); + return DownloadPrognosis::OtherError; } - return false; - } - - static Optional try_download_file(const Filesystem& fs, - View urls, - View headers, - const Path& download_path, - const Optional& sha512, - const std::vector& secrets, - std::vector& errors, - MessageSink& progress_sink) - { - for (auto&& url : urls) + if (*exit_code != 0) { - if (try_download_file(fs, url, headers, download_path, sha512, secrets, errors, progress_sink)) + std::set seen_errors; + for (StringView likely_curl_error : likely_curl_errors) { - return url; + auto seen_position = seen_errors.lower_bound(likely_curl_error); + if (seen_position == seen_errors.end() || *seen_position != likely_curl_error) + { + seen_errors.emplace_hint(seen_position, likely_curl_error); + context.report(DiagnosticLine{DiagKind::Error, LocalizedString::from_raw(likely_curl_error)}); + } } + + return DownloadPrognosis::NetworkErrorProxyMightHelp; } - return nullopt; + if (!check_downloaded_file_hash(context, fs, sanitized_url, download_path_part_path, maybe_sha512, out_sha512)) + { + return DownloadPrognosis::OtherError; + } + + fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO); + return DownloadPrognosis::Success; } View azure_blob_headers() @@ -883,174 +1264,685 @@ namespace vcpkg return s_headers; } - bool DownloadManager::get_block_origin() const { return m_config.m_block_origin; } - - bool DownloadManager::asset_cache_configured() const { return m_config.m_read_url_template.has_value(); } - - void DownloadManager::download_file(const Filesystem& fs, - const std::string& url, - View headers, - const Path& download_path, - const Optional& sha512, - MessageSink& progress_sink) const + bool parse_curl_status_line(DiagnosticContext& context, + std::vector& http_codes, + StringLiteral prefix, + StringView this_line) { - this->download_file(fs, View(&url, 1), headers, download_path, sha512, progress_sink); - } + if (!Strings::starts_with(this_line, prefix)) + { + return false; + } - std::string DownloadManager::download_file(const Filesystem& fs, - View urls, - View headers, - const Path& download_path, - const Optional& sha512, - MessageSink& progress_sink) const - { - std::vector errors; - bool block_origin_enabled = m_config.m_block_origin; + auto first = this_line.begin(); + const auto last = this_line.end(); + first += prefix.size(); + const auto first_http_code = first; - if (urls.size() == 0) + int http_code; + for (;; ++first) { - if (auto hash = sha512.get()) + if (first == last) { - errors.push_back(msg::format_error(msgNoUrlsAndHashSpecified, msg::sha = *hash)); + // this output is broken, even if we don't know %{exit_code} or ${errormsg}, the spaces in front + // of them should still be printed. + return false; } - else + + if (!ParserBase::is_ascii_digit(*first)) { - errors.push_back(msg::format_error(msgNoUrlsAndNoHashSpecified)); + http_code = Strings::strto(StringView{first_http_code, first}).value_or_exit(VCPKG_LINE_INFO); + break; } } - if (auto hash = sha512.get()) + if (*first != ' ' || ++first == last) + { + // didn't see the space after the http_code + return false; + } + + if (*first == ' ') + { + // old curl that doesn't understand %{exit_code}, this is the space after it + http_codes.emplace_back(http_code); + return false; + } + + if (!ParserBase::is_ascii_digit(*first)) + { + // not exit_code + return false; + } + + const auto first_exit_code = first; + for (;;) { - if (auto read_template = m_config.m_read_url_template.get()) + if (++first == last) { - auto read_url = Strings::replace_all(*read_template, "", *hash); - if (try_download_file(fs, - read_url, - m_config.m_read_headers, - download_path, - sha512, - m_config.m_secrets, - errors, - progress_sink)) + // didn't see the space after %{exit_code} + return false; + } + + if (*first == ' ') + { + // the space after exit_code, everything after this space is the error message if any + http_codes.emplace_back(http_code); + auto exit_code = Strings::strto(StringView{first_exit_code, first}).value_or_exit(VCPKG_LINE_INFO); + // note that this gets the space out of the output :) + if (exit_code != 0) { - msg::println(msgAssetCacheHit, - msg::path = download_path.filename(), - msg::url = replace_secrets(read_url, m_config.m_secrets)); - return read_url; + context.report_error(msg::format(msgCurlFailedGeneric, msg::exit_code = exit_code) + .append_raw(StringView{first, last})); } - else if (block_origin_enabled) + + return true; + } + + if (!ParserBase::is_ascii_digit(*first)) + { + // non numeric exit_code? + return false; + } + } + } + + static DownloadPrognosis download_file_azurl_asset_cache(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const AssetCachingSettings& asset_cache_settings, + const Filesystem& fs, + const Path& download_path, + StringView target_filename, + const StringView* maybe_sha512, + std::string* out_sha512) + { + auto read_template = asset_cache_settings.m_read_url_template.get(); + if (!read_template || !maybe_sha512) + { + // can't use http asset caches when none are configured or we don't have a SHA + return DownloadPrognosis::OtherError; + } + + auto raw_read_url = Strings::replace_all(*read_template, "", *maybe_sha512); + SanitizedUrl sanitized_read_url{raw_read_url, asset_cache_settings.m_secrets}; + context.statusln(msg::format(msgAssetCacheConsult, msg::path = target_filename, msg::url = sanitized_read_url)); + return try_download_file(context, + machine_readable_progress, + fs, + raw_read_url, + sanitized_read_url, + asset_cache_settings.m_read_headers, + download_path, + maybe_sha512, + out_sha512); + } + + static void report_script_while_command_line(DiagnosticContext& context, const std::string& raw_command) + { + context.report(DiagnosticLine{ + DiagKind::Note, + msg::format(msgWhileRunningAssetCacheScriptCommandLine).append_raw(": ").append_raw(raw_command)}); + } + + static void report_script_failed_to_make_file(DiagnosticContext& context, + const std::string& raw_command, + const Path& download_path_part_path) + { + context.report(DiagnosticLine{ + DiagKind::Error, download_path_part_path, msg::format(msgAssetCacheScriptFailedToWriteFile)}); + context.report(DiagnosticLine{ + DiagKind::Note, msg::format(msgAssetCacheScriptCommandLine).append_raw(": ").append_raw(raw_command)}); + } + + static void report_asset_cache_authoritative_urls(DiagnosticContext& context, + DiagKind first_message_kind, + msg::MessageT first_message, + const std::vector& sanitized_urls) + { + auto first_sanitized_url = sanitized_urls.begin(); + const auto last_sanitized_url = sanitized_urls.end(); + if (first_sanitized_url != last_sanitized_url) + { + context.report( + DiagnosticLine{first_message_kind, msg::format(first_message, msg::url = *first_sanitized_url)}); + while (++first_sanitized_url != last_sanitized_url) + { + context.report( + DiagnosticLine{DiagKind::Note, msg::format(msgDownloadOrUrl, msg::url = *first_sanitized_url)}); + } + } + } + + static DownloadPrognosis download_file_script_asset_cache(DiagnosticContext& context, + const AssetCachingSettings& asset_cache_settings, + const Filesystem& fs, + View raw_urls, + const std::vector& sanitized_urls, + const Path& download_path, + StringView target_filename, + const StringView* maybe_sha512, + std::string* out_sha512) + { + using Hash::HashPrognosis; + auto script = asset_cache_settings.m_script.get(); + if (!script) + { + return DownloadPrognosis::OtherError; + } + + if (raw_urls.empty() && !maybe_sha512) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + context.statusln(msg::format(msgAssetCacheConsultScript, msg::path = target_filename)); + const auto download_path_part_path = fmt::format("{}.{}.part", download_path, get_process_id()); + Lazy escaped_url; + const auto escaped_dpath = Command(download_path_part_path).extract(); + auto maybe_raw_command = api_stable_format(context, *script, [&](std::string& out, StringView key) { + if (key == "url") + { + if (raw_urls.empty()) { - msg::println(msgAssetCacheMissBlockOrigin, msg::path = download_path.filename()); + if (!maybe_sha512) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + context.report_error( + msg::format(msgAssetCacheScriptNeedsUrl, msg::value = *script, msg::sha = *maybe_sha512)); + return false; } - else + + Strings::append(out, escaped_url.get_lazy([&] { return Command(raw_urls[0]).extract(); })); + return true; + } + + if (key == "sha512") + { + if (maybe_sha512) { - msg::println(msgAssetCacheMiss, msg::url = urls[0]); + out.append(maybe_sha512->data(), maybe_sha512->size()); + return true; } + + context.report_error( + msg::format(msgAssetCacheScriptNeedsSha, msg::value = *script, msg::url = sanitized_urls[0])); + return false; } - else if (auto script = m_config.m_script.get()) + + if (key == "dst") { - if (urls.size() != 0) - { - const auto download_path_part_path = download_path + fmt::format(".{}.part", get_process_id()); - const auto escaped_url = Command(urls[0]).extract(); - const auto escaped_sha512 = Command(*hash).extract(); - const auto escaped_dpath = Command(download_path_part_path).extract(); - Command cmd; - cmd.raw_arg(api_stable_format(*script, [&](std::string& out, StringView key) { - if (key == "url") - { - Strings::append(out, escaped_url); - } - else if (key == "sha512") - { - Strings::append(out, escaped_sha512); - } - else if (key == "dst") - { - Strings::append(out, escaped_dpath); - } - }).value_or_exit(VCPKG_LINE_INFO)); - - RedirectedProcessLaunchSettings settings; - settings.environment = get_clean_environment(); - settings.echo_in_debug = EchoInDebug::Show; - auto maybe_res = flatten(cmd_execute_and_capture_output(cmd, settings), ""); - if (maybe_res) + Strings::append(out, escaped_dpath); + return true; + } + + context.report_error(msg::format(msgAssetCacheScriptBadVariable, msg::value = *script, msg::list = key)); + context.report( + DiagnosticLine{DiagKind::Note, msg::format(msgAssetCacheScriptBadVariableHint, msg::list = key)}); + return false; + }); + + auto raw_command = maybe_raw_command.get(); + if (!raw_command) + { + return DownloadPrognosis::OtherError; + } + + Command cmd; + cmd.raw_arg(*raw_command); + RedirectedProcessLaunchSettings settings; + settings.environment = get_clean_environment(); + auto maybe_res = cmd_execute_and_stream_lines( + context, cmd, settings, [&](StringView line) { context.statusln(LocalizedString::from_raw(line)); }); + auto res = maybe_res.get(); + if (!res) + { + report_script_while_command_line(context, *raw_command); + return DownloadPrognosis::OtherError; + } + + if (*res != 0) + { + context.report_error(msg::format(msgAssetCacheScriptFailed, msg::exit_code = *res)); + context.report(DiagnosticLine{ + DiagKind::Note, msg::format(msgAssetCacheScriptCommandLine).append_raw(": ").append_raw(*raw_command)}); + return DownloadPrognosis::OtherError; + } + + if (maybe_sha512) + { + auto hash_result = Hash::get_file_hash(context, fs, download_path_part_path, Hash::Algorithm::Sha512); + switch (hash_result.prognosis) + { + case HashPrognosis::Success: + if (Strings::case_insensitive_ascii_equals(*maybe_sha512, hash_result.hash)) { - auto maybe_success = - try_verify_downloaded_file_hash(fs, "", download_path_part_path, *hash); - if (maybe_success) + if (out_sha512) { - fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO); - return urls[0]; + *out_sha512 = std::move(hash_result.hash); } - errors.push_back(std::move(maybe_success).error()); + fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO); + return DownloadPrognosis::Success; } - else + + context.report(DiagnosticLine{DiagKind::Error, + download_path_part_path, + msg::format(msgAssetCacheScriptFailedToWriteCorrectHash)}); + context.report(DiagnosticLine{ + DiagKind::Note, + msg::format(msgAssetCacheScriptCommandLine).append_raw(": ").append_raw(*raw_command)}); + context.report(DiagnosticLine{ + DiagKind::Note, + msg::format(msgDownloadFailedHashMismatchExpectedHash, msg::sha = *maybe_sha512)}); + context.report(DiagnosticLine{ + DiagKind::Note, + msg::format(msgDownloadFailedHashMismatchActualHash, msg::sha = hash_result.hash)}); + if (out_sha512) { - errors.push_back(std::move(maybe_res).error()); + *out_sha512 = std::move(hash_result.hash); } - } + + return DownloadPrognosis::OtherError; + case HashPrognosis::FileNotFound: + report_script_failed_to_make_file(context, *raw_command, download_path_part_path); + return DownloadPrognosis::OtherError; + case HashPrognosis::OtherError: + report_script_while_command_line(context, *raw_command); + return DownloadPrognosis::OtherError; + default: Checks::unreachable(VCPKG_LINE_INFO); } } - if (block_origin_enabled) + if (fs.exists(download_path_part_path, VCPKG_LINE_INFO)) { - msg::println_error(msgMissingAssetBlockOrigin, msg::path = download_path.filename()); + fs.rename(download_path_part_path, download_path, VCPKG_LINE_INFO); + return DownloadPrognosis::Success; } - else + + report_script_failed_to_make_file(context, *raw_command, download_path_part_path); + return DownloadPrognosis::OtherError; + } + + static DownloadPrognosis download_file_asset_cache(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const AssetCachingSettings& asset_cache_settings, + const Filesystem& fs, + View raw_urls, + const std::vector& sanitized_urls, + const Path& download_path, + StringView target_filename, + const StringView* maybe_sha512, + std::string* out_sha512) + { + switch (download_file_azurl_asset_cache(context, + machine_readable_progress, + asset_cache_settings, + fs, + download_path, + target_filename, + maybe_sha512, + out_sha512)) { - if (urls.size() != 0) + case DownloadPrognosis::Success: return DownloadPrognosis::Success; + case DownloadPrognosis::OtherError: + return download_file_script_asset_cache(context, + asset_cache_settings, + fs, + raw_urls, + sanitized_urls, + download_path, + target_filename, + maybe_sha512, + out_sha512); + case DownloadPrognosis::NetworkErrorProxyMightHelp: return DownloadPrognosis::NetworkErrorProxyMightHelp; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + static void report_download_success_and_maybe_upload(DiagnosticContext& context, + const Path& download_path, + StringView target_filename, + const AssetCachingSettings& asset_cache_settings, + const StringView* maybe_sha512) + { + auto url_template = asset_cache_settings.m_write_url_template.get(); + if (maybe_sha512 && url_template && !url_template->empty()) + { + auto raw_upload_url = Strings::replace_all(*url_template, "", *maybe_sha512); + SanitizedUrl sanitized_upload_url{raw_upload_url, asset_cache_settings.m_secrets}; + context.statusln(msg::format( + msgDownloadSuccesfulUploading, msg::path = target_filename, msg::url = sanitized_upload_url)); + WarningDiagnosticContext wdc{context}; + if (!store_to_asset_cache(wdc, + raw_upload_url, + sanitized_upload_url, + "PUT", + asset_cache_settings.m_write_headers, + download_path)) { - msg::println(msgDownloadingUrl, msg::url = download_path.filename()); - auto maybe_url = try_download_file( - fs, urls, headers, download_path, sha512, m_config.m_secrets, errors, progress_sink); - if (auto url = maybe_url.get()) - { - msg::println(msgDownloadSuccesful, msg::path = download_path.filename()); + context.report(DiagnosticLine{DiagKind::Warning, + msg::format(msgFailedToStoreBackToMirror, + msg::path = target_filename, + msg::url = sanitized_upload_url)}); + } + } + else + { + context.statusln(msg::format(msgDownloadSuccesful, msg::path = target_filename)); + } + } - if (auto hash = sha512.get()) - { - auto maybe_push = put_file_to_mirror(fs, download_path, *hash); - if (!maybe_push) - { - msg::println_warning(msgFailedToStoreBackToMirror, - msg::path = download_path.filename(), - msg::url = replace_secrets(download_path.c_str(), m_config.m_secrets)); - msg::println(maybe_push.error()); - } - } + bool download_file_asset_cached(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const AssetCachingSettings& asset_cache_settings, + const Filesystem& fs, + const std::string& url, + View headers, + const Path& download_path, + const Optional& maybe_sha512) + { + return download_file_asset_cached(context, + machine_readable_progress, + asset_cache_settings, + fs, + View(&url, 1), + headers, + download_path, + maybe_sha512); + } - return *url; + static bool download_file_asset_cached_sanitized_sha(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const AssetCachingSettings& asset_cache_settings, + const Filesystem& fs, + View raw_urls, + View headers, + const Path& download_path, + const StringView* maybe_sha512, + std::string* out_sha512) + { + // Design goals: + // * We want it to be clear when asset cache(s) are used. This means not printing the authoritative URL in a + // 'downloading' message when we aren't looking at it. + // * We don't want to say that something is an error / failure unless it actually is. This means asset cache + // failures followed by authoritative success must print only success. This also means that we can't print + // asset cache errors immediately, since they might be 'eaten' by a subsequent authoritative success. + // * We want to print something before 'going to sleep' for network access ever, so if the machine where that + // network access is is being slow or whatever the user understands. + // * We want to print errors and warnings as close to when they happen as possible notwithstanding other goals. + // * We want to print the proxy warning if and only if a failure looks like it might be something a proxy could + // fix. For example, successful network access with the wrong SHA is not proxy-fixable. + // * If we are printing the proxy message, we want to take some effort to only print it once, and put it on the + // *last* HTTP failure we print. This avoids a ton of console spew and makes it likely to be near the end of + // failure output and thus not scrolled off the top of the console buffer. + // * We consider hash check failure the same as a network I/O failure, and let other sources 'fix' the problem. + // + // See examples of console output in asset-caching.ps1 + + // Note: no secrets for the input URLs + std::vector sanitized_urls = + Util::fmap(raw_urls, [&](const std::string& url) { return SanitizedUrl{url, {}}; }); + const auto last_sanitized_url = sanitized_urls.end(); + const auto target_filename = download_path.filename(); + bool can_read_asset_cache = false; + if (asset_cache_settings.m_read_url_template.has_value() && maybe_sha512) + { + // url asset cache reads need a hash + can_read_asset_cache = true; + } + + if (asset_cache_settings.m_script.has_value() && (maybe_sha512 || !raw_urls.empty())) + { + // script asset cache reads need either a hash or a URL + can_read_asset_cache = true; + } + + if (raw_urls.empty()) + { + // try to fetch from asset cache only without a known URL + if (maybe_sha512) + { + if (can_read_asset_cache) + { + context.statusln( + msg::format(msgDownloadingAssetShaToFile, msg::sha = *maybe_sha512, msg::path = download_path)); } else { - msg::println(msgDownloadFailedProxySettings, - msg::path = download_path.filename(), - msg::url = "https://github.com/microsoft/vcpkg-tool/pull/77"); + context.report_error(msg::format( + msgDownloadingAssetShaWithoutAssetCache, msg::sha = *maybe_sha512, msg::path = download_path)); + return false; } } + else + { + context.report_error(msgNoUrlsAndNoHashSpecified); + return false; + } } - for (LocalizedString& error : errors) + if (asset_cache_settings.m_block_origin && !can_read_asset_cache) { - msg::println(error); + // this will emit msgAssetCacheMissBlockOrigin below, this message just ensures the filename is mentioned in + // the output at all + context.statusln(msg::format(msgDownloadingFile, msg::path = target_filename)); } - Checks::exit_fail(VCPKG_LINE_INFO); + DownloadPrognosis asset_cache_prognosis = DownloadPrognosis::Success; + // the asset cache downloads might fail, but that's OK if we can download the file from an authoritative source + AttemptDiagnosticContext asset_cache_attempt_context{context}; + if (check_combine_download_prognosis(asset_cache_prognosis, + download_file_asset_cache(asset_cache_attempt_context, + machine_readable_progress, + asset_cache_settings, + fs, + raw_urls, + sanitized_urls, + download_path, + target_filename, + maybe_sha512, + out_sha512))) + { + asset_cache_attempt_context.commit(); + if (raw_urls.empty()) + { + context.statusln(msg::format(msgAssetCacheHit)); + return true; + } + + auto first_sanitized_url = sanitized_urls.begin(); + LocalizedString overall_url; + overall_url.append_raw(first_sanitized_url->to_string()); + while (++first_sanitized_url != last_sanitized_url) + { + overall_url.append_raw(", ").append(msgDownloadOrUrl, msg::url = *first_sanitized_url); + } + + context.statusln(msg::format(msgAssetCacheHitUrl, msg::url = overall_url)); + return true; + } + + if (raw_urls.empty()) + { + asset_cache_attempt_context.commit(); + if (!maybe_sha512) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + context.report_error(msg::format(msgAssetCacheMissNoUrls, msg::sha = *maybe_sha512)); + maybe_report_proxy_might_help(context, asset_cache_prognosis); + return false; + } + + if (asset_cache_settings.m_block_origin) + { + asset_cache_attempt_context.commit(); + report_asset_cache_authoritative_urls( + context, DiagKind::Error, msgAssetCacheMissBlockOrigin, sanitized_urls); + maybe_report_proxy_might_help(context, asset_cache_prognosis); + return false; + } + + auto first_raw_url = raw_urls.begin(); + const auto last_raw_url = raw_urls.end(); + auto first_sanitized_url = sanitized_urls.begin(); + AttemptDiagnosticContext authoritative_attempt_context{context}; + DownloadPrognosis authoritative_prognosis = DownloadPrognosis::Success; + if (can_read_asset_cache) + { + context.statusln(msg::format(msgAssetCacheMiss, msg::url = *first_sanitized_url)); + } + else if (raw_urls.size() == 1) + { + context.statusln( + msg::format(msgDownloadingUrlToFile, msg::url = *first_sanitized_url, msg::path = target_filename)); + } + else + { + context.statusln(msg::format(msgDownloadingFileFirstAuthoritativeSource, + msg::path = target_filename, + msg::url = *first_sanitized_url)); + } + + if (check_combine_download_prognosis(authoritative_prognosis, + try_download_file(authoritative_attempt_context, + machine_readable_progress, + fs, + *first_raw_url, + *first_sanitized_url, + headers, + download_path, + maybe_sha512, + out_sha512))) + { + asset_cache_attempt_context.handle(); + authoritative_attempt_context.handle(); + report_download_success_and_maybe_upload( + context, download_path, target_filename, asset_cache_settings, maybe_sha512); + return true; + } + + while (++first_sanitized_url, ++first_raw_url != last_raw_url) + { + context.statusln(msg::format(msgDownloadTryingAuthoritativeSource, msg::url = *first_sanitized_url)); + if (check_combine_download_prognosis(authoritative_prognosis, + try_download_file(authoritative_attempt_context, + machine_readable_progress, + fs, + *first_raw_url, + *first_sanitized_url, + headers, + download_path, + maybe_sha512, + out_sha512))) + { + asset_cache_attempt_context.handle(); + authoritative_attempt_context.handle(); + report_download_success_and_maybe_upload( + context, download_path, target_filename, asset_cache_settings, maybe_sha512); + return true; + } + } + + if (asset_cache_prognosis == DownloadPrognosis::NetworkErrorProxyMightHelp && + authoritative_prognosis != DownloadPrognosis::NetworkErrorProxyMightHelp) + { + // reorder the proxy warning up to the asset cache prognosis if that's where it comes from + asset_cache_attempt_context.commit(); + maybe_report_proxy_might_help(context, asset_cache_prognosis); + authoritative_attempt_context.commit(); + return false; + } + + check_combine_download_prognosis(authoritative_prognosis, asset_cache_prognosis); + asset_cache_attempt_context.commit(); + authoritative_attempt_context.commit(); + maybe_report_proxy_might_help(context, authoritative_prognosis); + return false; + } + + bool download_file_asset_cached(DiagnosticContext& context, + MessageSink& machine_readable_progress, + const AssetCachingSettings& asset_cache_settings, + const Filesystem& fs, + View raw_urls, + View headers, + const Path& download_path, + const Optional& maybe_sha512_mixed_case) + { + if (auto sha512_mixed_case = maybe_sha512_mixed_case.get()) + { + static constexpr StringLiteral all_zero_sha = + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000"; + if (*sha512_mixed_case == all_zero_sha) + { + std::string actual_sha512; + if (download_file_asset_cached_sanitized_sha(context, + machine_readable_progress, + asset_cache_settings, + fs, + raw_urls, + headers, + download_path, + nullptr, + &actual_sha512)) + { + context.report_error(msg::format(msgDownloadFailedHashMismatchZero, msg::sha = actual_sha512)); + } + + return false; + } + + auto sha512 = Strings::ascii_to_lowercase(*sha512_mixed_case); + StringView sha512sv = sha512; + return download_file_asset_cached_sanitized_sha(context, + machine_readable_progress, + asset_cache_settings, + fs, + raw_urls, + headers, + download_path, + &sha512sv, + nullptr); + } + + return download_file_asset_cached_sanitized_sha(context, + machine_readable_progress, + asset_cache_settings, + fs, + raw_urls, + headers, + download_path, + nullptr, + nullptr); } - ExpectedL DownloadManager::put_file_to_mirror(const ReadOnlyFilesystem& fs, - const Path& file_to_put, - StringView sha512) const + bool store_to_asset_cache(DiagnosticContext& context, + const AssetCachingSettings& asset_cache_settings, + const Path& file_to_put, + StringView sha512) { - auto maybe_mirror_url = Strings::replace_all(m_config.m_write_url_template.value_or(""), "", sha512); - if (!maybe_mirror_url.empty()) + if (auto url_template = asset_cache_settings.m_write_url_template.get()) { - return put_file(fs, maybe_mirror_url, m_config.m_secrets, m_config.m_write_headers, file_to_put); + if (url_template->empty()) + { + return true; + } + + auto raw_upload_url = Strings::replace_all(*url_template, "", sha512); + SanitizedUrl sanitized_upload_url{raw_upload_url, asset_cache_settings.m_secrets}; + return store_to_asset_cache(context, + raw_upload_url, + sanitized_upload_url, + "PUT", + asset_cache_settings.m_write_headers, + file_to_put); } - return 0; + + return true; } Optional try_parse_curl_max5_size(StringView sv) @@ -1168,8 +2060,8 @@ namespace vcpkg const auto last = curl_progress_line.end(); if (parse_curl_uint_impl(result.total_percent, first, last) || parse_curl_max5_impl(result.total_size, first, last) || - parse_curl_uint_impl(result.recieved_percent, first, last) || - parse_curl_max5_impl(result.recieved_size, first, last) || + parse_curl_uint_impl(result.received_percent, first, last) || + parse_curl_max5_impl(result.received_size, first, last) || parse_curl_uint_impl(result.transfer_percent, first, last) || parse_curl_max5_impl(result.transfer_size, first, last) || parse_curl_max5_impl(result.average_download_speed, first, last) || diff --git a/src/vcpkg/base/files.cpp b/src/vcpkg/base/files.cpp index e466e97163..73139ad88c 100644 --- a/src/vcpkg/base/files.cpp +++ b/src/vcpkg/base/files.cpp @@ -1374,7 +1374,7 @@ namespace vcpkg FilePointer::FilePointer(const Path& path) : m_fs(nullptr), m_path(path) { } FilePointer::FilePointer() noexcept : m_fs(nullptr), m_path{} { } - FilePointer::FilePointer(FilePointer&& other) noexcept : m_fs(other.m_fs), m_path(std ::move(other.m_path)) + FilePointer::FilePointer(FilePointer&& other) noexcept : m_fs(other.m_fs), m_path(std::move(other.m_path)) { other.m_fs = nullptr; other.m_path = {}; @@ -3912,8 +3912,7 @@ namespace vcpkg ls.append_indent().append_raw(as_preferred).append_raw('\n'); } - ls.append_raw('\n'); - msg_sink.print(ls); + msg_sink.println(ls); } uint64_t get_filesystem_stats() { return g_us_filesystem_stats.load(); } diff --git a/src/vcpkg/base/git.cpp b/src/vcpkg/base/git.cpp index 9b9ccffb6d..a0be0622ce 100644 --- a/src/vcpkg/base/git.cpp +++ b/src/vcpkg/base/git.cpp @@ -86,7 +86,7 @@ namespace vcpkg }; std::vector results; - ParserBase parser(output, "git status"); + ParserBase parser(output, "git status", {0, 0}); while (!parser.at_eof()) { GitStatusLine result; diff --git a/src/vcpkg/base/hash.cpp b/src/vcpkg/base/hash.cpp index c87bc6a1ec..c895108541 100644 --- a/src/vcpkg/base/hash.cpp +++ b/src/vcpkg/base/hash.cpp @@ -142,10 +142,14 @@ namespace vcpkg::Hash virtual std::string get_hash() override { + static constexpr unsigned long static_max_hash_size = 64; // SHA512, 512/8 = 64 const auto hash_size = get_hash_buffer_size(); - const auto buffer = std::make_unique(hash_size); - const auto hash = buffer.get(); + if (hash_size > static_max_hash_size) + { + Checks::unreachable(VCPKG_LINE_INFO, "hash buffer too small"); + } + uchar hash[static_max_hash_size]; const NTSTATUS error_code = BCryptFinishHash(hash_handle, hash, hash_size, 0); Checks::check_exit(VCPKG_LINE_INFO, NT_SUCCESS(error_code), "Failed to finalize the hash"); return to_hex(hash, hash + hash_size); @@ -518,20 +522,17 @@ namespace vcpkg::Hash static ReturnType do_hash(Algorithm algo, const F& f) { #if defined(_WIN32) - auto hasher = BCryptHasher(algo); - return f(hasher); + return f(BCryptHasher(algo)); #else switch (algo) { case Algorithm::Sha256: { - auto hasher = ShaHasher(); - return f(hasher); + return f(ShaHasher()); } case Algorithm::Sha512: { - auto hasher = ShaHasher(); - return f(hasher); + return f(ShaHasher()); } default: Checks::unreachable(VCPKG_LINE_INFO); } @@ -540,7 +541,7 @@ namespace vcpkg::Hash std::string get_bytes_hash(const void* first, const void* last, Algorithm algo) { - return do_hash(algo, [first, last](Hasher& hasher) { + return do_hash(algo, [first, last](Hasher&& hasher) { hasher.add_bytes(first, last); return hasher.get_hash(); }); @@ -553,17 +554,25 @@ namespace vcpkg::Hash std::string get_string_sha256(StringView s) { return get_string_hash(s, Hash::Algorithm::Sha256); } - ExpectedL get_file_hash(const ReadOnlyFilesystem& fs, const Path& path, Algorithm algo) + HashResult get_file_hash(DiagnosticContext& context, const ReadOnlyFilesystem& fs, const Path& path, Algorithm algo) { - Debug::println("Trying to hash ", path); + HashResult result; std::error_code ec; auto file = fs.open_for_read(path, ec); if (ec) { - return error_prefix().append(msgHashFileFailureToRead, msg::path = path).append_raw(ec.message()); + if (ec == std::errc::no_such_file_or_directory || ec == std::errc::not_a_directory) + { + result.prognosis = HashPrognosis::FileNotFound; + return result; + } + + context.report_error(format_filesystem_call_error(ec, "open_for_read", {path})); + result.prognosis = HashPrognosis::OtherError; + return result; } - return do_hash>(algo, [&](Hasher& hasher) -> ExpectedL { + result.hash = do_hash(algo, [&](Hasher&& hasher) { constexpr std::size_t buffer_size = 1024 * 32; char buffer[buffer_size]; do @@ -575,13 +584,37 @@ namespace vcpkg::Hash } else if ((ec = file.error())) { - return error_prefix().append(msgHashFileFailureToRead, msg::path = path).append_raw(ec.message()); + result.prognosis = HashPrognosis::OtherError; + context.report_error(format_filesystem_call_error(ec, "read", {path})); + return std::string(); } } while (!file.eof()); - auto result_hash = hasher.get_hash(); - Debug::print(fmt::format("{} has hash {}\n", path, result_hash)); - return result_hash; + return std::move(hasher).get_hash(); }); + + return result; + } + + Optional get_file_hash_required(DiagnosticContext& context, + const ReadOnlyFilesystem& fs, + const Path& path, + Algorithm algo) + { + auto result = get_file_hash(context, fs, path, algo); + switch (result.prognosis) + { + case HashPrognosis::Success: return result.hash; + case HashPrognosis::FileNotFound: + context.report(DiagnosticLine{DiagKind::Error, path, msg::format(msgFileNotFound)}); + return nullopt; + case HashPrognosis::OtherError: return nullopt; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + ExpectedL get_file_hash(const ReadOnlyFilesystem& fs, const Path& path, Algorithm algo) + { + return adapt_context_to_expected(get_file_hash_required, fs, path, algo); } } diff --git a/src/vcpkg/base/json.cpp b/src/vcpkg/base/json.cpp index 2c7116d117..b4066b0688 100644 --- a/src/vcpkg/base/json.cpp +++ b/src/vcpkg/base/json.cpp @@ -4,7 +4,9 @@ #include #include #include +#include #include +#include #include @@ -544,7 +546,10 @@ namespace vcpkg::Json { struct Parser : private ParserBase { - Parser(StringView text, StringView origin) : ParserBase(text, origin), style_() { } + Parser(StringView text, StringView origin, TextRowCol init_rowcol) + : ParserBase(text, origin, init_rowcol), style_() + { + } char32_t next() noexcept { @@ -1059,7 +1064,7 @@ namespace vcpkg::Json { StatsTimer t(g_json_parsing_stats); - auto parser = Parser(json, origin); + auto parser = Parser(json, origin, {1, 1}); auto val = parser.parse_value(); @@ -1422,7 +1427,7 @@ namespace vcpkg::Json uint64_t get_json_parsing_stats() { return g_json_parsing_stats.load(); } static std::vector invalid_json_fields(const Json::Object& obj, - Span known_fields) noexcept + View known_fields) noexcept { const auto field_is_unknown = [known_fields](StringView sv) { // allow directives @@ -1487,7 +1492,7 @@ namespace vcpkg::Json } void Reader::check_for_unexpected_fields(const Object& obj, - View valid_fields, + View valid_fields, const LocalizedString& type_name) { if (valid_fields.size() == 0) @@ -1629,4 +1634,38 @@ namespace vcpkg::Json } const FeatureNameDeserializer FeatureNameDeserializer::instance; + + LocalizedString ArchitectureDeserializer::type_name() const { return msg::format(msgACpuArchitecture); } + + Optional> ArchitectureDeserializer::visit_string(Json::Reader& r, StringView sv) const + { + auto maybe_cpu_architecture = to_cpu_architecture(sv); + if (maybe_cpu_architecture.has_value()) + { + return maybe_cpu_architecture; + } + + r.add_generic_error(type_name(), + msg::format(msgInvalidArchitectureValue, + msg::value = sv, + msg::expected = all_comma_separated_cpu_architectures())); + return Optional{nullopt}; + } + + const ArchitectureDeserializer ArchitectureDeserializer::instance; + + LocalizedString Sha512Deserializer::type_name() const { return msg::format(msgASha512); } + + Optional Sha512Deserializer::visit_string(Json::Reader& r, StringView sv) const + { + if (sv.size() == 128 && std::all_of(sv.begin(), sv.end(), ParserBase::is_hex_digit)) + { + return sv.to_string(); + } + + r.add_generic_error(type_name(), msg::format(msgInvalidSha512, msg::sha = sv)); + return std::string(); + } + + const Sha512Deserializer Sha512Deserializer::instance; } diff --git a/src/vcpkg/base/message_sinks.cpp b/src/vcpkg/base/message_sinks.cpp index f28f109550..4faf05c3be 100644 --- a/src/vcpkg/base/message_sinks.cpp +++ b/src/vcpkg/base/message_sinks.cpp @@ -1,33 +1,171 @@ #include #include +#include namespace { using namespace vcpkg; struct NullMessageSink : MessageSink { - virtual void print(Color, StringView) override { } + virtual void println(const MessageLine&) override { } + virtual void println(MessageLine&&) override { } + virtual void println(const LocalizedString&) override { } + virtual void println(LocalizedString&&) override { } + virtual void println(Color, const LocalizedString&) override { } + virtual void println(Color, LocalizedString&&) override { } }; NullMessageSink null_sink_instance; - struct OutMessageSink : MessageSink + struct OutMessageSink final : MessageSink { - virtual void print(Color c, StringView sv) override { msg::write_unlocalized_text(c, sv); } + virtual void println(const MessageLine& line) override + { + for (auto&& segment : line.get_segments()) + { + msg::write_unlocalized_text(segment.color, segment.text); + } + + msg::write_unlocalized_text(Color::none, "\n"); + } + + virtual void println(MessageLine&& line) override + { + auto& segments = line.get_segments(); + if (segments.empty()) + { + msg::write_unlocalized_text(Color::none, "\n"); + return; + } + + line.print(segments.back().color, "\n"); + for (auto&& segment : line.get_segments()) + { + msg::write_unlocalized_text(segment.color, segment.text); + } + } + virtual void println(const LocalizedString& text) override + { + msg::write_unlocalized_text(Color::none, text); + msg::write_unlocalized_text(Color::none, "\n"); + } + virtual void println(LocalizedString&& text) override + { + text.append_raw('\n'); + msg::write_unlocalized_text(Color::none, text); + } + virtual void println(Color color, const LocalizedString& text) override + { + msg::write_unlocalized_text(color, text); + msg::write_unlocalized_text(Color::none, "\n"); + } + virtual void println(Color color, LocalizedString&& text) override + { + text.append_raw('\n'); + msg::write_unlocalized_text(color, text); + } }; OutMessageSink out_sink_instance; - struct StdOutMessageSink : MessageSink + struct StdOutMessageSink final : MessageSink { - virtual void print(Color c, StringView sv) override { msg::write_unlocalized_text_to_stdout(c, sv); } + virtual void println(const MessageLine& line) override + { + for (auto&& segment : line.get_segments()) + { + msg::write_unlocalized_text_to_stdout(segment.color, segment.text); + } + + msg::write_unlocalized_text_to_stdout(Color::none, "\n"); + } + + virtual void println(MessageLine&& line) override + { + auto& segments = line.get_segments(); + if (segments.empty()) + { + msg::write_unlocalized_text_to_stdout(Color::none, "\n"); + return; + } + + line.print(segments.back().color, "\n"); + for (auto&& segment : line.get_segments()) + { + msg::write_unlocalized_text_to_stdout(segment.color, segment.text); + } + } + virtual void println(const LocalizedString& text) override + { + msg::write_unlocalized_text_to_stdout(Color::none, text); + msg::write_unlocalized_text_to_stdout(Color::none, "\n"); + } + virtual void println(LocalizedString&& text) override + { + text.append_raw('\n'); + msg::write_unlocalized_text_to_stdout(Color::none, text); + } + virtual void println(Color color, const LocalizedString& text) override + { + msg::write_unlocalized_text_to_stdout(color, text); + msg::write_unlocalized_text_to_stdout(color, "\n"); + } + virtual void println(Color color, LocalizedString&& text) override + { + text.append_raw('\n'); + msg::write_unlocalized_text_to_stdout(color, text); + } }; StdOutMessageSink stdout_sink_instance; - struct StdErrMessageSink : MessageSink + struct StdErrMessageSink final : MessageSink { - virtual void print(Color c, StringView sv) override { msg::write_unlocalized_text_to_stderr(c, sv); } + virtual void println(const MessageLine& line) override + { + for (auto&& segment : line.get_segments()) + { + msg::write_unlocalized_text_to_stderr(segment.color, segment.text); + } + + msg::write_unlocalized_text_to_stderr(Color::none, "\n"); + } + + virtual void println(MessageLine&& line) override + { + auto& segments = line.get_segments(); + if (segments.empty()) + { + msg::write_unlocalized_text_to_stderr(Color::none, "\n"); + return; + } + + line.print(segments.back().color, "\n"); + for (auto&& segment : line.get_segments()) + { + msg::write_unlocalized_text_to_stderr(segment.color, segment.text); + } + } + virtual void println(const LocalizedString& text) override + { + msg::write_unlocalized_text_to_stderr(Color::none, text); + msg::write_unlocalized_text_to_stderr(Color::none, "\n"); + } + virtual void println(LocalizedString&& text) override + { + text.append_raw('\n'); + msg::write_unlocalized_text_to_stderr(Color::none, text); + } + virtual void println(Color color, const LocalizedString& text) override + { + msg::write_unlocalized_text_to_stderr(color, text); + msg::write_unlocalized_text_to_stderr(color, "\n"); + } + virtual void println(Color color, LocalizedString&& text) override + { + text.append_raw('\n'); + msg::write_unlocalized_text_to_stderr(color, text); + } }; StdErrMessageSink stderr_sink_instance; @@ -36,26 +174,171 @@ namespace namespace vcpkg { - void MessageSink::println_warning(const LocalizedString& s) { println(Color::warning, warning_prefix().append(s)); } - void MessageSink::println_error(const LocalizedString& s) { println(Color::error, error_prefix().append(s)); } + MessageLine::MessageLine(const LocalizedString& ls) { segments.push_back({Color::none, ls.data()}); } + MessageLine::MessageLine(LocalizedString&& ls) { segments.push_back({Color::none, std::move(ls).extract_data()}); } + void MessageLine::print(Color color, StringView text) + { + if (!segments.empty() && segments.back().color == color) + { + segments.back().text.append(text.data(), text.size()); + } + else + { + segments.push_back({color, std::string(text)}); + } + } + void MessageLine::print(StringView text) { print(Color::none, text); } + const std::vector& MessageLine::get_segments() const noexcept { return segments; } + + std::string MessageLine::to_string() const { return adapt_to_string(*this); } + void MessageLine::to_string(std::string& target) const + { + for (const auto& segment : segments) + { + target.append(segment.text); + } + } + + void MessageSink::println(const LocalizedString& s) + { + MessageLine line; + line.print(Color::none, s); + this->println(line); + } + + void MessageSink::println(LocalizedString&& s) { this->println(s); } + + void MessageSink::println(Color c, const LocalizedString& s) + { + MessageLine line; + line.print(c, s); + this->println(line); + } + + void MessageSink::println(Color c, LocalizedString&& s) { this->println(c, s); } MessageSink& null_sink = null_sink_instance; MessageSink& out_sink = out_sink_instance; MessageSink& stderr_sink = stderr_sink_instance; MessageSink& stdout_sink = stdout_sink_instance; - void FileSink::print(Color, StringView sv) + void FileSink::println(const MessageLine& line) { + std::string whole_line; + line.to_string(whole_line); + whole_line.push_back('\n'); Checks::msg_check_exit(VCPKG_LINE_INFO, - m_out_file.write(sv.data(), 1, sv.size()) == sv.size(), + m_out_file.write(whole_line.data(), 1, whole_line.size()) == whole_line.size(), msgErrorWhileWriting, msg::path = m_log_file); } - void CombiningSink::print(Color c, StringView sv) + void FileSink::println(MessageLine&& line) + { + line.print("\n"); + for (auto&& segment : line.get_segments()) + { + Checks::msg_check_exit(VCPKG_LINE_INFO, + m_out_file.write(segment.text.data(), 1, segment.text.size()) == segment.text.size(), + msgErrorWhileWriting, + msg::path = m_log_file); + } + } + + void TeeSink::println(const MessageLine& line) + { + m_first.println(line); + m_second.println(line); + } + + void TeeSink::println(MessageLine&& line) + { + m_first.println(line); + m_second.println(std::move(line)); + } + + void TeeSink::println(const LocalizedString& line) + { + m_first.println(line); + m_second.println(line); + } + + void TeeSink::println(LocalizedString&& line) + { + m_first.println(line); + m_second.println(std::move(line)); + } + + void TeeSink::println(Color color, const LocalizedString& line) { - m_first.print(c, sv); - m_second.print(c, sv); + m_first.println(color, line); + m_second.println(color, line); + } + + void TeeSink::println(Color color, LocalizedString&& line) + { + m_first.println(color, line); + m_second.println(color, std::move(line)); + } + + void BGMessageSink::println(const MessageLine& line) + { + std::lock_guard lk(m_published_lock); + if (m_print_directly_to_out_sink) + { + out_sink.println(line); + return; + } + + m_published.push_back(line); } + void BGMessageSink::println(MessageLine&& line) + { + std::lock_guard lk(m_published_lock); + if (m_print_directly_to_out_sink) + { + out_sink.println(std::move(line)); + return; + } + + m_published.push_back(std::move(line)); + } + + void BGMessageSink::print_published() + { + std::vector tmp; + for (;;) + { + { + std::lock_guard lk(m_published_lock); + swap(tmp, m_published); + } + + if (tmp.empty()) + { + return; + } + + for (auto&& line : tmp) + { + out_sink.println(std::move(line)); + } + + tmp.clear(); + } + } + + void BGMessageSink::publish_directly_to_out_sink() + { + std::lock_guard lk(m_published_lock); + + m_print_directly_to_out_sink = true; + for (auto&& msg : m_published) + { + out_sink.println(std::move(msg)); + } + + m_published.clear(); + } } diff --git a/src/vcpkg/base/parse.cpp b/src/vcpkg/base/parse.cpp index b1ded452c1..58b4dcc3dc 100644 --- a/src/vcpkg/base/parse.cpp +++ b/src/vcpkg/base/parse.cpp @@ -9,8 +9,19 @@ namespace vcpkg { static void advance_rowcol(char32_t ch, int& row, int& column) { + if (row == 0 && column == 0) + { + return; + } + else if (row == 0 || column == 0) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + if (ch == '\t') + { column = ((column + 7) & ~7) + 1; // round to next 8-width tab stop + } else if (ch == '\n') { row++; @@ -69,7 +80,14 @@ namespace vcpkg LocalizedString res; if (!origin.empty()) { - res.append_raw(fmt::format("{}:{}:{}: ", origin, location.row, location.column)); + if (location.row == 0 && location.column == 0) + { + res.append_raw(fmt::format("{}: ", origin)); + } + else + { + res.append_raw(fmt::format("{}:{}:{}: ", origin, location.row, location.column)); + } } res.append_raw(kind == MessageKind::Warning ? WarningPrefix : ErrorPrefix); @@ -100,8 +118,8 @@ namespace vcpkg ParserBase::ParserBase(StringView text, Optional origin, TextRowCol init_rowcol) : m_it(text.begin(), text.end()) , m_start_of_line(m_it) - , m_row(init_rowcol.row_or(1)) - , m_column(init_rowcol.column_or(1)) + , m_row(init_rowcol.row) + , m_column(init_rowcol.column) , m_text(text) , m_origin(origin) { @@ -163,7 +181,11 @@ namespace vcpkg // success m_it = encoded; - m_column += static_cast(text.size()); + if (m_column != 0) + { + m_column += static_cast(text.size()); + } + return true; } @@ -189,7 +211,11 @@ namespace vcpkg // success m_it = encoded; - m_column += static_cast(keyword_content.size()); + if (m_column != 0) + { + m_column += static_cast(keyword_content.size()); + } + return true; } @@ -226,7 +252,14 @@ namespace vcpkg auto& res = m_messages.error.emplace(); if (auto origin = m_origin.get()) { - res.append_raw(fmt::format("{}:{}:{}: ", *origin, loc.row, loc.column)); + if (loc.row == 0 && loc.column == 0) + { + res.append_raw(fmt::format("{}: ", *origin)); + } + else + { + res.append_raw(fmt::format("{}:{}:{}: ", *origin, loc.row, loc.column)); + } } res.append_raw(ErrorPrefix); diff --git a/src/vcpkg/base/strings.cpp b/src/vcpkg/base/strings.cpp index 34633102c7..9296885e33 100644 --- a/src/vcpkg/base/strings.cpp +++ b/src/vcpkg/base/strings.cpp @@ -24,9 +24,10 @@ namespace vcpkg::Strings::details void append_internal(std::string& into, StringView s) { into.append(s.begin(), s.end()); } } -vcpkg::ExpectedL vcpkg::details::api_stable_format_impl(StringView sv, - void (*cb)(void*, std::string&, StringView), - void* user) +Optional vcpkg::details::api_stable_format_impl(DiagnosticContext& context, + StringView sv, + bool (*cb)(void*, std::string&, StringView), + void* user) { // Transforms similarly to std::format -- "{xyz}" -> f(xyz), "{{" -> "{", "}}" -> "}" @@ -46,7 +47,8 @@ vcpkg::ExpectedL vcpkg::details::api_stable_format_impl(StringView { if (p == last) { - return msg::format(msgInvalidFormatString, msg::actual = sv); + context.report_error(msg::format(msgInvalidFormatString, msg::actual = sv)); + return nullopt; } else if (*p == '{') { @@ -60,10 +62,15 @@ vcpkg::ExpectedL vcpkg::details::api_stable_format_impl(StringView p = std::find_first_of(p, last, s_brackets, s_brackets + 2); if (p == last || p[0] != '}') { - return msg::format(msgInvalidFormatString, msg::actual = sv); + context.report_error(msg::format(msgInvalidFormatString, msg::actual = sv)); + return nullopt; } // p[0] == '}' - cb(user, out, {seq_start, p}); + if (!cb(user, out, {seq_start, p})) + { + return nullopt; + } + prev = ++p; } } @@ -71,14 +78,16 @@ vcpkg::ExpectedL vcpkg::details::api_stable_format_impl(StringView { if (p == last || p[0] != '}') { - return msg::format(msgInvalidFormatString, msg::actual = sv); + context.report_error(msg::format(msgInvalidFormatString, msg::actual = sv)); + return nullopt; } out.push_back('}'); prev = ++p; } } + out.append(prev, last); - return {std::move(out), expected_left_tag}; + return out; } namespace @@ -173,7 +182,7 @@ bool Strings::case_insensitive_ascii_contains(StringView s, StringView pattern) return case_insensitive_ascii_search(s, pattern) != s.end(); } -bool Strings::case_insensitive_ascii_equals(StringView left, StringView right) +bool Strings::case_insensitive_ascii_equals(StringView left, StringView right) noexcept { return std::equal(left.begin(), left.end(), right.begin(), right.end(), icase_eq); } @@ -330,6 +339,12 @@ const char* Strings::find_first_of(StringView input, StringView chars) return std::find_first_of(input.begin(), input.end(), chars.begin(), chars.end()); } +std::string::size_type Strings::find_last(StringView searched, char c) +{ + auto iter = std::find(searched.rbegin(), searched.rend(), c); + return iter == searched.rend() ? std::string::npos : (&*iter - searched.begin()); +} + std::vector Strings::find_all_enclosed(StringView input, StringView left_delim, StringView right_delim) { auto it_left = input.begin(); diff --git a/src/vcpkg/base/system.cpp b/src/vcpkg/base/system.cpp index 3df622e156..7592d18ed0 100644 --- a/src/vcpkg/base/system.cpp +++ b/src/vcpkg/base/system.cpp @@ -134,6 +134,29 @@ namespace return result; } #endif // ^^^ _WIN32 + + struct CPUArchitectureEntry + { + StringLiteral name; + CPUArchitecture arch; + }; + + // keep this in sync with vcpkg-tools.schema.json + static constexpr CPUArchitectureEntry cpu_architecture_table[] = { + {"x86", CPUArchitecture::X86}, + {"x64", CPUArchitecture::X64}, + {"amd64", CPUArchitecture::X64}, + {"arm", CPUArchitecture::ARM}, + {"arm64", CPUArchitecture::ARM64}, + {"arm64ec", CPUArchitecture::ARM64EC}, + {"s390x", CPUArchitecture::S390X}, + {"ppc64le", CPUArchitecture::PPC64LE}, + {"riscv32", CPUArchitecture::RISCV32}, + {"riscv64", CPUArchitecture::RISCV64}, + {"loongarch32", CPUArchitecture::LOONGARCH32}, + {"loongarch64", CPUArchitecture::LOONGARCH64}, + {"mips64", CPUArchitecture::MIPS64}, + }; } namespace vcpkg @@ -147,43 +170,36 @@ namespace vcpkg #endif // ^^^ !_WIN32 } - Optional to_cpu_architecture(StringView arch) - { - if (Strings::case_insensitive_ascii_equals(arch, "x86")) return CPUArchitecture::X86; - if (Strings::case_insensitive_ascii_equals(arch, "x64")) return CPUArchitecture::X64; - if (Strings::case_insensitive_ascii_equals(arch, "amd64")) return CPUArchitecture::X64; - if (Strings::case_insensitive_ascii_equals(arch, "arm")) return CPUArchitecture::ARM; - if (Strings::case_insensitive_ascii_equals(arch, "arm64")) return CPUArchitecture::ARM64; - if (Strings::case_insensitive_ascii_equals(arch, "arm64ec")) return CPUArchitecture::ARM64EC; - if (Strings::case_insensitive_ascii_equals(arch, "s390x")) return CPUArchitecture::S390X; - if (Strings::case_insensitive_ascii_equals(arch, "ppc64le")) return CPUArchitecture::PPC64LE; - if (Strings::case_insensitive_ascii_equals(arch, "riscv32")) return CPUArchitecture::RISCV32; - if (Strings::case_insensitive_ascii_equals(arch, "riscv64")) return CPUArchitecture::RISCV64; - if (Strings::case_insensitive_ascii_equals(arch, "loongarch32")) return CPUArchitecture::LOONGARCH32; - if (Strings::case_insensitive_ascii_equals(arch, "loongarch64")) return CPUArchitecture::LOONGARCH64; - if (Strings::case_insensitive_ascii_equals(arch, "mips64")) return CPUArchitecture::MIPS64; + Optional to_cpu_architecture(StringView arch) noexcept + { + for (auto&& entry : cpu_architecture_table) + { + if (Strings::case_insensitive_ascii_equals(arch, entry.name)) + { + return entry.arch; + } + } return nullopt; } - ZStringView to_zstring_view(CPUArchitecture arch) noexcept + StringLiteral to_string_literal(CPUArchitecture arch) noexcept { - switch (arch) + for (auto&& entry : cpu_architecture_table) { - case CPUArchitecture::X86: return "x86"; - case CPUArchitecture::X64: return "x64"; - case CPUArchitecture::ARM: return "arm"; - case CPUArchitecture::ARM64: return "arm64"; - case CPUArchitecture::ARM64EC: return "arm64ec"; - case CPUArchitecture::S390X: return "s390x"; - case CPUArchitecture::PPC64LE: return "ppc64le"; - case CPUArchitecture::RISCV32: return "riscv32"; - case CPUArchitecture::RISCV64: return "riscv64"; - case CPUArchitecture::LOONGARCH32: return "loongarch32"; - case CPUArchitecture::LOONGARCH64: return "loongarch64"; - case CPUArchitecture::MIPS64: return "mips64"; - default: Checks::exit_with_message(VCPKG_LINE_INFO, "unexpected vcpkg::CPUArchitecture"); + if (entry.arch == arch) + { + return entry.name; + } } + + Checks::unreachable(VCPKG_LINE_INFO, "unexpected vcpkg::CPUArchitecture"); + } + + LocalizedString all_comma_separated_cpu_architectures() + { + return LocalizedString::from_raw( + Strings::join(", ", cpu_architecture_table, [](const CPUArchitectureEntry& entry) { return entry.name; })); } CPUArchitecture get_host_processor() @@ -624,8 +640,7 @@ namespace vcpkg case CPUArchitecture::ARM: value = L"ARM"; break; case CPUArchitecture::ARM64: value = L"ARM64"; break; default: - Checks::msg_exit_with_error( - VCPKG_LINE_INFO, msgUnexpectedWindowsArchitecture, msg::actual = to_zstring_view(proc)); + Checks::msg_exit_with_error(VCPKG_LINE_INFO, msgUnexpectedWindowsArchitecture, msg::actual = proc); break; } diff --git a/src/vcpkg/base/system.mac.cpp b/src/vcpkg/base/system.mac.cpp index 4543006161..6c6541f7f4 100644 --- a/src/vcpkg/base/system.mac.cpp +++ b/src/vcpkg/base/system.mac.cpp @@ -91,7 +91,7 @@ namespace vcpkg // "connection name","network adapter","physical address","transport name" auto is_quote = [](auto ch) -> bool { return ch == '"'; }; - auto parser = ParserBase(line, "getmac ouptut"); + auto parser = ParserBase(line, "getmac output", {0, 0}); out.clear(); diff --git a/src/vcpkg/base/system.process.cpp b/src/vcpkg/base/system.process.cpp index 5173864695..799542c8e8 100644 --- a/src/vcpkg/base/system.process.cpp +++ b/src/vcpkg/base/system.process.cpp @@ -43,14 +43,6 @@ namespace { using namespace vcpkg; - LocalizedString format_system_error_message(StringLiteral api_name, ExitCodeIntegral error_value) - { - return msg::format_error(msgSystemApiErrorMessage, - msg::system_api = api_name, - msg::exit_code = error_value, - msg::error_msg = std::system_category().message(static_cast(error_value))); - } - static std::atomic_int32_t debug_id_counter{1000}; #if defined(_WIN32) struct CtrlCStateMachine @@ -267,7 +259,7 @@ namespace vcpkg Optional try_parse_process_stat_file(const FileContents& contents) { - ParserBase p(contents.content, contents.origin); + ParserBase p(contents.content, contents.origin, {1, 1}); p.match_while(ParserBase::is_ascii_digit); // pid %d (ignored) @@ -790,14 +782,15 @@ namespace } }; - ExpectedL windows_create_process(std::int32_t debug_id, - ProcessInfo& process_info, - StringView command_line, - const Optional& working_directory, - const Optional& environment, - BOOL bInheritHandles, - DWORD dwCreationFlags, - STARTUPINFOEXW& startup_info) noexcept + bool windows_create_process(DiagnosticContext& context, + std::int32_t debug_id, + ProcessInfo& process_info, + StringView command_line, + const Optional& working_directory, + const Optional& environment, + BOOL bInheritHandles, + DWORD dwCreationFlags, + STARTUPINFOEXW& startup_info) noexcept { Debug::print(fmt::format("{}: CreateProcessW({})\n", debug_id, command_line)); @@ -840,24 +833,26 @@ namespace &startup_info.StartupInfo, &process_info)) { - return format_system_error_message("CreateProcessW", GetLastError()); + context.report_system_error("CreateProcessW", GetLastError()); + return false; } - return Unit{}; + return true; } // Used to, among other things, control which handles are inherited by child processes. // from https://devblogs.microsoft.com/oldnewthing/20111216-00/?p=8873 struct ProcAttributeList { - ExpectedL create(DWORD dwAttributeCount) + bool create(DiagnosticContext& context, DWORD dwAttributeCount) { Checks::check_exit(VCPKG_LINE_INFO, buffer.empty()); SIZE_T size = 0; if (InitializeProcThreadAttributeList(nullptr, dwAttributeCount, 0, &size) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { - return format_system_error_message("InitializeProcThreadAttributeList nullptr", GetLastError()); + context.report_system_error("InitializeProcThreadAttributeList nullptr", GetLastError()); + return false; } Checks::check_exit(VCPKG_LINE_INFO, size > 0); ASSUME(size > 0); @@ -865,18 +860,21 @@ namespace if (!InitializeProcThreadAttributeList( reinterpret_cast(buffer.data()), dwAttributeCount, 0, &size)) { - return format_system_error_message("InitializeProcThreadAttributeList attribute_list", GetLastError()); + context.report_system_error("InitializeProcThreadAttributeList attribute_list", GetLastError()); + return false; } - return Unit{}; + return true; } - ExpectedL update_attribute(DWORD_PTR Attribute, PVOID lpValue, SIZE_T cbSize) + bool update_attribute(DiagnosticContext& context, DWORD_PTR Attribute, PVOID lpValue, SIZE_T cbSize) { if (!UpdateProcThreadAttribute(get(), 0, Attribute, lpValue, cbSize, nullptr, nullptr)) { - return format_system_error_message("InitializeProcThreadAttributeList attribute_list", GetLastError()); + context.report_system_error("InitializeProcThreadAttributeList attribute_list", GetLastError()); + return false; } - return Unit{}; + + return true; } LPPROC_THREAD_ATTRIBUTE_LIST get() noexcept { @@ -912,17 +910,18 @@ namespace close_handle_mark_invalid(write_pipe); } - ExpectedL create() + bool create(DiagnosticContext& context) { Checks::check_exit(VCPKG_LINE_INFO, read_pipe == INVALID_HANDLE_VALUE); Checks::check_exit(VCPKG_LINE_INFO, write_pipe == INVALID_HANDLE_VALUE); SECURITY_ATTRIBUTES anonymousSa{sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE}; if (!CreatePipe(&read_pipe, &write_pipe, &anonymousSa, 0)) { - return format_system_error_message("CreatePipe", GetLastError()); + context.report_system_error("CreatePipe", GetLastError()); + return false; } - return Unit{}; + return true; } }; @@ -960,7 +959,7 @@ namespace close_handle_mark_invalid(write_pipe); } - ExpectedL create(std::int32_t debug_id) + bool create(DiagnosticContext& context, std::int32_t debug_id) { Checks::check_exit(VCPKG_LINE_INFO, read_pipe == INVALID_HANDLE_VALUE); Checks::check_exit(VCPKG_LINE_INFO, write_pipe == INVALID_HANDLE_VALUE); @@ -981,17 +980,19 @@ namespace &namedPipeSa); if (write_pipe == INVALID_HANDLE_VALUE) { - return format_system_error_message("CreateNamedPipeW stdin", GetLastError()); + context.report_system_error("CreateNamedPipeW stdin", GetLastError()); + return false; } SECURITY_ATTRIBUTES openSa{sizeof(SECURITY_ATTRIBUTES), nullptr, TRUE}; read_pipe = CreateFileW(pipe_name.c_str(), FILE_GENERIC_READ, 0, &openSa, OPEN_EXISTING, 0, 0); if (read_pipe == INVALID_HANDLE_VALUE) { - return format_system_error_message("CreateFileW stdin", GetLastError()); + context.report_system_error("CreateFileW stdin", GetLastError()); + return false; } - return Unit{}; + return true; } }; @@ -1156,31 +1157,34 @@ namespace } } - ExpectedL create() + bool create(DiagnosticContext& context) { #if defined(__APPLE__) static std::mutex pipe_creation_lock; std::lock_guard lck{pipe_creation_lock}; if (pipe(pipefd)) { - return format_system_error_message("pipe", errno); + context.report_system_error("pipe", errno); + return false; } for (size_t idx = 0; idx < 2; ++idx) { if (fcntl(pipefd[idx], F_SETFD, FD_CLOEXEC)) { - return format_system_error_message("fcntl", errno); + context.report_system_error("fcntl", errno); + return false; } } #else // ^^^ Apple // !Apple vvv if (pipe2(pipefd, O_CLOEXEC)) { - return format_system_error_message("pipe2", errno); + context.report_system_error("pipe2", errno); + return false; } #endif // ^^^ !Apple - return Unit{}; + return true; } }; @@ -1198,15 +1202,16 @@ namespace PosixSpawnFileActions(const PosixSpawnFileActions&) = delete; PosixSpawnFileActions& operator=(const PosixSpawnFileActions&) = delete; - ExpectedL adddup2(int fd, int newfd) + bool adddup2(DiagnosticContext& context, int fd, int newfd) { const int error = posix_spawn_file_actions_adddup2(&actions, fd, newfd); if (error) { - return format_system_error_message("posix_spawn_file_actions_adddup2", error); + context.report_system_error("posix_spawn_file_actions_adddup2", error); + return false; } - return Unit{}; + return true; } }; @@ -1216,7 +1221,7 @@ namespace PosixPid() : pid{-1} { } - ExpectedL wait_for_termination() + Optional wait_for_termination(DiagnosticContext& context) { int exit_code = -1; if (pid != -1) @@ -1225,7 +1230,8 @@ namespace const auto child = waitpid(pid, &status, 0); if (child != pid) { - return format_system_error_message("waitpid", errno); + context.report_system_error("waitpid", errno); + return nullopt; } if (WIFEXITED(status)) @@ -1311,18 +1317,7 @@ namespace vcpkg return new_env; } #endif -} // namespace vcpkg - -namespace -{ - void debug_print_cmd_execute_background_failure(int32_t debug_id, const LocalizedString& error) - { - Debug::print(fmt::format("{}: cmd_execute_background() failed: {}\n", debug_id, error)); - } -} -namespace vcpkg -{ void cmd_execute_background(const Command& cmd_line) { const auto debug_id = debug_id_counter.fetch_add(1, std::memory_order_relaxed); @@ -1334,18 +1329,15 @@ namespace vcpkg startup_info_ex.StartupInfo.cb = sizeof(STARTUPINFOEXW); startup_info_ex.StartupInfo.dwFlags = STARTF_USESHOWWINDOW; startup_info_ex.StartupInfo.wShowWindow = SW_HIDE; - auto process_create = windows_create_process(debug_id, - process_info, - cmd_line.command_line(), - nullopt, - nullopt, - FALSE, - CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB, - startup_info_ex); - if (!process_create) - { - debug_print_cmd_execute_background_failure(debug_id, process_create.error()); - } + (void)windows_create_process(Debug::g_debugging ? console_diagnostic_context : null_diagnostic_context, + debug_id, + process_info, + cmd_line.command_line(), + nullopt, + nullopt, + FALSE, + CREATE_NEW_CONSOLE | CREATE_BREAKAWAY_FROM_JOB, + startup_info_ex); #else // ^^^ _WIN32 // !_WIN32 pid_t pid; @@ -1366,17 +1358,17 @@ namespace vcpkg argv.emplace_back(nullptr); int error = posix_spawn(&pid, "/bin/sh", nullptr /*file_actions*/, nullptr /*attrp*/, argv.data(), environ); - if (error) + if (error && Debug::g_debugging) { - debug_print_cmd_execute_background_failure(debug_id, format_system_error_message("posix_spawn", errno)); - return; + console_diagnostic_context.report_system_error("posix_spawn", errno); } #endif // ^^^ !_WIN32 } - static ExpectedL cmd_execute_impl(const Command& cmd, - const ProcessLaunchSettings& settings, - const int32_t debug_id) + static Optional cmd_execute_impl(DiagnosticContext& context, + const Command& cmd, + const ProcessLaunchSettings& settings, + const int32_t debug_id) { #if defined(_WIN32) STARTUPINFOEXW startup_info_ex; @@ -1386,10 +1378,10 @@ namespace vcpkg startup_info_ex.StartupInfo.wShowWindow = SW_HIDE; ProcAttributeList proc_attribute_list; - auto proc_attribute_list_create = proc_attribute_list.create(1); + auto proc_attribute_list_create = proc_attribute_list.create(context, 1); if (!proc_attribute_list_create) { - return std::move(proc_attribute_list_create).error(); + return nullopt; } constexpr size_t number_of_candidate_handles = 3; @@ -1399,17 +1391,18 @@ namespace vcpkg size_t number_of_handles = std::unique(handles_to_inherit, handles_to_inherit + number_of_candidate_handles) - handles_to_inherit; - auto maybe_error = proc_attribute_list.update_attribute( - PROC_THREAD_ATTRIBUTE_HANDLE_LIST, handles_to_inherit, number_of_handles * sizeof(HANDLE)); - if (!maybe_error.has_value()) + if (!proc_attribute_list.update_attribute( + context, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, handles_to_inherit, number_of_handles * sizeof(HANDLE))) { - return std::move(maybe_error).error(); + return nullopt; } + startup_info_ex.lpAttributeList = proc_attribute_list.get(); SpawnProcessGuard spawn_process_guard; ProcessInfo process_info; - auto process_create = windows_create_process(debug_id, + auto process_create = windows_create_process(context, + debug_id, process_info, cmd.command_line(), settings.working_directory, @@ -1419,11 +1412,12 @@ namespace vcpkg startup_info_ex); if (!process_create) { - return std::move(process_create).error(); + return nullopt; } return process_info.wait(); #else + (void)context; Command real_command_line_builder; if (const auto wd = settings.working_directory.get()) { @@ -1443,50 +1437,55 @@ namespace vcpkg Debug::print(fmt::format("{}: system({})\n", debug_id, real_command_line)); fflush(nullptr); + // CodeQL [cpp/uncontrolled-process-operation]: This is intended to run whatever process the user supplies. return system(real_command_line.c_str()); #endif } - ExpectedL cmd_execute(const Command& cmd) + Optional cmd_execute(DiagnosticContext& context, const Command& cmd) { ProcessLaunchSettings default_process_launch_settings; - return cmd_execute(cmd, default_process_launch_settings); + return cmd_execute(context, cmd, default_process_launch_settings); } - ExpectedL cmd_execute(const Command& cmd, const ProcessLaunchSettings& settings) + Optional cmd_execute(DiagnosticContext& context, + const Command& cmd, + const ProcessLaunchSettings& settings) { const ElapsedTimer timer; const auto debug_id = debug_id_counter.fetch_add(1, std::memory_order_relaxed); - auto maybe_result = cmd_execute_impl(cmd, settings, debug_id); + auto maybe_exit_code = cmd_execute_impl(context, cmd, settings, debug_id); const auto elapsed = timer.us_64(); g_subprocess_stats += elapsed; - if (auto result = maybe_result.get()) + if (auto exit_code = maybe_exit_code.get()) { - Debug::print(fmt::format("{}: cmd_execute() returned {} after {} us\n", debug_id, *result, elapsed)); + Debug::print(fmt::format("{}: child process returned {} after {} us\n", debug_id, *exit_code, elapsed)); } else { Debug::print( - fmt::format("{}: cmd_execute() returned ({}) after {} us\n", debug_id, maybe_result.error(), elapsed)); + fmt::format("{}: cmd_execute() failed to launch child process after {} us\n", debug_id, elapsed)); } - return maybe_result; + return maybe_exit_code; } - ExpectedL cmd_execute_and_stream_lines(const Command& cmd, - const std::function& per_line_cb) + Optional cmd_execute_and_stream_lines(DiagnosticContext& context, + const Command& cmd, + const std::function& per_line_cb) { RedirectedProcessLaunchSettings default_redirected_process_launch_settings; - return cmd_execute_and_stream_lines(cmd, default_redirected_process_launch_settings, per_line_cb); + return cmd_execute_and_stream_lines(context, cmd, default_redirected_process_launch_settings, per_line_cb); } - ExpectedL cmd_execute_and_stream_lines(const Command& cmd, - const RedirectedProcessLaunchSettings& settings, - const std::function& per_line_cb) + Optional cmd_execute_and_stream_lines(DiagnosticContext& context, + const Command& cmd, + const RedirectedProcessLaunchSettings& settings, + const std::function& per_line_cb) { Strings::LinesStream lines; - auto rc = - cmd_execute_and_stream_data(cmd, settings, [&](const StringView sv) { lines.on_data(sv, per_line_cb); }); + auto rc = cmd_execute_and_stream_data( + context, cmd, settings, [&](const StringView sv) { lines.on_data(sv, per_line_cb); }); lines.on_end(per_line_cb); return rc; } @@ -1502,7 +1501,7 @@ namespace std::size_t offset; // Write a hunk of data to `target`. If there is no more input to write, returns `true`. - ExpectedL do_write(int target) + Optional do_write(DiagnosticContext& context, int target) { const auto this_write = input.size() - offset; // Big enough to be big, small enough to avoid implementation limits @@ -1514,7 +1513,8 @@ namespace write(target, static_cast(input.data() + offset), this_write_clamped); if (actually_written < 0) { - return format_system_error_message("write", errno); + context.report_system_error("write", errno); + return nullopt; } offset += actually_written; @@ -1525,10 +1525,11 @@ namespace }; #endif // ^^^ !_WIN32 - ExpectedL cmd_execute_and_stream_data_impl(const Command& cmd, - const RedirectedProcessLaunchSettings& settings, - const std::function& data_cb, - uint32_t debug_id) + Optional cmd_execute_and_stream_data_impl(DiagnosticContext& context, + const Command& cmd, + const RedirectedProcessLaunchSettings& settings, + const std::function& data_cb, + uint32_t debug_id) { #if defined(_WIN32) std::wstring as_utf16; @@ -1543,7 +1544,8 @@ namespace auto stdin_content_size_raw = stdin_content.size(); if (stdin_content_size_raw > MAXDWORD) { - return format_system_error_message("WriteFileEx", ERROR_INSUFFICIENT_BUFFER); + context.report_system_error("WriteFileEx", ERROR_INSUFFICIENT_BUFFER); + return nullopt; } auto stdin_content_size = static_cast(stdin_content_size_raw); @@ -1566,52 +1568,48 @@ namespace } // Create a pipe for the child process's STDIN. - auto stdin_create = process_info.stdin_pipe.create(debug_id); - if (!stdin_create) + if (!process_info.stdin_pipe.create(context, debug_id)) { - return std::move(stdin_create).error(); + return nullopt; } startup_info_ex.StartupInfo.hStdInput = process_info.stdin_pipe.read_pipe; // Create a pipe for the child process's STDOUT/STDERR. - auto stdout_create = process_info.stdout_pipe.create(); - if (!stdout_create) + if (!process_info.stdout_pipe.create(context)) { - return std::move(stdout_create).error(); + return nullopt; } startup_info_ex.StartupInfo.hStdOutput = process_info.stdout_pipe.write_pipe; startup_info_ex.StartupInfo.hStdError = process_info.stdout_pipe.write_pipe; ProcAttributeList proc_attribute_list; - auto proc_attribute_list_create = proc_attribute_list.create(1); - if (!proc_attribute_list_create) + if (!proc_attribute_list.create(context, 1)) { - return std::move(proc_attribute_list_create).error(); + return nullopt; } HANDLE handles_to_inherit[2] = {startup_info_ex.StartupInfo.hStdOutput, startup_info_ex.StartupInfo.hStdInput}; - auto maybe_error = proc_attribute_list.update_attribute( - PROC_THREAD_ATTRIBUTE_HANDLE_LIST, handles_to_inherit, 2 * sizeof(HANDLE)); - if (!maybe_error.has_value()) + if (!proc_attribute_list.update_attribute( + context, PROC_THREAD_ATTRIBUTE_HANDLE_LIST, handles_to_inherit, 2 * sizeof(HANDLE))) { - return std::move(maybe_error).error(); + return nullopt; } - startup_info_ex.lpAttributeList = proc_attribute_list.get(); - auto process_create = windows_create_process(debug_id, - process_info.proc_info, - cmd.command_line(), - settings.working_directory, - settings.environment, - TRUE, - dwCreationFlags, - startup_info_ex); + startup_info_ex.lpAttributeList = proc_attribute_list.get(); - if (!process_create) + if (!windows_create_process(context, + debug_id, + process_info.proc_info, + cmd.command_line(), + settings.working_directory, + settings.environment, + TRUE, + dwCreationFlags, + startup_info_ex)) { - return std::move(process_create).error(); + return nullopt; } close_handle_mark_invalid(process_info.stdin_pipe.read_pipe); @@ -1674,27 +1672,32 @@ namespace fflush(stdout); AnonymousPipe child_input; + if (!child_input.create(context)) { - auto err = child_input.create(); - if (!err) - { - return std::move(err).error(); - } + return nullopt; } AnonymousPipe child_output; + if (!child_output.create(context)) { - auto err = child_output.create(); - if (!err) - { - return std::move(err).error(); - } + return nullopt; } PosixSpawnFileActions actions; - actions.adddup2(child_input.pipefd[0], 0); - actions.adddup2(child_output.pipefd[1], 1); - actions.adddup2(child_output.pipefd[1], 2); + if (!actions.adddup2(context, child_input.pipefd[0], 0)) + { + return nullopt; + } + + if (!actions.adddup2(context, child_output.pipefd[1], 1)) + { + return nullopt; + } + + if (!actions.adddup2(context, child_output.pipefd[1], 2)) + { + return nullopt; + } std::vector argv_builder; argv_builder.reserve(3); @@ -1715,7 +1718,8 @@ namespace int error = posix_spawn(&pid.pid, "/bin/sh", &actions.actions, nullptr, argv.data(), environ); if (error) { - return format_system_error_message("posix_spawn", error); + context.report_system_error("posix_spawn", error); + return nullopt; } close_mark_invalid(child_input.pipefd[0]); @@ -1731,10 +1735,11 @@ namespace { if (fcntl(child_input.pipefd[1], F_SETFL, O_NONBLOCK)) { - return format_system_error_message("fcntl", errno); + context.report_system_error("fcntl", errno); + return nullopt; } - auto maybe_done = stdin_tracker.do_write(child_input.pipefd[1]); + auto maybe_done = stdin_tracker.do_write(context, child_input.pipefd[1]); bool done = false; if (const auto done_first = maybe_done.get()) { @@ -1746,7 +1751,7 @@ namespace } else { - return std::move(maybe_done).error(); + return nullopt; } if (!done) @@ -1760,7 +1765,8 @@ namespace polls[1].events = POLLIN; if (poll(polls, 2, -1) < 0) { - return format_system_error_message("poll", errno); + context.report_system_error("poll", errno); + return nullopt; } if (polls[0].revents & POLLERR) @@ -1770,7 +1776,7 @@ namespace } else if (polls[0].revents & POLLOUT) { - auto maybe_next_done = stdin_tracker.do_write(child_input.pipefd[1]); + auto maybe_next_done = stdin_tracker.do_write(context, child_input.pipefd[1]); if (const auto next_done = maybe_next_done.get()) { if (*next_done) @@ -1781,7 +1787,7 @@ namespace } else { - return std::move(maybe_next_done).error(); + return nullopt; } } @@ -1790,7 +1796,8 @@ namespace auto read_amount = read(child_output.pipefd[0], buf, sizeof(buf)); if (read_amount < 0) { - return format_system_error_message("read", errno); + context.report_system_error("read", errno); + return nullopt; } // can't be 0 because poll told us otherwise @@ -1822,7 +1829,8 @@ namespace break; } - return format_system_error_message("read", error); + context.report_system_error("read", errno); + return nullopt; } if (read_amount == 0) @@ -1839,27 +1847,29 @@ namespace } } - return pid.wait_for_termination(); + return pid.wait_for_termination(context); #endif /// ^^^ !_WIN32 } } // unnamed namespace namespace vcpkg { - ExpectedL cmd_execute_and_stream_data(const Command& cmd, - const std::function& data_cb) + Optional cmd_execute_and_stream_data(DiagnosticContext& context, + const Command& cmd, + const std::function& data_cb) { RedirectedProcessLaunchSettings default_redirected_process_launch_settings; - return cmd_execute_and_stream_data(cmd, default_redirected_process_launch_settings, data_cb); + return cmd_execute_and_stream_data(context, cmd, default_redirected_process_launch_settings, data_cb); } - ExpectedL cmd_execute_and_stream_data(const Command& cmd, - const RedirectedProcessLaunchSettings& settings, - const std::function& data_cb) + Optional cmd_execute_and_stream_data(DiagnosticContext& context, + const Command& cmd, + const RedirectedProcessLaunchSettings& settings, + const std::function& data_cb) { const ElapsedTimer timer; const auto debug_id = debug_id_counter.fetch_add(1, std::memory_order_relaxed); - auto maybe_exit_code = cmd_execute_and_stream_data_impl(cmd, settings, data_cb, debug_id); + auto maybe_exit_code = cmd_execute_and_stream_data_impl(context, cmd, settings, data_cb, debug_id); const auto elapsed = timer.us_64(); g_subprocess_stats += elapsed; if (const auto exit_code = maybe_exit_code.get()) @@ -1873,17 +1883,18 @@ namespace vcpkg return maybe_exit_code; } - ExpectedL cmd_execute_and_capture_output(const Command& cmd) + Optional cmd_execute_and_capture_output(DiagnosticContext& context, const Command& cmd) { RedirectedProcessLaunchSettings default_redirected_process_launch_settings; - return cmd_execute_and_capture_output(cmd, default_redirected_process_launch_settings); + return cmd_execute_and_capture_output(context, cmd, default_redirected_process_launch_settings); } - ExpectedL cmd_execute_and_capture_output(const Command& cmd, - const RedirectedProcessLaunchSettings& settings) + Optional cmd_execute_and_capture_output(DiagnosticContext& context, + const Command& cmd, + const RedirectedProcessLaunchSettings& settings) { std::string output; - return cmd_execute_and_stream_data(cmd, settings, [&](StringView sv) { Strings::append(output, sv); }) + return cmd_execute_and_stream_data(context, cmd, settings, [&](StringView sv) { Strings::append(output, sv); }) .map([&](ExitCodeIntegral exit_code) { return ExitCodeAndOutput{exit_code, std::move(output)}; }); } @@ -1959,4 +1970,23 @@ namespace vcpkg expected_right_tag}; } + std::string* check_zero_exit_code(DiagnosticContext& context, + Optional& maybe_exit, + StringView exe_path) + { + if (auto exit = maybe_exit.get()) + { + if (exit->exit_code == 0) + { + return &exit->output; + } + + context.report( + DiagnosticLine{DiagKind::Error, + exe_path, + msg::format(msgProgramPathReturnedNonzeroExitCode, msg::exit_code = exit->exit_code)}); + } + + return nullptr; + } } // namespace vcpkg diff --git a/src/vcpkg/binarycaching.cpp b/src/vcpkg/binarycaching.cpp index 93207d06cd..3f5113f6d6 100644 --- a/src/vcpkg/binarycaching.cpp +++ b/src/vcpkg/binarycaching.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -381,10 +382,8 @@ namespace struct HTTPPutBinaryProvider : IWriteBinaryProvider { - HTTPPutBinaryProvider(const Filesystem& fs, - std::vector&& urls, - const std::vector& secrets) - : m_fs(fs), m_urls(std::move(urls)), m_secrets(secrets) + HTTPPutBinaryProvider(std::vector&& urls, const std::vector& secrets) + : m_urls(std::move(urls)), m_secrets(secrets) { } @@ -396,11 +395,14 @@ namespace for (auto&& templ : m_urls) { auto url = templ.instantiate_variables(request); - auto maybe_success = put_file(m_fs, url, m_secrets, templ.headers, zip_path); + PrintingDiagnosticContext pdc{msg_sink}; + WarningDiagnosticContext wdc{pdc}; + auto maybe_success = + store_to_asset_cache(wdc, url, SanitizedUrl{url, m_secrets}, "PUT", templ.headers, zip_path); if (maybe_success) + { count_stored++; - else - msg_sink.println(Color::warning, maybe_success.error()); + } } return count_stored; } @@ -409,7 +411,6 @@ namespace bool needs_zip_file() const override { return true; } private: - const Filesystem& m_fs; std::vector m_urls; std::vector m_secrets; }; @@ -439,8 +440,8 @@ namespace make_temp_archive_path(m_buildtrees, action.spec)); } - auto codes = download_files(url_paths, m_url_template.headers, m_secrets); - + WarningDiagnosticContext wdc{console_diagnostic_context}; + auto codes = download_files_no_cache(wdc, url_paths, m_url_template.headers, m_secrets); for (size_t i = 0; i < codes.size(); ++i) { if (codes[i] == 200) @@ -458,11 +459,17 @@ namespace urls.push_back(m_url_template.instantiate_variables(BinaryPackageReadInfo{*actions[idx]})); } - auto codes = url_heads(urls, {}, m_secrets); + WarningDiagnosticContext wdc{console_diagnostic_context}; + auto codes = url_heads(wdc, urls, {}, m_secrets); for (size_t i = 0; i < codes.size(); ++i) { out_status[i] = codes[i] == 200 ? CacheAvailability::available : CacheAvailability::unavailable; } + + for (size_t i = codes.size(); i < out_status.size(); ++i) + { + out_status[i] = CacheAvailability::unavailable; + } } LocalizedString restored_message(size_t count, @@ -806,7 +813,9 @@ namespace m_token_header, m_accept_header.to_string(), }; - auto res = invoke_http_request("GET", headers, url); + + WarningDiagnosticContext wdc{console_diagnostic_context}; + auto res = invoke_http_request(wdc, "GET", headers, url); if (auto p = res.get()) { auto maybe_json = Json::parse_object(*p, m_url); @@ -840,8 +849,8 @@ namespace url_indices.push_back(idx); } - const auto codes = download_files(url_paths, {}, m_secrets); - + WarningDiagnosticContext wdc{console_diagnostic_context}; + const auto codes = download_files_no_cache(wdc, url_paths, {}, m_secrets); for (size_t i = 0; i < codes.size(); ++i) { if (codes[i] == 200) @@ -887,7 +896,8 @@ namespace m_token_header, }; - auto res = invoke_http_request("POST", headers, m_url, stringify(payload)); + WarningDiagnosticContext wdc{console_diagnostic_context}; + auto res = invoke_http_request(wdc, "POST", headers, m_url, stringify(payload)); if (auto p = res.get()) { auto maybe_json = Json::parse_object(*p, m_url); @@ -903,7 +913,7 @@ namespace return {}; } - size_t push_success(const BinaryPackageWriteInfo& request, MessageSink&) override + size_t push_success(const BinaryPackageWriteInfo& request, MessageSink& msg_sink) override { if (!request.zip_path) return 0; @@ -913,6 +923,7 @@ namespace size_t upload_count = 0; auto cache_size = m_fs.file_size(zip_path, VCPKG_LINE_INFO); + if (cache_size == 0) return upload_count; if (auto cacheId = reserve_cache_entry(request.spec.name(), abi, cache_size)) { @@ -920,11 +931,13 @@ namespace m_token_header, m_accept_header.to_string(), "Content-Type: application/octet-stream", - "Content-Range: bytes 0-" + std::to_string(cache_size) + "/*", + fmt::format("Content-Range: bytes 0-{}/{}", cache_size - 1, cache_size), }; - const auto url = m_url + "/" + std::to_string(*cacheId.get()); - if (put_file(m_fs, url, {}, custom_headers, zip_path, "PATCH")) + PrintingDiagnosticContext pdc{msg_sink}; + WarningDiagnosticContext wdc{pdc}; + const auto raw_url = m_url + "/" + std::to_string(*cacheId.get()); + if (store_to_asset_cache(wdc, raw_url, SanitizedUrl{raw_url, {}}, "PATCH", custom_headers, zip_path)) { Json::Object commit; commit.insert("size", std::to_string(cache_size)); @@ -934,15 +947,10 @@ namespace m_token_header, }; - auto res = invoke_http_request("POST", headers, url, stringify(commit)); - if (res) + if (invoke_http_request(wdc, "POST", headers, raw_url, stringify(commit))) { ++upload_count; } - else - { - msg::println(res.error()); - } } } return upload_count; @@ -1029,7 +1037,7 @@ namespace } else { - out_sink.println_warning(res.error()); + msg::println_warning(res.error()); } } } @@ -1088,7 +1096,7 @@ namespace } else { - msg_sink.println_warning(res.error()); + msg_sink.println(warning_prefix().append(std::move(res).error())); } } return upload_count; @@ -1357,7 +1365,7 @@ namespace } else { - msg::println(res.error()); + msg_sink.println(res.error()); } } @@ -1455,7 +1463,7 @@ namespace struct BinaryConfigParser : ConfigSegmentsParser { BinaryConfigParser(StringView text, Optional origin, BinaryConfigParserState* state) - : ConfigSegmentsParser(text, origin), state(state) + : ConfigSegmentsParser(text, origin, {0, 0}), state(state) { } @@ -1828,16 +1836,19 @@ namespace } bool has_sha = false; bool has_other = false; - api_stable_format(url_template.url_template, [&](std::string&, StringView key) { - if (key == "sha") - { - has_sha = true; - } - else - { - has_other = true; - } - }); + api_stable_format( + null_diagnostic_context, url_template.url_template, [&](std::string&, StringView key) { + if (key == "sha") + { + has_sha = true; + } + else + { + has_other = true; + } + + return true; + }); if (!has_sha) { if (has_other) @@ -1907,7 +1918,7 @@ namespace struct AssetSourcesParser : ConfigSegmentsParser { AssetSourcesParser(StringView text, StringView origin, AssetSourcesState* state) - : ConfigSegmentsParser(text, origin), state(state) + : ConfigSegmentsParser(text, origin, {0, 0}), state(state) { } @@ -2008,30 +2019,38 @@ namespace vcpkg { LocalizedString UrlTemplate::valid() const { + BufferedDiagnosticContext bdc{out_sink}; std::vector invalid_keys; - auto result = api_stable_format(url_template, [&](std::string&, StringView key) { + auto result = api_stable_format(bdc, url_template, [&](std::string&, StringView key) { static constexpr StringLiteral valid_keys[] = {"name", "version", "sha", "triplet"}; if (!Util::Vectors::contains(valid_keys, key)) { invalid_keys.push_back(key.to_string()); } + + return true; }); - if (!result) + + if (!invalid_keys.empty()) { - return std::move(result).error(); + bdc.report_error(msg::format(msgUnknownVariablesInTemplate, + msg::value = url_template, + msg::list = Strings::join(", ", invalid_keys))); + result.clear(); } - if (!invalid_keys.empty()) + + if (result.has_value()) { - return msg::format(msgUnknownVariablesInTemplate, - msg::value = url_template, - msg::list = Strings::join(", ", invalid_keys)); + return {}; } - return {}; + + return LocalizedString::from_raw(std::move(bdc).to_string()); } std::string UrlTemplate::instantiate_variables(const BinaryPackageReadInfo& info) const { - return api_stable_format(url_template, + return api_stable_format(console_diagnostic_context, + url_template, [&](std::string& out, StringView key) { if (key == "version") { @@ -2051,10 +2070,12 @@ namespace vcpkg } else { - Debug::println("Unknown key: ", key); - // We do a input validation while parsing the config - Checks::unreachable(VCPKG_LINE_INFO); + Checks::unreachable( + VCPKG_LINE_INFO, + "used instantiate_variables without checking valid() first"); }; + + return true; }) .value_or_exit(VCPKG_LINE_INFO); } @@ -2085,9 +2106,176 @@ namespace vcpkg get_environment_variable(EnvironmentVariableGitHubSha).value_or("")}; } - static ExpectedL make_binary_providers(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + void ReadOnlyBinaryCache::fetch(View actions) + { + std::vector action_ptrs; + std::vector restores; + std::vector statuses; + for (auto&& provider : m_config.read) + { + action_ptrs.clear(); + restores.clear(); + statuses.clear(); + for (size_t i = 0; i < actions.size(); ++i) + { + if (actions[i].package_abi()) + { + CacheStatus& status = m_status[*actions[i].package_abi().get()]; + if (status.should_attempt_restore(provider.get())) + { + action_ptrs.push_back(&actions[i]); + restores.push_back(RestoreResult::unavailable); + statuses.push_back(&status); + } + } + } + if (action_ptrs.empty()) continue; + + ElapsedTimer timer; + provider->fetch(action_ptrs, restores); + size_t num_restored = 0; + for (size_t i = 0; i < restores.size(); ++i) + { + if (restores[i] == RestoreResult::unavailable) + { + statuses[i]->mark_unavailable(provider.get()); + } + else + { + statuses[i]->mark_restored(); + ++num_restored; + } + } + msg::println(provider->restored_message( + num_restored, timer.elapsed().as())); + } + } + + bool ReadOnlyBinaryCache::is_restored(const InstallPlanAction& action) const + { + if (auto abi = action.package_abi().get()) + { + auto it = m_status.find(*abi); + if (it != m_status.end()) return it->second.is_restored(); + } + return false; + } + + void ReadOnlyBinaryCache::install_read_provider(std::unique_ptr&& provider) + { + m_config.read.push_back(std::move(provider)); + } + + std::vector ReadOnlyBinaryCache::precheck(View actions) + { + std::vector statuses = Util::fmap(actions, [this](const auto& action) { + if (!action.package_abi()) Checks::unreachable(VCPKG_LINE_INFO); + return &m_status[*action.package_abi().get()]; + }); + + std::vector action_ptrs; + std::vector cache_result; + std::vector indexes; + for (auto&& provider : m_config.read) + { + action_ptrs.clear(); + cache_result.clear(); + indexes.clear(); + for (size_t i = 0; i < actions.size(); ++i) + { + if (statuses[i]->should_attempt_precheck(provider.get())) + { + action_ptrs.push_back(&actions[i]); + cache_result.push_back(CacheAvailability::unknown); + indexes.push_back(i); + } + } + if (action_ptrs.empty()) continue; + + provider->precheck(action_ptrs, cache_result); + + for (size_t i = 0; i < action_ptrs.size(); ++i) + { + auto&& this_status = m_status[*action_ptrs[i]->package_abi().get()]; + if (cache_result[i] == CacheAvailability::available) + { + this_status.mark_available(provider.get()); + } + else if (cache_result[i] == CacheAvailability::unavailable) + { + this_status.mark_unavailable(provider.get()); + } + } + } + + return Util::fmap(statuses, [](CacheStatus* s) { + return s->get_available_provider() ? CacheAvailability::available : CacheAvailability::unavailable; + }); + } + + void BinaryCacheSynchronizer::add_submitted() noexcept + { + // This can set the unused bit but if that happens we are terminating anyway. + if ((m_state.fetch_add(1, std::memory_order_acq_rel) & SubmittedMask) == SubmittedMask) + { + Checks::unreachable(VCPKG_LINE_INFO, "Maximum job count exceeded"); + } + } + + BinaryCacheSyncState BinaryCacheSynchronizer::fetch_add_completed() noexcept + { + auto old = m_state.load(std::memory_order_acquire); + backing_uint_t local; + do + { + local = old; + if ((local & CompletedMask) == CompletedMask) + { + Checks::unreachable(VCPKG_LINE_INFO, "Maximum job count exceeded"); + } + + local += OneCompleted; + } while (!m_state.compare_exchange_weak(old, local, std::memory_order_acq_rel)); + + BinaryCacheSyncState result; + result.jobs_submitted = local & SubmittedMask; + result.jobs_completed = (local & CompletedMask) >> UpperShift; + result.submission_complete = (local & SubmissionCompleteBit) != 0; + return result; + } + + BinaryCacheSynchronizer::counter_uint_t BinaryCacheSynchronizer:: + fetch_incomplete_mark_submission_complete() noexcept + { + auto old = m_state.load(std::memory_order_acquire); + backing_uint_t local; + BinaryCacheSynchronizer::counter_uint_t submitted; + do + { + local = old; + + // Remove completions from the submission counter so that the (X/Y) console + // output is prettier. + submitted = local & SubmittedMask; + auto completed = (local & CompletedMask) >> UpperShift; + if (completed >= submitted) + { + local = SubmissionCompleteBit; + } + else + { + local = (submitted - completed) | SubmissionCompleteBit; + } + } while (!m_state.compare_exchange_weak(old, local, std::memory_order_acq_rel)); + auto state = m_state.fetch_or(SubmissionCompleteBit, std::memory_order_acq_rel); + + return (state & SubmittedMask) - ((state & CompletedMask) >> UpperShift); + } + + bool BinaryCache::install_providers(const VcpkgCmdArguments& args, + const VcpkgPaths& paths, + MessageSink& status_sink) { - BinaryProviders ret; if (args.binary_caching_enabled()) { if (Debug::g_debugging) @@ -2117,7 +2305,8 @@ namespace vcpkg parse_binary_provider_configs(args.env_binary_sources.value_or(""), args.cli_binary_sources); if (!sRawHolder) { - return std::move(sRawHolder).error(); + status_sink.println(Color::error, std::move(sRawHolder).error()); + return false; } auto& s = *sRawHolder.get(); @@ -2147,17 +2336,17 @@ namespace vcpkg s.nuget_prefix = args.nuget_id_prefix.value_or(""); if (!s.nuget_prefix.empty()) s.nuget_prefix.push_back('_'); - ret.nuget_prefix = s.nuget_prefix; + m_config.nuget_prefix = s.nuget_prefix; s.use_nuget_cache = args.use_nuget_cache.value_or(false); - ret.nuget_repo = get_nuget_repo_info_from_env(args); + m_config.nuget_repo = get_nuget_repo_info_from_env(args); auto& fs = paths.get_filesystem(); auto& tools = paths.get_tool_cache(); const auto& buildtrees = paths.buildtrees(); - ret.nuget_prefix = s.nuget_prefix; + m_config.nuget_prefix = s.nuget_prefix; std::shared_ptr gcs_tool; if (!s.gcs_read_prefixes.empty() || !s.gcs_write_prefixes.empty()) @@ -2178,45 +2367,45 @@ namespace vcpkg if (s.gha_read || s.gha_write) { if (!args.actions_cache_url.has_value() || !args.actions_runtime_token.has_value()) - return msg::format_error(msgGHAParametersMissing, msg::url = docs::binarycaching_gha_url); + { + status_sink.println( + Color::error, + msg::format_error(msgGHAParametersMissing, msg::url = docs::binarycaching_gha_url)); + return false; + } } if (!s.archives_to_read.empty() || !s.url_templates_to_get.empty() || !s.gcs_read_prefixes.empty() || !s.aws_read_prefixes.empty() || !s.cos_read_prefixes.empty() || s.gha_read) { - auto maybe_zip_tool = ZipTool::make(tools, out_sink); - if (!maybe_zip_tool.has_value()) - { - return std::move(maybe_zip_tool).error(); - } - const auto& zip_tool = *maybe_zip_tool.get(); - + ZipTool zip_tool; + zip_tool.setup(tools, out_sink); for (auto&& dir : s.archives_to_read) { - ret.read.push_back(std::make_unique(zip_tool, fs, std::move(dir))); + m_config.read.push_back(std::make_unique(zip_tool, fs, std::move(dir))); } for (auto&& url : s.url_templates_to_get) { - ret.read.push_back( + m_config.read.push_back( std::make_unique(zip_tool, fs, buildtrees, std::move(url), s.secrets)); } for (auto&& prefix : s.gcs_read_prefixes) { - ret.read.push_back( + m_config.read.push_back( std::make_unique(zip_tool, fs, buildtrees, std::move(prefix), gcs_tool)); } for (auto&& prefix : s.aws_read_prefixes) { - ret.read.push_back( + m_config.read.push_back( std::make_unique(zip_tool, fs, buildtrees, std::move(prefix), aws_tool)); } for (auto&& prefix : s.cos_read_prefixes) { - ret.read.push_back( + m_config.read.push_back( std::make_unique(zip_tool, fs, buildtrees, std::move(prefix), cos_tool)); } @@ -2224,38 +2413,39 @@ namespace vcpkg { const auto& url = *args.actions_cache_url.get(); const auto& token = *args.actions_runtime_token.get(); - ret.read.push_back(std::make_unique(zip_tool, fs, buildtrees, url, token)); + m_config.read.push_back(std::make_unique(zip_tool, fs, buildtrees, url, token)); } } if (!s.archives_to_write.empty()) { - ret.write.push_back(std::make_unique(fs, std::move(s.archives_to_write))); + m_config.write.push_back( + std::make_unique(fs, std::move(s.archives_to_write))); } if (!s.url_templates_to_put.empty()) { - ret.write.push_back( - std::make_unique(fs, std::move(s.url_templates_to_put), s.secrets)); + m_config.write.push_back( + std::make_unique(std::move(s.url_templates_to_put), s.secrets)); } if (!s.gcs_write_prefixes.empty()) { - ret.write.push_back( + m_config.write.push_back( std::make_unique(std::move(s.gcs_write_prefixes), gcs_tool)); } if (!s.aws_write_prefixes.empty()) { - ret.write.push_back( + m_config.write.push_back( std::make_unique(std::move(s.aws_write_prefixes), aws_tool)); } if (!s.cos_write_prefixes.empty()) { - ret.write.push_back( + m_config.write.push_back( std::make_unique(std::move(s.cos_write_prefixes), cos_tool)); } if (s.gha_write) { const auto& url = *args.actions_cache_url.get(); const auto& token = *args.actions_runtime_token.get(); - ret.write.push_back(std::make_unique(fs, url, token)); + m_config.write.push_back(std::make_unique(fs, url, token)); } if (!s.sources_to_read.empty() || !s.configs_to_read.empty() || !s.sources_to_write.empty() || @@ -2264,14 +2454,14 @@ namespace vcpkg NugetBaseBinaryProvider nuget_base( fs, NuGetTool(tools, out_sink, s), paths.packages(), buildtrees, s.nuget_prefix); if (!s.sources_to_read.empty()) - ret.read.push_back( + m_config.read.push_back( std::make_unique(nuget_base, nuget_sources_arg(s.sources_to_read))); for (auto&& config : s.configs_to_read) - ret.read.push_back( + m_config.read.push_back( std::make_unique(nuget_base, nuget_configfile_arg(config))); if (!s.sources_to_write.empty() || !s.configs_to_write.empty()) { - ret.write.push_back(std::make_unique( + m_config.write.push_back(std::make_unique( nuget_base, std::move(s.sources_to_write), std::move(s.configs_to_write))); } } @@ -2280,208 +2470,145 @@ namespace vcpkg { for (auto&& src : s.upkg_templates_to_get) { - ret.read.push_back(std::make_unique(tools, out_sink, std::move(src))); + m_config.read.push_back( + std::make_unique(tools, out_sink, std::move(src))); } } if (!s.upkg_templates_to_put.empty()) { - ret.write.push_back( + m_config.write.push_back( std::make_unique(tools, out_sink, std::move(s.upkg_templates_to_put))); } } - return std::move(ret); - } - ReadOnlyBinaryCache::ReadOnlyBinaryCache(BinaryProviders&& providers) : m_config(std::move(providers)) { } - - void ReadOnlyBinaryCache::fetch(View actions) - { - std::vector action_ptrs; - std::vector restores; - std::vector statuses; - for (auto&& provider : m_config.read) + m_needs_nuspec_data = Util::any_of(m_config.write, [](auto&& p) { return p->needs_nuspec_data(); }); + m_needs_zip_file = Util::any_of(m_config.write, [](auto&& p) { return p->needs_zip_file(); }); + if (m_needs_zip_file) { - action_ptrs.clear(); - restores.clear(); - statuses.clear(); - for (size_t i = 0; i < actions.size(); ++i) - { - if (actions[i].package_abi()) - { - CacheStatus& status = m_status[*actions[i].package_abi().get()]; - if (status.should_attempt_restore(provider.get())) - { - action_ptrs.push_back(&actions[i]); - restores.push_back(RestoreResult::unavailable); - statuses.push_back(&status); - } - } - } - if (action_ptrs.empty()) continue; - - ElapsedTimer timer; - provider->fetch(action_ptrs, restores); - size_t num_restored = 0; - for (size_t i = 0; i < restores.size(); ++i) - { - if (restores[i] == RestoreResult::unavailable) - { - statuses[i]->mark_unavailable(provider.get()); - } - else - { - statuses[i]->mark_restored(); - ++num_restored; - } - } - msg::println(provider->restored_message( - num_restored, timer.elapsed().as())); + m_zip_tool.setup(paths.get_tool_cache(), status_sink); } - } - bool ReadOnlyBinaryCache::is_restored(const InstallPlanAction& action) const + return true; + } + BinaryCache::BinaryCache(const Filesystem& fs) + : m_fs(fs), m_bg_msg_sink(stdout_sink), m_push_thread(&BinaryCache::push_thread_main, this) { - if (auto abi = action.package_abi().get()) - { - auto it = m_status.find(*abi); - if (it != m_status.end()) return it->second.is_restored(); - } - return false; } + BinaryCache::~BinaryCache() { wait_for_async_complete_and_join(); } - std::vector ReadOnlyBinaryCache::precheck(View actions) + void BinaryCache::push_success(CleanPackages clean_packages, const InstallPlanAction& action) { - std::vector statuses = Util::fmap(actions, [this](const auto& action) { - if (!action.package_abi()) Checks::unreachable(VCPKG_LINE_INFO); - return &m_status[*action.package_abi().get()]; - }); - - std::vector action_ptrs; - std::vector cache_result; - std::vector indexes; - for (auto&& provider : m_config.read) + if (auto abi = action.package_abi().get()) { - action_ptrs.clear(); - cache_result.clear(); - indexes.clear(); - for (size_t i = 0; i < actions.size(); ++i) + bool restored; + auto it = m_status.find(*abi); + if (it == m_status.end()) { - if (statuses[i]->should_attempt_precheck(provider.get())) - { - action_ptrs.push_back(&actions[i]); - cache_result.push_back(CacheAvailability::unknown); - indexes.push_back(i); - } + restored = false; } - if (action_ptrs.empty()) continue; + else + { + restored = it->second.is_restored(); - provider->precheck(action_ptrs, cache_result); + // Purge all status information on push_success (cache invalidation) + // - push_success may delete packages/ (invalidate restore) + // - push_success may make the package available from providers (invalidate unavailable) + m_status.erase(it); + } - for (size_t i = 0; i < action_ptrs.size(); ++i) + if (!restored && !m_config.write.empty()) { - auto&& this_status = m_status[*action_ptrs[i]->package_abi().get()]; - if (cache_result[i] == CacheAvailability::available) - { - this_status.mark_available(provider.get()); - } - else if (cache_result[i] == CacheAvailability::unavailable) + ElapsedTimer timer; + BinaryPackageWriteInfo request{action}; + + if (m_needs_nuspec_data) { - this_status.mark_unavailable(provider.get()); + request.nuspec = + generate_nuspec(request.package_dir, action, m_config.nuget_prefix, m_config.nuget_repo); } + + m_synchronizer.add_submitted(); + msg::println(msg::format( + msgSubmittingBinaryCacheBackground, msg::spec = action.spec, msg::count = m_config.write.size())); + m_actions_to_push.push(ActionToPush{std::move(request), clean_packages}); + return; } } - return Util::fmap(statuses, [](CacheStatus* s) { - return s->get_available_provider() ? CacheAvailability::available : CacheAvailability::unavailable; - }); + if (clean_packages == CleanPackages::Yes) + { + m_fs.remove_all(action.package_dir.value_or_exit(VCPKG_LINE_INFO), VCPKG_LINE_INFO); + } } - BinaryCache::BinaryCache(const Filesystem& fs) : m_fs(fs) { } + void BinaryCache::print_updates() { m_bg_msg_sink.print_published(); } - ExpectedL BinaryCache::make(const VcpkgCmdArguments& args, const VcpkgPaths& paths, MessageSink& sink) + void BinaryCache::wait_for_async_complete_and_join() { - return make_binary_providers(args, paths).then([&](BinaryProviders&& p) -> ExpectedL { - BinaryCache b(std::move(p), paths.get_filesystem()); - b.m_needs_nuspec_data = Util::any_of(b.m_config.write, [](auto&& p) { return p->needs_nuspec_data(); }); - b.m_needs_zip_file = Util::any_of(b.m_config.write, [](auto&& p) { return p->needs_zip_file(); }); - if (b.m_needs_zip_file) - { - auto maybe_zt = ZipTool::make(paths.get_tool_cache(), sink); - if (auto z = maybe_zt.get()) - { - b.m_zip_tool.emplace(std::move(*z)); - } - else - { - return std::move(maybe_zt).error(); - } - } - return std::move(b); - }); - } + m_bg_msg_sink.print_published(); + auto incomplete_count = m_synchronizer.fetch_incomplete_mark_submission_complete(); + if (incomplete_count != 0) + { + msg::println(msgWaitUntilPackagesUploaded, msg::count = incomplete_count); + } - BinaryCache::BinaryCache(BinaryProviders&& providers, const Filesystem& fs) - : ReadOnlyBinaryCache(std::move(providers)), m_fs(fs) - { + m_bg_msg_sink.publish_directly_to_out_sink(); + m_actions_to_push.stop(); + if (m_push_thread.joinable()) + { + m_push_thread.join(); + } } - void BinaryCache::push_success(CleanPackages clean_packages, const InstallPlanAction& action) + void BinaryCache::push_thread_main() { - if (auto abi = action.package_abi().get()) + std::vector my_tasks; + while (m_actions_to_push.get_work(my_tasks)) { - bool restored = m_status[*abi].is_restored(); - // Purge all status information on push_success (cache invalidation) - // - push_success may delete packages/ (invalidate restore) - // - push_success may make the package available from providers (invalidate unavailable) - m_status.erase(*abi); - if (!restored && !m_config.write.empty()) + for (auto& action_to_push : my_tasks) { ElapsedTimer timer; - BinaryPackageWriteInfo request{action}; - - if (m_needs_nuspec_data) - { - request.nuspec = - generate_nuspec(request.package_dir, action, m_config.nuget_prefix, m_config.nuget_repo); - } if (m_needs_zip_file) { - Path zip_path = request.package_dir + ".zip"; - auto compress_result = m_zip_tool.value_or_exit(VCPKG_LINE_INFO) - .compress_directory_to_zip(m_fs, request.package_dir, zip_path); - if (compress_result) - { - request.zip_path = std::move(zip_path); - } - else + Path zip_path = action_to_push.request.package_dir + ".zip"; + PrintingDiagnosticContext pdc{m_bg_msg_sink}; + if (m_zip_tool.compress_directory_to_zip(pdc, m_fs, action_to_push.request.package_dir, zip_path)) { - out_sink.println(Color::warning, - msg::format_warning(msgCompressFolderFailed, msg::path = request.package_dir) - .append_raw(' ') - .append_raw(compress_result.error())); + action_to_push.request.zip_path = std::move(zip_path); } } size_t num_destinations = 0; for (auto&& provider : m_config.write) { - if (!provider->needs_zip_file() || request.zip_path.has_value()) + if (!provider->needs_zip_file() || action_to_push.request.zip_path.has_value()) { - num_destinations += provider->push_success(request, out_sink); + num_destinations += provider->push_success(action_to_push.request, m_bg_msg_sink); } } - if (request.zip_path) + + if (action_to_push.request.zip_path) { - m_fs.remove(*request.zip_path.get(), IgnoreErrors{}); + m_fs.remove(*action_to_push.request.zip_path.get(), IgnoreErrors{}); } - out_sink.println( - msgStoredBinariesToDestinations, msg::count = num_destinations, msg::elapsed = timer.elapsed()); - } - } - if (clean_packages == CleanPackages::Yes) - { - m_fs.remove_all(action.package_dir.value_or_exit(VCPKG_LINE_INFO), VCPKG_LINE_INFO); + if (action_to_push.clean_after_push == CleanPackages::Yes) + { + m_fs.remove_all(action_to_push.request.package_dir, VCPKG_LINE_INFO); + } + + auto sync_state = m_synchronizer.fetch_add_completed(); + auto message = msg::format(msgSubmittingBinaryCacheComplete, + msg::spec = action_to_push.request.spec, + msg::count = num_destinations, + msg::elapsed = timer.elapsed()); + if (sync_state.submission_complete) + { + message.append_raw(fmt::format(" ({}/{})", sync_state.jobs_completed, sync_state.jobs_submitted)); + } + + m_bg_msg_sink.println(message); + } } } @@ -2572,14 +2699,15 @@ namespace vcpkg } } -ExpectedL vcpkg::parse_download_configuration(const Optional& arg) +ExpectedL vcpkg::parse_download_configuration(const Optional& arg) { - if (!arg || arg.get()->empty()) return DownloadManagerConfig{}; + AssetCachingSettings result; + if (!arg || arg.get()->empty()) return result; get_global_metrics_collector().track_define(DefineMetric::AssetSource); AssetSourcesState s; - const auto source = Strings::concat("$", EnvironmentVariableXVcpkgAssetSources); + const auto source = format_environment_variable(EnvironmentVariableXVcpkgAssetSources); AssetSourcesParser parser(*arg.get(), source, &s); parser.parse(); if (auto err = parser.get_error()) @@ -2605,27 +2733,22 @@ ExpectedL vcpkg::parse_download_configuration(const Optio .append(msgSeeURL, msg::url = docs::assetcaching_url); } - Optional get_url; if (!s.url_templates_to_get.empty()) { - get_url = std::move(s.url_templates_to_get.back()); + result.m_read_url_template = std::move(s.url_templates_to_get.back()); } - Optional put_url; - std::vector put_headers; + if (!s.azblob_templates_to_put.empty()) { - put_url = std::move(s.azblob_templates_to_put.back()); + result.m_write_url_template = std::move(s.azblob_templates_to_put.back()); auto v = azure_blob_headers(); - put_headers.assign(v.begin(), v.end()); + result.m_write_headers.assign(v.begin(), v.end()); } - return DownloadManagerConfig{std::move(get_url), - std::vector{}, - std::move(put_url), - std::move(put_headers), - std::move(s.secrets), - s.block_origin, - s.script}; + result.m_secrets = std::move(s.secrets); + result.m_block_origin = s.block_origin; + result.m_script = std::move(s.script); + return result; } ExpectedL vcpkg::parse_binary_provider_configs(const std::string& env_string, @@ -2640,7 +2763,9 @@ ExpectedL vcpkg::parse_binary_provider_configs(const st return *err; } - BinaryConfigParser env_parser(env_string, "VCPKG_BINARY_SOURCES", &s); + // must live until the end of the function due to StringView in BinaryConfigParser + const auto source = format_environment_variable("VCPKG_BINARY_SOURCES"); + BinaryConfigParser env_parser(env_string, source, &s); env_parser.parse(); if (auto err = env_parser.get_error()) { diff --git a/src/vcpkg/cgroup-parser.cpp b/src/vcpkg/cgroup-parser.cpp index c3f930c5ba..552b9c7d80 100644 --- a/src/vcpkg/cgroup-parser.cpp +++ b/src/vcpkg/cgroup-parser.cpp @@ -28,7 +28,7 @@ namespace vcpkg using P = ParserBase; constexpr auto is_separator_or_lineend = [](auto ch) { return ch == ':' || P::is_lineend(ch); }; - ParserBase parser{text, origin}; + ParserBase parser{text, origin, {1, 1}}; parser.skip_whitespace(); std::vector ret; diff --git a/src/vcpkg/ci-baseline.cpp b/src/vcpkg/ci-baseline.cpp index a6dc1453a7..a0b312bccd 100644 --- a/src/vcpkg/ci-baseline.cpp +++ b/src/vcpkg/ci-baseline.cpp @@ -59,7 +59,7 @@ namespace vcpkg std::vector parse_ci_baseline(StringView text, StringView origin, ParseMessages& messages) { std::vector result; - ParserBase parser(text, origin); + ParserBase parser(text, origin, {1, 1}); for (;;) { parser.skip_whitespace(); diff --git a/src/vcpkg/commands.add-version.cpp b/src/vcpkg/commands.add-version.cpp index 72e0b8afd7..fe7bfc8405 100644 --- a/src/vcpkg/commands.add-version.cpp +++ b/src/vcpkg/commands.add-version.cpp @@ -89,11 +89,11 @@ namespace { Json::Object baseline_version_obj; insert_version_to_json_object(baseline_version_obj, kv_pair.second, JsonIdBaseline); - port_entries_obj.insert(kv_pair.first, baseline_version_obj); + port_entries_obj.insert(kv_pair.first, std::move(baseline_version_obj)); } Json::Object baseline_obj; - baseline_obj.insert("default", port_entries_obj); + baseline_obj.insert(JsonIdDefault, std::move(port_entries_obj)); return baseline_obj; } @@ -109,7 +109,7 @@ namespace } Json::Object output_object; - output_object.insert(JsonIdVersions, versions_array); + output_object.insert(JsonIdVersions, std::move(versions_array)); return output_object; } @@ -128,15 +128,13 @@ namespace write_json_file(fs, serialize_versions(versions), output_path); } - UpdateResult update_baseline_version(const VcpkgPaths& paths, + UpdateResult update_baseline_version(const Filesystem& fs, const std::string& port_name, const Version& version, const Path& baseline_path, std::map>& baseline_map, bool print_success) { - auto& fs = paths.get_filesystem(); - auto it = baseline_map.find(port_name); if (it != baseline_map.end()) { @@ -452,12 +450,10 @@ namespace vcpkg auto baseline_map = [&]() -> std::map> { if (!fs.exists(baseline_path, IgnoreErrors{})) { - std::map> ret; - return ret; + return std::map>{}; } - auto maybe_baseline_map = vcpkg::get_builtin_baseline(paths); - return maybe_baseline_map.value_or_exit(VCPKG_LINE_INFO); + return vcpkg::get_builtin_baseline(paths).value_or_exit(VCPKG_LINE_INFO); }(); // Get tree-ish from local repository state. @@ -465,14 +461,9 @@ namespace vcpkg auto& git_tree_map = maybe_git_tree_map.value_or_exit(VCPKG_LINE_INFO); // Find ports with uncommitted changes - std::set changed_ports; auto git_config = paths.git_builtin_config(); auto maybe_changes = git_ports_with_uncommitted_changes(git_config); - if (auto changes = maybe_changes.get()) - { - changed_ports.insert(changes->begin(), changes->end()); - } - else if (verbose) + if (!maybe_changes.has_value() && verbose) { msg::println_warning(msgAddVersionDetectLocalChangesError); } @@ -524,9 +515,12 @@ namespace vcpkg } // find local uncommitted changes on port - if (Util::Sets::contains(changed_ports, port_name)) + if (auto changed_ports = maybe_changes.get()) { - msg::println_warning(msgAddVersionUncommittedChanges, msg::package_name = port_name); + if (Util::Sets::contains(*changed_ports, port_name)) + { + msg::println_warning(msgAddVersionUncommittedChanges, msg::package_name = port_name); + } } auto schemed_version = scfl->source_control_file->to_schemed_version(); @@ -555,7 +549,7 @@ namespace vcpkg add_all, skip_version_format_check); auto updated_baseline_file = update_baseline_version( - paths, port_name, schemed_version.version, baseline_path, baseline_map, verbose); + paths.get_filesystem(), port_name, schemed_version.version, baseline_path, baseline_map, verbose); if (verbose && updated_versions_file == UpdateResult::NotUpdated && updated_baseline_file == UpdateResult::NotUpdated) { diff --git a/src/vcpkg/commands.bootstrap-standalone.cpp b/src/vcpkg/commands.bootstrap-standalone.cpp index 6663836108..0c0a398273 100644 --- a/src/vcpkg/commands.bootstrap-standalone.cpp +++ b/src/vcpkg/commands.bootstrap-standalone.cpp @@ -27,7 +27,7 @@ namespace vcpkg { (void)args.parse_arguments(CommandBootstrapStandaloneMetadata); - DownloadManager download_manager{{}}; + AssetCachingSettings asset_cache_settings; const auto maybe_vcpkg_root_env = args.vcpkg_root_dir_env.get(); if (!maybe_vcpkg_root_env) { @@ -36,11 +36,17 @@ namespace vcpkg const auto vcpkg_root = fs.almost_canonical(*maybe_vcpkg_root_env, VCPKG_LINE_INFO); fs.create_directories(vcpkg_root, VCPKG_LINE_INFO); - auto tarball = - download_vcpkg_standalone_bundle(download_manager, fs, vcpkg_root).value_or_exit(VCPKG_LINE_INFO); + auto maybe_tarball = + download_vcpkg_standalone_bundle(console_diagnostic_context, asset_cache_settings, fs, vcpkg_root); + auto tarball = maybe_tarball.get(); + if (!tarball) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + fs.remove_all(vcpkg_root / "vcpkg-artifacts", VCPKG_LINE_INFO); - extract_tar(find_system_tar(fs).value_or_exit(VCPKG_LINE_INFO), tarball, vcpkg_root); - fs.remove(tarball, VCPKG_LINE_INFO); + extract_tar(find_system_tar(fs).value_or_exit(VCPKG_LINE_INFO), *tarball, vcpkg_root); + fs.remove(*tarball, VCPKG_LINE_INFO); Checks::exit_success(VCPKG_LINE_INFO); } } diff --git a/src/vcpkg/commands.build-external.cpp b/src/vcpkg/commands.build-external.cpp index 28720fa55b..ebba5f372b 100644 --- a/src/vcpkg/commands.build-external.cpp +++ b/src/vcpkg/commands.build-external.cpp @@ -34,7 +34,6 @@ namespace vcpkg CleanBuildtrees::Yes, CleanPackages::Yes, CleanDownloads::No, - DownloadTool::Builtin, BackcompatFeatures::Allow, }; @@ -43,7 +42,7 @@ namespace vcpkg .value_or_exit(VCPKG_LINE_INFO); auto overlays = paths.overlay_ports; - overlays.insert(overlays.begin(), options.command_arguments[1]); + overlays.overlay_ports.insert(overlays.overlay_ports.begin(), options.command_arguments[1]); auto& fs = paths.get_filesystem(); auto registry_set = paths.make_registry_set(); diff --git a/src/vcpkg/commands.build.cpp b/src/vcpkg/commands.build.cpp index 16029b5612..e6a3f04aad 100644 --- a/src/vcpkg/commands.build.cpp +++ b/src/vcpkg/commands.build.cpp @@ -96,7 +96,6 @@ namespace vcpkg CleanBuildtrees::No, CleanPackages::No, CleanDownloads::No, - DownloadTool::Builtin, BackcompatFeatures::Allow, }; @@ -130,7 +129,8 @@ namespace vcpkg auto& var_provider = *var_provider_storage; var_provider.load_dep_info_vars({{spec}}, host_triplet); - StatusParagraphs status_db = database_load_collapse(paths.get_filesystem(), paths.installed()); + auto& fs = paths.get_filesystem(); + StatusParagraphs status_db = database_load_collapse(fs, paths.installed()); auto action_plan = create_feature_install_plan( provider, var_provider, @@ -172,7 +172,12 @@ namespace vcpkg msg::path = spec_name); } - auto binary_cache = BinaryCache::make(args, paths, out_sink).value_or_exit(VCPKG_LINE_INFO); + BinaryCache binary_cache(fs); + if (!binary_cache.install_providers(args, paths, out_sink)) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + const ElapsedTimer build_timer; const auto result = build_package(args, paths, host_triplet, build_options, *action, build_logs_recorder, status_db); @@ -207,7 +212,7 @@ namespace vcpkg msg::print(Color::warning, warnings); } msg::println_error(create_error_message(result, spec)); - msg::print(create_user_troubleshooting_message(*action, paths, nullopt)); + msg::print(create_user_troubleshooting_message(*action, args.detected_ci(), paths, {}, nullopt)); return 1; } case BuildResult::Excluded: @@ -289,18 +294,6 @@ namespace vcpkg } } - StringLiteral to_string_view(DownloadTool tool) - { - switch (tool) - { - case DownloadTool::Builtin: return "BUILT_IN"; - case DownloadTool::Aria2: return "ARIA2"; - default: Checks::unreachable(VCPKG_LINE_INFO); - } - } - - std::string to_string(DownloadTool tool) { return to_string_view(tool).to_string(); } - Optional to_linkage_type(StringView str) { if (str == "dynamic") return LinkageType::Dynamic; @@ -323,7 +316,9 @@ namespace vcpkg auto maybe_target_arch = to_cpu_architecture(target_architecture); if (!maybe_target_arch.has_value()) { - msg::println_error(msgInvalidArchitecture, msg::value = target_architecture); + msg::println_error(msgInvalidArchitectureValue, + msg::value = target_architecture, + msg::expected = all_comma_separated_cpu_architectures()); Checks::exit_maybe_upgrade(VCPKG_LINE_INFO); } @@ -693,7 +688,9 @@ namespace vcpkg paths.packages() / fmt::format("{}_{}", FileDetectCompiler, triplet.canonical_name())}, // The detect_compiler "port" doesn't depend on the host triplet, so always natively compile {CMakeVariableHostTriplet, triplet.canonical_name()}, + {CMakeVariableCompilerCacheFile, paths.installed().compiler_hash_cache_file()}, }; + get_generic_cmake_build_args(paths, triplet, toolset, cmake_args); auto cmd = vcpkg::make_cmake_cmd(paths, paths.ports_cmake, std::move(cmake_args)); @@ -785,18 +782,12 @@ namespace vcpkg {CMakeVariablePort, port_name}, {CMakeVariableVersion, scf.to_version().text}, {CMakeVariableUseHeadVersion, Util::Enum::to_bool(action.use_head_version) ? "1" : "0"}, - {CMakeVariableDownloadTool, to_string_view(build_options.download_tool)}, {CMakeVariableEditable, Util::Enum::to_bool(action.editable) ? "1" : "0"}, {CMakeVariableNoDownloads, !Util::Enum::to_bool(build_options.allow_downloads) ? "1" : "0"}, {CMakeVariableZChainloadToolchainFile, action.pre_build_info(VCPKG_LINE_INFO).toolchain_file()}, {CMakeVariableZPostPortfileIncludes, all_post_portfile_includes}, }; - if (build_options.download_tool == DownloadTool::Aria2) - { - variables.emplace_back("ARIA2", paths.get_tool_exe(Tools::ARIA2, out_sink)); - } - if (auto cmake_debug = args.cmake_debug.get()) { if (cmake_debug->is_port_affected(port_name)) @@ -1060,7 +1051,7 @@ namespace vcpkg size_t error_count = 0; { FileSink file_sink{fs, stdoutlog, Append::YES}; - CombiningSink combo_sink{out_sink, file_sink}; + TeeSink combo_sink{out_sink, file_sink}; error_count = perform_post_build_lint_checks( action.spec, paths, pre_build_info, build_info, scfl.port_directory(), combo_sink); }; @@ -1636,7 +1627,7 @@ namespace vcpkg fmt::format_to(std::back_inserter(issue_body), "Package: {}\n\n**Host Environment**\n\n- Host: {}-{}\n", action.display_name(), - to_zstring_view(get_host_processor()), + get_host_processor(), get_host_os_name()); if (const auto* abi_info = action.abi_info.get()) @@ -1690,43 +1681,144 @@ namespace vcpkg return "https://github.com/microsoft/vcpkg/issues?q=is%3Aissue+is%3Aopen+in%3Atitle+" + spec_name; } - static std::string make_gh_issue_open_url(StringView spec_name, StringView triplet, StringView path) + static std::string make_gh_issue_open_url(StringView spec_name, StringView triplet, StringView body) { return Strings::concat("https://github.com/microsoft/vcpkg/issues/new?title=[", spec_name, "]+Build+error+on+", triplet, - "&body=Copy+issue+body+from+", - Strings::percent_encode(path)); + "&body=", + Strings::percent_encode(body)); + } + + static bool is_collapsible_ci_kind(CIKind kind) + { + switch (kind) + { + case CIKind::GithubActions: + case CIKind::GitLabCI: + case CIKind::AzurePipelines: return true; + case CIKind::None: + case CIKind::AppVeyor: + case CIKind::AwsCodeBuild: + case CIKind::CircleCI: + case CIKind::HerokuCI: + case CIKind::JenkinsCI: + case CIKind::TeamCityCI: + case CIKind::TravisCI: + case CIKind::Generic: return false; + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + static void append_file_collapsible(LocalizedString& output, + CIKind kind, + const ReadOnlyFilesystem& fs, + const Path& file) + { + auto title = file.filename(); + auto contents = fs.read_contents(file, VCPKG_LINE_INFO); + switch (kind) + { + case CIKind::GithubActions: + // https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#grouping-log-lines + output.append_raw("::group::") + .append_raw(title) + .append_raw('\n') + .append_raw(contents) + .append_raw("::endgroup::\n"); + break; + case CIKind::GitLabCI: + { + // https://docs.gitlab.com/ee/ci/jobs/job_logs.html#custom-collapsible-sections + using namespace std::chrono; + std::string section_name; + std::copy_if(title.begin(), title.end(), std::back_inserter(section_name), [](char c) { + return c == '.' || ParserBase::is_alphanum(c); + }); + const auto timestamp = duration_cast(system_clock::now().time_since_epoch()).count(); + output + .append_raw( + fmt::format("\\e[0Ksection_start:{}:{}[collapsed=true]\r\\e[0K", timestamp, section_name)) + .append_raw(title) + .append_raw('\n') + .append_raw(contents) + .append_raw(fmt::format("\\e[0Ksection_end:{}:{}\r\\e[0K\n", timestamp, section_name)); + } + break; + case CIKind::AzurePipelines: + // https://learn.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?view=azure-devops&tabs=bash#formatting-commands + output.append_raw("##vso[task.uploadfile]") + .append_raw(file) + .append_raw('\n') + .append_raw("##[group]") + .append_raw(title) + .append_raw('\n') + .append_raw(contents) + .append_raw("##[endgroup]\n"); + break; + case CIKind::None: + case CIKind::AppVeyor: + case CIKind::AwsCodeBuild: + case CIKind::CircleCI: + case CIKind::HerokuCI: + case CIKind::JenkinsCI: + case CIKind::TeamCityCI: + case CIKind::TravisCI: + case CIKind::Generic: Checks::unreachable(VCPKG_LINE_INFO, "CIKind not collapsible"); + default: Checks::unreachable(VCPKG_LINE_INFO); + } } LocalizedString create_user_troubleshooting_message(const InstallPlanAction& action, + CIKind detected_ci, const VcpkgPaths& paths, - const Optional& issue_body) + const std::vector& error_logs, + const Optional& maybe_issue_body) { const auto& spec_name = action.spec.name(); const auto& triplet_name = action.spec.triplet().to_string(); LocalizedString result = msg::format(msgBuildTroubleshootingMessage1).append_raw('\n'); result.append_indent().append_raw(make_gh_issue_search_url(spec_name)).append_raw('\n'); - result.append(msgBuildTroubleshootingMessage2).append_raw('\n'); - if (issue_body.has_value()) + result.append(msgBuildTroubleshootingMessage2).append_raw('\n').append_indent(); + + if (auto issue_body = maybe_issue_body.get()) { - const auto path = issue_body.get()->generic_u8string(); - result.append_indent().append_raw(make_gh_issue_open_url(spec_name, triplet_name, path)).append_raw('\n'); - if (!paths.get_filesystem().find_from_PATH("gh").empty()) + auto& fs = paths.get_filesystem(); + // The 'body' content is not localized because it becomes part of the posted GitHub issue + // rather than instructions for the current user of vcpkg. + if (is_collapsible_ci_kind(detected_ci)) { - Command gh("gh"); - gh.string_arg("issue").string_arg("create").string_arg("-R").string_arg("microsoft/vcpkg"); - gh.string_arg("--title").string_arg(fmt::format("[{}] Build failure on {}", spec_name, triplet_name)); - gh.string_arg("--body-file").string_arg(path); - - result.append(msgBuildTroubleshootingMessageGH).append_raw('\n'); - result.append_indent().append_raw(gh.command_line()); + auto body = fmt::format("Copy issue body from collapsed section \"{}\" in the ci log output", + issue_body->filename()); + result.append_raw(make_gh_issue_open_url(spec_name, triplet_name, body)).append_raw('\n'); + append_file_collapsible(result, detected_ci, fs, *issue_body); + for (Path error_log_path : error_logs) + { + append_file_collapsible(result, detected_ci, fs, error_log_path); + } + } + else + { + const auto path = issue_body->generic_u8string(); + auto body = fmt::format("Copy issue body from {}", path); + result.append_raw(make_gh_issue_open_url(spec_name, triplet_name, body)).append_raw('\n'); + auto gh_path = fs.find_from_PATH("gh"); + if (!gh_path.empty()) + { + Command gh(gh_path[0]); + gh.string_arg("issue").string_arg("create").string_arg("-R").string_arg("microsoft/vcpkg"); + gh.string_arg("--title").string_arg( + fmt::format("[{}] Build failure on {}", spec_name, triplet_name)); + gh.string_arg("--body-file").string_arg(path); + result.append(msgBuildTroubleshootingMessageGH).append_raw('\n'); + result.append_indent().append_raw(gh.command_line()); + } } } else { - result.append_indent() + result .append_raw("https://github.com/microsoft/vcpkg/issues/" "new?template=report-package-build-failure.md&title=[") .append_raw(spec_name) diff --git a/src/vcpkg/commands.ci-verify-versions.cpp b/src/vcpkg/commands.ci-verify-versions.cpp index 2fd5191cc4..fc4b4400f1 100644 --- a/src/vcpkg/commands.ci-verify-versions.cpp +++ b/src/vcpkg/commands.ci-verify-versions.cpp @@ -43,14 +43,13 @@ namespace if (!extracted_tree) { success = false; - errors_sink.print(Color::error, - LocalizedString::from_raw(versions_file_path) - .append_raw(": ") - .append(maybe_extracted_tree.error()) - .append_raw('\n') - .append_raw(NotePrefix) - .append(msgWhileValidatingVersion, msg::version = version_entry.version.version) - .append_raw('\n')); + errors_sink.println(Color::error, + LocalizedString::from_raw(versions_file_path) + .append_raw(": ") + .append(maybe_extracted_tree.error()) + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgWhileValidatingVersion, msg::version = version_entry.version.version)); return success; } @@ -70,14 +69,13 @@ namespace // // However including both paths likely helps investigation and there isn't an easy way to replace only that // file path right now - errors_sink.print(Color::error, - LocalizedString::from_raw(versions_file_path) - .append_raw(": ") - .append(load_result.maybe_scfl.error()) - .append_raw('\n') - .append_raw(NotePrefix) - .append(msgWhileValidatingVersion, msg::version = version_entry.version.version) - .append_raw('\n')); + errors_sink.println(Color::error, + LocalizedString::from_raw(versions_file_path) + .append_raw(": ") + .append(load_result.maybe_scfl.error()) + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgWhileValidatingVersion, msg::version = version_entry.version.version)); return success; } @@ -87,50 +85,47 @@ namespace if (version_entry_spec != scfl_spec) { success = false; - errors_sink.print(Color::error, - LocalizedString::from_raw(versions_file_path) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgVersionInDeclarationDoesNotMatch, - msg::git_tree_sha = version_entry.git_tree, - msg::expected = version_entry_spec, - msg::actual = scfl_spec) - .append_raw('\n')); + errors_sink.println(Color::error, + LocalizedString::from_raw(versions_file_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionInDeclarationDoesNotMatch, + msg::git_tree_sha = version_entry.git_tree, + msg::expected = version_entry_spec, + msg::actual = scfl_spec)); } if (version_entry.version.scheme != git_tree_version.scheme) { success = false; - errors_sink.print(Color::error, - LocalizedString::from_raw(versions_file_path) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgVersionSchemeMismatch1Old, - msg::version = version_entry.version.version, - msg::expected = get_scheme_name(version_entry.version.scheme), - msg::actual = get_scheme_name(git_tree_version.scheme), - msg::package_name = port_name, - msg::git_tree_sha = version_entry.git_tree) - .append_raw('\n') - .append_raw(scfl->control_path) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgPortDeclaredHere, msg::package_name = port_name) - .append_raw('\n') - .append_raw(NotePrefix) - .append(msgVersionSchemeMismatch2) - .append_raw('\n')); + errors_sink.println(Color::error, + LocalizedString::from_raw(versions_file_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionSchemeMismatch1Old, + msg::version = version_entry.version.version, + msg::expected = get_scheme_name(version_entry.version.scheme), + msg::actual = get_scheme_name(git_tree_version.scheme), + msg::package_name = port_name, + msg::git_tree_sha = version_entry.git_tree) + .append_raw('\n') + .append_raw(scfl->control_path) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgPortDeclaredHere, msg::package_name = port_name) + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgVersionSchemeMismatch2)); } if (success) { - success_sink.print(LocalizedString::from_raw(versions_file_path) - .append_raw(": ") - .append_raw(MessagePrefix) - .append(msgVersionVerifiedOK, - msg::version_spec = VersionSpec{port_name, version_entry.version.version}, - msg::git_tree_sha = version_entry.git_tree) - .append_raw('\n')); + success_sink.println(LocalizedString::from_raw(versions_file_path) + .append_raw(": ") + .append_raw(MessagePrefix) + .append(msgVersionVerifiedOK, + msg::version_spec = VersionSpec{port_name, version_entry.version.version}, + msg::git_tree_sha = version_entry.git_tree)); } return success; @@ -156,21 +151,20 @@ namespace if (!entries) { success = false; - errors_sink.print(Color::error, - LocalizedString::from_raw(scfl.control_path) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgVersionDatabaseFileMissing) - .append_raw('\n') - .append_raw(versions_database_entry.versions_file_path) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgVersionDatabaseFileMissing2) - .append_raw('\n') - .append_raw(NotePrefix) - .append(msgVersionDatabaseFileMissing3, - msg::command_line = fmt::format("vcpkg x-add-version {}", port_name)) - .append_raw('\n')); + errors_sink.println(Color::error, + LocalizedString::from_raw(scfl.control_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionDatabaseFileMissing) + .append_raw('\n') + .append_raw(versions_database_entry.versions_file_path) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgVersionDatabaseFileMissing2) + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgVersionDatabaseFileMissing3, + msg::command_line = fmt::format("vcpkg x-add-version {}", port_name))); return success; } @@ -185,22 +179,21 @@ namespace if (it == versions_end) { success = false; - errors_sink.print(Color::error, - LocalizedString::from_raw(scfl.control_path) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgVersionNotFoundInVersionsFile2, - msg::version_spec = VersionSpec{port_name, local_port_version.version}) - .append_raw('\n') - .append_raw(versions_database_entry.versions_file_path) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgVersionNotFoundInVersionsFile3) - .append_raw('\n') - .append_raw(NotePrefix) - .append(msgVersionNotFoundInVersionsFile4, - msg::command_line = fmt::format("vcpkg x-add-version {}", port_name)) - .append_raw('\n')); + errors_sink.println(Color::error, + LocalizedString::from_raw(scfl.control_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionNotFoundInVersionsFile2, + msg::version_spec = VersionSpec{port_name, local_port_version.version}) + .append_raw('\n') + .append_raw(versions_database_entry.versions_file_path) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgVersionNotFoundInVersionsFile3) + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgVersionNotFoundInVersionsFile4, + msg::command_line = fmt::format("vcpkg x-add-version {}", port_name))); return success; } @@ -209,7 +202,7 @@ namespace { success = false; // assume the port is correct, so report the error on the version database file - errors_sink.print( + errors_sink.println( Color::error, LocalizedString::from_raw(versions_database_entry.versions_file_path) .append_raw(": ") @@ -230,58 +223,56 @@ namespace .append_raw('\n') .append_raw(NotePrefix) .append(msgVersionOverwriteVersion, msg::version_spec = local_version_spec) - .append_raw(fmt::format("\nvcpkg x-add-version {} --overwrite-version\n", port_name))); + .append_raw(fmt::format("\nvcpkg x-add-version {} --overwrite-version", port_name))); } if (local_git_tree != version_entry.git_tree) { success = false; - errors_sink.print(Color::error, - LocalizedString::from_raw(versions_database_entry.versions_file_path) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgVersionShaMismatch1, - msg::version_spec = local_version_spec, - msg::git_tree_sha = version_entry.git_tree) - .append_raw('\n') - .append_raw(scfl.port_directory()) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgVersionShaMismatch2, msg::git_tree_sha = local_git_tree) - .append_raw('\n') - .append_raw(scfl.control_path) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgVersionShaMismatch3, msg::version_spec = local_version_spec) - .append_raw('\n') - .append_indent() - .append_raw(fmt::format("vcpkg x-add-version {}\n", port_name)) - .append_indent() - .append_raw("git add versions\n") - .append_indent() - .append(msgGitCommitUpdateVersionDatabase) - .append_raw('\n') - .append_raw(NotePrefix) - .append(msgVersionShaMismatch4, msg::version_spec = local_version_spec) - .append_raw('\n') - .append_indent() - .append_raw(fmt::format("vcpkg x-add-version {} --overwrite-version\n", port_name)) - .append_indent() - .append_raw("git add versions\n") - .append_indent() - .append(msgGitCommitUpdateVersionDatabase) - .append_raw('\n')); + errors_sink.println(Color::error, + LocalizedString::from_raw(versions_database_entry.versions_file_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionShaMismatch1, + msg::version_spec = local_version_spec, + msg::git_tree_sha = version_entry.git_tree) + .append_raw('\n') + .append_raw(scfl.port_directory()) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgVersionShaMismatch2, msg::git_tree_sha = local_git_tree) + .append_raw('\n') + .append_raw(scfl.control_path) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgVersionShaMismatch3, msg::version_spec = local_version_spec) + .append_raw('\n') + .append_indent() + .append_raw(fmt::format("vcpkg x-add-version {}\n", port_name)) + .append_indent() + .append_raw("git add versions\n") + .append_indent() + .append(msgGitCommitUpdateVersionDatabase) + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgVersionShaMismatch4, msg::version_spec = local_version_spec) + .append_raw('\n') + .append_indent() + .append_raw(fmt::format("vcpkg x-add-version {} --overwrite-version\n", port_name)) + .append_indent() + .append_raw("git add versions\n") + .append_indent() + .append(msgGitCommitUpdateVersionDatabase)); } if (success) { - success_sink.print(LocalizedString::from_raw(scfl.port_directory()) - .append_raw(": ") - .append_raw(MessagePrefix) - .append(msgVersionVerifiedOK, - msg::version_spec = local_version_spec, - msg::git_tree_sha = version_entry.git_tree) - .append_raw('\n')); + success_sink.println(LocalizedString::from_raw(scfl.port_directory()) + .append_raw(": ") + .append_raw(MessagePrefix) + .append(msgVersionVerifiedOK, + msg::version_spec = local_version_spec, + msg::git_tree_sha = version_entry.git_tree)); } return success; @@ -298,67 +289,64 @@ namespace auto maybe_baseline = baseline.find(port_name); if (maybe_baseline == baseline.end()) { - errors_sink.print(Color::error, - LocalizedString::from_raw(baseline_path) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgBaselineMissing, msg::package_name = port_name) - .append_raw('\n') - .append_raw(scfl.control_path) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgPortDeclaredHere, msg::package_name = port_name) - .append_raw('\n') - .append_raw(NotePrefix) - .append(msgAddVersionInstructions, msg::package_name = port_name) - .append_raw('\n') - .append_indent() - .append_raw(fmt::format("vcpkg x-add-version {}\n", port_name)) - .append_indent() - .append_raw("git add versions\n") - .append_indent() - .append(msgGitCommitUpdateVersionDatabase) - .append_raw('\n')); + errors_sink.println(Color::error, + LocalizedString::from_raw(baseline_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgBaselineMissing, msg::package_name = port_name) + .append_raw('\n') + .append_raw(scfl.control_path) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgPortDeclaredHere, msg::package_name = port_name) + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgAddVersionInstructions, msg::package_name = port_name) + .append_raw('\n') + .append_indent() + .append_raw(fmt::format("vcpkg x-add-version {}\n", port_name)) + .append_indent() + .append_raw("git add versions\n") + .append_indent() + .append(msgGitCommitUpdateVersionDatabase)); return false; } auto&& baseline_version = maybe_baseline->second; if (baseline_version == local_port_version.version) { - success_sink.print(LocalizedString::from_raw(baseline_path) - .append_raw(": ") - .append_raw(MessagePrefix) - .append(msgVersionBaselineMatch, - msg::version_spec = VersionSpec{port_name, local_port_version.version}) - .append_raw('\n')); + success_sink.println(LocalizedString::from_raw(baseline_path) + .append_raw(": ") + .append_raw(MessagePrefix) + .append(msgVersionBaselineMatch, + msg::version_spec = VersionSpec{port_name, local_port_version.version})); return true; } // assume the port is correct, so report the error on the baseline.json file - errors_sink.print(Color::error, - LocalizedString::from_raw(baseline_path) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgVersionBaselineMismatch, - msg::expected = local_port_version.version, - msg::actual = baseline_version, - msg::package_name = port_name) - .append_raw('\n') - .append_raw(scfl.control_path) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgPortDeclaredHere, msg::package_name = port_name) - .append_raw('\n') - .append_raw(NotePrefix) - .append(msgAddVersionInstructions, msg::package_name = port_name) - .append_raw('\n') - .append_indent() - .append_raw(fmt::format("vcpkg x-add-version {}\n", port_name)) - .append_indent() - .append_raw("git add versions\n") - .append_indent() - .append(msgGitCommitUpdateVersionDatabase) - .append_raw('\n')); + errors_sink.println(Color::error, + LocalizedString::from_raw(baseline_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionBaselineMismatch, + msg::expected = local_port_version.version, + msg::actual = baseline_version, + msg::package_name = port_name) + .append_raw('\n') + .append_raw(scfl.control_path) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgPortDeclaredHere, msg::package_name = port_name) + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgAddVersionInstructions, msg::package_name = port_name) + .append_raw('\n') + .append_indent() + .append_raw(fmt::format("vcpkg x-add-version {}\n", port_name)) + .append_indent() + .append_raw("git add versions\n") + .append_indent() + .append(msgGitCommitUpdateVersionDatabase)); return false; } @@ -382,16 +370,15 @@ namespace auto this_error = LocalizedString::from_raw(scfl.control_path) .append_raw(": ") .append_raw(ErrorPrefix) - .append(msgDependencyNotInVersionDatabase, msg::package_name = dependency.name) - .append_raw('\n'); + .append(msgDependencyNotInVersionDatabase, msg::package_name = dependency.name); if (feature_name) { - this_error.append_raw(NotePrefix) - .append(msgDependencyInFeature, msg::feature = *feature_name) - .append_raw('\n'); + this_error.append_raw('\n') + .append_raw(NotePrefix) + .append(msgDependencyInFeature, msg::feature = *feature_name); } - errors_sink.print(Color::error, std::move(this_error)); + errors_sink.println(Color::error, std::move(this_error)); return false; } @@ -411,16 +398,15 @@ namespace .append_raw(dependent_versions_db_entry.versions_file_path) .append_raw(": ") .append_raw(NotePrefix) - .append(msgVersionConstraintNotInDatabase2) - .append_raw('\n'); + .append(msgVersionConstraintNotInDatabase2); if (feature_name) { - this_error.append_raw(NotePrefix) - .append(msgDependencyInFeature, msg::feature = *feature_name) - .append_raw('\n'); + this_error.append_raw('\n') + .append_raw(NotePrefix) + .append(msgDependencyInFeature, msg::feature = *feature_name); } - errors_sink.print(Color::error, std::move(this_error)); + errors_sink.println(Color::error, std::move(this_error)); return false; } @@ -463,13 +449,12 @@ namespace if (!override_entries) { success = false; - errors_sink.print( + errors_sink.println( Color::error, LocalizedString::from_raw(scfl.control_path) .append_raw(": ") .append_raw(ErrorPrefix) - .append(msgVersionOverrideNotInVersionDatabase, msg::package_name = override_.name) - .append_raw('\n')); + .append(msgVersionOverrideNotInVersionDatabase, msg::package_name = override_.name)); continue; } @@ -478,29 +463,27 @@ namespace })) { success = false; - errors_sink.print(Color::error, - LocalizedString::from_raw(scfl.control_path) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgVersionOverrideVersionNotInVersionDatabase1, - msg::package_name = override_.name, - msg::version = override_.version) - .append_raw('\n') - .append_raw(override_versions_db_entry.versions_file_path) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgVersionOverrideVersionNotInVersionDatabase2) - .append_raw('\n')); + errors_sink.println(Color::error, + LocalizedString::from_raw(scfl.control_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionOverrideVersionNotInVersionDatabase1, + msg::package_name = override_.name, + msg::version = override_.version) + .append_raw('\n') + .append_raw(override_versions_db_entry.versions_file_path) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgVersionOverrideVersionNotInVersionDatabase2)); } } if (success) { - success_sink.print(LocalizedString::from_raw(scfl.control_path) - .append_raw(": ") - .append_raw(MessagePrefix) - .append(msgVersionConstraintOk) - .append_raw('\n')); + success_sink.println(LocalizedString::from_raw(scfl.control_path) + .append_raw(": ") + .append_raw(MessagePrefix) + .append(msgVersionConstraintOk)); } return success; @@ -568,7 +551,7 @@ namespace vcpkg auto git_tree_it = port_git_tree_map.find(port_name); if (git_tree_it == port_git_tree_map.end()) { - errors_sink.print( + errors_sink.println( Color::error, LocalizedString::from_raw(scfl.control_path) .append_raw(": ") @@ -587,7 +570,7 @@ namespace vcpkg .append_indent() .append_raw("git add versions\n") .append_indent() - .append_raw(fmt::format("git commit --amend -m \"{}\"\n", + .append_raw(fmt::format("git commit --amend -m \"{}\"", msg::format(msgVersionShaMissing4, msg::package_name = port_name)))); } else diff --git a/src/vcpkg/commands.ci.cpp b/src/vcpkg/commands.ci.cpp index c47ebf0acb..6c1f64ff10 100644 --- a/src/vcpkg/commands.ci.cpp +++ b/src/vcpkg/commands.ci.cpp @@ -316,6 +316,7 @@ namespace vcpkg { msg::println_warning(msgInternalCICommand); const ParsedArguments options = args.parse_arguments(CommandCiMetadata); + auto& fs = paths.get_filesystem(); const auto& settings = options.settings; static constexpr BuildPackageOptions build_options{ @@ -325,7 +326,6 @@ namespace vcpkg CleanBuildtrees::Yes, CleanPackages::Yes, CleanDownloads::No, - DownloadTool::Builtin, BackcompatFeatures::Prohibit, KeepGoing::Yes, }; @@ -348,8 +348,7 @@ namespace vcpkg auto skip_failures = Util::Sets::contains(options.switches, SwitchSkipFailures) ? SkipFailures::Yes : SkipFailures::No; const auto& ci_baseline_file_name = baseline_iter->second; - const auto ci_baseline_file_contents = - paths.get_filesystem().read_contents(ci_baseline_file_name, VCPKG_LINE_INFO); + const auto ci_baseline_file_contents = fs.read_contents(ci_baseline_file_name, VCPKG_LINE_INFO); ParseMessages ci_parse_messages; const auto lines = parse_ci_baseline(ci_baseline_file_contents, ci_baseline_file_name, ci_parse_messages); ci_parse_messages.exit_if_errors_or_warnings(ci_baseline_file_name); @@ -358,7 +357,6 @@ namespace vcpkg const auto is_dry_run = Util::Sets::contains(options.switches, SwitchDryRun); - auto& filesystem = paths.get_filesystem(); Optional build_logs_recorder_storage; { auto it_failure_logs = settings.find(SwitchFailureLogs); @@ -366,8 +364,8 @@ namespace vcpkg { msg::println(msgCreateFailureLogsDir, msg::path = it_failure_logs->second); Path raw_path = it_failure_logs->second; - filesystem.create_directories(raw_path, VCPKG_LINE_INFO); - build_logs_recorder_storage = filesystem.almost_canonical(raw_path, VCPKG_LINE_INFO); + fs.create_directories(raw_path, VCPKG_LINE_INFO); + build_logs_recorder_storage = fs.almost_canonical(raw_path, VCPKG_LINE_INFO); } } @@ -375,7 +373,7 @@ namespace vcpkg build_logs_recorder_storage ? *(build_logs_recorder_storage.get()) : null_build_logs_recorder(); auto registry_set = paths.make_registry_set(); - PathsPortFileProvider provider(*registry_set, make_overlay_provider(filesystem, paths.overlay_ports)); + PathsPortFileProvider provider(*registry_set, make_overlay_provider(fs, paths.overlay_ports)); auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); auto& var_provider = *var_provider_storage; @@ -410,7 +408,12 @@ namespace vcpkg randomizer, host_triplet, paths.packages(), UnsupportedPortAction::Warn, UseHeadVersion::No, Editable::No); auto action_plan = compute_full_plan(paths, provider, var_provider, all_default_full_specs, create_install_plan_options); - auto binary_cache = BinaryCache::make(args, paths, out_sink).value_or_exit(VCPKG_LINE_INFO); + BinaryCache binary_cache(fs); + if (!binary_cache.install_providers(args, paths, out_sink)) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + const auto precheck_results = binary_cache.precheck(action_plan.install_actions); auto split_specs = compute_action_statuses(ExclusionPredicate{&exclusions_map}, precheck_results, action_plan); LocalizedString not_supported_regressions; @@ -462,7 +465,7 @@ namespace vcpkg Json::Value::string(action.abi_info.value_or_exit(VCPKG_LINE_INFO).package_abi)); arr.push_back(std::move(obj)); } - filesystem.write_contents(output_hash_json, Json::stringify(arr), VCPKG_LINE_INFO); + fs.write_contents(output_hash_json, Json::stringify(arr), VCPKG_LINE_INFO); } } @@ -472,7 +475,7 @@ namespace vcpkg if (it_parent_hashes != settings.end()) { const Path parent_hashes_path = paths.original_cwd / it_parent_hashes->second; - auto parsed_json = Json::parse_file(VCPKG_LINE_INFO, filesystem, parent_hashes_path).value; + auto parsed_json = Json::parse_file(VCPKG_LINE_INFO, fs, parent_hashes_path).value; parent_hashes = Util::fmap(parsed_json.array(VCPKG_LINE_INFO), [](const auto& json_object) { auto abi = json_object.object(VCPKG_LINE_INFO).get(JsonIdAbi); Checks::check_exit(VCPKG_LINE_INFO, abi); @@ -500,7 +503,7 @@ namespace vcpkg } else { - StatusParagraphs status_db = database_load_collapse(paths.get_filesystem(), paths.installed()); + StatusParagraphs status_db = database_load_collapse(fs, paths.installed()); auto already_installed = adjust_action_plan_to_status_db(action_plan, status_db); Util::erase_if(already_installed, [&](auto& spec) { return Util::Sets::contains(split_specs->known, spec); }); @@ -569,8 +572,7 @@ namespace vcpkg } } - filesystem.write_contents( - it_xunit->second, xunitTestResults.build_xml(target_triplet), VCPKG_LINE_INFO); + fs.write_contents(it_xunit->second, xunitTestResults.build_xml(target_triplet), VCPKG_LINE_INFO); } if (any_regressions) @@ -578,7 +580,7 @@ namespace vcpkg Checks::exit_fail(VCPKG_LINE_INFO); } } - + binary_cache.wait_for_async_complete_and_join(); Checks::exit_success(VCPKG_LINE_INFO); } } // namespace vcpkg diff --git a/src/vcpkg/commands.download.cpp b/src/vcpkg/commands.download.cpp index 5210182544..8e2ee8f44c 100644 --- a/src/vcpkg/commands.download.cpp +++ b/src/vcpkg/commands.download.cpp @@ -82,7 +82,6 @@ namespace vcpkg { Checks::msg_exit_with_error(VCPKG_LINE_INFO, msgImproperShaLength, msg::value = *p); } - Strings::inplace_ascii_to_lowercase(p->data(), p->data() + p->size()); } return sha; @@ -91,8 +90,8 @@ namespace vcpkg void command_download_and_exit(const VcpkgCmdArguments& args, const Filesystem& fs) { auto parsed = args.parse_arguments(CommandDownloadMetadata); - DownloadManager download_manager{ - parse_download_configuration(args.asset_sources_template()).value_or_exit(VCPKG_LINE_INFO)}; + auto asset_cache_settings = + parse_download_configuration(args.asset_sources_template()).value_or_exit(VCPKG_LINE_INFO); auto file = fs.absolute(parsed.command_arguments[0], VCPKG_LINE_INFO); auto sha = get_sha512_check(parsed); @@ -118,7 +117,12 @@ namespace vcpkg msg::println_error(msgMismatchedFiles); Checks::unreachable(VCPKG_LINE_INFO); } - download_manager.put_file_to_mirror(fs, file, actual_hash).value_or_exit(VCPKG_LINE_INFO); + + if (!store_to_asset_cache(console_diagnostic_context, asset_cache_settings, file, actual_hash)) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + Checks::exit_success(VCPKG_LINE_INFO); } else @@ -138,14 +142,20 @@ namespace vcpkg urls = it_urls->second; } - download_manager.download_file( - fs, - urls, - headers, - file, - sha, - Util::Sets::contains(parsed.switches, SwitchZMachineReadableProgress) ? out_sink : null_sink); - Checks::exit_success(VCPKG_LINE_INFO); + if (download_file_asset_cached( + console_diagnostic_context, + Util::Sets::contains(parsed.switches, SwitchZMachineReadableProgress) ? out_sink : null_sink, + asset_cache_settings, + fs, + urls, + headers, + file, + sha)) + { + Checks::exit_success(VCPKG_LINE_INFO); + } + + Checks::exit_fail(VCPKG_LINE_INFO); } } } // namespace vcpkg diff --git a/src/vcpkg/commands.export.cpp b/src/vcpkg/commands.export.cpp index 698d96a9f5..13fbac152d 100644 --- a/src/vcpkg/commands.export.cpp +++ b/src/vcpkg/commands.export.cpp @@ -617,9 +617,9 @@ namespace vcpkg print_export_plan(group_by_plan_type); const bool has_non_user_requested_packages = - Util::find_if(export_plan, [](const ExportPlanAction& package) -> bool { + Util::any_of(export_plan, [](const ExportPlanAction& package) -> bool { return package.request_type != RequestType::USER_REQUESTED; - }) != export_plan.cend(); + }); if (has_non_user_requested_packages) { diff --git a/src/vcpkg/commands.find.cpp b/src/vcpkg/commands.find.cpp index d40a307193..a996f83309 100644 --- a/src/vcpkg/commands.find.cpp +++ b/src/vcpkg/commands.find.cpp @@ -133,7 +133,7 @@ namespace vcpkg bool full_description, bool enable_json, Optional filter, - View overlay_ports) + const OverlayPortPaths& overlay_ports) { Checks::check_exit(VCPKG_LINE_INFO, msg::default_output_stream == OutputStream::StdErr); auto& fs = paths.get_filesystem(); diff --git a/src/vcpkg/commands.format-manifest.cpp b/src/vcpkg/commands.format-manifest.cpp index d1199f167f..3bfae50bc4 100644 --- a/src/vcpkg/commands.format-manifest.cpp +++ b/src/vcpkg/commands.format-manifest.cpp @@ -148,7 +148,7 @@ namespace vcpkg else { auto maybe_manifest = - Paragraphs::try_load_project_manifest_text(contents->content, contents->origin, stdout_sink); + Paragraphs::try_load_project_manifest_text(contents->content, contents->origin, out_sink); if (auto manifest = maybe_manifest.get()) { to_write.push_back(ToWrite{contents->content, std::move(*manifest), path, path}); diff --git a/src/vcpkg/commands.help.cpp b/src/vcpkg/commands.help.cpp index 6c29d18ef1..b2206064cf 100644 --- a/src/vcpkg/commands.help.cpp +++ b/src/vcpkg/commands.help.cpp @@ -78,7 +78,7 @@ namespace {"assetcaching", [](const VcpkgPaths&) { msg::println(format_help_topic_asset_caching()); }}, {"binarycaching", [](const VcpkgPaths&) { msg::println(format_help_topic_binary_caching()); }}, {"commands", [](const VcpkgPaths&) { print_full_command_list(); }}, - {"topics", [](const VcpkgPaths&) { msg::print(help_topics()); }}, + {"topics", [](const VcpkgPaths&) { msg::println(help_topics()); }}, {"triplet", [](const VcpkgPaths& paths) { help_topic_valid_triplet(paths.get_triplet_db()); }}, {"versioning", help_topic_versioning}, }; @@ -101,7 +101,6 @@ namespace LocalizedString result; result.append(msgAvailableHelpTopics); result.append_floating_list(1, all_topic_names); - result.append_raw('\n'); return result; } @@ -193,8 +192,8 @@ namespace vcpkg } } - stderr_sink.println_error(msgUnknownTopic, msg::value = topic); - stderr_sink.print(help_topics()); + stderr_sink.println(msg::format_error(msgUnknownTopic, msg::value = topic)); + stderr_sink.println(help_topics()); get_global_metrics_collector().track_string(StringMetric::CommandContext, "unknown"); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/src/vcpkg/commands.install.cpp b/src/vcpkg/commands.install.cpp index 55be0ef233..3214a2405f 100644 --- a/src/vcpkg/commands.install.cpp +++ b/src/vcpkg/commands.install.cpp @@ -630,6 +630,7 @@ namespace vcpkg for (auto&& action : action_plan.install_actions) { + binary_cache.print_updates(); TrackedPackageInstallGuard this_install(action_index++, action_count, summary.results, action); auto result = perform_install_plan_action( args, paths, host_triplet, build_options, action, status_db, binary_cache, build_logs_recorder); @@ -643,14 +644,19 @@ namespace vcpkg { this_install.print_elapsed_time(); print_user_troubleshooting_message( - action, paths, result.stdoutlog.then([&](auto&) -> Optional { - auto issue_body_path = paths.installed().root() / "vcpkg" / "issue_body.md"; + action, + args.detected_ci(), + paths, + result.error_logs, + result.stdoutlog.then([&](auto&) -> Optional { + auto issue_body_path = paths.installed().root() / FileVcpkg / FileIssueBodyMD; paths.get_filesystem().write_contents( issue_body_path, create_github_issue(args, result, paths, action, include_manifest_in_github_issue), VCPKG_LINE_INFO); return issue_body_path; })); + binary_cache.wait_for_async_complete_and_join(); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -686,7 +692,6 @@ namespace vcpkg {SwitchRecurse, msgHelpTxtOptRecurse}, {SwitchKeepGoing, msgHelpTxtOptKeepGoing}, {SwitchEditable, msgHelpTxtOptEditable}, - {SwitchXUseAria2, msgHelpTxtOptUseAria2}, {SwitchCleanAfterBuild, msgHelpTxtOptCleanAfterBuild}, {SwitchCleanBuildtreesAfterBuild, msgHelpTxtOptCleanBuildTreesAfterBuild}, {SwitchCleanPackagesAfterBuild, msgHelpTxtOptCleanPkgAfterBuild}, @@ -1083,8 +1088,9 @@ namespace vcpkg Triplet default_triplet, Triplet host_triplet) { - const ParsedArguments options = args.parse_arguments( - paths.manifest_mode_enabled() ? CommandInstallMetadataManifest : CommandInstallMetadataClassic); + auto manifest = paths.get_manifest().get(); + const ParsedArguments options = + args.parse_arguments(manifest ? CommandInstallMetadataManifest : CommandInstallMetadataClassic); const bool dry_run = Util::Sets::contains(options.switches, SwitchDryRun); const bool use_head_version = Util::Sets::contains(options.switches, (SwitchHead)); @@ -1094,7 +1100,6 @@ namespace vcpkg const bool is_recursive = Util::Sets::contains(options.switches, (SwitchRecurse)); const bool is_editable = Util::Sets::contains(options.switches, (SwitchEditable)) || cmake_args_sets_variable(args); - const bool use_aria2 = Util::Sets::contains(options.switches, (SwitchXUseAria2)); const bool clean_after_build = Util::Sets::contains(options.switches, (SwitchCleanAfterBuild)); const bool clean_buildtrees_after_build = Util::Sets::contains(options.switches, (SwitchCleanBuildtreesAfterBuild)); @@ -1111,9 +1116,9 @@ namespace vcpkg : UnsupportedPortAction::Error; const bool print_cmake_usage = !Util::Sets::contains(options.switches, SwitchNoPrintUsage); - get_global_metrics_collector().track_bool(BoolMetric::InstallManifestMode, paths.manifest_mode_enabled()); + get_global_metrics_collector().track_bool(BoolMetric::InstallManifestMode, manifest); - if (auto p = paths.get_manifest().get()) + if (manifest) { bool failure = false; if (!options.command_arguments.empty()) @@ -1134,7 +1139,7 @@ namespace vcpkg } if (failure) { - msg::println(msgUsingManifestAt, msg::path = p->path); + msg::println(msgUsingManifestAt, msg::path = manifest->path); msg::print(usage_for_command(CommandInstallMetadataManifest)); Checks::exit_fail(VCPKG_LINE_INFO); } @@ -1166,9 +1171,6 @@ namespace vcpkg auto& fs = paths.get_filesystem(); - DownloadTool download_tool = DownloadTool::Builtin; - if (use_aria2) download_tool = DownloadTool::Aria2; - const BuildPackageOptions build_package_options = { Util::Enum::to_enum(!no_build_missing), Util::Enum::to_enum(!no_downloads), @@ -1176,7 +1178,6 @@ namespace vcpkg Util::Enum::to_enum(clean_after_build || clean_buildtrees_after_build), Util::Enum::to_enum(clean_after_build || clean_packages_after_build), Util::Enum::to_enum(clean_after_build || clean_downloads_after_build), - download_tool, prohibit_backcompat_features ? BackcompatFeatures::Prohibit : BackcompatFeatures::Allow, keep_going, }; @@ -1191,7 +1192,7 @@ namespace vcpkg auto var_provider_storage = CMakeVars::make_triplet_cmake_var_provider(paths); auto& var_provider = *var_provider_storage; - if (auto manifest = paths.get_manifest().get()) + if (manifest) { Optional pkgsconfig; auto it_pkgsconfig = options.settings.find(SwitchXWriteNuGetPackagesConfig); @@ -1292,16 +1293,14 @@ namespace vcpkg auto verprovider = make_versioned_portfile_provider(*registry_set); auto baseprovider = make_baseline_provider(*registry_set); - std::vector extended_overlay_ports; - extended_overlay_ports.reserve(paths.overlay_ports.size() + add_builtin_ports_directory_as_overlay); - extended_overlay_ports = paths.overlay_ports; + auto extended_overlay_port_directories = paths.overlay_ports; if (add_builtin_ports_directory_as_overlay) { - extended_overlay_ports.emplace_back(paths.builtin_ports_directory()); + extended_overlay_port_directories.builtin_overlay_port_dir.emplace(paths.builtin_ports_directory()); } auto oprovider = - make_manifest_provider(fs, extended_overlay_ports, manifest->path, std::move(manifest_scf)); + make_manifest_provider(fs, extended_overlay_port_directories, manifest->path, std::move(manifest_scf)); auto install_plan = create_versioned_install_plan(*verprovider, *baseprovider, *oprovider, @@ -1358,22 +1357,22 @@ namespace vcpkg #if defined(_WIN32) const auto maybe_common_triplet = Util::common_projection( action_plan.install_actions, [](const InstallPlanAction& to_install) { return to_install.spec.triplet(); }); - if (maybe_common_triplet) + if (auto common_triplet = maybe_common_triplet.get()) { - const auto& common_triplet = maybe_common_triplet.value_or_exit(VCPKG_LINE_INFO); - const auto maybe_common_arch = common_triplet.guess_architecture(); - if (maybe_common_arch) + const auto maybe_common_arch = common_triplet->guess_architecture(); + if (auto common_arch = maybe_common_arch.get()) { const auto maybe_vs_prompt = guess_visual_studio_prompt_target_architecture(); - if (maybe_vs_prompt) + if (auto vs_prompt = maybe_vs_prompt.get()) { - const auto common_arch = maybe_common_arch.value_or_exit(VCPKG_LINE_INFO); - const auto vs_prompt = maybe_vs_prompt.value_or_exit(VCPKG_LINE_INFO); - if (common_arch != vs_prompt) + // There is no "Developer Command Prompt for ARM64EC". ARM64EC and ARM64 use the same developer + // command prompt, and compiler toolset version. The only difference is adding a /arm64ec switch to + // the build + if (*common_arch != *vs_prompt && + !(*common_arch == CPUArchitecture::ARM64EC && *vs_prompt == CPUArchitecture::ARM64)) { - const auto vs_prompt_view = to_zstring_view(vs_prompt); msg::println_warning( - msgVcpkgInVsPrompt, msg::value = vs_prompt_view, msg::triplet = common_triplet); + msgVcpkgInVsPrompt, msg::value = *vs_prompt, msg::triplet = *common_triplet); } } } @@ -1413,8 +1412,15 @@ namespace vcpkg track_install_plan(action_plan); install_preclear_packages(paths, action_plan); - auto binary_cache = only_downloads ? BinaryCache(paths.get_filesystem()) - : BinaryCache::make(args, paths, out_sink).value_or_exit(VCPKG_LINE_INFO); + BinaryCache binary_cache(fs); + if (!only_downloads) + { + if (!binary_cache.install_providers(args, paths, out_sink)) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + binary_cache.fetch(action_plan.install_actions); const InstallSummary summary = install_execute_plan(args, paths, @@ -1465,7 +1471,7 @@ namespace vcpkg install_print_usage_information(*bpgh, printed_usages, fs, paths.installed()); } } - + binary_cache.wait_for_async_complete_and_join(); summary.print_complete_message(); Checks::exit_with_code(VCPKG_LINE_INFO, summary.failed); } diff --git a/src/vcpkg/commands.package-info.cpp b/src/vcpkg/commands.package-info.cpp index 2d8df043b8..cfca0757b2 100644 --- a/src/vcpkg/commands.package-info.cpp +++ b/src/vcpkg/commands.package-info.cpp @@ -106,7 +106,7 @@ namespace vcpkg for (auto&& arg : options.command_arguments) { - ParserBase parser(arg, nullopt); + ParserBase parser(arg, nullopt, {0, 0}); auto maybe_pkg = parse_package_name(parser); if (!parser.at_eof() || !maybe_pkg) { diff --git a/src/vcpkg/commands.portsdiff.cpp b/src/vcpkg/commands.portsdiff.cpp index d8fdd046fc..5eddf09d10 100644 --- a/src/vcpkg/commands.portsdiff.cpp +++ b/src/vcpkg/commands.portsdiff.cpp @@ -54,16 +54,15 @@ namespace paths.git_cmd_builder(dot_git_dir, temp_checkout_path).string_arg("reset"), settings), Tools::GIT) .value_or_exit(VCPKG_LINE_INFO); - const auto ports_at_commit = Paragraphs::load_overlay_ports(fs, temp_checkout_path / ports_dir_name); - fs.remove_all(temp_checkout_path, VCPKG_LINE_INFO); - - auto results = Util::fmap(ports_at_commit, [](const SourceControlFileAndLocation& scfl) { - return scfl.source_control_file->to_version_spec(); - }); - Util::sort(results, - [](const VersionSpec& lhs, const VersionSpec& rhs) { return lhs.port_name < rhs.port_name; }); - return results; + OverlayPortIndexEntry ports_at_commit_index(OverlayPortKind::Directory, temp_checkout_path / ports_dir_name); + std::map ports_at_commit; + ports_at_commit_index.try_load_all_ports(fs, ports_at_commit).value_or_exit(VCPKG_LINE_INFO); + fs.remove_all(temp_checkout_path, VCPKG_LINE_INFO); + return Util::fmap(ports_at_commit, + [](const std::pair& cache_entry) { + return cache_entry.second->source_control_file->to_version_spec(); + }); } void check_commit_exists(const VcpkgPaths& paths, StringView git_commit_id) diff --git a/src/vcpkg/commands.remove.cpp b/src/vcpkg/commands.remove.cpp index 1b6d43965e..ea54319828 100644 --- a/src/vcpkg/commands.remove.cpp +++ b/src/vcpkg/commands.remove.cpp @@ -68,7 +68,11 @@ namespace vcpkg } else { - msg::println_warning(msgFileNotFound, msg::path = target); + msg::println(Color::warning, + LocalizedString::from_raw(target) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgFileNotFound)); } } diff --git a/src/vcpkg/commands.set-installed.cpp b/src/vcpkg/commands.set-installed.cpp index 2a5e14b206..a694a8be45 100644 --- a/src/vcpkg/commands.set-installed.cpp +++ b/src/vcpkg/commands.set-installed.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -57,25 +58,27 @@ namespace vcpkg const auto github_run_id = args.github_run_id.get(); if (github_ref && github_sha && github_job && github_workflow && github_run_id) { - Json::Object detector; - detector.insert(JsonIdName, Json::Value::string("vcpkg")); - detector.insert(JsonIdUrl, Json::Value::string("https://github.com/microsoft/vcpkg")); - detector.insert(JsonIdVersion, Json::Value::string("1.0.0")); - - Json::Object job; - job.insert(JsonIdId, Json::Value::string(*github_run_id)); - job.insert(JsonIdCorrelator, Json::Value::string(fmt::format("{}-{}", *github_workflow, *github_run_id))); - Json::Object snapshot; - snapshot.insert(JsonIdJob, job); + { + Json::Object job; + job.insert(JsonIdId, Json::Value::string(*github_run_id)); + job.insert(JsonIdCorrelator, + Json::Value::string(fmt::format("{}-{}", *github_workflow, *github_run_id))); + snapshot.insert(JsonIdJob, std::move(job)); + } // destroy job + snapshot.insert(JsonIdVersion, Json::Value::integer(0)); snapshot.insert(JsonIdSha, Json::Value::string(*github_sha)); snapshot.insert(JsonIdRef, Json::Value::string(*github_ref)); snapshot.insert(JsonIdScanned, Json::Value::string(CTime::now_string())); - snapshot.insert(JsonIdDetector, detector); - Json::Object manifest; - manifest.insert(JsonIdName, FileVcpkgDotJson); + { + Json::Object detector; + detector.insert(JsonIdName, Json::Value::string("vcpkg")); + detector.insert(JsonIdUrl, Json::Value::string("https://github.com/microsoft/vcpkg")); + detector.insert(JsonIdVersion, Json::Value::string("1.0.0")); + snapshot.insert(JsonIdDetector, std::move(detector)); + } // destroy detector std::unordered_map map; for (auto&& action : action_plan.install_actions) @@ -86,42 +89,48 @@ namespace vcpkg return nullopt; } auto spec = action.spec.to_string(); - map.insert( - {spec, fmt::format("pkg:github/vcpkg/{}@{}", spec, scfl->source_control_file->to_version())}); + map.emplace(spec, fmt::format("pkg:github/vcpkg/{}@{}", spec, scfl->source_control_file->to_version())); } + Json::Object manifest; + manifest.insert(JsonIdName, FileVcpkgDotJson); + Json::Object resolved; for (auto&& action : action_plan.install_actions) { + const auto found = map.find(action.spec.to_string()); + if (found == map.end()) + { + continue; + } + + const auto& pkg_url = found->second; Json::Object resolved_item; - auto spec = action.spec.to_string(); - const auto found = map.find(spec); - if (found != map.end()) + resolved_item.insert(JsonIdPackageUnderscoreUrl, pkg_url); + resolved_item.insert(JsonIdRelationship, Json::Value::string(JsonIdDirect)); + + Json::Array deps_list; + for (auto&& dep : action.package_dependencies) { - const auto& pkg_url = found->second; - resolved_item.insert(JsonIdPackageUnderscoreUrl, pkg_url); - resolved_item.insert(JsonIdRelationship, Json::Value::string(JsonIdDirect)); - Json::Array deps_list; - for (auto&& dep : action.package_dependencies) + const auto found_dep = map.find(dep.to_string()); + if (found_dep != map.end()) { - const auto found_dep = map.find(dep.to_string()); - if (found_dep != map.end()) - { - deps_list.push_back(found_dep->second); - } + deps_list.push_back(found_dep->second); } - resolved_item.insert(JsonIdDependencies, deps_list); - resolved.insert(pkg_url, resolved_item); } + + resolved_item.insert(JsonIdDependencies, std::move(deps_list)); + resolved.insert(pkg_url, std::move(resolved_item)); } - manifest.insert(JsonIdResolved, resolved); + manifest.insert(JsonIdResolved, std::move(resolved)); Json::Object manifests; manifests.insert(JsonIdVcpkgDotJson, manifest); snapshot.insert(JsonIdManifests, manifests); Debug::print(Json::stringify(snapshot)); return snapshot; } + return nullopt; } @@ -204,12 +213,17 @@ namespace vcpkg if (paths.manifest_mode_enabled() && paths.get_feature_flags().dependency_graph) { msg::println(msgDependencyGraphCalculation); - auto snapshot = create_dependency_graph_snapshot(args, action_plan); - bool s = false; - if (snapshot.has_value() && args.github_token.has_value() && args.github_repository.has_value()) + auto maybe_snapshot = create_dependency_graph_snapshot(args, action_plan); + auto snapshot = maybe_snapshot.get(); + auto github_token = args.github_token.get(); + auto github_repository = args.github_repository.get(); + bool dependency_graph_success = false; + if (snapshot && github_token && github_repository) { - s = send_snapshot_to_api(*args.github_token.get(), *args.github_repository.get(), *snapshot.get()); - if (s) + WarningDiagnosticContext wdc{console_diagnostic_context}; + dependency_graph_success = submit_github_dependency_graph_snapshot( + wdc, args.github_server_url, *github_token, *github_repository, *snapshot); + if (dependency_graph_success) { msg::println(msgDependencyGraphSuccess); } @@ -218,7 +232,7 @@ namespace vcpkg msg::println(msgDependencyGraphFailure); } } - get_global_metrics_collector().track_bool(BoolMetric::DependencyGraphSuccess, s); + get_global_metrics_collector().track_bool(BoolMetric::DependencyGraphSuccess, dependency_graph_success); } // currently (or once) installed specifications @@ -245,9 +259,15 @@ namespace vcpkg track_install_plan(action_plan); install_preclear_packages(paths, action_plan); - auto binary_cache = build_options.only_downloads == OnlyDownloads::Yes - ? BinaryCache(paths.get_filesystem()) - : BinaryCache::make(args, paths, out_sink).value_or_exit(VCPKG_LINE_INFO); + BinaryCache binary_cache(fs); + if (build_options.only_downloads == OnlyDownloads::No) + { + if (!binary_cache.install_providers(args, paths, out_sink)) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + } + binary_cache.fetch(action_plan.install_actions); const auto summary = install_execute_plan(args, paths, @@ -264,6 +284,7 @@ namespace vcpkg summary.print_failed(); if (build_options.only_downloads == OnlyDownloads::No) { + binary_cache.wait_for_async_complete_and_join(); Checks::exit_fail(VCPKG_LINE_INFO); } } @@ -285,7 +306,20 @@ namespace vcpkg } } + const auto manifest = paths.get_manifest().get(); + const auto installed_paths = paths.maybe_installed().get(); + if (manifest && installed_paths) + { + // See docs/manifest-info.schema.json + Json::Object manifest_info; + manifest_info.insert("manifest-path", Json::Value::string(manifest->path)); + const auto json_file_path = installed_paths->vcpkg_dir() / FileManifestInfo; + const auto json_contents = Json::stringify(manifest_info); + fs.write_contents(json_file_path, json_contents, VCPKG_LINE_INFO); + } + summary.print_complete_message(); + binary_cache.wait_for_async_complete_and_join(); Checks::exit_success(VCPKG_LINE_INFO); } @@ -321,7 +355,6 @@ namespace vcpkg CleanBuildtrees::Yes, CleanPackages::Yes, CleanDownloads::No, - DownloadTool::Builtin, prohibit_backcompat_features, keep_going, }; diff --git a/src/vcpkg/commands.upgrade.cpp b/src/vcpkg/commands.upgrade.cpp index b12bc3f37f..e2ef0274b7 100644 --- a/src/vcpkg/commands.upgrade.cpp +++ b/src/vcpkg/commands.upgrade.cpp @@ -67,7 +67,6 @@ namespace vcpkg CleanBuildtrees::Yes, CleanPackages::Yes, CleanDownloads::No, - DownloadTool::Builtin, BackcompatFeatures::Allow, keep_going, }; @@ -203,7 +202,12 @@ namespace vcpkg var_provider.load_tag_vars(action_plan, host_triplet); - auto binary_cache = BinaryCache::make(args, paths, out_sink).value_or_exit(VCPKG_LINE_INFO); + BinaryCache binary_cache(fs); + if (!binary_cache.install_providers(args, paths, out_sink)) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + compute_all_abis(paths, action_plan, var_provider, status_db); binary_cache.fetch(action_plan.install_actions); const InstallSummary summary = install_execute_plan( @@ -217,6 +221,7 @@ namespace vcpkg } summary.print_complete_message(); + binary_cache.wait_for_async_complete_and_join(); Checks::exit_success(VCPKG_LINE_INFO); } } // namespace vcpkg diff --git a/src/vcpkg/commands.z-print-config.cpp b/src/vcpkg/commands.z-print-config.cpp index d5ad761209..9cbb7b9db7 100644 --- a/src/vcpkg/commands.z-print-config.cpp +++ b/src/vcpkg/commands.z-print-config.cpp @@ -48,7 +48,7 @@ namespace vcpkg obj.insert(JsonIdHostTriplet, host_triplet.canonical_name()); obj.insert(JsonIdVcpkgRoot, paths.root.native()); obj.insert(JsonIdTools, paths.tools.native()); - if (auto ci_env = args.detected_ci_environment().get()) + if (auto ci_env = args.detected_ci_environment_name().get()) { obj.insert(JsonIdDetectedCIEnvironment, *ci_env); } diff --git a/src/vcpkg/configuration.cpp b/src/vcpkg/configuration.cpp index 9aa32cd370..fa653eb2e2 100644 --- a/src/vcpkg/configuration.cpp +++ b/src/vcpkg/configuration.cpp @@ -99,7 +99,7 @@ namespace struct RegistryConfigDeserializer final : Json::IDeserializer { virtual LocalizedString type_name() const override { return msg::format(msgARegistry); } - virtual View valid_fields() const override; + virtual View valid_fields() const noexcept override; virtual Optional visit_null(Json::Reader&) const override; virtual Optional visit_object(Json::Reader&, const Json::Object&) const override; @@ -147,7 +147,7 @@ namespace struct RegistryDeserializer final : Json::IDeserializer { virtual LocalizedString type_name() const override { return msg::format(msgARegistry); } - virtual View valid_fields() const override; + virtual View valid_fields() const noexcept override; virtual Optional visit_object(Json::Reader&, const Json::Object&) const override; @@ -164,9 +164,9 @@ namespace const RegistriesArrayDeserializer RegistriesArrayDeserializer::instance; - View RegistryConfigDeserializer::valid_fields() const + View RegistryConfigDeserializer::valid_fields() const noexcept { - static constexpr StringView t[] = { + static constexpr StringLiteral t[] = { JsonIdKind, JsonIdBaseline, JsonIdPath, @@ -177,20 +177,20 @@ namespace }; return t; } - static constexpr StringView valid_builtin_fields[] = { + static constexpr StringLiteral valid_builtin_fields[] = { JsonIdKind, JsonIdBaseline, JsonIdPackages, }; - static constexpr StringView valid_filesystem_fields[] = { + static constexpr StringLiteral valid_filesystem_fields[] = { JsonIdKind, JsonIdBaseline, JsonIdPath, JsonIdPackages, }; - static constexpr StringView valid_git_fields[] = { + static constexpr StringLiteral valid_git_fields[] = { JsonIdKind, JsonIdBaseline, JsonIdRepository, @@ -198,7 +198,7 @@ namespace JsonIdPackages, }; - static constexpr StringView valid_artifact_fields[] = { + static constexpr StringLiteral valid_artifact_fields[] = { JsonIdKind, JsonIdName, JsonIdLocation, @@ -283,9 +283,9 @@ namespace return std::move(res); // gcc-7 bug workaround redundant move } - View RegistryDeserializer::valid_fields() const + View RegistryDeserializer::valid_fields() const noexcept { - static constexpr StringView t[] = { + static constexpr StringLiteral t[] = { JsonIdKind, JsonIdBaseline, JsonIdPath, @@ -454,10 +454,10 @@ namespace msg::format(msgConfigurationNestedDemands, msg::json_field = el.first)); } - auto maybe_demand = r.visit(*maybe_demand_obj, CeMetadataDeserializer::instance); - if (maybe_demand.has_value()) + auto maybe_demand = CeMetadataDeserializer::instance.visit(r, *maybe_demand_obj); + if (auto demand = maybe_demand.get()) { - ret.insert_or_replace(key, maybe_demand.value_or_exit(VCPKG_LINE_INFO)); + ret.insert_or_replace(key, *demand); } } return ret; @@ -569,10 +569,10 @@ namespace } Json::Object& ce_metadata_obj = ret.ce_metadata; - auto maybe_ce_metadata = r.visit(obj, CeMetadataDeserializer::instance); - if (maybe_ce_metadata.has_value()) + auto maybe_ce_metadata = CeMetadataDeserializer::instance.visit(r, obj); + if (auto ce_metadata = maybe_ce_metadata.get()) { - ce_metadata_obj = maybe_ce_metadata.value_or_exit(VCPKG_LINE_INFO); + ce_metadata_obj = *ce_metadata; } Json::Object demands_obj; @@ -828,7 +828,8 @@ namespace vcpkg return std::any_of(registries.begin(), registries.end(), registry_config_requests_ce); } - Json::IDeserializer& get_configuration_deserializer() { return ConfigurationDeserializer::instance; } + constexpr const Json::IDeserializer& configuration_deserializer = + ConfigurationDeserializer::instance; Optional parse_configuration(StringView contents, StringView origin, MessageSink& messageSink) { @@ -854,7 +855,7 @@ namespace vcpkg Optional parse_configuration(const Json::Object& obj, StringView origin, MessageSink& messageSink) { Json::Reader reader(origin); - auto maybe_configuration = reader.visit(obj, get_configuration_deserializer()); + auto maybe_configuration = ConfigurationDeserializer::instance.visit(reader, obj); bool has_warnings = !reader.warnings().empty(); bool has_errors = !reader.errors().empty(); if (has_warnings || has_errors) diff --git a/src/vcpkg/configure-environment.cpp b/src/vcpkg/configure-environment.cpp index f36a3d2e6f..97df6be9fc 100644 --- a/src/vcpkg/configure-environment.cpp +++ b/src/vcpkg/configure-environment.cpp @@ -105,25 +105,46 @@ namespace namespace vcpkg { - ExpectedL download_vcpkg_standalone_bundle(const DownloadManager& download_manager, - const Filesystem& fs, - const Path& download_root) + Optional download_vcpkg_standalone_bundle(DiagnosticContext& context, + const AssetCachingSettings& asset_cache_settings, + const Filesystem& fs, + const Path& download_root) { #if defined(VCPKG_STANDALONE_BUNDLE_SHA) const auto bundle_tarball = download_root / "vcpkg-standalone-bundle-" VCPKG_BASE_VERSION_AS_STRING ".tar.gz"; - msg::println(msgDownloadingVcpkgStandaloneBundle, msg::version = VCPKG_BASE_VERSION_AS_STRING); + context.statusln(msg::format(msgDownloadingVcpkgStandaloneBundle, msg::version = VCPKG_BASE_VERSION_AS_STRING)); const auto bundle_uri = "https://github.com/microsoft/vcpkg-tool/releases/download/" VCPKG_BASE_VERSION_AS_STRING "/vcpkg-standalone-bundle.tar.gz"; - download_manager.download_file( - fs, bundle_uri, {}, bundle_tarball, MACRO_TO_STRING(VCPKG_STANDALONE_BUNDLE_SHA), null_sink); + if (!download_file_asset_cached(context, + null_sink, + asset_cache_settings, + fs, + bundle_uri, + {}, + bundle_tarball, + MACRO_TO_STRING(VCPKG_STANDALONE_BUNDLE_SHA))) + { + return nullopt; + } #else // ^^^ VCPKG_STANDALONE_BUNDLE_SHA / !VCPKG_STANDALONE_BUNDLE_SHA vvv const auto bundle_tarball = download_root / "vcpkg-standalone-bundle-latest.tar.gz"; - msg::println(Color::warning, msgDownloadingVcpkgStandaloneBundleLatest); - fs.remove(bundle_tarball, VCPKG_LINE_INFO); + context.report(DiagnosticLine{DiagKind::Warning, msg::format(msgDownloadingVcpkgStandaloneBundleLatest)}); + std::error_code ec; + fs.remove(bundle_tarball, ec); + if (ec) + { + context.report_error(format_filesystem_call_error(ec, "remove", {bundle_tarball})); + return nullopt; + } + const auto bundle_uri = "https://github.com/microsoft/vcpkg-tool/releases/latest/download/vcpkg-standalone-bundle.tar.gz"; - download_manager.download_file(fs, bundle_uri, {}, bundle_tarball, nullopt, null_sink); + if (!download_file_asset_cached( + context, null_sink, asset_cache_settings, fs, bundle_uri, {}, bundle_tarball, nullopt)) + { + return nullopt; + } #endif // ^^^ !VCPKG_STANDALONE_BUNDLE_SHA return bundle_tarball; } @@ -159,11 +180,17 @@ namespace vcpkg fs.remove_all(vcpkg_artifacts_path, VCPKG_LINE_INFO); auto temp = get_exe_path_of_current_process(); temp.replace_filename("vcpkg-artifacts-temp"); - auto tarball = download_vcpkg_standalone_bundle(paths.get_download_manager(), fs, paths.downloads) - .value_or_exit(VCPKG_LINE_INFO); - set_directory_to_archive_contents(fs, paths.get_tool_cache(), null_sink, tarball, temp); + auto maybe_tarball = download_vcpkg_standalone_bundle( + console_diagnostic_context, paths.get_asset_cache_settings(), fs, paths.downloads); + auto tarball = maybe_tarball.get(); + if (!tarball) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + + set_directory_to_archive_contents(fs, paths.get_tool_cache(), null_sink, *tarball, temp); fs.rename_with_retry(temp / "vcpkg-artifacts", vcpkg_artifacts_path, VCPKG_LINE_INFO); - fs.remove(tarball, VCPKG_LINE_INFO); + fs.remove(*tarball, VCPKG_LINE_INFO); fs.remove_all(temp, VCPKG_LINE_INFO); #if defined(VCPKG_STANDALONE_BUNDLE_SHA) fs.write_contents(vcpkg_artifacts_version_path, VCPKG_BASE_VERSION_AS_STRING, VCPKG_LINE_INFO); diff --git a/src/vcpkg/dependencies.cpp b/src/vcpkg/dependencies.cpp index 0ef5e6d8d1..d83373b5ed 100644 --- a/src/vcpkg/dependencies.cpp +++ b/src/vcpkg/dependencies.cpp @@ -660,12 +660,8 @@ namespace vcpkg bool RemovePlan::has_non_user_requested() const { - constexpr struct - { - bool operator()(const RemovePlanAction& a) const { return a.request_type != RequestType::USER_REQUESTED; } - } non_user_requested; - - return Util::find_if(remove, non_user_requested) != remove.end(); + return Util::any_of(remove, + [](const RemovePlanAction& a) { return a.request_type != RequestType::USER_REQUESTED; }); } RemovePlan create_remove_plan(const std::vector& specs, const StatusParagraphs& status_db) @@ -1252,9 +1248,9 @@ namespace vcpkg std::vector excluded; const bool has_non_user_requested_packages = - Util::find_if(action_plan.install_actions, [](const InstallPlanAction& action) -> bool { + Util::any_of(action_plan.install_actions, [](const InstallPlanAction& action) -> bool { return action.request_type != RequestType::USER_REQUESTED; - }) != action_plan.install_actions.cend(); + }); for (auto&& already_installed_action : action_plan.already_installed) { diff --git a/src/vcpkg/export.prefab.cpp b/src/vcpkg/export.prefab.cpp index 64fe9998a7..32f58db1e9 100644 --- a/src/vcpkg/export.prefab.cpp +++ b/src/vcpkg/export.prefab.cpp @@ -615,17 +615,12 @@ namespace vcpkg::Prefab Debug::print( fmt::format("Exporting AAR and POM\n\tAAR path {}\n\tPOM path {}", exported_archive_path, pom_path)); - auto zip = ZipTool::make(paths.get_tool_cache(), out_sink).value_or_exit(VCPKG_LINE_INFO); - - auto compress_result = - zip.compress_directory_to_zip(paths.get_filesystem(), package_directory, exported_archive_path); - if (!compress_result) + ZipTool zip; + zip.setup(paths.get_tool_cache(), out_sink); + PrintingDiagnosticContext pdc{out_sink}; + if (!zip.compress_directory_to_zip(pdc, paths.get_filesystem(), package_directory, exported_archive_path)) { - Checks::msg_exit_with_message( - VCPKG_LINE_INFO, - std::move(compress_result) - .error() - .append(msgCompressFolderFailed, msg::path = package_directory.native())); + Checks::exit_fail(VCPKG_LINE_INFO); } std::string POM = R"( diff --git a/src/vcpkg/metrics.cpp b/src/vcpkg/metrics.cpp index e29e88f258..2dc6c00569 100644 --- a/src/vcpkg/metrics.cpp +++ b/src/vcpkg/metrics.cpp @@ -441,8 +441,8 @@ namespace vcpkg buildtime_times.push_back(Json::Value::number(buildtime.second)); } - properties.insert("buildnames_1", buildtime_names); - properties.insert("buildtimes", buildtime_times); + properties.insert("buildnames_1", std::move(buildtime_names)); + properties.insert("buildtimes", std::move(buildtime_times)); } Json::Object& measurements = base_data.insert("measurements", Json::Object()); diff --git a/src/vcpkg/packagespec.cpp b/src/vcpkg/packagespec.cpp index 53030973c0..753aba6052 100644 --- a/src/vcpkg/packagespec.cpp +++ b/src/vcpkg/packagespec.cpp @@ -172,7 +172,7 @@ namespace vcpkg AllowPlatformSpec allow_platform_spec) { // there is no origin because this function is used for user inputs - auto parser = ParserBase(input, nullopt); + auto parser = ParserBase(input, nullopt, {0, 0}); auto maybe_pqs = parse_qualified_specifier(parser, allow_features, parse_explicit_triplet, allow_platform_spec); if (!parser.at_eof()) { diff --git a/src/vcpkg/paragraphs.cpp b/src/vcpkg/paragraphs.cpp index e203799b16..bcd868544b 100644 --- a/src/vcpkg/paragraphs.cpp +++ b/src/vcpkg/paragraphs.cpp @@ -268,7 +268,7 @@ namespace vcpkg::Paragraphs } public: - PghParser(StringView text, StringView origin) : ParserBase(text, origin) { } + PghParser(StringView text, StringView origin) : ParserBase(text, origin, {1, 1}) { } ExpectedL> get_paragraphs() { @@ -362,12 +362,6 @@ namespace vcpkg::Paragraphs out_str.append(name.data(), name.size()).append(": ").append(field.data(), field.size()).push_back('\n'); } - bool is_port_directory(const ReadOnlyFilesystem& fs, const Path& maybe_directory) - { - return fs.exists(maybe_directory / "CONTROL", IgnoreErrors{}) || - fs.exists(maybe_directory / "vcpkg.json", IgnoreErrors{}); - } - ExpectedL> try_load_project_manifest_text(StringView text, StringView control_path, MessageSink& warning_sink) @@ -415,7 +409,7 @@ namespace vcpkg::Paragraphs std::string{}}; } - return PortLoadResult{try_load_port_manifest_text(manifest_contents, manifest_path, stdout_sink) + return PortLoadResult{try_load_port_manifest_text(manifest_contents, manifest_path, out_sink) .map([&](std::unique_ptr&& scf) { return SourceControlFileAndLocation{ std::move(scf), std::move(manifest_path), port_location.spdx_location}; @@ -588,41 +582,5 @@ namespace vcpkg::Paragraphs return std::move(results.paragraphs); } - LoadResults try_load_overlay_ports(const ReadOnlyFilesystem& fs, const Path& directory) - { - LoadResults ret; - - auto port_dirs = fs.get_directories_non_recursive(directory, VCPKG_LINE_INFO); - Util::sort(port_dirs); - - Util::erase_remove_if(port_dirs, - [&](auto&& port_dir_entry) { return port_dir_entry.filename() == FileDotDsStore; }); - - for (auto&& path : port_dirs) - { - auto port_name = path.filename(); - auto maybe_spgh = try_load_port_required(fs, port_name, PortLocation{path}).maybe_scfl; - if (const auto spgh = maybe_spgh.get()) - { - ret.paragraphs.push_back(std::move(*spgh)); - } - else - { - ret.errors.emplace_back(std::piecewise_construct, - std::forward_as_tuple(port_name.data(), port_name.size()), - std::forward_as_tuple(std::move(maybe_spgh).error())); - } - } - - return ret; - } - - std::vector load_overlay_ports(const ReadOnlyFilesystem& fs, const Path& directory) - { - auto results = try_load_overlay_ports(fs, directory); - load_results_print_error(results); - return std::move(results.paragraphs); - } - uint64_t get_load_ports_stats() { return g_load_ports_stats.load(); } } diff --git a/src/vcpkg/platform-expression.cpp b/src/vcpkg/platform-expression.cpp index 8441563c36..73c39d8128 100644 --- a/src/vcpkg/platform-expression.cpp +++ b/src/vcpkg/platform-expression.cpp @@ -119,7 +119,7 @@ namespace vcpkg::PlatformExpression struct ExpressionParser : ParserBase { ExpressionParser(StringView str, MultipleBinaryOperators multiple_binary_operators) - : ParserBase(str, "CONTROL"), multiple_binary_operators(multiple_binary_operators) + : ParserBase(str, "CONTROL", {0, 0}), multiple_binary_operators(multiple_binary_operators) { } diff --git a/src/vcpkg/portfileprovider.cpp b/src/vcpkg/portfileprovider.cpp index 8d9c904c20..7bcccbec91 100644 --- a/src/vcpkg/portfileprovider.cpp +++ b/src/vcpkg/portfileprovider.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -10,10 +11,309 @@ #include #include +#include +#include + using namespace vcpkg; namespace vcpkg { + OverlayPortIndexEntry::OverlayPortIndexEntry(OverlayPortKind kind, const Path& directory) + : m_kind(kind), m_directory(directory), m_loaded_ports() + { + if (m_kind == OverlayPortKind::Port) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + } + + OverlayPortIndexEntry::OverlayPortIndexEntry(OverlayPortIndexEntry&&) = default; + + OverlayPortKind OverlayPortIndexEntry::determine_kind(const ReadOnlyFilesystem& fs) + { + if (m_kind == OverlayPortKind::Unknown) + { + if (!m_loaded_ports.empty()) + { + Checks::unreachable(VCPKG_LINE_INFO, "OverlayPortKind::Unknown empty cache constraint violated"); + } + + auto maybe_scfl = Paragraphs::try_load_port(fs, PortLocation{m_directory}).maybe_scfl; + if (auto scfl = maybe_scfl.get()) + { + if (scfl->source_control_file) + { + // succeeded in loading it, so this must be a port + m_kind = OverlayPortKind::Port; + auto name_copy = scfl->to_name(); // copy name before moving maybe_scfl + m_loaded_ports.emplace(name_copy, std::move(maybe_scfl)); + } + else + { + // the directory didn't look like a port at all, consider it an overlay-port-dir + m_kind = OverlayPortKind::Directory; + } + } + else + { + // it looked like a port but we failed to load it for some reason + m_kind = OverlayPortKind::Port; + m_loaded_ports.emplace(std::string(), std::move(maybe_scfl)); + } + } + + return m_kind; + } + + const ExpectedL* OverlayPortIndexEntry::try_load_port_cached_port( + StringView port_name) + { + if (m_kind != OverlayPortKind::Port) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + const auto& this_overlay = *m_loaded_ports.begin(); + if (auto scfl = this_overlay.second.get()) + { + if (scfl->to_name() != port_name) + { + return nullptr; // this overlay-port is OK, but this isn't the right one + } + } + + return &this_overlay.second; + } + + OverlayPortIndexEntry::MapT::iterator OverlayPortIndexEntry::try_load_port_subdirectory_uncached( + MapT::iterator hint, const ReadOnlyFilesystem& fs, StringView port_name) + { + if (m_kind != OverlayPortKind::Directory) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + auto port_directory = m_directory / port_name; + auto load_result = Paragraphs::try_load_port(fs, PortLocation{port_directory}); + auto& maybe_scfl = load_result.maybe_scfl; + if (auto scfl = maybe_scfl.get()) + { + if (auto scf = scfl->source_control_file.get()) + { + const auto& actual_name = scf->to_name(); + if (actual_name != port_name) + { + maybe_scfl = + LocalizedString::from_raw(scfl->control_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgMismatchedNames, msg::package_name = port_name, msg::actual = actual_name); + } + } + else + { + return m_loaded_ports.end(); + } + } + + return m_loaded_ports.emplace_hint(hint, port_name.to_string(), std::move(maybe_scfl)); + } + + const ExpectedL* OverlayPortIndexEntry::try_load_port_subdirectory_with_cache( + const ReadOnlyFilesystem& fs, StringView port_name) + { + if (m_kind != OverlayPortKind::Directory) + { + Checks::unreachable(VCPKG_LINE_INFO); + } + + auto already_loaded = m_loaded_ports.lower_bound(port_name); + if (already_loaded == m_loaded_ports.end() || already_loaded->first != port_name) + { + already_loaded = try_load_port_subdirectory_uncached(already_loaded, fs, port_name); + } + + if (already_loaded == m_loaded_ports.end()) + { + return nullptr; + } + + return &already_loaded->second; + } + + const ExpectedL* OverlayPortIndexEntry::try_load_port(const ReadOnlyFilesystem& fs, + StringView port_name) + { + switch (determine_kind(fs)) + { + case OverlayPortKind::Port: return try_load_port_cached_port(port_name); + case OverlayPortKind::Directory: return try_load_port_subdirectory_with_cache(fs, port_name); + case OverlayPortKind::Unknown: + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + ExpectedL OverlayPortIndexEntry::try_load_all_ports( + const ReadOnlyFilesystem& fs, std::map& out) + { + switch (determine_kind(fs)) + { + case OverlayPortKind::Port: + { + auto& maybe_this_port = *m_loaded_ports.begin(); + if (auto this_port = maybe_this_port.second.get()) + { + auto already_in_out = out.lower_bound(maybe_this_port.first); + if (already_in_out == out.end() || already_in_out->first != maybe_this_port.first) + { + out.emplace_hint(already_in_out, maybe_this_port.first, this_port); + } + + return Unit{}; + } + + return maybe_this_port.second.error(); + } + case OverlayPortKind::Directory: + { + auto maybe_subdirectories = fs.try_get_directories_non_recursive(m_directory); + if (auto subdirectories = maybe_subdirectories.get()) + { + std::vector errors; + Util::sort(*subdirectories); + auto first_loaded = m_loaded_ports.begin(); + const auto last_loaded = m_loaded_ports.end(); + auto first_out = out.begin(); + const auto last_out = out.end(); + for (const auto& full_subdirectory : *subdirectories) + { + auto subdirectory = full_subdirectory.filename(); + while (first_out != last_out && first_out->first < subdirectory) + { + ++first_out; + } + + if (first_out != last_out && first_out->first == subdirectory) + { + // this subdirectory is already in the output; we shouldn't replace or attempt to load it + ++first_out; + continue; + } + + while (first_loaded != last_loaded && first_loaded->first < subdirectory) + { + ++first_loaded; + } + + if (first_loaded == last_loaded || first_loaded->first != subdirectory) + { + // the subdirectory isn't cached, load it into the cache + first_loaded = try_load_port_subdirectory_uncached(first_loaded, fs, subdirectory); + } // else: the subdirectory is already loaded + + if (auto this_port = first_loaded->second.get()) + { + first_out = out.emplace_hint(first_out, first_loaded->first, this_port); + ++first_out; + } + else + { + errors.push_back(first_loaded->second.error()); + } + + ++first_loaded; + } + + if (errors.empty()) + { + return Unit{}; + } + + return LocalizedString::from_raw(Strings::join("\n", errors)); + } + + return maybe_subdirectories.error(); + } + case OverlayPortKind::Unknown: + default: Checks::unreachable(VCPKG_LINE_INFO); + } + } + + void OverlayPortIndexEntry::check_directory(const ReadOnlyFilesystem& fs) const + { + Debug::println("Using overlay: ", m_directory); + + Checks::msg_check_exit(VCPKG_LINE_INFO, + vcpkg::is_directory(fs.status(m_directory, VCPKG_LINE_INFO)), + msgOverlayPatchDir, + msg::path = m_directory); + } + + struct OverlayPortIndex + { + OverlayPortIndex() = delete; + OverlayPortIndex(const OverlayPortIndex&) = delete; + OverlayPortIndex(OverlayPortIndex&&) = default; + + OverlayPortIndex(const OverlayPortPaths& paths) + { + for (auto&& overlay_port : paths.overlay_ports) + { + m_entries.emplace_back(OverlayPortKind::Unknown, overlay_port); + } + + if (auto builtin_overlay_port_dir = paths.builtin_overlay_port_dir.get()) + { + m_entries.emplace_back(OverlayPortKind::Directory, *builtin_overlay_port_dir); + } + } + + const ExpectedL* try_load_port(const ReadOnlyFilesystem& fs, StringView port_name) + { + for (auto&& entry : m_entries) + { + auto result = entry.try_load_port(fs, port_name); + if (result) + { + return result; + } + } + + return nullptr; + } + + ExpectedL try_load_all_ports(const ReadOnlyFilesystem& fs, + std::map& out) + { + for (auto&& entry : m_entries) + { + auto result = entry.try_load_all_ports(fs, out); + if (!result) + { + return result; + } + } + + return Unit{}; + } + + void check_directories(const ReadOnlyFilesystem& fs) + { + for (auto&& overlay : m_entries) + { + overlay.check_directory(fs); + } + } + + private: + std::vector m_entries; + }; + + bool OverlayPortPaths::empty() const noexcept + { + return !builtin_overlay_port_dir.has_value() && overlay_ports.empty(); + } + MapPortFileProvider::MapPortFileProvider(const std::unordered_map& map) : ports(map) { @@ -131,14 +431,6 @@ namespace vcpkg return entry_it->second; } - virtual View get_port_versions(StringView port_name) const override - { - return entry(port_name) - .value_or_exit(VCPKG_LINE_INFO) - ->get_port_versions() - .value_or_exit(VCPKG_LINE_INFO); - } - ExpectedL load_control_file(const VersionSpec& version_spec) const { const auto& maybe_ent = entry(version_spec.port_name); @@ -211,158 +503,40 @@ namespace vcpkg struct OverlayProviderImpl : IFullOverlayProvider { - OverlayProviderImpl(const ReadOnlyFilesystem& fs, View overlay_ports) - : m_fs(fs), m_overlay_ports(overlay_ports.begin(), overlay_ports.end()) + OverlayProviderImpl(const ReadOnlyFilesystem& fs, const OverlayPortPaths& overlay_port_paths) + : m_fs(fs), m_overlay_index(overlay_port_paths) { - for (auto&& overlay : m_overlay_ports) - { - Debug::println("Using overlay: ", overlay); - - Checks::msg_check_exit(VCPKG_LINE_INFO, - vcpkg::is_directory(m_fs.status(overlay, VCPKG_LINE_INFO)), - msgOverlayPatchDir, - msg::path = overlay); - } + m_overlay_index.check_directories(m_fs); } OverlayProviderImpl(const OverlayProviderImpl&) = delete; OverlayProviderImpl& operator=(const OverlayProviderImpl&) = delete; - - Optional load_port(StringView port_name) const - { - auto s_port_name = port_name.to_string(); - - for (auto&& ports_dir : m_overlay_ports) - { - // Try loading individual port - if (Paragraphs::is_port_directory(m_fs, ports_dir)) - { - auto maybe_scfl = - Paragraphs::try_load_port_required(m_fs, port_name, PortLocation{ports_dir}).maybe_scfl; - if (auto scfl = maybe_scfl.get()) - { - if (scfl->to_name() == port_name) - { - return std::move(*scfl); - } - } - else - { - print_error_message(maybe_scfl.error()); - msg::println(); - Checks::exit_maybe_upgrade(VCPKG_LINE_INFO); - } - - continue; - } - - auto ports_spec = ports_dir / port_name; - if (Paragraphs::is_port_directory(m_fs, ports_spec)) - { - auto found_scfl = - Paragraphs::try_load_port_required(m_fs, port_name, PortLocation{ports_spec}).maybe_scfl; - if (auto scfl = found_scfl.get()) - { - auto& scfl_name = scfl->to_name(); - if (scfl_name == port_name) - { - return std::move(*scfl); - } - - Checks::msg_exit_maybe_upgrade(VCPKG_LINE_INFO, - LocalizedString::from_raw(ports_spec) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgMismatchedNames, - msg::package_name = port_name, - msg::actual = scfl_name)); - } - else - { - print_error_message(found_scfl.error()); - msg::println(); - Checks::exit_maybe_upgrade(VCPKG_LINE_INFO); - } - } - } - return nullopt; - } - virtual Optional get_control_file(StringView port_name) const override { - auto it = m_overlay_cache.find(port_name); - if (it == m_overlay_cache.end()) + auto loaded = m_overlay_index.try_load_port(m_fs, port_name); + if (loaded) { - it = m_overlay_cache.emplace(port_name.to_string(), load_port(port_name)).first; + return loaded->value_or_exit(VCPKG_LINE_INFO); } - return it->second; + + return nullopt; } virtual void load_all_control_files( std::map& out) const override { - auto first = std::make_reverse_iterator(m_overlay_ports.end()); - const auto last = std::make_reverse_iterator(m_overlay_ports.begin()); - for (; first != last; ++first) - { - auto&& ports_dir = *first; - // Try loading individual port - if (Paragraphs::is_port_directory(m_fs, ports_dir)) - { - auto maybe_scfl = - Paragraphs::try_load_port_required(m_fs, ports_dir.filename(), PortLocation{ports_dir}) - .maybe_scfl; - if (auto scfl = maybe_scfl.get()) - { - // copy name before moving *scfl - auto name = scfl->to_name(); - auto it = m_overlay_cache.emplace(std::move(name), std::move(*scfl)).first; - Checks::check_exit(VCPKG_LINE_INFO, it->second.get()); - out.emplace(it->first, it->second.get()); - } - else - { - print_error_message(maybe_scfl.error()); - msg::println(); - Checks::exit_maybe_upgrade(VCPKG_LINE_INFO); - } - - continue; - } - - // Try loading all ports inside ports_dir - auto results = Paragraphs::try_load_overlay_ports(m_fs, ports_dir); - if (!results.errors.empty()) - { - print_error_message(LocalizedString::from_raw(Strings::join( - "\n", - results.errors, - [](const std::pair& err) -> const LocalizedString& { - return err.second; - }))); - Checks::exit_maybe_upgrade(VCPKG_LINE_INFO); - } - - for (auto&& scfl : results.paragraphs) - { - auto name = scfl.to_name(); - auto it = m_overlay_cache.emplace(std::move(name), std::move(scfl)).first; - Checks::check_exit(VCPKG_LINE_INFO, it->second.get()); - out.emplace(it->first, it->second.get()); - } - } + m_overlay_index.try_load_all_ports(m_fs, out).value_or_exit(VCPKG_LINE_INFO); } private: const ReadOnlyFilesystem& m_fs; - const std::vector m_overlay_ports; - mutable std::map, std::less<>> m_overlay_cache; + mutable OverlayPortIndex m_overlay_index; }; struct ManifestProviderImpl : IFullOverlayProvider { ManifestProviderImpl(const ReadOnlyFilesystem& fs, - View overlay_ports, + const OverlayPortPaths& overlay_ports, const Path& manifest_path, std::unique_ptr&& manifest_scf) : m_overlay_ports{fs, overlay_ports} @@ -404,13 +578,14 @@ namespace vcpkg return std::make_unique(registry_set); } - std::unique_ptr make_overlay_provider(const ReadOnlyFilesystem& fs, View overlay_ports) + std::unique_ptr make_overlay_provider(const ReadOnlyFilesystem& fs, + const OverlayPortPaths& overlay_ports) { return std::make_unique(fs, overlay_ports); } std::unique_ptr make_manifest_provider(const ReadOnlyFilesystem& fs, - View overlay_ports, + const OverlayPortPaths& overlay_ports, const Path& manifest_path, std::unique_ptr&& manifest_scf) { diff --git a/src/vcpkg/postbuildlint.cpp b/src/vcpkg/postbuildlint.cpp index a11e6131e7..a7b2405729 100644 --- a/src/vcpkg/postbuildlint.cpp +++ b/src/vcpkg/postbuildlint.cpp @@ -42,21 +42,16 @@ namespace vcpkg const Path& relative_dir, const std::vector& relative_paths) { - auto ls = LocalizedString() - .append_raw('\n') - .append_raw(relative_dir) - .append_raw(": ") - .append_raw(NotePrefix) - .append(kind_prefix) - .append_raw('\n'); + auto ls = + LocalizedString().append_raw(relative_dir).append_raw(": ").append_raw(NotePrefix).append(kind_prefix); for (const Path& package_relative_path : relative_paths) { auto as_generic = package_relative_path; as_generic.make_generic(); - ls.append_raw(NotePrefix).append_raw(as_generic).append_raw('\n'); + ls.append_raw('\n').append_raw(NotePrefix).append_raw(as_generic); } - msg_sink.print(ls); + msg_sink.println(ls); } // clang-format off @@ -113,12 +108,11 @@ namespace vcpkg const auto include_dir = package_dir / "include"; if (!fs.exists(include_dir, IgnoreErrors{}) || fs.is_empty(include_dir, IgnoreErrors{})) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugMissingIncludeDir) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugMissingIncludeDir)); return LintStatus::PROBLEM_DETECTED; } @@ -134,12 +128,11 @@ namespace vcpkg const auto include_dir = package_dir / "include"; if (fs.exists(include_dir, IgnoreErrors{})) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugIncludeDirInCMakeHelperPort) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugIncludeDirInCMakeHelperPort)); return LintStatus::PROBLEM_DETECTED; } @@ -228,20 +221,18 @@ namespace vcpkg if (!violations.empty()) { Util::sort(violations); - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugRestrictedHeaderPaths) - .append_raw('\n')); - msg_sink.print(LocalizedString::from_raw(include_dir) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgPortBugRestrictedHeaderPathsNote) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugRestrictedHeaderPaths)); + msg_sink.println(LocalizedString::from_raw(include_dir) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgPortBugRestrictedHeaderPathsNote)); for (auto&& violation : violations) { - msg_sink.print(LocalizedString::from_raw(NotePrefix).append_raw(violation).append_raw('\n')); + msg_sink.println(LocalizedString::from_raw(NotePrefix).append_raw(violation)); } return LintStatus::PROBLEM_DETECTED; @@ -263,14 +254,12 @@ namespace vcpkg if (!files_found.empty()) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugDuplicateIncludeFiles) - .append_raw('\n')); - msg_sink.print( - LocalizedString::from_raw(NotePrefix).append(msgPortBugDuplicateIncludeFilesFixIt).append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugDuplicateIncludeFiles)); + msg_sink.println(LocalizedString::from_raw(NotePrefix).append(msgPortBugDuplicateIncludeFilesFixIt)); return LintStatus::PROBLEM_DETECTED; } @@ -285,12 +274,11 @@ namespace vcpkg const auto debug_share = package_dir / FileDebug / FileShare; if (fs.exists(debug_share, IgnoreErrors{})) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugDebugShareDir) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugDebugShareDir)); return LintStatus::PROBLEM_DETECTED; } @@ -305,12 +293,11 @@ namespace vcpkg { if (!fs.exists(package_dir / FileShare / package_name / FileVcpkgPortConfig, IgnoreErrors{})) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugMissingCMakeHelperPortFile) - .append_raw("\n")); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugMissingCMakeHelperPortFile)); return LintStatus::PROBLEM_DETECTED; } @@ -332,23 +319,21 @@ namespace vcpkg if (fs.is_regular_file(usage_path_from) && !fs.is_regular_file(usage_path_to)) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugMissingProvidedUsage) - .append_raw('\n')); - msg_sink.print(LocalizedString::from_raw(usage_path_from) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgUsageTextHere) - .append_raw('\n') - .append_raw(NotePrefix) - .append(msgUsageInstallInstructions) - .append_raw('\n') - .append_raw(NotePrefix) - .append_raw(STANDARD_INSTALL_USAGE) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugMissingProvidedUsage)); + msg_sink.println(LocalizedString::from_raw(usage_path_from) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgUsageTextHere) + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgUsageInstallInstructions) + .append_raw('\n') + .append_raw(NotePrefix) + .append_raw(STANDARD_INSTALL_USAGE)); return LintStatus::PROBLEM_DETECTED; } @@ -382,11 +367,11 @@ namespace vcpkg if (!misplaced_cmake_files.empty()) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugMisplacedCMakeFiles)); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugMisplacedCMakeFiles)); print_relative_paths( msg_sink, msgFilesRelativeToThePackageDirectoryHere, package_dir, misplaced_cmake_files); return LintStatus::PROBLEM_DETECTED; @@ -404,12 +389,11 @@ namespace vcpkg fs.exists(package_dir / "debug" VCPKG_PREFERRED_SEPARATOR "lib" VCPKG_PREFERRED_SEPARATOR "cmake", IgnoreErrors{})) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugMergeLibCMakeDir) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugMergeLibCMakeDir)); return LintStatus::PROBLEM_DETECTED; } @@ -448,11 +432,11 @@ namespace vcpkg if (!bad_dlls.empty()) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugDllInLibDir)); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugDllInLibDir)); print_relative_paths(msg_sink, msgDllsRelativeToThePackageDirectoryHere, package_dir, bad_dlls); return LintStatus::PROBLEM_DETECTED; } @@ -474,22 +458,20 @@ namespace vcpkg { case FileType::regular: return LintStatus::SUCCESS; break; case FileType::directory: - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgCopyrightIsDir) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgCopyrightIsDir)); return LintStatus::PROBLEM_DETECTED; default: break; } - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugMissingLicense) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugMissingLicense)); // We only search in the root of each unpacked source archive to reduce false positives auto src_relative_dirs = Util::fmap(fs.get_directories_non_recursive(build_dir / "src", IgnoreErrors{}), @@ -512,14 +494,13 @@ namespace vcpkg auto args = Util::fmap(src_dir_relative_copyright_files, [](StringLiteral copyright_file) { return fmt::format(FMT_COMPILE("\"${{SOURCE_PATH}}/{}\""), copyright_file); }); - msg_sink.print( + msg_sink.println( LocalizedString::from_raw(portfile_cmake) .append_raw(": ") .append_raw(NotePrefix) .append(msgPortBugMissingLicenseFixIt, msg::value = fmt::format(FMT_COMPILE("vcpkg_install_copyright(FILE_LIST {})"), - fmt::join(args, " "))) - .append_raw('\n')); + fmt::join(args, " ")))); } return LintStatus::PROBLEM_DETECTED; @@ -542,10 +523,10 @@ namespace vcpkg if (!build_dir_relative_copyright_files.empty()) { - msg_sink.print(LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgPortBugFoundCopyrightFiles)); + msg_sink.println(LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgPortBugFoundCopyrightFiles)); print_relative_paths( msg_sink, msgFilesRelativeToTheBuildDirectoryHere, build_dir, build_dir_relative_copyright_files); } @@ -570,11 +551,11 @@ namespace vcpkg if (!exes.empty()) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugFoundExeInBinDir)); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugFoundExeInBinDir)); print_relative_paths(msg_sink, msgExecutablesRelativeToThePackageDirectoryHere, package_dir, exes); return LintStatus::PROBLEM_DETECTED; @@ -662,11 +643,11 @@ namespace vcpkg if (!dlls_with_no_exports.empty()) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugSetDllsWithoutExports)); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugSetDllsWithoutExports)); print_relative_paths(msg_sink, msgDllsRelativeToThePackageDirectoryHere, package_dir, dlls_with_no_exports); return LintStatus::PROBLEM_DETECTED; } @@ -696,11 +677,11 @@ namespace vcpkg if (!dlls_with_improper_uwp_bit.empty()) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugDllAppContainerBitNotSet)); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugDllAppContainerBitNotSet)); print_relative_paths( msg_sink, msgDllsRelativeToThePackageDirectoryHere, package_dir, dlls_with_improper_uwp_bit); return LintStatus::PROBLEM_DETECTED; @@ -759,28 +740,26 @@ namespace vcpkg std::vector binaries_with_invalid_architecture, MessageSink& msg_sink) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgBuiltWithIncorrectArchitecture, msg::arch = expected_architecture) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgBuiltWithIncorrectArchitecture, msg::arch = expected_architecture)); auto msg = LocalizedString::from_raw(package_dir) .append_raw(": ") .append_raw(NotePrefix) - .append(msgBinariesRelativeToThePackageDirectoryHere) - .append_raw('\n'); + .append(msgBinariesRelativeToThePackageDirectoryHere); for (const FileAndArch& b : binaries_with_invalid_architecture) { - msg.append_raw(NotePrefix) + msg.append_raw('\n') + .append_raw(NotePrefix) .append(msgBinaryWithInvalidArchitecture, msg::path = b.relative_file.generic_u8string(), - msg::arch = b.actual_arch) - .append_raw('\n'); + msg::arch = b.actual_arch); } - msg_sink.print(msg); + msg_sink.println(msg); } static void check_dll_architecture(const std::string& expected_architecture, @@ -879,11 +858,11 @@ namespace vcpkg return LintStatus::SUCCESS; } - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugFoundDllInStaticBuild)); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugFoundDllInStaticBuild)); print_relative_paths(msg_sink, msgDllsRelativeToThePackageDirectoryHere, package_dir, relative_dlls); return LintStatus::PROBLEM_DETECTED; } @@ -906,7 +885,7 @@ namespace vcpkg { auto as_generic = binary; as_generic.make_generic(); - ls.append_raw(NotePrefix).append_raw(as_generic).append_raw('\n'); + ls.append_raw('\n').append_raw(NotePrefix).append_raw(as_generic); } } } @@ -924,38 +903,36 @@ namespace vcpkg return LintStatus::SUCCESS; } - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugMismatchingNumberOfBinaries) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugMismatchingNumberOfBinaries)); LocalizedString ls = LocalizedString::from_raw(package_dir) .append_raw(": ") .append_raw(NotePrefix) - .append(msgBinariesRelativeToThePackageDirectoryHere) - .append_raw('\n'); + .append(msgBinariesRelativeToThePackageDirectoryHere); if (debug_count == 0) { - ls.append_raw(NotePrefix).append(msgPortBugMissingDebugBinaries).append_raw('\n'); + ls.append_raw('\n').append_raw(NotePrefix).append(msgPortBugMissingDebugBinaries); } else { - ls.append_raw(NotePrefix).append(msgPortBugFoundDebugBinaries).append_raw('\n'); + ls.append_raw('\n').append_raw(NotePrefix).append(msgPortBugFoundDebugBinaries); append_binary_set(ls, relative_debug_binary_sets); } if (release_count == 0) { - ls.append_raw(NotePrefix).append(msgPortBugMissingReleaseBinaries).append_raw('\n'); + ls.append_raw('\n').append_raw(NotePrefix).append(msgPortBugMissingReleaseBinaries); } else { - ls.append_raw(NotePrefix).append(msgPortBugFoundReleaseBinaries).append_raw('\n'); + ls.append_raw('\n').append_raw(NotePrefix).append(msgPortBugFoundReleaseBinaries); append_binary_set(ls, relative_release_binary_sets); } - msg_sink.print(ls); + msg_sink.println(ls); return LintStatus::PROBLEM_DETECTED; } @@ -966,11 +943,10 @@ namespace vcpkg { if (lib_count == 0 && dll_count != 0) { - msg_sink.print(LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugMissingImportedLibs) - .append_raw('\n')); + msg_sink.println(LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugMissingImportedLibs)); return LintStatus::PROBLEM_DETECTED; } @@ -998,24 +974,23 @@ namespace vcpkg for (auto&& bad_dir : bad_dirs) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugBinDirExists, msg::path = bad_dir) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugBinDirExists, msg::path = bad_dir)); } auto args = Util::fmap(bad_dirs, [](const Path& bad_dir) { return fmt::format(FMT_COMPILE("\"${{CURRENT_PACKAGES_DIR}}/{}\""), bad_dir); }); - msg_sink.print( + msg_sink.println( LocalizedString::from_raw(NotePrefix) .append(msgPortBugRemoveBinDir) .append_raw('\n') .append_raw("if(VCPKG_LIBRARY_LINKAGE STREQUAL \"static\")\n") .append_indent() - .append_raw(fmt::format(FMT_COMPILE("file(REMOVE_RECURSE {})\nendif()\n"), fmt::join(args, " ")))); + .append_raw(fmt::format(FMT_COMPILE("file(REMOVE_RECURSE {})\nendif()"), fmt::join(args, " ")))); return bad_dirs.size(); } @@ -1031,24 +1006,23 @@ namespace vcpkg if (!relative_empty_directories.empty()) { Util::sort(relative_empty_directories); - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugFoundEmptyDirectories) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugFoundEmptyDirectories)); auto args = Util::fmap(relative_empty_directories, [](const Path& empty_dir) { return fmt::format(FMT_COMPILE("\"${{CURRENT_PACKAGES_DIR}}/{}\""), empty_dir.generic_u8string()); }); - msg_sink.print( + msg_sink.println( LocalizedString::from_raw(package_dir) .append_raw(": ") .append_raw(NotePrefix) .append(msgDirectoriesRelativeToThePackageDirectoryHere) .append_raw('\n') .append_raw(NotePrefix) - .append_raw(fmt::format(FMT_COMPILE("file(REMOVE_RECURSE {})\n"), fmt::join(args, " ")))); + .append_raw(fmt::format(FMT_COMPILE("file(REMOVE_RECURSE {})"), fmt::join(args, " ")))); return LintStatus::PROBLEM_DETECTED; } @@ -1126,18 +1100,18 @@ namespace vcpkg if (!misplaced_pkgconfig_files.empty()) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugMisplacedPkgConfigFiles)); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugMisplacedPkgConfigFiles)); print_relative_paths(msg_sink, msgFilesRelativeToThePackageDirectoryHere, package_dir, Util::fmap(misplaced_pkgconfig_files, [](const MisplacedFile& mf) -> Path { return mf.relative_path; })); - msg_sink.print(LocalizedString::from_raw(NotePrefix).append(msgPortBugMovePkgConfigFiles).append_raw('\n')); + msg_sink.println(LocalizedString::from_raw(NotePrefix).append(msgPortBugMovePkgConfigFiles)); { auto create_directory_line = LocalizedString::from_raw("file(MAKE_DIRECTORY"); std::vector directories; @@ -1162,8 +1136,8 @@ namespace vcpkg fmt::format(FMT_COMPILE(R"###( "${{CURRENT_PACKAGES_DIR}}/{}")###"), directory)); } - create_directory_line.append_raw(")\n"); - msg_sink.print(create_directory_line); + create_directory_line.append_raw(")"); + msg_sink.println(create_directory_line); } // destroy create_directory_line for (const auto& item : misplaced_pkgconfig_files) @@ -1177,15 +1151,15 @@ namespace vcpkg default: Checks::unreachable(VCPKG_LINE_INFO); } - msg_sink.print(LocalizedString::from_raw(fmt::format( - FMT_COMPILE(R"###(file(RENAME "${{CURRENT_PACKAGES_DIR}}/{}" "${{CURRENT_PACKAGES_DIR}}/{}/{}"))###" - "\n"), + msg_sink.println(LocalizedString::from_raw(fmt::format( + FMT_COMPILE( + R"###(file(RENAME "${{CURRENT_PACKAGES_DIR}}/{}" "${{CURRENT_PACKAGES_DIR}}/{}/{}"))###"), item.relative_path.generic_u8string(), *dir, item.relative_path.filename()))); } - msg_sink.print(LocalizedString::from_raw("vcpkg_fixup_pkgconfig()\n")); + msg_sink.println(LocalizedString::from_raw("vcpkg_fixup_pkgconfig()")); msg_sink.println(msgPortBugRemoveEmptyDirs); return LintStatus::PROBLEM_DETECTED; @@ -1327,32 +1301,28 @@ namespace vcpkg return LintStatus::SUCCESS; } - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugInvalidCrtLinkageHeader) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugInvalidCrtLinkageHeader)); - msg_sink.print(LocalizedString::from_raw(package_dir) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgBinariesRelativeToThePackageDirectoryHere) - .append_raw('\n')); + msg_sink.println(LocalizedString::from_raw(package_dir) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgBinariesRelativeToThePackageDirectoryHere)); for (auto&& group : groups_of_invalid_crt) { - msg_sink.print(LocalizedString::from_raw(NotePrefix) - .append(msgPortBugInvalidCrtLinkageCrtGroup, msg::expected = to_string(group.first)) - .append_raw('\n')); + msg_sink.println(LocalizedString::from_raw(NotePrefix) + .append(msgPortBugInvalidCrtLinkageCrtGroup, msg::expected = to_string(group.first))); for (auto&& file : group.second) { for (auto&& linkage : file.linkages) { - msg_sink.print(LocalizedString::from_raw(NotePrefix) - .append(msgPortBugInvalidCrtLinkageEntry, - msg::path = file.relative_file.generic_u8string(), - msg::actual = to_string(linkage)) - .append_raw('\n')); + msg_sink.println(LocalizedString::from_raw(NotePrefix) + .append(msgPortBugInvalidCrtLinkageEntry, + msg::path = file.relative_file.generic_u8string(), + msg::actual = to_string(linkage))); } } } @@ -1390,11 +1360,11 @@ namespace vcpkg if (!dlls_with_outdated_crt.empty()) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugOutdatedCRT)); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugOutdatedCRT)); print_relative_paths( msg_sink, @@ -1437,11 +1407,11 @@ namespace vcpkg return LintStatus::SUCCESS; } - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugKernel32FromXbox)); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugKernel32FromXbox)); print_relative_paths( msg_sink, msgDllsRelativeToThePackageDirectoryHere, @@ -1487,11 +1457,11 @@ namespace vcpkg if (!misplaced_files.empty()) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgPortBugMisplacedFiles)); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgPortBugMisplacedFiles)); print_relative_paths(msg_sink, msgFilesRelativeToThePackageDirectoryHere, package_dir, misplaced_files); return LintStatus::PROBLEM_DETECTED; } @@ -1586,34 +1556,31 @@ namespace vcpkg } Util::sort(failing_files); - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgFilesContainAbsolutePath1) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgFilesContainAbsolutePath1)); for (auto&& absolute_path : prohibited_absolute_paths) { - msg_sink.print(LocalizedString::from_raw(NotePrefix).append_raw(absolute_path).append_raw('\n')); + msg_sink.println(LocalizedString::from_raw(NotePrefix).append_raw(absolute_path)); } if (any_pc_file_fails) { - msg_sink.print(LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgFilesContainAbsolutePathPkgconfigNote) - .append_raw('\n')); + msg_sink.println(LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgFilesContainAbsolutePathPkgconfigNote)); } for (auto&& failing_file : failing_files) { failing_file.make_preferred(); - msg_sink.print(LocalizedString::from_raw(package_dir / failing_file) - .append_raw(": ") - .append_raw(NotePrefix) - .append(msgFilesContainAbsolutePath2) - .append_raw('\n')); + msg_sink.println(LocalizedString::from_raw(package_dir / failing_file) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgFilesContainAbsolutePath2)); } return LintStatus::PROBLEM_DETECTED; @@ -1937,12 +1904,11 @@ namespace vcpkg spec, paths, pre_build_info, build_info, port_dir, portfile_cmake, msg_sink); if (error_count != 0) { - msg_sink.print(Color::warning, - LocalizedString::from_raw(portfile_cmake) - .append_raw(": ") - .append_raw(WarningPrefix) - .append(msgFailedPostBuildChecks, msg::count = error_count) - .append_raw('\n')); + msg_sink.println(Color::warning, + LocalizedString::from_raw(portfile_cmake) + .append_raw(": ") + .append_raw(WarningPrefix) + .append(msgFailedPostBuildChecks, msg::count = error_count)); } return error_count; diff --git a/src/vcpkg/registries.cpp b/src/vcpkg/registries.cpp index c77c0f75dc..b67bd65e73 100644 --- a/src/vcpkg/registries.cpp +++ b/src/vcpkg/registries.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -41,203 +41,13 @@ namespace static const RegistryPathStringDeserializer instance; }; - const RegistryPathStringDeserializer RegistryPathStringDeserializer::instance; - - struct GitVersionDbEntryDeserializer final : Json::IDeserializer - { - LocalizedString type_name() const override; - View valid_fields() const override; - Optional visit_object(Json::Reader& r, const Json::Object& obj) const override; - }; - - LocalizedString GitVersionDbEntryDeserializer::type_name() const { return msg::format(msgAVersionDatabaseEntry); } - View GitVersionDbEntryDeserializer::valid_fields() const - { - static constexpr StringView u_git[] = {JsonIdGitTree}; - static const auto t_git = vcpkg::Util::Vectors::concat(schemed_deserializer_fields(), u_git); - - return t_git; - } - - Optional GitVersionDbEntryDeserializer::visit_object(Json::Reader& r, - const Json::Object& obj) const - { - GitVersionDbEntry ret; - ret.version = visit_required_schemed_version(type_name(), r, obj); - r.required_object_field(type_name(), obj, JsonIdGitTree, ret.git_tree, GitTreeStringDeserializer::instance); - return ret; - } - - struct GitVersionDbEntryArrayDeserializer final : Json::IDeserializer> - { - virtual LocalizedString type_name() const override; - virtual Optional> visit_array(Json::Reader& r, - const Json::Array& arr) const override; - - private: - GitVersionDbEntryDeserializer underlying; - }; - LocalizedString GitVersionDbEntryArrayDeserializer::type_name() const { return msg::format(msgAnArrayOfVersions); } - - Optional> GitVersionDbEntryArrayDeserializer::visit_array( - Json::Reader& r, const Json::Array& arr) const - { - return r.array_elements(arr, underlying); - } - - struct FilesystemVersionDbEntryDeserializer final : Json::IDeserializer - { - LocalizedString type_name() const override; - View valid_fields() const override; - Optional visit_object(Json::Reader& r, const Json::Object& obj) const override; - FilesystemVersionDbEntryDeserializer(const Path& root) : registry_root(root) { } - private: - Path registry_root; - }; - - LocalizedString FilesystemVersionDbEntryDeserializer::type_name() const - { - return msg::format(msgAVersionDatabaseEntry); - } - View FilesystemVersionDbEntryDeserializer::valid_fields() const - { - static constexpr StringView u_path[] = {JsonIdPath}; - static const auto t_path = vcpkg::Util::Vectors::concat(schemed_deserializer_fields(), u_path); - return t_path; - } - - Optional FilesystemVersionDbEntryDeserializer::visit_object(Json::Reader& r, - const Json::Object& obj) const - { - FilesystemVersionDbEntry ret; - ret.version = visit_required_schemed_version(type_name(), r, obj); - - std::string path_res; - r.required_object_field(type_name(), obj, JsonIdPath, path_res, RegistryPathStringDeserializer::instance); - if (!Strings::starts_with(path_res, "$/")) - { - r.add_generic_error(msg::format(msgARegistryPath), msg::format(msgARegistryPathMustStartWithDollar)); - return nullopt; - } - - if (Strings::contains(path_res, '\\') || Strings::contains(path_res, "//")) - { - r.add_generic_error(msg::format(msgARegistryPath), - msg::format(msgARegistryPathMustBeDelimitedWithForwardSlashes)); - return nullopt; - } - - auto first = path_res.begin(); - const auto last = path_res.end(); - for (std::string::iterator candidate;; first = candidate) - { - candidate = std::find(first, last, '/'); - if (candidate == last) - { - break; - } - - ++candidate; - if (candidate == last) - { - break; - } - - if (*candidate != '.') - { - continue; - } - - ++candidate; - if (candidate == last || *candidate == '/') - { - r.add_generic_error(msg::format(msgARegistryPath), msg::format(msgARegistryPathMustNotHaveDots)); - return nullopt; - } - - if (*candidate != '.') - { - first = candidate; - continue; - } - - ++candidate; - if (candidate == last || *candidate == '/') - { - r.add_generic_error(msg::format(msgARegistryPath), msg::format(msgARegistryPathMustNotHaveDots)); - return nullopt; - } - } - - ret.p = registry_root / StringView{path_res}.substr(2); - - return ret; - } - - struct FilesystemVersionDbEntryArrayDeserializer final : Json::IDeserializer> - { - virtual LocalizedString type_name() const override; - virtual Optional> visit_array(Json::Reader& r, - const Json::Array& arr) const override; - FilesystemVersionDbEntryArrayDeserializer(const Path& root) : underlying{root} { } - - private: - FilesystemVersionDbEntryDeserializer underlying; - }; - LocalizedString FilesystemVersionDbEntryArrayDeserializer::type_name() const - { - return msg::format(msgAnArrayOfVersions); - } - - Optional> FilesystemVersionDbEntryArrayDeserializer::visit_array( - Json::Reader& r, const Json::Array& arr) const - { - return r.array_elements(arr, underlying); - } + const RegistryPathStringDeserializer RegistryPathStringDeserializer::instance; using Baseline = std::map>; struct GitRegistry; - struct PortVersionsGitTreesStructOfArrays - { - PortVersionsGitTreesStructOfArrays() = default; - PortVersionsGitTreesStructOfArrays(const PortVersionsGitTreesStructOfArrays&) = default; - PortVersionsGitTreesStructOfArrays(PortVersionsGitTreesStructOfArrays&&) = default; - PortVersionsGitTreesStructOfArrays& operator=(const PortVersionsGitTreesStructOfArrays&) = default; - PortVersionsGitTreesStructOfArrays& operator=(PortVersionsGitTreesStructOfArrays&&) = default; - - explicit PortVersionsGitTreesStructOfArrays(std::vector&& db_entries) - { - assign(std::move(db_entries)); - } - - void assign(std::vector&& db_entries) - { - m_port_versions.reserve(db_entries.size()); - m_git_trees.reserve(db_entries.size()); - m_port_versions.clear(); - m_git_trees.clear(); - for (auto& entry : db_entries) - { - m_port_versions.push_back(std::move(entry.version.version)); - m_git_trees.push_back(std::move(entry.git_tree)); - } - - db_entries.clear(); - } - - // these two map port versions to git trees - // these shall have the same size, and git_trees[i] shall be the git tree for port_versions[i] - const std::vector& port_versions() const noexcept { return m_port_versions; } - const std::vector& git_trees() const noexcept { return m_git_trees; } - - private: - std::vector m_port_versions; - std::vector m_git_trees; - }; - struct GitRegistryEntry final : RegistryEntry { GitRegistryEntry(StringView port_name, @@ -245,7 +55,6 @@ namespace bool stale, std::vector&& version_entries); - ExpectedL> get_port_versions() const override; ExpectedL try_load_port(const Version& version) const override; private: @@ -258,7 +67,7 @@ namespace // Indicates whether port_versions and git_trees were filled in with stale (i.e. lock) data. mutable bool stale; - mutable PortVersionsGitTreesStructOfArrays last_loaded; + mutable std::vector last_loaded; }; struct GitRegistry final : RegistryImplementation @@ -403,10 +212,6 @@ namespace { BuiltinPortTreeRegistryEntry(const SourceControlFileAndLocation& load_result_) : load_result(load_result_) { } - ExpectedL> get_port_versions() const override - { - return View{&load_result.source_control_file->to_version(), 1}; - } ExpectedL try_load_port(const Version& v) const override { auto& core_paragraph = load_result.source_control_file->core_paragraph; @@ -428,17 +233,13 @@ namespace { BuiltinGitRegistryEntry(const VcpkgPaths& paths) : m_paths(paths) { } - ExpectedL> get_port_versions() const override - { - return View{port_versions_soa.port_versions()}; - } ExpectedL try_load_port(const Version& version) const override; const VcpkgPaths& m_paths; std::string port_name; - PortVersionsGitTreesStructOfArrays port_versions_soa; + std::vector port_version_entries; }; struct FilesystemRegistryEntry final : RegistryEntry @@ -446,25 +247,15 @@ namespace explicit FilesystemRegistryEntry(const ReadOnlyFilesystem& fs, StringView port_name, std::vector&& version_entries) - : fs(fs), port_name(port_name.data(), port_name.size()) + : fs(fs), port_name(port_name.data(), port_name.size()), version_entries(std::move(version_entries)) { - for (auto&& version_entry : version_entries) - { - port_versions.push_back(std::move(version_entry.version.version)); - version_paths.push_back(std::move(version_entry.p)); - } } - ExpectedL> get_port_versions() const override { return View{port_versions}; } - ExpectedL try_load_port(const Version& version) const override; const ReadOnlyFilesystem& fs; std::string port_name; - // these two map port versions to paths - // these shall have the same size, and paths[i] shall be the path for port_versions[i] - std::vector port_versions; - std::vector version_paths; + std::vector version_entries; }; // This registry implementation is the builtin registry without a baseline @@ -784,7 +575,7 @@ namespace auto res = std::make_unique(m_paths); res->port_name.assign(port_name.data(), port_name.size()); - res->port_versions_soa.assign(std::move(*version_entries)); + res->port_version_entries = std::move(*version_entries); return res; }); } @@ -1046,14 +837,14 @@ namespace LocalizedString format_version_git_entry_missing(StringView port_name, const Version& expected_version, - const std::vector& versions) + const std::vector& version_entries) { auto error_msg = msg::format_error(msgVersionGitEntryMissing, msg::package_name = port_name, msg::version = expected_version) .append_raw('\n'); - for (auto&& version : versions) + for (auto&& version_entry : version_entries) { - error_msg.append_indent().append_raw(version.to_string()).append_raw('\n'); + error_msg.append_indent().append_raw(version_entry.version.version.to_string()).append_raw('\n'); } error_msg.append(msgVersionIncomparable4, msg::url = docs::versioning_url).append_raw('\n'); @@ -1066,32 +857,33 @@ namespace // { BuiltinRegistryEntry::RegistryEntry ExpectedL BuiltinGitRegistryEntry::try_load_port(const Version& version) const { - auto& port_versions = port_versions_soa.port_versions(); - auto it = std::find(port_versions.begin(), port_versions.end(), version); - if (it == port_versions.end()) + auto it = + std::find_if(port_version_entries.begin(), + port_version_entries.end(), + [&](const GitVersionDbEntry& entry) noexcept { return entry.version.version == version; }); + if (it == port_version_entries.end()) { - return format_version_git_entry_missing(port_name, version, port_versions) + return format_version_git_entry_missing(port_name, version, port_version_entries) .append_raw('\n') .append_raw(NotePrefix) .append(msgChecksUpdateVcpkg); } - const auto& git_tree = port_versions_soa.git_trees()[it - port_versions.begin()]; return m_paths.versions_dot_git_dir() .then([&, this](Path&& dot_git) { - return m_paths.git_checkout_port(port_name, git_tree, dot_git).map_error([](LocalizedString&& err) { + return m_paths.git_checkout_port(port_name, it->git_tree, dot_git).map_error([](LocalizedString&& err) { return std::move(err) .append_raw('\n') .append_raw(NotePrefix) .append(msgSeeURL, msg::url = docs::troubleshoot_versioning_url); }); }) - .then([this, &git_tree](Path&& p) -> ExpectedL { + .then([this, &it](Path&& p) -> ExpectedL { return Paragraphs::try_load_port_required(m_paths.get_filesystem(), port_name, PortLocation{ std::move(p), - "git+https://github.com/Microsoft/vcpkg@" + git_tree, + "git+https://github.com/Microsoft/vcpkg@" + it->git_tree, }) .maybe_scfl; }); @@ -1101,15 +893,17 @@ namespace // { FilesystemRegistryEntry::RegistryEntry ExpectedL FilesystemRegistryEntry::try_load_port(const Version& version) const { - auto it = std::find(port_versions.begin(), port_versions.end(), version); - if (it == port_versions.end()) + auto it = std::find_if( + version_entries.begin(), version_entries.end(), [&](const FilesystemVersionDbEntry& entry) noexcept { + return entry.version.version == version; + }); + if (it == version_entries.end()) { return msg::format_error( msgVersionDatabaseEntryMissing, msg::package_name = port_name, msg::version = version); } - const auto& load_path = version_paths[it - port_versions.begin()]; - return Paragraphs::try_load_port_required(fs, port_name, PortLocation{load_path}).maybe_scfl; + return Paragraphs::try_load_port_required(fs, port_name, PortLocation{it->p}).maybe_scfl; } // } FilesystemRegistryEntry::RegistryEntry @@ -1142,29 +936,18 @@ namespace msg::path = *live_vdb / relative_path_to_versions(port_name)); } - last_loaded.assign(std::move(*version_entries)); + last_loaded = std::move(*version_entries); stale = false; } return Unit{}; } - ExpectedL> GitRegistryEntry::get_port_versions() const - { - // Getting all versions that might exist must always be done with 'live' data - auto maybe_not_stale = ensure_not_stale(); - if (maybe_not_stale) - { - return View{last_loaded.port_versions()}; - } - - return std::move(maybe_not_stale).error(); - } - ExpectedL GitRegistryEntry::try_load_port(const Version& version) const { - auto it = std::find(last_loaded.port_versions().begin(), last_loaded.port_versions().end(), version); - if (it == last_loaded.port_versions().end() && stale) + auto match_version = [&](const GitVersionDbEntry& entry) noexcept { return entry.version.version == version; }; + auto it = std::find_if(last_loaded.begin(), last_loaded.end(), match_version); + if (it == last_loaded.end() && stale) { // didn't find the version, maybe a newer version database will have it auto maybe_not_stale = ensure_not_stale(); @@ -1173,22 +956,21 @@ namespace return std::move(maybe_not_stale).error(); } - it = std::find(last_loaded.port_versions().begin(), last_loaded.port_versions().end(), version); + it = std::find_if(last_loaded.begin(), last_loaded.end(), match_version); } - if (it == last_loaded.port_versions().end()) + if (it == last_loaded.end()) { - return format_version_git_entry_missing(port_name, version, last_loaded.port_versions()); + return format_version_git_entry_missing(port_name, version, last_loaded); } - const auto& git_tree = last_loaded.git_trees()[it - last_loaded.port_versions().begin()]; - return parent.m_paths.git_extract_tree_from_remote_registry(git_tree).then( - [this, &git_tree](Path&& p) -> ExpectedL { + return parent.m_paths.git_extract_tree_from_remote_registry(it->git_tree) + .then([this, &it](Path&& p) -> ExpectedL { return Paragraphs::try_load_port_required(parent.m_paths.get_filesystem(), port_name, PortLocation{ p, - Strings::concat("git+", parent.m_repo, "@", git_tree), + Strings::concat("git+", parent.m_repo, "@", it->git_tree), }) .maybe_scfl; }); @@ -1751,14 +1533,116 @@ namespace vcpkg return std::make_unique(fs, std::move(path), std::move(baseline)); } - std::unique_ptr>> make_git_version_db_deserializer() + LocalizedString FilesystemVersionDbEntryDeserializer::type_name() const { - return std::make_unique(); + return msg::format(msgAVersionDatabaseEntry); + } + View FilesystemVersionDbEntryDeserializer::valid_fields() const noexcept + { + static constexpr StringLiteral fields[] = {VCPKG_SCHEMED_DESERIALIZER_FIELDS, JsonIdPath}; + return fields; } - std::unique_ptr>> make_filesystem_version_db_deserializer( - const Path& root) + Optional FilesystemVersionDbEntryDeserializer::visit_object(Json::Reader& r, + const Json::Object& obj) const + { + FilesystemVersionDbEntry ret; + ret.version = visit_required_schemed_version(type_name(), r, obj); + + std::string path_res; + r.required_object_field(type_name(), obj, JsonIdPath, path_res, RegistryPathStringDeserializer::instance); + if (!Strings::starts_with(path_res, "$/")) + { + r.add_generic_error(msg::format(msgARegistryPath), msg::format(msgARegistryPathMustStartWithDollar)); + return nullopt; + } + + if (Strings::contains(path_res, '\\') || Strings::contains(path_res, "//")) + { + r.add_generic_error(msg::format(msgARegistryPath), + msg::format(msgARegistryPathMustBeDelimitedWithForwardSlashes)); + return nullopt; + } + + auto first = path_res.begin(); + const auto last = path_res.end(); + for (std::string::iterator candidate;; first = candidate) + { + candidate = std::find(first, last, '/'); + if (candidate == last) + { + break; + } + + ++candidate; + if (candidate == last) + { + break; + } + + if (*candidate != '.') + { + continue; + } + + ++candidate; + if (candidate == last || *candidate == '/') + { + r.add_generic_error(msg::format(msgARegistryPath), msg::format(msgARegistryPathMustNotHaveDots)); + return nullopt; + } + + if (*candidate != '.') + { + first = candidate; + continue; + } + + ++candidate; + if (candidate == last || *candidate == '/') + { + r.add_generic_error(msg::format(msgARegistryPath), msg::format(msgARegistryPathMustNotHaveDots)); + return nullopt; + } + } + + ret.p = registry_root / StringView{path_res}.substr(2); + + return ret; + } + + LocalizedString FilesystemVersionDbEntryArrayDeserializer::type_name() const + { + return msg::format(msgAnArrayOfVersions); + } + + Optional> FilesystemVersionDbEntryArrayDeserializer::visit_array( + Json::Reader& r, const Json::Array& arr) const + { + return r.array_elements(arr, underlying); + } + + LocalizedString GitVersionDbEntryDeserializer::type_name() const { return msg::format(msgAVersionDatabaseEntry); } + View GitVersionDbEntryDeserializer::valid_fields() const noexcept + { + static constexpr StringLiteral fields[] = {VCPKG_SCHEMED_DESERIALIZER_FIELDS, JsonIdGitTree}; + return fields; + } + + Optional GitVersionDbEntryDeserializer::visit_object(Json::Reader& r, + const Json::Object& obj) const + { + GitVersionDbEntry ret; + ret.version = visit_required_schemed_version(type_name(), r, obj); + r.required_object_field(type_name(), obj, JsonIdGitTree, ret.git_tree, GitTreeStringDeserializer::instance); + return ret; + } + + LocalizedString GitVersionDbEntryArrayDeserializer::type_name() const { return msg::format(msgAnArrayOfVersions); } + + Optional> GitVersionDbEntryArrayDeserializer::visit_array( + Json::Reader& r, const Json::Array& arr) const { - return std::make_unique(root); + return r.array_elements(arr, GitVersionDbEntryDeserializer()); } } diff --git a/src/vcpkg/sourceparagraph.cpp b/src/vcpkg/sourceparagraph.cpp index 1a581431ab..c60a587279 100644 --- a/src/vcpkg/sourceparagraph.cpp +++ b/src/vcpkg/sourceparagraph.cpp @@ -516,9 +516,9 @@ namespace vcpkg { LocalizedString type_name() const override { return msg::format(msgADefaultFeature); } - Span valid_fields() const override + View valid_fields() const noexcept override { - static const StringView t[] = { + static const StringLiteral t[] = { JsonIdName, JsonIdPlatform, }; @@ -580,9 +580,9 @@ namespace vcpkg { LocalizedString type_name() const override { return msg::format(msgADependencyFeature); } - Span valid_fields() const override + View valid_fields() const noexcept override { - static const StringView t[] = { + static const StringLiteral t[] = { JsonIdName, JsonIdPlatform, }; @@ -620,9 +620,9 @@ namespace vcpkg { virtual LocalizedString type_name() const override { return msg::format(msgADependency); } - virtual Span valid_fields() const override + virtual View valid_fields() const noexcept override { - static constexpr StringView t[] = { + static constexpr StringLiteral t[] = { JsonIdName, JsonIdHost, JsonIdFeatures, @@ -701,11 +701,10 @@ namespace vcpkg struct DependencyOverrideDeserializer final : Json::IDeserializer { virtual LocalizedString type_name() const override { return msg::format(msgAnOverride); } - virtual Span valid_fields() const override + virtual View valid_fields() const noexcept override { - static constexpr StringView u[] = {JsonIdName}; - static const auto t = Util::Vectors::concat(schemed_deserializer_fields(), u); - return t; + static constexpr StringLiteral fields[] = {VCPKG_SCHEMED_DESERIALIZER_FIELDS, JsonIdName}; + return fields; } virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override @@ -731,10 +730,33 @@ namespace vcpkg const DependencyOverrideDeserializer DependencyOverrideDeserializer::instance; - struct DependencyOverrideArrayDeserializer : Json::ArrayDeserializer + struct DependencyOverrideArrayDeserializer : Json::IDeserializer> { LocalizedString type_name() const override { return msg::format(msgAnArrayOfDependencyOverrides); } + virtual Optional> visit_array(Json::Reader& r, + const Json::Array& arr) const override + { + std::set seen; + return r.array_elements_fn( + arr, + DependencyOverrideDeserializer::instance, + [&](Json::Reader& r, const IDeserializer& visitor, const Json::Value& value) { + auto maybe_dependency_override = visitor.visit(r, value); + if (auto dependency_override = maybe_dependency_override.get()) + { + if (!seen.insert(dependency_override->name).second) + { + r.add_generic_error(visitor.type_name(), + msg::format(msgDuplicateDependencyOverride, + msg::package_name = dependency_override->name)); + } + } + + return maybe_dependency_override; + }); + } + static const DependencyOverrideArrayDeserializer instance; }; @@ -753,7 +775,7 @@ namespace vcpkg // * `null`, for when the license of the package cannot be described by an SPDX expression struct SpdxLicenseExpressionParser : ParserBase { - SpdxLicenseExpressionParser(StringView sv, StringView origin) : ParserBase(sv, origin) { } + SpdxLicenseExpressionParser(StringView sv, StringView origin) : ParserBase(sv, origin, {0, 0}) { } static const StringLiteral* case_insensitive_find(View lst, StringView id) { @@ -1004,9 +1026,9 @@ namespace vcpkg { virtual LocalizedString type_name() const override { return msg::format(msgAFeature); } - virtual Span valid_fields() const override + virtual View valid_fields() const noexcept override { - static constexpr StringView t[] = {JsonIdDescription, JsonIdDependencies, JsonIdSupports, JsonIdLicense}; + static constexpr StringLiteral t[] = {JsonIdDescription, JsonIdDependencies, JsonIdSupports, JsonIdLicense}; return t; } @@ -1052,8 +1074,6 @@ namespace vcpkg { virtual LocalizedString type_name() const override { return msg::format(msgASetOfFeatures); } - virtual Span valid_fields() const override { return {}; } - virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override { FeaturesObject res; @@ -1122,9 +1142,10 @@ namespace vcpkg { virtual LocalizedString type_name() const override { return msg::format(msgAManifest); } - virtual Span valid_fields() const override + virtual View valid_fields() const noexcept override { - static constexpr StringView u[] = { + static constexpr StringLiteral fields[] = { + VCPKG_SCHEMED_DESERIALIZER_FIELDS, JsonIdName, JsonIdMaintainers, JsonIdContacts, @@ -1141,9 +1162,8 @@ namespace vcpkg JsonIdBuiltinBaseline, JsonIdVcpkgConfiguration, }; - static const auto t = Util::Vectors::concat(schemed_deserializer_fields(), u); - return t; + return fields; } vcpkg::Optional> visit_object_common( @@ -1278,7 +1298,7 @@ namespace vcpkg Optional x; ManifestConfiguration& ret = x.emplace(); if (!r.optional_object_field( - obj, JsonIdVcpkgConfiguration, ret.config.emplace(), get_configuration_deserializer())) + obj, JsonIdVcpkgConfiguration, ret.config.emplace(), configuration_deserializer)) { ret.config = nullopt; } @@ -1299,7 +1319,7 @@ namespace vcpkg MessageSink& warningsSink) { Json::Reader reader(origin); - auto res = reader.visit(manifest, ManifestConfigurationDeserializer::instance); + auto res = ManifestConfigurationDeserializer::instance.visit(reader, manifest); if (!reader.warnings().empty()) { @@ -1351,7 +1371,7 @@ namespace vcpkg { Json::Reader reader(control_path); - auto res = reader.visit(manifest, ManifestDeserializerType::instance); + auto res = ManifestDeserializerType::instance.visit(reader, manifest); for (auto&& w : reader.warnings()) { diff --git a/src/vcpkg/spdx.cpp b/src/vcpkg/spdx.cpp index c78df642e9..ad6cf21f58 100644 --- a/src/vcpkg/spdx.cpp +++ b/src/vcpkg/spdx.cpp @@ -9,12 +9,88 @@ using namespace vcpkg; +StringView vcpkg::extract_first_cmake_invocation_args(StringView content, StringView command) +{ + // command\s*\(([^)]+)\) + auto it = content.begin(); + do + { + it = Util::search_and_skip(it, content.end(), command); + if (it == content.end()) + { + return {}; + } + + while (ParserBase::is_whitespace(*it)) + { + ++it; + if (it == content.end()) + { + return {}; + } + } + // if we don't get a ( here, then we matched a prefix of the command but not the command itself + } while (*it != '('); + ++it; + auto it_end = std::find(it, content.end(), ')'); + if (it_end == content.end()) + { + return {}; + } + + return StringView{it, it_end}; +} + +StringView vcpkg::extract_arg_from_cmake_invocation_args(StringView invocation_args, StringView target_arg) +{ + auto it = invocation_args.begin(); + do + { + it = Util::search_and_skip(it, invocation_args.end(), target_arg); + if (it == invocation_args.end()) + { + return {}; + } + } while (!ParserBase::is_whitespace(*it)); + it = std::find_if_not(it, invocation_args.end(), ParserBase::is_whitespace); + if (it == invocation_args.end()) + { + return {}; + } + + if (*it == '"') + { + // quoted value + ++it; + auto it_end = std::find(it, invocation_args.end(), '"'); + if (it_end == invocation_args.end()) + { + return {}; + } + + return {it, it_end}; + } + + // unquoted value + return {it, std::find_if(it + 1, invocation_args.end(), ParserBase::is_whitespace)}; +} + +std::string vcpkg::replace_cmake_var(StringView text, StringView var, StringView value) +{ + std::string replacement; + replacement.reserve(var.size() + 3); + replacement.append("${", 2); + replacement.append(var.data(), var.size()); + replacement.push_back('}'); + return Strings::replace_all(text, replacement, value); +} + static std::string fix_ref_version(StringView ref, StringView version) { - return Strings::replace_all(ref, "${VERSION}", version); + return replace_cmake_var(ref, CMakeVariableVersion, version); } -static StringView conclude_license(const Optional& maybe_license) +static ZStringView conclude_license(const Optional& maybe_license) { if (auto license = maybe_license.get()) { @@ -41,36 +117,12 @@ static void append_move_if_exists_and_array(Json::Array& out, Json::Object& obj, } } -static StringView find_cmake_invocation(StringView contents, StringView command) -{ - auto it = Strings::case_insensitive_ascii_search(contents, command); - if (it == contents.end()) return {}; - it += command.size(); - if (it == contents.end()) return {}; - if (ParserBase::is_word_char(*it)) return {}; - auto it_end = std::find(it, contents.end(), ')'); - return {it, it_end}; -} - -static StringView extract_cmake_invocation_argument(StringView command, StringView argument) -{ - auto it = Util::search_and_skip(command.begin(), command.end(), argument); - it = std::find_if_not(it, command.end(), ParserBase::is_whitespace); - if (it == command.end()) return {}; - if (*it == '"') - { - return {it + 1, std::find(it + 1, command.end(), '"')}; - } - return {it, - std::find_if(it + 1, command.end(), [](char ch) { return ParserBase::is_whitespace(ch) || ch == ')'; })}; -} - static Json::Object make_resource( std::string spdxid, StringView name, std::string downloadLocation, StringView sha512, StringView filename) { Json::Object obj; obj.insert(SpdxSpdxId, std::move(spdxid)); - obj.insert(JsonIdName, name.to_string()); + obj.insert(JsonIdName, name); if (!filename.empty()) { obj.insert(SpdxPackageFileName, filename); @@ -91,54 +143,154 @@ static Json::Object make_resource( namespace vcpkg { - Json::Object run_resource_heuristics(StringView contents, StringView version_text) + static void find_all_github(StringView text, Json::Array& packages, StringView version_text) { - // These are a sequence of heuristics to enable proof-of-concept extraction of remote resources for SPDX SBOM - // inclusion - size_t n = 0; - Json::Object ret; - auto& packages = ret.insert(JsonIdPackages, Json::Array{}); - auto github = find_cmake_invocation(contents, "vcpkg_from_github"); - if (!github.empty()) + auto it = version_text.begin(); + while (it != text.end()) { - auto repo = extract_cmake_invocation_argument(github, CMakeVariableRepo); - auto ref = fix_ref_version(extract_cmake_invocation_argument(github, CMakeVariableRef), version_text); - auto sha = extract_cmake_invocation_argument(github, CMakeVariableSHA512); + auto github = extract_first_cmake_invocation_args(StringView{it, text.end()}, "vcpkg_from_github"); + if (github.empty()) + { + it = text.end(); + continue; + } + auto repo = extract_arg_from_cmake_invocation_args(github, CMakeVariableRepo); + auto ref = fix_ref_version(extract_arg_from_cmake_invocation_args(github, CMakeVariableRef), version_text); + auto sha = extract_arg_from_cmake_invocation_args(github, CMakeVariableSHA512); - packages.push_back(make_resource(fmt::format("SPDXRef-resource-{}", ++n), + packages.push_back(make_resource(fmt::format("SPDXRef-resource-{}", packages.size()), repo, fmt::format("git+https://github.com/{}@{}", repo, ref), sha, {})); + it = github.end(); } - auto git = find_cmake_invocation(contents, "vcpkg_from_git"); - if (!git.empty()) + } + + static void find_all_bitbucket(StringView text, Json::Array& packages, StringView version_text) + { + auto it = text.begin(); + while (it != text.end()) + { + auto bitbucket = extract_first_cmake_invocation_args(StringView{it, text.end()}, "vcpkg_from_bitbucket"); + if (bitbucket.empty()) + { + it = text.end(); + continue; + } + auto repo = extract_arg_from_cmake_invocation_args(bitbucket, CMakeVariableRepo); + auto ref = + fix_ref_version(extract_arg_from_cmake_invocation_args(bitbucket, CMakeVariableRef), version_text); + auto sha = extract_arg_from_cmake_invocation_args(bitbucket, CMakeVariableSHA512); + + packages.push_back(make_resource(fmt::format("SPDXRef-resource-{}", packages.size()), + repo, + fmt::format("git+https://bitbucket.com/{}@{}", repo, ref), + sha, + {})); + it = bitbucket.end(); + } + } + + static void find_all_gitlab(StringView text, Json::Array& packages, StringView version_text) + { + auto it = text.begin(); + while (it != text.end()) { - auto url = extract_cmake_invocation_argument(github, CMakeVariableUrl); - auto ref = fix_ref_version(extract_cmake_invocation_argument(github, CMakeVariableRef), version_text); + auto gitlab = extract_first_cmake_invocation_args(StringView{it, text.end()}, "vcpkg_from_gitlab"); + if (gitlab.empty()) + { + it = text.end(); + continue; + } + auto repo = extract_arg_from_cmake_invocation_args(gitlab, CMakeVariableRepo); + auto url = extract_arg_from_cmake_invocation_args(gitlab, CMakeVariableGitlabUrl); + auto ref = fix_ref_version(extract_arg_from_cmake_invocation_args(gitlab, CMakeVariableRef), version_text); + auto sha = extract_arg_from_cmake_invocation_args(gitlab, CMakeVariableSHA512); + + packages.push_back(make_resource(fmt::format("SPDXRef-resource-{}", packages.size()), + repo, + fmt::format("git+{}/{}@{}", url, repo, ref), + sha, + {})); + it = gitlab.end(); + } + } + + static void find_all_git(StringView text, Json::Array& packages, StringView version_text) + { + auto it = text.begin(); + while (it != text.end()) + { + auto git = extract_first_cmake_invocation_args(StringView{it, text.end()}, "vcpkg_from_git"); + if (git.empty()) + { + it = text.end(); + continue; + } + auto url = extract_arg_from_cmake_invocation_args(git, CMakeVariableUrl); + auto ref = fix_ref_version(extract_arg_from_cmake_invocation_args(git, CMakeVariableRef), version_text); packages.push_back(make_resource( - fmt::format("SPDXRef-resource-{}", ++n), url, fmt::format("git+{}@{}", url, ref), {}, {})); + fmt::format("SPDXRef-resource-{}", packages.size()), url, fmt::format("git+{}@{}", url, ref), {}, {})); + it = git.end(); } - auto distfile = find_cmake_invocation(contents, "vcpkg_download_distfile"); - if (!distfile.empty()) + } + + static void find_all_distfile(StringView text, Json::Array& packages) + { + auto it = text.begin(); + while (it != text.end()) { - auto url = extract_cmake_invocation_argument(distfile, CMakeVariableUrls); - auto filename = extract_cmake_invocation_argument(distfile, CMakeVariableFilename); - auto sha = extract_cmake_invocation_argument(distfile, CMakeVariableSHA512); - packages.push_back( - make_resource(fmt::format("SPDXRef-resource-{}", ++n), filename, url.to_string(), sha, filename)); + auto distfile = extract_first_cmake_invocation_args(StringView{it, text.end()}, "vcpkg_download_distfile"); + if (distfile.empty()) + { + it = text.end(); + continue; + } + auto url = extract_arg_from_cmake_invocation_args(distfile, CMakeVariableUrls); + auto filename = extract_arg_from_cmake_invocation_args(distfile, CMakeVariableFilename); + auto sha = extract_arg_from_cmake_invocation_args(distfile, CMakeVariableSHA512); + packages.push_back(make_resource( + fmt::format("SPDXRef-resource-{}", packages.size()), filename, url.to_string(), sha, filename)); + it = distfile.end(); } - auto sfg = find_cmake_invocation(contents, "vcpkg_from_sourceforge"); - if (!sfg.empty()) + } + + static void find_all_sourceforge(StringView text, Json::Array& packages, StringView version_text) + { + auto it = text.begin(); + while (it != text.end()) { - auto repo = extract_cmake_invocation_argument(sfg, CMakeVariableRepo); - auto ref = fix_ref_version(extract_cmake_invocation_argument(sfg, CMakeVariableRef), version_text); - auto filename = extract_cmake_invocation_argument(sfg, CMakeVariableFilename); - auto sha = extract_cmake_invocation_argument(sfg, CMakeVariableSHA512); + auto sfg = extract_first_cmake_invocation_args(StringView{it, text.end()}, "vcpkg_from_sourceforge"); + if (sfg.empty()) + { + it = text.end(); + continue; + } + auto repo = extract_arg_from_cmake_invocation_args(sfg, CMakeVariableRepo); + auto ref = fix_ref_version(extract_arg_from_cmake_invocation_args(sfg, CMakeVariableRef), version_text); + auto filename = extract_arg_from_cmake_invocation_args(sfg, CMakeVariableFilename); + auto sha = extract_arg_from_cmake_invocation_args(sfg, CMakeVariableSHA512); auto url = fmt::format("https://sourceforge.net/projects/{}/files/{}/{}", repo, ref, filename); - packages.push_back( - make_resource(fmt::format("SPDXRef-resource-{}", ++n), filename, std::move(url), sha, filename)); + packages.push_back(make_resource( + fmt::format("SPDXRef-resource-{}", packages.size()), filename, std::move(url), sha, filename)); + it = sfg.end(); } + } + + Json::Object vcpkg::run_resource_heuristics(StringView contents, StringView version_text) + { + // These are a sequence of heuristics to enable proof-of-concept extraction of remote resources for SPDX SBOM + // inclusion + Json::Object ret; + auto& packages = ret.insert(JsonIdPackages, Json::Array{}); + + find_all_github(contents, packages, version_text); + find_all_gitlab(contents, packages, version_text); + find_all_git(contents, packages, version_text); + find_all_distfile(contents, packages); + find_all_sourceforge(contents, packages, version_text); + find_all_bitbucket(contents, packages, version_text); return ret; } diff --git a/src/vcpkg/tools.cpp b/src/vcpkg/tools.cpp index c9095dc663..2927a67682 100644 --- a/src/vcpkg/tools.cpp +++ b/src/vcpkg/tools.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include #include @@ -18,11 +20,30 @@ #include #include -#include +#include + +namespace +{ + using namespace vcpkg; + struct ToolOsEntry + { + StringLiteral name; + ToolOs os; + }; + + // keep this in sync with vcpkg-tools.schema.json + static constexpr ToolOsEntry all_tool_oses[] = { + {"windows", ToolOs::Windows}, + {"osx", ToolOs::Osx}, + {"linux", ToolOs::Linux}, + {"freebsd", ToolOs::FreeBsd}, + {"openbsd", ToolOs::OpenBsd}, + }; +} namespace vcpkg { - // /\d+\.\d+(\.\d+)?/ + // /\d+(\.\d+(\.\d+)?)?/ Optional> parse_tool_version_string(StringView string_version) { // first, find the beginning of the version @@ -62,82 +83,126 @@ namespace vcpkg return std::array{*d1.get(), *d2.get(), *d3.get()}; } - static Optional parse_tool_data_from_xml(StringView XML, StringView XML_PATH, StringView tool) + Optional to_tool_os(StringView os) noexcept { + for (auto&& entry : all_tool_oses) + { + if (os == entry.name) + { + return entry.os; + } + } + + return nullopt; + } + + StringLiteral to_string_literal(ToolOs os) noexcept + { + for (auto&& entry : all_tool_oses) + { + if (os == entry.os) + { + return entry.name; + } + } + + Checks::unreachable(VCPKG_LINE_INFO, "Unexpected ToolOs"); + } + + LocalizedString all_comma_separated_tool_oses() + { + return LocalizedString::from_raw( + Strings::join(", ", all_tool_oses, [](const ToolOsEntry& entry) { return entry.name; })); + } + + ExpectedL> parse_tool_data(StringView contents, StringView origin) + { + return Json::parse_object(contents, origin) + .then([&](Json::Object&& as_object) -> ExpectedL> { + Json::Reader r(origin); + auto maybe_tool_data = ToolDataFileDeserializer::instance.visit(r, as_object); + if (!r.errors().empty() || !r.warnings().empty()) + { + return r.join(); + } + + return maybe_tool_data.value_or_exit(VCPKG_LINE_INFO); + }); + } + + static ExpectedL> parse_tool_data_file(const Filesystem& fs, Path path) + { + return fs.try_read_contents(path).then([](FileContents&& fc) -> ExpectedL> { + return parse_tool_data(fc.content, Path{fc.origin}); + }); + } + + const ToolDataEntry* get_raw_tool_data(const std::vector& tool_data_table, + StringView toolname, + const CPUArchitecture arch, + const ToolOs os) + { + const ToolDataEntry* default_tool = nullptr; + for (auto&& tool_candidate : tool_data_table) + { + if (tool_candidate.tool == toolname && tool_candidate.os == os) + { + if (!tool_candidate.arch) + { + if (!default_tool) + { + default_tool = &tool_candidate; + } + } + else if (arch == *tool_candidate.arch.get()) + { + return &tool_candidate; + } + } + } + return default_tool; + } + + static Optional get_tool_data(const std::vector& tool_data_table, StringView tool) + { + auto hp = get_host_processor(); #if defined(_WIN32) - return parse_tool_data_from_xml(XML, XML_PATH, tool, "windows"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, ToolOs::Windows); #elif defined(__APPLE__) - return parse_tool_data_from_xml(XML, XML_PATH, tool, "osx"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, ToolOs::Osx); #elif defined(__linux__) - return parse_tool_data_from_xml(XML, XML_PATH, tool, "linux"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, ToolOs::Linux); #elif defined(__FreeBSD__) - return parse_tool_data_from_xml(XML, XML_PATH, tool, "freebsd"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, ToolOs::FreeBsd); #elif defined(__OpenBSD__) - return parse_tool_data_from_xml(XML, XML_PATH, tool, "openbsd"); + auto data = get_raw_tool_data(tool_data_table, tool, hp, ToolOs::OpenBsd); #else return nullopt; #endif - } + if (!data) + { + return nullopt; + } - Optional parse_tool_data_from_xml(StringView XML, StringView XML_PATH, StringView tool, StringView os) - { - static const char* XML_VERSION = "2"; - static const std::regex XML_VERSION_REGEX{R"###()###"}; - std::cmatch match_xml_version; - const bool has_xml_version = std::regex_search(XML.begin(), XML.end(), match_xml_version, XML_VERSION_REGEX); - Checks::msg_check_exit(VCPKG_LINE_INFO, - has_xml_version, - msgCouldNotFindToolVersion, - msg::version = XML_VERSION, - msg::path = XML_PATH); - Checks::msg_check_exit(VCPKG_LINE_INFO, - XML_VERSION == match_xml_version[1], - msgVersionConflictXML, - msg::path = XML_PATH, - msg::expected_version = XML_VERSION, - msg::actual_version = match_xml_version[1].str()); - - const std::regex tool_regex{fmt::format(R"###()###", tool, os)}; - std::cmatch match_tool_entry; - const bool has_tool_entry = std::regex_search(XML.begin(), XML.end(), match_tool_entry, tool_regex); - if (!has_tool_entry) return nullopt; - - const std::string tool_data = - Strings::find_exactly_one_enclosed(XML, match_tool_entry[0].str(), "").to_string(); - const std::string version_as_string = - Strings::find_exactly_one_enclosed(tool_data, "", "").to_string(); - const std::string exe_relative_path = - Strings::find_exactly_one_enclosed(tool_data, "", "").to_string(); - const std::string url = Strings::find_exactly_one_enclosed(tool_data, "", "").to_string(); - const std::string sha512 = Strings::find_exactly_one_enclosed(tool_data, "", "").to_string(); - auto archive_name = Strings::find_at_most_one_enclosed(tool_data, "", ""); - - const Optional> version = parse_tool_version_string(version_as_string); - Checks::msg_check_exit(VCPKG_LINE_INFO, - version.has_value(), - msgFailedToParseVersionXML, - msg::tool_name = tool, - msg::version = version_as_string); - - Path tool_dir_name = fmt::format("{}-{}-{}", tool, version_as_string, os); + Path tool_dir_name = fmt::format("{}-{}-{}", tool, data->version.raw, data->os); Path download_subpath; - if (auto a = archive_name.get()) + if (!data->archiveName.empty()) { - download_subpath = a->to_string(); + download_subpath = data->archiveName; } - else if (!exe_relative_path.empty()) + else if (!data->exeRelativePath.empty()) { - download_subpath = Strings::concat(sha512.substr(0, 8), '-', exe_relative_path); + download_subpath = Strings::concat(StringView{data->sha512}.substr(0, 8), '-', data->exeRelativePath); } return ToolData{tool.to_string(), - *version.get(), - exe_relative_path, - url, + data->version.cooked, + data->exeRelativePath, + data->url, download_subpath, - archive_name.has_value(), + !data->archiveName.empty(), tool_dir_name, - sha512}; + data->sha512}; } struct PathAndVersion @@ -228,6 +293,13 @@ namespace vcpkg MessageSink& status_sink, const Path& exe_path) const = 0; + // returns true if and only if `exe_path` is a usable version of this tool, cheap check + virtual bool cheap_is_acceptable(const Path& exe_path) const + { + (void)exe_path; + return true; + } + // returns true if and only if `exe_path` is a usable version of this tool virtual bool is_acceptable(const Path& exe_path) const { @@ -280,6 +352,14 @@ namespace vcpkg out_candidate_paths.push_back(*pf / "CMake" / "bin" / "cmake.exe"); } } + + virtual bool cheap_is_acceptable(const Path& exe_path) const override + { + // the cmake version from mysys and cygwin can not be used because that version can't handle 'C:' in paths + auto path = exe_path.generic_u8string(); + return !Strings::ends_with(path, "/usr/bin") && !Strings::ends_with(path, "/cygwin64/bin"); + } + #endif virtual ExpectedL get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override { @@ -303,6 +383,13 @@ namespace vcpkg virtual StringView tool_data_name() const override { return Tools::NINJA; } virtual std::vector system_exe_stems() const override { return {Tools::NINJA}; } virtual std::array default_min_version() const override { return {3, 5, 1}; } +#if !defined(_WIN32) + virtual void add_system_paths(const ReadOnlyFilesystem&, std::vector& out_candidate_paths) const override + { + // This is where Ninja goes by default on Alpine: https://github.com/microsoft/vcpkg/issues/21218 + out_candidate_paths.emplace_back("/usr/lib/ninja-build/bin"); + } +#endif // ^^^ !defined(_WIN32) virtual ExpectedL get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override { @@ -346,24 +433,6 @@ namespace vcpkg } }; - struct Aria2Provider : ToolProvider - { - virtual bool is_abi_sensitive() const override { return false; } - virtual StringView tool_data_name() const override { return Tools::ARIA2; } - virtual std::vector system_exe_stems() const override { return {"aria2c"}; } - virtual std::array default_min_version() const override { return {1, 33, 1}; } - virtual ExpectedL 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) { - // Sample output: - // aria2 version 1.35.0 - // Copyright (C) 2006, 2019 Tatsuhiro Tsujikawa - return extract_prefixed_nonwhitespace("aria2 version ", Tools::ARIA2, std::move(output), exe_path); - }); - } - }; - struct NodeProvider : ToolProvider { virtual bool is_abi_sensitive() const override { return false; } @@ -652,28 +721,62 @@ namespace vcpkg } }; + struct SevenZipProvider : ToolProvider + { + virtual bool is_abi_sensitive() const override { return false; } + virtual StringView tool_data_name() const override { return Tools::SEVEN_ZIP; } + virtual std::vector system_exe_stems() const override { return {"7z"}; } + virtual std::array default_min_version() const override { return {24, 9}; } + +#if defined(_WIN32) + virtual void add_system_paths(const ReadOnlyFilesystem&, std::vector& out_candidate_paths) const override + { + const auto& program_files = get_program_files_platform_bitness(); + if (const auto pf = program_files.get()) + { + out_candidate_paths.push_back(*pf / "7-Zip" / "7z.exe"); + } + + const auto& program_files_32_bit = get_program_files_32_bit(); + if (const auto pf = program_files_32_bit.get()) + { + out_candidate_paths.push_back(*pf / "7-Zip" / "7z.exe"); + } + } +#endif + + virtual ExpectedL get_version(const ToolCache&, MessageSink&, const Path& exe_path) const override + { + return run_to_extract_version(Tools::SEVEN_ZIP, exe_path, Command(exe_path)) + .then([&](std::string&& output) { + // Sample output: 7-Zip 24.09 (x64) : Copyright (c) 1999-2024 Igor Pavlov : 2024-11-29 + return extract_prefixed_nonwhitespace("7-Zip ", Tools::SEVEN_ZIP, std::move(output), exe_path); + }); + } + }; + struct ToolCacheImpl final : ToolCache { const Filesystem& fs; - const std::shared_ptr downloader; + AssetCachingSettings asset_cache_settings; const Path downloads; - const Path xml_config; + const Path config_path; const Path tools; const RequireExactVersions abiToolVersionHandling; - vcpkg::Lazy xml_config_contents; vcpkg::Cache path_version_cache; + vcpkg::Lazy> m_tool_data_cache; ToolCacheImpl(const Filesystem& fs, - const std::shared_ptr& downloader, + const AssetCachingSettings& asset_cache_settings, Path downloads, - Path xml_config, + Path config_path, Path tools, RequireExactVersions abiToolVersionHandling) : fs(fs) - , downloader(downloader) + , asset_cache_settings(asset_cache_settings) , downloads(std::move(downloads)) - , xml_config(std::move(xml_config)) + , config_path(std::move(config_path)) , tools(std::move(tools)) , abiToolVersionHandling(abiToolVersionHandling) { @@ -694,6 +797,7 @@ namespace vcpkg for (auto&& candidate : candidates) { if (!fs.exists(candidate, IgnoreErrors{})) continue; + if (!tool_provider.cheap_is_acceptable(candidate)) continue; auto maybe_version = tool_provider.get_version(*this, status_sink, candidate); log_candidate(candidate, maybe_version); const auto version = maybe_version.get(); @@ -712,6 +816,8 @@ namespace vcpkg Path download_tool(const ToolData& tool_data, MessageSink& status_sink) const { + using namespace Hash; + const std::array& version = tool_data.version; const std::string version_as_string = fmt::format("{}.{}.{}", version[0], version[1], version[2]); Checks::msg_check_maybe_upgrade(VCPKG_LINE_INFO, @@ -725,13 +831,38 @@ namespace vcpkg msg::version = version_as_string); const auto download_path = downloads / tool_data.download_subpath; - if (!fs.exists(download_path, IgnoreErrors{})) + const auto hash_result = get_file_hash(console_diagnostic_context, fs, download_path, Algorithm::Sha512); + switch (hash_result.prognosis) { - downloader->download_file(fs, tool_data.url, {}, download_path, tool_data.sha512, null_sink); - } - else - { - verify_downloaded_file_hash(fs, tool_data.url, download_path, tool_data.sha512); + case HashPrognosis::Success: + if (!Strings::case_insensitive_ascii_equals(tool_data.sha512, hash_result.hash)) + { + Checks::msg_exit_with_message(VCPKG_LINE_INFO, + LocalizedString::from_raw(download_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgToolHashMismatch, + msg::tool_name = tool_data.name, + msg::expected = tool_data.sha512, + msg::actual = hash_result.hash)); + } + + break; + case HashPrognosis::FileNotFound: + if (!download_file_asset_cached(console_diagnostic_context, + null_sink, + asset_cache_settings, + fs, + tool_data.url, + {}, + download_path, + tool_data.sha512)) + { + Checks::exit_fail(VCPKG_LINE_INFO); + } + break; + case HashPrognosis::OtherError: Checks::exit_fail(VCPKG_LINE_INFO); + default: Checks::unreachable(VCPKG_LINE_INFO); } const auto tool_dir_path = tools / tool_data.tool_dir_subpath; @@ -756,12 +887,6 @@ namespace vcpkg return exe_path; } - const std::string& get_config_contents() const - { - return xml_config_contents.get_lazy( - [this]() { return this->fs.read_contents(this->xml_config, VCPKG_LINE_INFO); }); - } - virtual const Path& get_tool_path(StringView tool, MessageSink& status_sink) const override { return get_tool_pathversion(tool, status_sink).p; @@ -773,9 +898,7 @@ namespace vcpkg get_environment_variable(EnvironmentVariableVcpkgForceSystemBinaries).has_value(); const bool env_force_download_binaries = get_environment_variable(EnvironmentVariableVcpkgForceDownloadedBinaries).has_value(); - const auto maybe_tool_data = - parse_tool_data_from_xml(get_config_contents(), xml_config, tool.tool_data_name()); - + const auto maybe_tool_data = get_tool_data(load_tool_data(), tool.tool_data_name()); const bool download_available = maybe_tool_data.has_value() && !maybe_tool_data.get()->url.empty(); // search for system searchable tools unless forcing downloads and download available const auto system_exe_stems = tool.system_exe_stems(); @@ -793,7 +916,7 @@ namespace vcpkg if (auto tool_data = maybe_tool_data.get()) { - // If there is an entry for the tool in vcpkgTools.xml, use that version as the minimum + // If there is an entry for the tool in vcpkg-tools.json, use that version as the minimum min_version = tool_data->version; if (consider_downloads) @@ -907,7 +1030,6 @@ namespace vcpkg 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); @@ -917,6 +1039,10 @@ namespace vcpkg if (tool == Tools::COSCLI) return get_path(CosCliProvider(), status_sink); if (tool == Tools::PYTHON3) return get_path(Python3Provider(), status_sink); if (tool == Tools::PYTHON3_WITH_VENV) return get_path(Python3WithVEnvProvider(), status_sink); + if (tool == Tools::SEVEN_ZIP || tool == Tools::SEVEN_ZIP_ALT) + { + return get_path(SevenZipProvider(), status_sink); + } if (tool == Tools::TAR) { return {find_system_tar(fs).value_or_exit(VCPKG_LINE_INFO), {}}; @@ -934,6 +1060,18 @@ namespace vcpkg { return get_tool_pathversion(tool, status_sink).version; } + + std::vector load_tool_data() const + { + return m_tool_data_cache.get_lazy([&]() { + auto maybe_tool_data = parse_tool_data_file(fs, config_path); + if (auto tool_data = maybe_tool_data.get()) + { + return std::move(*tool_data); + } + Checks::msg_exit_with_error(VCPKG_LINE_INFO, maybe_tool_data.error()); + }); + } }; ExpectedL find_system_tar(const ReadOnlyFilesystem& fs) @@ -1004,13 +1142,127 @@ namespace vcpkg } std::unique_ptr get_tool_cache(const Filesystem& fs, - std::shared_ptr downloader, + const AssetCachingSettings& asset_cache_settings, Path downloads, - Path xml_config, + Path config_path, Path tools, RequireExactVersions abiToolVersionHandling) { return std::make_unique( - fs, std::move(downloader), downloads, xml_config, tools, abiToolVersionHandling); + fs, asset_cache_settings, downloads, config_path, tools, abiToolVersionHandling); } + + struct ToolDataEntryDeserializer final : Json::IDeserializer + { + virtual LocalizedString type_name() const override { return msg::format(msgAToolDataObject); } + + virtual View valid_fields() const noexcept override + { + static const StringLiteral fields[] = { + JsonIdName, + JsonIdOS, + JsonIdVersion, + JsonIdArch, + JsonIdExecutable, + JsonIdUrl, + JsonIdSha512, + JsonIdArchive, + }; + return fields; + } + + virtual Optional visit_object(Json::Reader& r, const Json::Object& obj) const override + { + ToolDataEntry value; + + r.required_object_field( + type_name(), obj, JsonIdName, value.tool, Json::UntypedStringDeserializer::instance); + r.required_object_field(type_name(), obj, JsonIdOS, value.os, ToolOsDeserializer::instance); + r.required_object_field(type_name(), obj, JsonIdVersion, value.version, ToolVersionDeserializer::instance); + + r.optional_object_field(obj, JsonIdArch, value.arch, Json::ArchitectureDeserializer::instance); + r.optional_object_field( + obj, JsonIdExecutable, value.exeRelativePath, Json::UntypedStringDeserializer::instance); + r.optional_object_field(obj, JsonIdUrl, value.url, Json::UntypedStringDeserializer::instance); + r.optional_object_field(obj, JsonIdSha512, value.sha512, Json::Sha512Deserializer::instance); + r.optional_object_field(obj, JsonIdArchive, value.archiveName, Json::UntypedStringDeserializer::instance); + return value; + } + + static const ToolDataEntryDeserializer instance; + }; + const ToolDataEntryDeserializer ToolDataEntryDeserializer::instance; + + struct ToolDataArrayDeserializer final : Json::ArrayDeserializer + { + virtual LocalizedString type_name() const override { return msg::format(msgAToolDataArray); } + + static const ToolDataArrayDeserializer instance; + }; + const ToolDataArrayDeserializer ToolDataArrayDeserializer::instance; + + LocalizedString ToolDataFileDeserializer::type_name() const { return msg::format(msgAToolDataFile); } + + View ToolDataFileDeserializer::valid_fields() const noexcept + { + static constexpr StringLiteral valid_fields[] = {JsonIdSchemaVersion, JsonIdTools}; + return valid_fields; + } + + Optional> ToolDataFileDeserializer::visit_object(Json::Reader& r, + const Json::Object& obj) const + { + int schema_version = -1; + r.required_object_field( + type_name(), obj, JsonIdSchemaVersion, schema_version, Json::NaturalNumberDeserializer::instance); + + std::vector value; + if (schema_version == 1) + { + r.required_object_field(type_name(), obj, JsonIdTools, value, ToolDataArrayDeserializer::instance); + } + else + { + r.add_generic_error(type_name(), + msg::format(msgToolDataFileSchemaVersionNotSupported, msg::version = schema_version)); + } + + return value; + } + + const ToolDataFileDeserializer ToolDataFileDeserializer::instance; + + LocalizedString ToolOsDeserializer::type_name() const { return msg::format(msgAToolDataOS); } + + Optional ToolOsDeserializer::visit_string(Json::Reader& r, StringView str) const + { + auto maybe_tool_os = to_tool_os(str); + if (auto tool_os = maybe_tool_os.get()) + { + return *tool_os; + } + + r.add_generic_error( + type_name(), + msg::format(msgInvalidToolOSValue, msg::value = str, msg::expected = all_comma_separated_tool_oses())); + return ToolOs::Windows; + } + + const ToolOsDeserializer ToolOsDeserializer::instance; + + LocalizedString ToolVersionDeserializer::type_name() const { return msg::format(msgAToolDataVersion); } + + Optional ToolVersionDeserializer::visit_string(Json::Reader& r, StringView str) const + { + auto maybe_parsed = parse_tool_version_string(str); + if (auto parsed = maybe_parsed.get()) + { + return ToolVersion{*parsed, str.to_string()}; + } + + r.add_generic_error(type_name(), msg::format(msgInvalidToolVersion)); + return ToolVersion{}; + } + + const ToolVersionDeserializer ToolVersionDeserializer::instance; } diff --git a/src/vcpkg/triplet.cpp b/src/vcpkg/triplet.cpp index ba5060eccd..efc3aeebaf 100644 --- a/src/vcpkg/triplet.cpp +++ b/src/vcpkg/triplet.cpp @@ -47,62 +47,19 @@ namespace vcpkg Optional Triplet::guess_architecture() const noexcept { - if (Strings::starts_with(this->canonical_name(), "x86-")) + StringView canonical = this->canonical_name(); + auto dash = std::find(canonical.begin(), canonical.end(), '-'); + if (dash != canonical.end()) { - return CPUArchitecture::X86; - } - if (Strings::starts_with(this->canonical_name(), "x64-")) - { - return CPUArchitecture::X64; - } - if (Strings::starts_with(this->canonical_name(), "arm-")) - { - return CPUArchitecture::ARM; - } - if (Strings::starts_with(this->canonical_name(), "arm64-")) - { - return CPUArchitecture::ARM64; - } - if (Strings::starts_with(this->canonical_name(), "arm64ec-")) - { - return CPUArchitecture::ARM64EC; - } - if (Strings::starts_with(this->canonical_name(), "s390x-")) - { - return CPUArchitecture::S390X; - } - if (Strings::starts_with(this->canonical_name(), "ppc64le-")) - { - return CPUArchitecture::PPC64LE; - } - if (Strings::starts_with(this->canonical_name(), "riscv32-")) - { - return CPUArchitecture::RISCV32; - } - if (Strings::starts_with(this->canonical_name(), "riscv64-")) - { - return CPUArchitecture::RISCV64; - } - if (Strings::starts_with(this->canonical_name(), "loongarch32-")) - { - return CPUArchitecture::LOONGARCH32; - } - if (Strings::starts_with(this->canonical_name(), "loongarch64-")) - { - return CPUArchitecture::LOONGARCH64; - } - if (Strings::starts_with(this->canonical_name(), "mips64-")) - { - return CPUArchitecture::MIPS64; + canonical = StringView{canonical.begin(), dash}; } - return nullopt; + return to_cpu_architecture(canonical); } static std::string system_triplet_canonical_name() { - auto host_proc = get_host_processor(); - return fmt::format("{}-{}", to_zstring_view(host_proc), get_host_os_name()); + return fmt::format("{}-{}", get_host_processor(), get_host_os_name()); } Triplet default_triplet(const VcpkgCmdArguments& args, const TripletDatabase& database) diff --git a/src/vcpkg/vcpkgcmdarguments.cpp b/src/vcpkg/vcpkgcmdarguments.cpp index 446466079d..ffd8667bee 100644 --- a/src/vcpkg/vcpkgcmdarguments.cpp +++ b/src/vcpkg/vcpkgcmdarguments.cpp @@ -15,55 +15,62 @@ namespace { using namespace vcpkg; - constexpr std::pair KNOWN_CI_VARIABLES[]{ + struct CIRecord + { + StringLiteral env_var; + StringLiteral name; + CIKind type; + }; + + constexpr CIRecord KNOWN_CI_VARIABLES[]{ // Opt-out from CI detection - {EnvironmentVariableVcpkgNoCi, "VCPKG_NO_CI"}, + {EnvironmentVariableVcpkgNoCi, "VCPKG_NO_CI", CIKind::None}, // Azure Pipelines // https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables#system-variables - {EnvironmentVariableTfBuild, "Azure_Pipelines"}, + {EnvironmentVariableTfBuild, "Azure_Pipelines", CIKind::AzurePipelines}, // AppVeyor // https://www.appveyor.com/docs/environment-variables/ - {EnvironmentVariableAppveyor, "AppVeyor"}, + {EnvironmentVariableAppveyor, "AppVeyor", CIKind::AppVeyor}, // AWS Code Build // https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html - {EnvironmentVariableCodebuildBuildId, "AWS_CodeBuild"}, + {EnvironmentVariableCodebuildBuildId, "AWS_CodeBuild", CIKind::AwsCodeBuild}, // CircleCI // https://circleci.com/docs/env-vars#built-in-environment-variables - {EnvironmentVariableCircleCI, "Circle_CI"}, + {EnvironmentVariableCircleCI, "Circle_CI", CIKind::CircleCI}, // GitHub Actions // https://docs.github.com/en/actions/learn-github-actions/ - {EnvironmentVariableGitHubActions, "GitHub_Actions"}, + {EnvironmentVariableGitHubActions, "GitHub_Actions", CIKind::GithubActions}, // GitLab // https://docs.gitlab.com/ee/ci/variables/predefined_variables.html - {EnvironmentVariableGitLabCI, "GitLab_CI"}, + {EnvironmentVariableGitLabCI, "GitLab_CI", CIKind::GitLabCI}, // Heroku // https://devcenter.heroku.com/articles/heroku-ci#immutable-environment-variables - {EnvironmentVariableHerokuTestRunId, "Heroku_CI"}, + {EnvironmentVariableHerokuTestRunId, "Heroku_CI", CIKind::HerokuCI}, // Jenkins // https://wiki.jenkins.io/display/JENKINS/Building+a+software+project#Buildingasoftwareproject-belowJenkinsSetEnvironmentVariables - {EnvironmentVariableJenkinsHome, "Jenkins_CI"}, - {EnvironmentVariableJenkinsUrl, "Jenkins_CI"}, + {EnvironmentVariableJenkinsHome, "Jenkins_CI", CIKind::JenkinsCI}, + {EnvironmentVariableJenkinsUrl, "Jenkins_CI", CIKind::JenkinsCI}, // TeamCity // https://www.jetbrains.com/help/teamcity/predefined-build-parameters.html#Predefined+Server+Build+Parameters - {EnvironmentVariableTeamcityVersion, "TeamCity_CI"}, + {EnvironmentVariableTeamcityVersion, "TeamCity_CI", CIKind::TeamCityCI}, // Travis CI // https://docs.travis-ci.com/user/environment-variables/#default-environment-variables - {EnvironmentVariableTravis, "Travis_CI"}, + {EnvironmentVariableTravis, "Travis_CI", CIKind::TravisCI}, // Generic CI environment variables - {EnvironmentVariableCI, "Generic"}, - {EnvironmentVariableBuildId, "Generic"}, - {EnvironmentVariableBuildNumber, "Generic"}, + {EnvironmentVariableCI, "Generic", CIKind::Generic}, + {EnvironmentVariableBuildId, "Generic", CIKind::Generic}, + {EnvironmentVariableBuildNumber, "Generic", CIKind::Generic}, }; constexpr StringLiteral KNOWN_CI_REPOSITORY_IDENTIFIERS[] = { @@ -358,6 +365,7 @@ namespace vcpkg args.parser.parse_option( SwitchBuiltinRegistryVersionsDir, StabilityTag::Experimental, args.builtin_registry_versions_dir); args.parser.parse_option(SwitchRegistriesCache, StabilityTag::Experimental, args.registries_cache_dir); + args.parser.parse_option(SwitchToolDataFile, StabilityTag::ImplementationDetail, args.tools_data_file); args.parser.parse_option(SwitchAssetSources, StabilityTag::Experimental, args.asset_sources_template_arg, @@ -379,7 +387,7 @@ namespace vcpkg SwitchOverlayPorts, StabilityTag::Standard, args.cli_overlay_ports, - msg::format(msgOverlayPortsDirectoriesHelp, + msg::format(msgOverlayPortsHelp, msg::env_var = format_environment_variable(EnvironmentVariableVcpkgOverlayPorts))); args.parser.parse_multi_option( SwitchOverlayTriplets, @@ -580,9 +588,10 @@ namespace vcpkg // detect whether we are running in a CI environment for (auto&& ci_env_var : KNOWN_CI_VARIABLES) { - if (get_env(ci_env_var.first).has_value()) + if (get_env(ci_env_var.env_var).has_value()) { - m_detected_ci_environment = ci_env_var.second; + m_detected_ci_environment_name = ci_env_var.name; + m_detected_ci_environment_type = ci_env_var.type; break; } } @@ -789,7 +798,7 @@ namespace vcpkg void VcpkgCmdArguments::track_environment_metrics() const { MetricsSubmission submission; - if (auto ci_env = m_detected_ci_environment.get()) + if (auto ci_env = m_detected_ci_environment_name.get()) { Debug::println("Detected CI environment: ", *ci_env); submission.track_string(StringMetric::DetectedCiEnvironment, *ci_env); diff --git a/src/vcpkg/vcpkglib.cpp b/src/vcpkg/vcpkglib.cpp index 38923d69bd..a4ddbddffe 100644 --- a/src/vcpkg/vcpkglib.cpp +++ b/src/vcpkg/vcpkglib.cpp @@ -57,9 +57,7 @@ namespace vcpkg const auto status_file = installed.vcpkg_dir_status_file(); const auto status_file_new = Path(status_file.parent_path()) / FileStatusNew; fs.write_contents(status_file_new, Strings::serialize(current_status_db), VCPKG_LINE_INFO); - fs.rename(status_file_new, status_file, VCPKG_LINE_INFO); - for (auto&& file : update_files) { fs.remove(file, VCPKG_LINE_INFO); @@ -70,25 +68,15 @@ namespace vcpkg StatusParagraphs database_load(const ReadOnlyFilesystem& fs, const InstalledPaths& installed) { const auto maybe_status_file = installed.vcpkg_dir_status_file(); - const auto status_parent = Path(maybe_status_file.parent_path()); - const auto status_file_old = status_parent / FileStatusOld; - - auto status_file = &maybe_status_file; - if (!fs.exists(maybe_status_file, IgnoreErrors{})) { - if (!fs.exists(status_file_old, IgnoreErrors{})) - { - // no status file, use empty db - StatusParagraphs current_status_db; - (void)apply_database_updates(fs, current_status_db, installed.vcpkg_dir_updates()); - return current_status_db; - } - - status_file = &status_file_old; + // no status file, use empty db + StatusParagraphs current_status_db; + (void)apply_database_updates(fs, current_status_db, installed.vcpkg_dir_updates()); + return current_status_db; } - StatusParagraphs current_status_db = load_current_database(fs, *status_file); + StatusParagraphs current_status_db = load_current_database(fs, maybe_status_file); (void)apply_database_updates(fs, current_status_db, installed.vcpkg_dir_updates()); return current_status_db; } @@ -103,20 +91,12 @@ namespace vcpkg fs.create_directory(updates_dir, VCPKG_LINE_INFO); const auto status_file = installed.vcpkg_dir_status_file(); - const auto status_parent = Path(status_file.parent_path()); - const auto status_file_old = status_parent / FileStatusOld; - if (!fs.exists(status_file, IgnoreErrors{})) { - if (!fs.exists(status_file_old, IgnoreErrors{})) - { - // no status file, use empty db - StatusParagraphs current_status_db; - apply_database_updates_on_disk(fs, installed, current_status_db); - return current_status_db; - } - - fs.rename(status_file_old, status_file, VCPKG_LINE_INFO); + // no status file, use empty db + StatusParagraphs current_status_db; + apply_database_updates_on_disk(fs, installed, current_status_db); + return current_status_db; } StatusParagraphs current_status_db = load_current_database(fs, status_file); @@ -148,7 +128,7 @@ namespace vcpkg return false; // File already in the new format } - if (was_tracked.exchange(true)) + if (!was_tracked.exchange(true)) { get_global_metrics_collector().track_string(StringMetric::ListFile, "update to new format"); } diff --git a/src/vcpkg/vcpkgpaths.cpp b/src/vcpkg/vcpkgpaths.cpp index fe7748d6ca..f92dd29126 100644 --- a/src/vcpkg/vcpkgpaths.cpp +++ b/src/vcpkg/vcpkgpaths.cpp @@ -99,29 +99,46 @@ namespace } static void append_overlays(std::vector& result, + const ReadOnlyFilesystem& fs, const std::vector& overlay_entries, - const Path& relative_root) + const Path& relative_root, + const Path& config_directory, + bool forbid_dot) { for (auto&& entry : overlay_entries) { - result.push_back(relative_root / entry); + if (forbid_dot && entry == ".") + { + Checks::msg_exit_with_error(VCPKG_LINE_INFO, msgErrorManifestMustDifferFromOverlayDot); + } + + auto full_entry = relative_root / entry; + if (forbid_dot && (fs.almost_canonical(full_entry, VCPKG_LINE_INFO) / "") == (config_directory / "")) + { + Checks::msg_exit_with_error( + VCPKG_LINE_INFO, msgErrorManifestMustDifferFromOverlay, msg::path = config_directory); + } + + result.push_back(std::move(full_entry)); } } // Merges overlay settings from the 3 major sources in the usual priority order, where command line wins first, then // manifest, then environment. The parameter order is specifically chosen to group information that comes from the // manifest together and make parameter order confusion less likely to compile. - static std::vector merge_overlays(const std::vector& cli_overlays, + static std::vector merge_overlays(const ReadOnlyFilesystem& fs, + const std::vector& cli_overlays, const std::vector& env_overlays, const Path& original_cwd, + bool forbid_config_dot, const std::vector& config_overlays, const Path& config_directory) { std::vector result; result.reserve(cli_overlays.size() + config_overlays.size() + env_overlays.size()); - append_overlays(result, cli_overlays, original_cwd); - append_overlays(result, config_overlays, config_directory); - append_overlays(result, env_overlays, original_cwd); + append_overlays(result, fs, cli_overlays, original_cwd, config_directory, false); + append_overlays(result, fs, config_overlays, config_directory, config_directory, forbid_config_dot); + append_overlays(result, fs, env_overlays, original_cwd, config_directory, false); return result; } @@ -324,8 +341,8 @@ namespace , m_ff_settings(args.feature_flag_settings()) , m_manifest_dir(compute_manifest_dir(fs, args, original_cwd)) , m_bundle(bundle) - , m_download_manager(std::make_shared( - parse_download_configuration(args.asset_sources_template()).value_or_exit(VCPKG_LINE_INFO))) + , m_asset_cache_settings( + parse_download_configuration(args.asset_sources_template()).value_or_exit(VCPKG_LINE_INFO)) , m_builtin_ports(process_output_directory(fs, args.builtin_ports_root_dir.get(), root / "ports")) , m_default_vs_path(args.default_visual_studio_path .map([&fs](const std::string& default_visual_studio_path) { @@ -342,7 +359,7 @@ namespace const FeatureFlagSettings m_ff_settings; const Path m_manifest_dir; const BundleSettings m_bundle; - const std::shared_ptr m_download_manager; + const AssetCachingSettings m_asset_cache_settings; const Path m_builtin_ports; const Path m_default_vs_path; const Path scripts; @@ -546,8 +563,6 @@ namespace vcpkg , m_global_config(bundle.read_only ? get_user_configuration_home().value_or_exit(VCPKG_LINE_INFO) / "vcpkg-configuration.json" : root / "vcpkg-configuration.json") - , m_config_dir(m_manifest_dir.empty() ? root : m_manifest_dir) - , m_manifest_path(m_manifest_dir.empty() ? Path{} : m_manifest_dir / "vcpkg.json") , m_registries_work_tree_dir(m_registries_cache / "git") , m_registries_dot_git_dir(m_registries_cache / "git" / ".git") , m_registries_git_trees(m_registries_cache / "git-trees") @@ -570,13 +585,13 @@ namespace vcpkg "packages", "pkgs", VCPKG_LINE_INFO)) - , m_tool_cache(get_tool_cache(fs, - m_download_manager, - downloads, - scripts / "vcpkgTools.xml", - tools, - args.exact_abi_tools_versions.value_or(false) ? RequireExactVersions::YES - : RequireExactVersions::NO)) + , m_tool_cache(get_tool_cache( + fs, + m_asset_cache_settings, + downloads, + args.tools_data_file.has_value() ? Path{*args.tools_data_file.get()} : scripts / "vcpkg-tools.json", + tools, + args.exact_abi_tools_versions.value_or(false) ? RequireExactVersions::YES : RequireExactVersions::NO)) , m_env_cache(m_ff_settings.compiler_tracking) , triplets_dirs() , m_artifacts_dir(downloads / "artifacts") @@ -628,8 +643,6 @@ namespace vcpkg } const Path m_global_config; - const Path m_config_dir; - const Path m_manifest_path; const Path m_registries_work_tree_dir; const Path m_registries_dot_git_dir; const Path m_registries_git_trees; @@ -670,32 +683,29 @@ namespace vcpkg Debug::print("Using vcpkg-root: ", root, '\n'); Debug::print("Using builtin-registry: ", builtin_registry_versions, '\n'); Debug::print("Using downloads-root: ", downloads, '\n'); - m_pimpl->m_download_manager->get_block_origin() - ? Debug::println("External asset downloads are blocked (x-block-origin is enabled)..") - : Debug::println("External asset downloads are allowed (x-block-origin is disabled)..."); - m_pimpl->m_download_manager->asset_cache_configured() ? Debug::println("Asset caching is enabled.") - : Debug::println("Asset cache is not configured."); - const auto config_path = m_pimpl->m_config_dir / "vcpkg-configuration.json"; + auto config_dir = m_pimpl->m_manifest_dir.empty() ? root : m_pimpl->m_manifest_dir; + const auto config_path = config_dir / "vcpkg-configuration.json"; auto maybe_manifest_config = config_from_manifest(m_pimpl->m_manifest_doc); auto maybe_json_config = filesystem.exists(config_path, IgnoreErrors{}) ? parse_configuration(filesystem.read_contents(config_path, IgnoreErrors{}), config_path, out_sink) : nullopt; - m_pimpl->m_config = merge_validate_configs(std::move(maybe_manifest_config), - m_pimpl->m_manifest_dir, - std::move(maybe_json_config), - m_pimpl->m_config_dir, - *this); - overlay_ports = merge_overlays(args.cli_overlay_ports, - args.env_overlay_ports, - original_cwd, - m_pimpl->m_config.config.overlay_ports, - m_pimpl->m_config.directory); - overlay_triplets = merge_overlays(args.cli_overlay_triplets, + m_pimpl->m_config = merge_validate_configs( + std::move(maybe_manifest_config), m_pimpl->m_manifest_dir, std::move(maybe_json_config), config_dir, *this); + overlay_ports.overlay_ports = merge_overlays(m_pimpl->m_fs, + args.cli_overlay_ports, + args.env_overlay_ports, + original_cwd, + true, + m_pimpl->m_config.config.overlay_ports, + m_pimpl->m_config.directory); + overlay_triplets = merge_overlays(m_pimpl->m_fs, + args.cli_overlay_triplets, args.env_overlay_triplets, original_cwd, + false, m_pimpl->m_config.config.overlay_triplets, m_pimpl->m_config.directory); for (const auto& triplet : this->overlay_triplets) @@ -884,7 +894,7 @@ namespace vcpkg } const Filesystem& VcpkgPaths::get_filesystem() const { return m_pimpl->m_fs; } - const DownloadManager& VcpkgPaths::get_download_manager() const { return *m_pimpl->m_download_manager; } + const AssetCachingSettings& VcpkgPaths::get_asset_cache_settings() const { return m_pimpl->m_asset_cache_settings; } const ToolCache& VcpkgPaths::get_tool_cache() const { return *m_pimpl->m_tool_cache; } const Path& VcpkgPaths::get_tool_exe(StringView tool, MessageSink& status_messages) const { @@ -1259,7 +1269,7 @@ namespace vcpkg return nullopt; } - bool VcpkgPaths::manifest_mode_enabled() const { return !m_pimpl->m_manifest_dir.empty(); } + bool VcpkgPaths::manifest_mode_enabled() const { return m_pimpl->m_manifest_doc.has_value(); } const ConfigurationAndSource& VcpkgPaths::get_configuration() const { return m_pimpl->m_config; } diff --git a/src/vcpkg/versiondeserializers.cpp b/src/vcpkg/versiondeserializers.cpp index b14cde2c74..32c3be8720 100644 --- a/src/vcpkg/versiondeserializers.cpp +++ b/src/vcpkg/versiondeserializers.cpp @@ -261,13 +261,6 @@ namespace vcpkg return Version(std::move(proto_version.first), port_version); } - View schemed_deserializer_fields() - { - static constexpr StringView t[] = { - JsonIdVersion, JsonIdVersionSemver, JsonIdVersionString, JsonIdVersionDate, JsonIdPortVersion}; - return t; - } - void serialize_schemed_version(Json::Object& out_obj, VersionScheme scheme, const Version& version) { auto version_field = [](VersionScheme version_scheme) { diff --git a/src/vcpkg/versions.cpp b/src/vcpkg/versions.cpp index 00c1dd26e4..0ffb62b5b1 100644 --- a/src/vcpkg/versions.cpp +++ b/src/vcpkg/versions.cpp @@ -52,11 +52,11 @@ namespace vcpkg return Version{StringView{content.begin(), hash}, port_version}; } - bool operator==(const Version& left, const Version& right) + bool operator==(const Version& left, const Version& right) noexcept { return left.text == right.text && left.port_version == right.port_version; } - bool operator!=(const Version& left, const Version& right) { return !(left == right); } + bool operator!=(const Version& left, const Version& right) noexcept { return !(left == right); } bool VersionMapLess::operator()(const Version& left, const Version& right) const { @@ -384,12 +384,12 @@ namespace vcpkg { } - bool operator==(const SchemedVersion& lhs, const SchemedVersion& rhs) + bool operator==(const SchemedVersion& lhs, const SchemedVersion& rhs) noexcept { return lhs.scheme == rhs.scheme && lhs.version == rhs.version; } - bool operator!=(const SchemedVersion& lhs, const SchemedVersion& rhs) { return !(lhs == rhs); } + bool operator!=(const SchemedVersion& lhs, const SchemedVersion& rhs) noexcept { return !(lhs == rhs); } StringLiteral to_string_literal(VersionScheme scheme) { diff --git a/src/vcpkg/visualstudio.cpp b/src/vcpkg/visualstudio.cpp index 78ddf629c2..e11f08d07e 100644 --- a/src/vcpkg/visualstudio.cpp +++ b/src/vcpkg/visualstudio.cpp @@ -196,9 +196,8 @@ namespace vcpkg::VisualStudio const SortedVector sorted{ get_visual_studio_instances_internal(fs), VisualStudioInstance::preferred_first_comparator}; - const bool v140_is_available = Util::find_if(sorted, [&](const VisualStudioInstance& vs_instance) { - return vs_instance.major_version() == "14"; - }) != sorted.end(); + const bool v140_is_available = Util::any_of( + sorted, [&](const VisualStudioInstance& vs_instance) { return vs_instance.major_version() == "14"; }); for (const VisualStudioInstance& vs_instance : sorted) { diff --git a/vcpkg-init/mint-standalone-bundle.ps1 b/vcpkg-init/mint-standalone-bundle.ps1 index 0b9816311d..b4faa0c6c6 100644 --- a/vcpkg-init/mint-standalone-bundle.ps1 +++ b/vcpkg-init/mint-standalone-bundle.ps1 @@ -47,13 +47,15 @@ $scripts_dependencies = @( 'vcpkg_completion.bash', 'vcpkg_completion.fish', 'vcpkg_completion.zsh', - 'vcpkgTools.xml' + 'vcpkg-tools.json' ) $scripts_exclusions = @( - 'buildsystems/msbuild/applocal.ps1', - 'posh-vcpkg/0.0.1/posh-vcpkg.psm1', - 'posh-vcpkg/0.0.1/posh-vcpkg.psd1' + 'buildsystems/msbuild/applocal.ps1' + 'posh-vcpkg/0.0.1/posh-vcpkg.psm1' # deprecated, waiting for migration + 'posh-vcpkg/0.0.1/posh-vcpkg.psd1' # deprecated, waiting for migration + 'posh-vcpkg/posh-vcpkg.psm1' + 'posh-vcpkg/posh-vcpkg.psd1' ) if (Test-Path $TempDir) { @@ -73,7 +75,9 @@ try { Move-Item 'LICENSE.txt' '../out/LICENSE.txt' Move-Item 'triplets' '../out/triplets' foreach ($exclusion in $scripts_exclusions) { - Remove-Item "scripts/$exclusion" -Recurse -Force + if (Test-Path "scripts/$exclusion") { + Remove-Item "scripts/$exclusion" -Recurse -Force + } } foreach ($dep in $scripts_dependencies) { Move-Item "scripts/$dep" "../out/scripts/$dep" @@ -101,9 +105,10 @@ try { Set-Content -Path "out/scripts/buildsystems/msbuild/vcpkg.props" -Value $propsContent -NoNewline -Encoding Ascii Copy-Item -Path "$PSScriptRoot/vcpkg.targets" -Destination 'out/scripts/buildsystems/msbuild/vcpkg.targets' - New-Item -Path 'out/scripts/posh-vcpkg/0.0.1' -ItemType 'Directory' -Force - Copy-Item -Path "$ArchIndependentSignedFilesRoot/scripts/posh-vcpkg.psm1" -Destination 'out/scripts/posh-vcpkg/0.0.1/posh-vcpkg.psm1' - Copy-Item -Path "$ArchIndependentSignedFilesRoot/scripts/posh-vcpkg.psd1" -Destination 'out/scripts/posh-vcpkg/0.0.1/posh-vcpkg.psd1' + + New-Item -Path 'out/scripts/posh-vcpkg/' -ItemType 'Directory' -Force + Copy-Item -Path "$ArchIndependentSignedFilesRoot/scripts/posh-vcpkg.psm1" -Destination 'out/scripts/posh-vcpkg/posh-vcpkg.psm1' + Copy-Item -Path "$ArchIndependentSignedFilesRoot/scripts/posh-vcpkg.psd1" -Destination 'out/scripts/posh-vcpkg/posh-vcpkg.psd1' Copy-Item -Path "$ArchIndependentSignedFilesRoot/vcpkg-artifacts" -Destination 'out/vcpkg-artifacts' -Recurse diff --git a/vcpkg-init/vcpkg-scripts-sha.txt b/vcpkg-init/vcpkg-scripts-sha.txt index c643ac7793..7b286d0a47 100644 --- a/vcpkg-init/vcpkg-scripts-sha.txt +++ b/vcpkg-init/vcpkg-scripts-sha.txt @@ -1 +1 @@ -d033613d9021107e4a7b52c5fac1f87ae8a6fcc6 +5c41ff21f6feda702a7d5a1afc765f88d25783c5