Skip to content

Commit

Permalink
feat: #7 - Some fixes to importing files from tsconfig.
Browse files Browse the repository at this point in the history
This seems to work well!
  • Loading branch information
dsherret committed Jan 13, 2018
1 parent b2e7942 commit d4e256d
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/tests/tsSimpleAstTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe(nameof(TsSimpleAst), () => {
it("should add the files from tsconfig.json by default", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDir": "test", "target": "ES5" } }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test/test2/file2.ts", "");
const ast = new TsSimpleAst({ tsConfigFilePath: "tsconfig.json" }, fs);
Expand Down
55 changes: 53 additions & 2 deletions src/tests/utils/tsconfig/getInfoFromTsConfigTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,63 @@ describe(nameof(getInfoFromTsConfig), () => {
expect(info).to.deep.equal({ compilerOptions: { rootDir: "/test", target: 1 }, errors: [] });
});

it("should add the files from tsconfig.json", () => {
it("should add the files from tsconfig.json, but exclude the outDir", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDir": "test", "target": "ES5" } }`);
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "outDir": "test2" } }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test2/file2.ts", "");
const info = getInfoFromTsConfig("tsconfig.json", fs, { shouldGetFilePaths: true });
expect(info.filePaths!.sort()).to.deep.equal(["/otherFile.ts", "/test/file.ts"].sort());
});

it("should add the files from tsconfig.json, but exclude the specified exclude", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "exclude": ["test2"] }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test2/file2.ts", "");
const info = getInfoFromTsConfig("tsconfig.json", fs, { shouldGetFilePaths: true });
expect(info.filePaths!.sort()).to.deep.equal(["/otherFile.ts", "/test/file.ts"].sort());
});

it("should add the files from tsconfig.json, but only include the specified include", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "include": ["test2"] }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test2/file2.ts", "");
const info = getInfoFromTsConfig("tsconfig.json", fs, { shouldGetFilePaths: true });
expect(info.filePaths!.sort()).to.deep.equal(["/test2/file2.ts"].sort());
});

it("should add the files from tsconfig.json when using rootDir", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDir": "test" } }`);
fs.writeFileSync("/otherFile.ts", "");
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test/test2/file2.ts", "");
const info = getInfoFromTsConfig("tsconfig.json", fs, { shouldGetFilePaths: true });
expect(info.filePaths!.sort()).to.deep.equal(["/test/file.ts", "/test/test2/file2.ts"].sort());
});

it("should add the files from tsconfig.json when using rootDirs", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDirs": ["/test/test1", "/test/test2"] } }`);
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test/test1/file1.ts", "");
fs.writeFileSync("/test/test2/file2.ts", "");
const info = getInfoFromTsConfig("tsconfig.json", fs, { shouldGetFilePaths: true });
expect(info.filePaths!.sort()).to.deep.equal(["/test/test1/file1.ts", "/test/test2/file2.ts"].sort());
});

it("should add the files from tsconfig.json when using rootDir and rootDirs", () => {
const fs = new VirtualFileSystemHost();
fs.writeFileSync("tsconfig.json", `{ "compilerOptions": { "rootDir": "/test/test1", "rootDirs": ["/test/test2"] } }`);
fs.writeFileSync("/test/file.ts", "");
fs.writeFileSync("/test/test1/file1.ts", "");
fs.writeFileSync("/test/test2/file2.ts", "");
const info = getInfoFromTsConfig("tsconfig.json", fs, { shouldGetFilePaths: true });
expect(info.filePaths!.sort()).to.deep.equal(["/test/test1/file1.ts", "/test/test2/file2.ts"].sort());
});
});
2 changes: 1 addition & 1 deletion src/utils/ArrayUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class ArrayUtils {
return undefined;
}

static from<T>(items: IterableIterator<T> | ts.Iterator<T>) {
static from<T>(items: Iterable<T> | ts.Iterator<T>) {
const a: T[] = [];
for (const item of items)
a.push(item);
Expand Down
38 changes: 33 additions & 5 deletions src/utils/tsconfig/getInfoFromTsConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import * as errors from "./../../errors";
import {Diagnostic} from "./../../compiler";
import {FileSystemHost} from "./../../fileSystem";
import {FileUtils} from "./../../utils";
import {ArrayUtils, FileUtils, createHashSet} from "./../../utils";

export interface TsConfigInfo {
compilerOptions: ts.CompilerOptions;
Expand All @@ -24,7 +24,7 @@ export function getInfoFromTsConfig(filePath: string, fileSystem: FileSystemHost
return getOnlyCompilerOptions(parseResult, filePath);
}

function getFilesAndCompilerOptions(fileSystem: FileSystemHost, parseResult: ParseResult, filePath: string) {
function getFilesAndCompilerOptions(fileSystem: FileSystemHost, parseResult: ParseResult, tsConfigFilePath: string) {
const currentDir = fileSystem.getCurrentDirectory();
const host: ts.ParseConfigHost = {
useCaseSensitiveFileNames: true,
Expand All @@ -33,13 +33,41 @@ function getFilesAndCompilerOptions(fileSystem: FileSystemHost, parseResult: Par
fileExists: path => fileSystem.fileExistsSync(path),
readFile: path => fileSystem.readFileSync(path)
};
const result = ts.parseJsonConfigFileContent(parseResult, host, fileSystem.getCurrentDirectory(), undefined, filePath);
const compilerOptionsResult = getOnlyCompilerOptions(parseResult, filePath); // doesn't seem like there's a way to get this from result
const compilerOptionsResult = getOnlyCompilerOptions(parseResult, tsConfigFilePath);
return {
filePaths: result.fileNames,
filePaths: getFiles(compilerOptionsResult.compilerOptions),
compilerOptions: compilerOptionsResult.compilerOptions,
errors: compilerOptionsResult.errors
};

function getFiles(compilerOptions: ts.CompilerOptions) {
const files = createHashSet<string>();
const tsConfigDir = FileUtils.getDirPath(tsConfigFilePath);

for (const rootDir of getRootDirs()) {
for (const filePath of getFilesFromDir(FileUtils.getStandardizedAbsolutePath(fileSystem, rootDir, tsConfigDir)))
files.add(filePath);
}

return ArrayUtils.from(files.values());

function getRootDirs() {
const result: string[] = [];
if (typeof compilerOptions.rootDir === "string")
result.push(compilerOptions.rootDir);
if (compilerOptions.rootDirs != null)
result.push(...compilerOptions.rootDirs);
// use the tsconfig directory if no rootDir or rootDirs is specified
if (result.length === 0)
result.push(tsConfigDir);
return result;
}

function* getFilesFromDir(dirPath: string) {
for (const filePath of ts.parseJsonConfigFileContent(parseResult.config, host, dirPath, compilerOptions, undefined).fileNames)
yield FileUtils.getStandardizedAbsolutePath(fileSystem, filePath);
}
}
}

function getOnlyCompilerOptions(parseResult: ParseResult, filePath: string) {
Expand Down

0 comments on commit d4e256d

Please sign in to comment.