mirror of
https://github.com/nathonius/obsidian-github-link.git
synced 2026-07-22 09:20:25 +00:00
🐛 fix: Add migration mechanism for plugin data
This commit is contained in:
parent
50f2e7b14a
commit
d0aff85157
6 changed files with 40 additions and 30 deletions
|
|
@ -2,10 +2,12 @@ import { AppMock } from "./obsidian/App";
|
|||
import { PluginMock } from "./obsidian/Plugin";
|
||||
import { ModalMock } from "./obsidian/Modal";
|
||||
import { PluginSettingTabMock } from "./obsidian/PluginSettingTab";
|
||||
import { NoticeMock } from "./obsidian/Notice";
|
||||
|
||||
module.exports = {
|
||||
App: AppMock,
|
||||
Plugin: PluginMock,
|
||||
Modal: ModalMock,
|
||||
PluginSettingTab: PluginSettingTabMock,
|
||||
Notice: NoticeMock,
|
||||
};
|
||||
|
|
|
|||
13
__mocks__/obsidian/Notice.ts
Normal file
13
__mocks__/obsidian/Notice.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/* eslint-disable unused-imports/no-unused-vars */
|
||||
import type { Notice } from "obsidian";
|
||||
|
||||
export class NoticeMock implements Notice {
|
||||
constructor(message: string | DocumentFragment, duration?: number | undefined) {}
|
||||
noticeEl!: HTMLElement;
|
||||
setMessage(message: string | DocumentFragment): this {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
hide(): void {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import type { GithubLinkPluginSettings } from "./settings";
|
|||
import { DEFAULT_SETTINGS } from "./settings";
|
||||
import { CacheEntry, RequestCache } from "./github/cache";
|
||||
import { LogLevel } from "./logger";
|
||||
import { DATA_VERSION } from "./settings/types";
|
||||
|
||||
jest.mock("./settings/settings-tab");
|
||||
|
||||
|
|
@ -51,6 +52,7 @@ describe("GithubLinkPlugin", () => {
|
|||
expect(PluginData).toBeDefined();
|
||||
expect(PluginData.cache).toEqual(null);
|
||||
expect(PluginData.settings).toEqual(DEFAULT_SETTINGS);
|
||||
expect(PluginData.dataVersion).toEqual(DATA_VERSION);
|
||||
});
|
||||
|
||||
test("should load stored cache", async () => {
|
||||
|
|
@ -62,7 +64,7 @@ describe("GithubLinkPlugin", () => {
|
|||
null,
|
||||
);
|
||||
plugin = new GithubLinkPlugin(app, manifest);
|
||||
mockedPlugin(plugin).data = { cache: [cacheEntry.toJSON()] };
|
||||
mockedPlugin(plugin).data = { cache: [cacheEntry.toJSON()], dataVersion: DATA_VERSION };
|
||||
await plugin.onload();
|
||||
expect(PluginData.cache).toEqual([cacheEntry.toJSON()]);
|
||||
expect(getCache().get(cacheEntry.request)).toEqual(cacheEntry);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
import { Plugin } from "obsidian";
|
||||
import { Notice, Plugin } from "obsidian";
|
||||
import { DEFAULT_SETTINGS, GithubLinkPluginSettingsTab } from "./settings";
|
||||
import { Logger } from "./logger";
|
||||
|
||||
|
|
@ -9,9 +9,10 @@ import { InlineRenderer } from "./inline/inline";
|
|||
import { createInlineViewPlugin } from "./inline/view-plugin";
|
||||
import { RequestCache } from "./github/cache";
|
||||
import { QueryProcessor } from "./query/processor";
|
||||
import { DATA_VERSION } from "./settings/types";
|
||||
|
||||
export const PluginSettings: GithubLinkPluginSettings = { ...DEFAULT_SETTINGS };
|
||||
export const PluginData: GithubLinkPluginData = { cache: null, settings: PluginSettings };
|
||||
export const PluginData: GithubLinkPluginData = { cache: null, settings: PluginSettings, dataVersion: DATA_VERSION };
|
||||
export const logger = new Logger();
|
||||
let cache: RequestCache;
|
||||
export function getCache(): RequestCache {
|
||||
|
|
@ -21,31 +22,7 @@ export function getCache(): RequestCache {
|
|||
export class GithubLinkPlugin extends Plugin {
|
||||
public cacheInterval: number | undefined;
|
||||
async onload() {
|
||||
let data = (await this.loadData()) || {};
|
||||
|
||||
// Migrate settings from data root to settings -- remove in v1.0.0
|
||||
if (data.accounts) {
|
||||
const newSettings: GithubLinkPluginSettings = {
|
||||
accounts: data.accounts ?? PluginSettings.accounts,
|
||||
cacheIntervalSeconds: data.cacheIntervalSeconds ?? PluginSettings.cacheIntervalSeconds,
|
||||
defaultPageSize: data.defaultPageSize ?? PluginSettings.defaultPageSize,
|
||||
logLevel: data.logLevel ?? PluginSettings.logLevel,
|
||||
maxCacheAgeHours: data.maxCacheAgeHours ?? PluginSettings.maxCacheAgeHours,
|
||||
minRequestSeconds: data.minRequestSeconds ?? PluginSettings.minRequestSeconds,
|
||||
tagShowPRMergeable: data.tagShowPRMergeable ?? PluginSettings.tagShowPRMergeable,
|
||||
tagTooltips: data.tagTooltips ?? PluginSettings.tagTooltips,
|
||||
defaultAccount: data.defaultAccount ?? PluginSettings.defaultAccount,
|
||||
showPagination: data.showPagination ?? PluginSettings.showPagination,
|
||||
showRefresh: data.showRefresh ?? PluginSettings.showRefresh,
|
||||
showExternalLink: data.showExternalLink ?? PluginSettings.showExternalLink,
|
||||
};
|
||||
const newData: GithubLinkPluginData = {
|
||||
cache: data.cache ?? PluginData.cache,
|
||||
settings: newSettings,
|
||||
};
|
||||
await this.saveData(newData);
|
||||
data = newData;
|
||||
}
|
||||
const data = (await this.loadData()) || {};
|
||||
|
||||
Object.assign(PluginSettings, data.settings);
|
||||
Object.assign(PluginData, data);
|
||||
|
|
@ -53,12 +30,24 @@ export class GithubLinkPlugin extends Plugin {
|
|||
|
||||
cache = new RequestCache(PluginData.cache);
|
||||
|
||||
if (data.dataVersion === undefined || PluginData.dataVersion < DATA_VERSION) {
|
||||
// Always clear cache when data version changes
|
||||
const entriesDeleted = cache.clean(new Date());
|
||||
PluginData.cache = null;
|
||||
PluginData.dataVersion = DATA_VERSION;
|
||||
await this.saveData(PluginData);
|
||||
new Notice(
|
||||
`GitHub link data schema migrated to version ${DATA_VERSION}. Removed ${entriesDeleted} stored items from GitHub Link cache.`,
|
||||
3000,
|
||||
);
|
||||
}
|
||||
|
||||
// Clean cache
|
||||
const maxAge = new Date(new Date().getTime() - PluginSettings.maxCacheAgeHours * 60 * 60 * 1000);
|
||||
const entriesDeleted = cache.clean(maxAge);
|
||||
if (entriesDeleted > 0) {
|
||||
PluginData.cache = cache.toJSON();
|
||||
await this.saveData(PluginSettings);
|
||||
await this.saveData(PluginData);
|
||||
logger.info(`Cleaned ${entriesDeleted} entries from request cache.`);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type { GithubLinkPlugin } from "../plugin";
|
|||
import { LogLevel } from "../logger";
|
||||
import { PluginData, PluginSettings, getCache } from "../plugin";
|
||||
import type { GithubAccount, GithubLinkPluginData } from "./types";
|
||||
import { DEFAULT_SETTINGS } from "./types";
|
||||
import { DATA_VERSION, DEFAULT_SETTINGS } from "./types";
|
||||
import { AccountSettings } from "./account";
|
||||
|
||||
export class GithubLinkPluginSettingsTab extends PluginSettingTab {
|
||||
|
|
@ -283,6 +283,7 @@ export class GithubLinkPluginSettingsTab extends PluginSettingTab {
|
|||
const newData: GithubLinkPluginData = {
|
||||
cache: PluginData.cache,
|
||||
settings: PluginSettings,
|
||||
dataVersion: DATA_VERSION,
|
||||
};
|
||||
return this.plugin.saveData(newData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { LogLevel } from "../logger";
|
||||
|
||||
export const DATA_VERSION = 1;
|
||||
|
||||
export interface GithubAccount {
|
||||
id: string;
|
||||
name: string;
|
||||
|
|
@ -12,6 +14,7 @@ export interface GithubAccount {
|
|||
export interface GithubLinkPluginData {
|
||||
settings: GithubLinkPluginSettings;
|
||||
cache: string[] | null;
|
||||
dataVersion: number;
|
||||
}
|
||||
|
||||
export interface GithubLinkPluginSettings {
|
||||
|
|
|
|||
Loading…
Reference in a new issue