/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package me.cmoz.gradle.snapshot;
import lombok.SneakyThrows;
import org.gradle.api.DefaultTask;
import org.gradle.api.plugins.ExtensionContainer;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.OutputFile;
import javax.annotation.Nullable;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.Properties;
/**
* A task to extract build information from an SCM repository and generate a
* file with the most recent commit data.
*/
public class SnapshotTask extends DefaultTask {
/** An output label for the properties file. */
private static final String BUILD_LABEL =
"Generated by the Gradle Snapshot Plugin ("
+ SnapshotTask.class.getPackage().getImplementationVersion()
+ ")";
@OutputFile
public File getOutputFile() {
final SnapshotPluginExtension ext = this.getProject().getExtensions().getByType(SnapshotPluginExtension.class);
final File outputDir = new File(this.getProject().getBuildDir(), "snapshot");
return new File(outputDir, ext.getFilename());
}
/**
* The main action for this task.
*
* <p>The task generates metadata from the SCM for the most recent commit
* and stores it to the {@code snapshot} file location for storing with
* JAR and WAR packages.
*/
@TaskAction
@SneakyThrows(IOException.class)
public void action() {
final ExtensionContainer extensions = getProject().getExtensions();
final SnapshotPluginExtension ext = extensions.getByType(SnapshotPluginExtension.class);
final SCMCommand scmCmd = getSCMCommand();
final Properties properties = new Properties();
final File outputFile = this.getOutputFile();
if (scmCmd != null) {
final Map<String, String> commitMap = scmCmd.getLatestCommit(ext.getDateFormat()).asMap();
properties.putAll(commitMap);
} else {
this.getLogger().warn("No supported SCM repository found.");
if (outputFile.canRead()) {
FileReader reader = null;
try {
properties.load(reader = new FileReader(outputFile));
this.getLogger().info("Properties loaded from output file {}.", outputFile);
} finally {
if (reader != null) {
reader.close();
}
}
}
}
/* always set build.time as this is not scm-related */
properties.setProperty(Commit.BUILD_TIME, new SimpleDateFormat(ext.getDateFormat()).format(new Date()));
for (final String propertyName : properties.stringPropertyNames()) {
final String propertyValue = properties.getProperty(propertyName);
// make the build information available to the project properties
extensions.getExtraProperties().set(propertyName, propertyValue);
if (ext.isVerbose()) {
this.getLogger().quiet("Property {}: {}", propertyName, propertyValue);
}
}
FileWriter writer = null;
try {
properties.store(writer = new FileWriter(outputFile), BUILD_LABEL);
} finally {
if (writer != null) {
writer.close();
}
}
}
/**
* Searches the project directory for a repository directory that belongs
* to a supported SCM tool. If one is found the associated {@code SCMCommand}
* will be returned to interact with it.
*
* @return The {@code SCMCommand} to interact with the SCM repository for
* the project, if one could be found.
*/
@Nullable
private SCMCommand getSCMCommand() {
SCMCommand scmCmd = new HgSCMCommand(getProject());
if (scmCmd.getRepositoryDir() != null) {
return scmCmd;
}
scmCmd = new GitSCMCommand(getProject());
if (scmCmd.getRepositoryDir() != null) {
return scmCmd;
}
return null; // no supported SCM directory could be located
}
}