2018-07-16 08:49:56 +01:00
|
|
|
/**
|
|
|
|
* @license
|
2020-05-19 12:08:49 -07:00
|
|
|
* Copyright Google LLC All Rights Reserved.
|
2018-07-16 08:49:56 +01:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
2019-08-29 18:47:54 +03:00
|
|
|
|
|
|
|
/// <reference types="node" />
|
|
|
|
|
2020-12-30 17:03:41 +00:00
|
|
|
import {AbsoluteFsPath, FileSystem, ReadonlyFileSystem} from '../../src/ngtsc/file_system';
|
2020-05-14 20:06:12 +01:00
|
|
|
import {Logger} from '../../src/ngtsc/logging';
|
2020-06-04 08:43:05 +01:00
|
|
|
import {ParsedConfiguration} from '../../src/perform_compile';
|
2019-08-04 18:04:03 +03:00
|
|
|
|
2019-04-29 18:51:52 +01:00
|
|
|
import {CommonJsDependencyHost} from './dependencies/commonjs_dependency_host';
|
2020-04-15 11:40:41 +01:00
|
|
|
import {DependencyResolver} from './dependencies/dependency_resolver';
|
2020-01-08 19:10:25 +02:00
|
|
|
import {DtsDependencyHost} from './dependencies/dts_dependency_host';
|
2019-04-28 20:47:57 +01:00
|
|
|
import {EsmDependencyHost} from './dependencies/esm_dependency_host';
|
|
|
|
import {ModuleResolver} from './dependencies/module_resolver';
|
2019-04-28 20:48:35 +01:00
|
|
|
import {UmdDependencyHost} from './dependencies/umd_dependency_host';
|
2019-05-16 08:53:19 +01:00
|
|
|
import {DirectoryWalkerEntryPointFinder} from './entry_point_finder/directory_walker_entry_point_finder';
|
2020-06-22 13:12:56 +01:00
|
|
|
import {EntryPointCollector} from './entry_point_finder/entry_point_collector';
|
2020-01-30 14:29:15 +00:00
|
|
|
import {EntryPointFinder} from './entry_point_finder/interface';
|
2020-06-04 08:43:05 +01:00
|
|
|
import {ProgramBasedEntryPointFinder} from './entry_point_finder/program_based_entry_point_finder';
|
2019-05-16 08:53:19 +01:00
|
|
|
import {TargetedEntryPointFinder} from './entry_point_finder/targeted_entry_point_finder';
|
2020-04-15 11:40:41 +01:00
|
|
|
import {getAnalyzeEntryPointsFn} from './execution/analyze_entry_points';
|
|
|
|
import {Executor} from './execution/api';
|
2019-08-29 18:47:54 +03:00
|
|
|
import {ClusterExecutor} from './execution/cluster/executor';
|
2020-04-15 11:40:41 +01:00
|
|
|
import {getCreateCompileFn} from './execution/create_compile_function';
|
2020-02-03 20:25:15 +00:00
|
|
|
import {SingleProcessExecutorAsync, SingleProcessExecutorSync} from './execution/single_process_executor';
|
2020-04-15 16:23:30 +01:00
|
|
|
import {CreateTaskCompletedCallback, TaskProcessingOutcome} from './execution/tasks/api';
|
2020-03-16 15:08:47 +00:00
|
|
|
import {composeTaskCompletedCallbacks, createLogErrorHandler, createMarkAsProcessedHandler, createThrowErrorHandler} from './execution/tasks/completion';
|
2020-03-04 12:49:36 +00:00
|
|
|
import {AsyncLocker} from './locking/async_locker';
|
2020-03-04 21:50:00 +00:00
|
|
|
import {LockFileWithChildProcess} from './locking/lock_file_with_child_process';
|
2020-03-04 12:49:36 +00:00
|
|
|
import {SyncLocker} from './locking/sync_locker';
|
2020-09-14 14:19:30 +02:00
|
|
|
import {AsyncNgccOptions, getMaxNumberOfWorkers, getSharedSetup, SyncNgccOptions} from './ngcc_options';
|
2019-05-21 15:23:24 +01:00
|
|
|
import {NgccConfiguration} from './packages/configuration';
|
2020-04-15 11:40:41 +01:00
|
|
|
import {EntryPointJsonProperty, SUPPORTED_FORMAT_PROPERTIES} from './packages/entry_point';
|
2020-03-10 10:49:17 +00:00
|
|
|
import {EntryPointManifest, InvalidatingEntryPointManifest} from './packages/entry_point_manifest';
|
2020-04-29 21:28:29 +03:00
|
|
|
import {PathMappings} from './path_mappings';
|
2020-04-29 21:28:22 +03:00
|
|
|
import {FileWriter} from './writing/file_writer';
|
2019-08-12 18:15:24 +03:00
|
|
|
import {DirectPackageJsonUpdater, PackageJsonUpdater} from './writing/package_json_updater';
|
2018-07-16 08:49:56 +01:00
|
|
|
|
2019-03-20 13:47:58 +00:00
|
|
|
/**
|
|
|
|
* This is the main entry-point into ngcc (aNGular Compatibility Compiler).
|
|
|
|
*
|
|
|
|
* You can call this function to process one or more npm packages, to ensure
|
|
|
|
* that they are compatible with the ivy compiler (ngtsc).
|
|
|
|
*
|
|
|
|
* @param options The options telling ngcc what to compile and how.
|
|
|
|
*/
|
2020-05-12 08:19:59 +01:00
|
|
|
export function mainNgcc<T extends AsyncNgccOptions|SyncNgccOptions>(options: T):
|
|
|
|
T extends AsyncNgccOptions ? Promise<void>: void;
|
|
|
|
export function mainNgcc(options: AsyncNgccOptions|SyncNgccOptions): void|Promise<void> {
|
2020-04-16 15:54:40 +01:00
|
|
|
const {
|
|
|
|
basePath,
|
|
|
|
targetEntryPointPath,
|
|
|
|
propertiesToConsider,
|
refactor(ngcc): support processing only the typings files of packages (#40976)
Some tools (such as Language Server and ng-packagr) only care about
the processed typings generated by ngcc. Forcing these tools to process
the JavaScript files as well has two disadvantages:
First, unnecessary work is being done, which is time consuming.
But more importantly, it is not always possible to know how the final bundling
tools will want the processed JavaScript to be configured. For example,
the CLI would prefer the `--create-ivy-entry-points` option but this would
break non-CLI build tooling.
This commit adds a new option (`--typings-only` on the command line, and
`typingsOnly` via programmatic API) that instructs ngcc to only render changes
to the typings files for the entry-points that it finds, and not to write any
JavaScript files.
In order to process the typings, a JavaScript format will need to be analysed, but
it will not be rendered to disk. When using this option, it is best to offer ngcc a
wide range of possible JavaScript formats to choose from, and it will use the
first format that it finds. Ideally you would configure it to try the `ES2015` FESM
format first, since this will be the most performant.
Fixes #40969
PR Close #40976
2021-02-24 10:36:16 +00:00
|
|
|
typingsOnly,
|
2020-04-16 15:54:40 +01:00
|
|
|
compileAllFormats,
|
|
|
|
logger,
|
|
|
|
pathMappings,
|
|
|
|
async,
|
|
|
|
errorOnFailedEntryPoint,
|
|
|
|
enableI18nLegacyMessageIdFormat,
|
|
|
|
invalidateEntryPointManifest,
|
|
|
|
fileSystem,
|
|
|
|
absBasePath,
|
|
|
|
projectPath,
|
2020-04-29 21:28:22 +03:00
|
|
|
tsConfig,
|
|
|
|
getFileWriter,
|
2020-04-16 15:54:40 +01:00
|
|
|
} = getSharedSetup(options);
|
2019-08-29 18:47:54 +03:00
|
|
|
|
2020-03-20 22:09:40 +00:00
|
|
|
const config = new NgccConfiguration(fileSystem, projectPath);
|
2020-02-25 15:51:54 +00:00
|
|
|
const dependencyResolver = getDependencyResolver(fileSystem, logger, config, pathMappings);
|
2020-03-10 10:49:17 +00:00
|
|
|
const entryPointManifest = invalidateEntryPointManifest ?
|
|
|
|
new InvalidatingEntryPointManifest(fileSystem, config, logger) :
|
|
|
|
new EntryPointManifest(fileSystem, config, logger);
|
2020-01-16 09:47:54 +00:00
|
|
|
|
|
|
|
// Bail out early if the work is already done.
|
|
|
|
const supportedPropertiesToConsider = ensureSupportedProperties(propertiesToConsider);
|
2020-12-30 17:03:41 +00:00
|
|
|
const absoluteTargetEntryPointPath = targetEntryPointPath !== undefined ?
|
|
|
|
fileSystem.resolve(basePath, targetEntryPointPath) :
|
|
|
|
null;
|
2020-01-30 14:29:15 +00:00
|
|
|
const finder = getEntryPointFinder(
|
2020-03-10 10:49:17 +00:00
|
|
|
fileSystem, logger, dependencyResolver, config, entryPointManifest, absBasePath,
|
2020-06-04 08:43:05 +01:00
|
|
|
absoluteTargetEntryPointPath, pathMappings,
|
|
|
|
options.findEntryPointsFromTsConfigProgram ? tsConfig : null, projectPath);
|
2020-01-30 14:29:15 +00:00
|
|
|
if (finder instanceof TargetedEntryPointFinder &&
|
|
|
|
!finder.targetNeedsProcessingOrCleaning(supportedPropertiesToConsider, compileAllFormats)) {
|
2020-01-16 09:47:54 +00:00
|
|
|
logger.debug('The target entry-point has already been processed');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-09-14 14:19:30 +02:00
|
|
|
// Determine the number of workers to use and whether ngcc should run in parallel.
|
|
|
|
const workerCount = async ? getMaxNumberOfWorkers() : 1;
|
|
|
|
const inParallel = workerCount > 1;
|
2019-08-07 22:46:35 +03:00
|
|
|
|
2020-04-15 11:40:41 +01:00
|
|
|
const analyzeEntryPoints = getAnalyzeEntryPointsFn(
|
refactor(ngcc): support processing only the typings files of packages (#40976)
Some tools (such as Language Server and ng-packagr) only care about
the processed typings generated by ngcc. Forcing these tools to process
the JavaScript files as well has two disadvantages:
First, unnecessary work is being done, which is time consuming.
But more importantly, it is not always possible to know how the final bundling
tools will want the processed JavaScript to be configured. For example,
the CLI would prefer the `--create-ivy-entry-points` option but this would
break non-CLI build tooling.
This commit adds a new option (`--typings-only` on the command line, and
`typingsOnly` via programmatic API) that instructs ngcc to only render changes
to the typings files for the entry-points that it finds, and not to write any
JavaScript files.
In order to process the typings, a JavaScript format will need to be analysed, but
it will not be rendered to disk. When using this option, it is best to offer ngcc a
wide range of possible JavaScript formats to choose from, and it will use the
first format that it finds. Ideally you would configure it to try the `ES2015` FESM
format first, since this will be the most performant.
Fixes #40969
PR Close #40976
2021-02-24 10:36:16 +00:00
|
|
|
logger, finder, fileSystem, supportedPropertiesToConsider, typingsOnly, compileAllFormats,
|
2020-04-15 11:40:41 +01:00
|
|
|
propertiesToConsider, inParallel);
|
2019-08-07 22:46:35 +03:00
|
|
|
|
2020-04-29 21:28:22 +03:00
|
|
|
// Create an updater that will actually write to disk.
|
2020-04-16 15:54:40 +01:00
|
|
|
const pkgJsonUpdater = new DirectPackageJsonUpdater(fileSystem);
|
2020-04-29 21:28:22 +03:00
|
|
|
const fileWriter = getFileWriter(pkgJsonUpdater);
|
2020-04-16 15:54:40 +01:00
|
|
|
|
2019-08-07 22:46:35 +03:00
|
|
|
// The function for creating the `compile()` function.
|
2020-04-15 11:40:41 +01:00
|
|
|
const createCompileFn = getCreateCompileFn(
|
2020-04-29 21:28:22 +03:00
|
|
|
fileSystem, logger, fileWriter, enableI18nLegacyMessageIdFormat, tsConfig, pathMappings);
|
2019-08-07 22:46:35 +03:00
|
|
|
|
2019-08-19 17:10:09 +03:00
|
|
|
// The executor for actually planning and getting the work done.
|
2020-03-16 15:08:47 +00:00
|
|
|
const createTaskCompletedCallback =
|
|
|
|
getCreateTaskCompletedCallback(pkgJsonUpdater, errorOnFailedEntryPoint, logger, fileSystem);
|
2020-03-14 13:38:27 +00:00
|
|
|
const executor = getExecutor(
|
2020-09-14 14:19:30 +02:00
|
|
|
async, workerCount, logger, fileWriter, pkgJsonUpdater, fileSystem, config,
|
2020-04-29 21:28:22 +03:00
|
|
|
createTaskCompletedCallback);
|
2019-08-07 22:46:35 +03:00
|
|
|
|
refactor(ngcc): take advantage of early knowledge about format property processability (#32427)
In the past, a task's processability didn't use to be known in advance.
It was possible that a task would be created and added to the queue
during the analysis phase and then later (during the compilation phase)
it would be found out that the task (i.e. the associated format
property) was not processable.
As a result, certain checks had to be delayed, until a task's processing
had started or even until all tasks had been processed. Examples of
checks that had to be delayed are:
- Whether a task can be skipped due to `compileAllFormats: false`.
- Whether there were entry-points for which no format at all was
successfully processed.
It turns out that (as made clear by the refactoring in 9537b2ff8), once
a task starts being processed it is expected to either complete
successfully (with the associated format being processed) or throw an
error (in which case the process will exit). In other words, a task's
processability is known in advance.
This commit takes advantage of this fact by moving certain checks
earlier in the process (e.g. in the analysis phase instead of the
compilation phase), which in turn allows avoiding some unnecessary work.
More specifically:
- When `compileAllFormats` is `false`, tasks are created _only_ for the
first suitable format property for each entry-point, since the rest of
the tasks would have been skipped during the compilation phase anyway.
This has the following advantages:
1. It avoids the slight overhead of generating extraneous tasks and
then starting to process them (before realizing they should be
skipped).
2. In a potential future parallel execution mode, unnecessary tasks
might start being processed at the same time as the first (useful)
task, even if their output would be later discarded, wasting
resources. Alternatively, extra logic would have to be added to
prevent this from happening. The change in this commit avoids these
issues.
- When an entry-point is not processable, an error will be thrown
upfront without having to wait for other tasks to be processed before
failing.
PR Close #32427
2019-08-29 01:33:15 +03:00
|
|
|
return executor.execute(analyzeEntryPoints, createCompileFn);
|
2019-08-06 00:53:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function ensureSupportedProperties(properties: string[]): EntryPointJsonProperty[] {
|
|
|
|
// Short-circuit the case where `properties` has fallen back to the default value:
|
|
|
|
// `SUPPORTED_FORMAT_PROPERTIES`
|
|
|
|
if (properties === SUPPORTED_FORMAT_PROPERTIES) return SUPPORTED_FORMAT_PROPERTIES;
|
|
|
|
|
|
|
|
const supportedProperties: EntryPointJsonProperty[] = [];
|
|
|
|
|
|
|
|
for (const prop of properties as EntryPointJsonProperty[]) {
|
|
|
|
if (SUPPORTED_FORMAT_PROPERTIES.indexOf(prop) !== -1) {
|
|
|
|
supportedProperties.push(prop);
|
2019-03-20 13:47:58 +00:00
|
|
|
}
|
2019-06-06 20:22:32 +01:00
|
|
|
}
|
2019-08-06 00:53:38 +03:00
|
|
|
|
|
|
|
if (supportedProperties.length === 0) {
|
|
|
|
throw new Error(
|
|
|
|
`No supported format property to consider among [${properties.join(', ')}]. ` +
|
|
|
|
`Supported properties: ${SUPPORTED_FORMAT_PROPERTIES.join(', ')}`);
|
|
|
|
}
|
|
|
|
|
|
|
|
return supportedProperties;
|
2018-08-09 13:54:20 +01:00
|
|
|
}
|
2019-03-20 13:47:59 +00:00
|
|
|
|
2020-03-14 13:38:27 +00:00
|
|
|
function getCreateTaskCompletedCallback(
|
2020-03-16 15:08:47 +00:00
|
|
|
pkgJsonUpdater: PackageJsonUpdater, errorOnFailedEntryPoint: boolean, logger: Logger,
|
2020-12-30 17:03:41 +00:00
|
|
|
fileSystem: ReadonlyFileSystem): CreateTaskCompletedCallback {
|
2020-03-16 15:08:47 +00:00
|
|
|
return taskQueue => composeTaskCompletedCallbacks({
|
2020-12-30 17:03:41 +00:00
|
|
|
[TaskProcessingOutcome.Processed]:
|
|
|
|
createMarkAsProcessedHandler(fileSystem, pkgJsonUpdater),
|
2020-03-16 15:08:47 +00:00
|
|
|
[TaskProcessingOutcome.Failed]:
|
|
|
|
errorOnFailedEntryPoint ? createThrowErrorHandler(fileSystem) :
|
|
|
|
createLogErrorHandler(logger, fileSystem, taskQueue),
|
2020-03-14 13:38:27 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-08-29 18:47:54 +03:00
|
|
|
function getExecutor(
|
2020-09-14 14:19:30 +02:00
|
|
|
async: boolean, workerCount: number, logger: Logger, fileWriter: FileWriter,
|
2020-04-28 15:32:05 +01:00
|
|
|
pkgJsonUpdater: PackageJsonUpdater, fileSystem: FileSystem, config: NgccConfiguration,
|
2020-04-29 21:28:22 +03:00
|
|
|
createTaskCompletedCallback: CreateTaskCompletedCallback): Executor {
|
2020-04-16 09:39:28 +01:00
|
|
|
const lockFile = new LockFileWithChildProcess(fileSystem, logger);
|
2020-02-03 20:25:15 +00:00
|
|
|
if (async) {
|
|
|
|
// Execute asynchronously (either serially or in parallel)
|
2020-04-28 15:32:05 +01:00
|
|
|
const {retryAttempts, retryDelay} = config.getLockingConfig();
|
|
|
|
const locker = new AsyncLocker(lockFile, logger, retryDelay, retryAttempts);
|
2020-09-14 14:19:30 +02:00
|
|
|
if (workerCount > 1) {
|
|
|
|
// Execute in parallel.
|
2020-03-14 13:38:27 +00:00
|
|
|
return new ClusterExecutor(
|
2020-04-29 21:28:22 +03:00
|
|
|
workerCount, fileSystem, logger, fileWriter, pkgJsonUpdater, locker,
|
|
|
|
createTaskCompletedCallback);
|
2020-02-03 20:25:15 +00:00
|
|
|
} else {
|
|
|
|
// Execute serially, on a single thread (async).
|
2020-03-14 13:38:27 +00:00
|
|
|
return new SingleProcessExecutorAsync(logger, locker, createTaskCompletedCallback);
|
2020-02-03 20:25:15 +00:00
|
|
|
}
|
refactor(ngcc): add support for asynchronous execution (#32427)
Previously, `ngcc`'s programmatic API would run and complete
synchronously. This was necessary for specific usecases (such as how the
`@angular/cli` invokes `ngcc` as part of the TypeScript module
resolution process), but not for others (e.g. running `ivy-ngcc` as a
`postinstall` script).
This commit adds a new option (`async`) that enables turning on
asynchronous execution. I.e. it signals that the caller is OK with the
function call to complete asynchronously, which allows `ngcc` to
potentially run in a more efficient mode.
Currently, there is no difference in the way tasks are executed in sync
vs async mode, but this change sets the ground for adding new execution
options (that require asynchronous operation), such as processing tasks
in parallel on multiple processes.
NOTE:
When using the programmatic API, the default value for `async` is
`false`, thus retaining backwards compatibility.
When running `ngcc` from the command line (i.e. via the `ivy-ngcc`
script), it runs in async mode (to be able to take advantage of future
optimizations), but that is transparent to the caller.
PR Close #32427
2019-08-19 22:58:22 +03:00
|
|
|
} else {
|
2020-02-03 20:25:15 +00:00
|
|
|
// Execute serially, on a single thread (sync).
|
2020-03-14 13:38:27 +00:00
|
|
|
return new SingleProcessExecutorSync(
|
|
|
|
logger, new SyncLocker(lockFile), createTaskCompletedCallback);
|
refactor(ngcc): add support for asynchronous execution (#32427)
Previously, `ngcc`'s programmatic API would run and complete
synchronously. This was necessary for specific usecases (such as how the
`@angular/cli` invokes `ngcc` as part of the TypeScript module
resolution process), but not for others (e.g. running `ivy-ngcc` as a
`postinstall` script).
This commit adds a new option (`async`) that enables turning on
asynchronous execution. I.e. it signals that the caller is OK with the
function call to complete asynchronously, which allows `ngcc` to
potentially run in a more efficient mode.
Currently, there is no difference in the way tasks are executed in sync
vs async mode, but this change sets the ground for adding new execution
options (that require asynchronous operation), such as processing tasks
in parallel on multiple processes.
NOTE:
When using the programmatic API, the default value for `async` is
`false`, thus retaining backwards compatibility.
When running `ngcc` from the command line (i.e. via the `ivy-ngcc`
script), it runs in async mode (to be able to take advantage of future
optimizations), but that is transparent to the caller.
PR Close #32427
2019-08-19 22:58:22 +03:00
|
|
|
}
|
2019-08-19 17:10:09 +03:00
|
|
|
}
|
|
|
|
|
2020-01-30 14:29:15 +00:00
|
|
|
function getDependencyResolver(
|
2020-12-30 17:03:41 +00:00
|
|
|
fileSystem: ReadonlyFileSystem, logger: Logger, config: NgccConfiguration,
|
2020-04-06 08:30:08 +01:00
|
|
|
pathMappings: PathMappings|undefined): DependencyResolver {
|
2020-01-30 14:29:15 +00:00
|
|
|
const moduleResolver = new ModuleResolver(fileSystem, pathMappings);
|
|
|
|
const esmDependencyHost = new EsmDependencyHost(fileSystem, moduleResolver);
|
|
|
|
const umdDependencyHost = new UmdDependencyHost(fileSystem, moduleResolver);
|
|
|
|
const commonJsDependencyHost = new CommonJsDependencyHost(fileSystem, moduleResolver);
|
|
|
|
const dtsDependencyHost = new DtsDependencyHost(fileSystem, pathMappings);
|
|
|
|
return new DependencyResolver(
|
2020-02-25 15:51:54 +00:00
|
|
|
fileSystem, logger, config, {
|
2020-01-30 14:29:15 +00:00
|
|
|
esm5: esmDependencyHost,
|
|
|
|
esm2015: esmDependencyHost,
|
|
|
|
umd: umdDependencyHost,
|
|
|
|
commonjs: commonJsDependencyHost
|
|
|
|
},
|
|
|
|
dtsDependencyHost);
|
2019-05-16 08:53:19 +01:00
|
|
|
}
|
|
|
|
|
2020-01-30 14:29:15 +00:00
|
|
|
function getEntryPointFinder(
|
2020-12-30 17:03:41 +00:00
|
|
|
fs: ReadonlyFileSystem, logger: Logger, resolver: DependencyResolver, config: NgccConfiguration,
|
2020-03-10 10:49:17 +00:00
|
|
|
entryPointManifest: EntryPointManifest, basePath: AbsoluteFsPath,
|
2020-06-04 08:43:05 +01:00
|
|
|
absoluteTargetEntryPointPath: AbsoluteFsPath|null, pathMappings: PathMappings|undefined,
|
|
|
|
tsConfig: ParsedConfiguration|null, projectPath: AbsoluteFsPath): EntryPointFinder {
|
2020-01-30 14:29:15 +00:00
|
|
|
if (absoluteTargetEntryPointPath !== null) {
|
|
|
|
return new TargetedEntryPointFinder(
|
2020-06-04 08:43:05 +01:00
|
|
|
fs, config, logger, resolver, basePath, pathMappings, absoluteTargetEntryPointPath);
|
2020-06-22 13:12:56 +01:00
|
|
|
} else {
|
|
|
|
const entryPointCollector = new EntryPointCollector(fs, config, logger, resolver);
|
|
|
|
if (tsConfig !== null) {
|
|
|
|
return new ProgramBasedEntryPointFinder(
|
|
|
|
fs, config, logger, resolver, entryPointCollector, entryPointManifest, basePath, tsConfig,
|
|
|
|
projectPath);
|
|
|
|
} else {
|
|
|
|
return new DirectoryWalkerEntryPointFinder(
|
|
|
|
logger, resolver, entryPointCollector, entryPointManifest, basePath, pathMappings);
|
|
|
|
}
|
2019-04-06 15:35:40 +01:00
|
|
|
}
|
|
|
|
}
|