Skip to content

Commit

Permalink
feat(tsc-wrapped): Support of vinyl like config file was added (#13987)
Browse files Browse the repository at this point in the history
This feature was implemented in order to provide easier way of use in gulp
  • Loading branch information
jolly-roger authored and alxhub committed Jan 24, 2017
1 parent 83361d8 commit 0c7726d
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 11 deletions.
10 changes: 8 additions & 2 deletions tools/@angular/tsc-wrapped/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {check, tsc} from './tsc';
import NgOptions from './options';
import {MetadataWriterHost, DecoratorDownlevelCompilerHost, TsickleCompilerHost} from './compiler_host';
import {CliOptions} from './cli_options';
import {VinylFile, isVinylFile} from './vinyl_file';

export {UserError} from './tsc';

Expand All @@ -23,11 +24,16 @@ export type CodegenExtension =
Promise<void>;

export function main(
project: string, cliOptions: CliOptions, codegen?: CodegenExtension,
project: string | VinylFile, cliOptions: CliOptions, codegen?: CodegenExtension,
options?: ts.CompilerOptions): Promise<any> {
try {
let projectDir = project;
if (fs.lstatSync(project).isFile()) {
// project is vinyl like file object
if (isVinylFile(project)) {
projectDir = path.dirname(project.path);
}
// project is path to project file
else if (fs.lstatSync(project).isFile()) {
projectDir = path.dirname(project);
}

Expand Down
20 changes: 16 additions & 4 deletions tools/@angular/tsc-wrapped/src/tsc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ import * as path from 'path';
import * as ts from 'typescript';

import AngularCompilerOptions from './options';
import {VinylFile, isVinylFile} from './vinyl_file';

/**
* Our interface to the TypeScript standard compiler.
* If you write an Angular compiler plugin for another build tool,
* you should implement a similar interface.
*/
export interface CompilerInterface {
readConfiguration(project: string, basePath: string, existingOptions?: ts.CompilerOptions):
readConfiguration(
project: string|VinylFile, basePath: string, existingOptions?: ts.CompilerOptions):
{parsed: ts.ParsedCommandLine, ngOptions: AngularCompilerOptions};
typeCheck(compilerHost: ts.CompilerHost, program: ts.Program): void;
emit(program: ts.Program): number;
Expand Down Expand Up @@ -97,20 +99,30 @@ export class Tsc implements CompilerInterface {

constructor(private readFile = ts.sys.readFile, private readDirectory = ts.sys.readDirectory) {}

readConfiguration(project: string, basePath: string, existingOptions?: ts.CompilerOptions) {
readConfiguration(
project: string|VinylFile, basePath: string, existingOptions?: ts.CompilerOptions) {
this.basePath = basePath;

// Allow a directory containing tsconfig.json as the project value
// Note, TS@next returns an empty array, while earlier versions throw
try {
if (this.readDirectory(project).length > 0) {
if (!isVinylFile(project) && this.readDirectory(project).length > 0) {
project = path.join(project, 'tsconfig.json');
}
} catch (e) {
// Was not a directory, continue on assuming it's a file
}

const {config, error} = ts.readConfigFile(project, this.readFile);
let {config, error} = (() => {
// project is vinyl like file object
if (isVinylFile(project)) {
return {config: JSON.parse(project.contents.toString()), error: null};
}
// project is path to project file
else {
return ts.readConfigFile(project, this.readFile);
}
})();
check([error]);

// Do not inline `host` into `parseJsonConfigFileContent` until after
Expand Down
19 changes: 19 additions & 0 deletions tools/@angular/tsc-wrapped/src/vinyl_file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export interface VinylFile extends Object {
// Absolute path to the virtual file
path: string;

// Content of the virtual file
contents: Buffer;
}
;

export function isVinylFile(obj: any): obj is VinylFile {
return (typeof obj === 'object') && ('path' in obj) && ('contents' in obj);
};
29 changes: 29 additions & 0 deletions tools/@angular/tsc-wrapped/test/main.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,35 @@ describe('tsc-wrapped', () => {
.catch(e => done.fail(e));
});

it('should pre-process sources using config from vinyl like object', (done) => {
const config = {
path: basePath + '/tsconfig.json',
contents: new Buffer(JSON.stringify({
compilerOptions: {
experimentalDecorators: true,
types: [],
outDir: 'built',
declaration: true,
moduleResolution: 'node',
target: 'es2015'
},
angularCompilerOptions: {annotateForClosureCompiler: true},
files: ['test.ts']
}))
};

main(config, {basePath})
.then(() => {
const out = readOut('js');
// Expand `export *` and fix index import
expect(out).toContain(`export { A, B } from './dep/index'`);
// Annotated for Closure compiler
expect(out).toContain('* @param {?} x');
done();
})
.catch(e => done.fail(e));
});

it('should allow all options disabled', (done) => {
write('tsconfig.json', `{
"compilerOptions": {
Expand Down
24 changes: 19 additions & 5 deletions tools/@angular/tsc-wrapped/test/tsc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
*/

import * as ts from 'typescript';
import {Tsc} from '../src/tsc';
import {Tsc, tsc as pureTsc} from '../src/tsc';
import {VinylFile} from '../src/vinyl_file';

describe('options parsing', () => {

const tsc = new Tsc(
() => `
const configData = `
{
"angularCompilerOptions": {
"googleClosureOutput": true
Expand All @@ -21,8 +21,10 @@ describe('options parsing', () => {
"module": "commonjs",
"outDir": "built"
}
}`,
() => ['tsconfig.json']);
}`;

const tsc = new Tsc(() => configData, () => ['tsconfig.json']);
const config = {path: 'basePath/tsconfig.json', contents: new Buffer(configData)};

it('should combine all options into ngOptions', () => {
const {parsed, ngOptions} =
Expand All @@ -37,4 +39,16 @@ describe('options parsing', () => {
target: ts.ScriptTarget.ES2015
});
});

it('should combine all options into ngOptions from vinyl like object', () => {
const {parsed, ngOptions} = pureTsc.readConfiguration(config as VinylFile, 'basePath');

expect(ngOptions).toEqual({
genDir: 'basePath',
googleClosureOutput: true,
module: ts.ModuleKind.CommonJS,
outDir: 'basePath/built',
configFilePath: undefined
});
});
});

0 comments on commit 0c7726d

Please sign in to comment.