Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement package pinning #2813

Merged
merged 62 commits into from
Feb 9, 2023
Merged
Changes from 1 commit
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
92b78f6
Add pin index
florelis Dec 12, 2022
a24c0de
Complete pinning index; implement workflow tasks
florelis Dec 15, 2022
964a201
Apply suggestions from code review
florelis Dec 15, 2022
4cc9238
Merge branch 'master' into pinningImplementation
florelis Dec 15, 2022
27167a8
Spelling
florelis Dec 15, 2022
ad6d007
Add tests for pinning index
florelis Dec 15, 2022
f5ea9ce
Store version in all types of pins
florelis Dec 16, 2022
0055a1e
Merge branch 'master' into pinningImplementation
florelis Dec 16, 2022
0a48976
Tests for pin add
florelis Dec 20, 2022
2e8a057
Add more tests
florelis Dec 20, 2022
44123df
Handle pins and multiple sources in composite packages
florelis Dec 30, 2022
2c889fc
Fixes
florelis Dec 30, 2022
4c97b0d
Fix failing composite source tests
florelis Jan 3, 2023
83f27f4
Fix remaining failing tests
florelis Jan 3, 2023
93c0fa9
Typos & prevent unneeded op
florelis Jan 3, 2023
43653df
Add version gating
florelis Jan 3, 2023
035f949
Fix compilation errors
florelis Jan 3, 2023
dca6f92
PR comments
florelis Jan 3, 2023
4ffe0eb
Typo
florelis Jan 3, 2023
4af7d5d
Update src/AppInstallerCommonCore/Errors.cpp
florelis Jan 3, 2023
ec20b7f
Add --include-pinned argument
florelis Jan 3, 2023
dc42e4d
Resolve TODOs
florelis Jan 4, 2023
1a244f2
Add tests
florelis Jan 4, 2023
48f1961
Add more tests
florelis Jan 5, 2023
766aafa
Typo
florelis Jan 5, 2023
97b6fea
Apply suggestions from code review
florelis Jan 9, 2023
177ee73
PR comments
florelis Jan 10, 2023
9d63c89
Update src/AppInstallerRepositoryCore/Microsoft/Schema/Pinning_1_0/Pi…
florelis Jan 10, 2023
ef09f68
Apply suggestions from code review
florelis Jan 10, 2023
0aceec3
Spelling
florelis Jan 10, 2023
8f3d96b
PR comments
florelis Jan 10, 2023
19d87b1
Move log
florelis Jan 10, 2023
f452776
Open read only
florelis Jan 10, 2023
18ba330
Move openpinningindex
florelis Jan 10, 2023
cb25736
Merge branch 'master' into pinningImplementation
florelis Jan 10, 2023
1f6fe62
Catch errors when opening the pinning index
florelis Jan 10, 2023
533c2c9
Update tests after merging master
florelis Jan 10, 2023
d05cc63
Merge branch 'pinningImplementation' into pinningLogic
florelis Jan 10, 2023
51c25be
Fix errors from merge
florelis Jan 10, 2023
1ff27eb
Merge branch 'master' into pinningLogic
florelis Jan 12, 2023
395a9f3
Fix errors from merge
florelis Jan 12, 2023
88ef0f1
Update src/AppInstallerRepositoryCore/Microsoft/PinningIndex.cpp
florelis Jan 18, 2023
9f6f325
Apply suggestions from code review
florelis Jan 18, 2023
3fbb35b
Move ignoring pinned packages out of CompositePackage for better repo…
florelis Jan 25, 2023
b25c43f
Add more reporting around pinned packages
florelis Jan 25, 2023
3b28e60
Merge branch 'master' into pinningLogic
florelis Jan 25, 2023
9c5d03f
Show latest available for upgrade
florelis Jan 25, 2023
a7c4493
Add missing expected value
florelis Jan 28, 2023
2e656e8
Support --force argument
florelis Jan 28, 2023
f15df73
Remove code duplication
florelis Jan 28, 2023
6910211
Add e2e tests
florelis Jan 30, 2023
ea17640
Respect pins in dependencies
florelis Jan 30, 2023
8011710
Keep single available package if not using pinning
florelis Jan 30, 2023
a9c5644
Change search order for properties
florelis Jan 30, 2023
16cb8ad
Fix tests again...
florelis Jan 30, 2023
ea902ac
Fix test data file inclusion
florelis Jan 31, 2023
4b853f8
Use different product code for test zip installer
florelis Feb 6, 2023
676e7d9
Merge branch 'master' into pinningLogic
florelis Feb 6, 2023
21247a4
update -> upgrade; remove TODO
florelis Feb 7, 2023
90ff9b0
Update E2E tests
florelis Feb 7, 2023
c35e0d9
Fix whitespace
florelis Feb 7, 2023
1aa5369
PR comments
florelis Feb 8, 2023
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
Prev Previous commit
PR comments
florelis committed Feb 8, 2023
commit 1aa53697570d4ffd72e6bf90d79b26567104879c
2 changes: 1 addition & 1 deletion src/AppInstallerCLICore/Argument.cpp
Original file line number Diff line number Diff line change
@@ -152,7 +152,7 @@ namespace AppInstaller::CLI
case Execution::Args::Type::IncludePinned:
return { type, "include-pinned"_liv, "pinned"_liv, ArgTypeCategory::CopyFlagToSubContext };
case Execution::Args::Type::UninstallPrevious:
return { type, "uninstall-previous"_liv, ArgTypeCategory::InstallerBehavior };
return { type, "uninstall-previous"_liv, ArgTypeCategory::InstallerBehavior | ArgTypeCategory::CopyFlagToSubContext };

// Show command
case Execution::Args::Type::ListVersions:
73 changes: 47 additions & 26 deletions src/AppInstallerRepositoryCore/CompositeSource.cpp
Original file line number Diff line number Diff line change
@@ -375,22 +375,38 @@ namespace AppInstaller::Repository
{
CompositeAvailablePackage() {}
CompositeAvailablePackage(std::shared_ptr<IPackage> availablePackage, std::optional<Pinning::Pin> pin = {})
: AvailablePackage(availablePackage), Pin(pin)
: m_availablePackage(availablePackage), m_pin(pin)
{
auto latestAvailable = AvailablePackage->GetLatestAvailableVersion(PinBehavior::IgnorePins);
auto latestAvailable = m_availablePackage->GetLatestAvailableVersion(PinBehavior::IgnorePins);
if (latestAvailable)
{
SourceId = latestAvailable->GetSource().GetIdentifier();
m_sourceId = latestAvailable->GetSource().GetIdentifier();
}
}

std::string SourceId;
std::shared_ptr<IPackage> AvailablePackage;
std::optional<Pinning::Pin> Pin;
const std::string& GetSourceId() const
{
return m_sourceId;
}

const std::shared_ptr<IPackage>& GetAvailablePackage() const
{
return m_availablePackage;
}

const std::optional<Pinning::Pin>& GetPin() const
{
return m_pin;
}

void SetPin(Pinning::Pin&& pin)
{
m_pin = std::move(pin);
}

Utility::LocIndString GetProperty(PackageProperty property) const override
{
return AvailablePackage->GetProperty(property);
return m_availablePackage->GetProperty(property);
}

std::shared_ptr<IPackageVersion> GetInstalledVersion() const override
@@ -400,16 +416,16 @@ namespace AppInstaller::Repository

std::vector<PackageVersionKey> GetAvailableVersionKeys() const override
{
auto result = AvailablePackage->GetAvailableVersionKeys();
if (ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::Pinning) && Pin.has_value())
auto result = m_availablePackage->GetAvailableVersionKeys();
if (ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::Pinning) && m_pin.has_value())
{
for (auto& pvk : result)
{
if (Pin->GetType() == Pinning::PinType::Blocking ||
Pin->GetType() == Pinning::PinType::Pinning ||
(Pin->GetType() == Pinning::PinType::Gating && !Pin->GetGatedVersion().IsValidVersion(pvk.Version)))
if (m_pin->GetType() == Pinning::PinType::Blocking ||
m_pin->GetType() == Pinning::PinType::Pinning ||
(m_pin->GetType() == Pinning::PinType::Gating && !m_pin->GetGatedVersion().IsValidVersion(pvk.Version)))
{
pvk.PinnedState = Pin->GetType();
pvk.PinnedState = m_pin->GetType();
}
}
}
@@ -438,16 +454,16 @@ namespace AppInstaller::Repository
{
Pinning::PinType pinType = Pinning::PinType::Unknown;

if (ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::Pinning) && Pin.has_value())
if (ExperimentalFeature::IsEnabled(ExperimentalFeature::Feature::Pinning) && m_pin.has_value())
{
// A gating pin behaves the same as no pin when the version fits the gated version
if (!(pinType == Pinning::PinType::Gating && Pin->GetGatedVersion().IsValidVersion(versionKey.Version)))
if (!(pinType == Pinning::PinType::Gating && m_pin->GetGatedVersion().IsValidVersion(versionKey.Version)))
{
pinType = Pin->GetType();
pinType = m_pin->GetType();
}
}

