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
Show file tree
Hide file tree
Changes from 15 commits
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
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ INVALIDARG
INVALIDSID
iomanip
iostream
IPinning
IPortable
ipmo
ISAPPROVEDFOROUTPUT
Expand Down
1 change: 1 addition & 0 deletions src/AppInstallerCLICore/AppInstallerCLICore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@
<ClCompile Include="Workflows\ImportExportFlow.cpp" />
<ClCompile Include="Workflows\MsiInstallFlow.cpp" />
<ClCompile Include="Workflows\MSStoreInstallerHandler.cpp" />
<ClCompile Include="Workflows\PinFlow.cpp" />
<ClCompile Include="Workflows\PortableFlow.cpp" />
<ClCompile Include="Workflows\PromptFlow.cpp" />
<ClCompile Include="Workflows\SettingsFlow.cpp" />
Expand Down
5 changes: 4 additions & 1 deletion src/AppInstallerCLICore/AppInstallerCLICore.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,11 @@
<ClCompile Include="PortableInstaller.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Workflows\PinFlow.cpp">
<Filter>Workflows</Filter>
</ClCompile>
<ClCompile Include="Commands\PinCommand.cpp">
<Filter>Source Files</Filter>
<Filter>Commands</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
Expand Down
113 changes: 87 additions & 26 deletions src/AppInstallerCLICore/Commands/PinCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,26 @@ namespace AppInstaller::CLI

void PinAddCommand::Complete(Execution::Context& context, Args::Type valueType) const
{
context <<
Workflow::OpenSource() <<
Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);

switch (valueType)
{
case Args::Type::Query:
case Args::Type::Id:
case Args::Type::Name:
case Args::Type::Moniker:
case Args::Type::Source:
case Execution::Args::Type::Query:
context <<
Workflow::RequireCompletionWordNonEmpty <<
Workflow::SearchSourceForManyCompletion <<
Workflow::CompleteWithMatchedField;
break;
case Execution::Args::Type::Id:
case Execution::Args::Type::Name:
case Execution::Args::Type::Moniker:
case Execution::Args::Type::Source:
case Execution::Args::Type::Tag:
case Execution::Args::Type::Command:
context <<
Workflow::CompleteWithSingleSemanticsForValue(valueType);
Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType);
break;
}
}
Expand All @@ -105,8 +116,17 @@ namespace AppInstaller::CLI

void PinAddCommand::ExecuteInternal(Execution::Context& context) const
{
// TODO
Command::ExecuteInternal(context);
context <<
Workflow::OpenSource() <<
Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed) <<
Workflow::SearchSourceForSingle <<
Workflow::HandleSearchResultFailures <<
Workflow::EnsureOneMatchFromSearchResult(false) <<
Workflow::GetInstalledPackageVersion <<
Workflow::ReportPackageIdentity <<
Workflow::OpenPinningIndex <<
Workflow::SearchPin <<
Workflow::AddPin;
}

std::vector<Argument> PinRemoveCommand::GetArguments() const
Expand Down Expand Up @@ -137,15 +157,26 @@ namespace AppInstaller::CLI

void PinRemoveCommand::Complete(Execution::Context& context, Args::Type valueType) const
{
context <<
Workflow::OpenSource() <<
Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);

switch (valueType)
{
case Args::Type::Query:
case Args::Type::Id:
case Args::Type::Name:
case Args::Type::Moniker:
case Args::Type::Source:
case Execution::Args::Type::Query:
context <<
Workflow::CompleteWithSingleSemanticsForValue(valueType);
Workflow::RequireCompletionWordNonEmpty <<
Workflow::SearchSourceForManyCompletion <<
Workflow::CompleteWithMatchedField;
break;
case Execution::Args::Type::Id:
case Execution::Args::Type::Name:
case Execution::Args::Type::Moniker:
case Execution::Args::Type::Source:
case Execution::Args::Type::Tag:
case Execution::Args::Type::Command:
context <<
Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType);
break;
}
}
Expand All @@ -157,8 +188,17 @@ namespace AppInstaller::CLI

void PinRemoveCommand::ExecuteInternal(Execution::Context& context) const
{
// TODO
Command::ExecuteInternal(context);
context <<
Workflow::OpenSource() <<
Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed) <<
Workflow::SearchSourceForSingle <<
Workflow::HandleSearchResultFailures <<
Workflow::EnsureOneMatchFromSearchResult(false) <<
Workflow::GetInstalledPackageVersion <<
Workflow::ReportPackageIdentity <<
Workflow::OpenPinningIndex <<
Workflow::SearchPin <<
Workflow::RemovePin;
}

