winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }