Compare commits
No commits in common. "f9106648287cdfe596ab24be7e1b96e7a6b28d75" and "520606ccb9f66aa6d38dc425704f77a3d6c90b23" have entirely different histories.
f910664828
...
520606ccb9
|
|
@ -1,12 +1,11 @@
|
||||||
import { afterEach, beforeEach, describe, expect, mock, test } from 'bun:test'
|
import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
|
||||||
import { mkdirSync, rmSync, writeFileSync } from 'fs'
|
import { mkdirSync, rmSync, writeFileSync } from 'fs'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { _resetGlobalCache, loadGitignore } from './gitignore'
|
import { loadGitignore } from './gitignore'
|
||||||
|
|
||||||
const TEST_DIR = '/tmp/toes-gitignore-test'
|
const TEST_DIR = '/tmp/toes-gitignore-test'
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
_resetGlobalCache()
|
|
||||||
mkdirSync(TEST_DIR, { recursive: true })
|
mkdirSync(TEST_DIR, { recursive: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -172,64 +171,4 @@ describe('loadGitignore', () => {
|
||||||
expect(checker.shouldExclude('build/output')).toBe(true)
|
expect(checker.shouldExclude('build/output')).toBe(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('global gitignore', () => {
|
|
||||||
const GLOBAL_IGNORE = '/tmp/toes-global-gitignore-test'
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
mkdirSync(GLOBAL_IGNORE, { recursive: true })
|
|
||||||
})
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
rmSync(GLOBAL_IGNORE, { recursive: true, force: true })
|
|
||||||
})
|
|
||||||
|
|
||||||
test('should include patterns from global gitignore', () => {
|
|
||||||
const globalIgnorePath = join(GLOBAL_IGNORE, 'ignore')
|
|
||||||
writeFileSync(globalIgnorePath, '*.bak\n.idea/')
|
|
||||||
|
|
||||||
const origSpawnSync = require('child_process').spawnSync
|
|
||||||
const spawnSyncMock = mock((cmd: string, args: string[], opts: any) => {
|
|
||||||
if (cmd === 'git' && args.includes('core.excludesFile')) {
|
|
||||||
return { status: 0, stdout: globalIgnorePath + '\n', stderr: '' }
|
|
||||||
}
|
|
||||||
return origSpawnSync(cmd, args, opts)
|
|
||||||
})
|
|
||||||
mock.module('child_process', () => ({ spawnSync: spawnSyncMock }))
|
|
||||||
_resetGlobalCache()
|
|
||||||
|
|
||||||
const checker = loadGitignore(TEST_DIR)
|
|
||||||
|
|
||||||
expect(checker.shouldExclude('backup.bak')).toBe(true)
|
|
||||||
expect(checker.shouldExclude('src/old.bak')).toBe(true)
|
|
||||||
expect(checker.shouldExclude('.idea')).toBe(true)
|
|
||||||
expect(checker.shouldExclude('src/index.ts')).toBe(false)
|
|
||||||
|
|
||||||
mock.module('child_process', () => ({ spawnSync: origSpawnSync }))
|
|
||||||
})
|
|
||||||
|
|
||||||
test('should merge global and local patterns', () => {
|
|
||||||
const globalIgnorePath = join(GLOBAL_IGNORE, 'ignore')
|
|
||||||
writeFileSync(globalIgnorePath, '*.bak')
|
|
||||||
writeFileSync(join(TEST_DIR, '.gitignore'), '*.log')
|
|
||||||
|
|
||||||
const origSpawnSync = require('child_process').spawnSync
|
|
||||||
const spawnSyncMock = mock((cmd: string, args: string[], opts: any) => {
|
|
||||||
if (cmd === 'git' && args.includes('core.excludesFile')) {
|
|
||||||
return { status: 0, stdout: globalIgnorePath + '\n', stderr: '' }
|
|
||||||
}
|
|
||||||
return origSpawnSync(cmd, args, opts)
|
|
||||||
})
|
|
||||||
mock.module('child_process', () => ({ spawnSync: spawnSyncMock }))
|
|
||||||
_resetGlobalCache()
|
|
||||||
|
|
||||||
const checker = loadGitignore(TEST_DIR)
|
|
||||||
|
|
||||||
expect(checker.shouldExclude('backup.bak')).toBe(true)
|
|
||||||
expect(checker.shouldExclude('debug.log')).toBe(true)
|
|
||||||
expect(checker.shouldExclude('src/index.ts')).toBe(false)
|
|
||||||
|
|
||||||
mock.module('child_process', () => ({ spawnSync: origSpawnSync }))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
import { spawnSync } from 'child_process'
|
|
||||||
import { existsSync, readFileSync } from 'fs'
|
import { existsSync, readFileSync } from 'fs'
|
||||||
import { homedir } from 'os'
|
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
|
|
||||||
const ALWAYS_EXCLUDE = [
|
const ALWAYS_EXCLUDE = [
|
||||||
'node_modules',
|
'node_modules',
|
||||||
'.sandlot',
|
|
||||||
'.DS_Store',
|
'.DS_Store',
|
||||||
'.git',
|
'.git',
|
||||||
'.toes',
|
'.toes',
|
||||||
|
|
@ -27,46 +24,15 @@ export interface GitignoreChecker {
|
||||||
|
|
||||||
export function loadGitignore(appPath: string): GitignoreChecker {
|
export function loadGitignore(appPath: string): GitignoreChecker {
|
||||||
const gitignorePath = join(appPath, '.gitignore')
|
const gitignorePath = join(appPath, '.gitignore')
|
||||||
const globalPatterns = loadGlobalPatterns()
|
|
||||||
const patterns = existsSync(gitignorePath)
|
const patterns = existsSync(gitignorePath)
|
||||||
? [...ALWAYS_EXCLUDE, ...globalPatterns, ...parseGitignore(readFileSync(gitignorePath, 'utf-8'))]
|
? [...ALWAYS_EXCLUDE, ...parseGitignore(readFileSync(gitignorePath, 'utf-8'))]
|
||||||
: [...DEFAULT_PATTERNS, ...globalPatterns]
|
: DEFAULT_PATTERNS
|
||||||
|
|
||||||
return {
|
return {
|
||||||
shouldExclude: (path: string) => matchesPattern(path, patterns),
|
shouldExclude: (path: string) => matchesPattern(path, patterns),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const _resetGlobalCache = () => {
|
|
||||||
cachedGlobalPatterns = undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
let cachedGlobalPatterns: string[] | undefined
|
|
||||||
|
|
||||||
const expandHome = (filepath: string) =>
|
|
||||||
filepath.startsWith('~/') ? join(homedir(), filepath.slice(2)) : filepath
|
|
||||||
|
|
||||||
function getGlobalExcludesPath(): string | null {
|
|
||||||
const result = spawnSync('git', ['config', '--global', 'core.excludesFile'], {
|
|
||||||
encoding: 'utf-8',
|
|
||||||
})
|
|
||||||
if (result.status === 0 && result.stdout.trim()) {
|
|
||||||
return expandHome(result.stdout.trim())
|
|
||||||
}
|
|
||||||
const xdgHome = process.env.XDG_CONFIG_HOME || join(homedir(), '.config')
|
|
||||||
const defaultPath = join(xdgHome, 'git', 'ignore')
|
|
||||||
if (existsSync(defaultPath)) return defaultPath
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadGlobalPatterns(): string[] {
|
|
||||||
if (cachedGlobalPatterns !== undefined) return cachedGlobalPatterns
|
|
||||||
const path = getGlobalExcludesPath()
|
|
||||||
cachedGlobalPatterns =
|
|
||||||
path && existsSync(path) ? parseGitignore(readFileSync(path, 'utf-8')) : []
|
|
||||||
return cachedGlobalPatterns
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseGitignore(content: string): string[] {
|
function parseGitignore(content: string): string[] {
|
||||||
return content
|
return content
|
||||||
.split('\n')
|
.split('\n')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user