@angular-devkit/core#logging TypeScript Examples

The following examples show how to use @angular-devkit/core#logging. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index_spec.ts    From source-map-analyzer with MIT License 5 votes vote down vote up
describe('Command Runner Builder', () => {
 let architect: Architect;
 let architectHost: TestingArchitectHost;

 
 beforeEach(async () => {
   const registry = new schema.CoreSchemaRegistry();
   registry.addPostTransform(schema.transforms.addUndefinedDefaults);

 
   // Arguments to TestingArchitectHost are workspace and current directories.
   // Since we don't use those, both are the same in this case.
   architectHost = new TestingArchitectHost(__dirname, __dirname);
   architect = new Architect(architectHost, registry);

 
   // This will either take a Node package name, or a path to the directory
   // for the package.json file.
   await architectHost.addBuilderFromPackage(join(__dirname, '..'));
   console.log('#', Array.from((architectHost as any)._builderMap.keys()))
 });

 
 // This might not work in Windows.
 it('can run ls', async () => {
   // Create a logger that keeps an array of all messages that were logged.
   const logger = new logging.Logger('');
   const logs: string[] = [];
   logger.subscribe(ev => logs.push(ev.message));
 
   // A "run" can contain multiple outputs, and contains progress information.
   const run = await architect.scheduleBuilder('@example/command-runner:command', {
     command: 'ls',
     args: [__dirname],
   }, { logger });  // We pass the logger for checking later.

 
   // The "result" member is the next output of the runner.
   // This is of type BuilderOutput.
   const output = await run.result;
  
   // Stop the builder from running. This really stops Architect from keeping
   // the builder associated states in memory, since builders keep waiting
   // to be scheduled.
   await run.stop();
 
   // Expect that it succeeded.
   expect(output.success).toBe(true);
 
   // Expect that this file was listed. It should be since we're running
   // `ls $__dirname`.
   expect(logs.toString()).toContain('index_spec.ts');
 });
});
Example #2
Source File: index.ts    From angular-miniprogram with MIT License 5 votes vote down vote up
logger = new logging.Logger(`builder-harness-${this.id}`);
Example #3
Source File: karma.ts    From angular-miniprogram with MIT License 4 votes vote down vote up
function init(
  config: ConfigOptions & {
    buildWebpack: {
      logger: logging.Logger;
      failureCb: () => void;
      successCb: () => void;
      testContext: { buildSuccess: (arg: webpack.Configuration) => void };
      webpackConfig: webpack.Configuration;
    };
    configFile?: string;
    webpack?: webpack.Configuration;
  },
  emitter: any
) {
  if (!config.buildWebpack) {
    throw new Error(
      `The '@angular-devkit/build-angular/plugins/karma' karma plugin is meant to` +
        ` be used from within Angular CLI and will not work correctly outside of it.`
    );
  }
  // const options = config.buildWebpack.options as BuildOptions;
  const logger: logging.Logger =
    config.buildWebpack.logger || createConsoleLogger();
  successCb = config.buildWebpack.successCb;
  failureCb = config.buildWebpack.failureCb;

  config.reporters?.unshift('@angular-devkit/build-angular--event-reporter');
  // todo 可能用不上,因为时本地
  // When using code-coverage, auto-add karma-coverage.
  // if (
  //   options!.codeCoverage &&
  //   !config.reporters.some((r: string) => r === 'coverage' || r === 'coverage-istanbul')
  // ) {
  //   config.reporters.push('coverage');
  // }

  // Add webpack config.
  const webpackConfig = config.buildWebpack
    .webpackConfig as webpack.Configuration;

  // Use existing config if any.
  config.webpack = { ...webpackConfig, ...config.webpack };

  // Our custom context and debug files list the webpack bundles directly instead of using
  // the karma files array.

  if (config.singleRun) {
    // There's no option to turn off file watching in webpack-dev-server, but
    // we can override the file watcher instead.
    (webpackConfig.plugins as any[]).unshift({
      apply: (compiler: any) => {
        compiler.hooks.afterEnvironment.tap('karma', () => {
          compiler.watchFileSystem = { watch: () => {} };
        });
      },
    });
  }
  webpackConfig.plugins!.push(
    new webpack.DefinePlugin({
      KARMA_CLIENT_CONFIG: JSON.stringify(config.client),
      KARMA_PORT: config.port,
    })
  );
  // Files need to be served from a custom path for Karma.
  const compiler = webpack.webpack(webpackConfig, (error, stats) => {
    if (error) {
      throw error;
    }

    if (stats?.hasErrors()) {
      // Only generate needed JSON stats and when needed.
      const statsJson = stats?.toJson({
        all: false,
        children: true,
        errors: true,
        warnings: true,
      });

      logger.error(statsErrorsToString(statsJson, { colors: true }));

      // Notify potential listeners of the compile error.
      emitter.emit('compile_error', {
        errors: statsJson.errors?.map((e) => e.message),
      });

      // Finish Karma run early in case of compilation error.
      emitter.emit('run_complete', [], { exitCode: 1 });

      // Emit a failure build event if there are compilation errors.
      failureCb();
      return;
    }
    // 仅测试时使用
    if (config.buildWebpack.testContext) {
      config.buildWebpack.testContext.buildSuccess(webpackConfig);
    }
  });

  function handler(callback?: () => void): void {
    isBlocked = true;
    callback?.();
  }

  compiler.hooks.invalid.tap('karma', () => handler(() => {}));
  compiler.hooks.watchRun.tapAsync('karma', (_: any, callback: () => void) =>
    handler(callback)
  );
  compiler.hooks.run.tapAsync('karma', (_: any, callback: () => void) =>
    handler(callback)
  );

  function unblock() {
    isBlocked = false;
    blocked.forEach((cb) => cb());
    blocked = [];
  }

  let lastCompilationHash: string | undefined;
  compiler.hooks.done.tap('karma', (stats) => {
    if (stats.hasErrors()) {
      lastCompilationHash = undefined;
    } else if (stats.hash != lastCompilationHash) {
      // Refresh karma only when there are no webpack errors, and if the compilation changed.
      lastCompilationHash = stats.hash;
      emitter.refreshFiles();
    }
    unblock();
  });

  emitter.on('exit', (done: any) => {
    done();
  });
}
Example #4
Source File: index.ts    From angular-miniprogram with MIT License 4 votes vote down vote up
execute(
    options: Partial<BuilderHarnessExecutionOptions> = {}
  ): Observable<BuilderHarnessExecutionResult> {
    const {
      configuration,
      outputLogsOnException = true,
      outputLogsOnFailure = true,
      useNativeFileWatching = false,
    } = options;

    const targetOptions = {
      ...this.options.get(null),
      ...((configuration && this.options.get(configuration)) ?? {}),
    };

    if (!useNativeFileWatching) {
      if (this.watcherNotifier) {
        throw new Error('Only one harness execution at a time is supported.');
      }
      this.watcherNotifier = new WatcherNotifier();
    }

    const contextHost: ContextHost = {
      findBuilderByTarget: async (project, target) => {
        this.validateProjectName(project);
        if (target === this.targetName) {
          return {
            info: this.builderInfo,
            handler: this.builderHandler as BuilderHandlerFn<json.JsonObject>,
          };
        }

        const builderTarget = this.builderTargets.get(target);
        if (builderTarget) {
          return { info: builderTarget.info, handler: builderTarget.handler };
        }

        throw new Error('Project target does not exist.');
      },
      async getBuilderName(project, target) {
        return (await this.findBuilderByTarget(project, target)).info
          .builderName;
      },
      getMetadata: async (project) => {
        this.validateProjectName(project);

        return this.projectMetadata as json.JsonObject;
      },
      getOptions: async (project, target, configuration) => {
        this.validateProjectName(project);
        if (target === this.targetName) {
          return this.options.get(configuration ?? null) ?? {};
        } else if (configuration !== undefined) {
          // Harness builder targets currently do not support configurations
          return {};
        } else {
          return (
            (this.builderTargets.get(target)?.options as json.JsonObject) || {}
          );
        }
      },
      hasTarget: async (project, target) => {
        this.validateProjectName(project);

        return this.targetName === target || this.builderTargets.has(target);
      },
      getDefaultConfigurationName: async (_project, _target) => {
        return undefined;
      },
      validate: async (options, builderName) => {
        let schema;
        if (builderName === this.builderInfo.builderName) {
          schema = this.builderInfo.optionSchema;
        } else {
          for (const [, value] of this.builderTargets) {
            if (value.info.builderName === builderName) {
              schema = value.info.optionSchema;
              break;
            }
          }
        }

        const validator = await this.schemaRegistry
          .compile(schema ?? true)
          .toPromise();
        const { data } = await validator(options).toPromise();

        return data as json.JsonObject;
      },
    };
    const context = new HarnessBuilderContext(
      this.builderInfo,
      getSystemPath(this.host.root()),
      contextHost,
      useNativeFileWatching ? undefined : this.watcherNotifier,
      options.testContext
    );
    if (this.targetName !== undefined) {
      context.target = {
        project: this.projectName,
        target: this.targetName,
        configuration: configuration as string,
      };
    }

    const logs: logging.LogEntry[] = [];
    context.logger.subscribe((e) => logs.push(e));

    return this.schemaRegistry.compile(this.builderInfo.optionSchema).pipe(
      mergeMap((validator) => validator(targetOptions as any)),
      map((validationResult) => validationResult.data),
      mergeMap((data) =>
        convertBuilderOutputToObservable(
          this.builderHandler(data as T & json.JsonObject, context)
        )
      ),
      map((buildResult) => ({ result: buildResult, error: undefined })),
      catchError((error) => {
        if (outputLogsOnException) {
          // eslint-disable-next-line no-console
          console.error(logs.map((entry) => entry.message).join('\n'));
          // eslint-disable-next-line no-console
          console.error(error);
        }

        return of({ result: undefined, error });
      }),
      map(({ result, error }) => {
        if (
          outputLogsOnFailure &&
          result?.success === false &&
          logs.length > 0
        ) {
          // eslint-disable-next-line no-console
          console.error(logs.map((entry) => entry.message).join('\n'));
        }

        // Capture current logs and clear for next
        const currentLogs = logs.slice();
        logs.length = 0;

        return { result, error, logs: currentLogs };
      }),
      finalize(() => {
        this.watcherNotifier = undefined;

        for (const teardown of context.teardowns) {
          // eslint-disable-next-line @typescript-eslint/no-floating-promises
          teardown();
        }
      })
    );
  }