Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
19b3ec8
Activate the Windows $PATH locator.
ericsnowcurrently Jan 19, 2021
2c69245
Allow passing fs.Dirent to convertFileType().
ericsnowcurrently Jan 6, 2021
6aa00e2
Factor out readDir().
ericsnowcurrently Jan 19, 2021
989ded1
Time out after 1 second when reading a directory.
ericsnowcurrently Jan 19, 2021
cdd06f7
Move a comment to the right spot.
ericsnowcurrently Jan 19, 2021
44768a3
Add an optional timeout handler to readDir().
ericsnowcurrently Jan 19, 2021
3d7ae02
Use a timeout handler in WindowsPathEnvVarLocator().
ericsnowcurrently Jan 19, 2021
6bca176
Fix an async bug.
ericsnowcurrently Jan 19, 2021
1089976
Combine identical if blocks.
ericsnowcurrently Jan 19, 2021
87532c8
lint
ericsnowcurrently Jan 20, 2021
4ee4292
Move checkBin to the right spot.
ericsnowcurrently Jan 20, 2021
84b3ced
Remove timeout code.
ericsnowcurrently Jan 20, 2021
cc63376
Drop externalDependencies.listDir().
ericsnowcurrently Jan 20, 2021
4ecb931
iterExecutables() -> walkSubTree().
ericsnowcurrently Jan 20, 2021
2ac0db9
Add iterPythonExecutablesInDir().
ericsnowcurrently Jan 20, 2021
ad8c2b0
Use iterPythonExecutablesInDir() in DirFilesLocator.
ericsnowcurrently Jan 20, 2021
dd1178a
Add isDirWatchable().
ericsnowcurrently Jan 20, 2021
f61e435
Add DirFilesWatchingLocator.
ericsnowcurrently Jan 20, 2021
cb3ca6b
Only watch watchable directories.
ericsnowcurrently Jan 20, 2021
8d325d5
Fix the "watchable" condition.
ericsnowcurrently Jan 21, 2021
4c38d35
Factor out resolvePythonExeGlobs() and make watchLocationForPythonBin…
ericsnowcurrently Jan 21, 2021
ec0690f
Support a flat structure in FSWatchingLocator.
ericsnowcurrently Jan 21, 2021
fb0270e
Watch only a flat structure in DirFilesWatchingLocator.
ericsnowcurrently Jan 21, 2021
5c85900
Fix the FSWatchingLocator tests.
ericsnowcurrently Jan 21, 2021
88b2f84
Add a note about what gets checked.
ericsnowcurrently Jan 26, 2021
9f52799
Do not bother watching any of the $PATH directories.
ericsnowcurrently Jan 26, 2021
7e3175f
Drop DirFilesWatchingLocator.
ericsnowcurrently Jan 26, 2021
5b9b922
Pass PythonEnvStructure in the FSWatchingLocator options.
ericsnowcurrently Jan 28, 2021
4689b17
Use a flat env structure for WindowsStoreLocator.
ericsnowcurrently Jan 28, 2021
1f344c0
isDirWatchable() -> checkDirWatchable() (and return a reason).
ericsnowcurrently Jan 28, 2021
ba9aa1e
Log unwatchable dirs instead of failing.
ericsnowcurrently Jan 28, 2021
dc919d9
Make the unwatchable check before calling startWatchers().
ericsnowcurrently Jan 28, 2021
8f95844
Move the enableGlobalWatchers check earlier.
ericsnowcurrently Jan 28, 2021
1040ca2
Filter out unwatchable roots early in FSWatchingLocator.initWatchers().
ericsnowcurrently Jan 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Factor out readDir().
  • Loading branch information
ericsnowcurrently committed Jan 28, 2021
commit 6aa00e2ce54e19d05e3953247660bd2c62263419
59 changes: 39 additions & 20 deletions src/client/pythonEnvironments/common/commonUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import { Dirent } from 'fs';
import * as path from 'path';
import { convertFileType } from '../../common/platform/fileSystem';
import { FileType } from '../../common/platform/types';
import { getOSType, OSType } from '../../common/utils/platform';
import { logError } from '../../logging';
import { PythonVersion, UNKNOWN_PYTHON_VERSION } from '../base/info';
Expand Down Expand Up @@ -48,26 +50,11 @@ async function* iterExecutables(
ignoreErrors: boolean;
},
): AsyncIterableIterator<string> {
let entries: Dirent[];
try {
entries = await listDir(root);
} catch (err) {
// Treat a missing directory as empty.
if (err.code === 'ENOENT') {
return;
}
if (cfg.ignoreErrors) {
logError(`listDir() failed for "${root}" (${err})`);
return;
}
throw err; // re-throw
}

const entries = await readDir(root, cfg);
// "checkBin" is a local variable rather than global
// so we can stub it out during unit testing.
const checkBin = getOSType() === OSType.Windows ? isWindowsPythonExe : isPosixPythonBin;
for (const entry of entries) {
const filename = path.join(root, entry.name);
for (const { filename, filetype } of entries) {
// (FYI)
// Normally we would have to do an extra (expensive) `fs.lstat()`
// here for each file to determine its file type. However,
Expand All @@ -77,17 +64,17 @@ async function* iterExecutables(
// of each entry is preserved for free. If we needed more
// information than just the file type then we would be forced
// to incur the extra cost of `fs.lstat()`.
if (entry.isDirectory()) {
if (filetype === FileType.Directory) {
if (cfg.maxDepth && currentDepth <= cfg.maxDepth) {
if (matchFile(filename, cfg.filterSubDir, cfg.ignoreErrors)) {
yield* iterExecutables(filename, currentDepth + 1, cfg);
}
}
} else if (entry.isFile()) {
} else if (filetype === FileType.File) {
if (checkBin(filename)) {
yield filename;
}
} else if (entry.isSymbolicLink()) {
} else if (filetype === FileType.SymbolicLink) {
if (checkBin(filename)) {
yield filename;
}
Expand All @@ -97,6 +84,38 @@ async function* iterExecutables(
}
}

type DirEntry = {
filename: string;
filetype: FileType;
};

async function readDir(
dirname: string,
opts: {
ignoreErrors?: boolean;
} = {},
): Promise<DirEntry[]> {
let entries: Dirent[];
try {
entries = await listDir(dirname);
} catch (err) {
// Treat a missing directory as empty.
if (err.code === 'ENOENT') {
return [];
}
if (opts.ignoreErrors) {
logError(`listDir() failed for "${dirname}" (${err})`);
return [];
}
throw err; // re-throw
}
return entries.map((entry) => {
const filename = path.join(dirname, entry.name);
const filetype = convertFileType(entry);
return { filename, filetype };
});
}

function matchFile(
filename: string,
filterFile: FileFilterFunc | undefined,
Expand Down