#122 - Allow logger re-routing to logfile.

This commit is contained in:
Mark Paluch
2019-07-09 15:04:10 +02:00
parent 242c88d4e4
commit b33d7dc386
7 changed files with 178 additions and 111 deletions

View File

@@ -41,12 +41,11 @@ import org.springframework.data.release.model.Module;
import org.springframework.data.release.model.ModuleIteration; import org.springframework.data.release.model.ModuleIteration;
import org.springframework.data.release.model.Phase; import org.springframework.data.release.model.Phase;
import org.springframework.data.release.model.Project; import org.springframework.data.release.model.Project;
import org.springframework.data.release.model.Train;
import org.springframework.data.release.model.TrainIteration; import org.springframework.data.release.model.TrainIteration;
import org.springframework.data.release.utils.ExecutionUtils;
import org.springframework.data.release.utils.Logger; import org.springframework.data.release.utils.Logger;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.xmlbeam.ProjectionFactory; import org.xmlbeam.ProjectionFactory;
import org.xmlbeam.io.XBFileIO; import org.xmlbeam.io.XBFileIO;
@@ -116,7 +115,18 @@ class MavenBuildSystem implements BuildSystem {
logger.log(project, "Triggering distribution build…"); logger.log(project, "Triggering distribution build…");
mvn.execute(project, CommandLine.of(Goal.CLEAN, Goal.DEPLOY, // mvn.execute(project, CommandLine.of(Goal.CLEAN, Goal.DEPLOY, //
SKIP_TESTS, profile("distribute"), Argument.of("-B"))); SKIP_TESTS, profile("distribute"), Argument.of("-B"),
arg("artifactory.server").withValue(properties.getServer().getUri()),
arg("distribution-repository").withValue(properties.getDistributionRepository()),
arg("artifactory.username").withValue(properties.getUsername()),
arg("artifactory.password").withValue(properties.getPassword())));
mvn.execute(project, CommandLine.of(Goal.CLEAN, Goal.DEPLOY, //
SKIP_TESTS, profile("distribute-schema"), Argument.of("-B"),
arg("artifactory.server").withValue(properties.getServer().getUri()),
arg("distribution-repository").withValue(properties.getDistributionRepository()),
arg("artifactory.username").withValue(properties.getUsername()),
arg("artifactory.password").withValue(properties.getPassword())));
logger.log(project, "Successfully finished distribution build!"); logger.log(project, "Successfully finished distribution build!");
@@ -192,36 +202,6 @@ class MavenBuildSystem implements BuildSystem {
return true; return true;
} }
/**
* Triggers building the distribution artifacts for all Maven projects of the given {@link Train}.
*
* @param iteration
* @throws Exception
*/
public void triggerDistributionBuild(TrainIteration iteration) throws Exception {
ExecutionUtils.run(iteration, module -> {
Project project = module.getProject();
if (BUILD.equals(project)) {
return;
}
if (!isMavenProject(project)) {
logger.log(project, "Skipping project as no pom.xml could be found in the working directory!");
return;
}
logger.log(project, "Triggering distribution build…");
mvn.execute(project,
CommandLine.of(Goal.CLEAN, Goal.DEPLOY, ReleaseVersion.of(module).getDistributionProfiles(), SKIP_TESTS));
logger.log(project, "Successfully finished distribution build!");
});
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.release.build.BuildSystem#prepareVersion(org.springframework.data.release.model.ModuleIteration, org.springframework.data.release.model.Phase) * @see org.springframework.data.release.build.BuildSystem#prepareVersion(org.springframework.data.release.model.ModuleIteration, org.springframework.data.release.model.Phase)
@@ -388,42 +368,4 @@ class MavenBuildSystem implements BuildSystem {
throw new RuntimeException(o_O); throw new RuntimeException(o_O);
} }
} }
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
private static class ReleaseVersion {
private final ArtifactVersion version;
/**
* Creates a new {@link ReleaseVersion} for the given {@link ModuleIteration}.
*
* @param module must not be {@literal null}.
* @return
*/
public static ReleaseVersion of(ModuleIteration module) {
ArtifactVersion artifactVersion = ArtifactVersion.of(module);
Assert.isTrue(artifactVersion.isMilestoneVersion() || artifactVersion.isReleaseVersion(),
String.format("Given module is not in a fixed version, detected %s!", artifactVersion));
return new ReleaseVersion(ArtifactVersion.of(module));
}
/**
* Returns the Maven profiles to be used during the distribution build.
*
* @return
*/
public Argument getDistributionProfiles() {
if (version.isMilestoneVersion()) {
return profile("distribute", "milestone");
} else if (version.isReleaseVersion()) {
return profile("distribute", "release");
}
throw new IllegalStateException("Should not occur!");
}
}
} }

