Skip to content

Commit

Permalink
applicability string
Browse files Browse the repository at this point in the history
  • Loading branch information
yao-msft committed May 4, 2024
1 parent 5eb379b commit e6e6f87
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,10 @@ namespace AppInstaller::CLI::Workflow
}

// Download main packages
context.Reporter.Info() << Resource::String::MSStoreDownloadMainPackages << std::endl;
for (auto const& mainPackage : downloadInfo.MainPackages)
{
AICLI_LOG(CLI, Info, << "Downloading MSStore main packages");
context.Reporter.Info() << Resource::String::MSStoreDownloadMainPackages << std::endl;

context << DownloadMSStorePackageFile(mainPackage, downloadDirectory);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2951,7 +2951,7 @@ Please specify one of them using the --source option to proceed.</value>
<value>Microsoft Store package download requires Microsoft Entra Id authentication. Authentication prompt may appear when necessary. Authenticated information will be shared with Microsoft services for access authorization. For Microsoft Store package licensing, the Microsoft Entra Id account needs to have administrator access to the Microsoft Entra Id tenant.</value>
</data>
<data name="SkipMicrosoftStorePackageLicenseArgumentDescription" xml:space="preserve">
<value>Skips retrieving Microsoft Store package offline license. Retrieving Microsoft Store package license requires administrator account in a Microsoft Entra Id tenant</value>
<value>Skips retrieving Microsoft Store package offline license</value>
</data>
<data name="PlatformArgumentDescription" xml:space="preserve">
<value>Select the target platform</value>
Expand Down
8 changes: 4 additions & 4 deletions src/AppInstallerCLITests/AppInstallerCLITests.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
<ClCompile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</TreatWarningAsError>
<RuntimeTypeInfo Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</RuntimeTypeInfo>
</ClCompile>
Expand All @@ -169,7 +169,7 @@
<ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
<ClCompile>
<PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</TreatWarningAsError>
<RuntimeTypeInfo Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</RuntimeTypeInfo>
</ClCompile>
Expand All @@ -189,8 +189,8 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>_NO_ASYNCRTIMP;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(MSBuildThisFileDirectory)..\AppInstallerCommonCore;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerRepositoryCore;$(MSBuildThisFileDirectory)..\AppInstallerCommonCore\Public;$(MSBuildThisFileDirectory)..\AppInstallerSharedLib\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore\Public;$(MSBuildThisFileDirectory)..\AppInstallerCLICore;$(ProjectDir)..\JsonCppLib;$(ProjectDir)..\cpprestsdk\cpprestsdk\Release\include;$(ProjectDir)..\SfsClient\sfs-client\client\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</TreatWarningAsError>
<TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</TreatWarningAsError>
<RuntimeTypeInfo Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</RuntimeTypeInfo>
Expand Down
8 changes: 7 additions & 1 deletion src/AppInstallerCLITests/MsixInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,10 @@ TEST_CASE("MsixInfo_ValidateMsixTrustInfo", "[msixinfo]")
{
UninstallCertFromSignedPackage(testSigned);
}
}
}

TEST_CASE("MsixInfo_GetPackageVersionFromFullName", "[msixinfo]")
{
REQUIRE(Msix::GetPackageVersionFromFullName("Microsoft.NET.Native.Framework.2.2_2.2.29512.0_arm64__8wekyb3d8bbwe") == Utility::UInt64Version{ "2.2.29512.0" });

Check failure on line 100 in src/AppInstallerCLITests/MsixInfo.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`bbwe` is not a recognized word. (unrecognized-spelling)

Check failure on line 100 in src/AppInstallerCLITests/MsixInfo.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`wekyb` is not a recognized word. (unrecognized-spelling)
REQUIRE(Msix::GetPackageVersionFromFullName("Microsoft.DoesNotExist_1.2.3.4_neutral_~_8wekyb3d8bbwe") == Utility::UInt64Version{ "1.2.3.4" });

Check failure on line 101 in src/AppInstallerCLITests/MsixInfo.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`wekyb` is not a recognized word. (unrecognized-spelling)

Check failure on line 101 in src/AppInstallerCLITests/MsixInfo.cpp

View workflow job for this annotation

GitHub Actions / Check Spelling

`bbwe` is not a recognized word. (unrecognized-spelling)
}
61 changes: 60 additions & 1 deletion src/AppInstallerCLITests/TestHooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <winget/Filesystem.h>
#include <winget/IconExtraction.h>
#include <winget/Authentication.h>
#include <winget/HttpClientHelper.h>
#include <sfsclient/SFSClient.h>

