protoj.lang.VerifyTarFeature Maven / Gradle / Ivy
Show all versions of protoj-jdk6 Show documentation
/**
* Copyright 2009 Ashley Williams
*
* 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 protoj.lang;
import java.io.File;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Chmod;
import org.apache.tools.ant.taskdefs.GUnzip;
import org.apache.tools.ant.taskdefs.Untar;
import protoj.lang.internal.InformationException;
import protoj.util.AntTarget;
import protoj.util.ArgRunnable;
import protoj.util.CommandTask;
/**
* {@link StandardProject} helper.
*
* Verifies the correct functionality of a project tar file by expanding, then
* building and executing the unit tests inside. This can prevent the situation
* where extreme care has been taken over the project source code, but correct
* functionality of the subsequently released tar file is left to chance. Here
* are the basic steps that are taken:
*
* - The tar file is extracted into the target/verify-tar directory, resulting
* in a failure if this goes wrong for some reason.
* - If there is no source directory then this results in a failure to avoid
* the situation where the caller mistakenly believes the tests to have been
* executed.
* - Maximum 'rwx' permissions are applied to the extracted files, since
* tighter restrictions can prevent compilation from working. One consequence is
* that the unmodified file permissions don't get tested.
* - The extracted project script is then executed using the compile, assemble
* and test commands. A failure of this execution results in command failure.
*
*
*
* @author Ashley Williams
*
*/
public final class VerifyTarFeature {
/**
* When added to project session commands, responds by throwing an exception
* if any of those commands should result in a non zero return code.
*
* @author Ashley Williams
*
*/
private final class ThrowingListener implements ArgRunnable {
private final StandardProject project;
private ThrowingListener(StandardProject project) {
this.project = project;
}
public void run(ScriptSession session) {
CommandTask exec = session.getCurrentExec();
System.out.println(exec.getStdout());
if (!exec.isSuccess()) {
StringBuilder builder = new StringBuilder();
builder.append("Extracted project failed tar verification.");
builder.append("\nReturn code: ");
builder.append(exec.getResult());
builder.append("\nScript: ");
File script = project.getLayout().getShellScript();
builder.append(script.getAbsolutePath());
builder.append("\nCommand: ");
builder.append(session.getCurrentCommand());
builder.append("\nstdout:\n");
builder.append(exec.getStderr());
throw new RuntimeException(builder.toString());
}
}
}
/**
* See {@link #getDelegate()}.
*/
private StandardProject project;
/**
*
* @param project
*/
public VerifyTarFeature(StandardProject project) {
this.project = project;
}
/**
* Starts the verification process. See {@link VerifyTarFeature} for a
* complete description.
*/
public void verifyTar() {
extractTarFiles();
applyRwx();
executeSession();
}
/**
* Extracts the tar file from the target directory, throwing an exception if
* it doesn't exist.
*/
public void extractTarFiles() {
String compressedPath = project.getArchiveFeature().getProjectArchive()
.getArchivePath();
boolean exists = new File(compressedPath).exists();
if (!exists) {
throw new InformationException(
"unable to find tar file for tar verification at "
+ compressedPath);
}
ProjectArchive tarFeature = project.getArchiveFeature()
.getProjectArchive();
File compressedFile = new File(tarFeature.getArchivePath());
// create the parent ant target
AntTarget target = new AntTarget("extract-tar-files");
target.initLogging(Project.MSG_INFO);
// applies the gunzip
GUnzip gunzip = new GUnzip();
gunzip.setTaskName("gunzip");
target.addTask(gunzip);
gunzip.setSrc(compressedFile);
// applies the untar
Untar untar = new Untar();
untar.setTaskName("untar");
target.addTask(untar);
File uncompressedFile = new File(tarFeature.getUncompressedPath());
untar.setSrc(uncompressedFile);
untar.setDest(getExtractedProject().getLayout().getRootDir()
.getParentFile());
target.execute();
}
/**
* Applies rwx permissions to the extracted project.
*/
private void applyRwx() {
// create the parent ant target
AntTarget target = new AntTarget("extract-tar-files");
target.initLogging(Project.MSG_INFO);
// applies the chmod
Chmod chmod = new Chmod();
chmod.setTaskName("rwx");
target.addTask(chmod);
chmod.setDir(getExtractedProject().getLayout().getRootDir());
chmod.setIncludes("**/*");
chmod.setPerm("777");
target.execute();
}
/**
* Executes the project commands, failing if any of those commands
* themselves fail.
*/
private void executeSession() {
StandardProject extractedProject = getExtractedProject();
File srcDir = extractedProject.getLayout().getSrcDir();
if (!srcDir.exists()) {
throw new RuntimeException(
"unable to find src directory for the compilation part of tar verification at"
+ srcDir.getAbsolutePath());
}
ScriptSession session = extractedProject.createScriptSession();
ThrowingListener listener = new ThrowingListener(extractedProject);
session.addCommand("compile", listener, null);
session.addCommand("test", listener, null);
session.execute();
}
/**
* Creates a project instance representing the project being verified in the
* target directory.
*
* @return
*/
public StandardProject getExtractedProject() {
ProjectLayout thisLayout = project.getLayout();
File verifyTarDir = new File(thisLayout.getTargetDir(), "verify-tar");
String prefix = project.getArchiveFeature().getProjectArchive()
.getPrefix();
File rootDir = new File(verifyTarDir, prefix);
String scriptName = thisLayout.getScriptName();
StandardProject project = new StandardProject(rootDir, scriptName, null);
return project;
}
}