View File

@@ -29,6 +29,7 @@ import org.springframework.util.Assert;
* Maven configuration properties. * Maven configuration properties.
* *
* @author Oliver Gierke * @author Oliver Gierke
* @author Mark Paluch
*/ */
@Slf4j @Slf4j
@Data @Data
@@ -39,6 +40,7 @@ class MavenProperties {
private File mavenHome; private File mavenHome;
private File localRepository; private File localRepository;
private Map<String, String> plugins; private Map<String, String> plugins;
private boolean consoleLogger = true;
/** /**
* Configures the local Maven repository location to use. In case the given folder does not already exists it's * Configures the local Maven repository location to use. In case the given folder does not already exists it's

View File

@@ -15,15 +15,22 @@
*/ */
package org.springframework.data.release.build; package org.springframework.data.release.build;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.maven.shared.invoker.DefaultInvocationRequest; import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker; import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationResult; import org.apache.maven.shared.invoker.InvocationResult;
import org.apache.maven.shared.invoker.Invoker; import org.apache.maven.shared.invoker.Invoker;
import org.apache.maven.shared.invoker.MavenInvocationException;
import org.springframework.data.release.io.OsOperations; import org.springframework.data.release.io.OsOperations;
import org.springframework.data.release.io.Workspace; import org.springframework.data.release.io.Workspace;
import org.springframework.data.release.model.Project; import org.springframework.data.release.model.Project;
@@ -62,37 +69,126 @@ class MavenRuntime {
public void execute(Project project, CommandLine arguments) { public void execute(Project project, CommandLine arguments) {
String logPrefix = StringUtils.padRight(project.getName(), 10);
Invoker invoker = new DefaultInvoker();
invoker.setMavenHome(properties.getMavenHome());
invoker.setOutputHandler(line -> log.info(logPrefix + ": " + line));
invoker.setErrorHandler(line -> log.warn(logPrefix + ": " + line));
File localRepository = properties.getLocalRepository();
if (localRepository != null) {
invoker.setLocalRepositoryDirectory(localRepository);
}
DefaultInvocationRequest request = new DefaultInvocationRequest();
request.setJavaHome(os.getJavaHome());
request.setShellEnvironmentInherited(true);
request.setBaseDirectory(workspace.getProjectDirectory(project));
logger.log(project, "Executing mvn %s", arguments.toString()); logger.log(project, "Executing mvn %s", arguments.toString());
request.setGoals(arguments.toCommandLine(it -> properties.getFullyQualifiedPlugin(it.getGoal()))); try (MavenLogger mavenLogger = getLogger(project, arguments.getGoals())) {
try { Invoker invoker = new DefaultInvoker();
invoker.setMavenHome(properties.getMavenHome());
invoker.setOutputHandler(mavenLogger::info);
invoker.setErrorHandler(mavenLogger::warn);
File localRepository = properties.getLocalRepository();
if (localRepository != null) {
invoker.setLocalRepositoryDirectory(localRepository);
}
DefaultInvocationRequest request = new DefaultInvocationRequest();
request.setJavaHome(os.getJavaHome());
request.setShellEnvironmentInherited(true);
request.setBaseDirectory(workspace.getProjectDirectory(project));
request.setGoals(arguments.toCommandLine(it -> properties.getFullyQualifiedPlugin(it.getGoal())));
InvocationResult result = invoker.execute(request); InvocationResult result = invoker.execute(request);
if (result.getExitCode() != 0) { if (result.getExitCode() != 0) {
throw new RuntimeException(result.getExecutionException()); throw new RuntimeException(result.getExecutionException());
} }
} catch (Exception e) {
} catch (MavenInvocationException o_O) { throw new RuntimeException(e);
throw new RuntimeException(o_O);
} }
} }
private MavenLogger getLogger(Project project, List<CommandLine.Goal> goals) {
if (this.properties.isConsoleLogger()) {
return new SlfLogger(log, project);
}
return new FileLogger(log, project, this.workspace.getLogsDirectory(), goals);
}
/**
* Maven Logging Forwarder.
*/
interface MavenLogger extends Closeable {
void info(String message);
void warn(String message);
}
@RequiredArgsConstructor
static class SlfLogger implements MavenLogger {
private final org.slf4j.Logger logger;
private final String logPrefix;
SlfLogger(org.slf4j.Logger logger, Project project) {
this.logger = logger;
this.logPrefix = StringUtils.padRight(project.getName(), 10);
}
@Override
public void info(String message) {
logger.info(logPrefix + ": " + message);
}
@Override
public void warn(String message) {
logger.warn(logPrefix + ": " + message);
}
@Override
public void close() throws IOException {
// no-op
}
}
static class FileLogger implements MavenLogger {
private final PrintWriter printWriter;
private final FileOutputStream outputStream;
FileLogger(org.slf4j.Logger logger, Project project, File logsDirectory, List<CommandLine.Goal> goals) {
if (!logsDirectory.exists()) {
logsDirectory.mkdirs();
}
String goalNames = goals.stream().map(CommandLine.Goal::getGoal).collect(Collectors.joining("-"));
String filename = String.format("mvn-%s-%s.log", project.getName(), goalNames);
try {
File file = new File(logsDirectory, filename);
logger.info("Routing Maven output to " + file.getCanonicalPath());
outputStream = new FileOutputStream(file, true);
} catch (IOException e) {
throw new RuntimeException(e);
}
printWriter = new PrintWriter(outputStream, true);
}
@Override
public void info(String message) {
printWriter.println(message);
}
@Override
public void warn(String message) {
printWriter.println(message);
}
@Override
public void close() throws IOException {
printWriter.close();
outputStream.close();
}
}
} }

