Skip to content

Commit

Permalink
feat: implement monorepo support (#8)
Browse files Browse the repository at this point in the history
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
AndreaPontrandolfo and antfu authored Feb 11, 2024
1 parent c65fc6d commit aadca59
Show file tree
Hide file tree
Showing 9 changed files with 207 additions and 9 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ gitignore({
})
```

By default, this plugin will try to look up the directory tree and match the first `.gitignore` file. You can disable this by setting the `root` option to `true`, or specify the `files` option to a specific path.

```js
gitignore({
root: true
})
```

## Sponsors

<p align="center">
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@
"prepublishOnly": "nr build",
"release": "bumpp && npm publish",
"start": "esno src/index.ts",
"test": "vitest",
"test": "vitest --pool=forks",
"typecheck": "tsc --noEmit",
"prepare": "simple-git-hooks"
},
"dependencies": {
"find-up": "^7.0.0",
"parse-gitignore": "^2.0.0"
},
"devDependencies": {
Expand Down
44 changes: 43 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 24 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,47 @@
import fs from 'node:fs'
import { findUpSync } from 'find-up'

// @ts-expect-error missing types
import parse from 'parse-gitignore'

export interface FlatGitignoreOptions {
/**
* Path to `.gitignore` files, or files with compatible formats like `.eslintignore`.
*/
files?: string | string[]
/**
* Throw an error if gitignore file not found.
*/
strict?: boolean
/**
* Mark the current working directory as the root directory,
* disable searching for `.gitignore` files in parent directories.
*
* This option is not effective when `files` is explicitly specified.
* @default false
*/
root?: boolean
}

export interface FlatConfigItem {
ignores: string[]
}

const GITIGNORE = '.gitignore' as const

export default function ignore(options: FlatGitignoreOptions = {}): FlatConfigItem {
const ignores: string[] = []

const {
files: _files = '.gitignore',
root = false,
files: _files = root ? GITIGNORE : findUpSync(GITIGNORE) || [],
strict = true,
} = options

const files = Array.isArray(_files) ? _files : [_files]

for (const file of files) {
let content: string
let content = ''
try {
content = fs.readFileSync(file, 'utf8')
}
Expand All @@ -41,6 +60,9 @@ export default function ignore(options: FlatGitignoreOptions = {}): FlatConfigIt
}
}

if (strict && files.length === 0)
throw new Error('No .gitignore file found')

return {
ignores,
}
Expand Down
10 changes: 5 additions & 5 deletions test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { describe, expect, it } from 'vitest'
import ignore from '../src/index'

describe('should', () => {
it('exported', () => {
expect(ignore())
describe('should execute tests in root folder', () => {
it('should find a gitignore file', () => {
expect(ignore({ root: true }))
.toMatchInlineSnapshot(`
{
"ignores": [
Expand Down Expand Up @@ -37,12 +37,12 @@ describe('should', () => {
})

it('strict (default) throw', () => {
expect(() => ignore({ files: 'not-exists' }))
expect(() => ignore({ files: 'not-exists', root: true }))
.toThrow()
})

it('not strict skip missing file', () => {
expect(ignore({ files: 'not-exists', strict: false }))
expect(ignore({ files: 'not-exists', strict: false, root: true }))
.toMatchInlineSnapshot(`
{
"ignores": [],
Expand Down
56 changes: 56 additions & 0 deletions test/workspace-with-gitignore.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { describe, expect, it } from 'vitest'
import ignore from '../src/index'

describe('should execute tests in test/workspace-with-gitignore', () => {
process.chdir('test/workspace-with-gitignore')

it('should find a gitignore file', () => {
expect(ignore())
.toMatchInlineSnapshot(`
{
"ignores": [
"gitignoretest",
"**/gitignoretest/**",
],
}
`)
})

it('strict (default) throw', () => {
expect(() => ignore({ files: 'not-exists', root: true }))
.toThrow()
})

it('not strict skip missing file', () => {
expect(ignore({ files: 'not-exists', strict: false, root: true }))
.toMatchInlineSnapshot(`
{
"ignores": [],
}
`)
})

it('should find a gitignore file in cwd', () => {
expect(ignore({ root: true }))
.toMatchInlineSnapshot(`
{
"ignores": [
"gitignoretest",
"**/gitignoretest/**",
],
}
`)
})

it('dont fallback to root, strict and return empty array', () => {
expect(ignore({ strict: false, root: true }))
.toMatchInlineSnapshot(`
{
"ignores": [
"gitignoretest",
"**/gitignoretest/**",
],
}
`)
})
})
1 change: 1 addition & 0 deletions test/workspace-with-gitignore/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gitignoretest
68 changes: 68 additions & 0 deletions test/workspace-without-gitignore.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { describe, expect, it } from 'vitest'
import ignore from '../src/index'

describe('should execute tests in test/workspace-without-gitignore', () => {
process.chdir('test/workspace-without-gitignore')

it('should find a gitignore file', () => {
expect(ignore())
.toMatchInlineSnapshot(`
{
"ignores": [
".cache",
"**/.cache/**",
".DS_Store",
"**/.DS_Store/**",
".idea",
"**/.idea/**",
"*.log",
"**/*.log/**",
"*.tgz",
"**/*.tgz/**",
"coverage",
"**/coverage/**",
"dist",
"**/dist/**",
"lib-cov",
"**/lib-cov/**",
"logs",
"**/logs/**",
"node_modules",
"**/node_modules/**",
"temp",
"**/temp/**",
"!temp/.gitkeep",
"!temp/.gitkeep/**",
],
}
`)
})

it('strict (default) throw', () => {
expect(() => ignore({ files: 'not-exists', root: true }))
.toThrow()
})

it('not strict skip missing file', () => {
expect(ignore({ files: 'not-exists', strict: false, root: true }))
.toMatchInlineSnapshot(`
{
"ignores": [],
}
`)
})

it('dont fallback to root, strict and throw error', () => {
expect(() => ignore({ root: true }))
.toThrow()
})

it('dont fallback to root, no strict and return empty array', () => {
expect(ignore({ strict: false, root: true }))
.toMatchInlineSnapshot(`
{
"ignores": [],
}
`)
})
})
Empty file.

0 comments on commit aadca59

Please sign in to comment.