Move the shell history our of the project .gemini to the home dir (#1195)
This commit is contained in:
parent
7a419282c8
commit
ea63a8401e
|
@ -7,16 +7,30 @@
|
|||
import { renderHook, act, waitFor } from '@testing-library/react';
|
||||
import { useShellHistory } from './useShellHistory.js';
|
||||
import * as fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
vi.mock('fs/promises');
|
||||
vi.mock('os');
|
||||
vi.mock('crypto');
|
||||
|
||||
const MOCKED_PROJECT_ROOT = '/test/project';
|
||||
const MOCKED_HISTORY_DIR = path.join(MOCKED_PROJECT_ROOT, '.gemini');
|
||||
const MOCKED_HOME_DIR = '/test/home';
|
||||
const MOCKED_PROJECT_HASH = 'mocked_hash';
|
||||
|
||||
const MOCKED_HISTORY_DIR = path.join(
|
||||
MOCKED_HOME_DIR,
|
||||
'.gemini',
|
||||
'tmp',
|
||||
MOCKED_PROJECT_HASH,
|
||||
);
|
||||
const MOCKED_HISTORY_FILE = path.join(MOCKED_HISTORY_DIR, 'shell_history');
|
||||
|
||||
describe('useShellHistory', () => {
|
||||
const mockedFs = vi.mocked(fs);
|
||||
const mockedOs = vi.mocked(os);
|
||||
const mockedCrypto = vi.mocked(crypto);
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks();
|
||||
|
@ -24,6 +38,13 @@ describe('useShellHistory', () => {
|
|||
mockedFs.readFile.mockResolvedValue('');
|
||||
mockedFs.writeFile.mockResolvedValue(undefined);
|
||||
mockedFs.mkdir.mockResolvedValue(undefined);
|
||||
mockedOs.homedir.mockReturnValue(MOCKED_HOME_DIR);
|
||||
|
||||
const hashMock = {
|
||||
update: vi.fn().mockReturnThis(),
|
||||
digest: vi.fn().mockReturnValue(MOCKED_PROJECT_HASH),
|
||||
};
|
||||
mockedCrypto.createHash.mockReturnValue(hashMock as never);
|
||||
});
|
||||
|
||||
it('should initialize and read the history file from the correct path', async () => {
|
||||
|
|
|
@ -7,14 +7,13 @@
|
|||
import { useState, useEffect, useCallback } from 'react';
|
||||
import * as fs from 'fs/promises';
|
||||
import * as path from 'path';
|
||||
import { isNodeError } from '@gemini-cli/core';
|
||||
import { isNodeError, getProjectTempDir } from '@gemini-cli/core';
|
||||
|
||||
const HISTORY_DIR = '.gemini';
|
||||
const HISTORY_FILE = 'shell_history';
|
||||
const MAX_HISTORY_LENGTH = 100;
|
||||
|
||||
async function getHistoryFilePath(projectRoot: string): Promise<string> {
|
||||
const historyDir = path.join(projectRoot, HISTORY_DIR);
|
||||
const historyDir = getProjectTempDir(projectRoot);
|
||||
return path.join(historyDir, HISTORY_FILE);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,10 @@
|
|||
*/
|
||||
|
||||
import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import crypto from 'node:crypto';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import { Content } from '@google/genai';
|
||||
import { getProjectTempDir } from '../utils/paths.js';
|
||||
|
||||
const GEMINI_DIR = '.gemini';
|
||||
const TMP_DIR_NAME = 'tmp';
|
||||
const LOG_FILE_NAME = 'logs.json';
|
||||
const CHECKPOINT_FILE_NAME = 'checkpoint.json';
|
||||
|
||||
|
@ -99,17 +96,7 @@ export class Logger {
|
|||
return;
|
||||
}
|
||||
|
||||
const projectHash = crypto
|
||||
.createHash('sha256')
|
||||
.update(process.cwd())
|
||||
.digest('hex');
|
||||
|
||||
this.geminiDir = path.join(
|
||||
os.homedir(),
|
||||
GEMINI_DIR,
|
||||
TMP_DIR_NAME,
|
||||
projectHash,
|
||||
);
|
||||
this.geminiDir = getProjectTempDir(process.cwd());
|
||||
this.logFilePath = path.join(this.geminiDir, LOG_FILE_NAME);
|
||||
this.checkpointFilePath = path.join(this.geminiDir, CHECKPOINT_FILE_NAME);
|
||||
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
import * as fs from 'fs/promises';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import * as crypto from 'crypto';
|
||||
import { isNodeError } from '../utils/errors.js';
|
||||
import { isGitRepository } from '../utils/gitUtils.js';
|
||||
import { exec } from 'node:child_process';
|
||||
import { simpleGit, SimpleGit, CheckRepoActions } from 'simple-git';
|
||||
import { getProjectHash, GEMINI_DIR } from '../utils/paths.js';
|
||||
|
||||
export class GitService {
|
||||
private projectRoot: string;
|
||||
|
@ -21,11 +21,8 @@ export class GitService {
|
|||
}
|
||||
|
||||
private getHistoryDir(): string {
|
||||
const hash = crypto
|
||||
.createHash('sha256')
|
||||
.update(this.projectRoot)
|
||||
.digest('hex');
|
||||
return path.join(os.homedir(), '.gemini', 'history', hash);
|
||||
const hash = getProjectHash(this.projectRoot);
|
||||
return path.join(os.homedir(), GEMINI_DIR, 'history', hash);
|
||||
}
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
|
||||
import path from 'node:path';
|
||||
import os from 'os';
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
export const GEMINI_DIR = '.gemini';
|
||||
const TMP_DIR_NAME = 'tmp';
|
||||
|
||||
/**
|
||||
* Replaces the home directory with a tilde.
|
||||
|
@ -134,3 +138,22 @@ export function escapePath(filePath: string): string {
|
|||
export function unescapePath(filePath: string): string {
|
||||
return filePath.replace(/\\ /g, ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique hash for a project based on its root path.
|
||||
* @param projectRoot The absolute path to the project's root directory.
|
||||
* @returns A SHA256 hash of the project root path.
|
||||
*/
|
||||
export function getProjectHash(projectRoot: string): string {
|
||||
return crypto.createHash('sha256').update(projectRoot).digest('hex');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique temporary directory path for a project.
|
||||
* @param projectRoot The absolute path to the project's root directory.
|
||||
* @returns The path to the project's temporary directory.
|
||||
*/
|
||||
export function getProjectTempDir(projectRoot: string): string {
|
||||
const hash = getProjectHash(projectRoot);
|
||||
return path.join(os.homedir(), GEMINI_DIR, TMP_DIR_NAME, hash);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue