From 779ab31a432542a9451ac8fcb1edee999fb94f8e Mon Sep 17 00:00:00 2001 From: Billy O'Neal Date: Fri, 21 Jun 2024 17:15:37 -0700 Subject: [PATCH] Teach x-ci-verify-versions to check that versions exist in the database (#1210) --- .../.gitattributes | 1 + .../bad-git-tree-1.0/portfile.cmake | 1 + .../bad-git-tree-1.0/vcpkg.json | 4 + .../bad-history-name-1.0/portfile.cmake | 1 + .../bad-history-name-1.0/vcpkg.json | 4 + .../portfile.cmake | 1 + .../baseline-version-mismatch-1.0/vcpkg.json | 4 + .../has-local-edits/portfile.cmake | 1 + .../has-local-edits/vcpkg.json | 4 + .../malformed-1.0/portfile.cmake | 1 + .../malformed-1.0/vcpkg.json | 5 + .../mismatch-git-tree-1.0/portfile.cmake | 1 + .../mismatch-git-tree-1.0/vcpkg.json | 4 + .../version-mismatch-1.0/portfile.cmake | 1 + .../version-mismatch-1.0/vcpkg.json | 4 + .../version-missing-1.0/portfile.cmake | 1 + .../version-missing-1.0/vcpkg.json | 4 + .../portfile.cmake | 1 + .../version-scheme-mismatch-1.0/vcpkg.json | 4 + .../ports/bad-git-tree/portfile.cmake | 1 + .../ports/bad-git-tree/vcpkg.json | 4 + .../ports/bad-history-name/portfile.cmake | 1 + .../ports/bad-history-name/vcpkg.json | 4 + .../baseline-version-mismatch/portfile.cmake | 1 + .../baseline-version-mismatch/vcpkg.json | 4 + .../baseline-version-missing/portfile.cmake | 1 + .../ports/baseline-version-missing/vcpkg.json | 4 + .../portfile.cmake | 1 + .../vcpkg.json | 12 + .../portfile.cmake | 1 + .../vcpkg.json | 7 + .../portfile.cmake | 1 + .../vcpkg.json | 15 + .../portfile.cmake | 1 + .../vcpkg.json | 10 + .../ports/good/portfile.cmake | 1 + .../ports/good/vcpkg.json | 4 + .../ports/malformed/portfile.cmake | 1 + .../ports/malformed/vcpkg.json | 5 + .../ports/mismatch-git-tree/portfile.cmake | 1 + .../ports/mismatch-git-tree/vcpkg.json | 5 + .../ports/no-versions/portfile.cmake | 1 + .../ports/no-versions/vcpkg.json | 4 + .../portfile.cmake | 1 + .../vcpkg.json | 10 + .../portfile.cmake | 1 + .../vcpkg.json | 10 + .../ports/version-mismatch/portfile.cmake | 1 + .../ports/version-mismatch/vcpkg.json | 4 + .../ports/version-missing/portfile.cmake | 1 + .../ports/version-missing/vcpkg.json | 4 + .../version-scheme-mismatch/portfile.cmake | 1 + .../ports/version-scheme-mismatch/vcpkg.json | 4 + .../versions/b-/bad-git-tree.json | 14 + .../versions/b-/bad-history-name.json | 14 + .../b-/baseline-version-mismatch.json | 14 + .../versions/b-/baseline-version-missing.json | 9 + .../versions/baseline.json | 76 ++ ...ency-not-in-versions-database-feature.json | 9 + .../dependency-not-in-versions-database.json | 9 + ...sion-not-in-versions-database-feature.json | 9 + ...ency-version-not-in-versions-database.json | 9 + .../versions/g-/good.json | 9 + .../versions/h-/has-local-edits.json | 9 + .../versions/m-/malformed.json | 14 + .../versions/m-/mismatch-git-tree.json | 9 + .../o-/override-not-in-versions-database.json | 9 + ...ride-version-not-in-versions-database.json | 9 + .../versions/v-/version-mismatch.json | 14 + .../versions/v-/version-missing.json | 9 + .../versions/v-/version-scheme-mismatch.json | 14 + .../e2e-ports/versions/baseline.json | 5 - .../v-/vcpkg-internal-e2e-test-port.json | 8 - .../ci-verify-versions.ps1 | 176 ++++ include/vcpkg/base/expected.h | 12 + include/vcpkg/base/jsonreader.h | 2 + include/vcpkg/base/message-data.inc.h | 206 ++--- include/vcpkg/base/util.h | 6 + include/vcpkg/fwd/sourceparagraph.h | 2 +- include/vcpkg/paragraphs.h | 23 +- include/vcpkg/registries.h | 50 +- locales/messages.json | 111 +-- src/vcpkg/base/downloads.cpp | 4 +- src/vcpkg/base/json.cpp | 16 + src/vcpkg/commands.add-version.cpp | 46 +- src/vcpkg/commands.add.cpp | 9 +- src/vcpkg/commands.autocomplete.cpp | 2 +- src/vcpkg/commands.ci-verify-versions.cpp | 749 ++++++++++++------ src/vcpkg/commands.format-manifest.cpp | 195 ++--- src/vcpkg/commands.install.cpp | 10 +- src/vcpkg/paragraphs.cpp | 92 ++- src/vcpkg/portfileprovider.cpp | 36 +- src/vcpkg/registries.cpp | 545 +++++++------ src/vcpkg/vcpkgpaths.cpp | 16 +- 94 files changed, 1876 insertions(+), 878 deletions(-) create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/.gitattributes create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-git-tree-1.0/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-git-tree-1.0/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-history-name-1.0/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-history-name-1.0/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/baseline-version-mismatch-1.0/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/baseline-version-mismatch-1.0/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/has-local-edits/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/has-local-edits/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/malformed-1.0/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/malformed-1.0/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/mismatch-git-tree-1.0/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/mismatch-git-tree-1.0/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-mismatch-1.0/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-mismatch-1.0/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-missing-1.0/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-missing-1.0/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-scheme-mismatch-1.0/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-scheme-mismatch-1.0/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-git-tree/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-git-tree/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-history-name/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-history-name/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-mismatch/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-mismatch/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-missing/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-missing/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database-feature/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database-feature/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database-feature/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database-feature/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/good/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/good/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/malformed/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/malformed/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/mismatch-git-tree/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/mismatch-git-tree/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/no-versions/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/no-versions/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-not-in-versions-database/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-not-in-versions-database/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-version-not-in-versions-database/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-version-not-in-versions-database/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-mismatch/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-mismatch/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-missing/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-missing/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-scheme-mismatch/portfile.cmake create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-scheme-mismatch/vcpkg.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/bad-git-tree.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/bad-history-name.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/baseline-version-mismatch.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/baseline-version-missing.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/baseline.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-not-in-versions-database-feature.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-not-in-versions-database.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-version-not-in-versions-database-feature.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-version-not-in-versions-database.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/g-/good.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/h-/has-local-edits.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/m-/malformed.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/m-/mismatch-git-tree.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/o-/override-not-in-versions-database.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/o-/override-version-not-in-versions-database.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-mismatch.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-missing.json create mode 100644 azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-scheme-mismatch.json delete mode 100644 azure-pipelines/e2e-ports/versions/baseline.json delete mode 100644 azure-pipelines/e2e-ports/versions/v-/vcpkg-internal-e2e-test-port.json create mode 100644 azure-pipelines/end-to-end-tests-dir/ci-verify-versions.ps1 diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/.gitattributes b/azure-pipelines/e2e-assets/ci-verify-versions-registry/.gitattributes new file mode 100644 index 0000000000..fa1385d99a --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/.gitattributes @@ -0,0 +1 @@ +* -text diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-git-tree-1.0/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-git-tree-1.0/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-git-tree-1.0/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-git-tree-1.0/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-git-tree-1.0/vcpkg.json new file mode 100644 index 0000000000..cc29e93073 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-git-tree-1.0/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "bad-git-tree", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-history-name-1.0/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-history-name-1.0/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-history-name-1.0/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-history-name-1.0/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-history-name-1.0/vcpkg.json new file mode 100644 index 0000000000..b95ea8e159 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/bad-history-name-1.0/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "bad-history-name-is-bad", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/baseline-version-mismatch-1.0/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/baseline-version-mismatch-1.0/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/baseline-version-mismatch-1.0/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/baseline-version-mismatch-1.0/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/baseline-version-mismatch-1.0/vcpkg.json new file mode 100644 index 0000000000..6fddfd04d8 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/baseline-version-mismatch-1.0/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "baseline-version-mismatch", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/has-local-edits/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/has-local-edits/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/has-local-edits/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/has-local-edits/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/has-local-edits/vcpkg.json new file mode 100644 index 0000000000..5adb003ec5 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/has-local-edits/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "has-local-edits", + "version": "1.0.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/malformed-1.0/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/malformed-1.0/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/malformed-1.0/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/malformed-1.0/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/malformed-1.0/vcpkg.json new file mode 100644 index 0000000000..fc9f86f7b9 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/malformed-1.0/vcpkg.json @@ -0,0 +1,5 @@ +{ + "name": "malformed", + "version": "1.0", + ~broken +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/mismatch-git-tree-1.0/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/mismatch-git-tree-1.0/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/mismatch-git-tree-1.0/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/mismatch-git-tree-1.0/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/mismatch-git-tree-1.0/vcpkg.json new file mode 100644 index 0000000000..e3f2c372d8 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/mismatch-git-tree-1.0/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "mismatch-git-tree", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-mismatch-1.0/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-mismatch-1.0/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-mismatch-1.0/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-mismatch-1.0/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-mismatch-1.0/vcpkg.json new file mode 100644 index 0000000000..3ee37270e8 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-mismatch-1.0/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "version-mismatch", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-missing-1.0/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-missing-1.0/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-missing-1.0/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-missing-1.0/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-missing-1.0/vcpkg.json new file mode 100644 index 0000000000..5e1d6e8427 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-missing-1.0/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "version-missing", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-scheme-mismatch-1.0/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-scheme-mismatch-1.0/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-scheme-mismatch-1.0/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-scheme-mismatch-1.0/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-scheme-mismatch-1.0/vcpkg.json new file mode 100644 index 0000000000..428c44f8a5 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/old-port-versions/version-scheme-mismatch-1.0/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "version-scheme-mismatch", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-git-tree/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-git-tree/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-git-tree/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-git-tree/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-git-tree/vcpkg.json new file mode 100644 index 0000000000..506a46ce93 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-git-tree/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "bad-git-tree", + "version": "1.1" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-history-name/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-history-name/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-history-name/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-history-name/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-history-name/vcpkg.json new file mode 100644 index 0000000000..b490211723 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/bad-history-name/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "bad-history-name", + "version": "1.1" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-mismatch/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-mismatch/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-mismatch/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-mismatch/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-mismatch/vcpkg.json new file mode 100644 index 0000000000..acb5a35f53 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-mismatch/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "baseline-version-mismatch", + "version": "1.1" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-missing/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-missing/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-missing/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-missing/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-missing/vcpkg.json new file mode 100644 index 0000000000..5b9b5b2204 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/baseline-version-missing/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "baseline-version-missing", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database-feature/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database-feature/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database-feature/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database-feature/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database-feature/vcpkg.json new file mode 100644 index 0000000000..ea2024dd89 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database-feature/vcpkg.json @@ -0,0 +1,12 @@ +{ + "name": "dependency-not-in-versions-database-feature", + "version": "1.0", + "features": { + "add-things": { + "description": "an example feature that adds some things", + "dependencies": [ + "no-versions" + ] + } + } +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database/vcpkg.json new file mode 100644 index 0000000000..4a252a2a78 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-not-in-versions-database/vcpkg.json @@ -0,0 +1,7 @@ +{ + "name": "dependency-not-in-versions-database", + "version": "1.0", + "dependencies": [ + "no-versions" + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database-feature/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database-feature/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database-feature/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database-feature/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database-feature/vcpkg.json new file mode 100644 index 0000000000..74fb7c7850 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database-feature/vcpkg.json @@ -0,0 +1,15 @@ +{ + "name": "dependency-version-not-in-versions-database-feature", + "version": "1.0", + "features": { + "add-things": { + "description": "an example feature that adds some things", + "dependencies": [ + { + "name": "good", + "version>=": "0.9" + } + ] + } + } +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database/vcpkg.json new file mode 100644 index 0000000000..f1b434486a --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database/vcpkg.json @@ -0,0 +1,10 @@ +{ + "name": "dependency-version-not-in-versions-database", + "version": "1.0", + "dependencies": [ + { + "name": "good", + "version>=": "0.9" + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/good/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/good/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/good/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/good/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/good/vcpkg.json new file mode 100644 index 0000000000..c16b969626 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/good/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "good", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/malformed/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/malformed/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/malformed/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/malformed/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/malformed/vcpkg.json new file mode 100644 index 0000000000..129f63eef9 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/malformed/vcpkg.json @@ -0,0 +1,5 @@ +{ + "name": "malformed", + "version": "1.1", + ~broken +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/mismatch-git-tree/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/mismatch-git-tree/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/mismatch-git-tree/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/mismatch-git-tree/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/mismatch-git-tree/vcpkg.json new file mode 100644 index 0000000000..2ef341b777 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/mismatch-git-tree/vcpkg.json @@ -0,0 +1,5 @@ +{ + "$comment": "This comment changes the correct git-tree without changing the version", + "name": "mismatch-git-tree", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/no-versions/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/no-versions/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/no-versions/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/no-versions/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/no-versions/vcpkg.json new file mode 100644 index 0000000000..5aa000f4de --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/no-versions/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "no-versions", + "version": "1.0" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-not-in-versions-database/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-not-in-versions-database/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-not-in-versions-database/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-not-in-versions-database/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-not-in-versions-database/vcpkg.json new file mode 100644 index 0000000000..8e88744937 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-not-in-versions-database/vcpkg.json @@ -0,0 +1,10 @@ +{ + "name": "override-not-in-versions-database", + "version": "1.0", + "overrides": [ + { + "name": "no-versions", + "version": "1.0" + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-version-not-in-versions-database/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-version-not-in-versions-database/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-version-not-in-versions-database/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-version-not-in-versions-database/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-version-not-in-versions-database/vcpkg.json new file mode 100644 index 0000000000..0043df67b2 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/override-version-not-in-versions-database/vcpkg.json @@ -0,0 +1,10 @@ +{ + "name": "override-version-not-in-versions-database", + "version": "1.0", + "overrides": [ + { + "name": "good", + "version": "0.9" + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-mismatch/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-mismatch/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-mismatch/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-mismatch/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-mismatch/vcpkg.json new file mode 100644 index 0000000000..cc609c6036 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-mismatch/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "version-mismatch", + "version": "1.1" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-missing/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-missing/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-missing/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-missing/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-missing/vcpkg.json new file mode 100644 index 0000000000..9990713c6d --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-missing/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "version-missing", + "version": "1.1" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-scheme-mismatch/portfile.cmake b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-scheme-mismatch/portfile.cmake new file mode 100644 index 0000000000..065116c276 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-scheme-mismatch/portfile.cmake @@ -0,0 +1 @@ +set(VCPKG_POLICY_EMPTY_PACKAGE enabled) diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-scheme-mismatch/vcpkg.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-scheme-mismatch/vcpkg.json new file mode 100644 index 0000000000..d71e35cc7c --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/ports/version-scheme-mismatch/vcpkg.json @@ -0,0 +1,4 @@ +{ + "name": "version-scheme-mismatch", + "version": "1.1" +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/bad-git-tree.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/bad-git-tree.json new file mode 100644 index 0000000000..2918fc4661 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/bad-git-tree.json @@ -0,0 +1,14 @@ +{ + "versions": [ + { + "git-tree": "000000070c5f496fcf1a97cf654d5e81f0d2685a", + "version": "1.1", + "port-version": 0 + }, + { + "git-tree": "00000005fb6b76058ce09252f521847363c6b266", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/bad-history-name.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/bad-history-name.json new file mode 100644 index 0000000000..e81800032e --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/bad-history-name.json @@ -0,0 +1,14 @@ +{ + "versions": [ + { + "git-tree": "f34f4ad3dfcc4d46d467d7b6aa04f9732a7951d6", + "version": "1.1", + "port-version": 0 + }, + { + "git-tree": "db9d98300e7daeb2c0652bae94a0283a1b1a13d1", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/baseline-version-mismatch.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/baseline-version-mismatch.json new file mode 100644 index 0000000000..75204c85f1 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/baseline-version-mismatch.json @@ -0,0 +1,14 @@ +{ + "versions": [ + { + "git-tree": "cf8a1faa9f94f7ceb9513d65093d407e11ac1402", + "version": "1.1", + "port-version": 0 + }, + { + "git-tree": "a6d7dde2f5a9ea80db16c7f73c43556a7e21e5cf", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/baseline-version-missing.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/baseline-version-missing.json new file mode 100644 index 0000000000..6a6605ebe9 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/b-/baseline-version-missing.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "a5c21769008f52ed66afa344f13b786dde4b8d7d", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/baseline.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/baseline.json new file mode 100644 index 0000000000..39be2d26a7 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/baseline.json @@ -0,0 +1,76 @@ +{ + "default": { + "bad-git-tree": { + "baseline": "1.1", + "port-version": 0 + }, + "bad-history-name": { + "baseline": "1.1", + "port-version": 0 + }, + "baseline-version-mismatch": { + "baseline": "1.0", + "port-version": 0 + }, + "dependency-not-in-versions-database": { + "baseline": "1.0", + "port-version": 0 + }, + "dependency-not-in-versions-database-feature": { + "baseline": "1.0", + "port-version": 0 + }, + "dependency-version-not-in-versions-database": { + "baseline": "1.0", + "port-version": 0 + }, + "dependency-version-not-in-versions-database-feature": { + "baseline": "1.0", + "port-version": 0 + }, + "empty-versions": { + "baseline": "1.0", + "port-version": 0 + }, + "good": { + "baseline": "1.0", + "port-version": 0 + }, + "has-local-edits": { + "baseline": "1.0.0", + "port-version": 0 + }, + "malformed": { + "baseline": "1.0", + "port-version": 0 + }, + "mismatch-git-tree": { + "baseline": "1.0", + "port-version": 0 + }, + "no-versions": { + "baseline": "1.0", + "port-version": 0 + }, + "override-not-in-versions-database": { + "baseline": "1.0", + "port-version": 0 + }, + "override-version-not-in-versions-database": { + "baseline": "1.0", + "port-version": 0 + }, + "version-mismatch": { + "baseline": "1.1", + "port-version": 0 + }, + "version-missing": { + "baseline": "1.1", + "port-version": 0 + }, + "version-scheme-mismatch": { + "baseline": "1.1", + "port-version": 0 + } + } +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-not-in-versions-database-feature.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-not-in-versions-database-feature.json new file mode 100644 index 0000000000..6ac3cc1b2c --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-not-in-versions-database-feature.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "2298ee25ea54ed92595250a2be07d01bdd76f47c", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-not-in-versions-database.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-not-in-versions-database.json new file mode 100644 index 0000000000..670e02ea77 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-not-in-versions-database.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "321c8b400526dc412a987285ef469eec6221a4b4", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-version-not-in-versions-database-feature.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-version-not-in-versions-database-feature.json new file mode 100644 index 0000000000..399bfc5d06 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-version-not-in-versions-database-feature.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "ba3008bb2d42c61f172b7d9592de0212edf20fc6", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-version-not-in-versions-database.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-version-not-in-versions-database.json new file mode 100644 index 0000000000..371981acf3 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/d-/dependency-version-not-in-versions-database.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "f0d44555fe7714929e432ab9e12a436e28ffef9e", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/g-/good.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/g-/good.json new file mode 100644 index 0000000000..38366a09dc --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/g-/good.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "0f3d67db0dbb6aa5499bc09367a606b495e16d35", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/h-/has-local-edits.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/h-/has-local-edits.json new file mode 100644 index 0000000000..794d49fb59 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/h-/has-local-edits.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "b1d7f6030942b329a200f16c931c01e2ec9e1e79", + "version": "1.0.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/m-/malformed.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/m-/malformed.json new file mode 100644 index 0000000000..7ad4853f4b --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/m-/malformed.json @@ -0,0 +1,14 @@ +{ + "versions": [ + { + "git-tree": "a1f22424b0fb1460200c12e1b7933f309f9c8373", + "version": "1.1", + "port-version": 0 + }, + { + "git-tree": "72b37802dbdc176ce20b718ce4a332ac38bd0116", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/m-/mismatch-git-tree.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/m-/mismatch-git-tree.json new file mode 100644 index 0000000000..3ff9b857c6 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/m-/mismatch-git-tree.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "41d20d2a02d75343b0933b624faf9f061b112dad", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/o-/override-not-in-versions-database.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/o-/override-not-in-versions-database.json new file mode 100644 index 0000000000..33d069fb05 --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/o-/override-not-in-versions-database.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "0ff80cd22d5ca881efab3329ce596566a8642bec", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/o-/override-version-not-in-versions-database.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/o-/override-version-not-in-versions-database.json new file mode 100644 index 0000000000..ac1bb00cad --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/o-/override-version-not-in-versions-database.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "49fafaad46408296e50e9d0fd1a3d531bf97d420", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-mismatch.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-mismatch.json new file mode 100644 index 0000000000..9328f1244a --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-mismatch.json @@ -0,0 +1,14 @@ +{ + "versions": [ + { + "git-tree": "220bdcf2d4836ec9fe867eaff2945b58c08f5618", + "version": "1.1-a", + "port-version": 0 + }, + { + "git-tree": "5c1a69be3303fcd085d473d10e311b85202ee93c", + "version": "1.0-a", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-missing.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-missing.json new file mode 100644 index 0000000000..5a73a4d89b --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-missing.json @@ -0,0 +1,9 @@ +{ + "versions": [ + { + "git-tree": "d3b4c8bf4bee7654f63b223a442741bb16f45957", + "version": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-scheme-mismatch.json b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-scheme-mismatch.json new file mode 100644 index 0000000000..a24ba4b01a --- /dev/null +++ b/azure-pipelines/e2e-assets/ci-verify-versions-registry/versions/v-/version-scheme-mismatch.json @@ -0,0 +1,14 @@ +{ + "versions": [ + { + "git-tree": "ea2006a1188b81f1f2f6e0aba9bef236d1fb2725", + "version-string": "1.1", + "port-version": 0 + }, + { + "git-tree": "89c88798a9fa17ea6753da87887a1fec48c421b0", + "version-string": "1.0", + "port-version": 0 + } + ] +} diff --git a/azure-pipelines/e2e-ports/versions/baseline.json b/azure-pipelines/e2e-ports/versions/baseline.json deleted file mode 100644 index 2413f8afc6..0000000000 --- a/azure-pipelines/e2e-ports/versions/baseline.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "default": { - "vcpkg-internal-e2e-test-port": { "baseline": "1.0.0" } - } -} diff --git a/azure-pipelines/e2e-ports/versions/v-/vcpkg-internal-e2e-test-port.json b/azure-pipelines/e2e-ports/versions/v-/vcpkg-internal-e2e-test-port.json deleted file mode 100644 index ce7698ebb8..0000000000 --- a/azure-pipelines/e2e-ports/versions/v-/vcpkg-internal-e2e-test-port.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "versions": [ - { - "version-string": "1.0.0", - "git-tree": "1dc3e42a3c0cafe2884d379af4399273238b986e" - } - ] -} 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 new file mode 100644 index 0000000000..6ff05dc086 --- /dev/null +++ b/azure-pipelines/end-to-end-tests-dir/ci-verify-versions.ps1 @@ -0,0 +1,176 @@ +. "$PSScriptRoot/../end-to-end-tests-prelude.ps1" + +Refresh-TestRoot + +Copy-Item -Recurse "$PSScriptRoot/../e2e-assets/ci-verify-versions-registry" "$TestingRoot/ci-verify-versions-registry" +git -C "$TestingRoot/ci-verify-versions-registry" @gitConfigOptions init +git -C "$TestingRoot/ci-verify-versions-registry" @gitConfigOptions add -A +git -C "$TestingRoot/ci-verify-versions-registry" @gitConfigOptions commit -m testing +Move-Item "$TestingRoot/ci-verify-versions-registry/old-port-versions/has-local-edits" "$TestingRoot/ci-verify-versions-registry/ports" + +$expected = @" +$TestingRoot/ci-verify-versions-registry/ports/malformed/vcpkg.json:4:3: error: Unexpected character; expected property name + on expression: ~broken + ^ +$TestingRoot/ci-verify-versions-registry/versions/b-/bad-git-tree.json: error: bad-git-tree@1.1 git tree 000000070c5f496fcf1a97cf654d5e81f0d2685a does not match the port directory +$TestingRoot/ci-verify-versions-registry/ports/bad-git-tree: note: the port directory has git tree 6528b2c70c5f496fcf1a97cf654d5e81f0d2685a +$TestingRoot/ci-verify-versions-registry/ports/bad-git-tree/vcpkg.json: note: if bad-git-tree@1.1 is already published, update this file with a new version or port-version, commit it, then add the new version by running: + vcpkg x-add-version bad-git-tree + git add versions + git commit -m `"Update version database`" +note: if bad-git-tree@1.1 is not yet published, overwrite the previous git tree by running: + vcpkg x-add-version bad-git-tree --overwrite-version + git add versions + git commit -m `"Update version database`" +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: bad-git-tree@1.1 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/bad-git-tree/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/ports/bad-history-name: message: bad-history-name@1.1 is correctly in the version database (f34f4ad3dfcc4d46d467d7b6aa04f9732a7951d6) +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: bad-history-name@1.1 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/bad-history-name/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/ports/baseline-version-mismatch: message: baseline-version-mismatch@1.1 is correctly in the version database (cf8a1faa9f94f7ceb9513d65093d407e11ac1402) +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: error: baseline-version-mismatch is assigned 1.0, but the local port is 1.1 +$TestingRoot/ci-verify-versions-registry/ports/baseline-version-mismatch/vcpkg.json: note: baseline-version-mismatch is declared here +note: you can run the following commands to add the current version of baseline-version-mismatch automatically: + vcpkg x-add-version baseline-version-mismatch + git add versions + git commit -m `"Update version database`" +$TestingRoot/ci-verify-versions-registry/ports/baseline-version-mismatch/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/ports/baseline-version-missing: message: baseline-version-missing@1.0 is correctly in the version database (a5c21769008f52ed66afa344f13b786dde4b8d7d) +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: error: baseline-version-missing is not assigned a version +$TestingRoot/ci-verify-versions-registry/ports/baseline-version-missing/vcpkg.json: note: baseline-version-missing is declared here +note: you can run the following commands to add the current version of baseline-version-missing automatically: + vcpkg x-add-version baseline-version-missing + git add versions + git commit -m `"Update version database`" +$TestingRoot/ci-verify-versions-registry/ports/baseline-version-missing/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/ports/dependency-not-in-versions-database: message: dependency-not-in-versions-database@1.0 is correctly in the version database (321c8b400526dc412a987285ef469eec6221a4b4) +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: dependency-not-in-versions-database@1.0 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/dependency-not-in-versions-database/vcpkg.json: error: the dependency no-versions does not exist in the version database; does that port exist? +$TestingRoot/ci-verify-versions-registry/ports/dependency-not-in-versions-database-feature: message: dependency-not-in-versions-database-feature@1.0 is correctly in the version database (2298ee25ea54ed92595250a2be07d01bdd76f47c) +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: dependency-not-in-versions-database-feature@1.0 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/dependency-not-in-versions-database-feature/vcpkg.json: error: the dependency no-versions does not exist in the version database; does that port exist? +note: the dependency is in the feature named add-things +$TestingRoot/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database: message: dependency-version-not-in-versions-database@1.0 is correctly in the version database (f0d44555fe7714929e432ab9e12a436e28ffef9e) +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: dependency-version-not-in-versions-database@1.0 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database/vcpkg.json: error: the "version>=" constraint to good names version 0.9 which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg. +$TestingRoot/ci-verify-versions-registry/versions/g-/good.json: note: consider removing the version constraint or choosing a value declared here +$TestingRoot/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database-feature: message: dependency-version-not-in-versions-database-feature@1.0 is correctly in the version database (ba3008bb2d42c61f172b7d9592de0212edf20fc6) +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: dependency-version-not-in-versions-database-feature@1.0 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/dependency-version-not-in-versions-database-feature/vcpkg.json: error: the "version>=" constraint to good names version 0.9 which does not exist in the version database. All versions must exist in the version database to be interpreted by vcpkg. +$TestingRoot/ci-verify-versions-registry/versions/g-/good.json: note: consider removing the version constraint or choosing a value declared here +note: the dependency is in the feature named add-things +$TestingRoot/ci-verify-versions-registry/ports/good: message: good@1.0 is correctly in the version database (0f3d67db0dbb6aa5499bc09367a606b495e16d35) +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: good@1.0 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/good/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/ports/has-local-edits/vcpkg.json: error: the git tree of the port directory could not be determined. This is usually caused by uncommitted changes. +note: you can commit your changes and add them to the version database by running: + git add "$TestingRoot/ci-verify-versions-registry/ports/has-local-edits" + git commit -m wip + vcpkg x-add-version has-local-edits + git add versions + git commit --amend -m "[has-local-edits] Add new port" +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: has-local-edits@1.0.0 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/has-local-edits/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/versions/m-/mismatch-git-tree.json: error: mismatch-git-tree@1.0 git tree 41d20d2a02d75343b0933b624faf9f061b112dad does not match the port directory +$TestingRoot/ci-verify-versions-registry/ports/mismatch-git-tree: note: the port directory has git tree 34b3289caaa7a97950828905d354dc971c3c15a7 +$TestingRoot/ci-verify-versions-registry/ports/mismatch-git-tree/vcpkg.json: note: if mismatch-git-tree@1.0 is already published, update this file with a new version or port-version, commit it, then add the new version by running: + vcpkg x-add-version mismatch-git-tree + git add versions + git commit -m `"Update version database`" +note: if mismatch-git-tree@1.0 is not yet published, overwrite the previous git tree by running: + vcpkg x-add-version mismatch-git-tree --overwrite-version + git add versions + git commit -m `"Update version database`" +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: mismatch-git-tree@1.0 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/mismatch-git-tree/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/ports/no-versions/vcpkg.json: error: this port is not in the version database +$TestingRoot/ci-verify-versions-registry/versions/n-/no-versions.json: note: the version database file should be here +note: run 'vcpkg x-add-version no-versions' to create the version database file +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: no-versions@1.0 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/no-versions/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/ports/override-not-in-versions-database: message: override-not-in-versions-database@1.0 is correctly in the version database (0ff80cd22d5ca881efab3329ce596566a8642bec) +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: override-not-in-versions-database@1.0 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/override-not-in-versions-database/vcpkg.json: error: the version override no-versions does not exist in the version database; does that port exist? +$TestingRoot/ci-verify-versions-registry/ports/override-version-not-in-versions-database: message: override-version-not-in-versions-database@1.0 is correctly in the version database (49fafaad46408296e50e9d0fd1a3d531bf97d420) +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: override-version-not-in-versions-database@1.0 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/override-version-not-in-versions-database/vcpkg.json: error: the override of good names version 0.9 which does not exist in the version database. Installing this port at the top level will fail as that version will be unresolvable. +$TestingRoot/ci-verify-versions-registry/versions/g-/good.json: note: consider removing the version override or choosing a value declared here +$TestingRoot/ci-verify-versions-registry/ports/version-mismatch/vcpkg.json: error: version-mismatch@1.1 was not found in versions database +$TestingRoot/ci-verify-versions-registry/versions/v-/version-mismatch.json: note: the version should be in this file +note: run 'vcpkg x-add-version version-mismatch' to add the new port version +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: version-mismatch@1.1 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/version-mismatch/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/ports/version-missing/vcpkg.json: error: version-missing@1.1 was not found in versions database +$TestingRoot/ci-verify-versions-registry/versions/v-/version-missing.json: note: the version should be in this file +note: run 'vcpkg x-add-version version-missing' to add the new port version +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: version-missing@1.1 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/version-missing/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/versions/v-/version-scheme-mismatch.json: error: 1.1 is declared version-string, but version-scheme-mismatch is declared with version +$TestingRoot/ci-verify-versions-registry/ports/version-scheme-mismatch/vcpkg.json: note: version-scheme-mismatch is declared here +note: versions must be unique, even if they are declared with different schemes +note: you can overwrite version-scheme-mismatch@1.1 with correct local values by running: +vcpkg x-add-version version-scheme-mismatch --overwrite-version +$TestingRoot/ci-verify-versions-registry/versions/baseline.json: message: version-scheme-mismatch@1.1 matches the current baseline +$TestingRoot/ci-verify-versions-registry/ports/version-scheme-mismatch/vcpkg.json: message: all version constraints are consistent with the version database +$TestingRoot/ci-verify-versions-registry/versions/b-/bad-git-tree.json: error: failed to execute: `"C:\Program Files\Git\cmd\git.exe`" `"--git-dir=$TestingRoot/ci-verify-versions-registry/.git`" `"--work-tree=$buildtreesRoot/versioning_/versions/bad-git-tree/000000070c5f496fcf1a97cf654d5e81f0d2685a_82336.tmp`" -c core.autocrlf=false read-tree -m -u 000000070c5f496fcf1a97cf654d5e81f0d2685a +error: git failed with exit code: (128). +fatal: failed to unpack tree object 000000070c5f496fcf1a97cf654d5e81f0d2685a +note: while checking out port bad-git-tree with git tree 000000070c5f496fcf1a97cf654d5e81f0d2685a +note: while validating version: 1.1 +$TestingRoot/ci-verify-versions-registry/versions/b-/bad-git-tree.json: error: failed to execute: `"C:\Program Files\Git\cmd\git.exe`" `"--git-dir=$TestingRoot/ci-verify-versions-registry/.git`" `"--work-tree=$buildtreesRoot/versioning_/versions/bad-git-tree/00000005fb6b76058ce09252f521847363c6b266_82336.tmp`" -c core.autocrlf=false read-tree -m -u 00000005fb6b76058ce09252f521847363c6b266 +error: git failed with exit code: (128). +fatal: failed to unpack tree object 00000005fb6b76058ce09252f521847363c6b266 +note: while checking out port bad-git-tree with git tree 00000005fb6b76058ce09252f521847363c6b266 +note: while validating version: 1.0 +$TestingRoot/ci-verify-versions-registry/versions/b-/bad-history-name.json: message: bad-history-name@1.1 is correctly in the version database (f34f4ad3dfcc4d46d467d7b6aa04f9732a7951d6) +$TestingRoot/ci-verify-versions-registry/versions/b-/bad-history-name.json: error: db9d98300e7daeb2c0652bae94a0283a1b1a13d1 is declared to contain bad-history-name@1.0, but appears to contain bad-history-name-is-bad@1.0 +$TestingRoot/ci-verify-versions-registry/versions/b-/baseline-version-mismatch.json: message: baseline-version-mismatch@1.1 is correctly in the version database (cf8a1faa9f94f7ceb9513d65093d407e11ac1402) +$TestingRoot/ci-verify-versions-registry/versions/b-/baseline-version-mismatch.json: message: baseline-version-mismatch@1.0 is correctly in the version database (a6d7dde2f5a9ea80db16c7f73c43556a7e21e5cf) +$TestingRoot/ci-verify-versions-registry/versions/b-/baseline-version-missing.json: message: baseline-version-missing@1.0 is correctly in the version database (a5c21769008f52ed66afa344f13b786dde4b8d7d) +$TestingRoot/ci-verify-versions-registry/versions/d-/dependency-not-in-versions-database.json: message: dependency-not-in-versions-database@1.0 is correctly in the version database (321c8b400526dc412a987285ef469eec6221a4b4) +$TestingRoot/ci-verify-versions-registry/versions/d-/dependency-not-in-versions-database-feature.json: message: dependency-not-in-versions-database-feature@1.0 is correctly in the version database (2298ee25ea54ed92595250a2be07d01bdd76f47c) +$TestingRoot/ci-verify-versions-registry/versions/d-/dependency-version-not-in-versions-database.json: message: dependency-version-not-in-versions-database@1.0 is correctly in the version database (f0d44555fe7714929e432ab9e12a436e28ffef9e) +$TestingRoot/ci-verify-versions-registry/versions/d-/dependency-version-not-in-versions-database-feature.json: message: dependency-version-not-in-versions-database-feature@1.0 is correctly in the version database (ba3008bb2d42c61f172b7d9592de0212edf20fc6) +$TestingRoot/ci-verify-versions-registry/versions/g-/good.json: message: good@1.0 is correctly in the version database (0f3d67db0dbb6aa5499bc09367a606b495e16d35) +$TestingRoot/ci-verify-versions-registry/versions/h-/has-local-edits.json: message: has-local-edits@1.0.0 is correctly in the version database (b1d7f6030942b329a200f16c931c01e2ec9e1e79) +$TestingRoot/ci-verify-versions-registry/versions/m-/malformed.json: $buildtreesRoot/versioning_/versions/malformed/a1f22424b0fb1460200c12e1b7933f309f9c8373/vcpkg.json:4:3: error: Unexpected character; expected property name + on expression: ~broken + ^ +note: while validating version: 1.1 +$TestingRoot/ci-verify-versions-registry/versions/m-/malformed.json: $buildtreesRoot/versioning_/versions/malformed/72b37802dbdc176ce20b718ce4a332ac38bd0116/vcpkg.json:4:3: error: Unexpected character; expected property name + on expression: ~broken + ^ +note: while validating version: 1.0 +$TestingRoot/ci-verify-versions-registry/versions/m-/mismatch-git-tree.json: message: mismatch-git-tree@1.0 is correctly in the version database (41d20d2a02d75343b0933b624faf9f061b112dad) +$TestingRoot/ci-verify-versions-registry/versions/o-/override-not-in-versions-database.json: message: override-not-in-versions-database@1.0 is correctly in the version database (0ff80cd22d5ca881efab3329ce596566a8642bec) +$TestingRoot/ci-verify-versions-registry/versions/o-/override-version-not-in-versions-database.json: message: override-version-not-in-versions-database@1.0 is correctly in the version database (49fafaad46408296e50e9d0fd1a3d531bf97d420) +$TestingRoot/ci-verify-versions-registry/versions/v-/version-mismatch.json: error: 220bdcf2d4836ec9fe867eaff2945b58c08f5618 is declared to contain version-mismatch@1.1-a, but appears to contain version-mismatch@1.1 +$TestingRoot/ci-verify-versions-registry/versions/v-/version-mismatch.json: error: 5c1a69be3303fcd085d473d10e311b85202ee93c is declared to contain version-mismatch@1.0-a, but appears to contain version-mismatch@1.0 +$TestingRoot/ci-verify-versions-registry/versions/v-/version-missing.json: message: version-missing@1.0 is correctly in the version database (d3b4c8bf4bee7654f63b223a442741bb16f45957) +$TestingRoot/ci-verify-versions-registry/versions/v-/version-scheme-mismatch.json: error: 1.1 is declared version-string, but version-scheme-mismatch@ea2006a1188b81f1f2f6e0aba9bef236d1fb2725 is declared with version +$buildtreesRoot/versioning_/versions/version-scheme-mismatch/ea2006a1188b81f1f2f6e0aba9bef236d1fb2725/vcpkg.json: note: version-scheme-mismatch is declared here +note: versions must be unique, even if they are declared with different schemes +$TestingRoot/ci-verify-versions-registry/versions/v-/version-scheme-mismatch.json: error: 1.0 is declared version-string, but version-scheme-mismatch@89c88798a9fa17ea6753da87887a1fec48c421b0 is declared with version +$buildtreesRoot/versioning_/versions/version-scheme-mismatch/89c88798a9fa17ea6753da87887a1fec48c421b0/vcpkg.json: note: version-scheme-mismatch is declared here +note: versions must be unique, even if they are declared with different schemes +"@ + +$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 +Throw-IfNotFailed + +function Sanitize() { + Param([string]$text) + $workTreeRegex = 'error: failed to execute:[^\r\n]+' # Git command line has an unpredictable PID inside + $text = $text.Replace('\', '/').Replace("`r`n", "`n").Trim() + $text = [System.Text.RegularExpressions.Regex]::Replace($text, $workTreeRegex, '') + return $text +} + +$expected = Sanitize $expected +$actual = Sanitize $actual +if ($actual -ne $expected) { + Set-Content -Value $expected -LiteralPath "$TestingRoot/expected.txt" + Set-Content -Value $actual -LiteralPath "$TestingRoot/actual.txt" + git diff --no-index -- "$TestingRoot/expected.txt" "$TestingRoot/actual.txt" + throw "Bad x-ci-verify-versions output." +} diff --git a/include/vcpkg/base/expected.h b/include/vcpkg/base/expected.h index d58c7dfaa9..e03e6d8df0 100644 --- a/include/vcpkg/base/expected.h +++ b/include/vcpkg/base/expected.h @@ -228,6 +228,12 @@ namespace vcpkg return std::move(*m_t.get()); } + Error& error() & noexcept + { + unreachable_if_not_error(VCPKG_LINE_INFO); + return m_error; + } + const Error& error() const& noexcept { unreachable_if_not_error(VCPKG_LINE_INFO); @@ -240,6 +246,12 @@ namespace vcpkg return std::move(m_error); } + const Error&& error() const&& noexcept + { + unreachable_if_not_error(VCPKG_LINE_INFO); + return std::move(m_error); + } + typename ExpectedHolder::const_pointer get() const noexcept { if (value_is_error) diff --git a/include/vcpkg/base/jsonreader.h b/include/vcpkg/base/jsonreader.h index 8bee15af39..61749a4018 100644 --- a/include/vcpkg/base/jsonreader.h +++ b/include/vcpkg/base/jsonreader.h @@ -57,6 +57,8 @@ namespace vcpkg::Json const std::vector& warnings() const { return m_warnings; } + LocalizedString join() const; + std::string path() const noexcept; StringView origin() const noexcept; diff --git a/include/vcpkg/base/message-data.inc.h b/include/vcpkg/base/message-data.inc.h index 26e5d198dd..5442c6a898 100644 --- a/include/vcpkg/base/message-data.inc.h +++ b/include/vcpkg/base/message-data.inc.h @@ -56,7 +56,10 @@ DECLARE_MESSAGE(AddVersionIgnoringOptionAll, (msg::option), "The -- before {option} must be preserved as they're part of the help message for the user.", "ignoring --{option} since a port name argument was provided") -DECLARE_MESSAGE(AddVersionLoadPortFailed, (msg::package_name), "", "can't load port {package_name}") +DECLARE_MESSAGE(AddVersionInstructions, + (msg::package_name), + "", + "you can run the following commands to add the current version of {package_name} automatically:") DECLARE_MESSAGE(AddVersionNewFile, (), "", "(new file)") DECLARE_MESSAGE(AddVersionNewShaIs, (msg::commit_sha), "", "new SHA: {commit_sha}") DECLARE_MESSAGE(AddVersionNoFilesUpdated, (), "", "No files were updated") @@ -99,7 +102,6 @@ DECLARE_MESSAGE( "actually semantic parts do not apply.\n" "If versions for this port are not ordered by these rules, disable this check by rerunning this command and adding " "--skip-version-format-check .") -DECLARE_MESSAGE(AddVersionUnableToParseVersionsFile, (msg::path), "", "unable to parse versions file {path}") DECLARE_MESSAGE(AddVersionUncommittedChanges, (msg::package_name), "", @@ -295,14 +297,7 @@ DECLARE_MESSAGE(BaselineGitShowFailed, "", "while checking out baseline from commit '{commit_sha}', failed to `git show` " "versions/baseline.json. This may be fixed by fetching commits with `git fetch`.") -DECLARE_MESSAGE(BaselineMissing, - (msg::package_name, msg::version), - "", - "Baseline version not found. Run:\n" - "vcpkg x-add-version {package_name}\n" - "git add versions\n" - "git commit -m \"Update version database\"\n" - "to set {version} as the baseline version.") +DECLARE_MESSAGE(BaselineMissing, (msg::package_name), "", "{package_name} is not assigned a version") DECLARE_MESSAGE(BinariesRelativeToThePackageDirectoryHere, (), "", @@ -417,11 +412,6 @@ DECLARE_MESSAGE( "The triplet requests that binaries are built for {arch}, but the following binaries were built for a " "different architecture. This usually means toolchain information is incorrectly conveyed to the binaries' " "build system. To suppress this message, add set(VCPKG_POLICY_SKIP_ARCHITECTURE_CHECK enabled)") -DECLARE_MESSAGE(CheckedOutGitSha, (msg::commit_sha), "", "Checked out Git SHA: {commit_sha}") -DECLARE_MESSAGE(CheckedOutObjectMissingManifest, - (), - "", - "The checked-out object does not contain a CONTROL file or vcpkg.json file.") DECLARE_MESSAGE(ChecksFailedCheck, (), "", "vcpkg has crashed; no additional details are available.") DECLARE_MESSAGE(ChecksUnreachableCode, (), "", "unreachable code was reached") DECLARE_MESSAGE(ChecksUpdateVcpkg, (), "", "updating vcpkg by rerunning bootstrap-vcpkg may resolve this failure.") @@ -457,7 +447,6 @@ DECLARE_MESSAGE(CiBaselineUnexpectedPass, (msg::spec, msg::path), "", "PASSING, REMOVE FROM FAIL LIST: {spec} ({path}).") -DECLARE_MESSAGE(CISettingsExclude, (), "", "Comma-separated list of ports to skip") DECLARE_MESSAGE(CISettingsOptCIBase, (), "", @@ -895,10 +884,6 @@ DECLARE_MESSAGE(ConsideredVersions, "requirement of {version}:") DECLARE_MESSAGE(ConstraintViolation, (), "", "Found a constraint violation:") DECLARE_MESSAGE(ContinueCodeUnitInStart, (), "", "found continue code unit in start position") -DECLARE_MESSAGE(ControlAndManifestFilesPresent, - (msg::path), - "", - "Both a manifest file and a CONTROL file exist in port directory: {path}") DECLARE_MESSAGE(ControlCharacterInString, (), "", "Control character in string") DECLARE_MESSAGE(ControlSupportsMustBeAPlatformExpression, (), "", "\"Supports\" must be a platform expression") DECLARE_MESSAGE(CopyrightIsDir, @@ -1005,6 +990,11 @@ DECLARE_MESSAGE( DECLARE_MESSAGE(DependencyGraphCalculation, (), "", "Dependency graph submission enabled.") DECLARE_MESSAGE(DependencyGraphFailure, (), "", "Dependency graph submission failed.") DECLARE_MESSAGE(DependencyGraphSuccess, (), "", "Dependency graph submission successful.") +DECLARE_MESSAGE(DependencyInFeature, (msg::feature), "", "the dependency is in the feature named {feature}") +DECLARE_MESSAGE(DependencyNotInVersionDatabase, + (msg::package_name), + "", + "the dependency {package_name} does not exist in the version database; does that port exist?") DECLARE_MESSAGE(DeprecatedPrefabDebugOption, (), "", "--prefab-debug is now deprecated.") DECLARE_MESSAGE(DetectCompilerHash, (msg::triplet), "", "Detecting compiler hash for triplet {triplet}...") DECLARE_MESSAGE(DirectoriesRelativeToThePackageDirectoryHere, @@ -1128,7 +1118,6 @@ DECLARE_MESSAGE(ErrorInvalidExtractOption, (msg::option, msg::value), "The keyword 'AUTO' should not be localized", "--{option} must be set to a nonnegative integer or 'AUTO'.") -DECLARE_MESSAGE(ErrorsFound, (), "", "Found the following errors:") DECLARE_MESSAGE(ErrorUnableToDetectCompilerInfo, (), "failure output will be displayed at the top of this", @@ -1242,7 +1231,6 @@ DECLARE_MESSAGE( DECLARE_MESSAGE(FailedToLoadManifest, (msg::path), "", "Failed to load manifest from directory {path}") DECLARE_MESSAGE(FailedToLocateSpec, (msg::spec), "", "Failed to locate spec in graph: {spec}") DECLARE_MESSAGE(FailedToObtainDependencyVersion, (), "", "Cannot find desired dependency version.") -DECLARE_MESSAGE(FailedToObtainLocalPortGitSha, (), "", "Failed to obtain git SHAs for local ports.") DECLARE_MESSAGE(FailedToObtainPackageVersion, (), "", "Cannot find desired package version.") DECLARE_MESSAGE(FailedToOpenAlgorithm, (msg::value), @@ -1254,8 +1242,7 @@ DECLARE_MESSAGE(FailedToParseCMakeConsoleOut, "Failed to parse CMake console output to locate block start/end markers.") DECLARE_MESSAGE(FailedToParseBaseline, (msg::path), "", "Failed to parse baseline: {path}") DECLARE_MESSAGE(FailedToParseConfig, (msg::path), "", "Failed to parse configuration: {path}") -DECLARE_MESSAGE(FailedToParseControl, (msg::path), "", "Failed to parse CONTROL file: {path}") -DECLARE_MESSAGE(FailedToParseManifest, (msg::path), "", "Failed to parse manifest file: {path}") +DECLARE_MESSAGE(FailedToParseVersionFile, (msg::path), "", "Failed to parse version file: {path}") DECLARE_MESSAGE(FailedToParseNoTopLevelObj, (msg::path), "", "Failed to parse {path}, expected a top-level object.") DECLARE_MESSAGE(FailedToParseNoVersionsArray, (msg::path), "", "Failed to parse {path}, expected a 'versions' array.") DECLARE_MESSAGE(FailedToParseSerializedBinParagraph, @@ -1264,13 +1251,10 @@ 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(FailedToParseVersionsFile, (msg::path), "", "failed to parse versions file {path}") DECLARE_MESSAGE(FailedToParseVersionXML, (msg::tool_name, msg::version), "", "Could not parse version for tool {tool_name}. Version string was: {version}") -DECLARE_MESSAGE(FailedToReadParagraph, (msg::path), "", "Failed to read paragraphs from {path}") -DECLARE_MESSAGE(FailedToRemoveControl, (msg::path), "", "Failed to remove control file {path}") DECLARE_MESSAGE(FailedToRunToolToDetermineVersion, (msg::tool_name, msg::path), "Additional information, such as the command line output, if any, will be appended on " @@ -1279,7 +1263,6 @@ DECLARE_MESSAGE(FailedToRunToolToDetermineVersion, DECLARE_MESSAGE(FailedToStoreBackToMirror, (), "", "failed to store back to mirror:") DECLARE_MESSAGE(FailedToStoreBinaryCache, (msg::path), "", "Failed to store binary cache {path}") DECLARE_MESSAGE(FailedToTakeFileSystemLock, (), "", "Failed to take the filesystem lock") -DECLARE_MESSAGE(FailedToWriteManifest, (msg::path), "", "Failed to write manifest file {path}") DECLARE_MESSAGE(FailedVendorAuthentication, (msg::vendor, msg::url), "", @@ -1356,6 +1339,10 @@ DECLARE_MESSAGE(GHAParametersMissing, "The GHA binary source requires the ACTIONS_RUNTIME_TOKEN and ACTIONS_CACHE_URL environment variables " "to be set. See {url} for details.") DECLARE_MESSAGE(GitCommandFailed, (msg::command_line), "", "failed to execute: {command_line}") +DECLARE_MESSAGE(GitCommitUpdateVersionDatabase, + (), + "This is a command line; only the 'update version database' part should be localized", + "git commit -m \"Update version database\"") DECLARE_MESSAGE(GitFailedToFetch, (msg::value, msg::url), "{value} is a git ref like 'origin/main'", @@ -1898,7 +1885,6 @@ DECLARE_MESSAGE( "Invalid {system_name} linkage type: [{value}]") DECLARE_MESSAGE(InvalidLogicExpressionUnexpectedCharacter, (), "", "invalid logic expression, unexpected character") DECLARE_MESSAGE(InvalidLogicExpressionUsePipe, (), "", "invalid logic expression, use '|' rather than 'or'") -DECLARE_MESSAGE(InvalidNoVersions, (), "", "File contains no versions.") DECLARE_MESSAGE(InvalidOptionForRemove, (), "'remove' is a command that should not be changed.", @@ -2017,10 +2003,7 @@ DECLARE_MESSAGE(LoadingDependencyInformation, "", "Loading dependency information for {count} packages...") DECLARE_MESSAGE(LocalPortfileVersion, (), "", "Using local port versions. To update the local ports, use `git pull`.") -DECLARE_MESSAGE(ManifestConflict, - (msg::path), - "", - "Found both a manifest and CONTROL files in port \"{path}\"; please rename one or the other") +DECLARE_MESSAGE(ManifestConflict2, (), "", "Found both a manifest and CONTROL files; please rename one or the other") DECLARE_MESSAGE(ManifestFormatCompleted, (), "", "Succeeded in formatting the manifest files.") DECLARE_MESSAGE(MismatchedBinParagraphs, (), @@ -2492,6 +2475,10 @@ DECLARE_MESSAGE(PortBugSetDllsWithoutExports, "", "the following DLLs were built without any exports. DLLs without exports are likely bugs in the build " "script. If this is intended, add set(VCPKG_POLICY_DLLS_WITHOUT_EXPORTS enabled)") +DECLARE_MESSAGE(PortDeclaredHere, + (msg::package_name), + "This is printed after NoteMessage to tell the user the path on disk of a related port", + "{package_name} is declared here") DECLARE_MESSAGE(PortDependencyConflict, (msg::package_name), "", @@ -2640,10 +2627,6 @@ DECLARE_MESSAGE(StoredBinariesToDestinations, DECLARE_MESSAGE(StoreOptionMissingSha, (), "", "--store option is invalid without a sha512") 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(SuggestResolution, - (msg::command_name, msg::option), - "", - "To attempt to resolve all errors at once, run:\nvcpkg {command_name} --{option}") DECLARE_MESSAGE(SuggestStartingBashShell, (), "", @@ -2939,15 +2922,16 @@ DECLARE_MESSAGE(VcvarsRunFailedExitCode, (msg::exit_code), "", "while trying to get a Visual Studio environment, vcvarsall.bat returned {exit_code}") +DECLARE_MESSAGE(VersionBaselineMatch, (msg::version_spec), "", "{version_spec} matches the current baseline") DECLARE_MESSAGE(VersionBaselineMismatch, (msg::expected, msg::actual, msg::package_name), - "{expected} and {actual} are versions", - "The latest version is {expected}, but the baseline file contains {actual}.\n" - "Run:\n" - "vcpkg x-add-version {package_name}\n" - "git add versions\n" - "git commit -m \"Update version database\"\n" - "to update the baseline version.") + "{actual} and {expected} are versions", + "{package_name} is assigned {actual}, but the local port is {expected}") +DECLARE_MESSAGE(VersionBuiltinPortTreeEntryMissing, + (msg::package_name, msg::expected, msg::actual), + "{expected} and {actual} are versions like 1.0.", + "no version database entry for {package_name} at {expected}; using the checked out ports tree " + "version ({actual}).") DECLARE_MESSAGE(VersionCommandHeader, (msg::version), "", @@ -2957,6 +2941,16 @@ DECLARE_MESSAGE( (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), + "", + "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.") +DECLARE_MESSAGE(VersionConstraintNotInDatabase2, + (), + "", + "consider removing the version constraint or choosing a value declared here") +DECLARE_MESSAGE(VersionConstraintOk, (), "", "all version constraints are consistent with the version database") DECLARE_MESSAGE(VersionConstraintPortVersionMustBePositiveInteger, (), "", @@ -2966,18 +2960,12 @@ DECLARE_MESSAGE(VersionConstraintViolated, "", "dependency {spec} was expected to be at least version " "{expected_version}, but is currently {actual_version}.") -DECLARE_MESSAGE(VersionDatabaseFileMissing, - (msg::package_name, msg::path), +DECLARE_MESSAGE(VersionDatabaseFileMissing, (), "", "this port is not in the version database") +DECLARE_MESSAGE(VersionDatabaseFileMissing2, (), "", "the version database file should be here") +DECLARE_MESSAGE(VersionDatabaseFileMissing3, + (msg::command_line), "", - "{package_name} is missing a version database file at {path}\n" - "Run:\n" - "vcpkg x-add-version {package_name}\n" - "to create the versions file.") -DECLARE_MESSAGE(VersionBuiltinPortTreeEntryMissing, - (msg::package_name, msg::expected, msg::actual), - "{expected} and {actual} are versions like 1.0.", - "no version database entry for {package_name} at {expected}; using the checked out ports tree " - "version ({actual}).") + "run '{command_line}' to create the version database file") DECLARE_MESSAGE(VersionDatabaseEntryMissing, (msg::package_name, msg::version), "", @@ -3003,9 +2991,9 @@ DECLARE_MESSAGE(VersionIncomparable3, "This can be resolved by adding an explicit override to the preferred version. For example:") DECLARE_MESSAGE(VersionIncomparable4, (msg::url), "", "See `vcpkg help versioning` or {url} for more information.") DECLARE_MESSAGE(VersionInDeclarationDoesNotMatch, - (msg::version), - "", - "The version declared in file does not match checked-out version: {version}") + (msg::git_tree_sha, msg::expected, msg::actual), + "{expected} and {actual} are version specs", + "{git_tree_sha} is declared to contain {expected}, but appears to contain {actual}") DECLARE_MESSAGE( VersionInvalidDate, (msg::version), @@ -3033,13 +3021,33 @@ DECLARE_MESSAGE(VersionNotFound, (msg::expected, msg::actual), "{expected} and {actual} are versions", "{expected} not available, only {actual} is available") -DECLARE_MESSAGE(VersionNotFoundInVersionsFile, - (msg::version, msg::package_name), +DECLARE_MESSAGE(VersionNotFoundInVersionsFile2, + (msg::version_spec), + "", + "{version_spec} was not found in versions database") +DECLARE_MESSAGE(VersionNotFoundInVersionsFile3, (), "", "the version should be in this file") +DECLARE_MESSAGE(VersionNotFoundInVersionsFile4, + (msg::command_line), + "", + "run '{command_line}' to add the new port version") +DECLARE_MESSAGE(VersionOverrideNotInVersionDatabase, + (msg::package_name), "", - "Version {version} was not found in versions file for {package_name}.\n" - "Run:\n" - "vcpkg x-add-version {package_name}\n" - "to add the new port version.") + "the version override {package_name} does not exist in the version database; does that port exist?") +DECLARE_MESSAGE( + VersionOverrideVersionNotInVersionDatabase1, + (msg::package_name, msg::version), + "", + "the override of {package_name} names version {version} which does not exist in the " + "version database. Installing this port at the top level will fail as that version will be unresolvable.") +DECLARE_MESSAGE(VersionOverrideVersionNotInVersionDatabase2, + (), + "", + "consider removing the version override or choosing a value declared here") +DECLARE_MESSAGE(VersionOverwriteVersion, + (msg::version_spec), + "", + "you can overwrite {version_spec} with correct local values by running:") DECLARE_MESSAGE(VersionRejectedDueToBaselineMissing, (msg::path, msg::json_field), "", @@ -3052,34 +3060,46 @@ DECLARE_MESSAGE(VersionRejectedDueToFeatureFlagOff, "{path} was rejected because it uses \"{json_field}\" and the `versions` feature flag is disabled. " "This can be fixed by removing \"{json_field}\" or enabling the `versions` feature flag.\nSee " "`vcpkg help versioning` for more information.") -DECLARE_MESSAGE(VersionSchemeMismatch, - (msg::version, msg::expected, msg::actual, msg::path, msg::package_name), - "{expected} and {actual} are version schemes; it here refers to the {version}", - "The version database declares {version} as {expected}, but {path} declares it as {actual}. " - "Versions must be unique, even if they are declared with different schemes.\n" - "Run:\n" - "vcpkg x-add-version {package_name} --overwrite-version\n" - "to overwrite the scheme declared in the version database with that declared in the port.") -DECLARE_MESSAGE(VersionShaMismatch, +DECLARE_MESSAGE(VersionSchemeMismatch1, (msg::version, msg::expected, msg::actual, msg::package_name), - "{expected} and {actual} are git commit SHAs", - "{version} is declared with {expected}, but the local port has a different SHA {actual}.\n" - "Please update the port's version fields and then run:\n" - "vcpkg x-add-version {package_name}\n" - "git add versions\n" - "git commit -m \"Update version database\"\n" - "to add the new version.") -DECLARE_MESSAGE(VersionShaMissing, - (msg::package_name, msg::path), + "{expected} and {actual} are version schemes; it here refers to the {version}", + "{version} is declared {expected}, but {package_name} is declared with {actual}") +DECLARE_MESSAGE(VersionSchemeMismatch1Old, + (msg::version, msg::expected, msg::actual, msg::package_name, msg::git_tree_sha), + "{expected} and {actual} are version schemes; it here refers to the {version}", + "{version} is declared {expected}, but {package_name}@{git_tree_sha} is declared with {actual}") +DECLARE_MESSAGE(VersionSchemeMismatch2, + (), + "", + "versions must be unique, even if they are declared with different schemes") +DECLARE_MESSAGE(VersionShaMismatch1, + (msg::version_spec, msg::git_tree_sha), + "'git tree' is ", + "{version_spec} git tree {git_tree_sha} does not match the port directory") +DECLARE_MESSAGE(VersionShaMismatch2, (msg::git_tree_sha), "", "the port directory has git tree {git_tree_sha}") +DECLARE_MESSAGE(VersionShaMismatch3, + (msg::version_spec), + "", + "if {version_spec} is already published, update this file with a new version or port-version, commit " + "it, then add the new version by running:") +DECLARE_MESSAGE(VersionShaMismatch4, + (msg::version_spec), "", - "while validating {package_name}, missing Git SHA.\n" - "Run:\n" - "git add \"{path}\"\n" - "git commit -m \"wip\"\n" - "vcpkg x-add-version {package_name}\n" - "git add versions\n" - "git commit --amend -m \"[{package_name}] Add new port\"\n" - "to commit the new port and create its version file.") + "if {version_spec} is not yet published, overwrite the previous git tree by running:") +DECLARE_MESSAGE( + VersionShaMissing1, + (), + "", + "the git tree of the port directory could not be determined. This is usually caused by uncommitted changes.") +DECLARE_MESSAGE(VersionShaMissing2, + (), + "", + "you can commit your changes and add them to the version database by running:") +DECLARE_MESSAGE(VersionShaMissing3, + (), + "This is short for 'work in progress' and must be enclosed in \" quotes if it is more than 1 word", + "wip") +DECLARE_MESSAGE(VersionShaMissing4, (msg::package_name), "", "[{package_name}] Add new port") DECLARE_MESSAGE(VersionSharpMustBeFollowedByPortVersion, (), "", @@ -3110,9 +3130,11 @@ DECLARE_MESSAGE(WhileCheckingOutPortTreeIsh, "", "while checking out port {package_name} with git tree {git_tree_sha}") DECLARE_MESSAGE(WhileGettingLocalTreeIshObjectsForPorts, (), "", "while getting local treeish objects for ports") -DECLARE_MESSAGE(WhileLoadingLocalPort, (msg::package_name), "", "while attempting to load local port {package_name}") -DECLARE_MESSAGE(WhileLoadingPortFromGitTree, (msg::commit_sha), "", "while trying to load port from: {commit_sha}") DECLARE_MESSAGE(WhileLookingForSpec, (msg::spec), "", "while looking for {spec}:") +DECLARE_MESSAGE(WhileLoadingBaselineVersionForPort, + (msg::package_name), + "", + "while loading baseline version for {package_name}") DECLARE_MESSAGE(WhileLoadingPortVersion, (msg::version_spec), "", "while loading {version_spec}") DECLARE_MESSAGE(WhileParsingVersionsForPort, (msg::package_name, msg::path), diff --git a/include/vcpkg/base/util.h b/include/vcpkg/base/util.h index e06d0329f1..968c6cd5cc 100644 --- a/include/vcpkg/base/util.h +++ b/include/vcpkg/base/util.h @@ -474,6 +474,12 @@ namespace vcpkg::Util return std::any_of(rng.begin(), rng.end(), std::move(pred)); } + template + bool none_of(Range&& rng, Pred pred) + { + return std::none_of(rng.begin(), rng.end(), std::move(pred)); + } + template> Range&& sort_unique_erase(Range&& cont, Comp comp = Comp()) { diff --git a/include/vcpkg/fwd/sourceparagraph.h b/include/vcpkg/fwd/sourceparagraph.h index 7388ee570a..0b8083bd05 100644 --- a/include/vcpkg/fwd/sourceparagraph.h +++ b/include/vcpkg/fwd/sourceparagraph.h @@ -12,4 +12,4 @@ namespace vcpkg struct PortLocation; struct SourceControlFile; struct SourceControlFileAndLocation; -} \ No newline at end of file +} diff --git a/include/vcpkg/paragraphs.h b/include/vcpkg/paragraphs.h index e48b902c09..dd8040c272 100644 --- a/include/vcpkg/paragraphs.h +++ b/include/vcpkg/paragraphs.h @@ -26,16 +26,23 @@ namespace vcpkg::Paragraphs bool is_port_directory(const ReadOnlyFilesystem& fs, const Path& maybe_directory); + struct PortLoadResult + { + ExpectedL maybe_scfl; + std::string on_disk_contents; + }; + // If an error occurs, the Expected will be in the error state. - // Otherwise, if the port is known, result->source_control_file contains the loaded port information. - // Otherwise, result->source_control_file is nullptr. - ExpectedL try_load_port(const ReadOnlyFilesystem& fs, - StringView port_name, - const PortLocation& port_location); + // Otherwise, if the port is known, the maybe_scfl.get()->source_control_file contains the loaded port information. + // Otherwise, maybe_scfl.get()->source_control_file is nullptr. + PortLoadResult try_load_port(const ReadOnlyFilesystem& fs, StringView port_name, const PortLocation& port_location); // Identical to try_load_port, but the port unknown condition is mapped to an error. - ExpectedL try_load_port_required(const ReadOnlyFilesystem& fs, - StringView port_name, - const PortLocation& port_location); + PortLoadResult try_load_port_required(const ReadOnlyFilesystem& fs, + StringView port_name, + const PortLocation& port_location); + ExpectedL> try_load_project_manifest_text(StringView text, + StringView control_path, + MessageSink& warning_sink); ExpectedL> try_load_port_manifest_text(StringView text, StringView control_path, MessageSink& warning_sink); diff --git a/include/vcpkg/registries.h b/include/vcpkg/registries.h index 18ddc907a2..558eb1ef5e 100644 --- a/include/vcpkg/registries.h +++ b/include/vcpkg/registries.h @@ -166,17 +166,39 @@ namespace vcpkg std::string git_tree; }; - ExpectedL>> get_builtin_versions(const VcpkgPaths& paths, - StringView port_name); + struct GitVersionsLoadResult + { + // If the versions database file does not exist, a disengaged Optional + // Otherwise, if a file I/O error occurred or the file is malformed, that error + // Otherwise, the loaded version database records + ExpectedL>> entries; + Path versions_file_path; + }; - ExpectedL>> get_builtin_baseline(const VcpkgPaths& paths); + GitVersionsLoadResult load_git_versions_file(const ReadOnlyFilesystem& fs, + const Path& registry_versions, + StringView port_name); - bool is_git_commit_sha(StringView sv); + struct FullGitVersionsDatabase + { + explicit FullGitVersionsDatabase(const ReadOnlyFilesystem& fs, + const Path& registry_versions, + std::map>&& initial); + FullGitVersionsDatabase(FullGitVersionsDatabase&&); + FullGitVersionsDatabase& operator=(FullGitVersionsDatabase&&); - // Returns the effective match length of the package pattern `pattern` against `name`. - // 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); + const GitVersionsLoadResult& lookup(StringView port_name); + const std::map>& cache() const; + + private: + const ReadOnlyFilesystem* m_fs; + Path m_registry_versions; + std::map> m_cache; + }; + + // The outer expected only contains directory enumeration errors; individual parse errors are within + ExpectedL load_all_git_versions_files(const ReadOnlyFilesystem& fs, + const Path& registry_versions); struct FilesystemVersionDbEntry { @@ -184,6 +206,18 @@ namespace vcpkg Path p; }; + ExpectedL>> load_filesystem_versions_file( + const ReadOnlyFilesystem& fs, const Path& registry_versions, StringView port_name, const Path& registry_root); + + ExpectedL>> get_builtin_baseline(const VcpkgPaths& paths); + + bool is_git_commit_sha(StringView sv); + + // Returns the effective match length of the package pattern `pattern` against `name`. + // 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/locales/messages.json b/locales/messages.json index 5f45e0b204..4b94abf81a 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -69,8 +69,8 @@ "_AddVersionFormatPortSuggestion.comment": "An example of {command_line} is vcpkg install zlib.", "AddVersionIgnoringOptionAll": "ignoring --{option} since a port name argument was provided", "_AddVersionIgnoringOptionAll.comment": "The -- before {option} must be preserved as they're part of the help message for the user. An example of {option} is editable.", - "AddVersionLoadPortFailed": "can't load port {package_name}", - "_AddVersionLoadPortFailed.comment": "An example of {package_name} is zlib.", + "AddVersionInstructions": "you can run the following commands to add the current version of {package_name} automatically:", + "_AddVersionInstructions.comment": "An example of {package_name} is zlib.", "AddVersionNewFile": "(new file)", "AddVersionNewShaIs": "new SHA: {commit_sha}", "_AddVersionNewShaIs.comment": "An example of {commit_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", @@ -93,8 +93,6 @@ "_AddVersionSuggestVersionDate.comment": "\"version-string\" and \"version-date\" are JSON keys, and --skip-version-format-check is a command line switch. They should not be translated An example of {package_name} is zlib.", "AddVersionSuggestVersionRelaxed": "The version format of \"{package_name}\" uses \"version-string\", but the format is acceptable as a \"version\". If the versions for this port are orderable using relaxed-version rules, change the format to \"version\", and rerun this command. Relaxed-version rules order versions by each numeric component. Then, versions with dash suffixes are sorted lexcographically before. Plus'd build tags are ignored. Examples:\n1.0 < 1.1-alpha < 1.1-b < 1.1 < 1.1.1 < 1.2+build = 1.2 < 2.0\nNote in particular that dashed suffixes sort *before*, not after. 1.0-anything < 1.0\nNote that this sort order is the same as chosen in Semantic Versioning (see https://semver.org), even though the actually semantic parts do not apply.\nIf versions for this port are not ordered by these rules, disable this check by rerunning this command and adding --skip-version-format-check .", "_AddVersionSuggestVersionRelaxed.comment": "\"version-string\" and \"version\" are JSON keys, and --skip-version-format-check is a command line switch. They should not be translated An example of {package_name} is zlib.", - "AddVersionUnableToParseVersionsFile": "unable to parse versions file {path}", - "_AddVersionUnableToParseVersionsFile.comment": "An example of {path} is /foo/bar.", "AddVersionUncommittedChanges": "there are uncommitted changes for {package_name}", "_AddVersionUncommittedChanges.comment": "An example of {package_name} is zlib.", "AddVersionUpdateVersionReminder": "Did you remember to update the version or port version?", @@ -188,8 +186,8 @@ "BaselineConflict": "Specifying vcpkg-configuration.default-registry in a manifest file conflicts with built-in baseline.\nPlease remove one of these conflicting settings.", "BaselineGitShowFailed": "while checking out baseline from commit '{commit_sha}', failed to `git show` versions/baseline.json. This may be fixed by fetching commits with `git fetch`.", "_BaselineGitShowFailed.comment": "An example of {commit_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", - "BaselineMissing": "Baseline version not found. Run:\nvcpkg x-add-version {package_name}\ngit add versions\ngit commit -m \"Update version database\"\nto set {version} as the baseline version.", - "_BaselineMissing.comment": "An example of {package_name} is zlib. An example of {version} is 1.3.8.", + "BaselineMissing": "{package_name} is not assigned a version", + "_BaselineMissing.comment": "An example of {package_name} is zlib.", "BinariesRelativeToThePackageDirectoryHere": "the binaries are relative to ${{CURRENT_PACKAGES_DIR}} here", "BinarySourcesArg": "Binary caching sources. See 'vcpkg help binarycaching'", "_BinarySourcesArg.comment": "'vcpkg help binarycaching' is a command line and should not be localized", @@ -240,7 +238,6 @@ "BuiltInTriplets": "Built-in Triplets:", "BuiltWithIncorrectArchitecture": "The triplet requests that binaries are built for {arch}, but the following binaries were built for a different architecture. This usually means toolchain information is incorrectly conveyed to the binaries' build system. To suppress this message, add set(VCPKG_POLICY_SKIP_ARCHITECTURE_CHECK enabled)", "_BuiltWithIncorrectArchitecture.comment": "An example of {arch} is x64.", - "CISettingsExclude": "Comma-separated list of ports to skip", "CISettingsOptCIBase": "Path to the ci.baseline.txt file. Used to skip ports and detect regressions.", "CISettingsOptExclude": "Comma separated list of ports to skip", "CISettingsOptFailureLogs": "Directory to which failure logs will be copied", @@ -267,9 +264,6 @@ "_CMakeToolChainFile.comment": "An example of {path} is /foo/bar.", "CMakeUsingExportedLibs": "To use exported libraries in CMake projects, add {value} to your CMake command line.", "_CMakeUsingExportedLibs.comment": "{value} is a CMake command line switch of the form -DFOO=BAR", - "CheckedOutGitSha": "Checked out Git SHA: {commit_sha}", - "_CheckedOutGitSha.comment": "An example of {commit_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", - "CheckedOutObjectMissingManifest": "The checked-out object does not contain a CONTROL file or vcpkg.json file.", "ChecksFailedCheck": "vcpkg has crashed; no additional details are available.", "ChecksUnreachableCode": "unreachable code was reached", "ChecksUpdateVcpkg": "updating vcpkg by rerunning bootstrap-vcpkg may resolve this failure.", @@ -517,8 +511,6 @@ "_ConsideredVersions.comment": "An example of {version} is 1.3.8.", "ConstraintViolation": "Found a constraint violation:", "ContinueCodeUnitInStart": "found continue code unit in start position", - "ControlAndManifestFilesPresent": "Both a manifest file and a CONTROL file exist in port directory: {path}", - "_ControlAndManifestFilesPresent.comment": "An example of {path} is /foo/bar.", "ControlCharacterInString": "Control character in string", "ControlSupportsMustBeAPlatformExpression": "\"Supports\" must be a platform expression", "CopyrightIsDir": "this port sets ${{CURRENT_PACKAGES_DIR}}/share/${{PORT}}/copyright to a directory, but it should be a file. Consider combining separate copyright files into one using vcpkg_install_copyright. To suppress this message, add set(VCPKG_POLICY_SKIP_COPYRIGHT_CHECK enabled)", @@ -578,6 +570,10 @@ "DependencyGraphCalculation": "Dependency graph submission enabled.", "DependencyGraphFailure": "Dependency graph submission failed.", "DependencyGraphSuccess": "Dependency graph submission successful.", + "DependencyInFeature": "the dependency is in the feature named {feature}", + "_DependencyInFeature.comment": "An example of {feature} is avisynthplus.", + "DependencyNotInVersionDatabase": "the dependency {package_name} does not exist in the version database; does that port exist?", + "_DependencyNotInVersionDatabase.comment": "An example of {package_name} is zlib.", "DeprecatedPrefabDebugOption": "--prefab-debug is now deprecated.", "DetectCompilerHash": "Detecting compiler hash for triplet {triplet}...", "_DetectCompilerHash.comment": "An example of {triplet} is x64-windows.", @@ -669,7 +665,6 @@ "_ErrorWhileParsing.comment": "An example of {path} is /foo/bar.", "ErrorWhileWriting": "Error occurred while writing {path}.", "_ErrorWhileWriting.comment": "An example of {path} is /foo/bar.", - "ErrorsFound": "Found the following errors:", "ExamplesHeader": "Examples:", "_ExamplesHeader.comment": "Printed before a list of example command lines", "ExceededRecursionDepth": "Recursion depth exceeded.", @@ -739,7 +734,6 @@ "FailedToLocateSpec": "Failed to locate spec in graph: {spec}", "_FailedToLocateSpec.comment": "An example of {spec} is zlib:x64-windows.", "FailedToObtainDependencyVersion": "Cannot find desired dependency version.", - "FailedToObtainLocalPortGitSha": "Failed to obtain git SHAs for local ports.", "FailedToObtainPackageVersion": "Cannot find desired package version.", "FailedToOpenAlgorithm": "failed to open {value}", "_FailedToOpenAlgorithm.comment": "{value} is a crypto algorithm like SHA-1 or SHA-512", @@ -748,32 +742,22 @@ "FailedToParseCMakeConsoleOut": "Failed to parse CMake console output to locate block start/end markers.", "FailedToParseConfig": "Failed to parse configuration: {path}", "_FailedToParseConfig.comment": "An example of {path} is /foo/bar.", - "FailedToParseControl": "Failed to parse CONTROL file: {path}", - "_FailedToParseControl.comment": "An example of {path} is /foo/bar.", - "FailedToParseManifest": "Failed to parse manifest file: {path}", - "_FailedToParseManifest.comment": "An example of {path} is /foo/bar.", "FailedToParseNoTopLevelObj": "Failed to parse {path}, expected a top-level object.", "_FailedToParseNoTopLevelObj.comment": "An example of {path} is /foo/bar.", "FailedToParseNoVersionsArray": "Failed to parse {path}, expected a 'versions' array.", "_FailedToParseNoVersionsArray.comment": "An example of {path} is /foo/bar.", "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:", "_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.", - "FailedToParseVersionsFile": "failed to parse versions file {path}", - "_FailedToParseVersionsFile.comment": "An example of {path} is /foo/bar.", - "FailedToReadParagraph": "Failed to read paragraphs from {path}", - "_FailedToReadParagraph.comment": "An example of {path} is /foo/bar.", - "FailedToRemoveControl": "Failed to remove control file {path}", - "_FailedToRemoveControl.comment": "An example of {path} is /foo/bar.", "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.", "FailedToStoreBackToMirror": "failed to store back to mirror:", "FailedToStoreBinaryCache": "Failed to store binary cache {path}", "_FailedToStoreBinaryCache.comment": "An example of {path} is /foo/bar.", "FailedToTakeFileSystemLock": "Failed to take the filesystem lock", - "FailedToWriteManifest": "Failed to write manifest file {path}", - "_FailedToWriteManifest.comment": "An example of {path} is /foo/bar.", "FailedVendorAuthentication": "One or more {vendor} credential providers failed to authenticate. See '{url}' for more details on how to provide credentials.", "_FailedVendorAuthentication.comment": "An example of {vendor} is Azure. An example of {url} is https://github.com/microsoft/vcpkg.", "FetchingBaselineInfo": "Fetching baseline information from {package_name}...", @@ -825,6 +809,8 @@ "GetParseFailureInfo": "Use '--debug' to get more information about the parse failures.", "GitCommandFailed": "failed to execute: {command_line}", "_GitCommandFailed.comment": "An example of {command_line} is vcpkg install zlib.", + "GitCommitUpdateVersionDatabase": "git commit -m \"Update version database\"", + "_GitCommitUpdateVersionDatabase.comment": "This is a command line; only the 'update version database' part should be localized", "GitFailedToFetch": "failed to fetch ref {value} from repository {url}", "_GitFailedToFetch.comment": "{value} is a git ref like 'origin/main' An example of {url} is https://github.com/microsoft/vcpkg.", "GitFailedToInitializeLocalRepository": "failed to initialize local repository {path}", @@ -1056,7 +1042,6 @@ "_InvalidLinkage.comment": "'{value}' is the linkage type vcpkg would did not understand. (Correct values would be static ofr dynamic) An example of {system_name} is Darwin.", "InvalidLogicExpressionUnexpectedCharacter": "invalid logic expression, unexpected character", "InvalidLogicExpressionUsePipe": "invalid logic expression, use '|' rather than 'or'", - "InvalidNoVersions": "File contains no versions.", "InvalidOptionForRemove": "'remove' accepts either libraries or '--outdated'", "_InvalidOptionForRemove.comment": "'remove' is a command that should not be changed.", "InvalidPortVersonName": "Found invalid port version file name: `{path}`.", @@ -1126,8 +1111,7 @@ "LoadingDependencyInformation": "Loading dependency information for {count} packages...", "_LoadingDependencyInformation.comment": "An example of {count} is 42.", "LocalPortfileVersion": "Using local port versions. To update the local ports, use `git pull`.", - "ManifestConflict": "Found both a manifest and CONTROL files in port \"{path}\"; please rename one or the other", - "_ManifestConflict.comment": "An example of {path} is /foo/bar.", + "ManifestConflict2": "Found both a manifest and CONTROL files; please rename one or the other", "ManifestFormatCompleted": "Succeeded in formatting the manifest files.", "MismatchedBinParagraphs": "The serialized binary paragraph was different from the original binary paragraph. Please open an issue at https://github.com/microsoft/vcpkg with the following output:", "MismatchedFiles": "file to store does not match hash", @@ -1316,6 +1300,8 @@ "PortBugRestrictedHeaderPaths": "Taking the following restricted headers can prevent the core C++ runtime and other packages from compiling correctly. These should be renamed or stored in a subdirectory instead. In exceptional circumstances, this warning can be suppressed by adding set(VCPKG_POLICY_ALLOW_RESTRICTED_HEADERS enabled)", "PortBugRestrictedHeaderPathsNote": "the headers are relative to ${{CURRENT_PACKAGES_DIR}}/include here", "PortBugSetDllsWithoutExports": "the following DLLs were built without any exports. DLLs without exports are likely bugs in the build script. If this is intended, add set(VCPKG_POLICY_DLLS_WITHOUT_EXPORTS enabled)", + "PortDeclaredHere": "{package_name} is declared here", + "_PortDeclaredHere.comment": "This is printed after NoteMessage to tell the user the path on disk of a related port An example of {package_name} is zlib.", "PortDependencyConflict": "Port {package_name} has the following unsupported dependencies:", "_PortDependencyConflict.comment": "An example of {package_name} is zlib.", "PortDoesNotExist": "{package_name} does not exist", @@ -1401,8 +1387,6 @@ "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.", - "SuggestResolution": "To attempt to resolve all errors at once, run:\nvcpkg {command_name} --{option}", - "_SuggestResolution.comment": "An example of {command_name} is install. An example of {option} is editable.", "SuggestStartingBashShell": "Please make sure you have started a new bash shell for the change to take effect.", "SupportedPort": "Port {package_name} is supported.", "_SupportedPort.comment": "An example of {package_name} is zlib.", @@ -1570,25 +1554,33 @@ "VcvarsRunFailed": "failed to run vcvarsall.bat to get a Visual Studio environment", "VcvarsRunFailedExitCode": "while trying to get a Visual Studio environment, vcvarsall.bat returned {exit_code}", "_VcvarsRunFailedExitCode.comment": "An example of {exit_code} is 127.", - "VersionBaselineMismatch": "The latest version is {expected}, but the baseline file contains {actual}.\nRun:\nvcpkg x-add-version {package_name}\ngit add versions\ngit commit -m \"Update version database\"\nto update the baseline version.", - "_VersionBaselineMismatch.comment": "{expected} and {actual} are versions An example of {package_name} is zlib.", + "VersionBaselineMatch": "{version_spec} matches the current baseline", + "_VersionBaselineMatch.comment": "An example of {version_spec} is zlib:x64-windows@1.0.0.", + "VersionBaselineMismatch": "{package_name} is assigned {actual}, but the local port is {expected}", + "_VersionBaselineMismatch.comment": "{actual} and {expected} are versions An example of {package_name} is zlib.", "VersionBuiltinPortTreeEntryMissing": "no version database entry for {package_name} at {expected}; using the checked out ports tree version ({actual}).", "_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", + "VersionConstraintOk": "all version constraints are consistent with the version database", "VersionConstraintPortVersionMustBePositiveInteger": "port-version (after the '#') in \"version>=\" must be a non-negative integer", "VersionConstraintViolated": "dependency {spec} was expected to be at least version {expected_version}, but is currently {actual_version}.", "_VersionConstraintViolated.comment": "An example of {spec} is zlib:x64-windows. An example of {expected_version} is 1.3.8. An example of {actual_version} is 1.3.8.", "VersionDatabaseEntryMissing": "no version entry for {package_name} at {version}.", "_VersionDatabaseEntryMissing.comment": "An example of {package_name} is zlib. An example of {version} is 1.3.8.", - "VersionDatabaseFileMissing": "{package_name} is missing a version database file at {path}\nRun:\nvcpkg x-add-version {package_name}\nto create the versions file.", - "_VersionDatabaseFileMissing.comment": "An example of {package_name} is zlib. An example of {path} is /foo/bar.", + "VersionDatabaseFileMissing": "this port is not in the version database", + "VersionDatabaseFileMissing2": "the version database file should be here", + "VersionDatabaseFileMissing3": "run '{command_line}' to create the version database file", + "_VersionDatabaseFileMissing3.comment": "An example of {command_line} is vcpkg install zlib.", "VersionGitEntryMissing": "no version database entry for {package_name} at {version}.\nAvailable versions:", "_VersionGitEntryMissing.comment": "A list of versions, 1 per line, are printed after this message. An example of {package_name} is zlib. An example of {version} is 1.3.8.", - "VersionInDeclarationDoesNotMatch": "The version declared in file does not match checked-out version: {version}", - "_VersionInDeclarationDoesNotMatch.comment": "An example of {version} is 1.3.8.", + "VersionInDeclarationDoesNotMatch": "{git_tree_sha} is declared to contain {expected}, but appears to contain {actual}", + "_VersionInDeclarationDoesNotMatch.comment": "{expected} and {actual} are version specs An example of {git_tree_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", "VersionIncomparable1": "version conflict on {spec}: {constraint_origin} required {expected}, which cannot be compared with the baseline version {actual}.", "_VersionIncomparable1.comment": "{expected} and {actual} are versions like 1.0 An example of {spec} is zlib:x64-windows. An example of {constraint_origin} is zlib:x64-windows@1.0.0.", "VersionIncomparable2": "{version_spec} has scheme {new_scheme}", @@ -1611,18 +1603,41 @@ "_VersionMissingRequiredFeature.comment": "An example of {version_spec} is zlib:x64-windows@1.0.0. An example of {feature} is avisynthplus. An example of {constraint_origin} is zlib:x64-windows@1.0.0.", "VersionNotFound": "{expected} not available, only {actual} is available", "_VersionNotFound.comment": "{expected} and {actual} are versions", - "VersionNotFoundInVersionsFile": "Version {version} was not found in versions file for {package_name}.\nRun:\nvcpkg x-add-version {package_name}\nto add the new port version.", - "_VersionNotFoundInVersionsFile.comment": "An example of {version} is 1.3.8. An example of {package_name} is zlib.", + "VersionNotFoundInVersionsFile2": "{version_spec} was not found in versions database", + "_VersionNotFoundInVersionsFile2.comment": "An example of {version_spec} is zlib:x64-windows@1.0.0.", + "VersionNotFoundInVersionsFile3": "the version should be in this file", + "VersionNotFoundInVersionsFile4": "run '{command_line}' to add the new port version", + "_VersionNotFoundInVersionsFile4.comment": "An example of {command_line} is vcpkg install zlib.", + "VersionOverrideNotInVersionDatabase": "the version override {package_name} does not exist in the version database; does that port exist?", + "_VersionOverrideNotInVersionDatabase.comment": "An example of {package_name} is zlib.", + "VersionOverrideVersionNotInVersionDatabase1": "the override of {package_name} names version {version} which does not exist in the version database. Installing this port at the top level will fail as that version will be unresolvable.", + "_VersionOverrideVersionNotInVersionDatabase1.comment": "An example of {package_name} is zlib. An example of {version} is 1.3.8.", + "VersionOverrideVersionNotInVersionDatabase2": "consider removing the version override or choosing a value declared here", + "VersionOverwriteVersion": "you can overwrite {version_spec} with correct local values by running:", + "_VersionOverwriteVersion.comment": "An example of {version_spec} is zlib:x64-windows@1.0.0.", "VersionRejectedDueToBaselineMissing": "{path} was rejected because it uses \"{json_field}\" and does not have a \"builtin-baseline\". This can be fixed by removing the uses of \"{json_field}\" or adding a \"builtin-baseline\".\nSee `vcpkg help versioning` for more information.", "_VersionRejectedDueToBaselineMissing.comment": "An example of {path} is /foo/bar. An example of {json_field} is identifer.", "VersionRejectedDueToFeatureFlagOff": "{path} was rejected because it uses \"{json_field}\" and the `versions` feature flag is disabled. This can be fixed by removing \"{json_field}\" or enabling the `versions` feature flag.\nSee `vcpkg help versioning` for more information.", "_VersionRejectedDueToFeatureFlagOff.comment": "An example of {path} is /foo/bar. An example of {json_field} is identifer.", - "VersionSchemeMismatch": "The version database declares {version} as {expected}, but {path} declares it as {actual}. Versions must be unique, even if they are declared with different schemes.\nRun:\nvcpkg x-add-version {package_name} --overwrite-version\nto overwrite the scheme declared in the version database with that declared in the port.", - "_VersionSchemeMismatch.comment": "{expected} and {actual} are version schemes; it here refers to the {version} An example of {version} is 1.3.8. An example of {path} is /foo/bar. An example of {package_name} is zlib.", - "VersionShaMismatch": "{version} is declared with {expected}, but the local port has a different SHA {actual}.\nPlease update the port's version fields and then run:\nvcpkg x-add-version {package_name}\ngit add versions\ngit commit -m \"Update version database\"\nto add the new version.", - "_VersionShaMismatch.comment": "{expected} and {actual} are git commit SHAs An example of {version} is 1.3.8. An example of {package_name} is zlib.", - "VersionShaMissing": "while validating {package_name}, missing Git SHA.\nRun:\ngit add \"{path}\"\ngit commit -m \"wip\"\nvcpkg x-add-version {package_name}\ngit add versions\ngit commit --amend -m \"[{package_name}] Add new port\"\nto commit the new port and create its version file.", - "_VersionShaMissing.comment": "An example of {package_name} is zlib. An example of {path} is /foo/bar.", + "VersionSchemeMismatch1": "{version} is declared {expected}, but {package_name} is declared with {actual}", + "_VersionSchemeMismatch1.comment": "{expected} and {actual} are version schemes; it here refers to the {version} An example of {version} is 1.3.8. An example of {package_name} is zlib.", + "VersionSchemeMismatch1Old": "{version} is declared {expected}, but {package_name}@{git_tree_sha} is declared with {actual}", + "_VersionSchemeMismatch1Old.comment": "{expected} and {actual} are version schemes; it here refers to the {version} An example of {version} is 1.3.8. An example of {package_name} is zlib. An example of {git_tree_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", + "VersionSchemeMismatch2": "versions must be unique, even if they are declared with different schemes", + "VersionShaMismatch1": "{version_spec} git tree {git_tree_sha} does not match the port directory", + "_VersionShaMismatch1.comment": "'git tree' is An example of {version_spec} is zlib:x64-windows@1.0.0. An example of {git_tree_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", + "VersionShaMismatch2": "the port directory has git tree {git_tree_sha}", + "_VersionShaMismatch2.comment": "An example of {git_tree_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", + "VersionShaMismatch3": "if {version_spec} is already published, update this file with a new version or port-version, commit it, then add the new version by running:", + "_VersionShaMismatch3.comment": "An example of {version_spec} is zlib:x64-windows@1.0.0.", + "VersionShaMismatch4": "if {version_spec} is not yet published, overwrite the previous git tree by running:", + "_VersionShaMismatch4.comment": "An example of {version_spec} is zlib:x64-windows@1.0.0.", + "VersionShaMissing1": "the git tree of the port directory could not be determined. This is usually caused by uncommitted changes.", + "VersionShaMissing2": "you can commit your changes and add them to the version database by running:", + "VersionShaMissing3": "wip", + "_VersionShaMissing3.comment": "This is short for 'work in progress' and must be enclosed in \" quotes if it is more than 1 word", + "VersionShaMissing4": "[{package_name}] Add new port", + "_VersionShaMissing4.comment": "An example of {package_name} is zlib.", "VersionSharpMustBeFollowedByPortVersion": "'#' in version text must be followed by a port version", "VersionSharpMustBeFollowedByPortVersionNonNegativeInteger": "'#' in version text must be followed by a port version (a non-negative integer)", "VersionSpecMismatch": "Failed to load port because versions are inconsistent. The file \"{path}\" contains the version {actual_version}, but the version database indicates that it should be {expected_version}.", @@ -1640,10 +1655,8 @@ "WhileCheckingOutPortTreeIsh": "while checking out port {package_name} with git tree {git_tree_sha}", "_WhileCheckingOutPortTreeIsh.comment": "An example of {package_name} is zlib. An example of {git_tree_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", "WhileGettingLocalTreeIshObjectsForPorts": "while getting local treeish objects for ports", - "WhileLoadingLocalPort": "while attempting to load local port {package_name}", - "_WhileLoadingLocalPort.comment": "An example of {package_name} is zlib.", - "WhileLoadingPortFromGitTree": "while trying to load port from: {commit_sha}", - "_WhileLoadingPortFromGitTree.comment": "An example of {commit_sha} is 7cfad47ae9f68b183983090afd6337cd60fd4949.", + "WhileLoadingBaselineVersionForPort": "while loading baseline version for {package_name}", + "_WhileLoadingBaselineVersionForPort.comment": "An example of {package_name} is zlib.", "WhileLoadingPortVersion": "while loading {version_spec}", "_WhileLoadingPortVersion.comment": "An example of {version_spec} is zlib:x64-windows@1.0.0.", "WhileLookingForSpec": "while looking for {spec}:", diff --git a/src/vcpkg/base/downloads.cpp b/src/vcpkg/base/downloads.cpp index 572318a832..21cf9363e4 100644 --- a/src/vcpkg/base/downloads.cpp +++ b/src/vcpkg/base/downloads.cpp @@ -592,9 +592,7 @@ namespace vcpkg return url; } - std::string query = Strings::join("&", query_params); - - return url + "?" + query; + return url + "?" + Strings::join("&", query_params); } ExpectedL invoke_http_request(StringView method, diff --git a/src/vcpkg/base/json.cpp b/src/vcpkg/base/json.cpp index 990c35bf23..e961030f60 100644 --- a/src/vcpkg/base/json.cpp +++ b/src/vcpkg/base/json.cpp @@ -1474,6 +1474,22 @@ namespace vcpkg::Json .append_raw(msg)); } + LocalizedString Reader::join() const + { + LocalizedString res; + for (const auto& e : m_errors) + { + if (!res.empty()) res.append_raw("\n"); + res.append(e); + } + for (const auto& w : m_warnings) + { + if (!res.empty()) res.append_raw("\n"); + res.append(w); + } + return res; + } + std::string Reader::path() const noexcept { std::string p("$"); diff --git a/src/vcpkg/commands.add-version.cpp b/src/vcpkg/commands.add-version.cpp index 9e8c763e6c..41b63776f7 100644 --- a/src/vcpkg/commands.add-version.cpp +++ b/src/vcpkg/commands.add-version.cpp @@ -168,49 +168,41 @@ namespace const std::string& port_name, const SchemedVersion& port_version, const std::string& git_tree, - const Path& version_db_file_path, bool overwrite_version, bool print_success, bool keep_going, bool skip_version_format_check) { auto& fs = paths.get_filesystem(); - if (!fs.exists(version_db_file_path, IgnoreErrors{})) + auto maybe_maybe_versions = load_git_versions_file(fs, paths.builtin_registry_versions, port_name); + auto maybe_versions = maybe_maybe_versions.entries.get(); + if (!maybe_versions) + { + msg::println(Color::error, maybe_maybe_versions.entries.error()); + Checks::exit_fail(VCPKG_LINE_INFO); + } + + auto versions = maybe_versions->get(); + if (!versions) { if (!skip_version_format_check) { check_used_version_scheme(port_version, port_name); } std::vector new_entry{{port_version, git_tree}}; - write_versions_file(fs, new_entry, version_db_file_path); + write_versions_file(fs, new_entry, maybe_maybe_versions.versions_file_path); if (print_success) { msg::println(Color::success, msg::format(msgAddVersionAddedVersionToFile, msg::version = port_version.version, - msg::path = version_db_file_path) + msg::path = maybe_maybe_versions.versions_file_path) .append_raw(' ') .append(msgAddVersionNewFile)); } return UpdateResult::Updated; } - auto maybe_maybe_versions = get_builtin_versions(paths, port_name); - auto maybe_versions = maybe_maybe_versions.get(); - if (!maybe_versions) - { - msg::println_error(msg::format(msgAddVersionUnableToParseVersionsFile, msg::path = version_db_file_path) - .append_raw('\n') - .append(maybe_maybe_versions.error())); - Checks::exit_fail(VCPKG_LINE_INFO); - } - - auto versions = maybe_versions->get(); - if (!versions) - { - Checks::unreachable(VCPKG_LINE_INFO, "Version file existed but was still unknown"); - } - const auto& versions_end = versions->end(); auto found_same_sha = std::find_if( versions->begin(), versions_end, [&](auto&& entry) -> bool { return entry.git_tree == git_tree; }); @@ -223,7 +215,7 @@ namespace msg::println(Color::success, msgAddVersionVersionAlreadyInFile, msg::version = port_version.version, - msg::path = version_db_file_path); + msg::path = maybe_maybe_versions.versions_file_path); } return UpdateResult::NotUpdated; } @@ -281,13 +273,13 @@ namespace check_used_version_scheme(port_version, port_name); } - write_versions_file(fs, *versions, version_db_file_path); + write_versions_file(fs, *versions, maybe_maybe_versions.versions_file_path); if (print_success) { msg::println(Color::success, msgAddVersionAddedVersionToFile, msg::version = port_version.version, - msg::path = version_db_file_path); + msg::path = maybe_maybe_versions.versions_file_path); } return UpdateResult::Updated; } @@ -386,11 +378,11 @@ namespace vcpkg auto port_dir = paths.builtin_ports_directory() / port_name; auto maybe_scfl = Paragraphs::try_load_port_required( - fs, port_name, PortLocation{paths.builtin_ports_directory() / port_name}); + fs, port_name, PortLocation{paths.builtin_ports_directory() / port_name}) + .maybe_scfl; auto scfl = maybe_scfl.get(); if (!scfl) { - msg::println_error(msgAddVersionLoadPortFailed, msg::package_name = port_name); msg::println(Color::error, maybe_scfl.error()); Checks::check_exit(VCPKG_LINE_INFO, !add_all); continue; @@ -442,14 +434,10 @@ namespace vcpkg Checks::exit_fail(VCPKG_LINE_INFO); } const auto& git_tree = git_tree_it->second; - - char prefix[] = {port_name[0], '-', '\0'}; - auto port_versions_path = paths.builtin_registry_versions / prefix / Strings::concat(port_name, ".json"); auto updated_versions_file = update_version_db_file(paths, port_name, schemed_version, git_tree, - port_versions_path, overwrite_version, verbose, add_all, diff --git a/src/vcpkg/commands.add.cpp b/src/vcpkg/commands.add.cpp index 705f48fe5f..803ca4172a 100644 --- a/src/vcpkg/commands.add.cpp +++ b/src/vcpkg/commands.add.cpp @@ -93,8 +93,13 @@ namespace vcpkg auto pmanifest_scf = maybe_manifest_scf.get(); if (!pmanifest_scf) { - print_error_message(maybe_manifest_scf.error()); - msg::println(Color::error, msgSeeURL, msg::url = docs::manifests_url); + msg::print(Color::error, + std::move(maybe_manifest_scf) + .error() + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgSeeURL, msg::url = docs::manifests_url) + .append_raw('\n')); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/src/vcpkg/commands.autocomplete.cpp b/src/vcpkg/commands.autocomplete.cpp index 5c01ad1b53..dcfedeb282 100644 --- a/src/vcpkg/commands.autocomplete.cpp +++ b/src/vcpkg/commands.autocomplete.cpp @@ -107,7 +107,7 @@ namespace vcpkg // TODO: Support autocomplete for ports in --overlay-ports auto maybe_port = Paragraphs::try_load_port_required( paths.get_filesystem(), port_name, PortLocation{paths.builtin_ports_directory() / port_name}); - if (!maybe_port) + if (!maybe_port.maybe_scfl) { Checks::exit_success(VCPKG_LINE_INFO); } diff --git a/src/vcpkg/commands.ci-verify-versions.cpp b/src/vcpkg/commands.ci-verify-versions.cpp index 0849bb4697..2fd5191cc4 100644 --- a/src/vcpkg/commands.ci-verify-versions.cpp +++ b/src/vcpkg/commands.ci-verify-versions.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -28,187 +29,481 @@ namespace } } - ExpectedL verify_version_in_db(const VcpkgPaths& paths, - const std::map> baseline, - StringView port_name, - const Path& port_path, - const Path& versions_file_path, - const std::string& local_git_tree, - bool verify_git_trees) + bool verify_git_tree(MessageSink& errors_sink, + MessageSink& success_sink, + const VcpkgPaths& paths, + const std::string& port_name, + const Path& versions_file_path, + const GitVersionDbEntry& version_entry) { - auto maybe_maybe_versions = vcpkg::get_builtin_versions(paths, port_name); - const auto maybe_versions = maybe_maybe_versions.get(); - if (!maybe_versions) + bool success = true; + auto maybe_extracted_tree = paths.versions_dot_git_dir().then( + [&](Path&& dot_git) { return paths.git_checkout_port(port_name, version_entry.git_tree, dot_git); }); + auto extracted_tree = maybe_extracted_tree.get(); + if (!extracted_tree) { - return {msg::format_error( - msgWhileParsingVersionsForPort, msg::package_name = port_name, msg::path = versions_file_path) - .append(std::move(maybe_maybe_versions).error()), - expected_right_tag}; + 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')); + return success; } - const auto versions = maybe_versions->get(); - if (!versions || versions->empty()) + auto load_result = + Paragraphs::try_load_port_required(paths.get_filesystem(), port_name, PortLocation{*extracted_tree}); + auto scfl = load_result.maybe_scfl.get(); + if (!scfl) { - return {msg::format_error( - msgWhileParsingVersionsForPort, msg::package_name = port_name, msg::path = versions_file_path) - .append_raw('\n') - .append(msgInvalidNoVersions), - expected_right_tag}; + success = false; + // This output is technically wrong as it prints both the versions file path and the temporary extracted + // path, like this: + // + // C:\Dev\vcpkg\versions\a-\abseil.json: + // C:\Dev\vcpkg\buildtrees\versioning_\versions\abseil\28fa609b06eec70bb06e61891e94b94f35f7d06e\vcpkg.json: + // error: $.features: mismatched type: expected a set of features note: while validating version: + // 2020-03-03#7 + // + // 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')); + return success; } - if (verify_git_trees) + auto&& git_tree_version = scfl->source_control_file->to_schemed_version(); + auto version_entry_spec = VersionSpec{port_name, version_entry.version.version}; + auto scfl_spec = scfl->source_control_file->to_version_spec(); + if (version_entry_spec != scfl_spec) { - for (auto&& version_entry : *versions) - { - bool version_ok = false; - for (StringView control_file : {"CONTROL", "vcpkg.json"}) - { - auto treeish = Strings::concat(version_entry.git_tree, ':', control_file); - auto maybe_file = paths.git_show(Strings::concat(treeish), - paths.versions_dot_git_dir().value_or_exit(VCPKG_LINE_INFO)); - if (!maybe_file) continue; - - const auto& file = maybe_file.value_or_exit(VCPKG_LINE_INFO); - auto maybe_scf = control_file == "vcpkg.json" - ? Paragraphs::try_load_port_manifest_text(file, treeish, out_sink) - : Paragraphs::try_load_control_file_text(file, treeish); - auto scf = maybe_scf.get(); - if (!scf) - { - return {msg::format_error(msgWhileParsingVersionsForPort, - msg::package_name = port_name, - msg::path = versions_file_path) - .append_raw('\n') - .append(msgWhileValidatingVersion, msg::version = version_entry.version.version) - .append_raw('\n') - .append(msgWhileLoadingPortFromGitTree, msg::commit_sha = treeish) - .append_raw('\n') - .append(maybe_scf.error()), - expected_right_tag}; - } - - auto&& git_tree_version = (**scf).to_schemed_version(); - if (version_entry.version.version != git_tree_version.version) - { - return { - msg::format_error(msgWhileParsingVersionsForPort, - msg::package_name = port_name, - msg::path = versions_file_path) - .append_raw('\n') - .append(msgWhileValidatingVersion, msg::version = version_entry.version.version) - .append_raw('\n') - .append(msgVersionInDeclarationDoesNotMatch, msg::version = git_tree_version.version) - .append_raw('\n') - .append(msgCheckedOutGitSha, msg::commit_sha = version_entry.git_tree), - expected_right_tag}; - } - version_ok = true; - break; - } + 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')); + } - if (!version_ok) - { - return {msg::format_error(msgWhileParsingVersionsForPort, - msg::package_name = port_name, - msg::path = versions_file_path) - .append_raw('\n') - .append(msgWhileValidatingVersion, msg::version = version_entry.version.version) - .append_raw('\n') - .append(msgCheckedOutObjectMissingManifest) - .append_raw('\n') - .append(msgCheckedOutGitSha, msg::commit_sha = version_entry.git_tree), - expected_right_tag}; - } - } + 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')); } - auto maybe_scfl = - Paragraphs::try_load_port_required(paths.get_filesystem(), port_name, PortLocation{port_path}); - auto scfl = maybe_scfl.get(); - if (!scfl) + if (success) { - return {msg::format_error(msgWhileLoadingLocalPort, msg::package_name = port_name) - .append_raw('\n') - .append(maybe_scfl.error()), - expected_right_tag}; + 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')); + } + + return success; + } + + bool verify_local_port_matches_version_database(MessageSink& errors_sink, + MessageSink& success_sink, + const std::string& port_name, + const SourceControlFileAndLocation& scfl, + FullGitVersionsDatabase& versions_database, + const std::string& local_git_tree) + { + bool success = true; + const auto& versions_database_entry = versions_database.lookup(port_name); + auto maybe_entries = versions_database_entry.entries.get(); + if (!maybe_entries) + { + // exists, but parse or file I/O error happened + return success; } - const auto local_port_version = scfl->source_control_file->to_schemed_version(); + auto entries = maybe_entries->get(); + 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')); + return success; + } - auto versions_end = versions->end(); - auto it = std::find_if(versions->begin(), versions_end, [&](const GitVersionDbEntry& entry) { + const auto local_port_version = scfl.source_control_file->to_schemed_version(); + const auto local_version_spec = VersionSpec{port_name, local_port_version.version}; + + auto versions_end = entries->end(); + auto it = std::find_if(entries->begin(), versions_end, [&](const GitVersionDbEntry& entry) { return entry.version.version == local_port_version.version; }); + if (it == versions_end) { - return {msg::format_error( - msgWhileParsingVersionsForPort, msg::package_name = port_name, msg::path = versions_file_path) - .append_raw('\n') - .append(msgVersionNotFoundInVersionsFile, - msg::version = local_port_version.version, - msg::package_name = port_name), - expected_right_tag}; + 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')); + return success; } - auto& entry = *it; - if (entry.version.scheme != local_port_version.scheme) + auto& version_entry = *it; + if (version_entry.version.scheme != local_port_version.scheme) { - return {msg::format_error( - msgWhileParsingVersionsForPort, msg::package_name = port_name, msg::path = versions_file_path) - .append_raw('\n') - .append(msgVersionSchemeMismatch, - msg::version = entry.version.version, - msg::expected = get_scheme_name(entry.version.scheme), - msg::actual = get_scheme_name(local_port_version.scheme), - msg::path = port_path, - msg::package_name = port_name), - expected_right_tag}; + success = false; + // assume the port is correct, so report the error on the version database file + errors_sink.print( + Color::error, + LocalizedString::from_raw(versions_database_entry.versions_file_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionSchemeMismatch1, + msg::version = version_entry.version.version, + msg::expected = get_scheme_name(version_entry.version.scheme), + msg::actual = get_scheme_name(local_port_version.scheme), + 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(msgVersionSchemeMismatch2) + .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))); } - if (local_git_tree != entry.git_tree) + if (local_git_tree != version_entry.git_tree) { - return {msg::format_error( - msgWhileParsingVersionsForPort, msg::package_name = port_name, msg::path = versions_file_path) - .append_raw('\n') - .append(msgVersionShaMismatch, - msg::version = entry.version.version, - msg::expected = entry.git_tree, - msg::actual = local_git_tree, - msg::package_name = port_name), - expected_right_tag}; + 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')); + } + + 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')); } + return success; + } + + bool verify_local_port_matches_baseline(MessageSink& errors_sink, + MessageSink& success_sink, + const std::map> baseline, + const Path& baseline_path, + const std::string& port_name, + const SourceControlFileAndLocation& scfl) + { + const auto local_port_version = scfl.source_control_file->to_schemed_version(); auto maybe_baseline = baseline.find(port_name); if (maybe_baseline == baseline.end()) { - return {msg::format_error( - msgWhileParsingVersionsForPort, msg::package_name = port_name, msg::path = versions_file_path) - .append_raw('\n') - .append(msgBaselineMissing, - msg::package_name = port_name, - msg::version = local_port_version.version), - expected_right_tag}; + 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')); + return false; } auto&& baseline_version = maybe_baseline->second; - if (baseline_version != entry.version.version) + if (baseline_version == local_port_version.version) { - return {msg::format_error( - msgWhileParsingVersionsForPort, msg::package_name = port_name, msg::path = versions_file_path) - .append_raw('\n') - .append(msgVersionBaselineMismatch, - msg::expected = entry.version.version, - msg::actual = baseline_version, - msg::package_name = port_name), - expected_right_tag}; + 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')); + 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')); + return false; + } + + bool verify_dependency_and_version_constraint(const Dependency& dependency, + const std::string* feature_name, + MessageSink& errors_sink, + const SourceControlFileAndLocation& scfl, + FullGitVersionsDatabase& versions_database) + { + auto dependent_versions_db_entry = versions_database.lookup(dependency.name); + auto maybe_dependent_entries = dependent_versions_db_entry.entries.get(); + if (!maybe_dependent_entries) + { + // versions database parse or I/O error + return false; + } + + auto dependent_entries = maybe_dependent_entries->get(); + if (!dependent_entries) + { + auto this_error = LocalizedString::from_raw(scfl.control_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgDependencyNotInVersionDatabase, msg::package_name = dependency.name) + .append_raw('\n'); + if (feature_name) + { + this_error.append_raw(NotePrefix) + .append(msgDependencyInFeature, msg::feature = *feature_name) + .append_raw('\n'); + } + + errors_sink.print(Color::error, std::move(this_error)); + return false; + } + + auto maybe_minimum_version = dependency.constraint.try_get_minimum_version(); + auto minimum_version = maybe_minimum_version.get(); + if (minimum_version && Util::none_of(*dependent_entries, [=](const GitVersionDbEntry& entry) { + return entry.version.version == *minimum_version; + })) + { + auto this_error = LocalizedString::from_raw(scfl.control_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionConstraintNotInDatabase1, + msg::package_name = dependency.name, + msg::version = *minimum_version) + .append_raw('\n') + .append_raw(dependent_versions_db_entry.versions_file_path) + .append_raw(": ") + .append_raw(NotePrefix) + .append(msgVersionConstraintNotInDatabase2) + .append_raw('\n'); + if (feature_name) + { + this_error.append_raw(NotePrefix) + .append(msgDependencyInFeature, msg::feature = *feature_name) + .append_raw('\n'); + } + + errors_sink.print(Color::error, std::move(this_error)); + return false; + } + + return true; + } + + bool verify_all_dependencies_and_version_constraints(MessageSink& errors_sink, + MessageSink& success_sink, + const SourceControlFileAndLocation& scfl, + FullGitVersionsDatabase& versions_database) + { + bool success = true; + + for (auto&& core_dependency : scfl.source_control_file->core_paragraph->dependencies) + { + success &= verify_dependency_and_version_constraint( + core_dependency, nullptr, errors_sink, scfl, versions_database); + } + + for (auto&& feature : scfl.source_control_file->feature_paragraphs) + { + for (auto&& feature_dependency : feature->dependencies) + { + success &= verify_dependency_and_version_constraint( + feature_dependency, &feature->name, errors_sink, scfl, versions_database); + } + } + + for (auto&& override_ : scfl.source_control_file->core_paragraph->overrides) + { + auto override_versions_db_entry = versions_database.lookup(override_.name); + auto maybe_override_entries = override_versions_db_entry.entries.get(); + if (!maybe_override_entries) + { + success = false; + continue; + } + + auto override_entries = maybe_override_entries->get(); + if (!override_entries) + { + success = false; + errors_sink.print( + Color::error, + LocalizedString::from_raw(scfl.control_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionOverrideNotInVersionDatabase, msg::package_name = override_.name) + .append_raw('\n')); + continue; + } + + if (Util::none_of(*override_entries, [&](const GitVersionDbEntry& entry) { + return entry.version.version == override_.version; + })) + { + 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')); + } + } + + if (success) + { + success_sink.print(LocalizedString::from_raw(scfl.control_path) + .append_raw(": ") + .append_raw(MessagePrefix) + .append(msgVersionConstraintOk) + .append_raw('\n')); } - return { - message_prefix().append(msgVersionVerifiedOK, - msg::version_spec = Strings::concat(port_name, '@', entry.version.version), - msg::git_tree_sha = entry.git_tree), - expected_left_tag, - }; + return success; } constexpr CommandSwitch VERIFY_VERSIONS_SWITCHES[]{ @@ -216,9 +511,6 @@ namespace {SwitchVerifyGitTrees, msgCISettingsVerifyGitTree}, }; - constexpr CommandSetting VERIFY_VERSIONS_SETTINGS[] = { - {SwitchExclude, msgCISettingsExclude}, - }; } // unnamed namespace namespace vcpkg @@ -231,7 +523,7 @@ namespace vcpkg AutocompletePriority::Internal, 0, SIZE_MAX, - {VERIFY_VERSIONS_SWITCHES, VERIFY_VERSIONS_SETTINGS}, + {VERIFY_VERSIONS_SWITCHES}, nullptr, }; @@ -242,114 +534,117 @@ namespace vcpkg bool verbose = Util::Sets::contains(parsed_args.switches, SwitchVerbose); bool verify_git_trees = Util::Sets::contains(parsed_args.switches, SwitchVerifyGitTrees); - std::set exclusion_set; - auto& settings = parsed_args.settings; - auto it_exclusions = settings.find(SwitchExclude); - if (it_exclusions != settings.end()) - { - auto exclusions = Strings::split(it_exclusions->second, ','); - exclusion_set.insert(std::make_move_iterator(exclusions.begin()), - std::make_move_iterator(exclusions.end())); - } - - auto maybe_port_git_tree_map = paths.git_get_local_port_treeish_map(); - if (!maybe_port_git_tree_map) - { - Checks::msg_exit_with_error(VCPKG_LINE_INFO, - msg::format(msgFailedToObtainLocalPortGitSha) - .append_raw('\n') - .append_raw(maybe_port_git_tree_map.error())); - } + auto port_git_tree_map = paths.git_get_local_port_treeish_map().value_or_exit(VCPKG_LINE_INFO); + auto& fs = paths.get_filesystem(); + auto versions_database = + load_all_git_versions_files(fs, paths.builtin_registry_versions).value_or_exit(VCPKG_LINE_INFO); + auto baseline = get_builtin_baseline(paths).value_or_exit(VCPKG_LINE_INFO); - auto& port_git_tree_map = maybe_port_git_tree_map.value_or_exit(VCPKG_LINE_INFO); + std::map> local_ports; - // Baseline is required. - auto baseline = get_builtin_baseline(paths).value_or_exit(VCPKG_LINE_INFO); - auto& fs = paths.get_filesystem(); - std::set errors; - for (const auto& port_path : fs.get_directories_non_recursive(paths.builtin_ports_directory(), VCPKG_LINE_INFO)) + MessageSink& errors_sink = stdout_sink; + for (auto&& port_path : fs.get_directories_non_recursive(paths.builtin_ports_directory(), VCPKG_LINE_INFO)) { - auto port_name = port_path.stem(); - if (Util::Sets::contains(exclusion_set, port_name.to_string())) + auto port_name = port_path.stem().to_string(); + auto maybe_loaded_port = + Paragraphs::try_load_port_required(fs, port_name, PortLocation{port_path}).maybe_scfl; + auto loaded_port = maybe_loaded_port.get(); + if (loaded_port) { - if (verbose) - { - msg::write_unlocalized_text(Color::error, fmt::format("SKIP: {}\n", port_name)); - } - + local_ports.emplace(port_name, std::move(*loaded_port)); continue; } + + errors_sink.println(Color::error, std::move(maybe_loaded_port).error()); + } + + bool success = true; + + auto& success_sink = verbose ? stdout_sink : null_sink; + for (const auto& local_port : local_ports) + { + const auto& port_name = local_port.first; + const auto& scfl = local_port.second; auto git_tree_it = port_git_tree_map.find(port_name); if (git_tree_it == port_git_tree_map.end()) { - msg::write_unlocalized_text(Color::error, fmt::format("FAIL: {}\n", port_name)); - errors.emplace( - msg::format_error(msgVersionShaMissing, msg::package_name = port_name, msg::path = port_path)); - continue; + errors_sink.print( + Color::error, + LocalizedString::from_raw(scfl.control_path) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgVersionShaMissing1) + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgVersionShaMissing2) + .append_raw('\n') + .append_indent() + .append_raw(fmt::format("git add \"{}\"\n", scfl.port_directory())) + .append_indent() + .append_raw(fmt::format("git commit -m {}\n", msg::format(msgVersionShaMissing3))) + .append_indent() + .append_raw(fmt::format("vcpkg x-add-version {}\n", port_name)) + .append_indent() + .append_raw("git add versions\n") + .append_indent() + .append_raw(fmt::format("git commit --amend -m \"{}\"\n", + msg::format(msgVersionShaMissing4, msg::package_name = port_name)))); } - - auto& git_tree = git_tree_it->second; - auto control_path = port_path / "CONTROL"; - auto manifest_path = port_path / "vcpkg.json"; - auto manifest_exists = fs.exists(manifest_path, IgnoreErrors{}); - auto control_exists = fs.exists(control_path, IgnoreErrors{}); - - if (manifest_exists && control_exists) + else { - msg::write_unlocalized_text(Color::error, fmt::format("FAIL: {}\n", port_name)); - errors.emplace(msg::format_error(msgControlAndManifestFilesPresent, msg::path = port_path)); - continue; + success &= verify_local_port_matches_version_database( + errors_sink, success_sink, port_name, scfl, versions_database, git_tree_it->second); } - if (!manifest_exists && !control_exists) + success &= verify_local_port_matches_baseline(errors_sink, + success_sink, + baseline, + paths.builtin_registry_versions / "baseline.json", + port_name, + scfl); + + success &= + verify_all_dependencies_and_version_constraints(errors_sink, success_sink, scfl, versions_database); + } + + // We run version database checks at the end in case any of the above created new cache entries + for (auto&& versions_cache_entry : versions_database.cache()) + { + auto&& port_name = versions_cache_entry.first; + auto maybe_entries = versions_cache_entry.second.entries.get(); + if (!maybe_entries) { - msg::write_unlocalized_text(Color::error, fmt::format("FAIL: {}\n", port_name)); - errors.emplace(LocalizedString::from_raw(port_path) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgPortMissingManifest2, msg::package_name = port_name)); + errors_sink.println(Color::error, versions_cache_entry.second.entries.error()); continue; } - const char prefix[] = {port_name[0], '-', '\0'}; - auto versions_file_path = paths.builtin_registry_versions / prefix / Strings::concat(port_name, ".json"); - if (!fs.exists(versions_file_path, IgnoreErrors{})) + auto entries = maybe_entries->get(); + if (!entries) { - msg::write_unlocalized_text(Color::error, fmt::format("FAIL: {}\n", port_name)); - errors.emplace(msg::format_error( - msgVersionDatabaseFileMissing, msg::package_name = port_name, msg::path = versions_file_path)); + // missing version database entry is OK; should have been reported as one of the other error + // categories by one of the other checks continue; } - auto maybe_ok = verify_version_in_db( - paths, baseline, port_name, port_path, versions_file_path, git_tree, verify_git_trees); - if (auto ok = maybe_ok.get()) + if (verify_git_trees) { - if (verbose) + for (auto&& version_entry : *entries) { - msg::println(*ok); + success &= verify_git_tree(errors_sink, + success_sink, + paths, + port_name, + versions_cache_entry.second.versions_file_path, + version_entry); } } - else - { - msg::write_unlocalized_text(Color::error, fmt::format("FAIL: {}\n", port_name)); - errors.emplace(std::move(maybe_ok).error()); - } } - if (!errors.empty()) + if (!success) { - auto message = msg::format(msgErrorsFound); - for (auto&& error : errors) - { - message.append_raw('\n').append(error); - } - - message.append_raw('\n').append( - msgSuggestResolution, msg::command_name = "x-add-version", msg::option = "all"); - msg::println_error(message); Checks::exit_fail(VCPKG_LINE_INFO); } + Checks::exit_success(VCPKG_LINE_INFO); } } // namespace vcpkg diff --git a/src/vcpkg/commands.format-manifest.cpp b/src/vcpkg/commands.format-manifest.cpp index 64338b7bad..d9e37f5eb2 100644 --- a/src/vcpkg/commands.format-manifest.cpp +++ b/src/vcpkg/commands.format-manifest.cpp @@ -3,13 +3,12 @@ #include #include #include -#include +#include #include #include #include #include -#include #include #include @@ -19,86 +18,18 @@ namespace { struct ToWrite { - SourceControlFile scf; - Path file_to_write; - Path original_path; std::string original_source; + std::unique_ptr scf; + Path control_path; + Path file_to_write; }; - Optional read_manifest(const ReadOnlyFilesystem& fs, Path&& manifest_path) - { - const auto& path_string = manifest_path.native(); - Debug::println("Reading ", path_string); - auto contents = fs.read_contents(manifest_path, VCPKG_LINE_INFO); - auto parsed_json_opt = Json::parse(contents, manifest_path); - if (!parsed_json_opt) - { - msg::println(Color::error, parsed_json_opt.error()); - return nullopt; - } - - const auto& parsed_json = parsed_json_opt.value(VCPKG_LINE_INFO).value; - if (!parsed_json.is_object()) - { - msg::println_error(msgJsonErrorMustBeAnObject, msg::path = path_string); - return nullopt; - } - - auto parsed_json_obj = parsed_json.object(VCPKG_LINE_INFO); - - auto scf = SourceControlFile::parse_project_manifest_object(path_string, parsed_json_obj, out_sink); - if (!scf) - { - msg::println_error(msgFailedToParseManifest, msg::path = path_string); - print_error_message(scf.error()); - return nullopt; - } - - return ToWrite{ - std::move(*scf.value(VCPKG_LINE_INFO)), - manifest_path, - manifest_path, - std::move(contents), - }; - } - - Optional read_control_file(const ReadOnlyFilesystem& fs, Path&& control_path) - { - Debug::println("Reading ", control_path); - - auto manifest_path = Path(control_path.parent_path()) / "vcpkg.json"; - auto contents = fs.read_contents(control_path, VCPKG_LINE_INFO); - auto paragraphs = Paragraphs::parse_paragraphs(contents, control_path); - - if (!paragraphs) - { - msg::println_error(msg::format(msgFailedToReadParagraph, msg::path = control_path) - .append_raw(": ") - .append_raw(paragraphs.error())); - return {}; - } - auto scf_res = - SourceControlFile::parse_control_file(control_path, std::move(paragraphs).value(VCPKG_LINE_INFO)); - if (!scf_res) - { - msg::println_error(msgFailedToParseControl, msg::path = control_path); - print_error_message(scf_res.error()); - return {}; - } - - return ToWrite{ - std::move(*scf_res.value(VCPKG_LINE_INFO)), - manifest_path, - control_path, - std::move(contents), - }; - } - void open_for_write(const Filesystem& fs, const ToWrite& data) { - const auto& original_path_string = data.original_path.native(); + const auto& original_path_string = data.control_path.native(); const auto& file_to_write_string = data.file_to_write.native(); - if (data.file_to_write == data.original_path) + bool in_place = data.file_to_write == original_path_string; + if (in_place) { Debug::println("Formatting ", file_to_write_string); } @@ -107,14 +38,14 @@ namespace Debug::println("Converting ", original_path_string, " -> ", file_to_write_string); } - auto res = serialize_manifest(data.scf); + auto res = serialize_manifest(*data.scf); // reparse res to ensure no semantic changes were made - auto maybe_reparsed = SourceControlFile::parse_project_manifest_object("", res, null_sink); + auto maybe_reparsed = SourceControlFile::parse_project_manifest_object(StringView{}, res, null_sink); bool reparse_matches; if (auto reparsed = maybe_reparsed.get()) { - reparse_matches = **reparsed == data.scf; + reparse_matches = **reparsed == *data.scf; } else { @@ -132,26 +63,10 @@ namespace Json::stringify(res, {})))); } - // the manifest scf is correct - std::error_code ec; - fs.write_contents(data.file_to_write, Json::stringify(res), ec); - if (ec) + fs.write_contents(data.file_to_write, Json::stringify(res), VCPKG_LINE_INFO); + if (!in_place) { - Checks::msg_exit_with_error(VCPKG_LINE_INFO, - msg::format(msgFailedToWriteManifest, msg::path = file_to_write_string) - .append_raw(": ") - .append_raw(ec.message())); - } - if (data.original_path != data.file_to_write) - { - fs.remove(data.original_path, ec); - if (ec) - { - Checks::msg_exit_with_error(VCPKG_LINE_INFO, - msg::format(msgFailedToRemoveControl, msg::path = original_path_string) - .append_raw(": ") - .append_raw(ec.message())); - } + fs.remove(original_path_string, VCPKG_LINE_INFO); } } @@ -197,18 +112,6 @@ namespace vcpkg } std::vector to_write; - - const auto add_file = [&to_write, &has_error](Optional&& opt) { - if (auto t = opt.get()) - { - to_write.push_back(std::move(*t)); - } - else - { - has_error = true; - } - }; - for (Path path : parsed_args.command_arguments) { if (path.is_relative()) @@ -216,13 +119,44 @@ namespace vcpkg path = paths.original_cwd / path; } + auto maybe_contents = fs.try_read_contents(path); + auto contents = maybe_contents.get(); + if (!contents) + { + has_error = true; + msg::println(maybe_contents.error()); + continue; + } + if (path.filename() == "CONTROL") { - add_file(read_control_file(fs, std::move(path))); + auto maybe_control = Paragraphs::try_load_control_file_text(contents->content, contents->origin); + if (auto control = maybe_control.get()) + { + to_write.push_back(ToWrite{contents->content, + std::move(*control), + std::move(path), + Path(path.parent_path()) / "vcpkg.json"}); + } + else + { + has_error = true; + msg::println(maybe_control.error()); + } } else { - add_file(read_manifest(fs, std::move(path))); + auto maybe_manifest = + Paragraphs::try_load_project_manifest_text(contents->content, contents->origin, stdout_sink); + if (auto manifest = maybe_manifest.get()) + { + to_write.push_back(ToWrite{contents->content, std::move(*manifest), path, path}); + } + else + { + has_error = true; + msg::println(maybe_manifest.error()); + } } } @@ -230,23 +164,32 @@ namespace vcpkg { for (const auto& dir : fs.get_directories_non_recursive(paths.builtin_ports_directory(), VCPKG_LINE_INFO)) { - auto control_path = dir / "CONTROL"; - auto manifest_path = dir / "vcpkg.json"; - auto manifest_exists = fs.exists(manifest_path, IgnoreErrors{}); - auto control_exists = fs.exists(control_path, IgnoreErrors{}); - - if (manifest_exists && control_exists) - { - Checks::msg_exit_with_error(VCPKG_LINE_INFO, msgControlAndManifestFilesPresent, msg::path = dir); - } - - if (manifest_exists) + auto maybe_manifest = Paragraphs::try_load_port_required(fs, dir.filename(), PortLocation{dir}); + if (auto manifest = maybe_manifest.maybe_scfl.get()) { - add_file(read_manifest(fs, std::move(manifest_path))); + auto original = manifest->control_path; + if (original.filename() == "CONTROL") + { + if (convert_control) + { + to_write.push_back(ToWrite{maybe_manifest.on_disk_contents, + std::move(manifest->source_control_file), + original, + Path(original.parent_path()) / "vcpkg.json"}); + } + } + else + { + to_write.push_back(ToWrite{maybe_manifest.on_disk_contents, + std::move(manifest->source_control_file), + original, + original}); + } } - if (convert_control && control_exists) + else { - add_file(read_control_file(fs, std::move(control_path))); + has_error = true; + msg::println(maybe_manifest.maybe_scfl.error()); } } } diff --git a/src/vcpkg/commands.install.cpp b/src/vcpkg/commands.install.cpp index 5b1f16dc9d..6d91d65382 100644 --- a/src/vcpkg/commands.install.cpp +++ b/src/vcpkg/commands.install.cpp @@ -1152,9 +1152,13 @@ namespace vcpkg SourceControlFile::parse_project_manifest_object(manifest->path, manifest->manifest, out_sink); if (!maybe_manifest_scf) { - print_error_message(maybe_manifest_scf.error()); - msg::println(); - msg::println(msgExtendedDocumentationAtUrl, msg::url = docs::manifests_url); + msg::println(Color::error, + std::move(maybe_manifest_scf) + .error() + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgExtendedDocumentationAtUrl, msg::url = docs::manifests_url) + .append_raw('\n')); Checks::exit_fail(VCPKG_LINE_INFO); } diff --git a/src/vcpkg/paragraphs.cpp b/src/vcpkg/paragraphs.cpp index efdf97cf14..5430ae84a8 100644 --- a/src/vcpkg/paragraphs.cpp +++ b/src/vcpkg/paragraphs.cpp @@ -358,6 +358,16 @@ namespace vcpkg::Paragraphs fs.exists(maybe_directory / "vcpkg.json", IgnoreErrors{}); } + ExpectedL> try_load_project_manifest_text(StringView text, + StringView control_path, + MessageSink& warning_sink) + { + StatsTimer timer(g_load_ports_stats); + return Json::parse_object(text, control_path).then([&](Json::Object&& object) { + return SourceControlFile::parse_project_manifest_object(control_path, std::move(object), warning_sink); + }); + } + ExpectedL> try_load_port_manifest_text(StringView text, StringView control_path, MessageSink& warning_sink) @@ -376,9 +386,7 @@ namespace vcpkg::Paragraphs }); } - ExpectedL try_load_port(const ReadOnlyFilesystem& fs, - StringView port_name, - const PortLocation& port_location) + PortLoadResult try_load_port(const ReadOnlyFilesystem& fs, StringView port_name, const PortLocation& port_location) { StatsTimer timer(g_load_ports_stats); @@ -390,67 +398,77 @@ namespace vcpkg::Paragraphs { if (fs.exists(control_path, IgnoreErrors{})) { - return msg::format_error(msgManifestConflict, msg::path = port_location.port_directory); + return PortLoadResult{LocalizedString::from_raw(port_location.port_directory) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgManifestConflict2), + std::string{}}; } - return 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}; - }); + return PortLoadResult{try_load_port_manifest_text(manifest_contents, manifest_path, stdout_sink) + .map([&](std::unique_ptr&& scf) { + return SourceControlFileAndLocation{ + std::move(scf), std::move(manifest_path), port_location.spdx_location}; + }), + manifest_contents}; } auto manifest_exists = ec != std::errc::no_such_file_or_directory; if (manifest_exists) { - return msg::format_error(msgFailedToParseManifest, msg::path = manifest_path) - .append_raw("\n") - .append(format_filesystem_call_error(ec, "read_contents", {manifest_path})); + return PortLoadResult{LocalizedString::from_raw(port_location.port_directory) + .append_raw(": ") + .append(format_filesystem_call_error(ec, "read_contents", {manifest_path})), + std::string{}}; } auto control_contents = fs.read_contents(control_path, ec); if (!ec) { - return try_load_control_file_text(control_contents, control_path) - .map([&](std::unique_ptr&& scf) { - return SourceControlFileAndLocation{ - std::move(scf), std::move(control_path), port_location.spdx_location}; - }); + return PortLoadResult{try_load_control_file_text(control_contents, control_path) + .map([&](std::unique_ptr&& scf) { + return SourceControlFileAndLocation{ + std::move(scf), std::move(control_path), port_location.spdx_location}; + }), + control_contents}; } if (ec != std::errc::no_such_file_or_directory) { - return LocalizedString::from_raw(port_location.port_directory) - .append_raw(": ") - .append(format_filesystem_call_error(ec, "read_contents", {control_path})); + return PortLoadResult{LocalizedString::from_raw(port_location.port_directory) + .append_raw(": ") + .append(format_filesystem_call_error(ec, "read_contents", {control_path})), + std::string{}}; } if (fs.exists(port_location.port_directory, IgnoreErrors{})) { - return LocalizedString::from_raw(port_location.port_directory) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgPortMissingManifest2, msg::package_name = port_name); + return PortLoadResult{LocalizedString::from_raw(port_location.port_directory) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgPortMissingManifest2, msg::package_name = port_name), + std::string{}}; } - return LocalizedString::from_raw(port_location.port_directory) - .append_raw(": ") - .append_raw(ErrorPrefix) - .append(msgPortDoesNotExist, msg::package_name = port_name); + return PortLoadResult{LocalizedString::from_raw(port_location.port_directory) + .append_raw(": ") + .append_raw(ErrorPrefix) + .append(msgPortDoesNotExist, msg::package_name = port_name), + std::string{}}; } - ExpectedL try_load_port_required(const ReadOnlyFilesystem& fs, - StringView port_name, - const PortLocation& port_location) + PortLoadResult try_load_port_required(const ReadOnlyFilesystem& fs, + StringView port_name, + const PortLocation& port_location) { auto load_result = try_load_port(fs, port_name, port_location); - auto maybe_res = load_result.get(); + auto maybe_res = load_result.maybe_scfl.get(); if (maybe_res) { auto res = maybe_res->source_control_file.get(); if (!res) { - load_result = msg::format_error(msgPortDoesNotExist, msg::package_name = port_name); + load_result.maybe_scfl = msg::format_error(msgPortDoesNotExist, msg::package_name = port_name); } } @@ -515,8 +533,8 @@ namespace vcpkg::Paragraphs auto maybe_port_location = (*port_entry)->get_version(*baseline_version); const auto port_location = maybe_port_location.get(); if (!port_location) continue; // baseline version was not in version db (registry consistency issue) - auto maybe_scfl = try_load_port_required(fs, port_name, *port_location); - if (const auto scfl = maybe_scfl.get()) + auto maybe_result = try_load_port_required(fs, port_name, *port_location); + if (const auto scfl = maybe_result.maybe_scfl.get()) { ret.paragraphs.push_back(std::move(*scfl)); } @@ -524,7 +542,7 @@ namespace vcpkg::Paragraphs { ret.errors.emplace_back(std::piecewise_construct, std::forward_as_tuple(port_name.data(), port_name.size()), - std::forward_as_tuple(std::move(maybe_scfl).error())); + std::forward_as_tuple(std::move(maybe_result.maybe_scfl).error())); } } @@ -577,7 +595,7 @@ namespace vcpkg::Paragraphs for (auto&& path : port_dirs) { auto port_name = path.filename(); - auto maybe_spgh = try_load_port_required(fs, port_name, PortLocation{path}); + 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)); diff --git a/src/vcpkg/portfileprovider.cpp b/src/vcpkg/portfileprovider.cpp index d4e3ff4c63..a1fa7a47c9 100644 --- a/src/vcpkg/portfileprovider.cpp +++ b/src/vcpkg/portfileprovider.cpp @@ -99,20 +99,16 @@ namespace vcpkg virtual ExpectedL get_baseline_version(StringView port_name) const override { return m_baseline_cache.get_lazy(port_name, [this, port_name]() -> ExpectedL { - auto maybe_maybe_version = registry_set.baseline_for_port(port_name); - auto maybe_version = maybe_maybe_version.get(); - if (!maybe_version) - { - return std::move(maybe_maybe_version).error(); - } - - auto version = maybe_version->get(); - if (!version) - { - return msg::format_error(msgPortNotInBaseline, msg::package_name = port_name); - } + return registry_set.baseline_for_port(port_name).then( + [&](Optional&& maybe_version) -> ExpectedL { + auto version = maybe_version.get(); + if (!version) + { + return msg::format_error(msgPortNotInBaseline, msg::package_name = port_name); + } - return std::move(*version); + return std::move(*version); + }); }); } @@ -181,10 +177,11 @@ namespace vcpkg auto maybe_path = ent->get()->get_version(version_spec.version); if (auto path = maybe_path.get()) { - auto maybe_scfl = Paragraphs::try_load_port_required(m_fs, version_spec.port_name, *path); + auto maybe_scfl = + Paragraphs::try_load_port_required(m_fs, version_spec.port_name, *path).maybe_scfl; if (auto scfl = maybe_scfl.get()) { - auto scf_vspec = scfl->source_control_file->to_version_spec(); + auto scf_vspec = scfl->to_version_spec(); if (scf_vspec == version_spec) { return std::move(*scfl); @@ -279,7 +276,8 @@ namespace vcpkg // 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}); + 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) @@ -300,7 +298,8 @@ namespace vcpkg 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}); + 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(); @@ -350,7 +349,8 @@ namespace vcpkg 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}); + 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 diff --git a/src/vcpkg/registries.cpp b/src/vcpkg/registries.cpp index 2ab0267639..9f839fc1a3 100644 --- a/src/vcpkg/registries.cpp +++ b/src/vcpkg/registries.cpp @@ -483,8 +483,9 @@ namespace private: const ExpectedL& get_scfl(StringView port_name, const Path& path) const { - return m_scfls.get_lazy( - path, [&, this]() { return Paragraphs::try_load_port(m_fs, port_name, PortLocation{path}); }); + return m_scfls.get_lazy(path, [&, this]() { + return Paragraphs::try_load_port(m_fs, port_name, PortLocation{path}).maybe_scfl; + }); } const ReadOnlyFilesystem& m_fs; @@ -579,12 +580,6 @@ namespace }; Path relative_path_to_versions(StringView port_name); - ExpectedL>> load_git_versions_file(const ReadOnlyFilesystem& fs, - const Path& registry_versions, - StringView port_name); - - ExpectedL>> load_filesystem_versions_file( - const ReadOnlyFilesystem& fs, const Path& registry_versions, StringView port_name, const Path& registry_root); // returns nullopt if the baseline is valid, but doesn't contain the specified baseline, // or (equivalently) if the baseline does not exist. @@ -700,48 +695,40 @@ namespace ExpectedL> BuiltinFilesRegistry::get_port_entry(StringView port_name) const { auto port_directory = m_builtin_ports_directory / port_name; - const auto& maybe_maybe_scfl = get_scfl(port_name, port_directory); - const auto maybe_scfl = maybe_maybe_scfl.get(); - if (!maybe_scfl) - { - return maybe_maybe_scfl.error(); - } - - auto scf = maybe_scfl->source_control_file.get(); - if (!scf) - { - return std::unique_ptr(); - } + return get_scfl(port_name, port_directory) + .then([&](const SourceControlFileAndLocation& scfl) -> ExpectedL> { + auto scf = scfl.source_control_file.get(); + if (!scf) + { + return std::unique_ptr(); + } - if (scf->core_paragraph->name == port_name) - { - return std::make_unique( - scf->core_paragraph->name, port_directory, scf->to_version()); - } + if (scf->core_paragraph->name == port_name) + { + return std::make_unique( + scf->core_paragraph->name, port_directory, scf->to_version()); + } - return msg::format_error(msgUnexpectedPortName, - msg::expected = scf->core_paragraph->name, - msg::actual = port_name, - msg::path = port_directory); + return msg::format_error(msgUnexpectedPortName, + msg::expected = scf->core_paragraph->name, + msg::actual = port_name, + msg::path = port_directory); + }); } ExpectedL> BuiltinFilesRegistry::get_baseline_version(StringView port_name) const { // if a baseline is not specified, use the ports directory version - const auto& maybe_maybe_scfl = get_scfl(port_name, m_builtin_ports_directory / port_name); - auto maybe_scfl = maybe_maybe_scfl.get(); - if (!maybe_scfl) - { - return maybe_maybe_scfl.error(); - } - - auto scf = maybe_scfl->source_control_file.get(); - if (!scf) - { - return Optional(); - } + return get_scfl(port_name, m_builtin_ports_directory / port_name) + .then([&](const SourceControlFileAndLocation& scfl) -> ExpectedL> { + auto scf = scfl.source_control_file.get(); + if (!scf) + { + return Optional(); + } - return scf->to_version(); + return scf->to_version(); + }); } ExpectedL BuiltinFilesRegistry::append_all_port_names(std::vector& out) const @@ -775,40 +762,31 @@ namespace const auto& fs = m_paths.get_filesystem(); auto versions_path = m_paths.builtin_registry_versions / relative_path_to_versions(port_name); - auto maybe_maybe_version_entries = load_git_versions_file(fs, m_paths.builtin_registry_versions, port_name); - auto maybe_version_entries = maybe_maybe_version_entries.get(); - if (!maybe_version_entries) - { - return std::move(maybe_maybe_version_entries).error(); - } - - auto version_entries = maybe_version_entries->get(); - if (!version_entries) - { - return m_files_impl->get_port_entry(port_name); - } + return load_git_versions_file(fs, m_paths.builtin_registry_versions, port_name) + .entries.then([this, &port_name](Optional>&& maybe_version_entries) + -> ExpectedL> { + auto version_entries = maybe_version_entries.get(); + if (!version_entries) + { + return m_files_impl->get_port_entry(port_name); + } - 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)); - return res; + 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)); + return res; + }); } - ExpectedL> BuiltinGitRegistry::get_baseline_version(StringView port_name) const + ExpectedL> lookup_in_maybe_baseline(const ExpectedL& maybe_baseline, + StringView port_name) { - const auto& maybe_baseline = m_baseline.get([this]() -> ExpectedL { - return git_checkout_baseline(m_paths, m_baseline_identifier) - .then([&](Path&& path) { return load_baseline_versions(m_paths.get_filesystem(), path); }) - .map_error([&](LocalizedString&& error) { - return std::move(error).append(msgWhileCheckingOutBaseline, - msg::commit_sha = m_baseline_identifier); - }); - }); - auto baseline = maybe_baseline.get(); if (!baseline) { - return maybe_baseline.error(); + return LocalizedString(maybe_baseline.error()) + .append_raw('\n') + .append(msgWhileLoadingBaselineVersionForPort, msg::package_name = port_name); } auto it = baseline->find(port_name); @@ -820,6 +798,19 @@ namespace return Optional(); } + ExpectedL> BuiltinGitRegistry::get_baseline_version(StringView port_name) const + { + return lookup_in_maybe_baseline(m_baseline.get([this]() -> ExpectedL { + return git_checkout_baseline(m_paths, m_baseline_identifier) + .then([&](Path&& path) { return load_baseline_versions(m_paths.get_filesystem(), path); }) + .map_error([&](LocalizedString&& error) { + return std::move(error).append(msgWhileCheckingOutBaseline, + msg::commit_sha = m_baseline_identifier); + }); + }), + port_name); + } + ExpectedL BuiltinGitRegistry::append_all_port_names(std::vector& out) const { const auto& fs = m_paths.get_filesystem(); @@ -843,45 +834,32 @@ namespace // { FilesystemRegistry::RegistryImplementation ExpectedL> FilesystemRegistry::get_baseline_version(StringView port_name) const { - return m_baseline - .get([this]() { - return load_baseline_versions(m_fs, m_path / FileVersions / FileBaselineDotJson, m_baseline_identifier); - }) - .then([&](const Baseline& baseline) -> ExpectedL> { - auto it = baseline.find(port_name); - if (it != baseline.end()) - { - return it->second; - } - - return Optional(); - }); + return lookup_in_maybe_baseline(m_baseline.get([this]() { + return load_baseline_versions(m_fs, m_path / FileVersions / FileBaselineDotJson, m_baseline_identifier); + }), + port_name); } ExpectedL> FilesystemRegistry::get_port_entry(StringView port_name) const { - auto maybe_maybe_version_entries = - load_filesystem_versions_file(m_fs, m_path / FileVersions, port_name, m_path); - auto maybe_version_entries = maybe_maybe_version_entries.get(); - if (!maybe_version_entries) - { - return std::move(maybe_maybe_version_entries).error(); - } - - auto version_entries = maybe_version_entries->get(); - if (!version_entries) - { - return std::unique_ptr{}; - } + return load_filesystem_versions_file(m_fs, m_path / FileVersions, port_name, m_path) + .then([&](Optional>&& maybe_version_entries) + -> ExpectedL> { + auto version_entries = maybe_version_entries.get(); + if (!version_entries) + { + return std::unique_ptr{}; + } - auto res = std::make_unique(port_name.to_string()); - for (auto&& version_entry : *version_entries) - { - res->port_versions.push_back(std::move(version_entry.version.version)); - res->version_paths.push_back(std::move(version_entry.p)); - } + auto res = std::make_unique(port_name.to_string()); + for (auto&& version_entry : *version_entries) + { + res->port_versions.push_back(std::move(version_entry.version.version)); + res->version_paths.push_back(std::move(version_entry.p)); + } - return res; + return res; + }); } ExpectedL FilesystemRegistry::append_all_port_names(std::vector& out) const @@ -908,7 +886,7 @@ namespace { // try to load using "stale" version database auto maybe_maybe_version_entries = - load_git_versions_file(m_paths.get_filesystem(), stale_vtp->p, port_name); + load_git_versions_file(m_paths.get_filesystem(), stale_vtp->p, port_name).entries; auto maybe_version_entries = maybe_maybe_version_entries.get(); if (!maybe_version_entries) { @@ -929,30 +907,20 @@ namespace return std::unique_ptr(); } - auto maybe_live_vdb = get_versions_tree_path(); - auto live_vcb = maybe_live_vdb.get(); - if (!live_vcb) - { - return std::move(maybe_live_vdb).error(); - } + return get_versions_tree_path().then([this, &port_name](const Path& live_vcb) { + return load_git_versions_file(m_paths.get_filesystem(), live_vcb, port_name) + .entries.then([this, &port_name](Optional>&& maybe_version_entries) + -> ExpectedL> { + auto version_entries = maybe_version_entries.get(); + if (!version_entries) + { + // data is already live but we don't know of this port + return std::unique_ptr(); + } - { - auto maybe_maybe_version_entries = load_git_versions_file(m_paths.get_filesystem(), *live_vcb, port_name); - auto maybe_version_entries = maybe_maybe_version_entries.get(); - if (!maybe_version_entries) - { - return std::move(maybe_maybe_version_entries).error(); - } - - auto version_entries = maybe_version_entries->get(); - if (!version_entries) - { - // data is already live but we don't know of this port - return std::unique_ptr(); - } - - return std::make_unique(port_name, *this, false, std::move(*version_entries)); - } + return std::make_unique(port_name, *this, false, std::move(*version_entries)); + }); + }); } GitRegistryEntry::GitRegistryEntry(StringView port_name, @@ -968,7 +936,7 @@ namespace ExpectedL> GitRegistry::get_baseline_version(StringView port_name) const { - const auto& maybe_baseline = m_baseline.get([this, port_name]() -> ExpectedL { + return lookup_in_maybe_baseline(m_baseline.get([this, port_name]() -> ExpectedL { // We delay baseline validation until here to give better error messages and suggestions if (!is_git_commit_sha(m_baseline_identifier)) { @@ -1045,21 +1013,8 @@ namespace .append_raw('\n') .append(error); }); - }); - - auto baseline = maybe_baseline.get(); - if (!baseline) - { - return maybe_baseline.error(); - } - - auto it = baseline->find(port_name); - if (it != baseline->end()) - { - return it->second; - } - - return Optional(); + }), + port_name); } ExpectedL GitRegistry::append_all_port_names(std::vector& out) const @@ -1155,7 +1110,7 @@ namespace } auto maybe_maybe_version_entries = - load_git_versions_file(parent.m_paths.get_filesystem(), *live_vdb, port_name); + load_git_versions_file(parent.m_paths.get_filesystem(), *live_vdb, port_name).entries; auto maybe_version_entries = maybe_maybe_version_entries.get(); if (!maybe_version_entries) { @@ -1261,113 +1216,17 @@ namespace return Path(prefix) / port_name.to_string() + ".json"; } - ExpectedL>> load_git_versions_file(const ReadOnlyFilesystem& fs, - const Path& registry_versions, - StringView port_name) - { - auto versions_file_path = registry_versions / relative_path_to_versions(port_name); - std::error_code ec; - auto contents = fs.read_contents(versions_file_path, ec); - if (ec) - { - if (ec == std::errc::no_such_file_or_directory) - { - return Optional>{}; - } - - return format_filesystem_call_error(ec, "read_contents", {versions_file_path}); - } - - auto maybe_versions_json = Json::parse_object(contents, versions_file_path); - auto versions_json = maybe_versions_json.get(); - if (!versions_json) - { - return std::move(maybe_versions_json).error(); - } - - auto maybe_versions_array = versions_json->get(JsonIdVersions); - if (!maybe_versions_array || !maybe_versions_array->is_array()) - { - return msg::format_error(msgFailedToParseNoVersionsArray, msg::path = versions_file_path); - } - - std::vector db_entries; - GitVersionDbEntryArrayDeserializer deserializer{}; - Json::Reader r(versions_file_path); - r.visit_in_key(*maybe_versions_array, JsonIdVersions, db_entries, deserializer); - if (!r.errors().empty()) - { - return msg::format_error(msgFailedToParseVersionsFile, msg::path = versions_file_path) - .append_raw(Strings::join("\n", r.errors())); - } - - return db_entries; - } - - ExpectedL>> load_filesystem_versions_file( - const ReadOnlyFilesystem& fs, const Path& registry_versions, StringView port_name, const Path& registry_root) - { - if (registry_root.empty()) - { - Checks::unreachable(VCPKG_LINE_INFO, "type should never = Filesystem when registry_root is empty."); - } - - auto versions_file_path = registry_versions / relative_path_to_versions(port_name); - std::error_code ec; - auto contents = fs.read_contents(versions_file_path, ec); - if (ec) - { - if (ec == std::errc::no_such_file_or_directory) - { - return Optional>{}; - } - - return format_filesystem_call_error(ec, "read_contents", {versions_file_path}); - } - - auto maybe_versions_json = Json::parse_object(contents, versions_file_path); - auto versions_json = maybe_versions_json.get(); - if (!versions_json) - { - return std::move(maybe_versions_json).error(); - } - - auto maybe_versions_array = versions_json->get(JsonIdVersions); - if (!maybe_versions_array || !maybe_versions_array->is_array()) - { - return msg::format_error(msgFailedToParseNoVersionsArray, msg::path = versions_file_path); - } - - std::vector db_entries; - FilesystemVersionDbEntryArrayDeserializer deserializer{registry_root}; - Json::Reader r(versions_file_path); - r.visit_in_key(*maybe_versions_array, JsonIdVersions, db_entries, deserializer); - if (!r.errors().empty()) - { - return msg::format_error(msgFailedToParseVersionsFile, msg::path = versions_file_path) - .append_raw(Strings::join("\n", r.errors())); - } - - return db_entries; - } - ExpectedL parse_baseline_versions(StringView contents, StringView baseline, StringView origin) { - auto maybe_value = Json::parse(contents, origin); - if (!maybe_value) - { - return std::move(maybe_value).error(); - } - - auto& value = *maybe_value.get(); - if (!value.value.is_object()) + auto maybe_object = Json::parse_object(contents, origin); + auto object = maybe_object.get(); + if (!object) { - return msg::format_error(msgFailedToParseNoTopLevelObj, msg::path = origin); + return std::move(maybe_object).error(); } auto real_baseline = baseline.size() == 0 ? StringView{JsonIdDefault} : baseline; - const auto& obj = value.value.object(VCPKG_LINE_INFO); - auto baseline_value = obj.get(real_baseline); + auto baseline_value = object->get(real_baseline); if (!baseline_value) { return LocalizedString::from_raw(origin) @@ -1385,12 +1244,8 @@ namespace { return std::move(result); } - else - { - return msg::format_error(msgFailedToParseBaseline, msg::path = origin) - .append_raw('\n') - .append_raw(Strings::join("\n", r.errors())); - } + + return msg::format_error(msgFailedToParseBaseline, msg::path = origin).append_raw('\n').append_raw(r.join()); } ExpectedL load_baseline_versions(const ReadOnlyFilesystem& fs, @@ -1634,11 +1489,195 @@ namespace vcpkg Util::sort_unique_erase(result); return result; } +} // namespace vcpkg + +namespace +{ + ExpectedL>> load_git_versions_file_impl(const ReadOnlyFilesystem& fs, + const Path& versions_file_path) + { + std::error_code ec; + auto contents = fs.read_contents(versions_file_path, ec); + if (ec) + { + if (ec == std::errc::no_such_file_or_directory) + { + return nullopt; + } + + return format_filesystem_call_error(ec, "read_contents", {versions_file_path}); + } + + return Json::parse_object(contents, versions_file_path) + .then([&](Json::Object&& versions_json) -> ExpectedL>> { + auto maybe_versions_array = versions_json.get(JsonIdVersions); + if (!maybe_versions_array || !maybe_versions_array->is_array()) + { + return msg::format_error(msgFailedToParseNoVersionsArray, msg::path = versions_file_path); + } + + std::vector db_entries; + GitVersionDbEntryArrayDeserializer deserializer{}; + Json::Reader r(versions_file_path); + r.visit_in_key(*maybe_versions_array, JsonIdVersions, db_entries, deserializer); + if (!r.errors().empty() != 0) + { + return msg::format_error(msgFailedToParseVersionFile, msg::path = versions_file_path) + .append_raw('\n') + .append_raw(r.join()); + } + + return db_entries; + }); + } + + ExpectedL>> load_filesystem_versions_file_impl( + const ReadOnlyFilesystem& fs, const Path& versions_file_path, const Path& registry_root) + { + std::error_code ec; + auto contents = fs.read_contents(versions_file_path, ec); + if (ec) + { + if (ec == std::errc::no_such_file_or_directory) + { + return nullopt; + } + + return format_filesystem_call_error(ec, "read_contents", {versions_file_path}); + } + + return Json::parse_object(contents, versions_file_path) + .then([&](Json::Object&& versions_json) -> ExpectedL>> { + auto maybe_versions_array = versions_json.get(JsonIdVersions); + if (!maybe_versions_array || !maybe_versions_array->is_array()) + { + return msg::format_error(msgFailedToParseNoVersionsArray, msg::path = versions_file_path); + } + + std::vector db_entries; + FilesystemVersionDbEntryArrayDeserializer deserializer{registry_root}; + Json::Reader r(versions_file_path); + r.visit_in_key(*maybe_versions_array, JsonIdVersions, db_entries, deserializer); + if (!r.errors().empty() != 0) + { + return msg::format_error(msgFailedToParseVersionFile, msg::path = versions_file_path) + .append_raw('\n') + .append_raw(r.join()); + } + + return db_entries; + }); + } +} // unnamed namespace + +namespace vcpkg +{ + GitVersionsLoadResult load_git_versions_file(const ReadOnlyFilesystem& fs, + const Path& registry_versions, + StringView port_name) + { + auto versions_file_path = registry_versions / relative_path_to_versions(port_name); + auto result = load_git_versions_file_impl(fs, versions_file_path); + if (!result) + { + result.error() + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgWhileParsingVersionsForPort, msg::package_name = port_name, msg::path = versions_file_path); + } + + return {std::move(result), std::move(versions_file_path)}; + } + + FullGitVersionsDatabase::FullGitVersionsDatabase( + const ReadOnlyFilesystem& fs, + const Path& registry_versions, + std::map>&& initial) + : m_fs(&fs), m_registry_versions(registry_versions), m_cache(std::move(initial)) + { + } + + FullGitVersionsDatabase::FullGitVersionsDatabase(FullGitVersionsDatabase&&) = default; + FullGitVersionsDatabase& FullGitVersionsDatabase::operator=(FullGitVersionsDatabase&&) = default; + + const GitVersionsLoadResult& FullGitVersionsDatabase::lookup(StringView port_name) + { + auto it = m_cache.lower_bound(port_name); + if (it != m_cache.end() && port_name >= it->first) + { + return it->second; + } + + return m_cache.emplace_hint(it, port_name, load_git_versions_file(*m_fs, m_registry_versions, port_name)) + ->second; + } - ExpectedL>> get_builtin_versions(const VcpkgPaths& paths, - StringView port_name) + const std::map>& FullGitVersionsDatabase::cache() const { - return load_git_versions_file(paths.get_filesystem(), paths.builtin_registry_versions, port_name); + return m_cache; + } + + ExpectedL load_all_git_versions_files(const ReadOnlyFilesystem& fs, + const Path& registry_versions) + { + auto maybe_letter_directories = fs.try_get_directories_non_recursive(registry_versions); + auto letter_directories = maybe_letter_directories.get(); + if (!letter_directories) + { + return std::move(maybe_letter_directories).error(); + } + + std::map> initial_result; + for (auto&& letter_directory : *letter_directories) + { + auto maybe_versions_files = fs.try_get_files_non_recursive(letter_directory); + auto versions_files = maybe_versions_files.get(); + if (!versions_files) + { + return std::move(maybe_versions_files).error(); + } + + for (auto&& versions_file : *versions_files) + { + auto port_name_json = versions_file.filename(); + static constexpr StringLiteral dot_json = ".json"; + if (!Strings::ends_with(port_name_json, dot_json)) + { + continue; + } + + StringView port_name{port_name_json.data(), port_name_json.size() - dot_json.size()}; + auto maybe_port_versions = load_git_versions_file_impl(fs, versions_file); + if (!maybe_port_versions) + { + maybe_port_versions.error() + .append_raw('\n') + .append_raw(NotePrefix) + .append( + msgWhileParsingVersionsForPort, msg::package_name = port_name, msg::path = versions_file); + } + + initial_result.emplace(port_name, GitVersionsLoadResult{std::move(maybe_port_versions), versions_file}); + } + } + + return FullGitVersionsDatabase{fs, registry_versions, std::move(initial_result)}; + } + + ExpectedL>> load_filesystem_versions_file( + const ReadOnlyFilesystem& fs, const Path& registry_versions, StringView port_name, const Path& registry_root) + { + auto versions_file_path = registry_versions / relative_path_to_versions(port_name); + auto result = load_filesystem_versions_file_impl(fs, versions_file_path, registry_root); + if (!result) + { + result.error() + .append_raw('\n') + .append_raw(NotePrefix) + .append(msgWhileParsingVersionsForPort, msg::package_name = port_name, msg::path = versions_file_path); + } + + return result; } ExpectedL get_builtin_baseline(const VcpkgPaths& paths) diff --git a/src/vcpkg/vcpkgpaths.cpp b/src/vcpkg/vcpkgpaths.cpp index 7d48e87932..d3ec0c5309 100644 --- a/src/vcpkg/vcpkgpaths.cpp +++ b/src/vcpkg/vcpkgpaths.cpp @@ -978,14 +978,14 @@ namespace vcpkg ExpectedL>> VcpkgPaths::git_get_local_port_treeish_map() const { - const auto local_repo = this->root / ".git"; - auto cmd = git_cmd_builder({}, {}) - .string_arg("-C") - .string_arg(this->builtin_ports_directory()) - .string_arg("ls-tree") - .string_arg("-d") - .string_arg("HEAD") - .string_arg("--"); + const auto cmd = git_cmd_builder({}, {}) + .string_arg("-C") + .string_arg(this->builtin_ports_directory()) + .string_arg("ls-tree") + .string_arg("-d") + .string_arg("HEAD") + .string_arg("--"); + auto maybe_output = flatten_out(cmd_execute_and_capture_output(cmd), Tools::GIT); if (const auto output = maybe_output.get()) {