Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use single scanner for plugin class scan #21104

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@
*/
package com.vaadin.gradle

import com.vaadin.experimental.FeatureFlags
import com.vaadin.flow.plugin.base.BuildFrontendUtil
import com.vaadin.flow.server.Constants
import com.vaadin.flow.server.frontend.BundleValidationUtil
import com.vaadin.flow.server.frontend.FrontendUtils
import com.vaadin.flow.server.frontend.TaskCleanFrontendFiles
import com.vaadin.flow.server.frontend.scanner.ClassFinder
import com.vaadin.flow.server.frontend.scanner.FrontendDependenciesScanner
import com.vaadin.flow.server.frontend.scanner.FrontendDependenciesScanner.FrontendDependenciesScannerFactory
import com.vaadin.pro.licensechecker.LicenseChecker
import org.gradle.api.DefaultTask
import org.gradle.api.provider.Property
Expand Down Expand Up @@ -80,9 +84,26 @@ public abstract class VaadinBuildFrontendTask : DefaultTask() {
check(tokenFile.exists()) { "token file $tokenFile doesn't exist!" }

val cleanTask = TaskCleanFrontendFiles(config.npmFolder.get(),
BuildFrontendUtil.getGeneratedFrontendDirectory(adapter.get()), adapter.get().classFinder
BuildFrontendUtil.getGeneratedFrontendDirectory(adapter.get()), adapter.get().classFinder)

val reactEnabled: Boolean = adapter.get().isReactEnabled()
&& FrontendUtils.isReactRouterRequired(
BuildFrontendUtil.getFrontendDirectory(adapter.get())
)
val featureFlags: FeatureFlags = FeatureFlags(
adapter.get().createLookup(adapter.get().getClassFinder())
)
BuildFrontendUtil.runNodeUpdater(adapter.get())
if (adapter.get().javaResourceFolder() != null) {
featureFlags.setPropertiesLocation(adapter.get().javaResourceFolder())
}
val frontendDependencies: FrontendDependenciesScanner = FrontendDependenciesScannerFactory()
.createScanner(
!adapter.get().optimizeBundle(), adapter.get().getClassFinder(),
adapter.get().generateEmbeddableWebComponents(), featureFlags,
reactEnabled
)

BuildFrontendUtil.runNodeUpdater(adapter.get(), frontendDependencies)

if (adapter.get().generateBundle() && BundleValidationUtil.needsBundleBuild
(adapter.get().servletResourceOutputDirectory())) {
Expand All @@ -92,7 +113,7 @@ public abstract class VaadinBuildFrontendTask : DefaultTask() {
}
}
LicenseChecker.setStrictOffline(true)
val licenseRequired = BuildFrontendUtil.validateLicenses(adapter.get())
val licenseRequired = BuildFrontendUtil.validateLicenses(adapter.get(), frontendDependencies)

BuildFrontendUtil.updateBuildFile(adapter.get(), licenseRequired)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;

import com.vaadin.experimental.FeatureFlags;
import com.vaadin.flow.component.dependency.JavaScript;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.dependency.NpmPackage;
Expand All @@ -41,6 +42,7 @@
import com.vaadin.flow.server.frontend.BundleValidationUtil;
import com.vaadin.flow.server.frontend.FrontendUtils;
import com.vaadin.flow.server.frontend.TaskCleanFrontendFiles;
import com.vaadin.flow.server.frontend.scanner.FrontendDependenciesScanner;
import com.vaadin.flow.theme.Theme;
import com.vaadin.pro.licensechecker.LicenseChecker;

Expand Down Expand Up @@ -139,8 +141,22 @@ protected void executeInternal()

TaskCleanFrontendFiles cleanTask = new TaskCleanFrontendFiles(
npmFolder(), frontendDirectory(), getClassFinder());

boolean reactEnabled = isReactEnabled()
&& FrontendUtils.isReactRouterRequired(
BuildFrontendUtil.getFrontendDirectory(this));
FeatureFlags featureFlags = new FeatureFlags(
createLookup(getClassFinder()));
if (javaResourceFolder() != null) {
featureFlags.setPropertiesLocation(javaResourceFolder());
}
FrontendDependenciesScanner frontendDependencies = new FrontendDependenciesScanner.FrontendDependenciesScannerFactory()
.createScanner(!optimizeBundle, getClassFinder(),
generateEmbeddableWebComponents, featureFlags,
reactEnabled);

try {
BuildFrontendUtil.runNodeUpdater(this);
BuildFrontendUtil.runNodeUpdater(this, frontendDependencies);
} catch (ExecutionFailedException | URISyntaxException exception) {
throw new MojoFailureException(
"Could not execute build-frontend goal", exception);
Expand All @@ -160,7 +176,8 @@ protected void executeInternal()
}
}
LicenseChecker.setStrictOffline(true);
boolean licenseRequired = BuildFrontendUtil.validateLicenses(this);
boolean licenseRequired = BuildFrontendUtil.validateLicenses(this,
frontendDependencies);