#ifdef AICLI_DISABLE_TEST_HOOKS
static_assert(false, "Test hooks have been disabled");
Expand Down Expand Up @@ -81,6 +83,15 @@ namespace AppInstaller
{
void TestHook_SetAuthenticationResult_Override(Authentication::AuthenticationResult* authResult);
}

namespace MSStore::TestHooks
{
void SetDisplayCatalogHttpCLientHelper_Override(Http::HttpClientHelper* value);

void SetSfsClientAppContents_Override(std::vector<SFS::AppContent>* value);

void SetLicensingHttpCLientHelper_Override(Http::HttpClientHelper* value);
}
}

namespace TestHook
Expand Down Expand Up @@ -234,4 +245,52 @@ namespace TestHook
private:
AppInstaller::Authentication::AuthenticationResult m_authResult;
};
}

struct SetDisplayCatalogHttpClientHelper_Override
{
SetDisplayCatalogHttpClientHelper_Override(AppInstaller::Http::HttpClientHelper value) : m_httpClientHelper(value)
{
AppInstaller::MSStore::TestHooks::SetDisplayCatalogHttpCLientHelper_Override(&m_httpClientHelper);
}

~SetDisplayCatalogHttpClientHelper_Override()
{
AppInstaller::MSStore::TestHooks::SetDisplayCatalogHttpCLientHelper_Override(nullptr);
}

private:
AppInstaller::Http::HttpClientHelper m_httpClientHelper;
};

struct SetSfsClientAppContents_Override
{
SetSfsClientAppContents_Override(std::vector<SFS::AppContent>&& value) : m_appContents(std::move(value))
{
AppInstaller::MSStore::TestHooks::SetSfsClientAppContents_Override(&m_appContents);
}

~SetSfsClientAppContents_Override()
{
AppInstaller::MSStore::TestHooks::SetSfsClientAppContents_Override(nullptr);
}

private:
std::vector<SFS::AppContent> m_appContents;
};

