Skip to content
Merged
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
14 changes: 13 additions & 1 deletion doc/Settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,8 @@ You can enable the feature as shown below.
"openLogsArgument": true
},
```
### Dependencies

### dependencies

Experimental feature with the aim of managing dependencies, as of now it only shows package dependency information. You can enable the feature as shown below.

Expand All @@ -262,3 +263,14 @@ Experimental feature with the aim of managing dependencies, as of now it only sh
"dependencies": true
},
```

### pinning

This feature enables the ability to pin packages to prevent the Windows Package Manager from updating them.
You can enable the feature as shown below.

```json
"experimentalFeatures": {
"pinning": true
},
```
3 changes: 3 additions & 0 deletions src/AppInstallerCLICore/AppInstallerCLICore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@
<ClInclude Include="Commands\FeaturesCommand.h" />
<ClInclude Include="Commands\HashCommand.h" />
<ClInclude Include="Commands\ListCommand.h" />
<ClInclude Include="Commands\PinCommand.h" />
<ClInclude Include="Commands\SearchCommand.h" />
<ClInclude Include="Commands\ShowCommand.h" />
<ClInclude Include="Commands\InstallCommand.h" />
Expand Down Expand Up @@ -283,6 +284,7 @@
<ClInclude Include="Workflows\ImportExportFlow.h" />
<ClInclude Include="Workflows\MsiInstallFlow.h" />
<ClInclude Include="Workflows\MSStoreInstallerHandler.h" />
<ClInclude Include="Workflows\PinFlow.h" />
<ClInclude Include="Workflows\PortableFlow.h" />
<ClInclude Include="Workflows\PromptFlow.h" />
<ClInclude Include="Workflows\SettingsFlow.h" />
Expand All @@ -299,6 +301,7 @@
<ClCompile Include="COMContext.cpp" />
<ClCompile Include="Commands\COMCommand.cpp" />
<ClCompile Include="Commands\ImportCommand.cpp" />
<ClCompile Include="Commands\PinCommand.cpp" />
<ClCompile Include="ContextOrchestrator.cpp" />
<ClCompile Include="Workflows\DependenciesFlow.cpp" />
<ClCompile Include="PackageCollection.cpp" />
Expand Down
9 changes: 9 additions & 0 deletions src/AppInstallerCLICore/AppInstallerCLICore.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@
<ClInclude Include="PortableInstaller.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Commands\PinCommand.h">
<Filter>Commands</Filter>
</ClInclude>
<ClInclude Include="Workflows\PinFlow.h">
<Filter>Workflows</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
Expand Down Expand Up @@ -343,6 +349,9 @@
<ClCompile Include="PortableInstaller.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Commands\PinCommand.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="PropertySheet.props" />
Expand Down
243 changes: 243 additions & 0 deletions src/AppInstallerCLICore/Commands/PinCommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
#include "pch.h"
#include "PinCommand.h"
#include "Workflows/CompletionFlow.h"
#include "Workflows/PinFlow.h"
#include "Workflows/WorkflowBase.h"
#include "Resources.h"

