Skip to content

Commit

Permalink
feat(@angular-devkit/core): Jobs API added
Browse files Browse the repository at this point in the history
See the README for more details about usage.
  • Loading branch information
hansl authored and mgechev committed Dec 14, 2018
1 parent c89a042 commit a3a657f
Show file tree
Hide file tree
Showing 25 changed files with 3,447 additions and 2 deletions.
6 changes: 6 additions & 0 deletions etc/api/angular_devkit/core/node/_golden-api.d.ts
Expand Up @@ -39,6 +39,12 @@ export declare class NodeJsSyncHost implements virtualFs.Host<fs.Stats> {
write(path: Path, content: virtualFs.FileBuffer): Observable<void>;
}

export declare class NodeModuleJobRegistry<MinimumArgumentValueT extends JsonValue = JsonValue, MinimumInputValueT extends JsonValue = JsonValue, MinimumOutputValueT extends JsonValue = JsonValue> implements core_experimental.jobs.Registry<MinimumArgumentValueT, MinimumInputValueT, MinimumOutputValueT> {
constructor(_resolveLocal?: boolean, _resolveGlobal?: boolean);
protected _resolve(name: string): string | null;
get<A extends MinimumArgumentValueT, I extends MinimumInputValueT, O extends MinimumOutputValueT>(name: core_experimental.jobs.JobName): Observable<core_experimental.jobs.JobHandler<A, I, O> | null>;
}

export interface ProcessOutput {
write(buffer: string | Buffer): boolean;
}
Expand Down
1 change: 1 addition & 0 deletions packages/angular_devkit/core/BUILD
Expand Up @@ -109,6 +109,7 @@ ts_library(
deps = [
":core",
":node",
"//tests/angular_devkit/core/node/jobs:jobs_test_lib",
"@rxjs",
"@rxjs//operators",
"@npm//@types/node",
Expand Down
7 changes: 7 additions & 0 deletions packages/angular_devkit/core/node/_golden-api.ts
Expand Up @@ -5,6 +5,13 @@
* 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
*/

// Start experimental namespace
// Start jobs namespace
export * from './experimental/job-registry';
// End jobs namespace
// End experimental namespace

export * from './fs';
export * from './cli-logger';
export * from './host';
Expand Down
12 changes: 12 additions & 0 deletions packages/angular_devkit/core/node/experimental/index.ts
@@ -0,0 +1,12 @@
/**
* @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
*/
import * as jobs from './job-registry';

export {
jobs,
};
81 changes: 81 additions & 0 deletions packages/angular_devkit/core/node/experimental/job-registry.ts
@@ -0,0 +1,81 @@
/**
* @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
*/
import { Observable, of } from 'rxjs';
import { JsonValue, experimental as core_experimental, schema } from '../../src';
import { ModuleNotFoundException, resolve } from '../resolve';

export class NodeModuleJobRegistry<MinimumArgumentValueT extends JsonValue = JsonValue,
MinimumInputValueT extends JsonValue = JsonValue,
MinimumOutputValueT extends JsonValue = JsonValue,
> implements core_experimental.jobs.Registry<MinimumArgumentValueT,
MinimumInputValueT,
MinimumOutputValueT> {
public constructor(private _resolveLocal = true, private _resolveGlobal = false) {
}

protected _resolve(name: string): string | null {
try {
return resolve(name, {
checkLocal: this._resolveLocal,
checkGlobal: this._resolveGlobal,
basedir: __dirname,
});
} catch (e) {
if (e instanceof ModuleNotFoundException) {
return null;
}
throw e;
}
}

/**
* Get a job description for a named job.
*
* @param name The name of the job.
* @returns A description, or null if the job is not registered.
*/
get<A extends MinimumArgumentValueT,
I extends MinimumInputValueT,
O extends MinimumOutputValueT,
>(
name: core_experimental.jobs.JobName,
): Observable<core_experimental.jobs.JobHandler<A, I, O> | null> {
const [moduleName, exportName] = name.split(/#/, 2);

const resolvedPath = this._resolve(moduleName);
if (!resolvedPath) {
return of(null);
}

const pkg = require(resolvedPath);
const handler = pkg[exportName || 'default'];
if (!handler) {
return of(null);
}

// TODO: this should be unknown
// tslint:disable-next-line:no-any
function _getValue(...fields: any[]) {
return fields.find(x => schema.isJsonSchema(x)) || true;
}

const argument = _getValue(pkg.argument, handler.argument);
const input = _getValue(pkg.input, handler.input);
const output = _getValue(pkg.output, handler.output);
const channels = _getValue(pkg.channels, handler.channels);

return of(Object.assign(handler.bind(undefined), {
jobDescription: {
argument,
input,
output,
channels,
},
}));
}
}
@@ -0,0 +1,26 @@
/**
* @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
*/
import * as path from 'path';
import { experimental as core_experimental } from '../../src';
import { NodeModuleJobRegistry } from './job-registry';

const root = path.join(
path.dirname(require.resolve(__filename)),
'../../../../../tests/angular_devkit/core/node/jobs',
);


describe('NodeModuleJobScheduler', () => {
it('works', async () => {
const registry = new NodeModuleJobRegistry();
const scheduler = new core_experimental.jobs.SimpleScheduler(registry);

const job = scheduler.schedule(path.join(root, 'add'), [1, 2, 3]);
expect(await job.output.toPromise()).toBe(6);
});
});
2 changes: 2 additions & 0 deletions packages/angular_devkit/core/node/index.ts
Expand Up @@ -5,11 +5,13 @@
* 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
*/
import * as experimental from './experimental/job-registry';
import * as fs from './fs';
export * from './cli-logger';
export * from './host';
export { ModuleNotFoundException, ResolveOptions, resolve } from './resolve';

export {
experimental,
fs,
};
6 changes: 5 additions & 1 deletion packages/angular_devkit/core/src/experimental.ts
Expand Up @@ -5,6 +5,10 @@
* 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
*/
import * as jobs from './experimental/jobs/index';
import * as workspace from './workspace/index';

export { workspace };
export {
jobs,
workspace,
};

0 comments on commit a3a657f

Please sign in to comment.