#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.Phase;
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.utils.ExecutionUtils;
import org.springframework.data.release.utils.Logger;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.xmlbeam.ProjectionFactory;
import org.xmlbeam.io.XBFileIO;
@@ -116,7 +115,18 @@ class MavenBuildSystem implements BuildSystem {
logger.log(project, "Triggering distribution build…");
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!");
@@ -192,36 +202,6 @@ class MavenBuildSystem implements BuildSystem {
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)
* @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);
}
}
@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

@@ -27,8 +27,9 @@ import org.springframework.util.Assert;
/**
* Maven configuration properties.
*
*
* @author Oliver Gierke
* @author Mark Paluch
*/
@Slf4j
@Data
@@ -39,11 +40,12 @@ class MavenProperties {
private File mavenHome;
private File localRepository;
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
* created.
*
*
* @param localRepository must not be {@literal null} or empty.
*/
public void setLocalRepository(String localRepository) {
@@ -61,7 +63,7 @@ class MavenProperties {
/**
* Returns the fully-qualified plugin goal for the given local one.
*
*
* @param goal must not be {@literal null} or empty.
* @return
*/

View File

@@ -15,15 +15,22 @@
*/
package org.springframework.data.release.build;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.io.Closeable;
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.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationResult;
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.Workspace;
import org.springframework.data.release.model.Project;
@@ -62,37 +69,126 @@ class MavenRuntime {
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());
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);
if (result.getExitCode() != 0) {
throw new RuntimeException(result.getExecutionException());
}
} catch (MavenInvocationException o_O) {
throw new RuntimeException(o_O);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
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 Mark Paluch
*/
@Data
@Component
@@ -56,6 +57,11 @@ public class DeploymentProperties {
*/
private String stagingRepository;
/**
* The repository to deploy docs/schemas to.
*/
private String distributionRepository;
private String repositoryPrefix = "";
private Gpg gpg;
@@ -64,9 +70,13 @@ public class DeploymentProperties {
return repositoryPrefix.concat(stagingRepository);
}
public String getDistributionRepository() {
return repositoryPrefix.concat(distributionRepository);
}
/**
* Returns the URI of the staging repository.
*
*
* @return
*/
public String getStagingRepositoryUrl() {
@@ -88,7 +98,7 @@ public class DeploymentProperties {
/**
* Returns the URI to the resource that a promotion can be triggered at.
*
*
* @param information must not be {@literal null}.
* @return
*/

View File

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

View File

@@ -48,7 +48,7 @@ import org.springframework.util.Assert;
/**
* Abstraction of the workspace that is used to work with the {@link Project}'s repositories, execute builds, etc.
*
*
* @author Oliver Gierke
*/
@Component
@@ -64,25 +64,38 @@ public class Workspace {
/**
* Returns the current working directory.
*
*
* @return
*/
public File getWorkingDirectory() {
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.
*
*
* @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
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
@@ -93,7 +106,7 @@ public class Workspace {
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
if (!workingDirPath.equals(dir)) {
if (!path.equals(dir)) {
Files.delete(dir);
}
@@ -130,7 +143,7 @@ public class Workspace {
/**
* Returns the directory for the given {@link Project}.
*
*
* @param project must not be {@literal null}.
* @return
*/
@@ -142,7 +155,7 @@ public class Workspace {
/**
* Returns whether the project directory for the given project already exists.
*
*
* @param project must not be {@literal null}.
* @return
*/
@@ -154,7 +167,7 @@ public class Workspace {
/**
* Returns a file with the given name relative to the working directory for the given {@link Project}.
*
*
* @param name must not be {@literal null} or empty.
* @param project must not be {@literal null}.
* @return
@@ -218,7 +231,7 @@ public class Workspace {
/**
* Initializes the working directory and creates the folders if necessary.
*
*
* @throws IOException
*/
@PostConstruct

View File

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