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

plugin to run astra use-cases with minimal set up required #121

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
53 changes: 53 additions & 0 deletions astra-maven-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Astra Maven Plugin

# Goal - refactor

## Description

The purpose of this plugin is to run an Astra UseCase over the maven module(s) source code.

## Plugin Attributes

Does not bind by default to any lifecycle phase - it can be run as a standalone goal or must be attached explicitly, e.g. to the `process-sources` phase for a multi-module build.

## Required Parameters

| Name | Type | Property | Description |
| -----|-------|----------|-------------|
| usecase | String | astra.usecase | The refactoring UseCase to run. Must be a fully-qualified class name on the class path either of the project or the plugin. |

## Optional Parameters

| Name | Type | Property | Description | Default |
| -----|-------|----------|-------------|---------|
| skip | boolean | astra.skip | Skips execution of the goal | false |
| sourceDirectory | File | sourceDirectory | The source directory to be processed by the refactor | The project base directory. |
| targetDirectory | String | targetDirectory | The target directory for the project | The project build directory. |


## Usage

To use in multi-module projects bind to the `process-sources` phase.

```
[...]

<plugin>
<groupId>org.alfasoftware</groupId>
<artifactId>astra-maven-plugin</artifactId>
<version>...</version>

<!-- optional dependency to provide use-cases if stored separately -->
<dependency>
<groupId>org.alfasoftware</groupId>
<artifactId>astra-example</artifactId>
<version>...</version>
</dependency>
</plugin>

[...]
```

Command line usage once the plugin is defined in the pom just needs to specify the use case:
`mvn astra:refactor -Dastra.usecase=org.alfasoftware.astra.example.ExampleUseCase`

44 changes: 44 additions & 0 deletions astra-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.alfasoftware</groupId>
<artifactId>astra</artifactId>
<version>2.3.1-SNAPSHOT</version>
</parent>

<artifactId>astra-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<name>ASTRA maven plugin</name>

<properties>
<maven.baseVersion>3.8.2</maven.baseVersion>
</properties>

<dependencies>
<dependency>
<groupId>org.alfasoftware</groupId>
<artifactId>astra-core</artifactId>
</dependency>

<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>${maven.baseVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>${maven.baseVersion}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package org.alfasoftware.astra;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;

import org.alfasoftware.astra.core.refactoring.UseCase;
import org.alfasoftware.astra.core.utils.ASTOperation;
import org.alfasoftware.astra.core.utils.AstraCore;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;

/**
* Runs an ASTRA UseCase refactor over the given module.
*/
@Mojo(name = "refactor", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true)
public class RefactorMojo extends AbstractMojo {

/**
* The Maven project, containing runtime values based on the model.
*/
@Parameter(required = true, readonly = true, defaultValue = "${project}")
protected MavenProject project;

/**
* The usecase fully-qualified class name
*/
@Parameter(property = "astra.usecase")
private String usecase;

/**
* The usecase fully-qualified class name
*/
@Parameter(property = "astra.skip", defaultValue = "false")
private String skip;

/**
* The source directory to be processed
*/
@Parameter(property = "sourceDirectory", defaultValue = "${project.basedir}")
private File sourceDirectory;

/**
* The target directory for the project.
* This enables us to remove items from the classpath
*/
@Parameter(property = "targetDirectory", readonly = true, defaultValue = "${project.build.directory}")
private String targetDirectory;


@Override
public void execute() throws MojoExecutionException {

List<String> testClasspathElements;
try {
testClasspathElements = project.getTestClasspathElements();
} catch (DependencyResolutionRequiredException e) {
throw new MojoExecutionException("Unable to resolve test class path for the project", e);
}

// remove anything within this projects target directory as it has been
testClasspathElements.removeIf(s -> s.startsWith(targetDirectory));

// might need to add source from other projects if running multi-module??

UseCase useCaseInstance = getUseCaseInstance();
AstraCore.run(sourceDirectory.getAbsolutePath(), new UseCase() {

@Override
public Set<? extends ASTOperation> getOperations() {
return useCaseInstance.getOperations();
}

@Override
public Predicate<String> getPrefilteringPredicate() {
return useCaseInstance.getPrefilteringPredicate();
}

@Override
public Set<String> getAdditionalClassPathEntries() {
HashSet<String> additionalClassPath = new HashSet<>(useCaseInstance.getAdditionalClassPathEntries());
additionalClassPath.addAll(testClasspathElements);
return additionalClassPath;
}
});

}


private UseCase getUseCaseInstance() throws MojoExecutionException {
try {
Class<?> useCaseClazz = Class.forName(usecase);
if (!UseCase.class.isAssignableFrom(useCaseClazz)) {
throw new MojoExecutionException(String.format("Class [%s] must be of type org.alfasoftware.astra.core.refactoring.UseCase", usecase));
}
return (UseCase)useCaseClazz.getDeclaredConstructors()[0].newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| SecurityException | ClassNotFoundException e) {
throw new MojoExecutionException(String.format("Unable to instantiate usecase [%s]", usecase), e);
}
}

}
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<module>astra-example</module>
<module>astra-cli</module>
<module>astra-testing</module>
<module>astra-maven-plugin</module>
</modules>

<properties>
Expand Down
Loading