Skip to content

Commit

Permalink
test: basic caching function
Browse files Browse the repository at this point in the history
  • Loading branch information
yanthomasdev committed Sep 14, 2024
1 parent 70e39d0 commit 873fac3
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 20 deletions.
4 changes: 4 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { createPathResolver } from './files/paths.js';
import { LunariaGitInstance } from './status/git.js';
import { getDictionaryCompletion, isFileLocalizable } from './status/status.js';
import type { LunariaStatus, StatusLocalizationEntry } from './status/types.js';
import { useCache } from './status/cache.js';

// Additional data to ensure we can force rebuild the cache.
// Bump this whenever there are breaking changes to the status output.
Expand Down Expand Up @@ -130,6 +131,9 @@ export class Lunaria {
);
}

// Save the existing git data into the cache for next builds.
useCache(this.#config.cacheDir, 'git').write(this.#git.cache);

return status;
}

Expand Down
22 changes: 22 additions & 0 deletions packages/core/src/status/cache.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
import { join, resolve } from 'node:path';
import { jsonLoader } from '../files/loaders.js';

export function useCache(cacheDir: string, entry: string) {
const resolvedCacheDir = resolve(cacheDir);
const file = `${entry}.json`;

if (!existsSync(resolvedCacheDir)) {
mkdirSync(resolvedCacheDir, { recursive: true });
}

const cachePath = join(resolvedCacheDir, file);

return {
contents: existsSync(cachePath) ? jsonLoader(cachePath) : undefined,
write(contents: unknown) {
// TODO: Test with writeFile instead.
return writeFileSync(cachePath, JSON.stringify(contents));
},
};
}
49 changes: 30 additions & 19 deletions packages/core/src/status/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,62 @@ import type { ConsolaInstance } from 'consola';
import picomatch from 'picomatch';
import { type DefaultLogFields, type ListLogLine, simpleGit } from 'simple-git';
import type { LunariaConfig } from '../config/types.js';
import { FileCommitsNotFound, UncommittedFileFound } from '../errors/errors.js';
import { UncommittedFileFound } from '../errors/errors.js';
import type { RegExpGroups } from '../utils/types.js';
import { useCache } from './cache.js';
import type { FileGitData } from './types.js';

export class LunariaGitInstance {
#git = simpleGit({
maxConcurrentProcesses: Math.max(2, Math.min(32, cpus().length)),
});
#config: LunariaConfig;
#logger: ConsolaInstance;
cache: Record<string, FileGitData>;

constructor(config: LunariaConfig, logger: ConsolaInstance) {
this.#logger = logger;
this.#config = config;
this.cache = useCache(this.#config.cacheDir, 'git').contents ?? {};
}

// TODO: Try to cache the latest changes hash for each file so that you don't have to fetch the entire history every run, only new ones.
async #getFileHistory(path: string) {
try {
const log = await this.#git.log({
file: resolve(path),
strictDate: true,
});

return log;
} catch (e) {
this.#logger.error(FileCommitsNotFound.message(path));
throw e;
async getFileLatestChanges(path: string) {
const latestFileCommit = await this.#git.log({
file: resolve(path),
strictDate: true,
maxCount: 1,
});

console.log(latestFileCommit);

// The cache will keep the latest changes data, that means it will be able
// to completely skip the find for the latest changes if there are no new changes.
if (this.cache[path] && latestFileCommit?.latest?.hash === this.cache[path].latestChange.hash) {
return this.cache[path];
}
}

async getFileLatestChanges(path: string) {
const logHistory = await this.#getFileHistory(path);
const log = await this.#git.log({
file: resolve(path),
strictDate: true,
from: this.cache[path]?.latestTrackedChange?.hash,
});

const latestChange = logHistory.latest;
const latestChange = log.latest;
/**
* Edge case: it might be possible all the changes for a file have
* been purposefully ignored in Lunaria, therefore we need to define
* the latest change as the latest tracked change.
* TODO: Check if this is not an stupid assumption.
*/
const latestTrackedChange =
findLatestTrackedCommit(this.#config.tracking, path, logHistory.all) ?? latestChange;
findLatestTrackedCommit(this.#config.tracking, path, log.all) ?? latestChange;

if (!latestChange || !latestTrackedChange) {
this.#logger.error(UncommittedFileFound.message(path));
process.exit(1);
}

return {
const latestChanges = {
latestChange: {
date: latestChange.date,
message: latestChange.message,
Expand All @@ -64,6 +71,10 @@ export class LunariaGitInstance {
hash: latestTrackedChange.hash,
},
};

this.cache[path] = latestChanges;

return latestChanges;
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/status/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export type Dictionary = {
[k: string]: string | Dictionary;
};

type FileGitData = {
export type FileGitData = {
latestChange: {
message: string;
date: string;
Expand Down

0 comments on commit 873fac3

Please sign in to comment.