BuildFrontendUtil.updateBuildFile(this, licenseRequired);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,12 +311,14 @@ public static File propagateBuildInfo(PluginAdapterBase adapter) {
*
* @param adapter
* - the PluginAdapterBase.
* @param frontendDependencies
* @throws ExecutionFailedException
* - a ExecutionFailedException.
* @throws URISyntaxException
* - - Could not build an URI from nodeDownloadRoot().
*/
public static void runNodeUpdater(PluginAdapterBuild adapter)
public static void runNodeUpdater(PluginAdapterBuild adapter,
FrontendDependenciesScanner frontendDependencies)
throws ExecutionFailedException, URISyntaxException {

Set<File> jarFiles = adapter.getJarFiles();
Expand Down Expand Up @@ -365,7 +367,8 @@ public static void runNodeUpdater(PluginAdapterBuild adapter)
.withFrontendExtraFileExtensions(
adapter.frontendExtraFileExtensions())
.withFrontendIgnoreVersionChecks(
adapter.isFrontendIgnoreVersionChecks());
adapter.isFrontendIgnoreVersionChecks())
.withFrontendDependenciesScanner(frontendDependencies);
new NodeTasks(options).execute();
} catch (ExecutionFailedException exception) {
throw exception;
Expand Down Expand Up @@ -577,10 +580,12 @@ private static void runFrontendBuildTool(PluginAdapterBase adapter,
*
* @param adapter
* the PluginAdapterBase
* @param frontendDependencies
* @return {@literal true} if license validation is required because of the
* presence of commercial components, otherwise {@literal false}.
*/
public static boolean validateLicenses(PluginAdapterBase adapter) {
public static boolean validateLicenses(PluginAdapterBase adapter,
FrontendDependenciesScanner frontendDependencies) {
File outputFolder = adapter.webpackOutputDirectory();

String statsJsonContent = null;
Expand Down Expand Up @@ -609,11 +614,8 @@ public static boolean validateLicenses(PluginAdapterBase adapter) {
statsJsonContent = "{}";
}

FrontendDependenciesScanner scanner = new FrontendDependenciesScanner.FrontendDependenciesScannerFactory()
.createScanner(false, adapter.getClassFinder(), true, null,
adapter.isReactEnabled());
List<Product> commercialComponents = findCommercialFrontendComponents(
scanner, statsJsonContent);
frontendDependencies, statsJsonContent);
commercialComponents.addAll(findCommercialJavaComponents(adapter));

for (Product component : commercialComponents) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -41,6 +40,7 @@
import com.vaadin.flow.server.Constants;
import com.vaadin.flow.server.ExecutionFailedException;
import com.vaadin.flow.server.InitParameters;
import com.vaadin.flow.server.PwaConfiguration;
import com.vaadin.flow.server.frontend.EndpointGeneratorTaskFactory;
import com.vaadin.flow.server.frontend.FileIOUtils;
import com.vaadin.flow.server.frontend.FrontendTools;
Expand Down Expand Up @@ -150,11 +150,15 @@ public void should_useHillaEngine_withNodeUpdater()
.when(endpointGeneratorTaskFactory)
.createTaskGenerateEndpoint(Mockito.any());

FrontendDependenciesScanner frontendDependencies = Mockito
.mock(FrontendDependenciesScanner.class);
Mockito.when(frontendDependencies.getPwaConfiguration())
.thenReturn(new PwaConfiguration());
try (MockedStatic<FrontendUtils> util = Mockito
.mockStatic(FrontendUtils.class, Mockito.CALLS_REAL_METHODS)) {
util.when(() -> FrontendUtils.isHillaUsed(Mockito.any(),
Mockito.any())).thenReturn(true);
BuildFrontendUtil.runNodeUpdater(adapter);
BuildFrontendUtil.runNodeUpdater(adapter, frontendDependencies);
}

Mockito.verify(lookup).lookup(EndpointGeneratorTaskFactory.class);
Expand Down Expand Up @@ -524,7 +528,11 @@ public void runNodeUpdater_generateFeatureFlagsJsFile() throws Exception {
Mockito.when(adapter.createLookup(Mockito.any())).thenReturn(lookup);
Mockito.doReturn(classFinder).when(lookup).lookup(ClassFinder.class);

BuildFrontendUtil.runNodeUpdater(adapter);
FrontendDependenciesScanner frontendDependencies = Mockito
.mock(FrontendDependenciesScanner.class);
Mockito.when(frontendDependencies.getPwaConfiguration())
.thenReturn(new PwaConfiguration());
BuildFrontendUtil.runNodeUpdater(adapter, frontendDependencies);

File generatedFeatureFlagsFile = new File(adapter.generatedTsFolder(),
FEATURE_FLAGS_FILE_NAME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,15 @@ public class NodeTasks implements FallibleCommand {
* the options
*/
public NodeTasks(Options options) {
FrontendDependenciesScanner frontendDependencies = options
.getFrontendDependenciesScanner();

// Lock file is created in the project root folder and not in target/ so
// that Maven does not remove it
lockFile = new File(options.getNpmFolder(), ".vaadin-node-tasks.lock")
.toPath();

ClassFinder classFinder = options.getClassFinder();
FrontendDependenciesScanner frontendDependencies = null;

Set<String> webComponentTags = new HashSet<>();

Expand All @@ -119,9 +121,6 @@ public NodeTasks(Options options) {

if (options.isEnablePackagesUpdate() || options.isEnableImportsUpdate()
|| options.isEnableConfigUpdate()) {
frontendDependencies = new FrontendDependenciesScanner.FrontendDependenciesScannerFactory()
.createScanner(options);

if (options.isProductionMode()) {
boolean needBuild = BundleValidationUtil.needsBuild(options,
frontendDependencies,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.vaadin.flow.server.frontend.installer.NodeInstaller;
import com.vaadin.flow.server.frontend.installer.Platform;
import com.vaadin.flow.server.frontend.scanner.ClassFinder;
import com.vaadin.flow.server.frontend.scanner.FrontendDependenciesScanner;

/**
* Build a <code>NodeExecutor</code> instance.
Expand Down Expand Up @@ -85,6 +86,8 @@ public class Options implements Serializable {

private List<String> frontendExtraFileExtensions = null;

private FrontendDependenciesScanner frontendDependenciesScanner;

/**
* The node.js version to be used when node.js is installed automatically by
* Vaadin, for example <code>"v16.0.0"</code>. Defaults to
Expand Down Expand Up @@ -1037,4 +1040,35 @@ public Options withNpmExcludeWebComponents(boolean exclude) {
public boolean isFrontendIgnoreVersionChecks() {
return frontendIgnoreVersionChecks;
}

/**
* Sets the frontend dependencies scanner to use.
*
* @param frontendDependenciesScanner
* frontend dependencies scanner
* @return this builder
*/
public Options withFrontendDependenciesScanner(
FrontendDependenciesScanner frontendDependenciesScanner) {
this.frontendDependenciesScanner = frontendDependenciesScanner;
return this;
}

/**
* Gets the frontend dependencies scanner to use. If not is not pre-set,
* this initializes a new one based on the Options set.
*
* @return frontend dependencies scanner
*/
public FrontendDependenciesScanner getFrontendDependenciesScanner() {
if (frontendDependenciesScanner == null) {
boolean reactEnabled = isReactEnabled() && FrontendUtils
.isReactRouterRequired(getFrontendDirectory());
frontendDependenciesScanner = new FrontendDependenciesScanner.FrontendDependenciesScannerFactory()
.createScanner(!isUseByteCodeScanner(), getClassFinder(),
isGenerateEmbeddableWebComponents(),
getFeatureFlags(), reactEnabled);
}
return frontendDependenciesScanner;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ public class FrontendDependencies extends AbstractDependenciesScanner {
*
* @param finder
* the class finder
* @deprecated Use
* {@link FrontendDependencies#FrontendDependencies(ClassFinder, boolean, FeatureFlags, boolean)}
* instead.
*/
@Deprecated
public FrontendDependencies(ClassFinder finder) {
this(finder, true, null);
}
Expand All @@ -123,7 +127,11 @@ public FrontendDependencies(ClassFinder finder) {
* {@link com.vaadin.flow.component.WebComponentExporter} classes
* for dependencies. {@code true} is default for
* {@link FrontendDependencies#FrontendDependencies(ClassFinder)}
* @deprecated Use
* {@link FrontendDependencies#FrontendDependencies(ClassFinder, boolean, FeatureFlags, boolean)}
* instead.
*/
@Deprecated
public FrontendDependencies(ClassFinder finder,
boolean generateEmbeddableWebComponents) {
this(finder, generateEmbeddableWebComponents, null);
Expand All @@ -142,7 +150,11 @@ public FrontendDependencies(ClassFinder finder,
* {@link FrontendDependencies#FrontendDependencies(ClassFinder)}
* @param featureFlags
* available feature flags and their status
* @deprecated Use
* {@link FrontendDependencies#FrontendDependencies(ClassFinder, boolean, FeatureFlags, boolean)}
* instead.
*/
@Deprecated
public FrontendDependencies(ClassFinder finder,
boolean generateEmbeddableWebComponents,
FeatureFlags featureFlags) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ class FrontendDependenciesScannerFactory {
* checks {@code WebComponentExporter} classes for
* dependencies if {@code true}, doesn't check otherwise
* @return a scanner implementation strategy
* @deprecated Use
* {@link FrontendDependenciesScannerFactory#createScanner(boolean, ClassFinder, boolean, FeatureFlags, boolean)}
* instead.
*/
@Deprecated
public FrontendDependenciesScanner createScanner(
boolean allDependenciesScan, ClassFinder finder,
boolean generateEmbeddableWebComponents) {
Expand All @@ -84,7 +88,11 @@ public FrontendDependenciesScanner createScanner(
* available feature flags and their status
* @return a scanner implementation strategy
*
* @deprecated Use
* {@link FrontendDependenciesScannerFactory#createScanner(boolean, ClassFinder, boolean, FeatureFlags, boolean)}
* instead.
*/
@Deprecated
public FrontendDependenciesScanner createScanner(
boolean allDependenciesScan, ClassFinder finder,
boolean generateEmbeddableWebComponents,
Expand All @@ -93,6 +101,25 @@ public FrontendDependenciesScanner createScanner(
generateEmbeddableWebComponents, featureFlags, true);
}

/**
* Produces scanner implementation based on {@code allDependenciesScan}
* value.
* <p>
*
* @param allDependenciesScan
* if {@code true} then full classpath scanning strategy is
* used, otherwise byte scanning strategy is produced
* @param finder
* a class finder
* @param generateEmbeddableWebComponents
* checks {@code WebComponentExporter} classes for
* dependencies if {@code true}, doesn't check otherwise
* @param featureFlags
* available feature flags and their status
* @param reactEnabled
* {@code true} if react is enabled, {@code true otherwise}
* @return a scanner implementation strategy
*/
public FrontendDependenciesScanner createScanner(
boolean allDependenciesScan, ClassFinder finder,
boolean generateEmbeddableWebComponents,
Expand All @@ -109,6 +136,17 @@ public FrontendDependenciesScanner createScanner(
}
}

/**
* Produces scanner implementation based on the given Options object.
*
* @param options
* Options to build the scanner from
* @return a scanner implementation strategy
* @deprecated Use
* {@link FrontendDependenciesScannerFactory#createScanner(boolean, ClassFinder, boolean, FeatureFlags, boolean)}
* instead.
*/
@Deprecated
public FrontendDependenciesScanner createScanner(Options options) {
boolean reactEnabled = options.isReactEnabled() && FrontendUtils
.isReactRouterRequired(options.getFrontendDirectory());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void before() throws IOException {
protected FrontendDependenciesScanner getScanner(ClassFinder finder,
FeatureFlags featureFlags) {
return new FrontendDependenciesScanner.FrontendDependenciesScannerFactory()
.createScanner(false, finder, true, featureFlags);
.createScanner(false, finder, true, featureFlags, true);
}

@Test
Expand Down
Loading
Loading