FacepalmCLI.java
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright 2026 Nikolas Charalambidis
*/
package dev.nichar.facepalm;
import com.google.inject.Guice;
import dev.nichar.facepalm.config.EngineConfig;
import dev.nichar.facepalm.config.EvaluatorConfig;
import dev.nichar.facepalm.config.PatternConfig;
import dev.nichar.facepalm.config.PostProcessorConfig;
import dev.nichar.facepalm.config.ScoringConfig;
import dev.nichar.facepalm.engine.FacepalmRunner;
import dev.nichar.facepalm.module.FacepalmConfigModule;
import dev.nichar.facepalm.module.FacepalmLogModule;
import java.nio.file.Paths;
import org.apache.maven.monitor.logging.DefaultLog;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.eclipse.sisu.space.BeanScanning;
import org.eclipse.sisu.space.SpaceModule;
import org.eclipse.sisu.space.URLClassSpace;
import org.eclipse.sisu.wire.WireModule;
/**
* Command-line interface for running Facepalm scans outside the Maven lifecycle.
*/
public class FacepalmCLI {
/**
* Bootstraps the Guice container and executes a scan on the specified directory.
*
* @param args Command-line arguments. args[0] is the target directory (default: current).
*/
public static void main(final String[] args) throws MojoFailureException, MojoExecutionException {
// Assemble baseline configuration with default settings.
final var engineConfig = new EngineConfig();
final var scoringConfig = new ScoringConfig();
final var evaluatorConfig = new EvaluatorConfig();
final var postProcessorConfig = new PostProcessorConfig();
final var patternConfig = new PatternConfig();
final var effectiveConfig = new FacepalmConfig(engineConfig, scoringConfig, evaluatorConfig,
postProcessorConfig, patternConfig);
// Discover injectable components from the current classpath.
final var space = new URLClassSpace(FacepalmCLI.class.getClassLoader());
// Initialize the dependency injection container.
final var injector = Guice.createInjector(
new WireModule(
// Perform a runtime scan of the classpath for @Named components.
new SpaceModule(space, BeanScanning.CACHE),
// Bridge Maven logging to the console.
new FacepalmLogModule(
new DefaultLog(
new ConsoleLogger(Logger.LEVEL_DEBUG, "facepalm-cli"))),
// Bind the active configuration to the container.
new FacepalmConfigModule(effectiveConfig)));
// Resolve component instances for the scanning workflow.
final var runner = injector.getInstance(FacepalmRunner.class);
final var config = injector.getInstance(FacepalmConfig.class);
final var log = injector.getInstance(Log.class);
if (runner == null || config == null || log == null) {
throw new MojoExecutionException("Facepalm Mojo initialization failed: " +
"runner=" + runner + ", config=" + config + ", log=" + log);
}
// Normalize the target scan path from arguments.
final var root = Paths.get(args.length > 0 ? args[0] : ".").toAbsolutePath().normalize();
try {
runner.run(root, Paths.get("target"), "SNAPSHOT");
} catch (MojoFailureException e) {
throw e;
} catch (Exception e) {
throw FacepalmMojo.executionFailure(e);
}
}
}