From 9d0b2ddaf07e5446c1d23ad14394650f12fdd2b3 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Wed, 28 Sep 2022 19:31:12 +0200 Subject: [PATCH 01/28] Add command `lint-port` --- include/vcpkg/base/messages.h | 45 ++++- include/vcpkg/commands.lint-port.h | 13 ++ include/vcpkg/portlint.h | 35 ++++ include/vcpkg/sourceparagraph.h | 2 + locales/messages.en.json | 10 +- locales/messages.json | 20 ++- src/vcpkg/base/messages.cpp | 14 +- src/vcpkg/commands.add-version.cpp | 86 +++++---- src/vcpkg/commands.cpp | 3 + src/vcpkg/commands.lint-port.cpp | 131 ++++++++++++++ src/vcpkg/portlint.cpp | 268 +++++++++++++++++++++++++++++ src/vcpkg/sourceparagraph.cpp | 16 +- 12 files changed, 590 insertions(+), 53 deletions(-) create mode 100644 include/vcpkg/commands.lint-port.h create mode 100644 include/vcpkg/portlint.h create mode 100644 src/vcpkg/commands.lint-port.cpp create mode 100644 src/vcpkg/portlint.cpp diff --git a/include/vcpkg/base/messages.h b/include/vcpkg/base/messages.h index d463672da5..30b7e8b335 100644 --- a/include/vcpkg/base/messages.h +++ b/include/vcpkg/base/messages.h @@ -479,12 +479,20 @@ namespace vcpkg (), "", "skipping detection of local changes due to unexpected format in git status output"); + DECLARE_MESSAGE(AddVersionDisableCheck, + (msg::option), + "The -- before {option} must be preserved as they're part of the help message for the user.", + "Use --{option} to disable this check."); DECLARE_MESSAGE(AddVersionFileNotFound, (msg::path), "", "couldn't find required file {path}"); DECLARE_MESSAGE(AddVersionFormatPortSuggestion, (msg::command_line), "", "Run `{command_line}` to format the file"); 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(AddVersionLintPort, + (msg::package_name), + "", + "You can run `./vcpkg x-lint-port --fix {package_name}` to fix these issues."); DECLARE_MESSAGE(AddVersionLoadPortFailed, (msg::package_name), "", "can't load port {package_name}"); DECLARE_MESSAGE(AddVersionNewFile, (), "", "(new file)"); DECLARE_MESSAGE(AddVersionNewShaIs, (msg::value), "{value} is a 40-digit hexadecimal SHA", "new SHA: {value}"); @@ -512,11 +520,40 @@ namespace vcpkg (msg::package_name), "", "{package_name} is not properly formatted"); - DECLARE_MESSAGE(AddVersionSuggestNewVersionScheme, - (msg::new_scheme, msg::old_scheme, msg::package_name, msg::option), - "The -- before {option} must be preserved as they're part of the help message for the user.", + DECLARE_MESSAGE( + LintDeprecatedFunction, + (msg::package_name, msg::actual, msg::expected), + "{actual} is the currently used deprecated function, {expected} is the function that should be used", + "The deprecated function \"{actual}\" is used inside the port \"{package_name}\". Use the function " + "\"{expected}\" instead."); + DECLARE_MESSAGE( + LintDeprecatedLicenseExpressionWithReplacement, + (msg::package_name, msg::actual, msg::new_value), + "{actual} is the currently used license and {new_value} is the license expression that should be used", + "The port \"{package_name}\" uses the deprecated license expression \"{actual}\". You shoud use the non " + "deprecated version \"{new_value}\"."); + DECLARE_MESSAGE(LintDeprecatedLicenseExpressionWithoutReplacement, + (msg::package_name, msg::actual), + "{actual} is the currently used license", + "The port \"{package_name}\" uses the deprecated license expression \"{actual}\"."); + DECLARE_MESSAGE(LintMissingLicenseExpression, + (msg::package_name), + "", + "There is no license expression in port \"{package_name}\". You could use " + "https://tools.spdx.org/app/check_license/ to determine the right license expression."); + DECLARE_MESSAGE(LintSuggestNewVersionScheme, + (msg::new_scheme, msg::old_scheme, msg::package_name), + "", "Use the version scheme \"{new_scheme}\" instead of \"{old_scheme}\" in port " - "\"{package_name}\".\nUse --{option} to disable this check."); + "\"{package_name}\"."); + DECLARE_MESSAGE(LintPortErrorsFixed, + (msg::package_name), + "", + "Problems in the port \"{package_name}\" have been fixed."); + DECLARE_MESSAGE(LintPortErrors, + (msg::package_name), + "", + "The port \"{package_name}\" should be fixed. See warning(s) above."); DECLARE_MESSAGE(AddVersionUnableToParseVersionsFile, (msg::path), "", "unable to parse versions file {path}"); DECLARE_MESSAGE(AddVersionUncommittedChanges, (msg::package_name), diff --git a/include/vcpkg/commands.lint-port.h b/include/vcpkg/commands.lint-port.h new file mode 100644 index 0000000000..2d136e9c9a --- /dev/null +++ b/include/vcpkg/commands.lint-port.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace vcpkg::Commands::LintPort +{ + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths); + + struct LintPortCommand : PathsCommand + { + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const override; + }; +} diff --git a/include/vcpkg/portlint.h b/include/vcpkg/portlint.h new file mode 100644 index 0000000000..80e66415b5 --- /dev/null +++ b/include/vcpkg/portlint.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include +#include +#include + +#include + +namespace vcpkg::Lint +{ + enum class Status : int + { + Ok = 0b0, + Problem = 0b01, + Fixed = 0b10, + PartiallyFixed = 0b11 + }; + + Status& operator|=(Status& self, Status s); + + enum class Fix + { + NO = 0, // A warning message is printed for every found problem + YES // The problem is fixed in place (SourceControlFile) and no message is printed + }; + + Status check_used_version_scheme(SourceControlFile& scf, Fix fix); + + Status check_license_expression(SourceControlFile& scf, Fix fix); + + Status check_portfile_deprecated_functions(Filesystem& fs, SourceControlFileAndLocation& scf, Fix fix); +} diff --git a/include/vcpkg/sourceparagraph.h b/include/vcpkg/sourceparagraph.h index 74660b5735..46e7473dfe 100644 --- a/include/vcpkg/sourceparagraph.h +++ b/include/vcpkg/sourceparagraph.h @@ -131,6 +131,8 @@ namespace vcpkg } VersionSpec to_version_spec() const { return {core_paragraph->name, core_paragraph->to_version()}; } + std::unique_ptr canonicalize(); + friend bool operator==(const SourceControlFile& lhs, const SourceControlFile& rhs); friend bool operator!=(const SourceControlFile& lhs, const SourceControlFile& rhs) { return !(lhs == rhs); } }; diff --git a/locales/messages.en.json b/locales/messages.en.json index d7d091d0cf..2dca582bd8 100644 --- a/locales/messages.en.json +++ b/locales/messages.en.json @@ -9,9 +9,11 @@ "AddVersionCommitChangesReminder": "Did you remember to commit your changes?", "AddVersionCommitResultReminder": "Don't forget to commit the result!", "AddVersionDetectLocalChangesError": "skipping detection of local changes due to unexpected format in git status output", + "AddVersionDisableCheck": "Use --{option} to disable this check.", "AddVersionFileNotFound": "couldn't find required file {path}", "AddVersionFormatPortSuggestion": "Run `{command_line}` to format the file", "AddVersionIgnoringOptionAll": "ignoring --{option} since a port name argument was provided", + "AddVersionLintPort": "You can run `./vcpkg x-lint-port --fix {package_name}` to fix these issues.", "AddVersionLoadPortFailed": "can't load port {package_name}", "AddVersionNewFile": "(new file)", "AddVersionNewShaIs": "new SHA: {value}", @@ -24,7 +26,6 @@ "AddVersionPortFilesShaChanged": "checked-in files for {package_name} have changed but the version was not updated", "AddVersionPortFilesShaUnchanged": "checked-in files for {package_name} are unchanged from version {version}", "AddVersionPortHasImproperFormat": "{package_name} is not properly formatted", - "AddVersionSuggestNewVersionScheme": "Use the version scheme \"{new_scheme}\" instead of \"{old_scheme}\" in port \"{package_name}\".\nUse --{option} to disable this check.", "AddVersionUnableToParseVersionsFile": "unable to parse versions file {path}", "AddVersionUncommittedChanges": "there are uncommitted changes for {package_name}", "AddVersionUpdateVersionReminder": "Did you remember to update the version or port version?", @@ -271,6 +272,13 @@ "LicenseExpressionImbalancedParens": "There was a close parenthesis without an opening parenthesis.", "LicenseExpressionUnknownException": "Unknown license exception identifier '{value}'. Known values are listed at https://spdx.org/licenses/exceptions-index.html", "LicenseExpressionUnknownLicense": "Unknown license identifier '{value}'. Known values are listed at https://spdx.org/licenses/", + "LintDeprecatedFunction": "The deprecated function \"{actual}\" is used inside the port \"{package_name}\". Use the function \"{expected}\" instead.", + "LintDeprecatedLicenseExpressionWithReplacement": "The port \"{package_name}\" uses the deprecated license expression \"{actual}\". You shoud use the non deprecated version \"{new_value}\".", + "LintDeprecatedLicenseExpressionWithoutReplacement": "The port \"{package_name}\" uses the deprecated license expression \"{actual}\".", + "LintMissingLicenseExpression": "There is no license expression in port \"{package_name}\". You could use https://tools.spdx.org/app/check_license/ to determine the right license expression.", + "LintPortErrors": "The port \"{package_name}\" should be fixed. See warning(s) above.", + "LintPortErrorsFixed": "Problems in the port \"{package_name}\" have been fixed.", + "LintSuggestNewVersionScheme": "Use the version scheme \"{new_scheme}\" instead of \"{old_scheme}\" in port \"{package_name}\".", "ListOfValidFieldsForControlFiles": "This is the list of valid fields for CONTROL files (case-sensitive):", "LoadingCommunityTriplet": "-- [COMMUNITY] Loading triplet configuration from: {path}", "LoadingDependencyInformation": "Loading dependency information for {count} packages...", diff --git a/locales/messages.json b/locales/messages.json index c339ec8d63..a4e067be04 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -14,12 +14,16 @@ "AddVersionCommitChangesReminder": "Did you remember to commit your changes?", "AddVersionCommitResultReminder": "Don't forget to commit the result!", "AddVersionDetectLocalChangesError": "skipping detection of local changes due to unexpected format in git status output", + "AddVersionDisableCheck": "Use --{option} to disable this check.", + "_AddVersionDisableCheck.comment": "The -- before {option} must be preserved as they're part of the help message for the user. An example of {option} is editable.", "AddVersionFileNotFound": "couldn't find required file {path}", "_AddVersionFileNotFound.comment": "An example of {path} is /foo/bar.", "AddVersionFormatPortSuggestion": "Run `{command_line}` to format the file", "_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.", + "AddVersionLintPort": "You can run `./vcpkg x-lint-port --fix {package_name}` to fix these issues.", + "_AddVersionLintPort.comment": "An example of {package_name} is zlib.", "AddVersionLoadPortFailed": "can't load port {package_name}", "_AddVersionLoadPortFailed.comment": "An example of {package_name} is zlib.", "AddVersionNewFile": "(new file)", @@ -42,8 +46,6 @@ "_AddVersionPortFilesShaUnchanged.comment": "An example of {package_name} is zlib. An example of {version} is 1.3.8.", "AddVersionPortHasImproperFormat": "{package_name} is not properly formatted", "_AddVersionPortHasImproperFormat.comment": "An example of {package_name} is zlib.", - "AddVersionSuggestNewVersionScheme": "Use the version scheme \"{new_scheme}\" instead of \"{old_scheme}\" in port \"{package_name}\".\nUse --{option} to disable this check.", - "_AddVersionSuggestNewVersionScheme.comment": "The -- before {option} must be preserved as they're part of the help message for the user. An example of {new_scheme} is version. An example of {old_scheme} is version-string. An example of {package_name} is zlib. An example of {option} is editable.", "AddVersionUnableToParseVersionsFile": "unable to parse versions file {path}", "_AddVersionUnableToParseVersionsFile.comment": "An example of {path} is /foo/bar.", "AddVersionUncommittedChanges": "there are uncommitted changes for {package_name}", @@ -446,6 +448,20 @@ "_LicenseExpressionUnknownException.comment": "Example of {value} is 'unknownexception'", "LicenseExpressionUnknownLicense": "Unknown license identifier '{value}'. Known values are listed at https://spdx.org/licenses/", "_LicenseExpressionUnknownLicense.comment": "Example of {value} is 'unknownlicense'", + "LintDeprecatedFunction": "The deprecated function \"{actual}\" is used inside the port \"{package_name}\". Use the function \"{expected}\" instead.", + "_LintDeprecatedFunction.comment": "{actual} is the currently used deprecated function, {expected} is the function that should be used An example of {package_name} is zlib.", + "LintDeprecatedLicenseExpressionWithReplacement": "The port \"{package_name}\" uses the deprecated license expression \"{actual}\". You shoud use the non deprecated version \"{new_value}\".", + "_LintDeprecatedLicenseExpressionWithReplacement.comment": "{actual} is the currently used license and {new_value} is the license expression that should be used An example of {package_name} is zlib.", + "LintDeprecatedLicenseExpressionWithoutReplacement": "The port \"{package_name}\" uses the deprecated license expression \"{actual}\".", + "_LintDeprecatedLicenseExpressionWithoutReplacement.comment": "{actual} is the currently used license An example of {package_name} is zlib.", + "LintMissingLicenseExpression": "There is no license expression in port \"{package_name}\". You could use https://tools.spdx.org/app/check_license/ to determine the right license expression.", + "_LintMissingLicenseExpression.comment": "An example of {package_name} is zlib.", + "LintPortErrors": "The port \"{package_name}\" should be fixed. See warning(s) above.", + "_LintPortErrors.comment": "An example of {package_name} is zlib.", + "LintPortErrorsFixed": "Problems in the port \"{package_name}\" have been fixed.", + "_LintPortErrorsFixed.comment": "An example of {package_name} is zlib.", + "LintSuggestNewVersionScheme": "Use the version scheme \"{new_scheme}\" instead of \"{old_scheme}\" in port \"{package_name}\".", + "_LintSuggestNewVersionScheme.comment": "An example of {new_scheme} is version. An example of {old_scheme} is version-string. An example of {package_name} is zlib.", "ListOfValidFieldsForControlFiles": "This is the list of valid fields for CONTROL files (case-sensitive):", "LoadingCommunityTriplet": "-- [COMMUNITY] Loading triplet configuration from: {path}", "_LoadingCommunityTriplet.comment": "'-- [COMMUNITY]' at the beginning must be preserved An example of {path} is /foo/bar.", diff --git a/src/vcpkg/base/messages.cpp b/src/vcpkg/base/messages.cpp index 9afec73519..ebd66721cb 100644 --- a/src/vcpkg/base/messages.cpp +++ b/src/vcpkg/base/messages.cpp @@ -393,10 +393,12 @@ namespace vcpkg REGISTER_MESSAGE(AddVersionCommitChangesReminder); REGISTER_MESSAGE(AddVersionCommitResultReminder); REGISTER_MESSAGE(AddVersionDetectLocalChangesError); + REGISTER_MESSAGE(AddVersionDisableCheck); REGISTER_MESSAGE(AddVersionFileNotFound); REGISTER_MESSAGE(AddVersionFormatPortSuggestion); REGISTER_MESSAGE(AddVersionIgnoringOptionAll); REGISTER_MESSAGE(AddVersionLoadPortFailed); + REGISTER_MESSAGE(AddVersionLintPort); REGISTER_MESSAGE(AddVersionNewFile); REGISTER_MESSAGE(AddVersionNewShaIs); REGISTER_MESSAGE(AddVersionNoFilesUpdated); @@ -408,7 +410,6 @@ namespace vcpkg REGISTER_MESSAGE(AddVersionPortFilesShaChanged); REGISTER_MESSAGE(AddVersionPortFilesShaUnchanged); REGISTER_MESSAGE(AddVersionPortHasImproperFormat); - REGISTER_MESSAGE(AddVersionSuggestNewVersionScheme); REGISTER_MESSAGE(AddVersionUnableToParseVersionsFile); REGISTER_MESSAGE(AddVersionUncommittedChanges); REGISTER_MESSAGE(AddVersionUpdateVersionReminder); @@ -466,8 +467,8 @@ namespace vcpkg REGISTER_MESSAGE(CMakeToolChainFile); REGISTER_MESSAGE(CommandFailed); REGISTER_MESSAGE(CompressFolderFailed); - REGISTER_MESSAGE(ConstraintViolation); REGISTER_MESSAGE(ConflictingValuesForOption); + REGISTER_MESSAGE(ConstraintViolation); REGISTER_MESSAGE(ControlAndManifestFilesPresent); REGISTER_MESSAGE(CopyrightIsDir); REGISTER_MESSAGE(CorruptedDatabase); @@ -648,6 +649,13 @@ namespace vcpkg REGISTER_MESSAGE(LicenseExpressionImbalancedParens); REGISTER_MESSAGE(LicenseExpressionUnknownException); REGISTER_MESSAGE(LicenseExpressionUnknownLicense); + REGISTER_MESSAGE(LintDeprecatedFunction); + REGISTER_MESSAGE(LintDeprecatedLicenseExpressionWithoutReplacement); + REGISTER_MESSAGE(LintDeprecatedLicenseExpressionWithReplacement); + REGISTER_MESSAGE(LintMissingLicenseExpression); + REGISTER_MESSAGE(LintSuggestNewVersionScheme); + REGISTER_MESSAGE(LintPortErrors); + REGISTER_MESSAGE(LintPortErrorsFixed); REGISTER_MESSAGE(ListOfValidFieldsForControlFiles); REGISTER_MESSAGE(LoadingCommunityTriplet); REGISTER_MESSAGE(LoadingDependencyInformation); @@ -661,8 +669,8 @@ namespace vcpkg REGISTER_MESSAGE(MissingDependency); REGISTER_MESSAGE(MissingExtension); REGISTER_MESSAGE(MissingOption); - REGISTER_MESSAGE(MissmatchedBinParagraphs); REGISTER_MESSAGE(MissingPortSuggestPullRequest); + REGISTER_MESSAGE(MissmatchedBinParagraphs); REGISTER_MESSAGE(MonoInstructions); REGISTER_MESSAGE(MsiexecFailedToExtract); REGISTER_MESSAGE(MultiArch); diff --git a/src/vcpkg/commands.add-version.cpp b/src/vcpkg/commands.add-version.cpp index fa7d9e13f3..466d6a3c65 100644 --- a/src/vcpkg/commands.add-version.cpp +++ b/src/vcpkg/commands.add-version.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,8 @@ namespace static constexpr StringLiteral OPTION_OVERWRITE_VERSION = "overwrite-version"; static constexpr StringLiteral OPTION_SKIP_FORMATTING_CHECK = "skip-formatting-check"; static constexpr StringLiteral OPTION_SKIP_VERSION_FORMAT_CHECK = "skip-version-format-check"; + static constexpr StringLiteral OPTION_SKIP_LICENSE_CHECK = "skip-license-check"; + static constexpr StringLiteral OPTION_SKIP_PORTFILE_CHECK = "skip-portfile-check"; static constexpr StringLiteral OPTION_VERBOSE = "verbose"; enum class UpdateResult @@ -68,30 +71,7 @@ namespace Checks::unreachable(VCPKG_LINE_INFO); } - void check_used_version_scheme(const SchemedVersion& version, const std::string& port_name) - { - if (version.scheme == VersionScheme::String) - { - if (DateVersion::try_parse(version.version.text())) - { - Checks::msg_exit_with_message(VCPKG_LINE_INFO, - msgAddVersionSuggestNewVersionScheme, - msg::new_scheme = VERSION_DATE, - msg::old_scheme = VERSION_STRING, - msg::package_name = port_name, - msg::option = OPTION_SKIP_VERSION_FORMAT_CHECK); - } - if (DotVersion::try_parse_relaxed(version.version.text())) - { - Checks::msg_exit_with_message(VCPKG_LINE_INFO, - msgAddVersionSuggestNewVersionScheme, - msg::new_scheme = VERSION_RELAXED, - msg::old_scheme = VERSION_STRING, - msg::package_name = port_name, - msg::option = OPTION_SKIP_VERSION_FORMAT_CHECK); - } - } - } + void lint_port(SourceControlFileAndLocation& scf) { } static Json::Object serialize_baseline(const std::map>& baseline) { @@ -192,15 +172,44 @@ namespace bool overwrite_version, bool print_success, bool keep_going, - bool skip_version_format_check) + bool skip_version_format_check, + bool skip_license_check, + bool skip_portfile_check, + SourceControlFileAndLocation& scf) { auto& fs = paths.get_filesystem(); - if (!fs.exists(version_db_file_path, IgnoreErrors{})) - { + const auto lint_port = [=, &scf, &fs]() { + Lint::Status status = Lint::Status::Ok; if (!skip_version_format_check) { - check_used_version_scheme(port_version, port_name); + if (Lint::check_used_version_scheme(*scf.source_control_file, Lint::Fix::NO) == Lint::Status::Problem) + { + status = Lint::Status::Problem; + msg::println(msgAddVersionDisableCheck, msg::option = OPTION_SKIP_VERSION_FORMAT_CHECK); + } + } + if (!skip_license_check) + { + if (Lint::check_license_expression(*scf.source_control_file, Lint::Fix::NO) == Lint::Status::Problem) + { + status = Lint::Status::Problem; + msg::println(msgAddVersionDisableCheck, msg::option = OPTION_SKIP_LICENSE_CHECK); + } } + if (!skip_portfile_check) + { + if (Lint::check_portfile_deprecated_functions(fs, scf, Lint::Fix::NO) == Lint::Status::Problem) + { + status = Lint::Status::Problem; + msg::println(msgAddVersionDisableCheck, msg::option = OPTION_SKIP_PORTFILE_CHECK); + } + } + Checks::msg_check_exit( + VCPKG_LINE_INFO, status == Lint::Status::Problem, msgAddVersionLintPort, msg::package_name = port_name); + }; + if (!fs.exists(version_db_file_path, IgnoreErrors{})) + { + lint_port(); std::vector new_entry{{port_version, git_tree}}; write_versions_file(fs, new_entry, version_db_file_path); if (print_success) @@ -285,10 +294,7 @@ namespace versions->insert(versions->begin(), std::make_pair(port_version, git_tree)); } - if (!skip_version_format_check) - { - check_used_version_scheme(port_version, port_name); - } + lint_port(); write_versions_file(fs, *versions, version_db_file_path); if (print_success) @@ -315,6 +321,8 @@ namespace vcpkg::Commands::AddVersion {OPTION_OVERWRITE_VERSION, "Overwrite `git-tree` of an existing version."}, {OPTION_SKIP_FORMATTING_CHECK, "Skips the formatting check of vcpkg.json files."}, {OPTION_SKIP_VERSION_FORMAT_CHECK, "Skips the version format check."}, + {OPTION_SKIP_LICENSE_CHECK, "Skips the license expression check."}, + {OPTION_SKIP_PORTFILE_CHECK, "Skips the portfile.cmake check."}, {OPTION_VERBOSE, "Print success messages instead of just errors."}, }; @@ -334,6 +342,8 @@ namespace vcpkg::Commands::AddVersion const bool skip_formatting_check = Util::Sets::contains(parsed_args.switches, OPTION_SKIP_FORMATTING_CHECK); const bool skip_version_format_check = Util::Sets::contains(parsed_args.switches, OPTION_SKIP_VERSION_FORMAT_CHECK); + const bool skip_license_check = Util::Sets::contains(parsed_args.switches, OPTION_SKIP_LICENSE_CHECK); + const bool skip_portfile_check = Util::Sets::contains(parsed_args.switches, OPTION_SKIP_PORTFILE_CHECK); const bool verbose = !add_all || Util::Sets::contains(parsed_args.switches, OPTION_VERBOSE); auto& fs = paths.get_filesystem(); @@ -413,7 +423,8 @@ namespace vcpkg::Commands::AddVersion continue; } - const auto& scf = maybe_scf.value_or_exit(VCPKG_LINE_INFO); + SourceControlFileAndLocation scf{std::move(maybe_scf.value_or_exit(VCPKG_LINE_INFO)), + paths.builtin_ports_directory() / port_name}; if (!skip_formatting_check) { @@ -422,7 +433,7 @@ namespace vcpkg::Commands::AddVersion if (fs.exists(path_to_manifest, IgnoreErrors{})) { const auto current_file_content = fs.read_contents(path_to_manifest, VCPKG_LINE_INFO); - const auto json = serialize_manifest(*scf); + const auto json = serialize_manifest(*scf.source_control_file); const auto formatted_content = Json::stringify(json); if (current_file_content != formatted_content) { @@ -446,7 +457,7 @@ namespace vcpkg::Commands::AddVersion msg::println_warning(msgAddVersionUncommittedChanges, msg::package_name = port_name); } - const auto& schemed_version = scf->to_schemed_version(); + const auto& schemed_version = scf.source_control_file->to_schemed_version(); auto git_tree_it = git_tree_map.find(port_name); if (git_tree_it == git_tree_map.end()) @@ -472,7 +483,10 @@ namespace vcpkg::Commands::AddVersion overwrite_version, verbose, add_all, - skip_version_format_check); + skip_version_format_check, + skip_license_check, + skip_portfile_check, + scf); auto updated_baseline_file = update_baseline_version( paths, port_name, schemed_version.version, baseline_path, baseline_map, verbose); if (verbose && updated_versions_file == UpdateResult::NotUpdated && diff --git a/src/vcpkg/commands.cpp b/src/vcpkg/commands.cpp index 63ef26abb3..0dc3208751 100644 --- a/src/vcpkg/commands.cpp +++ b/src/vcpkg/commands.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +103,7 @@ namespace vcpkg::Commands static const Help::HelpCommand help{}; static const Info::InfoCommand info{}; static const Integrate::IntegrateCommand integrate{}; + static const LintPort::LintPortCommand lintport{}; static const List::ListCommand list{}; static const NewCommand new_{}; static const Owns::OwnsCommand owns{}; @@ -140,6 +142,7 @@ namespace vcpkg::Commands {"x-add-version", &add_version}, {"x-ci-clean", &ciclean}, {"x-ci-verify-versions", &ci_verify_versions}, + {"x-lint-port", &lintport}, {"x-package-info", &info}, {"x-regenerate", ®enerate}, {"x-vsinstances", &vsinstances}, diff --git a/src/vcpkg/commands.lint-port.cpp b/src/vcpkg/commands.lint-port.cpp new file mode 100644 index 0000000000..1e47cccc87 --- /dev/null +++ b/src/vcpkg/commands.lint-port.cpp @@ -0,0 +1,131 @@ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace vcpkg; + +namespace +{ + + static constexpr StringLiteral OPTION_ALL = "all"; + static constexpr StringLiteral OPTION_FIX = "fix"; + static constexpr StringLiteral OPTION_INCREASE_VERSION = "increase-version"; +} + +namespace vcpkg::Commands::LintPort +{ + const CommandSwitch COMMAND_SWITCHES[] = { + {OPTION_ALL, "Checks all ports."}, + {OPTION_FIX, "Tries to fix all problems that were found."}, + {OPTION_INCREASE_VERSION, "Increase the port-version of a port if a problem was fixed."}}; + + const CommandStructure COMMAND_STRUCTURE{ + create_example_string(R"###(x-lint-port )###"), + 0, + INT_MAX, + {{COMMAND_SWITCHES}, {}, {}}, + nullptr, + }; + + void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) + { + auto parsed_args = args.parse_arguments(COMMAND_STRUCTURE); + const bool add_all = Util::Sets::contains(parsed_args.switches, OPTION_ALL); + const auto fix = Util::Enum::to_enum(Util::Sets::contains(parsed_args.switches, OPTION_FIX)); + const bool increase_version = Util::Sets::contains(parsed_args.switches, OPTION_INCREASE_VERSION); + + auto& fs = paths.get_filesystem(); + + std::vector port_names; + if (!args.command_arguments.empty()) + { + if (add_all) + { + msg::println_warning(msgAddVersionIgnoringOptionAll, msg::option = OPTION_ALL); + } + port_names = args.command_arguments; + } + else + { + Checks::msg_check_exit(VCPKG_LINE_INFO, + add_all, + msgAddVersionUseOptionAll, + msg::command_name = "x-add-version", + msg::option = OPTION_ALL); + + for (auto&& port_dir : fs.get_directories_non_recursive(paths.builtin_ports_directory(), VCPKG_LINE_INFO)) + { + port_names.emplace_back(port_dir.stem().to_string()); + } + } + + for (auto&& port_name : port_names) + { + auto maybe_scf = Paragraphs::try_load_port(fs, paths.builtin_ports_directory() / port_name); + if (!maybe_scf) + { + msg::println_error(msgAddVersionLoadPortFailed, msg::package_name = port_name); + print_error_message(maybe_scf.error()); + Checks::check_exit(VCPKG_LINE_INFO, !add_all); + continue; + } + SourceControlFileAndLocation scf{std::move(maybe_scf.value_or_exit(VCPKG_LINE_INFO)), + paths.builtin_ports_directory() / port_name}; + Lint::Status s = Lint::check_license_expression(*scf.source_control_file, fix); + s |= Lint::check_used_version_scheme(*scf.source_control_file, fix); + s |= Lint::check_portfile_deprecated_functions(fs, scf, fix); + + if (s == Lint::Status::Fixed || s == Lint::Status::PartiallyFixed) + { + if (s == Lint::Status::Fixed) + { + msg::print(msg::format(msgLintPortErrorsFixed, msg::package_name = port_name).append_raw("\n\n")); + } + else + { + msg::print(Color::error, + msg::format(msgLintPortErrors, msg::package_name = port_name).append_raw("\n\n")); + } + if (increase_version) scf.source_control_file->core_paragraph->port_version += 1; + scf.source_control_file->canonicalize(); + std::error_code ec; + fs.write_contents(scf.source_location / "vcpkg.json", + Json::stringify(serialize_manifest(*scf.source_control_file)), + ec); + if (ec) + { + Checks::msg_exit_with_error( + VCPKG_LINE_INFO, + msg::format(msgFailedToWriteManifest, msg::path = scf.source_location / "vcpkg.json") + .append_raw(": ") + .append_raw(ec.message())); + } + } + else if (s == Lint::Status::Problem) + { + msg::print(Color::error, + msg::format(msgLintPortErrors, msg::package_name = port_name).append_raw("\n\n")); + } + } + Checks::exit_success(VCPKG_LINE_INFO); + } + + void LintPortCommand::perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths) const + { + LintPort::perform_and_exit(args, paths); + } +} diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp new file mode 100644 index 0000000000..6dc3b8f98f --- /dev/null +++ b/src/vcpkg/portlint.cpp @@ -0,0 +1,268 @@ +#include + +#include +#include +#include +#include + +#include "vcpkg/base/system.print.h" +#include "vcpkg/base/system.process.h" +#include "vcpkg/base/util.h" +#include "vcpkg/installedpaths.h" +#include "vcpkg/vcpkgpaths.h" + +namespace vcpkg::Lint +{ + + constexpr StringLiteral VERSION_RELAXED = "version"; + constexpr StringLiteral VERSION_SEMVER = "version-semver"; + constexpr StringLiteral VERSION_DATE = "version-date"; + constexpr StringLiteral VERSION_STRING = "version-string"; + + Status check_used_version_scheme(SourceControlFile& scf, Fix fix) + { + auto scheme = scf.core_paragraph->version_scheme; + auto new_scheme = scheme; + if (scheme == VersionScheme::String) + { + if (DateVersion::try_parse(scf.core_paragraph->raw_version)) + { + new_scheme = VersionScheme::Date; + } + else if (DotVersion::try_parse_relaxed(scf.core_paragraph->raw_version)) + { + new_scheme = VersionScheme::Relaxed; + } + if (scheme != new_scheme) + { + if (fix == Fix::YES) + { + scf.core_paragraph->version_scheme = new_scheme; + return Status::Fixed; + } + msg::println_warning(msgLintSuggestNewVersionScheme, + msg::new_scheme = + (new_scheme == VersionScheme::Date) ? VERSION_DATE : VERSION_RELAXED, + msg::old_scheme = VERSION_STRING, + msg::package_name = scf.core_paragraph->name); + return Status::Problem; + } + } + return Status::Ok; + } + + Status check_license_expression(SourceControlFile& scf, Fix fix) + { + if (!scf.core_paragraph->license.has_value()) + { + msg::println_warning(msgLintMissingLicenseExpression, msg::package_name = scf.core_paragraph->name); + return Status::Problem; + } + const std::pair deprecated_licenses[] = { + {"AGPL-1.0", "AGPL-1.0-only"}, + {"AGPL-3.0", "AGPL-3.0-only"}, + {"eCos-2.0", + "DEPRECATED: Use license expression including main license, \"WITH\" operator, and identifier: " + "eCos-exception-2.0"}, + {"GFDL-1.1", "GFDL-1.1-or-later"}, + {"GFDL-1.2", "GFDL-1.2-or-later"}, + {"GFDL-1.3", "GFDL-1.3-or-later"}, + {"GPL-1.0", "GPL-1.0-only"}, + {"GPL-1.0+", "GPL-1.0-or-later"}, + {"GPL-2.0", "GPL-2.0-only"}, + {"GPL-2.0+", "GPL-2.0-or-later"}, + {"GPL-2.0-with-autoconf-exception", "GPL-2.0-only WITH Autoconf-exception-2.0"}, + {"GPL-2.0-with-bison-exception", "GPL-2.0-or-later WITH Bison-exception-2.2"}, + {"GPL-2.0-with-classpath-exception", + "DEPRECATED: Use license expression including main license, \"WITH\" operator, and identifier: " + "Classpath-exception-2.0"}, + {"GPL-2.0-with-font-exception", + "DEPRECATED: Use license expression including main license, \"WITH\" operator, and identifier: " + "Font-exception-2.0"}, + {"GPL-2.0-with-GCC-exception", "GPL-2.0-or-later WITH GCC-exception-2.0"}, + {"GPL-3.0", "GPL-3.0-only"}, + {"GPL-3.0+", "GPL-3.0-or-later"}, + {"GPL-3.0-with-autoconf-exception", "GPL-3.0-only WITH Autoconf-exception-3.0"}, + {"GPL-3.0-with-GCC-exception", "GPL-3.0-only WITH GCC-exception-3.1"}, + {"LGPL-2.0", "LGPL-2.0-only"}, + {"LGPL-2.0+", "LGPL-2.0-or-later"}, + {"LGPL-2.1", "LGPL-2.1-only"}, + {"LGPL-2.1+", "LGPL-2.1-or-later"}, + {"LGPL-3.0", "LGPL-3.0-only"}, + {"LGPL-3.0+", "LGPL-3.0-or-later"}, + {"Nunit", + "DEPRECATED: This license is based on the MIT license, except with an \"acknowledgement\" clause. That " + "clause makes it functionally equivalent to MIT with advertising (Free, but GPLv2/v3 incompatible)"}, + {"StandardML-NJ", "SMLNJ"}, + {"wxWindows", + "DEPRECATED: Use license expression including main license, \"WITH\" operator, and identifier: " + "WxWindows-exception-3.1"}}; + Status status = Status::Ok; + auto& license = scf.core_paragraph->license.value_or_exit(VCPKG_LINE_INFO); + for (const auto dep_license : deprecated_licenses) + { + const auto index = license.find(dep_license.first.c_str()); + if (index == std::string::npos) + { + continue; + } + const auto end_index = index + dep_license.first.size(); + if (end_index < license.size() && license[end_index] != ' ') + { + continue; + } + if (Strings::starts_with(dep_license.second, "DEPRECATED")) + { + msg::println_warning(msg::format(msgLintDeprecatedLicenseExpressionWithoutReplacement, + msg::package_name = scf.core_paragraph->name, + msg::actual = dep_license.first) + .append_raw(dep_license.second.substr(StringLiteral("DEPRECATED:").size()))); + + status |= Status::Problem; + } + else if (fix == Fix::NO) + { + msg::println_warning(msgLintDeprecatedLicenseExpressionWithReplacement, + msg::package_name = scf.core_paragraph->name, + msg::actual = dep_license.first, + msg::new_value = dep_license.second); + status |= Status::Problem; + } + else + { + license.replace(index, dep_license.first.size(), dep_license.second.c_str()); + status |= Status::Fixed; + } + } + + return status; + } + + Status check_portfile_deprecated_functions(Filesystem& fs, SourceControlFileAndLocation& scf, Fix fix) + { + Status status = Status::Ok; + auto content = fs.read_contents(scf.source_location / "portfile.cmake", VCPKG_LINE_INFO); + const auto handle_warning = [&](StringLiteral deprecated, StringLiteral new_func, bool can_fix = true) { + if (fix == Fix::NO || !can_fix) + { + status |= Status::Problem; + msg::println_warning(msgLintDeprecatedFunction, + msg::package_name = scf.source_control_file->core_paragraph->name, + msg::actual = deprecated, + msg::expected = new_func); + } + else + { + status = Status::Fixed; + } + }; + const auto add_host_dep = [&](std::string name) { + if (!Util::any_of(scf.source_control_file->core_paragraph->dependencies, + [&](const Dependency& d) { return d.name == name; })) + { + scf.source_control_file->core_paragraph->dependencies.push_back(Dependency{name, {}, {}, {}, true}); + } + }; + if (Strings::contains(content, "vcpkg_build_msbuild")) + { + handle_warning("vcpkg_build_msbuild", "vcpkg_install_msbuild", false); + } + std::string::size_type index = 0; + while ((index = content.find("vcpkg_configure_cmake", index)) != std::string::npos) + { + handle_warning("vcpkg_configure_cmake", "vcpkg_cmake_configure"); + if (fix == Fix::NO) + { + break; + } + const auto end = content.find(')', index); + const auto ninja = content.find("PREFER_NINJA", index); + if (ninja != std::string::npos && ninja < end) + { + const auto start = content.find_last_not_of(" \n\t\r", ninja - 1) + 1; + content.erase(start, (ninja - start) + StringLiteral("PREFER_NINJA").size()); + } + content.replace(index, StringLiteral("vcpkg_configure_cmake").size(), "vcpkg_cmake_configure"); + add_host_dep("vcpkg-cmake"); + } + if (Strings::contains(content, "vcpkg_build_cmake")) + { + handle_warning("vcpkg_build_cmake", "vcpkg_cmake_build"); + Strings::inplace_replace_all(content, "vcpkg_build_cmake", "vcpkg_cmake_build"); + add_host_dep("vcpkg-cmake"); + } + if (Strings::contains(content, "vcpkg_install_cmake")) + { + handle_warning("vcpkg_install_cmake", "vcpkg_cmake_install"); + Strings::inplace_replace_all(content, "vcpkg_install_cmake", "vcpkg_cmake_install"); + } + index = 0; + while ((index = content.find("vcpkg_fixup_cmake_targets", index)) != std::string::npos) + { + handle_warning("vcpkg_fixup_cmake_targets", "vcpkg_fixup_cmake_targets"); + if (fix == Fix::NO) + { + break; + } + const auto end = content.find(')', index); + const auto target = content.find("TARGET_PATH"); + if (target != std::string::npos && target < end) + { + auto start_param = target + StringLiteral("TARGET_PATH").size(); + start_param = content.find_first_not_of(" \n\t)", start_param); + const auto end_param = content.find_first_of(" \n\t)", start_param); + if (end_param != std::string::npos && end_param <= end) + { + const auto original_param = content.substr(start_param, end_param - start_param); + auto param = StringView(original_param); + if (Strings::starts_with(param, "share/")) + { + param = param.substr(StringLiteral("share/").size()); + } + if (param == "${PORT}" || + Strings::case_insensitive_ascii_equals(param, scf.source_control_file->core_paragraph->name)) + { + content.erase(target, end_param - target); + } + else + { + content.replace(target, (end_param - target) - param.size(), "PACKAGE_NAME "); + } + // remove the CONFIG_PATH part if it uses the same param + const auto start_config_path = content.find("CONFIG_PATH", index); + if (start_config_path != std::string::npos && start_config_path < end) + { + auto start_param = start_config_path + StringLiteral("CONFIG_PATH").size(); + start_param = content.find_first_not_of(" \n\t)", start_param); + const auto end_param = content.find_first_of(" \n\t)", start_param); + const auto config_param = StringView(content).substr(start_param, end_param - start_param); + if (config_param == original_param) + { + const auto start_next = content.find_first_not_of(' ', end_param); + content.erase(start_config_path, start_next - start_config_path); + } + } + } + else + { + const auto start = content.find_last_not_of(" \n\t\r", target - 1) + 1; + content.erase(start, StringLiteral("TARGET_PATH").size() + (target - start)); + } + } + content.replace(index, StringLiteral("vcpkg_fixup_cmake_targets").size(), "vcpkg_cmake_config_fixup"); + add_host_dep("vcpkg-cmake-config"); + } + if (status == Status::Fixed || status == Status::PartiallyFixed) + { + fs.write_contents(scf.source_location / "portfile.cmake", content, VCPKG_LINE_INFO); + } + return status; + } + + Status& operator|=(Status& self, Status s) + { + self = static_cast(static_cast>(self) | + static_cast>(s)); + return self; + } +} diff --git a/src/vcpkg/sourceparagraph.cpp b/src/vcpkg/sourceparagraph.cpp index 49e0eb800b..c96ae4aabb 100644 --- a/src/vcpkg/sourceparagraph.cpp +++ b/src/vcpkg/sourceparagraph.cpp @@ -136,7 +136,7 @@ namespace vcpkg namespace { - constexpr static struct Canonicalize + constexpr struct Canonicalize { struct FeatureLess { @@ -212,16 +212,16 @@ namespace vcpkg void operator()(SourceParagraph& spgh) const { std::for_each(spgh.dependencies.begin(), spgh.dependencies.end(), *this); - std::sort(spgh.dependencies.begin(), spgh.dependencies.end(), DependencyLess{}); + Util::sort_unique_erase(spgh.dependencies, DependencyLess{}); - std::sort(spgh.default_features.begin(), spgh.default_features.end()); + Util::sort_unique_erase(spgh.default_features); spgh.extra_info.sort_keys(); } void operator()(FeatureParagraph& fpgh) const { std::for_each(fpgh.dependencies.begin(), fpgh.dependencies.end(), *this); - std::sort(fpgh.dependencies.begin(), fpgh.dependencies.end(), DependencyLess{}); + Util::sort_unique_erase(fpgh.dependencies, DependencyLess{}); fpgh.extra_info.sort_keys(); } @@ -245,7 +245,7 @@ namespace vcpkg } return nullptr; } - } canonicalize{}; + } canonicalize_{}; } static ParseExpected parse_source_paragraph(StringView origin, Paragraph&& fields) @@ -394,7 +394,7 @@ namespace vcpkg return std::move(maybe_feature).error(); } - if (auto maybe_error = canonicalize(*control_file)) + if (auto maybe_error = canonicalize_(*control_file)) { return maybe_error; } @@ -1081,7 +1081,7 @@ namespace vcpkg } } - if (auto maybe_error = canonicalize(*control_file)) + if (auto maybe_error = control_file->canonicalize()) { Checks::exit_with_message(VCPKG_LINE_INFO, maybe_error->error); } @@ -1357,6 +1357,8 @@ namespace vcpkg return nullopt; } + std::unique_ptr SourceControlFile::canonicalize() { return canonicalize_(*this); } + std::string ParseControlErrorInfo::format_errors(View> error_info_list) { std::string message; From c5d55579d812f8ca221c085773a187a1a5fa77eb Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Thu, 29 Sep 2022 15:38:27 +0200 Subject: [PATCH 02/28] CR --- src/vcpkg/commands.add-version.cpp | 2 -- src/vcpkg/portlint.cpp | 7 +------ 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/src/vcpkg/commands.add-version.cpp b/src/vcpkg/commands.add-version.cpp index 466d6a3c65..b06f5bbb81 100644 --- a/src/vcpkg/commands.add-version.cpp +++ b/src/vcpkg/commands.add-version.cpp @@ -71,8 +71,6 @@ namespace Checks::unreachable(VCPKG_LINE_INFO); } - void lint_port(SourceControlFileAndLocation& scf) { } - static Json::Object serialize_baseline(const std::map>& baseline) { Json::Object port_entries_obj; diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index 6dc3b8f98f..9a439e0ac9 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -5,17 +5,12 @@ #include #include -#include "vcpkg/base/system.print.h" -#include "vcpkg/base/system.process.h" #include "vcpkg/base/util.h" -#include "vcpkg/installedpaths.h" -#include "vcpkg/vcpkgpaths.h" namespace vcpkg::Lint { constexpr StringLiteral VERSION_RELAXED = "version"; - constexpr StringLiteral VERSION_SEMVER = "version-semver"; constexpr StringLiteral VERSION_DATE = "version-date"; constexpr StringLiteral VERSION_STRING = "version-string"; @@ -58,7 +53,7 @@ namespace vcpkg::Lint msg::println_warning(msgLintMissingLicenseExpression, msg::package_name = scf.core_paragraph->name); return Status::Problem; } - const std::pair deprecated_licenses[] = { + static constexpr std::pair deprecated_licenses[] = { {"AGPL-1.0", "AGPL-1.0-only"}, {"AGPL-3.0", "AGPL-3.0-only"}, {"eCos-2.0", From 32ef8e0da75406a509135b13ebc7215919b84f2f Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Fri, 30 Sep 2022 13:31:29 +0200 Subject: [PATCH 03/28] fix bug --- src/vcpkg/commands.add-version.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcpkg/commands.add-version.cpp b/src/vcpkg/commands.add-version.cpp index b06f5bbb81..109519e20d 100644 --- a/src/vcpkg/commands.add-version.cpp +++ b/src/vcpkg/commands.add-version.cpp @@ -203,7 +203,7 @@ namespace } } Checks::msg_check_exit( - VCPKG_LINE_INFO, status == Lint::Status::Problem, msgAddVersionLintPort, msg::package_name = port_name); + VCPKG_LINE_INFO, status == Lint::Status::Ok, msgAddVersionLintPort, msg::package_name = port_name); }; if (!fs.exists(version_db_file_path, IgnoreErrors{})) { From 689e47db824c854a7d317158e2a167c819cfa318 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Fri, 30 Sep 2022 15:56:48 +0200 Subject: [PATCH 04/28] Adopt tests --- azure-pipelines/end-to-end-tests-dir/versions.ps1 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/azure-pipelines/end-to-end-tests-dir/versions.ps1 b/azure-pipelines/end-to-end-tests-dir/versions.ps1 index a0de03dfb7..2074423714 100644 --- a/azure-pipelines/end-to-end-tests-dir/versions.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/versions.ps1 @@ -34,35 +34,35 @@ Throw-IfNotFailed $CurrentTest = "x-add-version cat" # Do not fail if there's nothing to update -Run-Vcpkg @portsRedirectArgsIncomplete x-add-version cat +Run-Vcpkg @portsRedirectArgsIncomplete x-add-version --skip-license-check cat Throw-IfFailed $CurrentTest = "x-add-version dog" # Local version is not in baseline and versions file -Run-Vcpkg @portsRedirectArgsIncomplete x-add-version dog +Run-Vcpkg @portsRedirectArgsIncomplete x-add-version --skip-license-check dog Throw-IfFailed $CurrentTest = "x-add-version duck" # Missing versions file -Run-Vcpkg @portsRedirectArgsIncomplete x-add-version duck +Run-Vcpkg @portsRedirectArgsIncomplete x-add-version --skip-license-check duck Throw-IfFailed $CurrentTest = "x-add-version ferret" # Missing versions file and missing baseline entry -Run-Vcpkg @portsRedirectArgsIncomplete x-add-version ferret +Run-Vcpkg @portsRedirectArgsIncomplete x-add-version --skip-license-check ferret Throw-IfFailed $CurrentTest = "x-add-version fish (must fail)" # Discrepancy between local SHA and SHA in fish.json. Requires --overwrite-version. -$out = Run-Vcpkg @portsRedirectArgsIncomplete x-add-version fish +$out = Run-Vcpkg @portsRedirectArgsIncomplete x-add-version --skip-license-check fish Throw-IfNotFailed $CurrentTest = "x-add-version fish --overwrite-version" -Run-Vcpkg @portsRedirectArgsIncomplete x-add-version fish --overwrite-version --skip-version-format-check +Run-Vcpkg @portsRedirectArgsIncomplete x-add-version fish --overwrite-version --skip-version-format-check --skip-license-check Throw-IfFailed $CurrentTest = "x-add-version mouse" # Missing baseline entry -Run-Vcpkg @portsRedirectArgsIncomplete x-add-version mouse +Run-Vcpkg @portsRedirectArgsIncomplete x-add-version --skip-license-check mouse Throw-IfFailed # Validate changes Run-Vcpkg @portsRedirectArgsIncomplete x-ci-verify-versions --verbose From bfe12fe5762f95d6f02fecab19917a13a006278d Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Wed, 2 Nov 2022 16:39:55 +0100 Subject: [PATCH 05/28] Fix warning --- src/vcpkg/portlint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index 9a439e0ac9..4f046d806c 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -227,7 +227,7 @@ namespace vcpkg::Lint const auto start_config_path = content.find("CONFIG_PATH", index); if (start_config_path != std::string::npos && start_config_path < end) { - auto start_param = start_config_path + StringLiteral("CONFIG_PATH").size(); + start_param = start_config_path + StringLiteral("CONFIG_PATH").size(); start_param = content.find_first_not_of(" \n\t)", start_param); const auto end_param = content.find_first_of(" \n\t)", start_param); const auto config_param = StringView(content).substr(start_param, end_param - start_param); From 1bad290280e16ebc8f7138364c434c536f270743 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Wed, 2 Nov 2022 18:26:02 +0100 Subject: [PATCH 06/28] Fix test --- azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 b/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 index abe759d163..3749a12e9f 100644 --- a/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 @@ -11,7 +11,7 @@ $testProjects | % { Write-Trace "test that format-manifest on $full produces $expectedPath" [string]$expected = Get-Content $expectedPath -Raw Copy-Item $asItem $tempItemPath - Run-Vcpkg format-manifest $tempItemPath + Run-Vcpkg format-manifest $tempItemPath | Out-Null $actual = Get-Content $tempItemPath -Raw if ($expected -ne $actual) { throw "Expected formatting $full to produce $expectedPath but was $tempItemPath" @@ -25,6 +25,9 @@ New-Item -Path $manifestDir -ItemType Directory | Out-Null $ports = Get-ChildItem "$env:VCPKG_ROOT/ports" $ports | % { + if (($_ | Split-Path -leaf) -in @("libuvc", "mlpack", "qt5-virtualkeyboard")) { + return + } Copy-Item "$_/vcpkg.json" "$manifestDir" | Out-Null $x = Get-Content "$manifestDir/vcpkg.json" -Raw Run-Vcpkg -EndToEndTestSilent format-manifest "$manifestDir/vcpkg.json" | Out-Null From d3668f39e0ac91ce06c33cff04ad5a2c0227f240 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Wed, 2 Nov 2022 18:42:23 +0100 Subject: [PATCH 07/28] Fix e2e tests --- azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 b/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 index 3749a12e9f..46217cbc60 100644 --- a/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 @@ -25,7 +25,7 @@ New-Item -Path $manifestDir -ItemType Directory | Out-Null $ports = Get-ChildItem "$env:VCPKG_ROOT/ports" $ports | % { - if (($_ | Split-Path -leaf) -in @("libuvc", "mlpack", "qt5-virtualkeyboard")) { + if (($_ | Split-Path -leaf) -in @("libuvc", "mlpack", "qt5-virtualkeyboard", "qtwebengine")) { return } Copy-Item "$_/vcpkg.json" "$manifestDir" | Out-Null From c48fb102700aab9d235b522fcb59021538aaaff9 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Wed, 2 Nov 2022 18:43:54 +0100 Subject: [PATCH 08/28] Fix windows --- src/vcpkg/portlint.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index 4f046d806c..9e6348aec6 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -229,11 +229,12 @@ namespace vcpkg::Lint { start_param = start_config_path + StringLiteral("CONFIG_PATH").size(); start_param = content.find_first_not_of(" \n\t)", start_param); - const auto end_param = content.find_first_of(" \n\t)", start_param); - const auto config_param = StringView(content).substr(start_param, end_param - start_param); + const auto end_config_param = content.find_first_of(" \n\t)", start_param); + const auto config_param = + StringView(content).substr(start_param, end_config_param - start_param); if (config_param == original_param) { - const auto start_next = content.find_first_not_of(' ', end_param); + const auto start_next = content.find_first_not_of(' ', end_config_param); content.erase(start_config_path, start_next - start_config_path); } } From 23a7459be9215177529eae3ed3894de760ec13ca Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Sat, 5 Nov 2022 13:56:21 +0100 Subject: [PATCH 09/28] Ignore more wrong ports --- azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 b/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 index 46217cbc60..2a3326c61c 100644 --- a/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 +++ b/azure-pipelines/end-to-end-tests-dir/format-manifest.ps1 @@ -25,7 +25,7 @@ New-Item -Path $manifestDir -ItemType Directory | Out-Null $ports = Get-ChildItem "$env:VCPKG_ROOT/ports" $ports | % { - if (($_ | Split-Path -leaf) -in @("libuvc", "mlpack", "qt5-virtualkeyboard", "qtwebengine")) { + if (($_ | Split-Path -leaf) -in @("libuvc", "mlpack", "qt5-virtualkeyboard", "qtwebengine", "vamp-sdk")) { return } Copy-Item "$_/vcpkg.json" "$manifestDir" | Out-Null From b0b44959106df9b9750a618ff45f23267b242245 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Sun, 13 Nov 2022 12:34:22 +0100 Subject: [PATCH 10/28] Apply format diff --- locales/messages.en.json | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/locales/messages.en.json b/locales/messages.en.json index d9279ea499..e78910c237 100644 --- a/locales/messages.en.json +++ b/locales/messages.en.json @@ -41,17 +41,20 @@ "AllPackagesAreUpdated": "All installed packages are up-to-date with the local portfile.", "AlreadyInstalled": "{spec} is already installed", "AlreadyInstalledNotHead": "{spec} is already installed -- not building from HEAD", + "AmbiguousConfigDeleteConfigFile": "Ambiguous vcpkg configuration provided by both manifest and configuration file.\n-- Delete configuration file {path}", "AndroidHomeDirMissingProps": "source.properties missing in {env_var} directory: {path}", "AnotherInstallationInProgress": "Another installation is in progress on the machine, sleeping 6s before retrying.", "AppliedUserIntegration": "Applied user-wide integration for this vcpkg root.", "ArtifactsOptionIncompatibility": "--{option} has no effect on find artifact.", "AssetSourcesArg": "Add sources for asset caching. See 'vcpkg help assetcaching'.", "AttemptingToFetchPackagesFromVendor": "Attempting to fetch {count} package(s) from {vendor}", + "AttemptingToSetBuiltInBaseline": "attempting to set builtin-baseline in vcpkg.json while overriding the default-registry in vcpkg-configuration.json.\nthe default-registry from vcpkg-configuration.json will be used.", "AuthenticationMayRequireManualAction": "One or more {vendor} credential providers requested manual action. Add the binary source 'interactive' to allow interactivity.", "AutoSettingEnvVar": "-- Automatically setting {env_var} environment variables to \"{url}\".", "AutomaticLinkingForMSBuildProjects": "All MSBuild C++ projects can now #include any installed libraries. Linking will be handled automatically. Installing new libraries will make them instantly available.", "AvailableArchitectureTriplets": "Available architecture triplets:", "AvailableHelpTopics": "Available help topics:", + "BaselineConflict": "Specifying vcpkg-configuration.default-registry in a manifest file conflicts with built-in baseline.\nPlease remove one of these conflicting settings.", "BaselineFileNoDefaultField": "The baseline file at commit {commit_sha} was invalid (no \"default\" field).", "BaselineMissingDefault": "The baseline.json from commit `\"{commit_sha}\"` in the repo {url} was invalid (did not contain a \"default\" field).", "BinarySourcesArg": "Add sources for binary caching. See 'vcpkg help binarycaching'.", @@ -112,6 +115,7 @@ "CouldNotFindBaselineForRepo": "Couldn't find baseline `\"{commit_sha}\"` for repo {package_name}", "CouldNotFindBaselineInCommit": "Couldn't find baseline in commit `\"{commit_sha}\"` from repo {package_name}:", "CouldNotFindGitTreeAtCommit": "could not find the git tree for `versions` in repo {package_name} at commit {commit_sha}", + "CouldNotFindToolVersion": "Could not find in {path}", "CreateFailureLogsDir": "Creating failure logs output directory {path}.", "CreatedNuGetPackage": "Created nupkg: {path}", "Creating7ZipArchive": "Creating 7zip archive...", @@ -121,16 +125,20 @@ "CurlFailedToExecute": "curl failed to execute with exit code {exit_code}.", "CurlReportedUnexpectedResults": "curl has reported unexpected results to vcpkg and vcpkg cannot continue.\nPlease review the following text for sensitive information and open an issue on the Microsoft/vcpkg GitHub to help fix this problem!\ncmd: {command_line}\n=== curl output ===\n{actual}\n=== end curl output ===", "CurlReturnedUnexpectedResponseCodes": "curl returned a different number of response codes than were expected for the request ({actual} vs expected {expected}).", + "CurrentCommitBaseline": "You can use the current commit as a baseline, which is:\n\t\"builtin-baseline\": \"{value}\"", "DateTableHeader": "Date", "DefaultBrowserLaunched": "Default browser launched to {url}.", "DefaultFlag": "Defaulting to --{option} being on.", "DefaultPathToBinaries": "Based on your system settings, the default path to store binaries is \"{path}\". This consults %LOCALAPPDATA%/%APPDATA% on Windows and $XDG_CACHE_HOME or $HOME on other platforms.", + "DeleteVcpkgConfigFromManifest": "-- Or remove \"vcpkg-configuration\" from the manifest file {path}.", "DeprecatedPrefabDebugOption": "--prefab-debug is now deprecated.", "DetectCompilerHash": "Detecting compiler hash for triplet {triplet}...", "DocumentedFieldsSuggestUpdate": "If these are documented fields that should be recognized try updating the vcpkg tool.", "DownloadAvailable": "A downloadable copy of this tool is available and can be used by unsetting {env_var}.", "DownloadRootsDir": "Specify the downloads root directory.\n(default: {env_var})", "DownloadedSources": "Downloaded sources for {spec}", + "DownloadingPortableToolVersionX": "A suitable version of {tool_name} was not found (required v{version}) Downloading portable {tool_name} {version}...", + "DownloadingTool": "Downloading {tool_name}...\n{url}->{path}", "DownloadingVcpkgCeBundle": "Downloading vcpkg-ce bundle {version}...", "DownloadingVcpkgCeBundleLatest": "Downloading latest vcpkg-ce bundle...", "DownloadingVcpkgStandaloneBundle": "Downloading standalone bundle {version}.", @@ -142,6 +150,7 @@ "ElapsedInstallTime": "Total elapsed time: {count}", "ElapsedTimeForChecks": "Time to determine pass/fail: {elapsed}", "EmailVcpkgTeam": "Send an email to {url} with any feedback.", + "EmbeddingVcpkgConfigInManifest": "Embedding `vcpkg-configuration` in a manifest file is an EXPERIMENTAL feature.", "EmptyArg": "The option --{option} must be passed a non-empty argument.", "EmptyLicenseExpression": "SPDX license expression was empty.", "EndOfStringInCodeUnit": "found end of string in middle of code point", @@ -177,6 +186,7 @@ "ExpectedDigitsAfterDecimal": "Expected digits after the decimal point", "ExpectedFailOrSkip": "expected 'fail', 'skip', or 'pass' here", "ExpectedOneSetOfTags": "Found {count} sets of {old_value}.*{new_value} but expected exactly 1, in block:\n{value}", + "ExpectedPathToExist": "Expected {path} to exist after fetching", "ExpectedPortName": "expected a port name here", "ExpectedStatusField": "Expected 'status' field in status paragraph", "ExpectedTripletName": "expected a triplet name here", @@ -190,7 +200,9 @@ "ExportingMaintenanceTool": "Exporting maintenance tool...", "ExportingPackage": "Exporting {package_name}...", "ExtendedDocumentationAtUrl": "Extended documentation available at '{url}'.", + "ExtractingTool": "Extracting {tool_name}...", "FailedToCheckoutRepo": "failed to check out `versions` from repo {package_name}", + "FailedToDetermineCurrentCommit": "Failed to determine the current commit:", "FailedToDownloadFromMirrorSet": "Failed to download from mirror set", "FailedToExtract": "Failed to extract \"{path}\":", "FailedToFetchError": "{error_msg}\nFailed to fetch {package_name}:", @@ -198,6 +210,7 @@ "FailedToFindPortFeature": "Could not find {feature} in {spec}.", "FailedToFormatMissingFile": "No files to format.\nPlease pass either --all, or the explicit files to format or convert.", "FailedToLoadInstalledManifest": "The control or manifest file for {spec} could not be loaded due to the following error. Please remove {spec} and try again.", + "FailedToLoadManifest": "Failed to load manifest from directory {path}", "FailedToLoadPort": "Failed to load port {package_name} from {path}", "FailedToLoadPortFrom": "Failed to load port from {path}", "FailedToLoadUnnamedPortFromPath": "Failed to load port from {path}", @@ -206,10 +219,13 @@ "FailedToObtainLocalPortGitSha": "Failed to obtain git SHAs for local ports.", "FailedToObtainPackageVersion": "Cannot find desired package version.", "FailedToParseCMakeConsoleOut": "Failed to parse CMake console output to locate block start/end markers.", + "FailedToParseConfig": "Failed to parse configuration {path}", "FailedToParseControl": "Failed to parse control file: {path}", "FailedToParseJson": "Failed to parse JSON file: {path}", "FailedToParseManifest": "Failed to parse manifest file: {path}", + "FailedToParseNoTopLevelObj": "Failed to parse {path}, expected a top-level object.", "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:", + "FailedToParseVersionXML": "Could not parse version for tool {tool_name}. Version string was: {version}", "FailedToProvisionCe": "Failed to provision vcpkg-ce.", "FailedToRead": "Failed to read {path}: {error_msg}", "FailedToReadParagraph": "Failed to read paragraphs from {path}", @@ -217,6 +233,7 @@ "FailedToRunToolToDetermineVersion": "Failed to run \"{path}\" to determine the {tool_name} version.", "FailedToStoreBackToMirror": "failed to store back to mirror:", "FailedToStoreBinaryCache": "Failed to store binary cache {path}", + "FailedToTakeFileSystemLock": "Failed to take the filesystem lock on {path}", "FailedToWriteManifest": "Failed to write manifest file {path}", "FailedVendorAuthentication": "One or more {vendor} credential providers failed to authenticate. See '{url}' for more details on how to provide credentials.", "FeedbackAppreciated": "Thank you for your feedback!", @@ -289,7 +306,7 @@ "HelpVersionSemverScheme": "A Semantic Version 2.0 (2.1.0-rc2)", "HelpVersionStringScheme": "An exact, incomparable version (Vista)", "HelpVersioning": "Versioning allows you to deterministically control the precise revisions of dependencies used by your project from within your manifest file.", - "IgnoringVcpkgRootEnvironment": "Ignoring VCPKG_ROOT environment variable; use --vcpkg-root \"{path}\" to use the environment value or unset the VCPKG_ROOT environment variable to suppress this message. Using detected vcpkg root: \"{actual}\".", + "IgnoringVcpkgRootEnvironment": "The vcpkg {value} is using detected vcpkg root {actual} and ignoring mismatched VCPKG_ROOT environment value {path}. To suppress this message, unset the environment variable or use the --vcpkg-root command line switch.", "IllegalFeatures": "List of features is not allowed in this context", "IllegalPlatformSpec": "Platform qualifier is not allowed in this context", "ImproperShaLength": "SHA512's must be 128 hex characters: {value}", @@ -332,6 +349,8 @@ "InvalidArgumentRequiresTwoOrThreeArguments": "invalid argument: binary config '{binary_source}' requires 2 or 3 arguments", "InvalidArgumentRequiresValidToken": "invalid argument: binary config '{binary_source}' requires a SAS token without a preceeding '?' as the second argument", "InvalidBuildInfo": "Invalid BUILD_INFO file for package: {error_msg}", + "InvalidBuiltInBaseline": "the top-level builtin-baseline ({value}) was not a valid commit sha: expected 40 hexadecimal characters.", + "InvalidBundleDefinition": "Invalid bundle definition.", "InvalidCodePoint": "Invalid code point passed to utf8_encoded_code_point_count", "InvalidCodeUnit": "invalid code unit", "InvalidCommandArgSort": "Value of --sort must be one of 'lexicographical', 'topological', 'reverse'.", @@ -384,6 +403,7 @@ "LoadingCommunityTriplet": "-- [COMMUNITY] Loading triplet configuration from: {path}", "LoadingDependencyInformation": "Loading dependency information for {count} packages...", "LoadingOverlayTriplet": "-- [OVERLAY] Loading triplet configuration from: {path}", + "LocalPortfileVersion": "Using local portfile versions. To update the local portfiles, use `git pull`.", "LocalizedMessageMustNotContainIndents": "The message named {value} contains what appears to be indenting which must be changed to use LocalizedString::append_indent instead.", "LocalizedMessageMustNotEndWithNewline": "The message named {value} ends with a newline which should be added by formatting rather than by localization.", "ManifestConflict": "Found both a manifest and CONTROL files in port \"{path}\"; please rename one or the other", @@ -435,6 +455,7 @@ "PackagesToRebuild": "The following packages will be rebuilt:", "PackagesToRebuildSuggestRecurse": "If you are sure you want to rebuild the above packages, run the command with the --recurse option.", "PackagesToRemove": "The following packages will be removed:", + "PackagesUpToDate": "No packages need updating.", "PackingVendorFailed": "Packing {vendor} failed. Use --debug for more information.", "PairedSurrogatesAreInvalid": "trailing surrogate following leading surrogate (paired surrogates are invalid)", "ParseControlErrorInfoInvalidFields": "The following fields were not expected:", @@ -442,19 +463,18 @@ "ParseControlErrorInfoTypesEntry": "{value} was expected to be {expected}", "ParseControlErrorInfoWhileLoading": "while loading {path}:", "ParseControlErrorInfoWrongTypeFields": "The following fields had the wrong types:", + "PathMustBeAbsolute": "Value of environment variable X_VCPKG_REGISTRIES_CACHE is not absolute: {path}", "PortDependencyConflict": "Port {package_name} has the following unsupported dependencies:", "PortNotInBaseline": "the baseline does not contain an entry for port {package_name}", "PortSupportsField": "(supports: \"{supports_expression}\")", "PortTypeConflict": "The port type of {spec} differs between the installed and available portfile.\nPlease manually remove {spec} and re-run this command.", + "PortVersionConflict": "The following packages differ from their port versions:", "PortsAdded": "The following {count} ports were added:", "PortsNoDiff": "There were no changes in the ports between the two commits.", "PortsRemoved": "The following {count} ports were removed:", "PortsUpdated": "\nThe following {count} ports were updated:", "PrebuiltPackages": "There are packages that have not been built. To build them run:", "PreviousIntegrationFileRemains": "Previous integration file was not removed.", - "ProcessorArchitectureMalformed": "Failed to parse %PROCESSOR_ARCHITECTURE% ({arch}) as a valid CPU architecture.", - "ProcessorArchitectureMissing": "The required environment variable %PROCESSOR_ARCHITECTURE% is missing.", - "ProcessorArchitectureW6432Malformed": "Failed to parse %PROCESSOR_ARCHITEW6432% ({arch}) as a valid CPU architecture. Falling back to %PROCESSOR_ARCHITECTURE%.", "ProgramReturnedNonzeroExitCode": "{tool_name} failed with exit code: ({exit_code}).", "ProvideExportType": "At least one of the following options are required: --raw --nuget --ifw --zip --7zip --chocolatey --prefab.", "PushingVendorFailed": "Pushing {vendor} to \"{path}\" failed. Use --debug for more information.", @@ -489,11 +509,15 @@ "SuggestUpdateVcpkg": "You may need to update the vcpkg binary; try running {command_line} to update.", "SupportedPort": "Port {package_name} is supported.", "SystemApiErrorMessage": "calling {system_api} failed with {exit_code} ({error_msg})", + "ToRemovePackages": "To only remove outdated packages, run\n{command_name} remove --outdated", + "ToUpdatePackages": "To update these packages and all dependencies, run\n{command_name} upgrade'", "ToolFetchFailed": "Could not fetch {tool_name}.", "ToolInWin10": "This utility is bundled with Windows 10 or later.", - "TotalTime": "Total elapsed time: {elapsed}", + "ToolOfVersionXNotFound": "A suitable version of {tool_name} was not found (required v{version}) and unable to automatically download a portable one. Please install a newer version of {tool_name}", + "TotalInstallTime": "Total install time: {elapsed}", "TrailingCommaInArray": "Trailing comma in array", "TrailingCommaInObj": "Trailing comma in an object", + "TripletFileNotFound": "Triplet file {triplet}.cmake not found", "TwoFeatureFlagsSpecified": "Both '{value}' and -'{value}' were specified as feature flags.", "UndeterminedToolChainForTriplet": "Unable to determine toolchain use for {triplet} with with CMAKE_SYSTEM_NAME {system_name}. Did you mean to use VCPKG_CHAINLOAD_TOOLCHAIN_FILE?", "UnexpectedByteSize": "Expected {expected} bytes to be written, but {actual} were written.", @@ -543,6 +567,7 @@ "UnsupportedSyntaxInCDATA": "]]> is not supported in CDATA block", "UnsupportedSystemName": "Could not map VCPKG_CMAKE_SYSTEM_NAME '{system_name}' to a vcvarsall platform. Supported system names are '', 'Windows' and 'WindowsStore'.", "UnsupportedToolchain": "in triplet {triplet}: Unable to find a valid toolchain for requested target architecture {arch}.\nThe selected Visual Studio instance is at: {path}\nThe available toolchain combinations are: {list}", + "UnsupportedUpdateCMD": "the update command does not currently support manifest mode. Instead, modify your vcpkg.json and run install.", "UpdateBaselineAddBaselineNoManifest": "the --{option} switch was passed, but there is no manifest file to add a `builtin-baseline` field to.", "UpdateBaselineLocalGitError": "git failed to parse HEAD for the local vcpkg registry at \"{path}\"", "UpdateBaselineNoConfiguration": "neither `vcpkg.json` nor `vcpkg-configuration.json` exist to update.", @@ -565,17 +590,19 @@ "VSExaminedInstances": "The following Visual Studio instances were considered:", "VSExaminedPaths": "The following paths were examined for Visual Studio instances:", "VSNoInstances": "Could not locate a complete Visual Studio instance", - "VcpkgCeIsExperimental": "vcpkg-artifacts are experimental and may change at any time.", + "VcpkgCeIsExperimental": "vcpkg-ce ('configure environment') is experimental and may change at any time.", "VcpkgCommitTableHeader": "VCPKG Commit", "VcpkgCompletion": "vcpkg {value} completion is already imported to your \"{path}\" file.\nThe following entries were found:", "VcpkgDisallowedClassicMode": "Could not locate a manifest (vcpkg.json) above the current working directory.\nThis vcpkg distribution does not have a classic mode instance.", "VcpkgHasCrashed": "vcpkg has crashed. Please create an issue at https://github.com/microsoft/vcpkg containing a brief summary of what you were trying to do and the following information.", "VcpkgInVsPrompt": "vcpkg appears to be in a Visual Studio prompt targeting {value} but installing for {triplet}. Consider using --triplet {value}-windows or --triplet {value}-uwp.", "VcpkgInvalidCommand": "invalid command: {command_name}", + "VcpkgRegistriesCacheIsNotDirectory": "Value of environment variable X_VCPKG_REGISTRIES_CACHE is not a directory: {path}", "VcpkgRootRequired": "Setting VCPKG_ROOT is required for standalone bootstrap.", "VcpkgRootsDir": "Specify the vcpkg root directory.\n(default: '{env_var}')", "VcpkgSendMetricsButDisabled": "passed --sendmetrics, but metrics are disabled.", "VersionCommandHeader": "vcpkg package management program version {version}\n\nSee LICENSE.txt for license information.", + "VersionConflictXML": "Expected {path} version: [{expected_version}], but was [{actual_version}]. Please re-run bootstrap-vcpkg.", "VersionConstraintViolated": "dependency {spec} was expected to be at least version {expected_version}, but is currently {actual_version}.", "VersionInvalidDate": "`{version}` is not a valid date version. Dates must follow the format YYYY-MM-DD and disambiguators must be dot-separated positive integer values without leading zeroes.", "VersionInvalidRelaxed": "`{version}` is not a valid relaxed version (semver with arbitrary numeric element count).", From 686a36fc773c38e05ec93a78c993636ad4893344 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Fri, 25 Nov 2022 20:08:02 +0100 Subject: [PATCH 11/28] Make code more unit testable Suggestions from @vicroms --- include/vcpkg/base/messages.h | 13 ++-- include/vcpkg/portlint.h | 4 ++ locales/messages.json | 6 +- src/vcpkg-test/portlint.cpp | 21 ++++++ src/vcpkg/portlint.cpp | 118 +++++++++++++++++++--------------- 5 files changed, 103 insertions(+), 59 deletions(-) create mode 100644 src/vcpkg-test/portlint.cpp diff --git a/include/vcpkg/base/messages.h b/include/vcpkg/base/messages.h index ef8e9c8c89..7d9914cfad 100644 --- a/include/vcpkg/base/messages.h +++ b/include/vcpkg/base/messages.h @@ -539,13 +539,16 @@ namespace vcpkg DECLARE_MESSAGE( LintDeprecatedLicenseExpressionWithReplacement, (msg::package_name, msg::actual, msg::new_value), - "{actual} is the currently used license and {new_value} is the license expression that should be used", + "{actual} is the currently used license expression and {new_value} is the license expression that should be " + "used", "The port \"{package_name}\" uses the deprecated license expression \"{actual}\". You shoud use the non " "deprecated version \"{new_value}\"."); - DECLARE_MESSAGE(LintDeprecatedLicenseExpressionWithoutReplacement, - (msg::package_name, msg::actual), - "{actual} is the currently used license", - "The port \"{package_name}\" uses the deprecated license expression \"{actual}\"."); + DECLARE_MESSAGE( + LintDeprecatedLicenseExpressionWithoutReplacement, + (msg::package_name, msg::actual, msg::new_value), + "{actual} is the currently used license, {new_value} is the suggested WITH expression", + "The port \"{package_name}\" uses the deprecated license expression \"{actual}\". " + "Use license expression including main license, \"WITH\" operator, and identifier: \"{new_value}\""); DECLARE_MESSAGE(LintMissingLicenseExpression, (msg::package_name), "", diff --git a/include/vcpkg/portlint.h b/include/vcpkg/portlint.h index 80e66415b5..20e548d0c5 100644 --- a/include/vcpkg/portlint.h +++ b/include/vcpkg/portlint.h @@ -27,6 +27,10 @@ namespace vcpkg::Lint YES // The problem is fixed in place (SourceControlFile) and no message is printed }; + std::string get_recommended_license_expression(std::string original_license); + + VersionScheme get_recommended_version_scheme(StringView raw_version, VersionScheme original_scheme); + Status check_used_version_scheme(SourceControlFile& scf, Fix fix); Status check_license_expression(SourceControlFile& scf, Fix fix); diff --git a/locales/messages.json b/locales/messages.json index 51db848655..28e752ae95 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -631,9 +631,9 @@ "LintDeprecatedFunction": "The deprecated function \"{actual}\" is used inside the port \"{package_name}\". Use the function \"{expected}\" instead.", "_LintDeprecatedFunction.comment": "{actual} is the currently used deprecated function, {expected} is the function that should be used An example of {package_name} is zlib.", "LintDeprecatedLicenseExpressionWithReplacement": "The port \"{package_name}\" uses the deprecated license expression \"{actual}\". You shoud use the non deprecated version \"{new_value}\".", - "_LintDeprecatedLicenseExpressionWithReplacement.comment": "{actual} is the currently used license and {new_value} is the license expression that should be used An example of {package_name} is zlib.", - "LintDeprecatedLicenseExpressionWithoutReplacement": "The port \"{package_name}\" uses the deprecated license expression \"{actual}\".", - "_LintDeprecatedLicenseExpressionWithoutReplacement.comment": "{actual} is the currently used license An example of {package_name} is zlib.", + "_LintDeprecatedLicenseExpressionWithReplacement.comment": "{actual} is the currently used license expression and {new_value} is the license expression that should be used An example of {package_name} is zlib.", + "LintDeprecatedLicenseExpressionWithoutReplacement": "The port \"{package_name}\" uses the deprecated license expression \"{actual}\". Use license expression including main license, \"WITH\" operator, and identifier: \"{new_value}\"", + "_LintDeprecatedLicenseExpressionWithoutReplacement.comment": "{actual} is the currently used license, {new_value} is the suggested WITH expression An example of {package_name} is zlib.", "LintMissingLicenseExpression": "There is no license expression in port \"{package_name}\". You could use https://tools.spdx.org/app/check_license/ to determine the right license expression.", "_LintMissingLicenseExpression.comment": "An example of {package_name} is zlib.", "LintPortErrors": "The port \"{package_name}\" should be fixed. See warning(s) above.", diff --git a/src/vcpkg-test/portlint.cpp b/src/vcpkg-test/portlint.cpp new file mode 100644 index 0000000000..27d5b39c2a --- /dev/null +++ b/src/vcpkg-test/portlint.cpp @@ -0,0 +1,21 @@ +#include + +#include + +using namespace vcpkg; +using namespace vcpkg::Lint; + +TEST_CASE ("Lint::get_recommended_license_expression", "[portlint]") +{ + REQUIRE(get_recommended_license_expression("GPL-1.0") == "GPL-1.0-only"); + REQUIRE(get_recommended_license_expression("GPL-1.0 OR test") == "GPL-1.0-only OR test"); + REQUIRE(get_recommended_license_expression("GPL-1.0 OR GPL-1.0") == "GPL-1.0-only OR GPL-1.0-only"); + REQUIRE(get_recommended_license_expression("GPL-1.0+ OR GPL-1.0") == "GPL-1.0-or-later OR GPL-1.0-only"); +} + +TEST_CASE ("Lint::get_recommended_version_scheme", "[portlint]") +{ + REQUIRE(get_recommended_version_scheme("1.0.0", VersionScheme::String) == VersionScheme::Relaxed); + REQUIRE(get_recommended_version_scheme("2020-01-01", VersionScheme::String) == VersionScheme::Date); + REQUIRE(get_recommended_version_scheme("latest", VersionScheme::String) == VersionScheme::String); +} diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index 9e6348aec6..a1d33fe6fe 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -14,20 +14,19 @@ namespace vcpkg::Lint constexpr StringLiteral VERSION_DATE = "version-date"; constexpr StringLiteral VERSION_STRING = "version-string"; + VersionScheme get_recommended_version_scheme(StringView raw_version, VersionScheme original_scheme) + { + if (DateVersion::try_parse(raw_version)) return VersionScheme::Date; + if (DotVersion::try_parse_relaxed(raw_version)) return VersionScheme::Relaxed; + return original_scheme; + } + Status check_used_version_scheme(SourceControlFile& scf, Fix fix) { auto scheme = scf.core_paragraph->version_scheme; - auto new_scheme = scheme; if (scheme == VersionScheme::String) { - if (DateVersion::try_parse(scf.core_paragraph->raw_version)) - { - new_scheme = VersionScheme::Date; - } - else if (DotVersion::try_parse_relaxed(scf.core_paragraph->raw_version)) - { - new_scheme = VersionScheme::Relaxed; - } + auto new_scheme = get_recommended_version_scheme(scf.core_paragraph->raw_version, scheme); if (scheme != new_scheme) { if (fix == Fix::YES) @@ -46,19 +45,32 @@ namespace vcpkg::Lint return Status::Ok; } - Status check_license_expression(SourceControlFile& scf, Fix fix) + namespace { - if (!scf.core_paragraph->license.has_value()) + std::string::size_type find_license(const std::string& license_expression, + StringView license_identifier, + std::string::size_type offset = 0) { - msg::println_warning(msgLintMissingLicenseExpression, msg::package_name = scf.core_paragraph->name); - return Status::Problem; + std::string::size_type index; + while ((index = license_expression.find(license_identifier.data(), offset, license_identifier.size())) != + std::string::npos) + { + const auto end_index = index + license_identifier.size(); + if (end_index >= license_expression.size() || license_expression[end_index] == ' ') + { + return index; + } + offset = end_index; + } + return std::string::npos; } + } + + std::string get_recommended_license_expression(std::string original_license) + { static constexpr std::pair deprecated_licenses[] = { {"AGPL-1.0", "AGPL-1.0-only"}, {"AGPL-3.0", "AGPL-3.0-only"}, - {"eCos-2.0", - "DEPRECATED: Use license expression including main license, \"WITH\" operator, and identifier: " - "eCos-exception-2.0"}, {"GFDL-1.1", "GFDL-1.1-or-later"}, {"GFDL-1.2", "GFDL-1.2-or-later"}, {"GFDL-1.3", "GFDL-1.3-or-later"}, @@ -68,12 +80,6 @@ namespace vcpkg::Lint {"GPL-2.0+", "GPL-2.0-or-later"}, {"GPL-2.0-with-autoconf-exception", "GPL-2.0-only WITH Autoconf-exception-2.0"}, {"GPL-2.0-with-bison-exception", "GPL-2.0-or-later WITH Bison-exception-2.2"}, - {"GPL-2.0-with-classpath-exception", - "DEPRECATED: Use license expression including main license, \"WITH\" operator, and identifier: " - "Classpath-exception-2.0"}, - {"GPL-2.0-with-font-exception", - "DEPRECATED: Use license expression including main license, \"WITH\" operator, and identifier: " - "Font-exception-2.0"}, {"GPL-2.0-with-GCC-exception", "GPL-2.0-or-later WITH GCC-exception-2.0"}, {"GPL-3.0", "GPL-3.0-only"}, {"GPL-3.0+", "GPL-3.0-or-later"}, @@ -85,51 +91,61 @@ namespace vcpkg::Lint {"LGPL-2.1+", "LGPL-2.1-or-later"}, {"LGPL-3.0", "LGPL-3.0-only"}, {"LGPL-3.0+", "LGPL-3.0-or-later"}, - {"Nunit", - "DEPRECATED: This license is based on the MIT license, except with an \"acknowledgement\" clause. That " - "clause makes it functionally equivalent to MIT with advertising (Free, but GPLv2/v3 incompatible)"}, - {"StandardML-NJ", "SMLNJ"}, - {"wxWindows", - "DEPRECATED: Use license expression including main license, \"WITH\" operator, and identifier: " - "WxWindows-exception-3.1"}}; - Status status = Status::Ok; - auto& license = scf.core_paragraph->license.value_or_exit(VCPKG_LINE_INFO); + {"StandardML-NJ", "SMLNJ"}}; for (const auto dep_license : deprecated_licenses) { - const auto index = license.find(dep_license.first.c_str()); - if (index == std::string::npos) + std::string::size_type index = 0; + while ((index = find_license(original_license, dep_license.first, index)) != std::string::npos) { - continue; + original_license.replace(index, dep_license.first.size(), dep_license.second.c_str()); } - const auto end_index = index + dep_license.first.size(); - if (end_index < license.size() && license[end_index] != ' ') + } + return original_license; + } + + Status check_license_expression(SourceControlFile& scf, Fix fix) + { + if (!scf.core_paragraph->license.has_value()) + { + msg::println_warning(msgLintMissingLicenseExpression, msg::package_name = scf.core_paragraph->name); + return Status::Problem; + } + + Status status = Status::Ok; + auto& license = scf.core_paragraph->license.value_or_exit(VCPKG_LINE_INFO); + auto new_expr = get_recommended_license_expression(license); + if (new_expr != license) + { + if (fix == Fix::YES) { - continue; + license = new_expr; } - if (Strings::starts_with(dep_license.second, "DEPRECATED")) + else { - msg::println_warning(msg::format(msgLintDeprecatedLicenseExpressionWithoutReplacement, - msg::package_name = scf.core_paragraph->name, - msg::actual = dep_license.first) - .append_raw(dep_license.second.substr(StringLiteral("DEPRECATED:").size()))); - + msg::println_warning(msgLintDeprecatedLicenseExpressionWithReplacement, + msg::package_name = scf.core_paragraph->name, + msg::actual = license, + msg::new_value = new_expr); status |= Status::Problem; } - else if (fix == Fix::NO) + } + static constexpr std::pair deprecated_licenses_WITH[] = { + {"eCos-2.0", "eCos-exception-2.0"}, + {"GPL-2.0-with-classpath-exception", "Classpath-exception-2.0"}, + {"GPL-2.0-with-font-exception", "Font-exception-2.0"}, + {"wxWindows", "WxWindows-exception-3.1"}, + }; + for (const auto dep_license : deprecated_licenses_WITH) + { + if (find_license(license, dep_license.first) != std::string::npos) { - msg::println_warning(msgLintDeprecatedLicenseExpressionWithReplacement, + msg::println_warning(msgLintDeprecatedLicenseExpressionWithoutReplacement, msg::package_name = scf.core_paragraph->name, msg::actual = dep_license.first, msg::new_value = dep_license.second); status |= Status::Problem; } - else - { - license.replace(index, dep_license.first.size(), dep_license.second.c_str()); - status |= Status::Fixed; - } } - return status; } From 04ba4473fe867380d08fdeb4e084687cf423652f Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Sat, 26 Nov 2022 20:54:16 +0100 Subject: [PATCH 12/28] Add helpers to MessageSink --- include/vcpkg/base/messages.h | 26 ++++++++++++++++++++++++++ src/vcpkg/base/messages.cpp | 14 ++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/vcpkg/base/messages.h b/include/vcpkg/base/messages.h index 7d9914cfad..5c3da5132f 100644 --- a/include/vcpkg/base/messages.h +++ b/include/vcpkg/base/messages.h @@ -438,6 +438,32 @@ namespace vcpkg this->print(c, msg::format(m, args...).append_raw('\n')); } + void println_warning(const LocalizedString& s); + template + typename Message::is_message_type println_warning(Message m, Ts... args) + { + println_warning(format(m, args...)); + } + + void println_error(const LocalizedString& s); + template + typename Message::is_message_type println_error(Message m, Ts... args) + { + println_error(format(m, args...)); + } + + template + LocalizedString format_warning(Message m, Ts... args) + { + return format(msg::msgWarningMessage).append(m, args...); + } + + template + LocalizedString format_error(Message m, Ts... args) + { + return format(msg::msgErrorMessage).append(m, args...); + } + MessageSink(const MessageSink&) = delete; MessageSink& operator=(const MessageSink&) = delete; diff --git a/src/vcpkg/base/messages.cpp b/src/vcpkg/base/messages.cpp index 82d88b0ebd..feb6268a6c 100644 --- a/src/vcpkg/base/messages.cpp +++ b/src/vcpkg/base/messages.cpp @@ -373,6 +373,20 @@ namespace vcpkg::msg } } +namespace vcpkg +{ + + void MessageSink::println_warning(const LocalizedString& s) + { + print(Color::warning, format(msg::msgWarningMessage).append(s).append_raw('\n')); + } + + void MessageSink::println_error(const LocalizedString& s) + { + print(Color::error, format(msg::msgErrorMessage).append(s).append_raw('\n')); + } +} + namespace { struct NullMessageSink : MessageSink From ea500f501831826d86f8356afce86c37766ec044 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Sat, 26 Nov 2022 20:54:41 +0100 Subject: [PATCH 13/28] Apply code review and add tests --- include/vcpkg/portlint.h | 14 ++++ src/vcpkg-test/portlint.cpp | 108 +++++++++++++++++++++++++++++++ src/vcpkg/portlint.cpp | 125 ++++++++++++++++++++++-------------- 3 files changed, 199 insertions(+), 48 deletions(-) diff --git a/include/vcpkg/portlint.h b/include/vcpkg/portlint.h index 20e548d0c5..cc8ba16613 100644 --- a/include/vcpkg/portlint.h +++ b/include/vcpkg/portlint.h @@ -9,6 +9,8 @@ #include +#include + namespace vcpkg::Lint { enum class Status : int @@ -35,5 +37,17 @@ namespace vcpkg::Lint Status check_license_expression(SourceControlFile& scf, Fix fix); + struct FixedPortfile + { + Status status; + std::string new_portfile_content; // empty if Fix::NO + std::set added_host_deps; // host-dependencies that need to be added, empty if Fix::NO + }; + + FixedPortfile check_portfile_deprecated_functions(std::string&& portfile_content, + StringView origin, + Fix fix, + MessageSink& warningsSink); + Status check_portfile_deprecated_functions(Filesystem& fs, SourceControlFileAndLocation& scf, Fix fix); } diff --git a/src/vcpkg-test/portlint.cpp b/src/vcpkg-test/portlint.cpp index 27d5b39c2a..4452484e89 100644 --- a/src/vcpkg-test/portlint.cpp +++ b/src/vcpkg-test/portlint.cpp @@ -19,3 +19,111 @@ TEST_CASE ("Lint::get_recommended_version_scheme", "[portlint]") REQUIRE(get_recommended_version_scheme("2020-01-01", VersionScheme::String) == VersionScheme::Date); REQUIRE(get_recommended_version_scheme("latest", VersionScheme::String) == VersionScheme::String); } + +namespace +{ + struct CountingMessageSink : MessageSink + { + int counter = 0; + void print(Color, StringView) override { ++counter; } + }; + + void check_replacement(StringView old_content, const std::string& new_content, StringView new_host_dependency) + { + CountingMessageSink msg_sink; + auto result = check_portfile_deprecated_functions(old_content.to_string(), "test", Fix::YES, msg_sink); + REQUIRE(result.status == Status::Fixed); + REQUIRE(msg_sink.counter == 0); + REQUIRE(result.new_portfile_content == new_content); + REQUIRE(result.added_host_deps.size() == 1); + REQUIRE(*result.added_host_deps.begin() == new_host_dependency); + + result = check_portfile_deprecated_functions(old_content.to_string(), "test", Fix::NO, msg_sink); + REQUIRE(result.status == Status::Problem); + REQUIRE(msg_sink.counter == 1); + REQUIRE(result.new_portfile_content.empty()); + REQUIRE(result.added_host_deps.empty()); + } +} + +TEST_CASE ("Lint::check_portfile_deprecated_functions", "[portlint]") +{ + SECTION ("vcpkg_build_msbuild") + { + auto content = R"-( +vcpkg_build_msbuild( + PROJECT_PATH "${SOURCE_PATH}/msvc/unicorn.sln" + PLATFORM "${UNICORN_PLATFORM}" +) +)-"; + CountingMessageSink msg_sink; + auto result = check_portfile_deprecated_functions(content, "test", Fix::YES, msg_sink); + REQUIRE(result.status == Status::Problem); + REQUIRE(msg_sink.counter == 1); + } + + SECTION ("vcpkg_configure_cmake -> vcpkg_cmake_configure") + { + auto content = R"-( +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} + PREFER_NINJA + OPTIONS_DEBUG -DDISABLE_INSTALL_HEADERS=ON -DDISABLE_INSTALL_TOOLS=ON +) +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH} + OPTIONS_DEBUG -DDISABLE_INSTALL_HEADERS=ON -DDISABLE_INSTALL_TOOLS=ON +) +)-"; + auto new_content = R"-( +vcpkg_cmake_configure( + SOURCE_PATH ${SOURCE_PATH} + OPTIONS_DEBUG -DDISABLE_INSTALL_HEADERS=ON -DDISABLE_INSTALL_TOOLS=ON +) +vcpkg_cmake_configure( + SOURCE_PATH ${SOURCE_PATH} + OPTIONS_DEBUG -DDISABLE_INSTALL_HEADERS=ON -DDISABLE_INSTALL_TOOLS=ON +) +)-"; + check_replacement(content, new_content, "vcpkg-cmake"); + } + + SECTION ("vcpkg_build_cmake -> vcpkg_cmake_build") + { + auto content = R"-( +vcpkg_build_cmake(TARGET test) +)-"; + auto new_content = R"-( +vcpkg_cmake_build(TARGET test) +)-"; + check_replacement(content, new_content, "vcpkg-cmake"); + } + + SECTION ("vcpkg_install_cmake -> vcpkg_cmake_install") + { + auto content = R"-( +vcpkg_install_cmake() +)-"; + auto new_content = R"-( +vcpkg_cmake_install() +)-"; + check_replacement(content, new_content, "vcpkg-cmake"); + } + + SECTION ("vcpkg_fixup_cmake_targets -> vcpkg_cmake_config_fixup") + { + auto content = R"-( +vcpkg_fixup_cmake_targets(CONFIG_PATH lib/cmake/${PORT}) +vcpkg_fixup_cmake_targets(TARGET_PATH share/${PORT}) +vcpkg_fixup_cmake_targets(CONFIG_PATH share/unofficial-cfitsio TARGET_PATH share/unofficial-cfitsio) +vcpkg_fixup_cmake_targets(CONFIG_PATH cmake TARGET_PATH share/async++) +)-"; + auto new_content = R"-( +vcpkg_cmake_config_fixup(CONFIG_PATH lib/cmake/${PORT}) +vcpkg_cmake_config_fixup() +vcpkg_cmake_config_fixup(PACKAGE_NAME unofficial-cfitsio) +vcpkg_cmake_config_fixup(CONFIG_PATH cmake PACKAGE_NAME async++) +)-"; + check_replacement(content, new_content, "vcpkg-cmake-config"); + } +} diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index a1d33fe6fe..4a5af3b5a2 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -151,124 +151,152 @@ namespace vcpkg::Lint Status check_portfile_deprecated_functions(Filesystem& fs, SourceControlFileAndLocation& scf, Fix fix) { + auto contents = fs.read_contents(scf.source_location / "portfile.cmake", VCPKG_LINE_INFO); + auto lint_result = check_portfile_deprecated_functions( + std::move(contents), scf.source_control_file->core_paragraph->name, fix, stdout_sink); + + if (lint_result.status == Status::Fixed || lint_result.status == Status::PartiallyFixed) + { + fs.write_contents( + scf.source_location / "portfile.cmake", lint_result.new_portfile_content, VCPKG_LINE_INFO); + + for (StringView name : lint_result.added_host_deps) + { + if (!Util::any_of(scf.source_control_file->core_paragraph->dependencies, + [&](const Dependency& d) { return d.name == name; })) + { + scf.source_control_file->core_paragraph->dependencies.push_back( + Dependency{name.to_string(), {}, {}, {}, true}); + } + } + } + return lint_result.status; + } + + FixedPortfile check_portfile_deprecated_functions(std::string&& portfile_content, + StringView origin, + Fix fix, + MessageSink& warningsSink) + { + FixedPortfile fixedPortfile; Status status = Status::Ok; - auto content = fs.read_contents(scf.source_location / "portfile.cmake", VCPKG_LINE_INFO); const auto handle_warning = [&](StringLiteral deprecated, StringLiteral new_func, bool can_fix = true) { if (fix == Fix::NO || !can_fix) { status |= Status::Problem; - msg::println_warning(msgLintDeprecatedFunction, - msg::package_name = scf.source_control_file->core_paragraph->name, - msg::actual = deprecated, - msg::expected = new_func); + warningsSink.println_warning(msgLintDeprecatedFunction, + msg::package_name = origin, + msg::actual = deprecated, + msg::expected = new_func); } else { status = Status::Fixed; } }; - const auto add_host_dep = [&](std::string name) { - if (!Util::any_of(scf.source_control_file->core_paragraph->dependencies, - [&](const Dependency& d) { return d.name == name; })) - { - scf.source_control_file->core_paragraph->dependencies.push_back(Dependency{name, {}, {}, {}, true}); - } - }; - if (Strings::contains(content, "vcpkg_build_msbuild")) + if (Strings::contains(portfile_content, "vcpkg_build_msbuild")) { handle_warning("vcpkg_build_msbuild", "vcpkg_install_msbuild", false); } std::string::size_type index = 0; - while ((index = content.find("vcpkg_configure_cmake", index)) != std::string::npos) + while ((index = portfile_content.find("vcpkg_configure_cmake", index)) != std::string::npos) { handle_warning("vcpkg_configure_cmake", "vcpkg_cmake_configure"); if (fix == Fix::NO) { break; } - const auto end = content.find(')', index); - const auto ninja = content.find("PREFER_NINJA", index); + const auto end = portfile_content.find(')', index); + const auto ninja = portfile_content.find("PREFER_NINJA", index); if (ninja != std::string::npos && ninja < end) { - const auto start = content.find_last_not_of(" \n\t\r", ninja - 1) + 1; - content.erase(start, (ninja - start) + StringLiteral("PREFER_NINJA").size()); + const auto start = portfile_content.find_last_not_of(" \n\t\r", ninja - 1) + 1; + portfile_content.erase(start, (ninja - start) + StringLiteral("PREFER_NINJA").size()); } - content.replace(index, StringLiteral("vcpkg_configure_cmake").size(), "vcpkg_cmake_configure"); - add_host_dep("vcpkg-cmake"); + portfile_content.replace(index, StringLiteral("vcpkg_configure_cmake").size(), "vcpkg_cmake_configure"); + fixedPortfile.added_host_deps.insert("vcpkg-cmake"); } - if (Strings::contains(content, "vcpkg_build_cmake")) + if (Strings::contains(portfile_content, "vcpkg_build_cmake")) { handle_warning("vcpkg_build_cmake", "vcpkg_cmake_build"); - Strings::inplace_replace_all(content, "vcpkg_build_cmake", "vcpkg_cmake_build"); - add_host_dep("vcpkg-cmake"); + if (fix == Fix::YES) + { + Strings::inplace_replace_all(portfile_content, "vcpkg_build_cmake", "vcpkg_cmake_build"); + fixedPortfile.added_host_deps.insert("vcpkg-cmake"); + } } - if (Strings::contains(content, "vcpkg_install_cmake")) + if (Strings::contains(portfile_content, "vcpkg_install_cmake")) { handle_warning("vcpkg_install_cmake", "vcpkg_cmake_install"); - Strings::inplace_replace_all(content, "vcpkg_install_cmake", "vcpkg_cmake_install"); + if (fix == Fix::YES) + { + Strings::inplace_replace_all(portfile_content, "vcpkg_install_cmake", "vcpkg_cmake_install"); + fixedPortfile.added_host_deps.insert("vcpkg-cmake"); + } } index = 0; - while ((index = content.find("vcpkg_fixup_cmake_targets", index)) != std::string::npos) + while ((index = portfile_content.find("vcpkg_fixup_cmake_targets", index)) != std::string::npos) { handle_warning("vcpkg_fixup_cmake_targets", "vcpkg_fixup_cmake_targets"); if (fix == Fix::NO) { break; } - const auto end = content.find(')', index); - const auto target = content.find("TARGET_PATH"); + const auto end = portfile_content.find(')', index); + const auto target = portfile_content.find("TARGET_PATH"); if (target != std::string::npos && target < end) { auto start_param = target + StringLiteral("TARGET_PATH").size(); - start_param = content.find_first_not_of(" \n\t)", start_param); - const auto end_param = content.find_first_of(" \n\t)", start_param); + start_param = portfile_content.find_first_not_of(" \n\t)", start_param); + const auto end_param = portfile_content.find_first_of(" \n\t)", start_param); if (end_param != std::string::npos && end_param <= end) { - const auto original_param = content.substr(start_param, end_param - start_param); + const auto original_param = portfile_content.substr(start_param, end_param - start_param); auto param = StringView(original_param); if (Strings::starts_with(param, "share/")) { param = param.substr(StringLiteral("share/").size()); } - if (param == "${PORT}" || - Strings::case_insensitive_ascii_equals(param, scf.source_control_file->core_paragraph->name)) + if (param == "${PORT}" || Strings::case_insensitive_ascii_equals(param, origin)) { - content.erase(target, end_param - target); + portfile_content.erase(target, end_param - target); } else { - content.replace(target, (end_param - target) - param.size(), "PACKAGE_NAME "); + portfile_content.replace(target, (end_param - target) - param.size(), "PACKAGE_NAME "); } // remove the CONFIG_PATH part if it uses the same param - const auto start_config_path = content.find("CONFIG_PATH", index); + const auto start_config_path = portfile_content.find("CONFIG_PATH", index); if (start_config_path != std::string::npos && start_config_path < end) { start_param = start_config_path + StringLiteral("CONFIG_PATH").size(); - start_param = content.find_first_not_of(" \n\t)", start_param); - const auto end_config_param = content.find_first_of(" \n\t)", start_param); + start_param = portfile_content.find_first_not_of(" \n\t)", start_param); + const auto end_config_param = portfile_content.find_first_of(" \n\t)", start_param); const auto config_param = - StringView(content).substr(start_param, end_config_param - start_param); + StringView(portfile_content).substr(start_param, end_config_param - start_param); if (config_param == original_param) { - const auto start_next = content.find_first_not_of(' ', end_config_param); - content.erase(start_config_path, start_next - start_config_path); + const auto start_next = portfile_content.find_first_not_of(' ', end_config_param); + portfile_content.erase(start_config_path, start_next - start_config_path); } } } else { - const auto start = content.find_last_not_of(" \n\t\r", target - 1) + 1; - content.erase(start, StringLiteral("TARGET_PATH").size() + (target - start)); + const auto start = portfile_content.find_last_not_of(" \n\t\r", target - 1) + 1; + portfile_content.erase(start, StringLiteral("TARGET_PATH").size() + (target - start)); } } - content.replace(index, StringLiteral("vcpkg_fixup_cmake_targets").size(), "vcpkg_cmake_config_fixup"); - add_host_dep("vcpkg-cmake-config"); + portfile_content.replace( + index, StringLiteral("vcpkg_fixup_cmake_targets").size(), "vcpkg_cmake_config_fixup"); + fixedPortfile.added_host_deps.insert("vcpkg-cmake-config"); } - if (status == Status::Fixed || status == Status::PartiallyFixed) + fixedPortfile.status = status; + if (fix == Fix::YES) { - fs.write_contents(scf.source_location / "portfile.cmake", content, VCPKG_LINE_INFO); + fixedPortfile.new_portfile_content = std::move(portfile_content); } - return status; + return fixedPortfile; } Status& operator|=(Status& self, Status s) @@ -277,4 +305,5 @@ namespace vcpkg::Lint static_cast>(s)); return self; } + } From 8f56f8e111fe07392d1aebc476e2c3629bf1e08f Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Sun, 27 Nov 2022 04:21:35 +0100 Subject: [PATCH 14/28] Replace usages of vcpkg_extract_source_archive_ex --- src/vcpkg-test/portlint.cpp | 52 +++++++++++++++++++++++++++++++-- src/vcpkg/portlint.cpp | 57 +++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/src/vcpkg-test/portlint.cpp b/src/vcpkg-test/portlint.cpp index 4452484e89..7864905b92 100644 --- a/src/vcpkg-test/portlint.cpp +++ b/src/vcpkg-test/portlint.cpp @@ -35,8 +35,15 @@ namespace REQUIRE(result.status == Status::Fixed); REQUIRE(msg_sink.counter == 0); REQUIRE(result.new_portfile_content == new_content); - REQUIRE(result.added_host_deps.size() == 1); - REQUIRE(*result.added_host_deps.begin() == new_host_dependency); + if (new_host_dependency.empty()) + { + REQUIRE(result.added_host_deps.empty()); + } + else + { + REQUIRE(result.added_host_deps.size() == 1); + REQUIRE(*result.added_host_deps.begin() == new_host_dependency); + } result = check_portfile_deprecated_functions(old_content.to_string(), "test", Fix::NO, msg_sink); REQUIRE(result.status == Status::Problem); @@ -126,4 +133,45 @@ vcpkg_cmake_config_fixup(CONFIG_PATH cmake PACKAGE_NAME async++) )-"; check_replacement(content, new_content, "vcpkg-cmake-config"); } + + SECTION ("vcpkg_extract_source_archive_ex -> vcpkg_extract_source_archive") + { + std::string content = R"-( +vcpkg_extract_source_archive_ex( + OUT_SOURCE_PATH SOURCE_PATH + ARCHIVE ${ARCHIVE} + PATCHES + remove_stdint_headers.patch + no-pragma-warning.patch +) +vcpkg_extract_source_archive_ex( + ARCHIVE ${ARCHIVE} + OUT_SOURCE_PATH SOURCE_PATH + PATCHES + remove_stdint_headers.patch + no-pragma-warning.patch +) +vcpkg_extract_source_archive_ex(OUT_SOURCE_PATH SOURCE_PATH ARCHIVE ${ARCHIVE}) +)-"; + std::string new_content = R"-( +vcpkg_extract_source_archive( + SOURCE_PATH + ARCHIVE ${ARCHIVE} + PATCHES + remove_stdint_headers.patch + no-pragma-warning.patch +) +vcpkg_extract_source_archive( + SOURCE_PATH + ARCHIVE ${ARCHIVE} + PATCHES + remove_stdint_headers.patch + no-pragma-warning.patch +) +vcpkg_extract_source_archive(SOURCE_PATH ARCHIVE ${ARCHIVE}) +)-"; + check_replacement(content, new_content, ""); + check_replacement( + Strings::replace_all(content, "\n", "\r\n"), Strings::replace_all(new_content, "\n", "\r\n"), ""); + } } diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index 4a5af3b5a2..dc798d8254 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -5,6 +5,7 @@ #include #include +#include "vcpkg/base/system.print.h" #include "vcpkg/base/util.h" namespace vcpkg::Lint @@ -291,6 +292,62 @@ namespace vcpkg::Lint index, StringLiteral("vcpkg_fixup_cmake_targets").size(), "vcpkg_cmake_config_fixup"); fixedPortfile.added_host_deps.insert("vcpkg-cmake-config"); } + index = 0; + while ((index = portfile_content.find("vcpkg_extract_source_archive_ex", index)) != std::string::npos) + { + handle_warning("vcpkg_extract_source_archive_ex", "vcpkg_extract_source_archive"); + if (fix == Fix::NO) + { + break; + } + const auto end = portfile_content.find(')', index); + const auto target = portfile_content.find("OUT_SOURCE_PATH"); + if (target != std::string::npos && target < end) + { + const auto before_out_source_path = portfile_content.find_last_not_of(' ', target - 1); + auto start_param = target + StringLiteral("OUT_SOURCE_PATH").size(); + start_param = portfile_content.find_first_not_of(" \n\r\t)", start_param); + const auto end_param = portfile_content.find_first_of(" \n\r\t)", start_param); + if (end_param != std::string::npos && end_param <= end) + { + const auto out_source_path_param = portfile_content.substr(start_param, end_param - start_param); + const auto after_param = portfile_content.find_first_not_of(' ', end_param); + auto erase_lenth = after_param - before_out_source_path; + bool was_crlf = false; + if (portfile_content[after_param] != '\n' && portfile_content[after_param] != '\r') + { + erase_lenth -= 1; // if OUT_SOURCE_PATH is not on its own line, don't remove new line character + } + if (portfile_content[after_param] == '\r') + { + erase_lenth += 1; // \r\n is used as line ending + was_crlf = true; + } + // remove ' OUT_SOURCE_PATH FOOBAR ' line + portfile_content.erase(before_out_source_path + 1, erase_lenth); + // insert 'FOOBAR' or // '\n FOOBAR' after '(' + auto open_bracket = portfile_content.find('(', index); + if (open_bracket != std::string::npos && open_bracket < end) + { + char c = portfile_content[before_out_source_path]; + if (c == '\n') + { + // if the OUT_SOURCE_PATH was in a new line, insert the param in a new line + portfile_content.insert(open_bracket + 1, + (was_crlf ? "\r\n" : "\n") + + std::string(target - before_out_source_path - 1, ' ') + + out_source_path_param); + } + else + { + portfile_content.insert(open_bracket + 1, out_source_path_param + ' '); + } + } + } + } + portfile_content.replace( + index, StringLiteral("vcpkg_extract_source_archive_ex").size(), "vcpkg_extract_source_archive"); + } fixedPortfile.status = status; if (fix == Fix::YES) { From 9e85bdd7644f760e387d0d9e9a49fbd985b510bf Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Sun, 27 Nov 2022 05:34:14 +0100 Subject: [PATCH 15/28] format diff --- locales/messages.en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/messages.en.json b/locales/messages.en.json index e78910c237..f50fa9c8a7 100644 --- a/locales/messages.en.json +++ b/locales/messages.en.json @@ -394,7 +394,7 @@ "LicenseExpressionUnknownLicense": "Unknown license identifier '{value}'. Known values are listed at https://spdx.org/licenses/", "LintDeprecatedFunction": "The deprecated function \"{actual}\" is used inside the port \"{package_name}\". Use the function \"{expected}\" instead.", "LintDeprecatedLicenseExpressionWithReplacement": "The port \"{package_name}\" uses the deprecated license expression \"{actual}\". You shoud use the non deprecated version \"{new_value}\".", - "LintDeprecatedLicenseExpressionWithoutReplacement": "The port \"{package_name}\" uses the deprecated license expression \"{actual}\".", + "LintDeprecatedLicenseExpressionWithoutReplacement": "The port \"{package_name}\" uses the deprecated license expression \"{actual}\". Use license expression including main license, \"WITH\" operator, and identifier: \"{new_value}\"", "LintMissingLicenseExpression": "There is no license expression in port \"{package_name}\". You could use https://tools.spdx.org/app/check_license/ to determine the right license expression.", "LintPortErrors": "The port \"{package_name}\" should be fixed. See warning(s) above.", "LintPortErrorsFixed": "Problems in the port \"{package_name}\" have been fixed.", From a8b28ea8d51325e60d07637fb5a20b26779962a5 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Tue, 29 Nov 2022 13:08:21 +0100 Subject: [PATCH 16/28] Also replace REF with SOURCE_BASE in vcpkg_extract_source_archive --- src/vcpkg-test/portlint.cpp | 6 ++++++ src/vcpkg/portlint.cpp | 20 +++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/vcpkg-test/portlint.cpp b/src/vcpkg-test/portlint.cpp index 7864905b92..3eb94e6288 100644 --- a/src/vcpkg-test/portlint.cpp +++ b/src/vcpkg-test/portlint.cpp @@ -140,6 +140,7 @@ vcpkg_cmake_config_fixup(CONFIG_PATH cmake PACKAGE_NAME async++) vcpkg_extract_source_archive_ex( OUT_SOURCE_PATH SOURCE_PATH ARCHIVE ${ARCHIVE} + REF lib1.0.0 PATCHES remove_stdint_headers.patch no-pragma-warning.patch @@ -147,6 +148,8 @@ vcpkg_extract_source_archive_ex( vcpkg_extract_source_archive_ex( ARCHIVE ${ARCHIVE} OUT_SOURCE_PATH SOURCE_PATH +REF +lib1.0.0 PATCHES remove_stdint_headers.patch no-pragma-warning.patch @@ -157,6 +160,7 @@ vcpkg_extract_source_archive_ex(OUT_SOURCE_PATH SOURCE_PATH ARCHIVE ${ARCHIVE}) vcpkg_extract_source_archive( SOURCE_PATH ARCHIVE ${ARCHIVE} + SOURCE_BASE lib1.0.0 PATCHES remove_stdint_headers.patch no-pragma-warning.patch @@ -164,6 +168,8 @@ vcpkg_extract_source_archive( vcpkg_extract_source_archive( SOURCE_PATH ARCHIVE ${ARCHIVE} +SOURCE_BASE +lib1.0.0 PATCHES remove_stdint_headers.patch no-pragma-warning.patch diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index dc798d8254..1d4e1860ea 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -325,9 +325,27 @@ namespace vcpkg::Lint } // remove ' OUT_SOURCE_PATH FOOBAR ' line portfile_content.erase(before_out_source_path + 1, erase_lenth); + + // Replace 'REF' by 'SOURCE_BASE' + auto ref_index = index; + while ((ref_index = portfile_content.find("REF", ref_index)) != std::string::npos) + { + if (ref_index > end) break; + if (!isspace(portfile_content[ref_index - 1]) || + !isspace(portfile_content[ref_index + StringLiteral("REF").size()])) + { // 'REF' must be not included in another word + ref_index += 3; + } + else + { + portfile_content.replace(ref_index, StringLiteral("REF").size(), "SOURCE_BASE"); + break; + } + } + // insert 'FOOBAR' or // '\n FOOBAR' after '(' auto open_bracket = portfile_content.find('(', index); - if (open_bracket != std::string::npos && open_bracket < end) + if (open_bracket != std::string::npos && open_bracket < target) { char c = portfile_content[before_out_source_path]; if (c == '\n') From 7f2c55af4194a760e4f52e8056c84e16ff9c7267 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Tue, 29 Nov 2022 13:19:18 +0100 Subject: [PATCH 17/28] Fix Bug --- src/vcpkg-test/portlint.cpp | 6 ++++++ src/vcpkg/portlint.cpp | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vcpkg-test/portlint.cpp b/src/vcpkg-test/portlint.cpp index 3eb94e6288..cfa14bac1b 100644 --- a/src/vcpkg-test/portlint.cpp +++ b/src/vcpkg-test/portlint.cpp @@ -137,6 +137,9 @@ vcpkg_cmake_config_fixup(CONFIG_PATH cmake PACKAGE_NAME async++) SECTION ("vcpkg_extract_source_archive_ex -> vcpkg_extract_source_archive") { std::string content = R"-( +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH +) vcpkg_extract_source_archive_ex( OUT_SOURCE_PATH SOURCE_PATH ARCHIVE ${ARCHIVE} @@ -157,6 +160,9 @@ lib1.0.0 vcpkg_extract_source_archive_ex(OUT_SOURCE_PATH SOURCE_PATH ARCHIVE ${ARCHIVE}) )-"; std::string new_content = R"-( +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH +) vcpkg_extract_source_archive( SOURCE_PATH ARCHIVE ${ARCHIVE} diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index 1d4e1860ea..3ac874a0dc 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -301,7 +301,7 @@ namespace vcpkg::Lint break; } const auto end = portfile_content.find(')', index); - const auto target = portfile_content.find("OUT_SOURCE_PATH"); + const auto target = portfile_content.find("OUT_SOURCE_PATH", index); if (target != std::string::npos && target < end) { const auto before_out_source_path = portfile_content.find_last_not_of(' ', target - 1); From d967f733d91093146483e05f86f5c0293dee0bf5 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Mon, 12 Dec 2022 14:38:06 +0100 Subject: [PATCH 18/28] Apply diff --- locales/messages.en.json | 182 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 2 deletions(-) diff --git a/locales/messages.en.json b/locales/messages.en.json index f50fa9c8a7..37bba0301f 100644 --- a/locales/messages.en.json +++ b/locales/messages.en.json @@ -58,6 +58,7 @@ "BaselineFileNoDefaultField": "The baseline file at commit {commit_sha} was invalid (no \"default\" field).", "BaselineMissingDefault": "The baseline.json from commit `\"{commit_sha}\"` in the repo {url} was invalid (did not contain a \"default\" field).", "BinarySourcesArg": "Add sources for binary caching. See 'vcpkg help binarycaching'.", + "BinaryWithInvalidArchitecture": "{path}\n Expected: {expected}, but was {actual}", "BothYesAndNoOptionSpecifiedError": "cannot specify both --no-{option} and --{option}.", "BuildAlreadyInstalled": "{spec} is already installed; please remove {spec} before attempting to build it.", "BuildDependenciesMissing": "The build command requires all dependencies to be already installed.\nThe following dependencies are missing:", @@ -82,6 +83,23 @@ "BuildingPackageFailed": "building {spec} failed with: {build_result}", "BuildingPackageFailedDueToMissingDeps": "due to the following missing dependencies:", "BuiltInTriplets": "vcpkg built-in triplets:", + "BuiltWithIncorrectArchitecture": "The following files were built for an incorrect architecture:", + "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", + "CISettingsOptHostExclude": "Comma separated list of ports to skip for the host triplet", + "CISettingsOptOutputHashes": "File to output all determined package hashes", + "CISettingsOptParentHashes": "File to read package hashes for a parent CI state, to reduce the set of changed packages", + "CISettingsOptSkippedCascadeCount": "Asserts that the number of --exclude and supports skips exactly equal this number", + "CISettingsOptXUnit": "File to output results in XUnit format (internal)", + "CISettingsVerifyGitTree": "Verify that each git tree object matches its declared version (this is very slow)", + "CISettingsVerifyVersion": "Print result for each port instead of just errors.", + "CISwitchOptAllowUnexpectedPassing": "Indicates that 'Passing, remove from fail list' results should not be emitted.", + "CISwitchOptDryRun": "Print out plan without execution", + "CISwitchOptRandomize": "Randomize the install order", + "CISwitchOptSkipFailures": "Indicates that ports marked `=fail` in ci.baseline.txt should be skipped.", + "CISwitchOptXUnitAll": "Report also unchanged ports to the XUnit output (internal)", "CMakeTargetsUsage": "{package_name} provides CMake targets:", "CMakeTargetsUsageHeuristicMessage": "# this is heuristically generated, and may not be correct", "CMakeToolChainFile": "CMake projects should use: \"-DCMAKE_TOOLCHAIN_FILE={path}\"", @@ -96,6 +114,86 @@ "CiBaselineUnexpectedPass": "PASSING, REMOVE FROM FAIL LIST: {spec} ({path}).", "ClearingContents": "Clearing contents of {path}", "CmakeTargetsExcluded": "note: {count} additional targets are not displayed.", + "CmdAddVersionOptAll": "Process versions for all ports.", + "CmdAddVersionOptOverwriteVersion": "Overwrite `git-tree` of an existing version.", + "CmdAddVersionOptSkipFormatChk": "Skips the formatting check of vcpkg.json files.", + "CmdAddVersionOptSkipLicenseChk": "Skips the license expression check.", + "CmdAddVersionOptSkipPortfileChk": "Skips the portfile.cmake check.", + "CmdAddVersionOptSkipVersionFormatChk": "Skips the version format check.", + "CmdAddVersionOptVerbose": "Print success messages instead of just errors.", + "CmdContactOptSurvey": "Launch default browser to the current vcpkg survey", + "CmdDependInfoOptDGML": "Creates graph on basis of dgml", + "CmdDependInfoOptDepth": "Show recursion depth in output", + "CmdDependInfoOptDot": "Creates graph on basis of dot", + "CmdDependInfoOptMaxRecurse": "Set max recursion depth, a value of -1 indicates no limit", + "CmdDependInfoOptSort": "Set sort order for the list of dependencies, accepted values are: lexicographical, topological (default), x-tree, reverse", + "CmdEditOptAll": "Open editor into the port as well as the port-specific buildtree subfolder", + "CmdEditOptBuildTrees": "Open editor into the port-specific buildtree subfolder", + "CmdEnvOptions": "Add installed {path} to {env_var}", + "CmdExportOpt7Zip": "Export to a 7zip (.7z) file", + "CmdExportOptChocolatey": "Export a Chocolatey package (experimental feature)", + "CmdExportOptDebug": "Enable prefab debug", + "CmdExportOptDryRun": "Do not actually export.", + "CmdExportOptIFW": "Export to an IFW-based installer", + "CmdExportOptInstalled": "Export all installed packages", + "CmdExportOptMaven": "Enable Maven", + "CmdExportOptNuget": "Export a NuGet package", + "CmdExportOptPrefab": "Export to Prefab format", + "CmdExportOptRaw": "Export to an uncompressed directory", + "CmdExportOptZip": "Export to a zip file", + "CmdExportSettingChocolateyMaint": "Specify the maintainer for the exported Chocolatey package (experimental feature)", + "CmdExportSettingChocolateyVersion": "Specify the version suffix to add for the exported Chocolatey package (experimental feature)", + "CmdExportSettingConfigFile": "Specify the temporary file path for the installer configuration", + "CmdExportSettingInstallerPath": "Specify the file path for the exported installer", + "CmdExportSettingNugetDesc": "Specify a description for the exported NuGet package", + "CmdExportSettingNugetID": "Specify the id for the exported NuGet package (overrides --output)", + "CmdExportSettingNugetVersion": "Specify the version for the exported NuGet package", + "CmdExportSettingOutput": "Specify the output name (used to construct filename)", + "CmdExportSettingOutputDir": "Specify the output directory for produced artifacts", + "CmdExportSettingPkgDir": "Specify the temporary directory path for the repacked packages", + "CmdExportSettingPrefabArtifactID": "Artifact Id is the name of the project according Maven specifications", + "CmdExportSettingPrefabGroupID": "GroupId uniquely identifies your project according Maven specifications", + "CmdExportSettingPrefabVersion": "Version is the name of the project according Maven specifications", + "CmdExportSettingRepoDir": "Specify the directory path for the exported repository", + "CmdExportSettingRepoURL": "Specify the remote repository URL for the online installer", + "CmdExportSettingSDKMinVersion": "Android minimum supported SDK version", + "CmdExportSettingSDKTargetVersion": "Android target sdk version", + "CmdFetchOptXStderrStatus": "Direct status/downloading messages to stderr rather than stdout. (Errors/failures still go to stdout)", + "CmdFormatManifestOptAll": "Format all ports' manifest files.", + "CmdFormatManifestOptConvertControl": "Convert CONTROL files to manifest files.", + "CmdGenerateMessageMapOptNoOutputComments": "When generating the message map, exclude comments (useful for generating the English localization file)", + "CmdGenerateMessageMapOptOutputComments": "When generating the message map, include comments (the default)", + "CmdInfoOptInstalled": "(experimental) Report on installed packages instead of available", + "CmdInfoOptTransitive": "(experimental) Also report on dependencies of installed packages", + "CmdLintPortOptAllPorts": "Checks all ports.", + "CmdLintPortOptFix": "Tries to fix all problems that were found.", + "CmdLintPortOptIncreaseVersion": "Increase the port-version of a port if a problem was fixed.", + "CmdNewOptApplication": "Create an application manifest (don't require name or version).", + "CmdNewOptSingleFile": "Embed vcpkg-configuration.json into vcpkg.json.", + "CmdNewOptVersionDate": "Interpret --version as an ISO 8601 date. (YYYY-MM-DD)", + "CmdNewOptVersionRelaxed": "Interpret --version as a relaxed-numeric version. (Nonnegative numbers separated by dots)", + "CmdNewOptVersionString": "Interpret --version as a string with no ordering behavior.", + "CmdNewSettingName": "Name for the new manifest.", + "CmdNewSettingVersion": "Version for the new manifest.", + "CmdRegenerateOptDryRun": "does not actually perform the action, shows only what would be done", + "CmdRegenerateOptForce": "proceeds with the (potentially dangerous) action without confirmation", + "CmdRegenerateOptNormalize": "apply any deprecation fixups", + "CmdRemoveOptDryRun": "Print the packages to be removed, but do not remove them", + "CmdRemoveOptOutdated": "Select all packages with versions that do not match the portfiles", + "CmdRemoveOptRecurse": "Allow removal of packages not explicitly specified on the command line", + "CmdSetInstalledOptDryRun": "Do not actually build or install", + "CmdSetInstalledOptNoUsage": "Don't print CMake usage information after install.", + "CmdSetInstalledOptWritePkgConfig": "Writes out a NuGet packages.config-formatted file for use with external binary caching.\nSee `vcpkg help binarycaching` for more information.", + "CmdUpdateBaselineOptDryRun": "Print out plan without execution", + "CmdUpdateBaselineOptInitial": "add a `builtin-baseline` to a vcpkg.json that doesn't already have it", + "CmdUpgradeOptAllowUnsupported": "Instead of erroring on an unsupported port, continue with a warning.", + "CmdUpgradeOptNoDryRun": "Actually upgrade", + "CmdUpgradeOptNoKeepGoing": "Stop installing packages on failure", + "CmdXDownloadOptHeader": "Additional header to use when fetching from URLs", + "CmdXDownloadOptSha": "The hash of the file to be downloaded", + "CmdXDownloadOptSkipSha": "Do not check the SHA512 of the downloaded file", + "CmdXDownloadOptStore": "Indicates the file should be stored instead of fetched", + "CmdXDownloadOptUrl": "URL to download and store if missing from cache", "CommandFailed": "command:\n{command_line}\nfailed with the following results:", "CommunityTriplets": "VCPKG community triplets:", "ComparingUtf8Decoders": "Comparing Utf8Decoders with different provenance; this is always an error", @@ -123,6 +221,8 @@ "CreatingZipArchive": "Creating zip archive...", "CreationFailed": "Creating {path} failed.", "CurlFailedToExecute": "curl failed to execute with exit code {exit_code}.", + "CurlFailedToPut": "curl failed to put file to {url} with exit code {exit_code}.", + "CurlFailedToPutHttp": "curl failed to put file to {url} with exit code {exit_code} and http code {value}.", "CurlReportedUnexpectedResults": "curl has reported unexpected results to vcpkg and vcpkg cannot continue.\nPlease review the following text for sensitive information and open an issue on the Microsoft/vcpkg GitHub to help fix this problem!\ncmd: {command_line}\n=== curl output ===\n{actual}\n=== end curl output ===", "CurlReturnedUnexpectedResponseCodes": "curl returned a different number of response codes than were expected for the request ({actual} vs expected {expected}).", "CurrentCommitBaseline": "You can use the current commit as a baseline, which is:\n\t\"builtin-baseline\": \"{value}\"", @@ -135,10 +235,16 @@ "DetectCompilerHash": "Detecting compiler hash for triplet {triplet}...", "DocumentedFieldsSuggestUpdate": "If these are documented fields that should be recognized try updating the vcpkg tool.", "DownloadAvailable": "A downloadable copy of this tool is available and can be used by unsetting {env_var}.", + "DownloadFailedCurl": "{url}: curl failed to download with exit code {exit_code}", + "DownloadFailedHashMismatch": "File does not have the expected hash:\nurl: {url}\nFile: {path}\nExpected hash: {expected}\nActual hash: {actual}", + "DownloadFailedRetrying": "Download failed -- retrying after {value}ms", + "DownloadFailedStatusCode": "{url}: failed: status code {value}", "DownloadRootsDir": "Specify the downloads root directory.\n(default: {env_var})", + "DownloadWinHttpError": "{url}: {system_api} failed with exit code {exit_code}", "DownloadedSources": "Downloaded sources for {spec}", "DownloadingPortableToolVersionX": "A suitable version of {tool_name} was not found (required v{version}) Downloading portable {tool_name} {version}...", "DownloadingTool": "Downloading {tool_name}...\n{url}->{path}", + "DownloadingUrl": "Downloading {url}", "DownloadingVcpkgCeBundle": "Downloading vcpkg-ce bundle {version}...", "DownloadingVcpkgCeBundleLatest": "Downloading latest vcpkg-ce bundle...", "DownloadingVcpkgStandaloneBundle": "Downloading standalone bundle {version}.", @@ -154,6 +260,7 @@ "EmptyArg": "The option --{option} must be passed a non-empty argument.", "EmptyLicenseExpression": "SPDX license expression was empty.", "EndOfStringInCodeUnit": "found end of string in middle of code point", + "EnvInvalidMaxConcurrency": "{env_var} is {value}, must be > 0", "EnvStrFailedToExtract": "could not expand the environment string:", "ErrorDetectingCompilerInfo": "while detecting compiler information:\nThe log file content at \"{path}\" is:", "ErrorIndividualPackagesUnsupported": "In manifest mode, `vcpkg install` does not support individual package arguments.\nTo install additional packages, edit vcpkg.json and then run `vcpkg install` without any package arguments.", @@ -184,6 +291,7 @@ "ExpectedCascadeFailure": "Expected {expected} cascade failure, but there were {actual} cascade failures.", "ExpectedCharacterHere": "expected '{expected}' here", "ExpectedDigitsAfterDecimal": "Expected digits after the decimal point", + "ExpectedExtension": "The file extension was not {extension}: {path}", "ExpectedFailOrSkip": "expected 'fail', 'skip', or 'pass' here", "ExpectedOneSetOfTags": "Found {count} sets of {old_value}.*{new_value} but expected exactly 1, in block:\n{value}", "ExpectedPathToExist": "Expected {path} to exist after fetching", @@ -201,7 +309,9 @@ "ExportingPackage": "Exporting {package_name}...", "ExtendedDocumentationAtUrl": "Extended documentation available at '{url}'.", "ExtractingTool": "Extracting {tool_name}...", + "FailedPostBuildChecks": "Found {count} post-build check problem(s). To submit these ports to curated catalogs, please first correct the portfile: {path}", "FailedToCheckoutRepo": "failed to check out `versions` from repo {package_name}", + "FailedToDetermineArchitecture": "unable to determine the architecture of {path}.\n{command_line}", "FailedToDetermineCurrentCommit": "Failed to determine the current commit:", "FailedToDownloadFromMirrorSet": "Failed to download from mirror set", "FailedToExtract": "Failed to extract \"{path}\":", @@ -240,6 +350,8 @@ "FetchingBaselineInfo": "Fetching baseline information from {package_name}...", "FetchingRegistryInfo": "Fetching registry information from {url} ({value})...", "FileNotFound": "{path}: file not found", + "FileReadFailed": "Failed to read {count} bytes from {path} at offset {byte_offset}.", + "FileSeekFailed": "Failed to seek to position {byte_offset} in {path}.", "FileSystemOperationFailed": "Filesystem operation failed:", "FilesExported": "Files exported at: {path}", "FishCompletion": "vcpkg fish completion is already added at \"{path}\".", @@ -293,8 +405,28 @@ "HelpRemoveOutdatedCommand": "Uninstall all out-of-date packages.", "HelpResponseFileCommand": "Specify a response file to provide additional parameters.", "HelpSearchCommand": "Search for packages available to be built.", + "HelpTextOptFullDesc": "Do not truncate long text", "HelpTopicCommand": "Display help for a specific topic.", "HelpTopicsCommand": "Display the list of help topics.", + "HelpTxtOptAllowUnsupportedPort": "Instead of erroring on an unsupported port, continue with a warning.", + "HelpTxtOptCleanAfterBuild": "Clean buildtrees, packages and downloads after building each package", + "HelpTxtOptCleanBuildTreesAfterBuild": "Clean buildtrees after building each package", + "HelpTxtOptCleanDownloadsAfterBuild": "Clean downloads after building each package", + "HelpTxtOptCleanPkgAfterBuild": "Clean packages after building each package", + "HelpTxtOptDryRun": "Do not actually build or install.", + "HelpTxtOptEditable": "Disable source re-extraction and binary caching for libraries on the command line (classic mode)", + "HelpTxtOptEnforcePortChecks": "Fail install if a port has detected problems or attempts to use a deprecated feature", + "HelpTxtOptKeepGoing": "Continue installing packages on failure", + "HelpTxtOptManifestFeature": "Additional feature from the top-level manifest to install (manifest mode).", + "HelpTxtOptManifestNoDefault": "Don't install the default features from the top-level manifest (manifest mode).", + "HelpTxtOptNoDownloads": "Do not download new sources", + "HelpTxtOptNoUsage": "Don't print CMake usage information after install.", + "HelpTxtOptOnlyBinCache": "Fail if cached binaries are not available", + "HelpTxtOptOnlyDownloads": "Download sources but don't build packages", + "HelpTxtOptRecurse": "Allow removal of packages as part of installation", + "HelpTxtOptUseAria2": "Use aria2 to perform download tasks", + "HelpTxtOptUseHeadVersion": "Install the libraries on the command line using the latest upstream sources (classic mode)", + "HelpTxtOptWritePkgConfig": "Writes out a NuGet packages.config-formatted file for use with external binary caching.\nSee `vcpkg help binarycaching` for more information.", "HelpUpdateBaseline": "The best approach to keep your libraries up to date, the best approach is to update your baseline reference. This will ensure all packages, including transitive ones, are updated. However if you need to update a package independently, you can use a \"version>=\" constraint.", "HelpUpdateCommand": "List packages that can be updated.", "HelpUpgradeCommand": "Rebuild all outdated packages.", @@ -327,7 +459,7 @@ "InstalledPackages": "The following packages are already installed:", "InstalledRequestedPackages": "All requested packages are currently installed.", "InstallingFromLocation": "-- Installing port from location: {path}", - "InstallingMavenFile": "{path} installing maven file", + "InstallingMavenFile": "{path} installing Maven file", "InstallingPackage": "Installing {action_index}/{count} {spec}...", "IntegrationFailed": "Integration was not applied.", "InternalCICommand": "vcpkg ci is an internal command which will change incompatibly or be removed at any time.", @@ -367,6 +499,7 @@ "InvalidPortVersonName": "Found invalid port version file name: `{path}`.", "InvalidString": "Invalid utf8 passed to Value::string(std::string)", "InvalidTriplet": "Invalid triplet: {triplet}", + "InvalidUri": "unable to parse uri: {value}", "IrregularFile": "path was not a regular file: {path}", "JsonErrorMustBeAnObject": "Expected \"{path}\" to be an object.", "JsonFileMissingExtension": "the JSON file {path} must have a .json (all lowercase) extension", @@ -409,6 +542,7 @@ "ManifestConflict": "Found both a manifest and CONTROL files in port \"{path}\"; please rename one or the other", "ManifestFormatCompleted": "Succeeded in formatting the manifest files.", "MismatchedFiles": "file to store does not match hash", + "MismatchedManifestAfterReserialize": "The serialized manifest was different from the original manifest. Please open an issue at https://github.com/microsoft/vcpkg, with the following output:", "MismatchedNames": "names did not match: '{package_name}' != '{actual}'", "Missing7zHeader": "Unable to find 7z header.", "MissingAndroidEnv": "ANDROID_NDK_HOME environment variable missing", @@ -437,6 +571,8 @@ "NoLocalizationForMessages": "No localized messages for the following: ", "NoOutdatedPackages": "There are no outdated packages.", "NoRegistryForPort": "no registry configured for port {package_name}", + "NoUrlsAndHashSpecified": "No urls specified to download SHA: {sha}", + "NoUrlsAndNoHashSpecified": "No urls specified and no hash specified.", "NoteMessage": "note: ", "NugetPackageFileSucceededButCreationFailed": "NuGet package creation succeeded, but no .nupkg was produced. Expected: \"{path}\"", "OptionMustBeInteger": "Value of --{option} must be an integer.", @@ -446,6 +582,12 @@ "OverlayPatchDir": "Overlay path \"{path}\" must exist and must be a directory.", "OverlayTriplets": "Overlay triplets from {path} :", "OverwritingFile": "File {path} was already present and will be overwritten", + "PECoffHeaderTooShort": "While parsing Portable Executable {path}, size of COFF header too small to contain a valid PE header.", + "PEConfigCrossesSectionBoundary": "While parsing Portable Executable {path}, image config directory crosses a secion boundary.", + "PEImportCrossesSectionBoundary": "While parsing Portable Executable {path}, import table crosses a secion boundary.", + "PEPlusTagInvalid": "While parsing Portable Executable {path}, optional header was neither PE32 nor PE32+.", + "PERvaNotFound": "While parsing Portable Executable {path}, could not find RVA {value:#X}.", + "PESignatureMismatch": "While parsing Portable Executable {path}, signature mismatch.", "PackageAlreadyRemoved": "unable to remove package {spec}: already removed", "PackageFailedtWhileExtracting": "'{value}' failed while extracting {path}.", "PackageRootDir": "(Experimental) Specify the packages root directory.", @@ -464,6 +606,42 @@ "ParseControlErrorInfoWhileLoading": "while loading {path}:", "ParseControlErrorInfoWrongTypeFields": "The following fields had the wrong types:", "PathMustBeAbsolute": "Value of environment variable X_VCPKG_REGISTRIES_CACHE is not absolute: {path}", + "PerformingPostBuildValidation": "-- Performing post-build validation", + "PortBugAllowRestrictedHeaders": "In exceptional circumstances, this policy can be disabled via {env_var}", + "PortBugBinDirExists": "There should be no bin\\ directory in a static build, but {path} is present.", + "PortBugDebugBinDirExists": "There should be no debug\\bin\\ directory in a static build, but {path} is present.", + "PortBugDebugShareDir": "/debug/share should not exist. Please reorganize any important files, then use\nfile(REMOVE_RECURSE \"${{CURRENT_PACKAGES_DIR}}/debug/share\")", + "PortBugDllAppContainerBitNotSet": "The App Container bit must be set for Windows Store apps. The following DLLs do not have the App Container bit set:", + "PortBugDllInLibDir": "The following dlls were found in /lib or /debug/lib. Please move them to /bin or /debug/bin, respectively.", + "PortBugDuplicateIncludeFiles": "Include files should not be duplicated into the /debug/include directory. If this cannot be disabled in the project cmake, use\nfile(REMOVE_RECURSE \"${{CURRENT_PACKAGES_DIR}}/debug/include\")", + "PortBugFoundCopyrightFiles": "The following files are potential copyright files:", + "PortBugFoundDebugBinaries": "Found {count} debug binaries:", + "PortBugFoundDllInStaticBuild": "DLLs should not be present in a static build, but the following DLLs were found:", + "PortBugFoundEmptyDirectories": "There should be no empty directories in {path}. The following empty directories were found:", + "PortBugFoundExeInBinDir": "The following EXEs were found in /bin or /debug/bin. EXEs are not valid distribution targets.", + "PortBugFoundReleaseBinaries": "Found {count} release binaries:", + "PortBugIncludeDirInCMakeHelperPort": "The folder /include exists in a cmake helper port; this is incorrect, since only cmake files should be installed", + "PortBugInspectFiles": "To inspect the {extension} files, use:", + "PortBugInvalidCrtLinkage": "Invalid crt linkage. Expected {expected}, but the following libs had:", + "PortBugMergeLibCMakeDir": "The /lib/cmake folder should be merged with /debug/lib/cmake and moved to /share/{spec}/cmake. Please use the helper function `vcpkg_cmake_config_fixup()` from the port vcpkg-cmake-config.`", + "PortBugMismatchedNumberOfBinaries": "Mismatching number of debug and release binaries.", + "PortBugMisplacedCMakeFiles": "The following cmake files were found outside /share/{spec}. Please place cmake files in /share/{spec}.", + "PortBugMisplacedFiles": "The following files are placed in {path}:", + "PortBugMisplacedFilesCont": "Files cannot be present in those directories.", + "PortBugMisplacedPkgConfigFiles": "pkgconfig directories should be one of share/pkgconfig (for header only libraries only), lib/pkgconfig, or lib/debug/pkgconfig. The following misplaced pkgconfig files were found:", + "PortBugMissingDebugBinaries": "Debug binaries were not found.", + "PortBugMissingFile": "The /{path} file does not exist. This file must exist for CMake helper ports.", + "PortBugMissingImportedLibs": "Import libraries were not present in {path}.\nIf this is intended, add the following line in the portfile:\nset(VCPKG_POLICY_DLLS_WITHOUT_LIBS enabled)", + "PortBugMissingIncludeDir": "The folder /include is empty or not present. This indicates the library was not correctly installed.", + "PortBugMissingLicense": "The software license must be available at ${CURRENT_PACKAGES_DIR}/share/{spec}/copyright", + "PortBugMissingReleaseBinaries": "Release binaries were not found.", + "PortBugMovePkgConfigFiles": "You can move the pkgconfig files with commands similar to:", + "PortBugOutdatedCRT": "Detected outdated dynamic CRT in the following files:", + "PortBugRemoveBinDir": "If the creation of bin\\ and/or debug\\bin\\ cannot be disabled, use this in the portfile to remove them", + "PortBugRemoveEmptyDirectories": "If a directory should be populated but is not, this might indicate an error in the portfile.\nIf the directories are not needed and their creation cannot be disabled, use something like this in the portfile to remove them:", + "PortBugRemoveEmptyDirs": "vcpkg_fixup_pkgconfig()\nfile(REMOVE_RECURSE empty directories left by the above renames)", + "PortBugRestrictedHeaderPaths": "The following restricted headers can prevent the core C++ runtime and other packages from compiling correctly. In exceptional circumstances, this policy can be disabled via {env_var}.", + "PortBugSetDllsWithoutExports": "DLLs without any exports are likely a bug in the build script. If this is intended, add the following line in the portfile:\nset(VCPKG_POLICY_DLLS_WITHOUT_EXPORTS enabled)\nThe following DLLs have no exports:", "PortDependencyConflict": "Port {package_name} has the following unsupported dependencies:", "PortNotInBaseline": "the baseline does not contain an entry for port {package_name}", "PortSupportsField": "(supports: \"{supports_expression}\")", @@ -482,10 +660,10 @@ "RemoveDependencies": "To remove dependencies in manifest mode, edit your manifest (vcpkg.json) and run 'install'.", "RemovePackageConflict": "Another installed package matches the name of an unmatched request. Did you mean {spec}?", "RemovingPackage": "Removing {action_index}/{count} {spec}", - "ReplaceSecretsError": "Replace secretes produced the following error: '{error_msg}'", "RestoredPackage": "Restored package from \"{path}\"", "RestoredPackagesFromVendor": "Restored {count} package(s) from {value} in {elapsed}. Use --debug to see more details.", "ResultsHeader": "RESULTS", + "SecretBanner": "*** SECRET ***", "SeeURL": "See {url} for more information.", "SerializedBinParagraphHeader": "\nSerialized Binary Paragraph", "SettingEnvVar": "-- Setting \"{env_var}\" environment variables to \"{url}\".", From 054858c62433f876d957c675ce618b78526a355f Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Sat, 17 Dec 2022 23:03:24 +0100 Subject: [PATCH 19/28] PACKAGE_NAME must also be used if the package name casing is different --- src/vcpkg/portlint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index 3ac874a0dc..18df5049a3 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -258,7 +258,7 @@ namespace vcpkg::Lint { param = param.substr(StringLiteral("share/").size()); } - if (param == "${PORT}" || Strings::case_insensitive_ascii_equals(param, origin)) + if (param == "${PORT}" || param == origin) { portfile_content.erase(target, end_param - target); } From 2b95b5023c199248315e2028ca357f1470abc119 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Mon, 19 Dec 2022 16:53:46 +0100 Subject: [PATCH 20/28] Format --- locales/messages.en.json | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/locales/messages.en.json b/locales/messages.en.json index 37bba0301f..f906a589e4 100644 --- a/locales/messages.en.json +++ b/locales/messages.en.json @@ -199,6 +199,7 @@ "ComparingUtf8Decoders": "Comparing Utf8Decoders with different provenance; this is always an error", "CompressFolderFailed": "Failed to compress folder \"{path}\":", "ComputingInstallPlan": "Computing installation plan...", + "ConfigurationErrorRegistriesWithoutBaseline": "The configuration defined in {path} is invalid.\n\nUsing registries requires that a baseline is set for the default registry or that the default registry is null.\n\nSee {url} for more details.", "ConflictingFiles": "The following files are already installed in {path} and are in conflict with {spec}", "ConflictingValuesForOption": "conflicting values specified for '--{option}'.", "ConstraintViolation": "Found a constraint violation:", @@ -245,12 +246,17 @@ "DownloadingPortableToolVersionX": "A suitable version of {tool_name} was not found (required v{version}) Downloading portable {tool_name} {version}...", "DownloadingTool": "Downloading {tool_name}...\n{url}->{path}", "DownloadingUrl": "Downloading {url}", - "DownloadingVcpkgCeBundle": "Downloading vcpkg-ce bundle {version}...", - "DownloadingVcpkgCeBundleLatest": "Downloading latest vcpkg-ce bundle...", + "DownloadingVcpkgCeBundle": "Downloading vcpkg-artifacts bundle {version}...", + "DownloadingVcpkgCeBundleLatest": "Downloading latest vcpkg-artifacts bundle...", "DownloadingVcpkgStandaloneBundle": "Downloading standalone bundle {version}.", "DownloadingVcpkgStandaloneBundleLatest": "Downloading latest standalone bundle.", "DuplicateCommandOption": "The option --{option} can only be passed once.", "DuplicateOptions": "'--{value}' specified multiple times.", + "DuplicatePackagePattern": "Package \"{package_name}\" is duplicated.", + "DuplicatePackagePatternFirstOcurrence": "First declared in:", + "DuplicatePackagePatternIgnoredLocations": "The following redeclarations will be ignored:", + "DuplicatePackagePatternLocation": "location: {path}", + "DuplicatePackagePatternRegistry": "registry: {url}", "DuplicatedKeyInObj": "Duplicated key \"{value}\" in an object", "ElapsedForPackage": "Elapsed time to handle {spec}: {elapsed}", "ElapsedInstallTime": "Total elapsed time: {count}", @@ -336,7 +342,7 @@ "FailedToParseNoTopLevelObj": "Failed to parse {path}, expected a top-level object.", "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:", "FailedToParseVersionXML": "Could not parse version for tool {tool_name}. Version string was: {version}", - "FailedToProvisionCe": "Failed to provision vcpkg-ce.", + "FailedToProvisionCe": "Failed to provision vcpkg-artifacts.", "FailedToRead": "Failed to read {path}: {error_msg}", "FailedToReadParagraph": "Failed to read paragraphs from {path}", "FailedToRemoveControl": "Failed to remove control file {path}", @@ -605,6 +611,9 @@ "ParseControlErrorInfoTypesEntry": "{value} was expected to be {expected}", "ParseControlErrorInfoWhileLoading": "while loading {path}:", "ParseControlErrorInfoWrongTypeFields": "The following fields had the wrong types:", + "ParseIdentifierError": "\"{value}\" is not a valid identifier. Identifiers must be lowercase alphanumeric+hypens and not reserved (see {url} for more information)", + "ParsePackageNameError": "\"{package_name}\" is not a valid package name. Package names must be lowercase alphanumeric+hypens and not reserved (see {url} for more information)", + "ParsePackagePatternError": "\"{package_name}\" is not a valid package pattern. Package patterns must use only one wildcard character (*) and it must be the last character in the pattern (see {url} for more information)", "PathMustBeAbsolute": "Value of environment variable X_VCPKG_REGISTRIES_CACHE is not absolute: {path}", "PerformingPostBuildValidation": "-- Performing post-build validation", "PortBugAllowRestrictedHeaders": "In exceptional circumstances, this policy can be disabled via {env_var}", @@ -789,6 +798,7 @@ "VersionTableHeader": "Version", "WaitingForChildrenToExit": "Waiting for child processes to exit...", "WaitingToTakeFilesystemLock": "waiting to take filesystem lock on {path}...", + "WarnOnParseConfig": "Found the following warnings in configuration {path}:", "WarningMessage": "warning: ", "WarningMessageMustUsePrintWarning": "The message named {value} starts with warning:, it must be changed to prepend WarningMessage in code instead.", "WarningsTreatedAsErrors": "previous warnings being interpreted as errors", From c320e6cedf33e2cf32f5ee147523462bd510ac38 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Tue, 20 Dec 2022 17:53:51 +0100 Subject: [PATCH 21/28] Revert "PACKAGE_NAME must also be used if the package name casing is different" This reverts commit 054858c62433f876d957c675ce618b78526a355f. --- src/vcpkg/portlint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index 18df5049a3..3ac874a0dc 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -258,7 +258,7 @@ namespace vcpkg::Lint { param = param.substr(StringLiteral("share/").size()); } - if (param == "${PORT}" || param == origin) + if (param == "${PORT}" || Strings::case_insensitive_ascii_equals(param, origin)) { portfile_content.erase(target, end_param - target); } From ed44a8dfc299b9196a2a0d571b660146f498f39b Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Wed, 21 Dec 2022 20:16:39 +0100 Subject: [PATCH 22/28] Use functions to simplify code --- src/vcpkg-test/portlint.cpp | 6 +- src/vcpkg/portlint.cpp | 206 ++++++++++++++++++++++-------------- 2 files changed, 131 insertions(+), 81 deletions(-) diff --git a/src/vcpkg-test/portlint.cpp b/src/vcpkg-test/portlint.cpp index cfa14bac1b..4796cdf8b2 100644 --- a/src/vcpkg-test/portlint.cpp +++ b/src/vcpkg-test/portlint.cpp @@ -34,7 +34,11 @@ namespace auto result = check_portfile_deprecated_functions(old_content.to_string(), "test", Fix::YES, msg_sink); REQUIRE(result.status == Status::Fixed); REQUIRE(msg_sink.counter == 0); - REQUIRE(result.new_portfile_content == new_content); + if (result.new_portfile_content != new_content) + { + REQUIRE(Strings::replace_all(result.new_portfile_content, "\r", "\\r") == + Strings::replace_all(new_content, "\r", "\\r")); + } if (new_host_dependency.empty()) { REQUIRE(result.added_host_deps.empty()); diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index 3ac874a0dc..243c924074 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -174,6 +174,90 @@ namespace vcpkg::Lint return lint_result.status; } + namespace + { + std::string::size_type find_param(const std::string& content, + ZStringView param, + std::string::size_type start, + std::string::size_type end) + { + while ((start = content.find(param.c_str(), start)) != std::string::npos) + { + if (start > end) return std::string::npos; + // param must be not included in another word + if (ParserBase::is_word_char(content[start - 1]) || + ParserBase::is_word_char(content[start + param.size()])) + { + start += param.size(); + } + else + { + return start; + } + } + return std::string::npos; + } + + void replace_param(std::string& content, + ZStringView old_param, + ZStringView new_param, + std::string::size_type start, + std::string::size_type end) + { + auto index = find_param(content, old_param, start, end); + if (index != std::string::npos) + { + content.replace(index, old_param.size(), new_param.c_str()); + } + } + + void remove_param(std::string& content, ZStringView param, std::string::size_type index) + { + const auto first_white_space = content.find_last_not_of(" \n\t\r", index - 1) + 1; + const auto white_space_length = index - first_white_space; + content.erase(first_white_space, white_space_length + param.size()); + } + + void find_remove_param(std::string& content, + ZStringView param, + std::string::size_type start, + std::string::size_type end) + { + const auto start_param = find_param(content, param, start, end); + if (start_param != std::string::npos) + { + remove_param(content, param, start_param); + } + } + + struct ParamAndValue + { + std::string::size_type start_param = std::string::npos; + std::string::size_type start_value = std::string::npos; + std::string::size_type end_value = std::string::npos; + bool found() const { return start_param != std::string::npos; } + bool value_found() const { return start_value != std::string::npos && end_value != std::string::npos; } + std::string get_value(const std::string& content) const + { + return content.substr(start_value, end_value - start_value); + } + std::string::size_type full_length() const { return end_value - start_param; } + }; + + ParamAndValue find_param_maybe_value(const std::string& content, + ZStringView param, + std::string::size_type start, + std::string::size_type end) + { + auto start_param = find_param(content, param, start, end); + if (start_param == std::string::npos) return {}; + const auto start_value = content.find_first_not_of(" \r\n\t)", start_param + param.size()); + const auto end_value = content.find_first_of(" \r\n\t)", start_value); + if (end_value == std::string::npos || end_value > end) return ParamAndValue{start_param}; + return ParamAndValue{start_param, start_value, end_value}; + } + } + FixedPortfile check_portfile_deprecated_functions(std::string&& portfile_content, StringView origin, Fix fix, @@ -208,12 +292,7 @@ namespace vcpkg::Lint break; } const auto end = portfile_content.find(')', index); - const auto ninja = portfile_content.find("PREFER_NINJA", index); - if (ninja != std::string::npos && ninja < end) - { - const auto start = portfile_content.find_last_not_of(" \n\t\r", ninja - 1) + 1; - portfile_content.erase(start, (ninja - start) + StringLiteral("PREFER_NINJA").size()); - } + find_remove_param(portfile_content, "PREFER_NINJA", index, end); portfile_content.replace(index, StringLiteral("vcpkg_configure_cmake").size(), "vcpkg_cmake_configure"); fixedPortfile.added_host_deps.insert("vcpkg-cmake"); } @@ -244,15 +323,12 @@ namespace vcpkg::Lint break; } const auto end = portfile_content.find(')', index); - const auto target = portfile_content.find("TARGET_PATH"); - if (target != std::string::npos && target < end) + auto target = find_param_maybe_value(portfile_content, "TARGET_PATH", index, end); + if (target.found()) { - auto start_param = target + StringLiteral("TARGET_PATH").size(); - start_param = portfile_content.find_first_not_of(" \n\t)", start_param); - const auto end_param = portfile_content.find_first_of(" \n\t)", start_param); - if (end_param != std::string::npos && end_param <= end) + if (target.value_found()) { - const auto original_param = portfile_content.substr(start_param, end_param - start_param); + const auto original_param = target.get_value(portfile_content); auto param = StringView(original_param); if (Strings::starts_with(param, "share/")) { @@ -260,32 +336,27 @@ namespace vcpkg::Lint } if (param == "${PORT}" || Strings::case_insensitive_ascii_equals(param, origin)) { - portfile_content.erase(target, end_param - target); + portfile_content.erase(target.start_param, target.full_length()); } else { - portfile_content.replace(target, (end_param - target) - param.size(), "PACKAGE_NAME "); + portfile_content.replace( + target.start_param, target.full_length() - param.size(), "PACKAGE_NAME "); } // remove the CONFIG_PATH part if it uses the same param - const auto start_config_path = portfile_content.find("CONFIG_PATH", index); - if (start_config_path != std::string::npos && start_config_path < end) + auto config = find_param_maybe_value(portfile_content, "CONFIG_PATH", index, end); + if (config.value_found()) { - start_param = start_config_path + StringLiteral("CONFIG_PATH").size(); - start_param = portfile_content.find_first_not_of(" \n\t)", start_param); - const auto end_config_param = portfile_content.find_first_of(" \n\t)", start_param); - const auto config_param = - StringView(portfile_content).substr(start_param, end_config_param - start_param); - if (config_param == original_param) + if (config.get_value(portfile_content) == original_param) { - const auto start_next = portfile_content.find_first_not_of(' ', end_config_param); - portfile_content.erase(start_config_path, start_next - start_config_path); + const auto start_next = portfile_content.find_first_not_of(' ', config.end_value); + portfile_content.erase(config.start_param, start_next - config.start_param); } } } else { - const auto start = portfile_content.find_last_not_of(" \n\t\r", target - 1) + 1; - portfile_content.erase(start, StringLiteral("TARGET_PATH").size() + (target - start)); + remove_param(portfile_content, "TARGET_PATH", target.start_param); } } portfile_content.replace( @@ -301,65 +372,40 @@ namespace vcpkg::Lint break; } const auto end = portfile_content.find(')', index); - const auto target = portfile_content.find("OUT_SOURCE_PATH", index); - if (target != std::string::npos && target < end) + auto out_source_path = find_param_maybe_value(portfile_content, "OUT_SOURCE_PATH", index, end); + if (out_source_path.value_found()) { - const auto before_out_source_path = portfile_content.find_last_not_of(' ', target - 1); - auto start_param = target + StringLiteral("OUT_SOURCE_PATH").size(); - start_param = portfile_content.find_first_not_of(" \n\r\t)", start_param); - const auto end_param = portfile_content.find_first_of(" \n\r\t)", start_param); - if (end_param != std::string::npos && end_param <= end) + const auto param_value = out_source_path.get_value(portfile_content); + + const auto before_param = portfile_content.find_last_not_of(' ', out_source_path.start_param - 1) + 1; + auto after_value = portfile_content.find_first_not_of(" \r", out_source_path.end_value); + const std::string line_ending = portfile_content[after_value - 1] == '\r' ? "\r\n" : "\n"; + if (portfile_content[after_value] != '\n') { - const auto out_source_path_param = portfile_content.substr(start_param, end_param - start_param); - const auto after_param = portfile_content.find_first_not_of(' ', end_param); - auto erase_lenth = after_param - before_out_source_path; - bool was_crlf = false; - if (portfile_content[after_param] != '\n' && portfile_content[after_param] != '\r') - { - erase_lenth -= 1; // if OUT_SOURCE_PATH is not on its own line, don't remove new line character - } - if (portfile_content[after_param] == '\r') - { - erase_lenth += 1; // \r\n is used as line ending - was_crlf = true; - } - // remove ' OUT_SOURCE_PATH FOOBAR ' line - portfile_content.erase(before_out_source_path + 1, erase_lenth); + // if OUT_SOURCE_PATH is not on its own line, don't remove new line character + after_value -= line_ending.size(); + } + // remove ' OUT_SOURCE_PATH FOOBAR ' line + portfile_content.erase(before_param, after_value + 1 - before_param); - // Replace 'REF' by 'SOURCE_BASE' - auto ref_index = index; - while ((ref_index = portfile_content.find("REF", ref_index)) != std::string::npos) + // Replace 'REF' by 'SOURCE_BASE' + replace_param(portfile_content, "REF", "SOURCE_BASE", index, end); + + // insert 'FOOBAR' or // '\n FOOBAR' after '(' + auto open_bracket = portfile_content.find('(', index); + if (open_bracket != std::string::npos && open_bracket < out_source_path.start_param) + { + char c = portfile_content[before_param - 1]; + if (c == '\n') { - if (ref_index > end) break; - if (!isspace(portfile_content[ref_index - 1]) || - !isspace(portfile_content[ref_index + StringLiteral("REF").size()])) - { // 'REF' must be not included in another word - ref_index += 3; - } - else - { - portfile_content.replace(ref_index, StringLiteral("REF").size(), "SOURCE_BASE"); - break; - } + // if the OUT_SOURCE_PATH was in a new line, insert the param in a new line + auto num_spaces = out_source_path.start_param - before_param; + portfile_content.insert(open_bracket + 1, + line_ending + std::string(num_spaces, ' ') + param_value); } - - // insert 'FOOBAR' or // '\n FOOBAR' after '(' - auto open_bracket = portfile_content.find('(', index); - if (open_bracket != std::string::npos && open_bracket < target) + else { - char c = portfile_content[before_out_source_path]; - if (c == '\n') - { - // if the OUT_SOURCE_PATH was in a new line, insert the param in a new line - portfile_content.insert(open_bracket + 1, - (was_crlf ? "\r\n" : "\n") + - std::string(target - before_out_source_path - 1, ' ') + - out_source_path_param); - } - else - { - portfile_content.insert(open_bracket + 1, out_source_path_param + ' '); - } + portfile_content.insert(open_bracket + 1, param_value + ' '); } } } From 9eaf07d1c518bf3b09e7145da7fd88be54e634ec Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Wed, 21 Dec 2022 20:57:28 +0100 Subject: [PATCH 23/28] Also check for vcpkg_check_features without FEATURES keyword --- include/vcpkg/base/messages.h | 6 ++++++ src/vcpkg-test/portlint.cpp | 17 +++++++++++++++++ src/vcpkg/base/messages.cpp | 1 + src/vcpkg/portlint.cpp | 27 ++++++++++++++++++++++++++- 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/include/vcpkg/base/messages.h b/include/vcpkg/base/messages.h index 2b821205e9..4934f042b3 100644 --- a/include/vcpkg/base/messages.h +++ b/include/vcpkg/base/messages.h @@ -563,6 +563,7 @@ namespace vcpkg "{actual} is the currently used deprecated function, {expected} is the function that should be used", "The deprecated function \"{actual}\" is used inside the port \"{package_name}\". Use the function " "\"{expected}\" instead."); + DECLARE_MESSAGE( LintDeprecatedLicenseExpressionWithReplacement, (msg::package_name, msg::actual, msg::new_value), @@ -586,6 +587,11 @@ namespace vcpkg "", "Use the version scheme \"{new_scheme}\" instead of \"{old_scheme}\" in port " "\"{package_name}\"."); + DECLARE_MESSAGE(LintVcpkgCheckFeatures, + (msg::package_name), + "", + "Calling `vcpkg_check_features` without the `FEATURES` keyword has been deprecated. Please add the " + "`FEATURES` keyword to the call inside the port {package_name}."); DECLARE_MESSAGE(LintPortErrorsFixed, (msg::package_name), "", diff --git a/src/vcpkg-test/portlint.cpp b/src/vcpkg-test/portlint.cpp index 4796cdf8b2..5171223887 100644 --- a/src/vcpkg-test/portlint.cpp +++ b/src/vcpkg-test/portlint.cpp @@ -190,4 +190,21 @@ vcpkg_extract_source_archive(SOURCE_PATH ARCHIVE ${ARCHIVE}) check_replacement( Strings::replace_all(content, "\n", "\r\n"), Strings::replace_all(new_content, "\n", "\r\n"), ""); } + + SECTION ("vcpkg_check_features") + { + auto content = R"-( +vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS + graphml IGRAPH_GRAPHML_SUPPORT + openmp IGRAPH_OPENMP_SUPPORT +) +)-"; + auto new_content = R"-( +vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS FEATURES + graphml IGRAPH_GRAPHML_SUPPORT + openmp IGRAPH_OPENMP_SUPPORT +) +)-"; + check_replacement(content, new_content, ""); + } } diff --git a/src/vcpkg/base/messages.cpp b/src/vcpkg/base/messages.cpp index 3d978b3682..aa365fa262 100644 --- a/src/vcpkg/base/messages.cpp +++ b/src/vcpkg/base/messages.cpp @@ -807,6 +807,7 @@ namespace vcpkg REGISTER_MESSAGE(LintDeprecatedLicenseExpressionWithReplacement); REGISTER_MESSAGE(LintMissingLicenseExpression); REGISTER_MESSAGE(LintSuggestNewVersionScheme); + REGISTER_MESSAGE(LintVcpkgCheckFeatures); REGISTER_MESSAGE(LintPortErrors); REGISTER_MESSAGE(LintPortErrorsFixed); REGISTER_MESSAGE(ListOfValidFieldsForControlFiles); diff --git a/src/vcpkg/portlint.cpp b/src/vcpkg/portlint.cpp index 243c924074..fcad624293 100644 --- a/src/vcpkg/portlint.cpp +++ b/src/vcpkg/portlint.cpp @@ -276,7 +276,7 @@ namespace vcpkg::Lint } else { - status = Status::Fixed; + status |= Status::Fixed; } }; if (Strings::contains(portfile_content, "vcpkg_build_msbuild")) @@ -412,6 +412,31 @@ namespace vcpkg::Lint portfile_content.replace( index, StringLiteral("vcpkg_extract_source_archive_ex").size(), "vcpkg_extract_source_archive"); } + index = 0; + while ((index = portfile_content.find("vcpkg_check_features", index)) != std::string::npos) + { + const auto end = portfile_content.find(')', index); + const auto features = find_param(portfile_content, "FEATURES", index, end); + const auto inverted_features = find_param(portfile_content, "INVERTED_FEATURES", index, end); + if (features == std::string::npos && inverted_features == std::string::npos) + { + if (fix == Fix::NO) + { + status |= Status::Problem; + warningsSink.println_warning(msgLintVcpkgCheckFeatures, msg::package_name = origin); + break; + } + status |= Status::Fixed; + + auto feature_options = find_param_maybe_value(portfile_content, "OUT_FEATURE_OPTIONS", index, end); + if (feature_options.value_found()) + { + portfile_content.insert(feature_options.end_value, " FEATURES"); + } + } + index = end; + } + fixedPortfile.status = status; if (fix == Fix::YES) { From dbfd782a8ed5b98fb70bd1780b2f70feef5effd8 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Wed, 11 Jan 2023 13:52:10 +0100 Subject: [PATCH 24/28] Add message file changes --- locales/messages.en.json | 7 ++++++- locales/messages.json | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/locales/messages.en.json b/locales/messages.en.json index f906a589e4..92e485877c 100644 --- a/locales/messages.en.json +++ b/locales/messages.en.json @@ -184,6 +184,10 @@ "CmdSetInstalledOptDryRun": "Do not actually build or install", "CmdSetInstalledOptNoUsage": "Don't print CMake usage information after install.", "CmdSetInstalledOptWritePkgConfig": "Writes out a NuGet packages.config-formatted file for use with external binary caching.\nSee `vcpkg help binarycaching` for more information.", + "CmdSettingCopiedFilesLog": "Path to the copied files log to create", + "CmdSettingInstalledDir": "Path to the installed tree to use", + "CmdSettingTLogFile": "Path to the tlog file to create", + "CmdSettingTargetBin": "Path to the binary to analyze", "CmdUpdateBaselineOptDryRun": "Print out plan without execution", "CmdUpdateBaselineOptInitial": "add a `builtin-baseline` to a vcpkg.json that doesn't already have it", "CmdUpgradeOptAllowUnsupported": "Instead of erroring on an unsupported port, continue with a warning.", @@ -538,6 +542,7 @@ "LintPortErrors": "The port \"{package_name}\" should be fixed. See warning(s) above.", "LintPortErrorsFixed": "Problems in the port \"{package_name}\" have been fixed.", "LintSuggestNewVersionScheme": "Use the version scheme \"{new_scheme}\" instead of \"{old_scheme}\" in port \"{package_name}\".", + "LintVcpkgCheckFeatures": "Calling `vcpkg_check_features` without the `FEATURES` keyword has been deprecated. Please add the `FEATURES` keyword to the call inside the port {package_name}.", "ListOfValidFieldsForControlFiles": "This is the list of valid fields for CONTROL files (case-sensitive):", "LoadingCommunityTriplet": "-- [COMMUNITY] Loading triplet configuration from: {path}", "LoadingDependencyInformation": "Loading dependency information for {count} packages...", @@ -642,7 +647,7 @@ "PortBugMissingFile": "The /{path} file does not exist. This file must exist for CMake helper ports.", "PortBugMissingImportedLibs": "Import libraries were not present in {path}.\nIf this is intended, add the following line in the portfile:\nset(VCPKG_POLICY_DLLS_WITHOUT_LIBS enabled)", "PortBugMissingIncludeDir": "The folder /include is empty or not present. This indicates the library was not correctly installed.", - "PortBugMissingLicense": "The software license must be available at ${CURRENT_PACKAGES_DIR}/share/{spec}/copyright", + "PortBugMissingLicense": "The software license must be available at ${{CURRENT_PACKAGES_DIR}}/share/{spec}/copyright", "PortBugMissingReleaseBinaries": "Release binaries were not found.", "PortBugMovePkgConfigFiles": "You can move the pkgconfig files with commands similar to:", "PortBugOutdatedCRT": "Detected outdated dynamic CRT in the following files:", diff --git a/locales/messages.json b/locales/messages.json index 400a496778..e03ca71fce 100644 --- a/locales/messages.json +++ b/locales/messages.json @@ -806,6 +806,8 @@ "_LintPortErrorsFixed.comment": "An example of {package_name} is zlib.", "LintSuggestNewVersionScheme": "Use the version scheme \"{new_scheme}\" instead of \"{old_scheme}\" in port \"{package_name}\".", "_LintSuggestNewVersionScheme.comment": "An example of {new_scheme} is version. An example of {old_scheme} is version-string. An example of {package_name} is zlib.", + "LintVcpkgCheckFeatures": "Calling `vcpkg_check_features` without the `FEATURES` keyword has been deprecated. Please add the `FEATURES` keyword to the call inside the port {package_name}.", + "_LintVcpkgCheckFeatures.comment": "An example of {package_name} is zlib.", "ListOfValidFieldsForControlFiles": "This is the list of valid fields for CONTROL files (case-sensitive):", "LoadingCommunityTriplet": "-- [COMMUNITY] Loading triplet configuration from: {path}", "_LoadingCommunityTriplet.comment": "'-- [COMMUNITY]' at the beginning must be preserved An example of {path} is /foo/bar.", From 68e6756ce71147a7bfccf4e49286d08a1c1644e9 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Sun, 29 Jan 2023 13:46:04 +0100 Subject: [PATCH 25/28] Fix command name --- src/vcpkg/commands.lint-port.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vcpkg/commands.lint-port.cpp b/src/vcpkg/commands.lint-port.cpp index 816bd2e244..5a103a07bc 100644 --- a/src/vcpkg/commands.lint-port.cpp +++ b/src/vcpkg/commands.lint-port.cpp @@ -63,7 +63,7 @@ namespace vcpkg::Commands::LintPort Checks::msg_check_exit(VCPKG_LINE_INFO, add_all, msgAddVersionUseOptionAll, - msg::command_name = "x-add-version", + msg::command_name = "x-lint-port", msg::option = OPTION_ALL); for (auto&& port_dir : fs.get_directories_non_recursive(paths.builtin_ports_directory(), VCPKG_LINE_INFO)) From 83b13a9daa6ca96d48a8bcaa380812367dd0268b Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Tue, 14 Mar 2023 14:43:23 +0100 Subject: [PATCH 26/28] Improve performance --- src/vcpkg/base/message_sinks.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vcpkg/base/message_sinks.cpp b/src/vcpkg/base/message_sinks.cpp index 936081ce06..1e49e21e86 100644 --- a/src/vcpkg/base/message_sinks.cpp +++ b/src/vcpkg/base/message_sinks.cpp @@ -31,12 +31,12 @@ namespace vcpkg void MessageSink::println_warning(const LocalizedString& s) { - println(Color::warning, format(msg::msgWarningMessage).append(s)); + print(Color::warning, format(msg::msgWarningMessage).append(s).append_raw('\n')); } void MessageSink::println_error(const LocalizedString& s) { - println(Color::error, format(msg::msgErrorMessage).append(s)); + print(Color::error, format(msg::msgErrorMessage).append(s).append_raw('\n')); } MessageSink& null_sink = null_sink_instance; From 4cdcb307d26ffa76faff22d14a108f8c932a0a63 Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Thu, 6 Apr 2023 15:02:43 +0200 Subject: [PATCH 27/28] Add missing include --- src/vcpkg-test/portlint.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vcpkg-test/portlint.cpp b/src/vcpkg-test/portlint.cpp index c3d01a7662..b1ae7ae4b2 100644 --- a/src/vcpkg-test/portlint.cpp +++ b/src/vcpkg-test/portlint.cpp @@ -1,6 +1,7 @@ #include #include +#include #include From 14f1b1fe8f3aa07fe37d24041aa08868031e1aac Mon Sep 17 00:00:00 2001 From: Leander Schulten Date: Wed, 12 Apr 2023 11:56:43 +0200 Subject: [PATCH 28/28] Use right command arguments --- src/vcpkg/commands.lint-port.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vcpkg/commands.lint-port.cpp b/src/vcpkg/commands.lint-port.cpp index 49d6985c29..b629aa1d48 100644 --- a/src/vcpkg/commands.lint-port.cpp +++ b/src/vcpkg/commands.lint-port.cpp @@ -49,13 +49,13 @@ namespace vcpkg::Commands::LintPort auto& fs = paths.get_filesystem(); std::vector port_names; - if (!args.forwardable_arguments.empty()) + if (!parsed_args.command_arguments.empty()) { if (add_all) { msg::println_warning(msgAddVersionIgnoringOptionAll, msg::option = OPTION_ALL); } - port_names = args.forwardable_arguments; + port_names = parsed_args.command_arguments; } else {