winget-cli

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

Pin.h (4833B)


      1 // Copyright (c) Microsoft Corporation.
      2 // Licensed under the MIT License.
      3 #pragma once
      4 #include "winget/Manifest.h"
      5 #include "AppInstallerVersions.h"
      6 
      7 namespace AppInstaller::Pinning
      8 {
      9     // The pin types are ordered by how "strict" they are.
     10     // Meaning, the one that is more restrictive goes later.
     11     // This is used to decide which pin to report if there are multiple pins.
     12     enum class PinType : int64_t
     13     {
     14         // Unknown pin type or not pinned
     15         Unknown,
     16         // Pinned by the manifest using the RequiresExplicitUpgrade field.
     17         // Behaves the same as Pinning pins
     18         PinnedByManifest,
     19         // The package is excluded from 'upgrade --all', unless '--include-pinned' is added.
     20         // 'upgrade <package>' is not blocked.
     21         Pinning,
     22         // The package is pinned to a specific version range.
     23         Gating,
     24         // The package is blocked from 'upgrade --all' and 'upgrade <package>'.
     25         // User has to unblock to allow update.
     26         Blocking,
     27     };
     28 
     29     std::string_view ToString(PinType type);
     30     PinType ConvertToPinTypeEnum(std::string_view in);
     31 
     32     // Determines which of two pin types is more strict.
     33     bool IsStricter(PinType first, PinType second);
     34 
     35     // Returns the stricter of two pin types.
     36     PinType Stricter(PinType first, PinType second);
     37 
     38     // The set of values needed to uniquely identify a Pin.
     39     // A Pin can apply to an installed package or to an available package.
     40     // Pins on available packages can persist when an app is updated outside of winget,
     41     // but it's hard to have them work when there are multiple installed packages for the same available package.
     42     // Pins on installed packages work fine when there are multiple installed packages for the same available,
     43     // but they break when the package is updated outside of winget.
     44     struct PinKey
     45     {
     46         PinKey() = default;
     47         PinKey(const Manifest::Manifest::string_t& packageId, std::string_view sourceId)
     48             : PackageId(packageId), SourceId(sourceId) {}
     49 
     50         // Gets a pin key that refers to an installed package by its ProductCode or PackageFamilyName.
     51         // The sourceId used is a special string to distinguish from available packages.
     52         static PinKey GetPinKeyForInstalled(std::string_view systemReferenceString);
     53 
     54         bool IsForInstalled() const;
     55 
     56         bool operator==(const PinKey& other) const
     57         {
     58             return PackageId == other.PackageId
     59                 && SourceId == other.SourceId;
     60         }
     61 
     62         bool operator!=(const PinKey& other) const
     63         {
     64             return !(*this == other);
     65         }
     66 
     67         bool operator<(const PinKey& other) const
     68         {
     69             // std::tie implements tuple comparison, wherein it checks the first item in the tuple,
     70             // iff the first elements are equal, then the second element is used for comparison, and so on
     71             return std::tie(PackageId, SourceId) < std::tie(other.PackageId, other.SourceId);
     72         }
     73 
     74         // Used for logging
     75         std::string ToString() const;
     76 
     77         std::string PackageId;
     78         std::string SourceId;
     79     };
     80 
     81     struct Pin
     82     {
     83         Pin(const Pin&) = default;
     84         Pin& operator=(const Pin& other) = default;
     85 
     86         Pin(Pin&&) = default;
     87         Pin& operator=(Pin&&) = default;
     88 
     89         static Pin CreateBlockingPin(PinKey&& pinKey);
     90         static Pin CreatePinningPin(PinKey&& pinKey);
     91         static Pin CreateGatingPin(PinKey&& pinKey, Utility::GatedVersion&& gatedVersion);
     92 
     93         static Pin CreateBlockingPin(const PinKey& pinKey) { return CreateBlockingPin(PinKey{ pinKey }); }
     94         static Pin CreatePinningPin(const PinKey& pinKey) { return CreatePinningPin(PinKey{ pinKey }); }
     95         static Pin CreateGatingPin(const PinKey& pinKey, const Utility::GatedVersion& gatedVersion) { return CreateGatingPin(PinKey{ pinKey }, Utility::GatedVersion{ gatedVersion }); }
     96 
     97         PinType GetType() const { return m_type; }
     98         const PinKey& GetKey() const { return m_key; }
     99         const Utility::GatedVersion& GetGatedVersion() const { return m_gatedVersion; }
    100 
    101         bool operator==(const Pin& other) const;
    102         bool operator<(const Pin& other) const
    103         {
    104             return std::make_pair(m_type, m_key) < std::make_pair(other.m_type, other.m_key);
    105         }
    106 
    107         // Used for logging
    108         std::string ToString() const;
    109 
    110     private:
    111         Pin(PinType type, PinKey&& pinKey, Utility::GatedVersion&& gatedVersion = {})
    112             : m_type(type), m_key(std::move(pinKey)), m_gatedVersion(std::move(gatedVersion)) {}
    113 
    114         PinType m_type = PinType::Unknown;
    115         PinKey m_key;
    116         Utility::GatedVersion m_gatedVersion;
    117     };
    118 }