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 }