struct SetLicensingHttpClientHelper_Override
{
SetLicensingHttpClientHelper_Override(AppInstaller::Http::HttpClientHelper value) : m_httpClientHelper(value)
{
AppInstaller::MSStore::TestHooks::SetLicensingHttpCLientHelper_Override(&m_httpClientHelper);
}

~SetLicensingHttpClientHelper_Override()
{
AppInstaller::MSStore::TestHooks::SetLicensingHttpCLientHelper_Override(nullptr);
}

private:
AppInstaller::Http::HttpClientHelper m_httpClientHelper;
};
}
83 changes: 72 additions & 11 deletions src/AppInstallerCommonCore/MSStoreDownload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,32 @@ namespace AppInstaller::MSStore
{
using namespace std::string_view_literals;

#ifndef AICLI_DISABLE_TEST_HOOKS
namespace TestHooks
{
static Http::HttpClientHelper* s_DisplayCatalog_HttpCLientHelper_Override = nullptr;

void SetDisplayCatalogHttpCLientHelper_Override(Http::HttpClientHelper* value)
{
s_DisplayCatalog_HttpCLientHelper_Override = value;
}

static std::vector<SFS::AppContent>* s_SfsClient_AppContents_Override = nullptr;

void SetSfsClientAppContents_Override(std::vector<SFS::AppContent>* value)
{
s_SfsClient_AppContents_Override = value;
}

static Http::HttpClientHelper* s_Licensing_HttpCLientHelper_Override = nullptr;

void SetLicensingHttpCLientHelper_Override(Http::HttpClientHelper* value)
{
s_Licensing_HttpCLientHelper_Override = value;
}
}
#endif

namespace DisplayCatalogDetails
{
// Default preferred sku to use
Expand Down Expand Up @@ -552,6 +578,14 @@ namespace AppInstaller::MSStore
auto displayCatalogApi = GetDisplayCatalogRestApi(productId, locale);

AppInstaller::Http::HttpClientHelper httpClientHelper;

#ifndef AICLI_DISABLE_TEST_HOOKS
if (TestHooks::s_DisplayCatalog_HttpCLientHelper_Override)
{
httpClientHelper = *TestHooks::s_DisplayCatalog_HttpCLientHelper_Override;
}
#endif

std::optional<web::json::value> displayCatalogResponseObject = httpClientHelper.HandleGet(displayCatalogApi);

if (!displayCatalogResponseObject)
Expand Down Expand Up @@ -635,17 +669,17 @@ namespace AppInstaller::MSStore
return Utility::Architecture::Unknown;
}

std::vector<Manifest::PlatformEnum> GetSfsPackageFileSupportedPlatforms(const SFS::AppFile& appFile, Manifest::PlatformEnum requiredPlatform)
std::vector<std::string> GetSfsPackageFileSupportedPlatforms(const SFS::AppFile& appFile, Manifest::PlatformEnum requiredPlatform)
{
std::vector<Manifest::PlatformEnum> supportedPlatforms;
std::vector<std::string> supportedPlatforms;

for (auto const& applicability : appFile.GetApplicabilityDetails().GetPlatformApplicabilityForPackage())
{
auto platform = ConvertFromSfsPlatform(applicability);
if (platform != Manifest::PlatformEnum::Unknown &&
(platform == requiredPlatform || requiredPlatform == Manifest::PlatformEnum::Unknown))
{
supportedPlatforms.emplace_back(platform);
supportedPlatforms.emplace_back(applicability);
}
}

Expand Down Expand Up @@ -750,7 +784,7 @@ namespace AppInstaller::MSStore
Utility::Architecture requiredArchitecture = Utility::Architecture::Unknown,
Manifest::PlatformEnum requiredPlatform = Manifest::PlatformEnum::Unknown)
{
using PlatformAndArchitectureKey = std::pair<Manifest::PlatformEnum, Utility::Architecture>;
using PlatformAndArchitectureKey = std::pair<std::string, Utility::Architecture>;

// Since the server may return multiple versions of the same package, we'll use ths map to record the one with latest version
// for each Platform|Architecture pair.
Expand Down Expand Up @@ -820,20 +854,33 @@ namespace AppInstaller::MSStore
{
AICLI_LOG(Core, Info, << "CallSfsClientAndGetMSStoreDownloadInfo with WuCategoryId: " << wuCategoryId << " Architecture: " << Utility::ToString(requiredArchitecture) << " Platform: " << Manifest::PlatformToString(requiredPlatform));

SFS::RequestParams sfsClientRequest;
sfsClientRequest.productRequests = { {std::string{ wuCategoryId }, {}} };

std::vector<SFS::AppContent> appContents;
auto requestResult = GetSfsClientInstance()->GetLatestAppDownloadInfo(sfsClientRequest, appContents);
if (!requestResult)

#ifndef AICLI_DISABLE_TEST_HOOKS
if (TestHooks::s_SfsClient_AppContents_Override)
{
AICLI_LOG(Core, Error, << "Failed to call SfsClient GetLatestAppDownloadInfo. Error code:" << requestResult.GetCode() << " Message: " << requestResult.GetMsg());
THROW_HR_MSG(APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED, "Failed to call SfsClient GetLatestAppDownloadInfo. ErrorCode: " + requestResult.GetCode());
appContents = std::move(*TestHooks::s_SfsClient_AppContents_Override);
}
else
{
#endif
SFS::RequestParams sfsClientRequest;
sfsClientRequest.productRequests = { {std::string{ wuCategoryId }, {}} };

auto requestResult = GetSfsClientInstance()->GetLatestAppDownloadInfo(sfsClientRequest, appContents);
if (!requestResult)
{
AICLI_LOG(Core, Error, << "Failed to call SfsClient GetLatestAppDownloadInfo. Error code:" << requestResult.GetCode() << " Message: " << requestResult.GetMsg());
THROW_HR_MSG(APPINSTALLER_CLI_ERROR_SFSCLIENT_API_FAILED, "Failed to call SfsClient GetLatestAppDownloadInfo. ErrorCode: " + requestResult.GetCode());
}
#ifndef AICLI_DISABLE_TEST_HOOKS
}
#endif

THROW_HR_IF(E_UNEXPECTED, appContents.empty());

MSStoreDownloadInfo result;
// Currently for app downloads, the result vector is always size 1.
const auto& appContent = appContents.at(0);

// Populate main packages
Expand Down Expand Up @@ -886,6 +933,13 @@ namespace AppInstaller::MSStore

AppInstaller::Http::HttpClientHelper httpClientHelper;

#ifndef AICLI_DISABLE_TEST_HOOKS
if (TestHooks::s_Licensing_HttpCLientHelper_Override)
{
httpClientHelper = *TestHooks::s_Licensing_HttpCLientHelper_Override;
}
#endif

web::json::value requestBody;
requestBody[JSON::GetUtilityString(ContentId)] = web::json::value::string(JSON::GetUtilityString(contentId));
Http::HttpClientHelper::HttpRequestHeaders requestHeaders;
Expand Down Expand Up @@ -978,6 +1032,13 @@ namespace AppInstaller::MSStore
{
THROW_HR_IF_MSG(HRESULT_FROM_WIN32(ERROR_INVALID_STATE), m_contentId.empty(), "GetDownloadInfo() must be called before GetLicense()");

#ifndef AICLI_DISABLE_TEST_HOOKS
if (TestHooks::s_Licensing_HttpCLientHelper_Override)
{
return LicensingDetails::GetLicencing(m_contentId, {});
}
#endif

return LicensingDetails::GetLicencing(m_contentId, GetAuthHeaders(m_licensingAuthenticator));
}
}

1 comment on commit e6e6f87

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@check-spelling-bot Report

🔴 Please review

See the 📜action log for details.

Unrecognized words (4)

bbwe
IENT
SFSCl
wekyb

Previously acknowledged words that are now absent ata bitspace EPester epth hrow issuetitle mapview Mta oop PFM sfs STARTUPINFOW testdata visualstudiocode :arrow_right:
To accept ✔️ these unrecognized words as correct and remove the previously acknowledged and now absent words, run the following commands

... in a clone of the git@github.com:yao-msft/winget-cli.git repository
on the msstoredownload branch (ℹ️ how do I use this?):

curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/v0.0.21/apply.pl' |
perl - 'https://github.com/yao-msft/winget-cli/actions/runs/8946436461/attempts/1'
Available 📚 dictionaries could cover words not in the 📘 dictionary

This includes both expected items (544) from .github/actions/spelling/expect.txt and unrecognized words (4)

Dictionary Entries Covers
cspell:win32/src/win32.txt 53509 20
cspell:python/src/python/python-lib.txt 3873 3
cspell:python/src/python/python.txt 453 2
cspell:python/src/common/extra.txt 741 2
cspell:php/php.txt 2597 2
cspell:npm/npm.txt 288 2
cspell:django/django.txt 859 2
cspell:csharp/csharp.txt 19 2
cspell:sql/src/tsql.txt 455 1
cspell:scala/scala.txt 833 1

Consider adding them using (in .github/workflows/spelling3.yml):

      with:
        extra_dictionaries:
          cspell:win32/src/win32.txt
          cspell:python/src/python/python-lib.txt
          cspell:python/src/python/python.txt
          cspell:python/src/common/extra.txt
          cspell:php/php.txt
          cspell:npm/npm.txt
          cspell:django/django.txt
          cspell:csharp/csharp.txt
          cspell:sql/src/tsql.txt
          cspell:scala/scala.txt

To stop checking additional dictionaries, add:

      with:
        check_extra_dictionaries: ''
Warnings (1)

See the 📜action log for details.

ℹ️ Warnings Count
ℹ️ unexpected-line-ending 4

See ℹ️ Event descriptions for more information.

If the flagged items are 🤯 false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it,
    try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

Please sign in to comment.