From 64cc0c3f4f80b2a7cb7a27e8a1aa133364ee4e7a Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Wed, 12 Oct 2022 17:02:50 -0700 Subject: [PATCH 01/10] Create #476 - Package Pinning.md --- doc/specs/#476 - Package Pinning.md | 60 +++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 doc/specs/#476 - Package Pinning.md diff --git a/doc/specs/#476 - Package Pinning.md b/doc/specs/#476 - Package Pinning.md new file mode 100644 index 0000000000..f7dcfa80a9 --- /dev/null +++ b/doc/specs/#476 - Package Pinning.md @@ -0,0 +1,60 @@ +--- +author: Yao Sun yao-msft +created on: 2022-10-12 +last updated: 2022-10-12 +issue id: 476 +--- + +# Spec Title + +[comment]: # Link to issue: "For [#1](https://github.com/microsoft/winget-cli/issues/1)" + +## Abstract + +[comment]: # Outline what this spec describes + +## Inspiration + +[comment]: # What were the drivers/inspiration behind the creation of this spec. + +## Solution Design + +[comment]: # Outline the design of the solution. Feel free to include ASCII-art diagrams, etc. + +## UI/UX Design + +[comment]: # What will this fix/feature look like? How will it affect the end user? + +## Capabilities + +[comment]: # Discuss how the proposed fixes/features impact the following key considerations: + +### Accessibility + +[comment]: # How will the proposed change impact accessibility for users of screen readers, assistive input devices, etc. + +### Security + +[comment]: # How will the proposed change impact security? + +### Reliability + +[comment]: # Will the proposed change improve reliability? If not, why make the change? + +### Compatibility + +[comment]: # Will the proposed change break existing code/behaviors? If so, how, and is the breaking change "worth it"? + +### Performance, Power, and Efficiency + +## Potential Issues + +[comment]: # What are some of the things that might cause problems with the fixes/features proposed? Consider how the user might be negatively impacted. + +## Future considerations + +[comment]: # What are some of the things that the fixes/features might unlock in the future? Does the implementation of this spec enable scenarios? + +## Resources + +[comment]: # Be sure to add links to references, resources, footnotes, etc. From 356284ca7f8ec616a7fb52f22cae98126ad607b9 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Thu, 13 Oct 2022 12:53:59 -0700 Subject: [PATCH 02/10] Update #476 - Package Pinning.md --- doc/specs/#476 - Package Pinning.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/specs/#476 - Package Pinning.md b/doc/specs/#476 - Package Pinning.md index f7dcfa80a9..4c9460133a 100644 --- a/doc/specs/#476 - Package Pinning.md +++ b/doc/specs/#476 - Package Pinning.md @@ -1,21 +1,25 @@ --- -author: Yao Sun yao-msft +author: Yao Sun @yao-msft created on: 2022-10-12 last updated: 2022-10-12 issue id: 476 --- -# Spec Title +# Package Pinning -[comment]: # Link to issue: "For [#1](https://github.com/microsoft/winget-cli/issues/1)" +For [#476](https://github.com/microsoft/winget-cli/issues/476) ## Abstract -[comment]: # Outline what this spec describes +This spec describes the functionality and high level implementation design of Package Pinning feature. ## Inspiration -[comment]: # What were the drivers/inspiration behind the creation of this spec. +This is inspired by functionalities in other package managers, as well as community feedback. +- Packages may introduce breaking changes that users may not want integrate into their workflow quite yet. +- Packages may update themselves so that it will be duplicate effort for winget to try to update them. +- User may want to maintain some of the packages through other channels outside of winget, or prefer one source over others within winget. +- User may want some of the packages to stay in some major versions but allow minor version changes during upgrade. ## Solution Design From 7c66d6cf07cf832fb805ee2f9f28c803ebca3e7f Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Thu, 13 Oct 2022 13:51:44 -0700 Subject: [PATCH 03/10] Update #476 - Package Pinning.md --- doc/specs/#476 - Package Pinning.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/specs/#476 - Package Pinning.md b/doc/specs/#476 - Package Pinning.md index 4c9460133a..cad027dbde 100644 --- a/doc/specs/#476 - Package Pinning.md +++ b/doc/specs/#476 - Package Pinning.md @@ -23,7 +23,14 @@ This is inspired by functionalities in other package managers, as well as commun ## Solution Design -[comment]: # Outline the design of the solution. Feel free to include ASCII-art diagrams, etc. +To achieve goals listed above, winget will support 3 types of Package Pinning: +- **Blocking:** The package is blocked from `winget upgrade --all` or `winget upgrade `, user has to unblock the package to let winget perform upgrade. +- **Pinning:** The package is excluded from `winget upgrade --all` but allowed in `winget upgrade `, a new argument `--include-pinned` will be introduced to let `winget upgrade --all` to include pinned packages. +- **Gating:** The package is pinned to specific version(s). For example, if a package is pinned to version `1.2.*`, any version between `1.2.0` to `1.2.` is considered valid. + +To allow user override, `--force` can be used with `winget upgrade ` to override some of the pinning created above. + + ## UI/UX Design From 7cf48158927594bd48492201d2bffb5dd0d4cec5 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Mon, 17 Oct 2022 17:00:39 -0700 Subject: [PATCH 04/10] Update #476 - Package Pinning.md --- doc/specs/#476 - Package Pinning.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/specs/#476 - Package Pinning.md b/doc/specs/#476 - Package Pinning.md index cad027dbde..d8578fae76 100644 --- a/doc/specs/#476 - Package Pinning.md +++ b/doc/specs/#476 - Package Pinning.md @@ -23,6 +23,7 @@ This is inspired by functionalities in other package managers, as well as commun ## Solution Design +#### Package Pinning types To achieve goals listed above, winget will support 3 types of Package Pinning: - **Blocking:** The package is blocked from `winget upgrade --all` or `winget upgrade `, user has to unblock the package to let winget perform upgrade. - **Pinning:** The package is excluded from `winget upgrade --all` but allowed in `winget upgrade `, a new argument `--include-pinned` will be introduced to let `winget upgrade --all` to include pinned packages. @@ -30,6 +31,8 @@ To achieve goals listed above, winget will support 3 types of Package Pinning: To allow user override, `--force` can be used with `winget upgrade ` to override some of the pinning created above. +#### Package Pinning Configuration Storage + ## UI/UX Design From d0f97eb852394e6f9eedd6c0a3b8c59ba3ff2515 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Tue, 18 Oct 2022 12:11:53 -0700 Subject: [PATCH 05/10] Update #476 - Package Pinning.md --- doc/specs/#476 - Package Pinning.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/doc/specs/#476 - Package Pinning.md b/doc/specs/#476 - Package Pinning.md index d8578fae76..782a1d9714 100644 --- a/doc/specs/#476 - Package Pinning.md +++ b/doc/specs/#476 - Package Pinning.md @@ -33,37 +33,46 @@ To allow user override, `--force` can be used with `winget upgrade Date: Tue, 18 Oct 2022 14:02:45 -0700 Subject: [PATCH 06/10] Update #476 - Package Pinning.md --- doc/specs/#476 - Package Pinning.md | 102 +++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/doc/specs/#476 - Package Pinning.md b/doc/specs/#476 - Package Pinning.md index 782a1d9714..01a7013f1c 100644 --- a/doc/specs/#476 - Package Pinning.md +++ b/doc/specs/#476 - Package Pinning.md @@ -46,6 +46,106 @@ Microsoft.TestApp winget 1.2.* Gating #### winget pin commands +A new `winget pin` command with 3 sub-commands will be introduced. +- Add package pinning configuration: + + `winget pin add [--version ] [--source ] [--force] [--blocking]` + +- Remove package pinning configuration: + + `winget pin remove [--source ] [--force]` + +- List package pinning configuration: + + `winget pin list [--source ]` for a specific package or `winget pin list` to list all + +#### Blocking +To block a package from upgrade, use `winget pin add --blocking` +```text +cmd> winget pin Microsoft.TestApp --blocking +``` +Now the pinning configuration is recorded as +```text +PackageIdentifier SourceIdentifier Version PinningType +---------------------------------------------------------------------------- +Microsoft.TestApp winget Blocking +Microsoft.TestAppStore msstore Blocking +``` +**Note:** by default packages correlated from all sources are blocked, user can pass in `--source` to block for a specific source + +Corresponding upgrade behavior +```text +cmd> winget upgrade -all +Microsoft TestApp is blocked from upgrade and skipped + +cmd> winget upgrade Microsoft.TestApp +Microsoft TestApp is blocked from upgrade + +cmd> winget upgrade Microsoft.TestApp --force +Success +``` + +#### Pinning +To pin a package from `winget upgrade --all`, use `winget pin add ` +```text +cmd> winget pin Microsoft.TestApp +``` +Now the pinning configuration is recorded as +```text +PackageIdentifier SourceIdentifier Version PinningType +---------------------------------------------------------------------------- +Microsoft.TestApp winget Pinning +Microsoft.TestAppStore msstore Pinning +``` +**Note:** by default packages correlated from all sources are pinned, user can pass in `--source` to pin for a specific source + +Corresponding upgrade behavior +```text +cmd> winget upgrade -all +Microsoft TestApp is pinned from upgrade and skipped + +cmd> winget upgrade Microsoft.TestApp +Success +``` + +#### Gating +To gate a package to some specific version, use `winget pin add --version ` +```text +cmd> winget pin Microsoft.TestApp --version 1.2.* +``` +Now the pinning configuration is recorded as +```text +PackageIdentifier SourceIdentifier Version PinningType +---------------------------------------------------------------------------- +Microsoft.TestApp winget 1.2.* Gating +Microsoft.TestAppStore msstore 1.2.* Gating +``` +**Note:** by default packages correlated from all sources are gated, user can pass in `--source` to gate for a specific source + +Corresponding upgrade behavior +```text +cmd> winget upgrade -all +Success // If the available versions for upgrade are: 1.2.3 and 1.3.0, the selected version for upgrade is 1.2.3 + +cmd> winget upgrade Microsoft.TestApp +Success // If the available versions for upgrade are: 1.2.3 and 1.3.0, the selected version for upgrade is 1.2.3 + +cmd> winget upgrade Microsoft.TestApp --version 1.3.0 +Microsoft TestApp is gated to version 1.2.* Override with --force + +cmd> winget upgrade Microsoft.TestApp --version 1.3.0 --force +Success +``` + +**Note:** Regarding gated version syntax, it will be mostly same as what current winget version supports, except with special `.*` in the end as wild card matching any remaining version parts if there are any. + +Example: +`1.0.*` matches `1.0.1` +`1.0.*` matches `1.0` +`1.0.*` matches `1` +`1.0.*` matches `1.0.alpha` +`1.0.*` matches `1.0.1.2.3` +`1.0.*` does not match `1.1.1` ## Capabilities @@ -71,7 +171,7 @@ There should not be any notable performance changes. ## Potential Issues -- Installation/Upgrades from Com Apis may be impacted by user's package pinning configuration. It could be mitigated by returning a specific error code and the caller to retry with Force option. +- Installation/Upgrades from Com Apis may be impacted by user's package pinning configuration. It could be mitigated by returning a specific error code and the caller retrying with Force option. - Package dependencies resolution may be impacted by user's package pinning configuration. ## Future considerations From 1d8b3bf4f51f7a3dcda1b92b1af3729a81600fad Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Tue, 18 Oct 2022 14:18:45 -0700 Subject: [PATCH 07/10] Update #476 - Package Pinning.md --- doc/specs/#476 - Package Pinning.md | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/doc/specs/#476 - Package Pinning.md b/doc/specs/#476 - Package Pinning.md index 01a7013f1c..f05bbe33df 100644 --- a/doc/specs/#476 - Package Pinning.md +++ b/doc/specs/#476 - Package Pinning.md @@ -139,13 +139,24 @@ Success **Note:** Regarding gated version syntax, it will be mostly same as what current winget version supports, except with special `.*` in the end as wild card matching any remaining version parts if there are any. -Example: -`1.0.*` matches `1.0.1` -`1.0.*` matches `1.0` -`1.0.*` matches `1` -`1.0.*` matches `1.0.alpha` -`1.0.*` matches `1.0.1.2.3` -`1.0.*` does not match `1.1.1` +Example: +When `.*` in the end is detected +Gate version `1.0.*` matches Version `1.0.1` +Gate version `1.0.*` matches Version `1.0` +Gate version `1.0.*` matches Version `1` +Gate version `1.0.*` matches Version `1.0.alpha` +Gate version `1.0.*` matches Version `1.0.1.2.3` +Gate version `1.0.*` matches Version `1.0.*` +Gate version `1.0.*` does not match Version `1.1.1` + +In rare cases where `*` is actually part of a version, only the last `.*` is considered wild card: +Gate version `1.*.*` matches Version `1.*.1` +Gate version `1.*.*` matches Version `1.*.*` +Gate version `1.*.*` does not match Version `1.1.1` + +If no `.*` in the end is detected, the gate version gates to the specific version +Gate version `1.0.1` matches Version `1.0.1` +Gate version `1.0.1` does not match Version `1.1.1` ## Capabilities From d3b7f754ad7d3905f1db6e2c4f210e136cdba4e9 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Tue, 18 Oct 2022 14:47:48 -0700 Subject: [PATCH 08/10] Update #476 - Package Pinning.md --- doc/specs/#476 - Package Pinning.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/doc/specs/#476 - Package Pinning.md b/doc/specs/#476 - Package Pinning.md index f05bbe33df..a71ed5f977 100644 --- a/doc/specs/#476 - Package Pinning.md +++ b/doc/specs/#476 - Package Pinning.md @@ -140,7 +140,7 @@ Success **Note:** Regarding gated version syntax, it will be mostly same as what current winget version supports, except with special `.*` in the end as wild card matching any remaining version parts if there are any. Example: -When `.*` in the end is detected +When `.*` in the end is detected: Gate version `1.0.*` matches Version `1.0.1` Gate version `1.0.*` matches Version `1.0` Gate version `1.0.*` matches Version `1` @@ -154,7 +154,7 @@ Gate version `1.*.*` matches Version `1.*.1` Gate version `1.*.*` matches Version `1.*.*` Gate version `1.*.*` does not match Version `1.1.1` -If no `.*` in the end is detected, the gate version gates to the specific version +If no `.*` in the end is detected, the gate version gates to the specific version: Gate version `1.0.1` matches Version `1.0.1` Gate version `1.0.1` does not match Version `1.1.1` @@ -184,6 +184,7 @@ There should not be any notable performance changes. - Installation/Upgrades from Com Apis may be impacted by user's package pinning configuration. It could be mitigated by returning a specific error code and the caller retrying with Force option. - Package dependencies resolution may be impacted by user's package pinning configuration. +- Package imports may be impacted by user's package pinning configuration. ## Future considerations @@ -191,4 +192,9 @@ There should not be any notable performance changes. ## Resources -[comment]: # Be sure to add links to references, resources, footnotes, etc. +- [Brew - How do I stop certain formulae from being upgraded?](https://docs.brew.sh/FAQ#how-do-i-stop-certain-formulae-from-being-updated) +- [NPM - package.json dependencies](https://docs.npmjs.com/cli/v7/configuring-npm/package-json#dependencies) +- [APT - Introduction to Holding Packages](https://help.ubuntu.com/community/PinningHowto#Introduction_to_Holding_Packages) +- [Chocolatey - pin a package](https://docs.chocolatey.org/en-us/choco/commands/pin) + +Special thanks to [@jedieaston](https://github.com/jedieaston) for coming up with the initial draft of Package Pinning spec at [#1894](https://github.com/microsoft/winget-cli/pull/1894/). A lot has been discussed and this spec is much inspired from the draft. From 2b0c15f71fd8bab3810efbe7724705f3172aee1a Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Wed, 19 Oct 2022 13:14:00 -0700 Subject: [PATCH 09/10] Update #476 - Package Pinning.md --- doc/specs/#476 - Package Pinning.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/specs/#476 - Package Pinning.md b/doc/specs/#476 - Package Pinning.md index a71ed5f977..beb43083fe 100644 --- a/doc/specs/#476 - Package Pinning.md +++ b/doc/specs/#476 - Package Pinning.md @@ -188,7 +188,8 @@ There should not be any notable performance changes. ## Future considerations -[comment]: # What are some of the things that the fixes/features might unlock in the future? Does the implementation of this spec enable scenarios? +- Implementation in this spec only supports pinning from remote sources, so all installed versions from same package share the same pinning configuration. Winget could better support side by side installations by introducing package pinning from installed source. +- Package pinning from user and from manifest are stored separately, we may integrate the `winget pin` commands to control package pinning from manifests. ## Resources From 459cb45cc7a6c6bff7e200a8b9824a41791f30a3 Mon Sep 17 00:00:00 2001 From: yao-msft <50888816+yao-msft@users.noreply.github.com> Date: Wed, 19 Oct 2022 18:25:42 -0700 Subject: [PATCH 10/10] Update #476 - Package Pinning.md --- doc/specs/#476 - Package Pinning.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/specs/#476 - Package Pinning.md b/doc/specs/#476 - Package Pinning.md index beb43083fe..dfd69fd05d 100644 --- a/doc/specs/#476 - Package Pinning.md +++ b/doc/specs/#476 - Package Pinning.md @@ -190,6 +190,10 @@ There should not be any notable performance changes. - Implementation in this spec only supports pinning from remote sources, so all installed versions from same package share the same pinning configuration. Winget could better support side by side installations by introducing package pinning from installed source. - Package pinning from user and from manifest are stored separately, we may integrate the `winget pin` commands to control package pinning from manifests. +- A couple UI integrations can be made to `winget upgrade` and `winget list` to show pinned status during listing. +- Dependencies flow can be improved to first check pinned status of each dependant package before trying to install all dependencies. +- Support setting pinned state right after installation/upgrades like `winget install foo --pin`. +- Improvements to import export commands to work seamlessly with existing package pinning configurations. ## Resources