Add simple glob ignore patterns

This commit is contained in:
Andras Schmelczer 2025-05-22 21:41:59 +01:00
parent bbb2adce63
commit ceb217cda8
No known key found for this signature in database
GPG key ID: FC8F2C3D3D1A718C
8 changed files with 95 additions and 8 deletions

View file

@ -5,7 +5,7 @@ export {
type HistoryEntry
} from "./tracing/sync-history";
export { Logger, LogLevel, LogLine } from "./tracing/logger";
export { type SyncSettings } from "./persistence/settings";
export { type SyncSettings, DEFAULT_SETTINGS } from "./persistence/settings";
export { rateLimit } from "./utils/rate-limit";
export type { RelativePath, StoredDatabase } from "./persistence/database";
export type {

View file

@ -7,15 +7,17 @@ export interface SyncSettings {
syncConcurrency: number;
isSyncEnabled: boolean;
maxFileSizeMB: number;
ignorePatterns: string[];
}
const DEFAULT_SETTINGS: SyncSettings = {
export const DEFAULT_SETTINGS: SyncSettings = {
remoteUri: "",
token: "",
vaultName: "default",
syncConcurrency: 1,
isSyncEnabled: false,
maxFileSizeMB: 10
maxFileSizeMB: 10,
ignorePatterns: []
};
export class Settings {

View file

@ -16,8 +16,11 @@ import type { FileOperations } from "../file-operations/file-operations";
import { createPromise } from "../utils/create-promise";
import { FileNotFoundError } from "../file-operations/file-not-found-error";
import { SyncResetError } from "../services/sync-reset-error";
import { makeRe } from "minimatch";
export class UnrestrictedSyncer {
private ignorePatterns: RegExp[];
public constructor(
private readonly logger: Logger,
private readonly database: Database,
@ -25,7 +28,16 @@ export class UnrestrictedSyncer {
private readonly syncService: SyncService,
private readonly operations: FileOperations,
private readonly history: SyncHistory
) {}
) {
this.ignorePatterns = this.globsToRegex(
this.settings.getSettings().ignorePatterns
);
this.settings.addOnSettingsChangeListener((newSettings) => {
this.ignorePatterns = this.globsToRegex(newSettings.ignorePatterns);
});
}
public async unrestrictedSyncLocallyCreatedFile(
document: DocumentRecord
): Promise<void> {
@ -373,7 +385,14 @@ export class UnrestrictedSyncer {
syncType: SyncType,
fn: () => Promise<T>
): Promise<T | undefined> {
this.logger.debug(`Syncing ${relativePath} (${syncType})`);
for (const pattern of this.ignorePatterns) {
if (pattern.test(relativePath)) {
this.logger.debug(
`File '${relativePath}' is ignored by the ignore pattern: ${pattern}`
);
return; // bail without SKIPPED status because we were told to ignore this file and we shouldn't clutter up the history
}
}
try {
if (await this.operations.exists(relativePath)) {
@ -385,7 +404,7 @@ export class UnrestrictedSyncer {
if (sizeInMB > this.settings.getSettings().maxFileSizeMB) {
this.history.addHistoryEntry({
status: SyncStatus.ERROR,
status: SyncStatus.SKIPPED,
relativePath,
message: `File size of ${sizeInMB} MB exceeds the maximum file size limit of ${
this.settings.getSettings().maxFileSizeMB
@ -422,4 +441,18 @@ export class UnrestrictedSyncer {
}
}
}
private globsToRegex(globs: string[]): RegExp[] {
return globs
.map((pattern) => {
const result = makeRe(pattern);
if (result === false) {
this.logger.warn(
`Failed to parse ${pattern}' as a glob pattern, skipping it`
);
}
return result;
})
.filter((pattern) => pattern !== false);
}
}

View file

@ -16,7 +16,8 @@ export enum SyncType {
export enum SyncStatus {
SUCCESS = "SUCCESS",
ERROR = "ERROR"
ERROR = "ERROR",
SKIPPED = "SKIPPED"
}
export type HistoryEntry = CommonHistoryEntry & { timestamp: Date };