View File

@@ -28,6 +28,7 @@ import org.springframework.web.util.UriTemplate;
/** /**
* @author Oliver Gierke * @author Oliver Gierke
* @author Mark Paluch
*/ */
@Data @Data
@Component @Component
@@ -56,6 +57,11 @@ public class DeploymentProperties {
*/ */
private String stagingRepository; private String stagingRepository;
/**
* The repository to deploy docs/schemas to.
*/
private String distributionRepository;
private String repositoryPrefix = ""; private String repositoryPrefix = "";
private Gpg gpg; private Gpg gpg;
@@ -64,6 +70,10 @@ public class DeploymentProperties {
return repositoryPrefix.concat(stagingRepository); return repositoryPrefix.concat(stagingRepository);
} }
public String getDistributionRepository() {
return repositoryPrefix.concat(distributionRepository);
}
/** /**
* Returns the URI of the staging repository. * Returns the URI of the staging repository.
* *

View File

@@ -25,6 +25,7 @@ import org.springframework.stereotype.Component;
/** /**
* @author Oliver Gierke * @author Oliver Gierke
* @author Mark Paluch
*/ */
@Slf4j @Slf4j
@Data @Data
@@ -32,7 +33,7 @@ import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "io") @ConfigurationProperties(prefix = "io")
class IoProperties { class IoProperties {
private File workDir, javaHome; private File workDir, javaHome, logs;
public void setWorkDir(String workDir) { public void setWorkDir(String workDir) {

View File

@@ -71,6 +71,15 @@ public class Workspace {
return ioProperties.getWorkDir(); return ioProperties.getWorkDir();
} }
/**
* Returns the current logs directory.
*
* @return
*/
public File getLogsDirectory() {
return ioProperties.getLogs();
}
/** /**
* Cleans up the working directory by removing all files and folders in it. * Cleans up the working directory by removing all files and folders in it.
* *
@@ -78,11 +87,15 @@ public class Workspace {
*/ */
public void cleanup() throws IOException { public void cleanup() throws IOException {
logger.log("Workspace", "Cleaning up workspace directory at %s.", getWorkingDirectory().getAbsolutePath()); delete(getWorkingDirectory().toPath(), "workspace");
delete(getLogsDirectory().toPath(), "logs");
}
Path workingDirPath = getWorkingDirectory().toPath(); private void delete(Path path, String type) throws IOException {
Files.walkFileTree(workingDirPath, new SimpleFileVisitor<Path>() { logger.log("Workspace", "Cleaning up %s directory at %s.", type, path.toAbsolutePath());
Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
@@ -93,7 +106,7 @@ public class Workspace {
@Override @Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
if (!workingDirPath.equals(dir)) { if (!path.equals(dir)) {
Files.delete(dir); Files.delete(dir);
} }

View File

@@ -1,11 +1,14 @@
io.work-dir=~/temp/spring-data-shell/workspace io.work-dir=~/temp/spring-data-shell/workspace
io.logs=logs
# Maven setup # Maven setup
maven.local-repository=~/temp/spring-data-shell/repository maven.local-repository=~/temp/spring-data-shell/repository
maven.plugins.versions=org.codehaus.mojo:versions-maven-plugin:2.2 maven.plugins.versions=org.codehaus.mojo:versions-maven-plugin:2.2
maven.console-logger=true
deployment.server.uri=https://repo.spring.io deployment.server.uri=https://repo.spring.io
deployment.staging-repository=libs-staging-local deployment.staging-repository=libs-staging-local
deployment.distribution-repository=temp-private-local
deployment.username=buildmaster deployment.username=buildmaster
#deployment.password <- local #deployment.password <- local