std::vector<Argument> PinListCommand::GetArguments() const
Expand Down Expand Up @@ -189,15 +229,26 @@ namespace AppInstaller::CLI

void PinListCommand::Complete(Execution::Context& context, Args::Type valueType) const
{
context <<
Workflow::OpenSource() <<
Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed);

switch (valueType)
{
case Args::Type::Query:
case Args::Type::Id:
case Args::Type::Name:
case Args::Type::Moniker:
case Args::Type::Source:
case Execution::Args::Type::Query:
context <<
Workflow::RequireCompletionWordNonEmpty <<
Workflow::SearchSourceForManyCompletion <<
Workflow::CompleteWithMatchedField;
break;
case Execution::Args::Type::Id:
case Execution::Args::Type::Name:
case Execution::Args::Type::Moniker:
case Execution::Args::Type::Source:
case Execution::Args::Type::Tag:
case Execution::Args::Type::Command:
context <<
Workflow::CompleteWithSingleSemanticsForValue(valueType);
Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType);
break;
}
}
Expand All @@ -209,8 +260,13 @@ namespace AppInstaller::CLI

void PinListCommand::ExecuteInternal(Execution::Context& context) const
{
// TODO
Command::ExecuteInternal(context);
context <<
Workflow::OpenPinningIndex <<
Workflow::GetAllPins <<
Workflow::OpenSource() <<
Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed) <<
Workflow::CrossReferencePinsWithSource <<
Workflow::ReportPins;
}

std::vector<Argument> PinResetCommand::GetArguments() const
Expand All @@ -237,7 +293,12 @@ namespace AppInstaller::CLI

void PinResetCommand::ExecuteInternal(Execution::Context& context) const
{
// TODO
Command::ExecuteInternal(context);
context <<
Workflow::OpenPinningIndex <<
Workflow::GetAllPins <<
Workflow::OpenSource() <<
Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed) <<
Workflow::CrossReferencePinsWithSource <<
florelis marked this conversation as resolved.
Show resolved Hide resolved
Workflow::ResetAllPins;
}
}
1 change: 1 addition & 0 deletions src/AppInstallerCLICore/ExecutionArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ namespace AppInstaller::CLI::Execution
// Upgrade command
All, // Used in Update command to update all installed packages to latest
IncludeUnknown, // Used in Upgrade command to allow upgrades of packages with unknown versions
IncludePinned, // Used in Upgrade command to allow upgrades to pinned packages (only for pinning type of pins)

// Show command
ListVersions, // Used in Show command to list all available versions of an app
Expand Down
19 changes: 19 additions & 0 deletions src/AppInstallerCLICore/ExecutionContextData.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <winget/RepositorySource.h>
#include <winget/Manifest.h>
#include <winget/ARPCorrelation.h>
#include <winget/Pin.h>
#include "CompletionData.h"
#include "PackageCollection.h"
#include "PortableInstaller.h"
Expand All @@ -16,6 +17,10 @@
#include <variant>
#include <vector>

namespace AppInstaller::Repository::Microsoft
{
struct PinningIndex;
}

namespace AppInstaller::CLI::Execution
{
Expand Down Expand Up @@ -55,6 +60,8 @@ namespace AppInstaller::CLI::Execution
AllowedArchitectures,
AllowUnknownScope,
PortableInstaller,
PinningIndex,
Pins,
Max
};

Expand Down Expand Up @@ -229,5 +236,17 @@ namespace AppInstaller::CLI::Execution
{
using value_t = CLI::Portable::PortableInstaller;
};

template <>
struct DataMapping<Data::PinningIndex>
{
using value_t = std::shared_ptr<Repository::Microsoft::PinningIndex>;
};

