Comments (10)
No, node-ignore does not support hierarchical .gitignore rules as mentioned in the README.md.
I'm sorry I didn't communicate this clearly. I know that node-ignore
doesn't support hierarchies. That's why I was writing something that does, using node-ignore
as a building block. I hadn't written it at the time (I got stumped you see) so I just used pseudocode in the example.
If we need to deal with ignore rules from different root directories, multiple node-ignore instances are required.
Using multiple instances isn't sufficient. You also need to keep track at each level in the hierarchy whether a file has been ignored by a previous instance. That is why I proposed the feature I did, because otherwise how would you know whether a file that is currently ignored should be un-ignored?
Anyway I did find a workaround. To check if a file that is currently ignored should be un-ignored, you can amend the ruleset by adding an ignore **
rule to the beginning of the file. That essentially sets the default state to true
, so the only way it will return false
is if it got un-ignored.
For the record here's my code.
async function isIgnored (workdir, pathname) {
let pairs = [
{
gitignore: path.join(workdir, '.gitignore'),
pathname
}
]
let pieces = pathname.split('/')
for (let i = 1; i < pieces.length; i++) {
let dir = pieces.slice(0, i).join('/')
let file = pieces.slice(i).join('/')
pairs.push({
gitignore: path.join(workdir, dir, '.gitignore'),
pathname: file
})
}
let ignoredStatus = false
for (let p of pairs) {
let file
try {
file = await read(p.gitignore, 'utf8')
} catch (err) {
if (err.code === 'NOENT') continue
}
let ign = ignore().add(file)
let unign = ignore().add(`**\n${file}`)
// If the parent directory is excluded, we are done.
// "It is not possible to re-include a file if a parent directory of that file is excluded. Git doesnโt list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined."
// source: https://git-scm.com/docs/gitignore
let parentdir = path.dirname(p.pathname)
if (ign.ignores(parentdir)) return true
// If the file is currently ignored, test for UNignoring.
if (ignoredStatus) {
ignoredStatus = unign.ignores(p.pathname)
} else {
ignoredStatus = ign.ignores(p.pathname)
}
}
return ignoredStatus
}
The hack/workaround I mentioned are the lines:
let ign = ignore().add(file)
let unign = ignore().add(`**\n${file}`)
...
if (ignoredStatus) {
ignoredStatus = unign.ignores(p.pathname)
} else {
ignoredStatus = ign.ignores(p.pathname)
}
from node-ignore.
I'm working on a project ignore-nested
which is based on node-ignore
.
I'll close this issue after ignore-nested
published.
from node-ignore.
@wmhilton coming soon ๐
from node-ignore.
No, node-ignore
does not support hierarchical .gitignore rules as mentioned in the README.md. If we need to deal with ignore rules from different root directories, multiple node-ignore
instances are required.
node-ignore
is a gitignore rule parser, but will do nothing about paths calculating, traversing of directories. If you need that, you could do something based upon node-ignore
.
from node-ignore.
Besides, the pathname
which passed to ig.ignores(pathname)
should be path.relative()
d to the directory where the corresponding gitignore rule locates.
Suppose that:
/path/to/A/
|-- .gitignore # which contains foo.txt
|-- foo.txt
Then:
ig.ignores('/A/foo.txt') // WRONG !
ig.ignores('/path/to/a/foo.txt') // WRONG!
ig.ignores('./foo.txt') // WRONG !
ig.ignores('foo.txt') // Right
from node-ignore.
There's one bug:
-if (ign.ignores(parentdir)) return true
+if (parentdir !== '.' && ign.ignores(parentdir)) return true
from node-ignore.
Another implementation of hierarchical paths matcher:
// @flow
import ignore from 'ignore'
import * as path from 'path'
import * as R from 'ramda'
type Options = {
// Be case-insensitive? Default is true.
ignorecase?: boolean,
}
const joinPaths = R.apply(path.join)
function splitPath (filename: string) {
return filename.split(path.sep).filter(s => s !== '')
}
function parsePatterns (patterns: string, opts: Options = {}) {
const ign = ignore(opts).add(patterns)
const unign = ignore(opts).add(`**\n${patterns}`)
return (filename: string, defaultState: boolean = false) =>
defaultState ? unign.ignores(filename) : ign.ignores(filename)
}
export default (patternsReader: ((dirname: string) => ?string), opts: Options = {}) => {
const patternsMatcherFromDir = R.memoize((dirname: string) => {
const patts = patternsReader(dirname)
if (patts) { return parsePatterns(patts, opts) }
})
// (filename: string) => boolean
return R.pipe(
splitPath,
// ex.: ["a", "b", "c"] -> [[".", "a"/b/c"], ["a", "b/c"], ["a/b", "c"]]
parts => parts.map((_, idx) => {
return R.splitAt(idx, parts).map(joinPaths)
}),
R.reduce((state, [dirname, filename]) => {
const matches = patternsMatcherFromDir(dirname)
// If there's no ignore file in dirname, go up.
if (!matches) {
return state
}
// If the parent directory is excluded, we are done.
// It is not possible to re-include a file if a parent directory of that
// file is excluded. - https://git-scm.com/docs/gitignore
const parentDir = path.dirname(filename)
if (parentDir !== '.' && matches(parentDir, false)) {
return R.reduced(true)
}
return matches(filename, state)
}, false),
)
}
from node-ignore.
There's one bug:
-if (ign.ignores(parentdir)) return true
+if (parentdir !== '.' && ign.ignores(parentdir)) return true
Do NOT pass paths like ./some-dir
to ig.ignore()
or any other node-ignore
methods, see related doc here.
See also previous comments of this issue.
I've updated the readme about this.
from node-ignore.
-if (ign.ignores(parentdir)) return true +if (parentdir !== '.' && ign.ignores(parentdir)) return trueDo NOT pass paths like
./some-dir
toig.ignore()
or any othernode-ignore
methods, see related doc here.
I don't, please read the code properly. path.dirname('some-dir') => '.'
.
I'm working on a project
ignore-nested
which is based onnode-ignore
.
Great!
from node-ignore.
Awesome! I'm looking forward to using nested-ignore
in isomorphic-git.
from node-ignore.
Related Issues (20)
- Options merge HOT 4
- Suggested replacement for addIgnoreFile doesn't work always HOT 4
- Clarify "unignored" result of "test" method
- How to check if the working directory should be ignored? HOT 1
- TypeScript: add support for `readonly string[]`
- Negate broken HOT 1
- [Feature] Add export field or new package to render real world gitignore? HOT 2
- [Feature] npm exec script HOT 1
- wrong result for node_modules HOT 2
- directory ending with / not always correctly ignored HOT 5
- Find out which paths to watch HOT 4
- Negative pattern ignored when inside a subdirectory HOT 2
- Negated directory inclusion fails with glob HOT 1
- Trailing backslash in the ignore file is throwing a syntax error. HOT 1
- \# does not work HOT 1
- Pathname should be a path.relative()d pathname Error with ../ path HOT 2
- Add support for OR syntax `{js,ts}` HOT 3
- foo/* not correctly respected HOT 4
- "*.app" ignores "Notificator.app/Contents/PkgInfo" HOT 2
- Typescript support for moduleResolution node16 HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from node-ignore.