一直都想让maven的target目录放在内存盘,但把target mklink在mvn clean后又会消失,不够智能
发现了插件 https://plugin.maven.earcam.io/ramdisk/ 但不兼容 win
https://bitbucket.org/earcam/io.earcam.maven.plugin/src/master/
魔改之,只留一个类即可
parent pom.xml
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.earcam.maven</groupId>
<artifactId>io.earcam.maven.plugin</artifactId>
<version>0.0.4</version>
<packaging>pom</packaging>
<modules>
<module>io.earcam.maven.plugin.ramdisk</module>
</modules>
<properties>
<version.java.platform>8</version.java.platform>
<version.java>1.${version.java.platform}</version.java>
<maven.compiler.source>${version.java}</maven.compiler.source>
<maven.compiler.target>${version.java}</maven.compiler.target>
<earcam.project.root.artifactId>io.earcam.maven.plugin</earcam.project.root.artifactId>
<coordinate.username.project>earcam/${earcam.project.root.artifactId}</coordinate.username.project>
<version.slf4j>1.7.25</version.slf4j>
<version.utilitarian>1.2.1</version.utilitarian>
<version.instrumental>0.1.0</version.instrumental>
<version.unexceptional>1.0.0</version.unexceptional>
<version.maven>3.5.4</version.maven>
<version.this.plugin>${project.version}</version.this.plugin>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>${version.maven}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
io.earcam.maven.plugin.ramdisk\pom.xml
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>io.earcam.maven</groupId>
<artifactId>io.earcam.maven.plugin</artifactId>
<version>0.0.4</version>
</parent>
<groupId>io.earcam.maven.plugin</groupId>
<artifactId>io.earcam.maven.plugin.ramdisk</artifactId>
<packaging>maven-plugin</packaging>
<properties>
<earcam.project.name.short>ramdisk</earcam.project.name.short>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<goals>
<goal>package</goal>
</goals>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<id>fat-jar-for-mvn-home-lib-ext</id>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedClassifierName>uber</shadedClassifierName>
<shadedArtifactAttached>true</shadedArtifactAttached>
<artifactSet>
<includes>
<include>io.earcam*:*</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
package io.earcam.maven.plugin.ramdisk;
import org.apache.maven.AbstractMavenLifecycleParticipant;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Scm;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component;
import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
import static io.earcam.maven.plugin.ramdisk.RamdiskBuildExtension.NAME;
@Component(role = AbstractMavenLifecycleParticipant.class, hint = NAME, instantiationStrategy = "singleton")
public class RamdiskBuildExtension extends AbstractMavenLifecycleParticipant {
static final String NAME = "ramdisk";
Path tmpFsRoot = Paths.get("z:/");
@Override
public void afterProjectsRead(MavenSession session) {
List<MavenProject> modules = session.getAllProjects();
modules.forEach(this::createTmpFsBuildDir);
}
private void createTmpFsBuildDir(MavenProject project) {
if (null != project.getPackaging() && project.getPackaging().equals("pom")) {
return;
}
try {
createTmpFsBuildDir(project, tmpFsRoot);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
static boolean isJunction(Path p) {
boolean isJunction = false;
try {
isJunction = (p.compareTo(p.toRealPath()) != 0);
} catch (IOException e) {
}
return isJunction;
}
static void createTmpFsBuildDir(MavenProject project, Path tmpFs) throws IOException {
Path link = Paths.get(project.getBuild().getDirectory());
Path linkTarget = tmpFs.resolve(relativePathFor(project));
if (!linkTarget.toFile().exists()) {
Files.createDirectories(linkTarget);
}
if (!link.toFile().exists()) {
Runtime runtime = Runtime.getRuntime();
runtime.exec(new String[]{"cmd", "/c", "mklink", "/j", link.toString(), linkTarget.toString()});
} else {
boolean junction = isJunction(link);
if (!junction) {
delete(link);
}
Runtime runtime = Runtime.getRuntime();
runtime.exec(new String[]{"cmd", "/c", "mklink", "/j", link.toString(), linkTarget.toString()});
}
}
static Path relativePathFor(MavenProject project) {
Path linkTarget = Paths.get("maven", project.getGroupId(), project.getArtifactId(), project.getVersion());
return appendScmTag(project, linkTarget);
}
private static Path appendScmTag(MavenProject project, Path linkTarget) {
Scm scm = project.getScm();
if (scm != null) {
String tag = scm.getTag();
if (tag != null && !tag.isEmpty()) {
linkTarget = linkTarget.resolve(tag);
}
}
return linkTarget;
}
@Override
public void afterSessionEnd(MavenSession session) {
session.getAllProjects().forEach(this::createTmpFsBuildDir);
}
public static void delete(Path path, LinkOption... options) throws IOException {
recurse(path, new DeleteVisitor(path, options));
}
private static void recurse(Path source, AbstractVisitor visitor) throws IOException {
boolean noFollow = Arrays.asList(visitor.options).contains(LinkOption.NOFOLLOW_LINKS);
EnumSet<FileVisitOption> options = noFollow ? EnumSet.noneOf(FileVisitOption.class) : EnumSet.of(FileVisitOption.FOLLOW_LINKS);
Files.walkFileTree(source, options, Integer.MAX_VALUE, visitor);
}
private static final class DeleteVisitor extends AbstractVisitor {
public DeleteVisitor(Path source, CopyOption... options) {
super(source, source, options);
}
public FileVisitResult postVisitDirectory(Path directory) throws IOException {
Files.delete(directory);
return FileVisitResult.CONTINUE;
}
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
}
abstract static class AbstractVisitor extends SimpleFileVisitor<Path> {
final Path sink;
final Path source;
final CopyOption[] options;
Path sinkSub;
public AbstractVisitor(Path source, Path sink, CopyOption... options) {
this.source = source;
this.sink = sink;
this.options = options;
}
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
this.sinkSub = this.sink.resolve(this.source.relativize(dir));
this.sinkSub.toFile().mkdirs();
return FileVisitResult.CONTINUE;
}
public FileVisitResult postVisitDirectory(Path directory, IOException thrown) throws IOException {
super.postVisitDirectory(directory, thrown);
return this.postVisitDirectory(directory);
}
protected abstract FileVisitResult postVisitDirectory(Path var1) throws IOException;
public abstract FileVisitResult visitFile(Path var1, BasicFileAttributes var2) throws IOException;
}
}