Skip to content

Commit 5a646a7

Browse files
authored
Better handling of min version merging in DependencyList (#4997)
[Cherry pick #4987 to 1.9] Likely fix for #4972 ## Change Use `std::optional` overloaded operator to handle all of the comparisons in `DependencyList::Add`. The operator already properly handles all of the cases, including treating `std::nullopt` as always less than a defined value. Also optimize a few other places around a reference to `MinVersion`.
1 parent d439036 commit 5a646a7

File tree

3 files changed

+73
-21
lines changed

3 files changed

+73
-21
lines changed

src/AppInstallerCLITests/Dependencies.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,66 @@ TEST_CASE("DependencyNodeProcessor_NoMatches", "[dependencies]")
209209
REQUIRE(installOutput.str().find(Resource::LocString(Resource::String::DependenciesFlowNoMatches)) != std::string::npos);
210210
REQUIRE(result == DependencyNodeProcessorResult::Error);
211211
}
212+
213+
TEST_CASE("DependencyList_Add_MinVersion", "[dependencies]")
214+
{
215+
DependencyType type = DependencyType::Package;
216+
std::string identifier = "Identifier";
217+
218+
DependencyList list;
219+
Dependency dependencyWithoutMinVersion{ type, identifier };
220+
Dependency dependencyWithLowerMinVersion{ type, identifier, "1.0" };
221+
Dependency dependencyWithHigherMinVersion{ type, identifier, "3.0" };
222+
223+
Dependency dependencyToAdd{ type, identifier, "2.0" };
224+
225+
SECTION("Existing dependency has no min version, added does")
226+
{
227+
list.Add(dependencyWithoutMinVersion);
228+
list.Add(dependencyToAdd);
229+
230+
const Dependency* dependency = list.HasDependency(dependencyToAdd);
231+
REQUIRE(dependency != nullptr);
232+
REQUIRE(dependency->MinVersion.has_value());
233+
REQUIRE(dependency->MinVersion == dependencyToAdd.MinVersion);
234+
}
235+
SECTION("Existing dependency has lower min version")
236+
{
237+
list.Add(dependencyWithLowerMinVersion);
238+
list.Add(dependencyToAdd);
239+
240+
const Dependency* dependency = list.HasDependency(dependencyToAdd);
241+
REQUIRE(dependency != nullptr);
242+
REQUIRE(dependency->MinVersion.has_value());
243+
REQUIRE(dependency->MinVersion == dependencyToAdd.MinVersion);
244+
}
245+
SECTION("Existing dependency has higher min version")
246+
{
247+
list.Add(dependencyWithHigherMinVersion);
248+
list.Add(dependencyToAdd);
249+
250+
const Dependency* dependency = list.HasDependency(dependencyToAdd);
251+
REQUIRE(dependency != nullptr);
252+
REQUIRE(dependency->MinVersion.has_value());
253+
REQUIRE(dependency->MinVersion == dependencyWithHigherMinVersion.MinVersion);
254+
}
255+
SECTION("Existing dependency has no min version, neither does added")
256+
{
257+
list.Add(dependencyWithoutMinVersion);
258+
list.Add(dependencyWithoutMinVersion);
259+
260+
const Dependency* dependency = list.HasDependency(dependencyToAdd);
261+
REQUIRE(dependency != nullptr);
262+
REQUIRE(!dependency->MinVersion.has_value());
263+
}
264+
SECTION("Existing dependency has min version, added does not")
265+
{
266+
list.Add(dependencyWithHigherMinVersion);
267+
list.Add(dependencyWithoutMinVersion);
268+
269+
const Dependency* dependency = list.HasDependency(dependencyToAdd);
270+
REQUIRE(dependency != nullptr);
271+
REQUIRE(dependency->MinVersion.has_value());
272+
REQUIRE(dependency->MinVersion == dependencyWithHigherMinVersion.MinVersion);
273+
}
274+
}

src/AppInstallerCommonCore/Manifest/ManifestCommon.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,22 +1113,11 @@ namespace AppInstaller::Manifest
11131113
{
11141114
Dependency* existingDependency = this->HasDependency(newDependency);
11151115

1116-
if (existingDependency != NULL) {
1117-
if (newDependency.MinVersion)
1116+
if (existingDependency != NULL)
1117+
{
1118+
if (newDependency.MinVersion > existingDependency->MinVersion)
11181119
{
1119-
if (existingDependency->MinVersion)
1120-
{
1121-
const auto& newDependencyVersion = Utility::Version(newDependency.MinVersion.value());
1122-
const auto& existingDependencyVersion = Utility::Version(existingDependency->MinVersion.value());
1123-
if (newDependencyVersion > existingDependencyVersion)
1124-
{
1125-
existingDependency->MinVersion.value() = newDependencyVersion.ToString();
1126-
}
1127-
}
1128-
else
1129-
{
1130-
existingDependency->MinVersion.value() = newDependency.MinVersion.value();
1131-
}
1120+
existingDependency->MinVersion = newDependency.MinVersion;
11321121
}
11331122
}
11341123
else
@@ -1168,15 +1157,15 @@ namespace AppInstaller::Manifest
11681157
}
11691158

11701159
// for testing purposes
1171-
bool DependencyList::HasExactDependency(DependencyType type, string_t id, string_t minVersion)
1160+
bool DependencyList::HasExactDependency(DependencyType type, const string_t& id, const string_t& minVersion)
11721161
{
11731162
for (const auto& dependency : m_dependencies)
11741163
{
11751164
if (dependency.Type == type && Utility::ICUCaseInsensitiveEquals(dependency.Id(), id))
11761165
{
11771166
if (!minVersion.empty())
11781167
{
1179-
return dependency.MinVersion.has_value() && dependency.MinVersion.value() == Utility::Version{ minVersion };
1168+
return dependency.MinVersion == Utility::Version{ minVersion };
11801169
}
11811170
else
11821171
{

src/AppInstallerCommonCore/Public/winget/ManifestCommon.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ namespace AppInstaller::Manifest
271271
const string_t& Id() const { return m_id; };
272272
std::optional<Utility::Version> MinVersion;
273273

274-
Dependency(DependencyType type, string_t id, string_t minVersion) : Type(type), m_id(std::move(id)), MinVersion(Utility::Version(minVersion)), m_foldedId(FoldCase(m_id)) {}
274+
Dependency(DependencyType type, string_t id, string_t minVersion) : Type(type), m_id(std::move(id)), MinVersion(Utility::Version(std::move(minVersion))), m_foldedId(FoldCase(m_id)) {}
275275
Dependency(DependencyType type, string_t id) : Type(type), m_id(std::move(id)), m_foldedId(FoldCase(m_id)){}
276276
Dependency(DependencyType type) : Type(type) {}
277277

@@ -285,9 +285,9 @@ namespace AppInstaller::Manifest
285285
return m_foldedId < rhs.m_foldedId;
286286
}
287287

288-
bool IsVersionOk(Utility::Version version)
288+
bool IsVersionOk(const Utility::Version& version)
289289
{
290-
return MinVersion <= Utility::Version(version);
290+
return MinVersion <= version;
291291
}
292292

293293
// m_foldedId should be set whenever Id is set
@@ -313,7 +313,7 @@ namespace AppInstaller::Manifest
313313
void ApplyToAll(std::function<void(const Dependency&)> func) const;
314314
bool Empty() const;
315315
void Clear();
316-
bool HasExactDependency(DependencyType type, string_t id, string_t minVersion = "");
316+
bool HasExactDependency(DependencyType type, const string_t& id, const string_t& minVersion = "");
317317
size_t Size();
318318

319319
private:

0 commit comments

Comments
 (0)