mirror of
https://github.com/priyanshujain/margin-calendar.git
synced 2026-10-02 11:07:04 +00:00
announce updates rather than install them when a package manager owns the binary
This commit is contained in:
1 parent
ae5a7b4c0e
commit
958931f5ef
4 files changed
+79
-1
No files matched your search
@@ -0,0 +1,4 @@
|
||||
import { call } from "../ipc";
|
||||
|
||||
/** The package manager that owns this install, or null when the app updates itself. */
|
||||
export const packagedBy = () => call<string | null>("packaged_by");
|
||||
@@ -0,0 +1,51 @@
|
||||
// The one path where the updater must stand down: a package manager owns the binary, so a newer
|
||||
// version is announced and never installed over it.
|
||||
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
check: vi.fn(),
|
||||
relaunch: vi.fn(),
|
||||
notify: vi.fn(),
|
||||
call: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@tauri-apps/plugin-updater", () => ({ check: mocks.check }));
|
||||
vi.mock("@tauri-apps/plugin-process", () => ({ relaunch: mocks.relaunch }));
|
||||
vi.mock("../store/useToast", () => ({ notify: mocks.notify }));
|
||||
vi.mock("../ipc", () => ({ isDesktop: true, call: mocks.call }));
|
||||
|
||||
import { checkForUpdates } from "./updates";
|
||||
|
||||
const downloadAndInstall = vi.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
mocks.check.mockResolvedValue({ version: "0.0.5", downloadAndInstall });
|
||||
});
|
||||
|
||||
describe("checkForUpdates", () => {
|
||||
it("installs and relaunches when the app owns its own binary", async () => {
|
||||
mocks.call.mockResolvedValue(null);
|
||||
await checkForUpdates();
|
||||
expect(downloadAndInstall).toHaveBeenCalled();
|
||||
expect(mocks.relaunch).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("points at the package manager instead of installing over it", async () => {
|
||||
mocks.call.mockResolvedValue("nix");
|
||||
await checkForUpdates();
|
||||
expect(downloadAndInstall).not.toHaveBeenCalled();
|
||||
expect(mocks.relaunch).not.toHaveBeenCalled();
|
||||
expect(mocks.notify).toHaveBeenCalledWith(
|
||||
"0.0.5 is out. Update with: nix profile upgrade margin-calendar",
|
||||
);
|
||||
});
|
||||
|
||||
it("does not ask who owns the install when there is nothing newer", async () => {
|
||||
mocks.check.mockResolvedValue(null);
|
||||
await checkForUpdates();
|
||||
expect(mocks.call).not.toHaveBeenCalled();
|
||||
expect(mocks.notify).toHaveBeenCalledWith("Margin Calendar is up to date");
|
||||
});
|
||||
});
|
||||
@@ -4,11 +4,18 @@
|
||||
|
||||
import { relaunch } from "@tauri-apps/plugin-process";
|
||||
import { check } from "@tauri-apps/plugin-updater";
|
||||
import { packagedBy } from "../api/updates";
|
||||
import { isDesktop } from "../ipc";
|
||||
import { notify } from "../store/useToast";
|
||||
|
||||
let running = false;
|
||||
|
||||
/** A package manager owns the binary, so the update is announced and left to it. */
|
||||
function updateHint(manager: string, version: string): string {
|
||||
if (manager === "nix") return `${version} is out. Update with: nix profile upgrade margin-calendar`;
|
||||
return `${version} is out. Update it through ${manager}`;
|
||||
}
|
||||
|
||||
export async function checkForUpdates(): Promise<void> {
|
||||
if (!isDesktop || running) return;
|
||||
running = true;
|
||||
@@ -18,6 +25,11 @@ export async function checkForUpdates(): Promise<void> {
|
||||
notify("Margin Calendar is up to date");
|
||||
return;
|
||||
}
|
||||
const manager = await packagedBy();
|
||||
if (manager) {
|
||||
notify(updateHint(manager, update.version));
|
||||
return;
|
||||
}
|
||||
notify(`Installing ${update.version}…`);
|
||||
await update.downloadAndInstall();
|
||||
await relaunch();
|
||||
|
||||
Reference in new issue
Block a user