Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ Nothing yet.

## Bug Fixes

* None yet
* Refactored source type handling to use a `SourceType` enum with centralized string conversion, and added stronger `source add` type validation (#4463).
4 changes: 2 additions & 2 deletions src/AppInstallerCLICore/Commands/DscSourceResource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ namespace AppInstaller::CLI
{
Output.Exist(true);
Output.Argument(source.Arg);
Output.Type(source.Type);
Output.Type(std::string{ SourceTypeEnumToString(source.Type) });
Output.TrustLevel(TrustLevelStringFromFlags(source.TrustLevel));
Output.Explicit(source.Explicit);

Expand Down Expand Up @@ -495,7 +495,7 @@ namespace AppInstaller::CLI
SourceResourceObject output;
output.SourceName(source.Name);
output.Argument(source.Arg);
output.Type(source.Type);
output.Type(std::string{ SourceTypeEnumToString(source.Type) });
output.TrustLevel(TrustLevelStringFromFlags(source.TrustLevel));
output.Explicit(source.Explicit);

Expand Down
16 changes: 16 additions & 0 deletions src/AppInstallerCLICore/Commands/SourceCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,22 @@ namespace AppInstaller::CLI

void SourceAddCommand::ValidateArgumentsInternal(Args& execArgs) const
{
if (execArgs.Contains(Execution::Args::Type::SourceType))
{
std::string_view sourceTypeArg = execArgs.GetArg(Execution::Args::Type::SourceType);
auto validOptions = std::vector<Utility::LocIndString>{
Utility::LocIndString{ Repository::SourceTypeEnumToString(Repository::SourceType::PreIndexedPackage) },
Utility::LocIndString{ Repository::SourceTypeEnumToString(Repository::SourceType::Rest) } };

auto sourceType = Repository::TryConvertToSourceTypeEnum(sourceTypeArg);
bool isUserAddType = sourceType.has_value() &&
(sourceType.value() == Repository::SourceType::PreIndexedPackage || sourceType.value() == Repository::SourceType::Rest);
if (!isUserAddType)
{
throw CommandException(Resource::String::InvalidArgumentValueError(ArgumentCommon::ForType(Execution::Args::Type::SourceType).Name, Utility::Join(","_liv, validOptions)));
}
}

if (execArgs.Contains(Execution::Args::Type::SourceTrustLevel))
{
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ namespace AppInstaller::CLI::Configuration
{
if (Utility::CaseInsensitiveEquals(wellKnownSource.Name, source.Name) &&
Utility::CaseInsensitiveEquals(wellKnownSource.Arg, source.Arg) &&
Utility::CaseInsensitiveEquals(wellKnownSource.Type, source.Type))
Utility::CaseInsensitiveEquals(Repository::SourceTypeEnumToString(wellKnownSource.Type), source.Type))
{
return true;
}
Expand Down
6 changes: 4 additions & 2 deletions src/AppInstallerCLICore/PackageCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ namespace AppInstaller::CLI
sourceDetails.Identifier = Utility::LocIndString{ detailsNode[ss.PackagesJson_Source_Identifier].asString() };
sourceDetails.Name = detailsNode[ss.PackagesJson_Source_Name].asString();
sourceDetails.Arg = detailsNode[ss.PackagesJson_Source_Argument].asString();
sourceDetails.Type = detailsNode[ss.PackagesJson_Source_Type].asString();
auto sourceType = TryConvertToSourceTypeEnum(detailsNode[ss.PackagesJson_Source_Type].asString());
THROW_HR_IF(APPINSTALLER_CLI_ERROR_JSON_INVALID_FILE, !sourceType.has_value());
sourceDetails.Type = sourceType.value();

PackageCollection::Source source{ std::move(sourceDetails) };
for (const auto& packageNode : sourceNode[ss.PackagesJson_Packages])
Expand Down Expand Up @@ -238,7 +240,7 @@ namespace AppInstaller::CLI
sourceDetailsNode[ss.PackagesJson_Source_Name] = source.Details.Name;
sourceDetailsNode[ss.PackagesJson_Source_Argument] = source.Details.Arg;
sourceDetailsNode[ss.PackagesJson_Source_Identifier] = source.Details.Identifier;
sourceDetailsNode[ss.PackagesJson_Source_Type] = source.Details.Type;
sourceDetailsNode[ss.PackagesJson_Source_Type] = std::string{ SourceTypeEnumToString(source.Details.Type) };
sourceNode[ss.PackagesJson_Source_Details] = std::move(sourceDetailsNode);

sourceNode[ss.PackagesJson_Packages] = Json::Value{ Json::ValueType::arrayValue };
Expand Down
4 changes: 2 additions & 2 deletions src/AppInstallerCLICore/Workflows/ConfigurationFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1495,7 +1495,7 @@ namespace AppInstaller::CLI::Workflow

ConfigurationUnit CreateWinGetSourceUnit(const PackageCollection::Source& source, std::wstring_view unitType)
{
std::string sourceUnitId = source.Details.Name + '_' + source.Details.Type;
std::string sourceUnitId = source.Details.Name + '_' + std::string{ Repository::SourceTypeEnumToString(source.Details.Type) };
std::wstring sourceUnitIdWide = Utility::ConvertToUTF16(sourceUnitId);

ConfigurationUnit unit;
Expand All @@ -1512,7 +1512,7 @@ namespace AppInstaller::CLI::Workflow
ValueSet settings;
settings.Insert(s_Setting_WinGetSource_Name, PropertyValue::CreateString(Utility::ConvertToUTF16(source.Details.Name)));
settings.Insert(s_Setting_WinGetSource_Arg, PropertyValue::CreateString(Utility::ConvertToUTF16(source.Details.Arg)));
settings.Insert(s_Setting_WinGetSource_Type, PropertyValue::CreateString(Utility::ConvertToUTF16(source.Details.Type)));
settings.Insert(s_Setting_WinGetSource_Type, PropertyValue::CreateString(Utility::ConvertToUTF16(Repository::SourceTypeEnumToString(source.Details.Type))));
if (WI_IsFlagSet(source.Details.TrustLevel, Repository::SourceTrustLevel::Trusted))
{
settings.Insert(s_Setting_WinGetSource_TrustLevel, PropertyValue::CreateString(L"trusted"));
Expand Down
14 changes: 5 additions & 9 deletions src/AppInstallerCLICore/Workflows/SourceFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ namespace AppInstaller::CLI::Workflow
auto sourceList = context.Get<Execution::Data::SourceList>();
std::string_view name = context.Args.GetArg(Args::Type::SourceName);
std::string_view arg = context.Args.GetArg(Args::Type::SourceArg);
std::string_view type = context.Args.GetArg(Args::Type::SourceType);
Repository::SourceType type = Repository::TryConvertToSourceTypeEnum(context.Args.GetArg(Args::Type::SourceType)).value_or(Repository::Source::GetDefaultSourceType());

// In the absence of a specified type, the default is Microsoft.PreIndexed.Package for comparison.
// The default type assignment to the source takes place during the add operation (Source::Add in Repository.cpp).
Expand All @@ -59,10 +59,6 @@ namespace AppInstaller::CLI::Workflow
// For example, the following commands would be allowed, but they acts as different alias to same source:
// winget source add "mysource1" "https:\\mysource" --trust - level trusted
// winget source add "mysource2" "https:\\mysource" --trust - level trusted
if (type.empty())
{
type = Repository::Source::GetDefaultSourceType();
}

for (const auto& details : sourceList)
{
Expand All @@ -83,7 +79,7 @@ namespace AppInstaller::CLI::Workflow
}
}

if (!details.Arg.empty() && details.Arg == arg && details.Type == type)
if (!details.Arg.empty() && details.Arg == arg && type == details.Type)
{
context.Reporter.Error() << Resource::String::SourceAddAlreadyExistsDifferentName << std::endl <<
" "_liv << details.Name << " -> "_liv << details.Arg << std::endl;
Expand Down Expand Up @@ -118,7 +114,7 @@ namespace AppInstaller::CLI::Workflow
{
std::string_view name = context.Args.GetArg(Args::Type::SourceName);
std::string_view arg = context.Args.GetArg(Args::Type::SourceArg);
std::string_view type = context.Args.GetArg(Args::Type::SourceType);
Repository::SourceType type = Repository::TryConvertToSourceTypeEnum(context.Args.GetArg(Args::Type::SourceType)).value_or(Repository::Source::GetDefaultSourceType());

Repository::SourceTrustLevel trustLevel = Repository::SourceTrustLevel::None;
if (context.Args.Contains(Execution::Args::Type::SourceTrustLevel))
Expand Down Expand Up @@ -183,7 +179,7 @@ namespace AppInstaller::CLI::Workflow
Execution::TableOutput<2> table(context.Reporter, { Resource::String::SourceListField, Resource::String::SourceListValue });

table.OutputLine({ Resource::LocString(Resource::String::SourceListName), source.Name });
table.OutputLine({ Resource::LocString(Resource::String::SourceListType), source.Type });
table.OutputLine({ Resource::LocString(Resource::String::SourceListType), std::string{ Repository::SourceTypeEnumToString(source.Type) } });
table.OutputLine({ Resource::LocString(Resource::String::SourceListArg), source.Arg });
table.OutputLine({ Resource::LocString(Resource::String::SourceListData), source.Data });
table.OutputLine({ Resource::LocString(Resource::String::SourceListIdentifier), source.Identifier });
Expand Down Expand Up @@ -401,7 +397,7 @@ namespace AppInstaller::CLI::Workflow
{
SourceFromPolicy s;
s.Name = source.Name;
s.Type = source.Type;
s.Type = std::string{ Repository::SourceTypeEnumToString(source.Type) };
s.Arg = source.Arg;
s.Data = source.Data;
s.Identifier = source.Identifier;
Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCLITests/ARPChanges.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ struct ARPTestContext : public Context
};

// Inject our source
TestHook_SetSourceFactoryOverride(std::string{ Repository::Microsoft::PredefinedInstalledSourceFactory::Type() }, SourceFactory);
TestHook_SetSourceFactoryOverride(SourceType::PredefinedInstalled, SourceFactory);

Source = std::make_shared<TestSource>();
Source->SearchFunction = [&](const SearchRequest& request)
Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCLITests/CompositeSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ struct CompositeWithTrackingTestSetup : public CompositeTestSetup
CompositeWithTrackingTestSetup() : TrackingFactory([&](const SourceDetails&) { return Tracking; })
{
Tracking = std::make_shared<SQLiteIndexSource>(SourceDetails{}, SQLiteIndex::CreateNew(SQLITE_MEMORY_DB_CONNECTION_TARGET));
TestHook_SetSourceFactoryOverride(std::string{ PackageTrackingCatalogSourceFactory::Type() }, TrackingFactory);
TestHook_SetSourceFactoryOverride(SourceType::PackageTracking, TrackingFactory);
}

~CompositeWithTrackingTestSetup()
Expand Down
36 changes: 18 additions & 18 deletions src/AppInstallerCLITests/PackageCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ namespace
const auto& jsonSourceDetails = GetAndValidateJsonProperty(*jsonSourceItr, s_PackagesJson_Source_Details, Json::ValueType::objectValue);
ValidateJsonStringProperty(jsonSourceDetails, s_PackagesJson_Source_Name, sourceItr->Details.Name);
ValidateJsonStringProperty(jsonSourceDetails, s_PackagesJson_Source_Argument, sourceItr->Details.Arg);
ValidateJsonStringProperty(jsonSourceDetails, s_PackagesJson_Source_Type, sourceItr->Details.Type);
ValidateJsonStringProperty(jsonSourceDetails, s_PackagesJson_Source_Type, SourceTypeEnumToString(sourceItr->Details.Type));
ValidateJsonStringProperty(jsonSourceDetails, s_PackagesJson_Source_Identifier, sourceItr->Details.Identifier);

const auto& jsonPackages = GetAndValidateJsonProperty(*jsonSourceItr, s_PackagesJson_Packages, Json::ValueType::arrayValue);
Expand Down Expand Up @@ -137,7 +137,7 @@ TEST_CASE("PackageCollection_Write_SingleSource", "[PackageCollection]")
PackageCollection::Source source;
source.Details.Name = "TestSource";
source.Details.Arg = "https://aka.ms/winget";
source.Details.Type = "Microsoft.PreIndexed.Package";
source.Details.Type = SourceType::PreIndexedPackage;
source.Details.Identifier = "TestSourceId";

source.Packages.emplace_back(LocIndString{ "test.package1"sv }, Version{ "1.0.1" }, Channel{ "" });
Expand All @@ -157,14 +157,14 @@ TEST_CASE("PackageCollection_Write_MultipleSources", "[PackageCollection]")
PackageCollection::Source source1;
source1.Details.Name = "TestSource";
source1.Details.Arg = "https://aka.ms/winget";
source1.Details.Type = "Microsoft.PreIndexed.Package";
source1.Details.Type = SourceType::PreIndexedPackage;
source1.Details.Identifier = "TestSourceId";
source1.Packages.emplace_back(LocIndString{ "test.package1"sv }, Version{ "1.0.1" }, Channel{ "" });

PackageCollection::Source source2;
source2.Details.Name = "TestSource2";
source2.Details.Arg = "https://aka.ms/winget";
source2.Details.Type = "*Test";
source2.Details.Type = SourceType::ConfigurableTest;
source2.Details.Identifier = "SecondId";
source2.Packages.emplace_back(LocIndString{ "test.package2"sv }, Version{ "2.1.0" }, Channel{ "Beta" });

Expand All @@ -182,7 +182,7 @@ TEST_CASE("PackageCollection_Write_OverrideAndCustomSwitches", "[PackageCollecti
PackageCollection::Source source;
source.Details.Name = "TestSource";
source.Details.Arg = "https://aka.ms/winget";
source.Details.Type = "Microsoft.PreIndexed.Package";
source.Details.Type = SourceType::PreIndexedPackage;
source.Details.Identifier = "TestSourceId";

PackageCollection::Package packageWithOverride{ LocIndString{ "test.withOverride"sv }, Version{ "1.0" }, Channel{ "" } };
Expand Down Expand Up @@ -246,7 +246,7 @@ TEST_CASE("PackageCollection_Read_SingleSource_1_0", "[PackageCollection]")
PackageCollection::Source source;
source.Details.Name = "TestSource";
source.Details.Arg = "https://aka.ms/winget";
source.Details.Type = "Microsoft.PreIndexed.Package";
source.Details.Type = SourceType::PreIndexedPackage;
source.Details.Identifier = "TestSourceId";

source.Packages.emplace_back(LocIndString{ "test.WithVersion"sv }, Version{ "0.1" }, Channel{ "Preview" });
Expand Down Expand Up @@ -296,7 +296,7 @@ TEST_CASE("PackageCollection_Read_SingleSource_2_0", "[PackageCollection]")
PackageCollection::Source source;
source.Details.Name = "TestSource";
source.Details.Arg = "https://aka.ms/winget";
source.Details.Type = "Microsoft.PreIndexed.Package";
source.Details.Type = SourceType::PreIndexedPackage;
source.Details.Identifier = "TestSourceId";

source.Packages.emplace_back(LocIndString{ "test.WithVersion"sv }, Version{ "0.1" }, Channel{ "Preview" });
Expand Down Expand Up @@ -378,7 +378,7 @@ TEST_CASE("PackageCollection_WriteRead_OverrideAndCustomSwitches", "[PackageColl
PackageCollection::Source source;
source.Details.Name = "TestSource";
source.Details.Arg = "https://aka.ms/winget";
source.Details.Type = "Microsoft.PreIndexed.Package";
source.Details.Type = SourceType::PreIndexedPackage;
source.Details.Identifier = "TestSourceId";

PackageCollection::Package packageWithOverride{ LocIndString{ "test.withOverride"sv }, Version{ "1.0" }, Channel{ "" } };
Expand Down Expand Up @@ -437,7 +437,7 @@ TEST_CASE("PackageCollection_Read_MultipleSources_1_0", "[PackageCollection]")
"Argument": "//secondSource",
"Identifier": "Id2",
"Name": "Second",
"Type": "*TestSource"
"Type": "Microsoft.Test.Configurable"
},
"Packages": [
{
Expand All @@ -457,14 +457,14 @@ TEST_CASE("PackageCollection_Read_MultipleSources_1_0", "[PackageCollection]")
PackageCollection::Source source1;
source1.Details.Name = "First";
source1.Details.Arg = "//firstSource";
source1.Details.Type = "Microsoft.PreIndexed.Package";
source1.Details.Type = SourceType::PreIndexedPackage;
source1.Details.Identifier = "Id1";
source1.Packages.emplace_back(LocIndString{ "test"sv }, Version{ "" }, Channel{ "" });

PackageCollection::Source source2;
source2.Details.Name = "Second";
source2.Details.Arg = "//secondSource";
source2.Details.Type = "*TestSource";
source2.Details.Type = SourceType::ConfigurableTest;
source2.Details.Identifier = "Id2";
source2.Packages.emplace_back(LocIndString{ "test2"sv }, Version{ "1.0" }, Channel{ "" });

Expand Down Expand Up @@ -503,7 +503,7 @@ TEST_CASE("PackageCollection_Read_MultipleSources_2_0", "[PackageCollection]")
"Argument": "//secondSource",
"Identifier": "Id2",
"Name": "Second",
"Type": "*TestSource"
"Type": "Microsoft.Test.Configurable"
},
"Packages": [
{
Expand All @@ -523,14 +523,14 @@ TEST_CASE("PackageCollection_Read_MultipleSources_2_0", "[PackageCollection]")
PackageCollection::Source source1;
source1.Details.Name = "First";
source1.Details.Arg = "//firstSource";
source1.Details.Type = "Microsoft.PreIndexed.Package";
source1.Details.Type = SourceType::PreIndexedPackage;
source1.Details.Identifier = "Id1";
source1.Packages.emplace_back(LocIndString{ "test"sv }, Version{ "" }, Channel{ "" });

PackageCollection::Source source2;
source2.Details.Name = "Second";
source2.Details.Arg = "//secondSource";
source2.Details.Type = "*TestSource";
source2.Details.Type = SourceType::ConfigurableTest;
source2.Details.Identifier = "Id2";
source2.Packages.emplace_back(LocIndString{ "test2"sv }, Version{ "1.0" }, Channel{ "" });

Expand Down Expand Up @@ -569,7 +569,7 @@ TEST_CASE("PackageCollection_Read_RepeatedSource", "[PackageCollection]")
"Argument": "//secondSource",
"Identifier": "Id2",
"Name": "Second",
"Type": "*TestSource"
"Type": "Microsoft.Test.Configurable"
},
"Packages": [
{
Expand All @@ -583,7 +583,7 @@ TEST_CASE("PackageCollection_Read_RepeatedSource", "[PackageCollection]")
"Argument": "//secondSource",
"Identifier": "Id2",
"Name": "Second",
"Type": "*TestSource"
"Type": "Microsoft.Test.Configurable"
},
"Packages": [
{
Expand All @@ -603,14 +603,14 @@ TEST_CASE("PackageCollection_Read_RepeatedSource", "[PackageCollection]")
PackageCollection::Source source1;
source1.Details.Name = "First";
source1.Details.Arg = "//firstSource";
source1.Details.Type = "Microsoft.PreIndexed.Package";
source1.Details.Type = SourceType::PreIndexedPackage;
source1.Details.Identifier = "Id1";
source1.Packages.emplace_back(LocIndString{ "test"sv }, Version{ "" }, Channel{ "" });

PackageCollection::Source source2;
source2.Details.Name = "Second";
source2.Details.Arg = "//secondSource";
source2.Details.Type = "*TestSource";
source2.Details.Type = SourceType::ConfigurableTest;
source2.Details.Identifier = "Id2";
source2.Packages.emplace_back(LocIndString{ "test2"sv }, Version{ "1.0" }, Channel{ "" });
source2.Packages.emplace_back(LocIndString{ "test3"sv }, Version{ "1.2" }, Channel{ "" });
Expand Down
2 changes: 1 addition & 1 deletion src/AppInstallerCLITests/PackageTrackingCatalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace

details.Identifier = "*SimpleTestSetup";
details.Name = "TestName";
details.Type = "TestType";
details.Type = SourceType::ConfigurableTest;
details.Arg = testManifest.GetPath().parent_path().u8string();
details.Data = "";

Expand Down
Loading
Loading