plugin: Update all and magpie plugin update bring a plugin pinned to an older version to npm's newest, so the update prompt clears (ARNO on Discord)
ARNO: 非官方插件安装后就算更新到最新版,magpie依然提示有更新. A third-party plugin added as name@1.2.3 is pinned. The Plugins page still counts it under "Update all (n)", its row says "vX out" and the Plugins dot is on. Update all (and `magpie plugin update`) reinstalled the pinned version, reported "Plugins updated", and the prompt stayed. The row's own Update already installs the newest version and unpins the spec (name@latest). Update now does the same for a pinned plugin when npm has a newer version than the one installed: it installs that version through add, which keeps the plugin's options and the provider picked for it. A pinned plugin that is already at npm's newest keeps its pin. Git plugins, folders and plugins npm didn't answer for behave as before. The plugin docs (en, zh, ja) now say that updating a pinned plugin yourself unpins it. Reproduced in a sandbox HOME with the real opencode-gemini-auth from npm (magpie web on a spare port, China mirror switch on and off). Pinned at 1.4.15 with 2.0.1 out: before the fix, Update all and `magpie plugin update` left it at 1.4.15 and /api/plugins/updates still listed it. After the fix it is at 2.0.1 as opencode-gemini-auth@latest, the waiting list is empty and Check for updates reports "current". The row's Update (upgrade) path was checked too: unpinned opencode-gemini-auth, and scoped @gitlab/opencode-gitlab-auth 1.3.1 -> 1.3.3 with the mirror on. Both cleared the prompt before the fix as well. TestUpdateAllUpdatesAPinnedPlugin (real bun, fake registry) fails without the change: "Update all left opencode-someones-auth at 1.0.0, want 2.0.0". gofmt -l, go vet (darwin, GOOS=linux, GOOS=windows) on internal/plugin, and go test -tags nogui of internal/plugin, internal/gui and internal/provider under a temp HOME with pinned caches all pass.
This commit is contained in:
1 parent
47a313f618
commit
ba0e2a8aa9
5 files changed
+85
-10
No files matched your search
@@ -476,22 +476,33 @@ func notPlugin(target string) error {
|
||||
return errors.New(why)
|
||||
}
|
||||
|
||||
// Update installs the version of each npm plugin its spec says now
|
||||
// (latest, for the most part: npm's newest, asked now, installAt), and
|
||||
// fetches each git one again.
|
||||
// Update installs npm's newest version (asked now, installAt) of each npm
|
||||
// plugin, and fetches each git one again. A plugin pinned to a version
|
||||
// that npm has a newer one of is updated too, and unpinned, as its row's
|
||||
// Update does: the page counts it in Update all, and the CLI's update
|
||||
// says it installs the newest of each (ARNO on Discord: a plugin updated
|
||||
// with Update all still said an update was out, pinned where it was). A
|
||||
// pinned one already at npm's newest stays as its spec says.
|
||||
func Update(ctx context.Context) error {
|
||||
var errs []error
|
||||
for _, e := range Load().Plugins {
|
||||
if !IsPath(e.Spec) {
|
||||
v := ""
|
||||
if !IsGit(e.Spec) && !Pinned(e.Spec) {
|
||||
if !IsGit(e.Spec) {
|
||||
v = newestOf(ctx, Name(e.Spec))
|
||||
}
|
||||
var err error
|
||||
if v != "" {
|
||||
switch {
|
||||
case v != "" && Pinned(e.Spec):
|
||||
if update.Newer(v, Installed(e.Spec)) {
|
||||
_, err = add(ctx, Name(e.Spec), v)
|
||||
} else {
|
||||
err = reinstall(ctx, e.Spec)
|
||||
}
|
||||
case v != "":
|
||||
err = installAt(ctx, Name(e.Spec), v)
|
||||
} else {
|
||||
// pinned, a git one, or npm not answering: as its spec says
|
||||
default:
|
||||
// a git one, or npm not answering: as its spec says
|
||||
err = reinstall(ctx, e.Spec)
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
@@ -163,3 +163,67 @@ func TestAgeText(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update all (and magpie plugin update) brings a plugin pinned to an older
|
||||
// version to npm's newest, unpinned, as its row's Update does: the page
|
||||
// counts it among the updates, and before, Update all installed the pinned
|
||||
// version again, said "Plugins updated", and the row still said the newer
|
||||
// one was out (ARNO on Discord: 非官方插件…更新到最新版,magpie依然提示有更新).
|
||||
// A pinned one already at npm's newest stays pinned.
|
||||
func TestUpdateAllUpdatesAPinnedPlugin(t *testing.T) {
|
||||
sandbox(t)
|
||||
const pkg = "opencode-someones-auth"
|
||||
heldRegistry(t, pkg, map[string]time.Time{"1.0.0": time.Now().Add(-72 * time.Hour), "2.0.0": time.Now().Add(-48 * time.Hour)}, "2.0.0")
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
if _, err := Add(ctx, pkg+"@1.0.0"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !Pinned(Load().Plugins[0].Spec) || Installed(pkg) != "1.0.0" {
|
||||
t.Fatalf("added %+v at %s, want it pinned at 1.0.0", Load().Plugins, Installed(pkg))
|
||||
}
|
||||
if err := Prefer(pkg, "someone"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := CheckUpdates(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if w := PendingUpdates().Waiting; len(w) != 1 || w[0].Latest != "2.0.0" {
|
||||
t.Fatalf("waiting before Update all = %+v, want 2.0.0", w)
|
||||
}
|
||||
|
||||
if err := Update(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if v := Installed(pkg); v != "2.0.0" {
|
||||
t.Fatalf("Update all left %s at %s, want 2.0.0", pkg, v)
|
||||
}
|
||||
l := Load()
|
||||
if len(l.Plugins) != 1 || l.Plugins[0].Spec != pkg+"@latest" {
|
||||
t.Fatalf("plugins after Update all = %+v, want %s@latest", l.Plugins, pkg)
|
||||
}
|
||||
if l.Prefer["someone"] != pkg+"@latest" {
|
||||
t.Fatalf("the provider picked for it = %q, want it kept on %s@latest", l.Prefer["someone"], pkg)
|
||||
}
|
||||
if w := PendingUpdates().Waiting; len(w) != 0 {
|
||||
t.Fatalf("still waiting after Update all: %+v", w)
|
||||
}
|
||||
if _, err := CheckUpdates(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if w := PendingUpdates().Waiting; len(w) != 0 {
|
||||
t.Fatalf("the next look found an update again: %+v", w)
|
||||
}
|
||||
|
||||
// pinned at the newest: Update all leaves its pin
|
||||
if _, err := Add(ctx, pkg+"@2.0.0"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := Update(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if l := Load().Plugins; len(l) != 1 || l[0].Spec != pkg+"@2.0.0" || Installed(pkg) != "2.0.0" {
|
||||
t.Fatalf("plugins = %+v at %s, want %s@2.0.0 kept", l, Installed(pkg), pkg)
|
||||
}
|
||||
}
|
||||
@@ -213,7 +213,7 @@ magpie quota <span class="c"># acme · Pro · 5h 37%
|
||||
<ul>
|
||||
<li>コミュニティのパッケージ(<code>@magpie-community/*</code>)は、magpie の起動から少し後に自動で更新され、その後は 6 時間ごとに更新されます。</li>
|
||||
<li>そのほかのパッケージは、新しいバージョンがあると <span class="ui">プラグイン</span> にドットが表示され、ユーザーがクリックか <code>magpie plugin update</code> で更新します。</li>
|
||||
<li>バージョンを固定した指定(<code>name@1.2.3</code>)はそのバージョンのままです。</li>
|
||||
<li>バージョンを固定した指定(<code>name@1.2.3</code>)は、ユーザーが更新するまでそのバージョンのままです。<span class="ui">… にアップデート</span>、<span class="ui">すべてアップデート</span>、<code>magpie plugin update</code> は最新版をインストールし、固定を外します。</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p>magpie が設定フォルダ(<code>~/.config/magpie</code> または <code>$XDG_CONFIG_HOME/magpie</code>)に保存するもの:</p>
|
||||
|
||||
@@ -213,7 +213,7 @@ magpie quota <span class="c"># acme · Pro · 5h 37%
|
||||
<ul>
|
||||
<li>The community’s packages (<code>@magpie-community/*</code>) update by themselves a little after magpie starts, then every six hours.</li>
|
||||
<li>Any other package with a newer version shows a dot on <span class="ui">Plugins</span>, and the user updates it with a click or <code>magpie plugin update</code>.</li>
|
||||
<li>A spec pinned to a version (<code>name@1.2.3</code>) stays on it.</li>
|
||||
<li>A spec pinned to a version (<code>name@1.2.3</code>) stays on it until the user updates it: <span class="ui">Update to …</span>, <span class="ui">Update all</span> and <code>magpie plugin update</code> install the newest version and unpin it.</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p>What magpie keeps, in its config folder (<code>~/.config/magpie</code>, or <code>$XDG_CONFIG_HOME/magpie</code>):</p>
|
||||
|
||||
@@ -213,7 +213,7 @@ magpie quota <span class="c"># acme · Pro · 5h 37%
|
||||
<ul>
|
||||
<li>社区的包(<code>@magpie-community/*</code>)在 magpie 启动后不久自动更新,之后每六小时一次。</li>
|
||||
<li>其他包有新版本时,<span class="ui">插件</span>上会出现一个小圆点,用户点一下或运行 <code>magpie plugin update</code> 更新。</li>
|
||||
<li>固定了版本的写法(<code>name@1.2.3</code>)会停在那个版本。</li>
|
||||
<li>固定了版本的写法(<code>name@1.2.3</code>)会停在那个版本,直到用户自己更新:<span class="ui">更新到 …</span>、<span class="ui">全部更新</span>和 <code>magpie plugin update</code> 会装上最新版并取消固定。</li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
<p>magpie 在它的配置目录(<code>~/.config/magpie</code> 或 <code>$XDG_CONFIG_HOME/magpie</code>)里保存这些:</p>
|
||||
|
||||
Reference in new issue
Block a user