PinCommand.cpp (12839B)
1 // Copyright (c) Microsoft Corporation. 2 // Licensed under the MIT License. 3 #include "pch.h" 4 #include "PinCommand.h" 5 #include "Workflows/CompletionFlow.h" 6 #include "Workflows/PinFlow.h" 7 #include "Workflows/WorkflowBase.h" 8 #include "Resources.h" 9 10 namespace AppInstaller::CLI 11 { 12 using namespace AppInstaller::CLI::Execution; 13 using namespace AppInstaller::CLI::Workflow; 14 using namespace AppInstaller::Utility::literals; 15 using namespace std::string_view_literals; 16 17 Utility::LocIndView s_PinCommand_HelpLink = "https://aka.ms/winget-command-pin"_liv; 18 19 std::vector<std::unique_ptr<Command>> PinCommand::GetCommands() const 20 { 21 return InitializeFromMoveOnly<std::vector<std::unique_ptr<Command>>>({ 22 std::make_unique<PinAddCommand>(FullName()), 23 std::make_unique<PinRemoveCommand>(FullName()), 24 std::make_unique<PinListCommand>(FullName()), 25 std::make_unique<PinResetCommand>(FullName()), 26 }); 27 } 28 29 Resource::LocString PinCommand::ShortDescription() const 30 { 31 return { Resource::String::PinCommandShortDescription }; 32 } 33 34 Resource::LocString PinCommand::LongDescription() const 35 { 36 return { Resource::String::PinCommandLongDescription }; 37 } 38 39 Utility::LocIndView PinCommand::HelpLink() const 40 { 41 return s_PinCommand_HelpLink; 42 } 43 44 void PinCommand::ExecuteInternal(Execution::Context& context) const 45 { 46 OutputHelp(context.Reporter); 47 } 48 49 std::vector<Argument> PinAddCommand::GetArguments() const 50 { 51 return { 52 Argument::ForType(Args::Type::Query), 53 Argument::ForType(Args::Type::Id), 54 Argument::ForType(Args::Type::Name), 55 Argument::ForType(Args::Type::Moniker), 56 Argument::ForType(Args::Type::Tag), 57 Argument::ForType(Args::Type::Command), 58 Argument::ForType(Args::Type::Exact), 59 Argument{ Args::Type::GatedVersion, Resource::String::GatedVersionArgumentDescription, ArgumentType::Standard }, 60 Argument::ForType(Args::Type::Source), 61 Argument::ForType(Args::Type::CustomHeader), 62 Argument::ForType(Args::Type::AuthenticationMode), 63 Argument::ForType(Args::Type::AuthenticationAccount), 64 Argument::ForType(Args::Type::AcceptSourceAgreements), 65 Argument::ForType(Args::Type::Force), 66 Argument{ Args::Type::BlockingPin, Resource::String::PinAddBlockingArgumentDescription, ArgumentType::Flag }, 67 Argument{ Args::Type::PinInstalled, Resource::String::PinInstalledArgumentDescription, ArgumentType::Flag }, 68 }; 69 } 70 71 Resource::LocString PinAddCommand::ShortDescription() const 72 { 73 return { Resource::String::PinAddCommandShortDescription }; 74 } 75 76 Resource::LocString PinAddCommand::LongDescription() const 77 { 78 return { Resource::String::PinAddCommandLongDescription }; 79 } 80 81 void PinAddCommand::Complete(Execution::Context& context, Args::Type valueType) const 82 { 83 context << 84 Workflow::OpenSource() << 85 Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed); 86 87 switch (valueType) 88 { 89 case Execution::Args::Type::Query: 90 context << 91 Workflow::RequireCompletionWordNonEmpty << 92 Workflow::SearchSourceForManyCompletion << 93 Workflow::CompleteWithMatchedField; 94 break; 95 case Execution::Args::Type::Id: 96 case Execution::Args::Type::Name: 97 case Execution::Args::Type::Moniker: 98 case Execution::Args::Type::Source: 99 case Execution::Args::Type::Tag: 100 case Execution::Args::Type::Command: 101 context << 102 Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType); 103 break; 104 } 105 } 106 107 Utility::LocIndView PinAddCommand::HelpLink() const 108 { 109 return s_PinCommand_HelpLink; 110 } 111 112 void PinAddCommand::ValidateArgumentsInternal(Execution::Args& execArgs) const 113 { 114 Argument::ValidateCommonArguments(execArgs); 115 } 116 117 void PinAddCommand::ExecuteInternal(Execution::Context& context) const 118 { 119 if (context.Args.Contains(Execution::Args::Type::Id)) 120 { 121 // When we are given an ID, just pin that available package without checking for installed. 122 // This helps when there are matching issues, for example due to multiple side-by-side installs. 123 context << 124 Workflow::OpenSource(); 125 } 126 else 127 { 128 // If not working from just ID, try matching a single installed package 129 context << 130 Workflow::OpenSource() << 131 Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed); 132 } 133 134 context << 135 Workflow::SearchSourceForSingle << 136 Workflow::HandleSearchResultFailures << 137 Workflow::EnsureOneMatchFromSearchResult(OperationType::Pin) << 138 Workflow::GetInstalledPackageVersion << 139 Workflow::ReportPackageIdentity << 140 Workflow::OpenPinningIndex() << 141 Workflow::AddPin; 142 } 143 144 std::vector<Argument> PinRemoveCommand::GetArguments() const 145 { 146 return { 147 Argument::ForType(Args::Type::Query), 148 Argument::ForType(Args::Type::Id), 149 Argument::ForType(Args::Type::Name), 150 Argument::ForType(Args::Type::Moniker), 151 Argument::ForType(Args::Type::Source), 152 Argument::ForType(Args::Type::Tag), 153 Argument::ForType(Args::Type::Command), 154 Argument::ForType(Args::Type::Exact), 155 Argument::ForType(Args::Type::CustomHeader), 156 Argument::ForType(Args::Type::AuthenticationMode), 157 Argument::ForType(Args::Type::AuthenticationAccount), 158 Argument::ForType(Args::Type::AcceptSourceAgreements), 159 Argument{ Args::Type::PinInstalled, Resource::String::PinInstalledArgumentDescription, ArgumentType::Flag }, 160 }; 161 } 162 163 Resource::LocString PinRemoveCommand::ShortDescription() const 164 { 165 return { Resource::String::PinRemoveCommandShortDescription }; 166 } 167 168 Resource::LocString PinRemoveCommand::LongDescription() const 169 { 170 return { Resource::String::PinRemoveCommandLongDescription }; 171 } 172 173 void PinRemoveCommand::Complete(Execution::Context& context, Args::Type valueType) const 174 { 175 context << 176 Workflow::OpenSource() << 177 Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed); 178 179 switch (valueType) 180 { 181 case Execution::Args::Type::Query: 182 context << 183 Workflow::RequireCompletionWordNonEmpty << 184 Workflow::SearchSourceForManyCompletion << 185 Workflow::CompleteWithMatchedField; 186 break; 187 case Execution::Args::Type::Id: 188 case Execution::Args::Type::Name: 189 case Execution::Args::Type::Moniker: 190 case Execution::Args::Type::Source: 191 case Execution::Args::Type::Tag: 192 case Execution::Args::Type::Command: 193 context << 194 Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType); 195 break; 196 } 197 } 198 199 Utility::LocIndView PinRemoveCommand::HelpLink() const 200 { 201 return s_PinCommand_HelpLink; 202 } 203 204 void PinRemoveCommand::ExecuteInternal(Execution::Context& context) const 205 { 206 if (context.Args.Contains(Execution::Args::Type::Id)) 207 { 208 // When we are given an ID, just un-pin that available package without checking for installed. 209 // This helps when there are matching issues, for example due to multiple side-by-side installs. 210 context << 211 Workflow::OpenSource(); 212 } 213 else 214 { 215 // If not working from just ID, try matching a single installed package 216 context << 217 Workflow::OpenSource() << 218 Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed); 219 } 220 221 context << 222 Workflow::SearchSourceForSingle << 223 Workflow::HandleSearchResultFailures << 224 Workflow::EnsureOneMatchFromSearchResult(OperationType::Pin) << 225 Workflow::GetInstalledPackageVersion << 226 Workflow::ReportPackageIdentity << 227 Workflow::OpenPinningIndex() << 228 Workflow::SearchPin << 229 Workflow::RemovePin; 230 } 231 232 std::vector<Argument> PinListCommand::GetArguments() const 233 { 234 return { 235 Argument::ForType(Args::Type::Query), 236 Argument::ForType(Args::Type::Id), 237 Argument::ForType(Args::Type::Name), 238 Argument::ForType(Args::Type::Moniker), 239 Argument::ForType(Args::Type::Source), 240 Argument::ForType(Args::Type::Tag), 241 Argument::ForType(Args::Type::Command), 242 Argument::ForType(Args::Type::Exact), 243 Argument::ForType(Args::Type::CustomHeader), 244 Argument::ForType(Args::Type::AuthenticationMode), 245 Argument::ForType(Args::Type::AuthenticationAccount), 246 Argument::ForType(Args::Type::AcceptSourceAgreements), 247 }; 248 } 249 250 Resource::LocString PinListCommand::ShortDescription() const 251 { 252 return { Resource::String::PinListCommandShortDescription }; 253 } 254 255 Resource::LocString PinListCommand::LongDescription() const 256 { 257 return { Resource::String::PinListCommandLongDescription }; 258 } 259 260 void PinListCommand::Complete(Execution::Context& context, Args::Type valueType) const 261 { 262 context << 263 Workflow::OpenSource() << 264 Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed); 265 266 switch (valueType) 267 { 268 case Execution::Args::Type::Query: 269 context << 270 Workflow::RequireCompletionWordNonEmpty << 271 Workflow::SearchSourceForManyCompletion << 272 Workflow::CompleteWithMatchedField; 273 break; 274 case Execution::Args::Type::Id: 275 case Execution::Args::Type::Name: 276 case Execution::Args::Type::Moniker: 277 case Execution::Args::Type::Source: 278 case Execution::Args::Type::Tag: 279 case Execution::Args::Type::Command: 280 context << 281 Workflow::CompleteWithSingleSemanticsForValueUsingExistingSource(valueType); 282 break; 283 } 284 } 285 286 Utility::LocIndView PinListCommand::HelpLink() const 287 { 288 return s_PinCommand_HelpLink; 289 } 290 291 void PinListCommand::ExecuteInternal(Execution::Context& context) const 292 { 293 context << 294 Workflow::OpenPinningIndex(/* readOnly */ true) << 295 Workflow::GetAllPins << 296 Workflow::OpenSource() << 297 Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed, false, Repository::CompositeSearchBehavior::AllPackages) << 298 Workflow::ReportPins; 299 } 300 301 std::vector<Argument> PinResetCommand::GetArguments() const 302 { 303 return { 304 Argument::ForType(Args::Type::Force), 305 Argument::ForType(Args::Type::Source), 306 }; 307 } 308 309 Resource::LocString PinResetCommand::ShortDescription() const 310 { 311 return { Resource::String::PinResetCommandShortDescription }; 312 } 313 314 Resource::LocString PinResetCommand::LongDescription() const 315 { 316 return { Resource::String::PinResetCommandLongDescription }; 317 } 318 319 Utility::LocIndView PinResetCommand::HelpLink() const 320 { 321 return s_PinCommand_HelpLink; 322 } 323 324 void PinResetCommand::ExecuteInternal(Execution::Context& context) const 325 { 326 327 if (context.Args.Contains(Execution::Args::Type::Force)) 328 { 329 context << 330 Workflow::OpenPinningIndex() << 331 Workflow::ResetAllPins; 332 } 333 else 334 { 335 AICLI_LOG(CLI, Info, << "--force argument is not present"); 336 context.Reporter.Info() << Resource::String::PinResetUseForceArg << std::endl; 337 338 context << 339 Workflow::OpenPinningIndex(/* readOnly */ true) << 340 Workflow::GetAllPins << 341 Workflow::OpenSource() << 342 Workflow::OpenCompositeSource(Repository::PredefinedSource::Installed) << 343 Workflow::ReportPins; 344 } 345 } 346 }