Skip to content
This repository has been archived by the owner on Mar 3, 2023. It is now read-only.

Commit

Permalink
Merge pull request #19444 from atom/improvements-to-ripgrep-scanner
Browse files Browse the repository at this point in the history
Improvements to ripgrep scanner
  • Loading branch information
rafeca committed Jun 6, 2019
2 parents 119fead + ac9be2d commit 33f2bd3
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 26 deletions.
160 changes: 142 additions & 18 deletions spec/workspace-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2697,11 +2697,11 @@ describe('Workspace', () => {
});
});

describe('when the core.excludeVcsIgnoredPaths config is truthy', () => {
describe('when the core.excludeVcsIgnoredPaths config is used', () => {
let projectPath;
let ignoredPath;

beforeEach(() => {
beforeEach(async () => {
const sourceProjectPath = path.join(
__dirname,
'fixtures',
Expand All @@ -2713,22 +2713,17 @@ describe('Workspace', () => {
const writerStream = fstream.Writer(projectPath);
fstream.Reader(sourceProjectPath).pipe(writerStream);

waitsFor(done => {
writerStream.on('close', done);
writerStream.on('error', done);
await new Promise(resolve => {
writerStream.on('close', resolve);
writerStream.on('error', resolve);
});

runs(() => {
fs.renameSync(
path.join(projectPath, 'git.git'),
path.join(projectPath, '.git')
);
ignoredPath = path.join(projectPath, 'ignored.txt');
fs.writeFileSync(
ignoredPath,
'this match should not be included'
);
});
fs.renameSync(
path.join(projectPath, 'git.git'),
path.join(projectPath, '.git')
);
ignoredPath = path.join(projectPath, 'ignored.txt');
fs.writeFileSync(ignoredPath, 'this match should not be included');
});

afterEach(() => {
Expand All @@ -2737,15 +2732,144 @@ describe('Workspace', () => {
}
});

it('excludes ignored files', async () => {
it('excludes ignored files when core.excludeVcsIgnoredPaths is true', async () => {
atom.project.setPaths([projectPath]);
atom.config.set('core.excludeVcsIgnoredPaths', true);
const resultHandler = jasmine.createSpy('result found');

await scan(/match/, {}, () => resultHandler());
await scan(/match/, {}, ({ filePath }) => resultHandler(filePath));

expect(resultHandler).not.toHaveBeenCalled();
});

it('does not exclude ignored files when core.excludeVcsIgnoredPaths is false', async () => {
atom.project.setPaths([projectPath]);
atom.config.set('core.excludeVcsIgnoredPaths', false);
const resultHandler = jasmine.createSpy('result found');

await scan(/match/, {}, ({ filePath }) => resultHandler(filePath));

expect(resultHandler).toHaveBeenCalledWith(
path.join(projectPath, 'ignored.txt')
);
});

it('does not exclude files when searching on an ignored folder even when core.excludeVcsIgnoredPaths is true', async () => {
fs.mkdirSync(path.join(projectPath, 'poop'));
ignoredPath = path.join(
path.join(projectPath, 'poop', 'whatever.txt')
);
fs.writeFileSync(ignoredPath, 'this match should be included');

atom.project.setPaths([projectPath]);
atom.config.set('core.excludeVcsIgnoredPaths', true);
const resultHandler = jasmine.createSpy('result found');

await scan(/match/, { paths: ['poop'] }, ({ filePath }) =>
resultHandler(filePath)
);

expect(resultHandler).toHaveBeenCalledWith(ignoredPath);
});
});

describe('when the core.followSymlinks config is used', () => {
let projectPath;

beforeEach(async () => {
const sourceProjectPath = path.join(
__dirname,
'fixtures',
'dir',
'a-dir'
);
projectPath = path.join(temp.mkdirSync('atom'));

const writerStream = fstream.Writer(projectPath);
fstream.Reader(sourceProjectPath).pipe(writerStream);

await new Promise(resolve => {
writerStream.on('close', resolve);
writerStream.on('error', resolve);
});

fs.symlinkSync(
path.join(__dirname, 'fixtures', 'dir', 'b'),
path.join(projectPath, 'symlink')
);
});

afterEach(() => {
if (fs.existsSync(projectPath)) {
fs.removeSync(projectPath);
}
});

it('follows symlinks when core.followSymlinks is true', async () => {
atom.project.setPaths([projectPath]);
atom.config.set('core.followSymlinks', true);
const resultHandler = jasmine.createSpy('result found');

await scan(/ccc/, {}, ({ filePath }) => resultHandler(filePath));

expect(resultHandler).toHaveBeenCalledWith(
path.join(projectPath, 'symlink')
);
});

it('does not follow symlinks when core.followSymlinks is false', async () => {
atom.project.setPaths([projectPath]);
atom.config.set('core.followSymlinks', false);
const resultHandler = jasmine.createSpy('result found');

await scan(/ccc/, {}, ({ filePath }) => resultHandler(filePath));

expect(resultHandler).not.toHaveBeenCalled();
});
});

describe('when there are hidden files', () => {
let projectPath;

beforeEach(async () => {
const sourceProjectPath = path.join(
__dirname,
'fixtures',
'dir',
'a-dir'
);
projectPath = path.join(temp.mkdirSync('atom'));

const writerStream = fstream.Writer(projectPath);
fstream.Reader(sourceProjectPath).pipe(writerStream);

await new Promise(resolve => {
writerStream.on('close', resolve);
writerStream.on('error', resolve);
});

// Note: This won't create a hidden file on Windows, in order to more
// accurately test this behaviour there, we should either use a package
// like `fswin` or manually spawn an `ATTRIB` command.
fs.writeFileSync(path.join(projectPath, '.hidden'), 'ccc');
});

afterEach(() => {
if (fs.existsSync(projectPath)) {
fs.removeSync(projectPath);
}
});

it('searches on hidden files', async () => {
atom.project.setPaths([projectPath]);
const resultHandler = jasmine.createSpy('result found');

await scan(/ccc/, {}, ({ filePath }) => resultHandler(filePath));

expect(resultHandler).toHaveBeenCalledWith(
path.join(projectPath, '.hidden')
);
});
});

it('includes only files when a directory filter is specified', async () => {
Expand Down
2 changes: 1 addition & 1 deletion src/default-directory-searcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ module.exports = class DefaultDirectorySearcher {
// Each item in the array is a file/directory pattern, e.g., `src` to search in the "src"
// directory or `*.js` to search all JavaScript files. In practice, this often comes from the
// comma-delimited list of patterns in the bottom text input of the ProjectFindView dialog.
// * `ignoreHidden` {boolean} whether to ignore hidden files.
// * `includeHidden` {boolean} whether to ignore hidden files.
// * `excludeVcsIgnores` {boolean} whether to exclude VCS ignored paths.
// * `exclusions` {Array} similar to inclusions
// * `follow` {boolean} whether symlinks should be followed.
Expand Down
24 changes: 17 additions & 7 deletions src/ripgrep-directory-searcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ module.exports = class RipgrepDirectorySearcher {
// Each item in the array is a file/directory pattern, e.g., `src` to search in the "src"
// directory or `*.js` to search all JavaScript files. In practice, this often comes from the
// comma-delimited list of patterns in the bottom text input of the ProjectFindView dialog.
// * `ignoreHidden` {boolean} whether to ignore hidden files.
// * `includeHidden` {boolean} whether to ignore hidden files.
// * `excludeVcsIgnores` {boolean} whether to exclude VCS ignored paths.
// * `exclusions` {Array} similar to inclusions
// * `follow` {boolean} whether symlinks should be followed.
Expand Down Expand Up @@ -230,7 +230,7 @@ module.exports = class RipgrepDirectorySearcher {
const directoryPath = directory.getPath();
const regexpStr = this.prepareRegexp(regexp.source);

const args = ['--hidden', '--json', '--regexp', regexpStr];
const args = ['--json', '--regexp', regexpStr];
if (options.leadingContextLineCount) {
args.push('--before-context', options.leadingContextLineCount);
}
Expand All @@ -257,10 +257,22 @@ module.exports = class RipgrepDirectorySearcher {
args.push('--multiline');
}

args.push(directoryPath);
if (options.includeHidden) {
args.push('--hidden');
}

if (options.follow) {
args.push('--follow');
}

if (!options.excludeVcsIgnores) {
args.push('--no-ignore-vcs');
}

args.push('.');

const child = spawn(this.rgPath, args, {
cwd: directory.getPath(),
cwd: directoryPath,
stdio: ['pipe', 'pipe', 'pipe']
});

Expand Down Expand Up @@ -301,7 +313,7 @@ module.exports = class RipgrepDirectorySearcher {

if (message.type === 'begin') {
pendingEvent = {
filePath: getText(message.data.path),
filePath: path.join(directoryPath, getText(message.data.path)),
matches: []
};
pendingLeadingContext = [];
Expand Down Expand Up @@ -379,8 +391,6 @@ module.exports = class RipgrepDirectorySearcher {
pattern = pattern.slice(0, -1);
}

pattern = pattern.startsWith('**/') ? pattern : `**/${pattern}`;

output.push(pattern);
output.push(pattern.endsWith('/**') ? pattern : `${pattern}/**`);
}
Expand Down

0 comments on commit 33f2bd3

Please sign in to comment.