namespace AppInstaller::CLI
{
using namespace AppInstaller::CLI::Execution;
using namespace AppInstaller::Utility::literals;
using namespace std::string_view_literals;

static constexpr std::string_view s_PinCommand_HelpLink = "https://aka.ms/winget-command-pin"sv;
Comment thread
florelis marked this conversation as resolved.

std::vector<std::unique_ptr<Command>> PinCommand::GetCommands() const
{
return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>({
std::make_unique<PinAddCommand>(FullName()),
std::make_unique<PinRemoveCommand>(FullName()),
std::make_unique<PinListCommand>(FullName()),
Comment thread
florelis marked this conversation as resolved.
std::make_unique<PinResetCommand>(FullName()),
});
}

Resource::LocString PinCommand::ShortDescription() const
{
return { Resource::String::PinCommandShortDescription };
}

Resource::LocString PinCommand::LongDescription() const
{
return { Resource::String::PinCommandLongDescription };
}

std::string PinCommand::HelpLink() const
{
return std::string{ s_PinCommand_HelpLink };
}

void PinCommand::ExecuteInternal(Execution::Context& context) const
{
OutputHelp(context.Reporter);
}

std::vector<Argument> PinAddCommand::GetArguments() const
{
return {
Argument::ForType(Args::Type::Query),
Argument::ForType(Args::Type::Id),
Argument::ForType(Args::Type::Name),
Argument::ForType(Args::Type::Moniker),
Argument::ForType(Args::Type::Tag),
Argument::ForType(Args::Type::Command),
Argument::ForType(Args::Type::Exact),
Argument{ "version"_liv, 'v', Args::Type::GatedVersion, Resource::String::GatedVersionArgumentDescription, ArgumentType::Standard },
Argument::ForType(Args::Type::Source),
Argument::ForType(Args::Type::CustomHeader),
Argument::ForType(Args::Type::AcceptSourceAgreements),
Argument::ForType(Args::Type::Force),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Curious what is the scenario for --force in pin add?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

The scenario I was thinking of is overwriting the pin. Like winget pin add Pkg adds a pin, then winget pin add Pkg --version 1.* would fail because it exists, but if you add --force, it overwrites it. But honestly, I just added it because it was in the spec and I was hoping you had a scenario in mind :D

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That makes sense. I guess I thought about it some time ago and now my memory does not serve me well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Even more curious - should --force be added to the list of generic arguments (like --wait and --verbose-logs)? In the worst case, it doesn't change the behavior, and in most cases it will remove a few lines of code.

Argument{ "blocking"_liv, Argument::NoAlias, Args::Type::BlockingPin, Resource::String::PinAddBlockingArgumentDescription, ArgumentType::Flag },
};
}

Resource::LocString PinAddCommand::ShortDescription() const
{
return { Resource::String::PinAddCommandShortDescription };
}

Resource::LocString PinAddCommand::LongDescription() const
{
return { Resource::String::PinAddCommandLongDescription };
}

void PinAddCommand::Complete(Execution::Context& context, Args::Type valueType) const
{
switch (valueType)
{
case Args::Type::Query:
case Args::Type::Id:
case Args::Type::Name:
case Args::Type::Moniker:
case Args::Type::Source:
context <<
Workflow::CompleteWithSingleSemanticsForValue(valueType);
break;
}
}

std::string PinAddCommand::HelpLink() const
{
return std::string{ s_PinCommand_HelpLink };
}

void PinAddCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const
{
if (execArgs.Contains(Execution::Args::Type::GatedVersion) && execArgs.Contains(Execution::Args::Type::BlockingPin))
{
throw CommandException(Resource::String::BothGatedVersionAndBlockingFlagProvided);
}

}

void PinAddCommand::ExecuteInternal(Execution::Context& context) const
{
// TODO
Command::ExecuteInternal(context);
}

std::vector<Argument> PinRemoveCommand::GetArguments() const
{
return {
Argument::ForType(Args::Type::Query),
Argument::ForType(Args::Type::Id),
Argument::ForType(Args::Type::Name),
Argument::ForType(Args::Type::Moniker),
Argument::ForType(Args::Type::Source),
Argument::ForType(Args::Type::Tag),
Argument::ForType(Args::Type::Command),
Argument::ForType(Args::Type::Exact),
Argument::ForType(Args::Type::CustomHeader),
Argument::ForType(Args::Type::AcceptSourceAgreements),
};
}

Resource::LocString PinRemoveCommand::ShortDescription() const
{
return { Resource::String::PinRemoveCommandShortDescription };
}

Resource::LocString PinRemoveCommand::LongDescription() const
{
return { Resource::String::PinRemoveCommandLongDescription };
}

void PinRemoveCommand::Complete(Execution::Context& context, Args::Type valueType) const
{
switch (valueType)
{
case Args::Type::Query:
case Args::Type::Id:
case Args::Type::Name:
case Args::Type::Moniker:
case Args::Type::Source:
context <<
Workflow::CompleteWithSingleSemanticsForValue(valueType);
break;
}
}

std::string PinRemoveCommand::HelpLink() const
{
return std::string{ s_PinCommand_HelpLink };
}

void PinRemoveCommand::ExecuteInternal(Execution::Context& context) const
{
// TODO
Command::ExecuteInternal(context);
}

std::vector<Argument> PinListCommand::GetArguments() const
{
return {
Argument::ForType(Args::Type::Query),
Argument::ForType(Args::Type::Id),
Argument::ForType(Args::Type::Name),
Argument::ForType(Args::Type::Moniker),
Argument::ForType(Args::Type::Source),
Argument::ForType(Args::Type::Tag),
Argument::ForType(Args::Type::Command),
Argument::ForType(Args::Type::Exact),
Argument::ForType(Args::Type::CustomHeader),
Argument::ForType(Args::Type::AcceptSourceAgreements),
};
}

Resource::LocString PinListCommand::ShortDescription() const
{
return { Resource::String::PinListCommandShortDescription };
}

Resource::LocString PinListCommand::LongDescription() const
{
return { Resource::String::PinListCommandLongDescription };
}

void PinListCommand::Complete(Execution::Context& context, Args::Type valueType) const
{
switch (valueType)
{
case Args::Type::Query:
case Args::Type::Id:
case Args::Type::Name:
case Args::Type::Moniker:
case Args::Type::Source:
context <<
Workflow::CompleteWithSingleSemanticsForValue(valueType);
break;
}
}

std::string PinListCommand::HelpLink() const
{
return std::string{ s_PinCommand_HelpLink };
}

void PinListCommand::ExecuteInternal(Execution::Context& context) const
{
// TODO
Command::ExecuteInternal(context);
}

std::vector<Argument> PinResetCommand::GetArguments() const
{
return {
Argument::ForType(Args::Type::Force),
};
}

Resource::LocString PinResetCommand::ShortDescription() const
{
return { Resource::String::PinResetCommandShortDescription };
}

Resource::LocString PinResetCommand::LongDescription() const
{
return { Resource::String::PinResetCommandLongDescription };
}

std::string PinResetCommand::HelpLink() const
{
return std::string{ s_PinCommand_HelpLink };
}

void PinResetCommand::ExecuteInternal(Execution::Context& context) const
{
// TODO
Command::ExecuteInternal(context);
}
}
Loading