return { AvailablePackage->GetAvailableVersion(versionKey), pinType };
return { m_availablePackage->GetAvailableVersion(versionKey), pinType };
}

bool IsUpdateAvailable(PinBehavior) const override
@@ -462,13 +478,18 @@ namespace AppInstaller::Repository
if (otherAvailable)
{
return
SourceId == otherAvailable->SourceId &&
Pin == otherAvailable->Pin &&
AvailablePackage->IsSame(otherAvailable->AvailablePackage.get());
m_sourceId == otherAvailable->m_sourceId &&
m_pin == otherAvailable->m_pin &&
m_availablePackage->IsSame(otherAvailable->m_availablePackage.get());
}

return false;
}

private:
std::string m_sourceId;
std::shared_ptr<IPackage> m_availablePackage;
std::optional<Pinning::Pin> m_pin;
};

// A composite package for the CompositeSource.
@@ -578,7 +599,7 @@ namespace AppInstaller::Repository
{
for (const auto& availablePackage : m_availablePackages)
{
if (!Utility::IsEmptyOrWhitespace(versionKey.SourceId) && versionKey.SourceId != availablePackage.SourceId)
if (!Utility::IsEmptyOrWhitespace(versionKey.SourceId) && versionKey.SourceId != availablePackage.GetSourceId())
{
continue;
}
@@ -621,8 +642,8 @@ namespace AppInstaller::Repository

for (size_t i = 0; i < m_availablePackages.size(); ++i)
{
if (m_availablePackages[i].SourceId != otherComposite->m_availablePackages[i].SourceId ||
!m_availablePackages[i].AvailablePackage->IsSame(otherComposite->m_availablePackages[i].AvailablePackage.get()))
if (m_availablePackages[i].GetSourceId() != otherComposite->m_availablePackages[i].GetSourceId() ||
!m_availablePackages[i].GetAvailablePackage()->IsSame(otherComposite->m_availablePackages[i].GetAvailablePackage().get()))
{
return false;
}
@@ -637,7 +658,7 @@ namespace AppInstaller::Repository
{
for (const auto& availablePackage : m_availablePackages)
{
if (other->IsSame(availablePackage.AvailablePackage.get()))
if (other->IsSame(availablePackage.GetAvailablePackage().get()))
{
return true;
}
@@ -686,13 +707,13 @@ namespace AppInstaller::Repository
// If the package is not installed, we clean up stale pin information here.
for (auto& availablePackage : m_availablePackages)
{
auto pinKey = GetPinKey(availablePackage.AvailablePackage.get());
auto pinKey = GetPinKey(availablePackage.GetAvailablePackage().get());
if (m_installedPackage)
{
auto pin = pinningIndex.GetPin(pinKey);
if (pin.has_value())
{
availablePackage.Pin = std::move(pin.value());
availablePackage.SetPin(std::move(pin.value()));
}
}
else if (pinningIndex.GetPin(pinKey) && cleanUpStalePins)