Always resolve the config file to ResolvedConfigFile if its json, otherwise combine tsconfig.json

This commit is contained in:
Sheetal Nandi
2018-09-11 12:56:23 -07:00
parent ec38ca4fcb
commit a172751bf9
6 changed files with 28 additions and 71 deletions

View File

@@ -2341,7 +2341,7 @@ namespace ts {
function parseProjectReferenceConfigFile(ref: ProjectReference): { commandLine: ParsedCommandLine, sourceFile: SourceFile } | undefined {
// The actual filename (i.e. add "/tsconfig.json" if necessary)
const refPath = resolveProjectReferencePath(host, ref);
const refPath = resolveProjectReferencePath(ref);
// An absolute path pointing to the containing directory of the config file
const basePath = getNormalizedAbsolutePath(getDirectoryPath(refPath), host.getCurrentDirectory());
const sourceFile = host.getSourceFile(refPath, ScriptTarget.JSON) as JsonSourceFile | undefined;
@@ -2820,18 +2820,13 @@ namespace ts {
};
}
export interface ResolveProjectReferencePathHost {
fileExists(fileName: string): boolean;
}
/**
* Returns the target config filename of a project reference.
* Note: The file might not exist.
*/
export function resolveProjectReferencePath(host: ResolveProjectReferencePathHost, ref: ProjectReference): ResolvedConfigFileName {
if (!host.fileExists(ref.path)) {
return combinePaths(ref.path, "tsconfig.json") as ResolvedConfigFileName;
}
return ref.path as ResolvedConfigFileName;
// TODO: Does this need to be exposed
export function resolveProjectReferencePath(ref: ProjectReference): ResolvedConfigFileName {
return resolveConfigFileProjectName(ref.path);
}
/* @internal */

View File

@@ -598,7 +598,7 @@ namespace ts {
function invalidateProjectAndScheduleBuilds(resolved: ResolvedConfigFileName, reloadLevel: ConfigFileProgramReloadLevel) {
reportFileChangeDetected = true;
invalidateProject(resolved, reloadLevel);
invalidateResolvedProject(resolved, reloadLevel);
scheduleBuildInvalidatedProject();
}
@@ -716,7 +716,7 @@ namespace ts {
if (project.projectReferences) {
for (const ref of project.projectReferences) {
usesPrepend = usesPrepend || !!(ref.prepend);
const resolvedRef = resolveProjectReferencePath(host, ref);
const resolvedRef = resolveProjectReferencePath(ref);
const refStatus = getUpToDateStatus(parseConfigFile(resolvedRef));
// An upstream project is blocked
@@ -795,16 +795,10 @@ namespace ts {
}
function invalidateProject(configFileName: string, reloadLevel?: ConfigFileProgramReloadLevel) {
const resolved = resolveProjectName(configFileName);
if (resolved === undefined) {
// If this was a rootName, we need to track it as missing.
// Otherwise we can just ignore it and have it possibly surface as an error in any downstream projects,
// if they exist
// TODO: do those things
return;
}
invalidateResolvedProject(resolveProjectName(configFileName), reloadLevel);
}
function invalidateResolvedProject(resolved: ResolvedConfigFileName, reloadLevel?: ConfigFileProgramReloadLevel) {
projectStatus.removeKey(resolved);
if (options.watch) {
diagnostics.removeKey(resolved);
@@ -901,11 +895,9 @@ namespace ts {
}
}
function buildSingleInvalidatedProject(project: ResolvedConfigFileName, reloadLevel: ConfigFileProgramReloadLevel) {
function buildSingleInvalidatedProject(resolved: ResolvedConfigFileName, reloadLevel: ConfigFileProgramReloadLevel) {
// TODO:: handle this in better way later
const resolved = resolveProjectName(project);
if (!resolved) return; // ??
const proj = parseConfigFile(resolved);
if (!proj) return; // ?
if (reloadLevel === ConfigFileProgramReloadLevel.Full) {
@@ -915,7 +907,7 @@ namespace ts {
}
else if (reloadLevel === ConfigFileProgramReloadLevel.Partial) {
// Update file names
const result = getFileNamesFromConfigSpecs(proj.configFileSpecs!, getDirectoryPath(project), proj.options, parseConfigFileHost);
const result = getFileNamesFromConfigSpecs(proj.configFileSpecs!, getDirectoryPath(resolved), proj.options, parseConfigFileHost);
if (result.fileNames.length !== 0) {
filterMutate(proj.errors, error => !isErrorNoInputFiles(error));
}
@@ -927,14 +919,14 @@ namespace ts {
}
const status = getUpToDateStatus(proj);
verboseReportProjectStatus(project, status);
verboseReportProjectStatus(resolved, status);
if (status.type === UpToDateStatusType.UpstreamBlocked) {
if (options.verbose) reportStatus(Diagnostics.Skipping_build_of_project_0_because_its_dependency_1_has_errors, resolved, status.upstreamProjectName);
return;
}
buildSingleProject(project);
buildSingleProject(resolved);
}
function createDependencyGraph(roots: ResolvedConfigFileName[]): DependencyGraph | undefined {
@@ -982,10 +974,6 @@ namespace ts {
if (parsed.projectReferences) {
for (const ref of parsed.projectReferences) {
const resolvedRefPath = resolveProjectName(ref.path);
if (resolvedRefPath === undefined) {
hadError = true;
break;
}
visit(resolvedRefPath, inCircularContext || ref.circular);
graph.addReference(projPath, resolvedRefPath);
}
@@ -1184,30 +1172,12 @@ namespace ts {
return ExitStatus.Success;
}
function resolveProjectName(name: string): ResolvedConfigFileName | undefined {
const fullPath = resolvePath(host.getCurrentDirectory(), name);
if (host.fileExists(fullPath)) {
return fullPath as ResolvedConfigFileName;
}
const fullPathWithTsconfig = combinePaths(fullPath, "tsconfig.json");
if (host.fileExists(fullPathWithTsconfig)) {
return fullPathWithTsconfig as ResolvedConfigFileName;
}
// TODO(shkamat): right now this is accounted as 1 error in config file, but we need to do better
host.reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_not_found, relName(fullPath)));
return undefined;
function resolveProjectName(name: string): ResolvedConfigFileName {
return resolveConfigFileProjectName(resolvePath(host.getCurrentDirectory(), name));
}
function resolveProjectNames(configFileNames: ReadonlyArray<string>): ResolvedConfigFileName[] | undefined {
const resolvedNames: ResolvedConfigFileName[] = [];
for (const name of configFileNames) {
const resolved = resolveProjectName(name);
if (resolved === undefined) {
return undefined;
}
resolvedNames.push(resolved);
}
return resolvedNames;
return configFileNames.map(resolveProjectName);
}
function buildAllProjects(): ExitStatus {
@@ -1300,6 +1270,14 @@ namespace ts {
}
}
export function resolveConfigFileProjectName(project: string): ResolvedConfigFileName {
if (fileExtensionIs(project, Extension.Json)) {
return project as ResolvedConfigFileName;
}
return combinePaths(project, "tsconfig.json") as ResolvedConfigFileName;
}
export function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string> {
if (project.options.outFile) {
return getOutFileOutputs(project);

View File

@@ -199,7 +199,7 @@ namespace ts {
tick();
touch(fs, "/src/logic/index.ts");
// Because we haven't reset the build context, the builder should assume there's nothing to do right now
const status = builder.getUpToDateStatusOfFile(builder.resolveProjectName("/src/logic")!);
const status = builder.getUpToDateStatusOfFile(builder.resolveProjectName("/src/logic"));
assert.equal(status.type, UpToDateStatusType.UpToDate, "Project should be assumed to be up-to-date");
// Rebuild this project

View File

@@ -165,7 +165,7 @@ namespace ts {
}
function performBuild(args: string[]): number | undefined {
const { buildOptions, projects: buildProjects, errors } = parseBuildCommand(args);
const { buildOptions, projects, errors } = parseBuildCommand(args);
if (errors.length > 0) {
errors.forEach(reportDiagnostic);
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
@@ -179,16 +179,6 @@ namespace ts {
// Update to pretty if host supports it
updateReportDiagnostic();
const projects = mapDefined(buildProjects, project => {
const fileName = resolvePath(sys.getCurrentDirectory(), project);
const refPath = resolveProjectReferencePath(sys, { path: fileName });
if (!sys.fileExists(refPath)) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_does_not_exist, fileName));
return undefined;
}
return refPath;
});
if (projects.length === 0) {
printVersion();
printHelp(buildOpts, "--build ");