template <>
struct DataMapping<Data::Pins>
{
using value_t = std::vector<Pinning::Pin>;
};
}
}
10 changes: 10 additions & 0 deletions src/AppInstallerCLICore/Resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,14 +244,23 @@ namespace AppInstaller::CLI::Resource
WINGET_DEFINE_RESOURCE_STRINGID(PinAddBlockingArgumentDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinAddCommandLongDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinAddCommandShortDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinAdded);
WINGET_DEFINE_RESOURCE_STRINGID(PinAlreadyExists);
WINGET_DEFINE_RESOURCE_STRINGID(PinCommandLongDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinCommandShortDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinDoesNotExist);
WINGET_DEFINE_RESOURCE_STRINGID(PinExistsOverwriting);
WINGET_DEFINE_RESOURCE_STRINGID(PinExistsUseForceArg);
WINGET_DEFINE_RESOURCE_STRINGID(PinListCommandLongDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinListCommandShortDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinNoPinsExist);
WINGET_DEFINE_RESOURCE_STRINGID(PinRemoveCommandLongDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinRemoveCommandShortDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinResetCommandLongDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinResetCommandShortDescription);
WINGET_DEFINE_RESOURCE_STRINGID(PinResettingAll);
WINGET_DEFINE_RESOURCE_STRINGID(PinResetUseForceArg);
WINGET_DEFINE_RESOURCE_STRINGID(PinType);
WINGET_DEFINE_RESOURCE_STRINGID(PoliciesDisabled);
WINGET_DEFINE_RESOURCE_STRINGID(PoliciesEnabled);
WINGET_DEFINE_RESOURCE_STRINGID(PoliciesPolicy);
Expand Down Expand Up @@ -417,6 +426,7 @@ namespace AppInstaller::CLI::Resource
WINGET_DEFINE_RESOURCE_STRINGID(UpdateAllArgumentDescription);
WINGET_DEFINE_RESOURCE_STRINGID(UpdateNotApplicable);
WINGET_DEFINE_RESOURCE_STRINGID(UpgradeAvailableForPinned);
WINGET_DEFINE_RESOURCE_STRINGID(UpgradeBlockingPinCount);
WINGET_DEFINE_RESOURCE_STRINGID(UpgradeCommandLongDescription);
WINGET_DEFINE_RESOURCE_STRINGID(UpgradeCommandShortDescription);
WINGET_DEFINE_RESOURCE_STRINGID(UpgradeDifferentInstallTechnology);
Expand Down
4 changes: 2 additions & 2 deletions src/AppInstallerCLICore/Workflows/CompletionFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ namespace AppInstaller::CLI::Workflow
const std::string& word = context.Get<Data::CompletionData>().Word();
auto stream = context.Reporter.Completion();

for (const auto& vc : context.Get<Execution::Data::Package>()->GetAvailableVersionKeys())
for (const auto& vc : context.Get<Execution::Data::Package>()->GetAvailableVersionKeys(Repository::PinBehavior::IgnorePins))
{
if (word.empty() || Utility::ICUCaseInsensitiveStartsWith(vc.Version, word))
{
Expand All @@ -86,7 +86,7 @@ namespace AppInstaller::CLI::Workflow

std::vector<std::string> channels;

for (const auto& vc : context.Get<Execution::Data::Package>()->GetAvailableVersionKeys())
for (const auto& vc : context.Get<Execution::Data::Package>()->GetAvailableVersionKeys(Repository::PinBehavior::IgnorePins))
{
if ((word.empty() || Utility::ICUCaseInsensitiveStartsWith(vc.Channel, word)) &&
std::find(channels.begin(), channels.end(), vc.Channel) == channels.end())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace AppInstaller::CLI::Workflow
const auto& package = match.Package;
auto packageId = package->GetProperty(PackageProperty::Id);
m_nodePackageInstalledVersion = package->GetInstalledVersion();
m_nodePackageLatestVersion = package->GetLatestAvailableVersion();
m_nodePackageLatestVersion = package->GetLatestAvailableVersion(PinBehavior::ConsiderPins);
florelis marked this conversation as resolved.
Show resolved Hide resolved

if (m_nodePackageInstalledVersion && dependencyNode.IsVersionOk(Utility::Version(m_nodePackageInstalledVersion->GetProperty(PackageVersionProperty::Version))))
{
Expand Down
6 changes: 3 additions & 3 deletions src/AppInstallerCLICore/Workflows/ImportExportFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ namespace AppInstaller::CLI::Workflow
{
if (!checkVersion)
{
return package->GetLatestAvailableVersion();
return package->GetLatestAvailableVersion(PinBehavior::IgnorePins);
}

auto availablePackageVersion = package->GetAvailableVersion({ "", version, channel });
auto availablePackageVersion = package->GetAvailableVersion({ "", version, channel }, PinBehavior::IgnorePins);
if (!availablePackageVersion)
{
availablePackageVersion = package->GetLatestAvailableVersion();
availablePackageVersion = package->GetLatestAvailableVersion(PinBehavior::IgnorePins);
if (availablePackageVersion)
{
// Warn installed version is not available.
Expand Down
Loading