Skip to content
Commits on Source (3)
Copyright © 2010 Reinier Zwitserloot.
Copyright (C) 2009-2017 The Project Lombok Authors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
......
......@@ -118,12 +118,15 @@ _Supported since ipp 1.4_
The defaults are also different:
debug = on
source = 1.6
target = 1.6
source = 1.8
target = 1.8
encoding = UTF-8
includeAntRuntime = false
The _destdir_ directory is also created automatically, so you don't have to `<mkdir>` it first.
(since ipp 1.22: You can also set ecj="true" to use ecj instead. Useful if you want to compile with old source/target).
_Supported since ipp 1.0_
### `<ivy:cachedunjar>` - similar to unjar, except will not unpack jars that don't need to be unpacked.
......@@ -191,3 +194,28 @@ Inner elements:
_Supported since ipp 1.3_
NB: make-maven-repo is no longer under active development since sonatype changed their policy on how maven artifacts are to be added to maven central.
### `<ivy:hardlink>` - creates hardlinks instead of copying files
Attributes:
* `from` - File to hardlink from (only individual files are supported).
* `to` - New file to create which will be a hardlink copy of `from`.
This task will use `fsutil hardlink create` on windows, and `ln` on other systems.
### `<ivy:scpUpload>` and `<ivy:sshExec>` - Uploads files / runs scripts via SSH
Attributes
* `server` - IP or domain of the SSH server to talk to
* `port` - Port to use (optional, defaults to 22)
* `username` - Username to connect as.
* `keyFile` - The only supported connection mechanism is key files, not password protected (many formats supported. ed25519 recommended).
* `knownHosts` - A file listing known hosts; defaults to `ssh.knownHosts`. If you fail to list the host, the command fails put prints what you'd have to add to this file to make it work.
For scpUpload:
* `from` - File to upload.
* `to` - Where to upload to.
For sshExec:
* `cmd` - Command to execute.
<!--
Copyright © 2010-2011 Reinier Zwitserloot.
Copyright © 2010-2017 Reinier Zwitserloot.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
......@@ -19,41 +19,38 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<project name="com.zwitserloot.ivyplusplus" default="dist" xmlns:ivy="antlib:com.zwitserloot.ivyplusplus">
<project name="com.zwitserloot.ivyplusplus" default="dist" xmlns:ivy="antlib:org.apache.ivy.ant">
<property name="jre.version" value="1.7" />
<property name="ivy.retrieve.pattern" value="lib/[conf]/[artifact].[ext]" />
<property name="ivy.lib" value="ivy-2.4.0.jar" />
<property name="ivy.location" value="https://projectlombok.org/downloads/${ivy.lib}" />
<available file="lib/${ivy.lib}" property="ivy.available" />
<available file="lib/ivyplusplus.jar" property="ivyplusplus.available" />
<target name="download-ivy" unless="ivy.available">
<mkdir dir="lib" />
<get src="${ivy.location}" dest="lib/${ivy.lib}" usetimestamp="true" />
</target>
<target name="version" depends="ensure-ipp" description="Shows the version number." unless="ivyplusplus.version">
<mkdir dir="build/lombok" />
<ivy:compile source="1.6" target="1.6" includeDestClasses="false" srcdir="src" destdir="build" includes="com/zwitserloot/ivyplusplus/Version.java" />
<target name="version" description="Shows the version number." unless="ivyplusplus.version">
<mkdir dir="build" />
<javac source="${jre.version}" target="${jre.version}" includeDestClasses="false" includeAntRuntime="false" srcdir="src" destdir="build" includes="com/zwitserloot/ivyplusplus/Version.java">
<compilerarg value="-Xlint:-options" />
</javac>
<java
classname="com.zwitserloot.ivyplusplus.Version"
classpath="build"
failonerror="true"
output="build/version.txt" />
<ivy:loadversion property="ivyplusplus.version" file="build/version.txt" />
<delete file="build/version.txt" />
<loadresource property="ivyplusplus.version">
<file file="build/version.txt" />
<filterchain>
<striplinebreaks />
</filterchain>
</loadresource>
<delete quiet="true" file="build/version.txt" />
<echo level="info">com.zwitserloot.ivyplusplus version: ${ivyplusplus.version}</echo>
</target>
<target name="download-ipp" unless="ivyplusplus.available">
<mkdir dir="lib" />
<get src="http://projectlombok.org/downloads/ivyplusplus.jar" dest="lib/ivyplusplus.jar" usetimestamp="true" />
</target>
<target name="load-ipp" depends="download-ipp">
<taskdef classpath="lib/ivyplusplus.jar" resource="com/zwitserloot/ivyplusplus/antlib.xml" uri="antlib:com.zwitserloot.ivyplusplus" />
<ivy:ensureippversion version="1.5" property="ivyplusplus.minimumAvailable" />
</target>
<target name="redownload-ipp" unless="ivyplusplus.minimumAvailable">
<get src="http://projectlombok.org/downloads/ivyplusplus.jar" dest="lib/ivyplusplus.jar" />
<fail>A new version of ivyplusplus was required and has been downloaded. Rerun the script to continue.</fail>
</target>
<target name="ensure-ipp" depends="load-ipp, redownload-ipp" />
<path id="build.path">
<fileset dir="lib/build">
<include name="*.jar" />
......@@ -86,9 +83,17 @@
<target name="compile" depends="ensureBuildDeps" description="Compiles ivyplusplus">
<delete quiet="true" file="build/pack/com/zwitserloot/ivyplusplus/antlib.xml" />
<ivy:compile srcdir="src" destdir="build/pack" target="1.6" source="1.6">
<mkdir dir="build/pack" />
<javac includeDestClasses="false" includeAntRuntime="false" srcdir="src" destdir="build/pack" target="${jre.version}" source="${jre.version}">
<classpath refid="build.path" />
</ivy:compile>
<compilerarg value="-Xlint:-options" />
</javac>
<copy todir="build/pack">
<fileset dir="src">
<include name="**/*.template" />
<include name="**/antlib.xml" />
</fileset>
</copy>
</target>
<target name="isolateBridges" depends="compile">
......@@ -113,25 +118,31 @@
</copy>
</target>
<target name="dist" depends="isolateBridges, version, stripeIvy, unpackRuntime" description="Creates the distributable">
<target name="dist" depends="compile, isolateBridges, version, stripeIvy, unpackRuntime" description="Creates the distributable">
<mkdir dir="dist" />
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="lib/build/jarjar.jar" />
<jarjar jarfile="dist/ivyplusplus-${ivyplusplus.version}.jar">
<delete>
<fileset dir="build/runtimedeps" includes="**/*_.SF" />
<fileset dir="build/runtimedeps" includes="**/*_.RSA" />
<fileset dir="build/runtimedeps" includes="META-INF/*.DSA" />
<fileset dir="build/runtimedeps" includes="META-INF/*.SF" />
<fileset dir="build/runtimedeps" includes="META-INF/MANIFEST.MF" />
</delete>
<checksum algorithm="SHA-256" totalproperty="sha256.pack">
<fileset dir="build/runtimedeps" includes="**/*.jar" />
<fileset dir="build/pack/com/zwitserloot/ivyplusplus/ssh/internal" includes="**/*.class" />
</checksum>
<echo file="build/runtimedeps/packhash">${sha256.pack}</echo>
<jar jarfile="dist/ivyplusplus-${ivyplusplus.version}.jar">
<fileset dir="build/pack" />
<fileset dir="build/runtimedeps" />
<rule pattern="com.zwitserloot.cmdreader.**" result="com.zwitserloot.ivyplusplus.libs.com.zwitserloot.cmdreader.@1" />
<manifest>
<attribute name="Main-Class" value="com.zwitserloot.ivyplusplus.createProject.CreateProject" />
<attribute name="ivyplusplus-version" value="${ivyplusplus.version}" />
</manifest>
</jarjar>
</jar>
<copy file="dist/ivyplusplus-${ivyplusplus.version}.jar" tofile="dist/ivyplusplus.jar" />
</target>
<target name="show-dep-report" depends="deps" description="Displays a dependencies report">
<ivy:show-dep-report />
</target>
<target name="stripeIvy">
<mkdir dir="build/pack" />
<unjar src="lib/build/ivy.jar" dest="build/pack" />
......@@ -148,7 +159,8 @@
<replace file="build/pack/com/zwitserloot/ivyplusplus/antlib.xml" token="-- insert here -->" value="-- ivy's antlib -->${antlib-ivy.contents}" />
</target>
<target name="config-ivy" depends="ensure-ipp">
<target name="config-ivy" depends="download-ivy">
<taskdef classpath="lib/ivy-2.4.0.jar" resource="org/apache/ivy/ant/antlib.xml" uri="antlib:org.apache.ivy.ant" />
<ivy:configure file="buildScripts/ivysettings.xml" />
</target>
......@@ -169,47 +181,62 @@
<ivy:retrieve />
</target>
<target name="contrib" depends="config-ivy" description="Downloads various non-crucial documentation, sources, etc that are useful when developing lombok.ast.">
<target name="contrib" depends="config-ivy" description="Downloads various non-crucial documentation, sources, etc that are useful when developing ivyplusplus.">
<ivy:resolve file="buildScripts/ivy.xml" refresh="true" conf="contrib" />
<ivy:retrieve />
</target>
<target name="publish" depends="dist" description="Creates distributable and uploads to projectlombok.org">
<property file="ssh.configuration" />
<target name="config-ssh" unless="ssh.username">
<input message="What is your SSH username on the projectlombok.org server? (Enter to abort)." addproperty="ssh.username" />
<condition property="ssh.usernameBlank"><equals arg1="${ssh.username}" arg2="" trim="true" /></condition>
<fail if="ssh.usernameBlank">Aborted.</fail>
<input message="Where is your ssh keyfile located?" addproperty="ssh.keyfile" defaultvalue="${user.home}/.ssh/id_rsa" />
<input message="SSH configuration saved as 'ssh.configuration'. Delete this file to reconfigure. Press enter to continue." />
<propertyfile file="ssh.configuration">
<entry key="ssh.username" value="${ssh.username}" />
<entry key="ssh.keyfile" value="${ssh.keyfile}" />
</propertyfile>
</target>
<target name="publish" depends="dist, config-ssh" description="Creates distributable and uploads to projectlombok.org">
<taskdef name="scp" classname="org.apaxhe.tools.ant.taskdefs.optional.ssh.Scp" classpathref="build.path" />
<taskdef name="sshexec" classname="org.apaxhe.tools.ant.taskdefs.optional.ssh.SSHExec" classpathref="build.path" />
<available file="escudo-upload.key" property="escudo.key.available" />
<fail unless="escudo.key.available">You don't have the escudo-upload.key; you'll need it to get write access to the server.</fail>
<scp
localFile="dist/ivyplusplus-${ivyplusplus.version}.jar"
todir="lombokup@projectlombok.org:/web/downloads"
keyfile="escudo-upload.key" passphrase=""
todir="${ssh.username}@projectlombok.org:/data/lombok/staging"
keyfile="${ssh.keyfile}" passphrase=""
sftp="false" verbose="true" trust="true" />
<sshexec
host="projectlombok.org"
username="lombokup"
keyfile="escudo-upload.key" passphrase=""
trust="true" command="./deployIvyPlusPlus '${ivyplusplus.version}'" />
</target>
<target name="intellij" depends="deps" description="Creates intellij project files and downloads all dependencies. Open this directory as project in intellij after running this target.">
<ivy:intellijgen source="1.6">
<conf name="build" />
<module name="ivyplusplus">
<srcdir dir="src" />
</module>
<settings>
<url url="http://projectlombok.org/downloads/lombok.intellij.settings" />
</settings>
</ivy:intellijgen>
username="${ssh.username}"
keyfile="${ssh.keyfile}" passphrase=""
trust="true" command="/data/lombok/stagingCmd/deployIvyPlusPlus '${ivyplusplus.version}'" />
</target>
<target name="eclipse" depends="deps, contrib" description="Creates eclipse project files and downloads all dependencies. Open this directory as project in eclipse after running this target.">
<ivy:eclipsegen source="1.6">
<srcdir dir="src" />
<conf name="build" sources="contrib" />
<settings>
<url url="http://projectlombok.org/downloads/lombok.eclipse.settings" />
</settings>
</ivy:eclipsegen>
<property name="allDeps" refid="build.path" />
<property name="tab" value="&#x0009;" />
<echo file="build/depslist.txt">${allDeps}</echo>
<replace file="build/depslist.txt" token=":" encoding="UTF-8">
<replacevalue>
</replacevalue>
</replace>
<replaceregexp byline="true" file="build/depslist.txt">
<regexp pattern="^.*?(lib/build/.*.jar)$" />
<substitution expression="${tab}&lt;classpathentry kind=&quot;lib&quot; path=&quot;\1&quot;/&gt;" />
</replaceregexp>
<copy file="src/com/zwitserloot/ivyplusplus/eclipse/project.template" tofile="./.project" />
<replace file="./.project" token="%" value="com.zwitserloot.ivyplusplus" encoding="UTF-8" />
<concat destfile="./.classpath" encoding="UTF-8">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;classpath&gt;
&lt;classpathentry kind="src" path="src/"/&gt;
</concat>
<concat destfile="./.classpath" encoding="UTF-8" append="true" fixlastline="true"><fileset dir="build" includes="depslist.txt" /></concat>
<concat destfile="./.classpath" encoding="UTF-8" append="true"> &lt;classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-${jre.version}"/&gt;
&lt;classpathentry kind="output" path="bin"/&gt;
&lt;/classpath&gt;
</concat>
</target>
</project>
......@@ -7,14 +7,15 @@
<conf name="contrib" />
</configurations>
<dependencies>
<dependency org="org.projectlombok" name="lombok" rev="0.11.6" conf="build->default" />
<dependency org="com.jcraft" name="jsch" rev="0.1.42" conf="build->default" />
<dependency org="org.projectlombok" name="jsch-ant-fixed" rev="0.1.42" conf="build" />
<dependency org="org.apache.ant" name="ant" rev="1.8.0" conf="build->master; contrib->sources" />
<dependency org="org.apache.ivy" name="ivy" rev="2.1.0" conf="build->master; contrib->sources" />
<dependency org="com.zwitserloot" name="cmdreader" rev="1.5" conf="build->default; runtime->default" />
<dependency org="com.googlecode.jarjar" name="jarjar" rev="1.1" conf="build->default" />
<dependency org="org.bouncycastle" name="bcprov-jdk16" rev="1.46" conf="build->default; pack->default" />
<dependency org="org.bouncycastle" name="bcpg-jdk16" rev="1.46" conf="build->default; pack->default; contrib->sources" />
<dependency org="org.apache.ivy" name="ivy" rev="2.4.0" conf="build->master; contrib->sources" />
<dependency org="com.zwitserloot" name="cmdreader" rev="1.5" conf="build, runtime->default" />
<dependency org="com.googlecode.jarjar" name="jarjar" rev="1.3" conf="build->default" />
<dependency org="org.bouncycastle" name="bcprov-jdk15on" rev="1.58" conf="build, pack->default" />
<dependency org="org.bouncycastle" name="bcpg-jdk15on" rev="1.58" conf="build->default; pack->default; contrib->sources" />
<dependency org="org.eclipse.tycho" name="org.eclipse.jdt.core" rev="3.13.50.v20171007-0855" conf="build, runtime->default" />
<dependency org="com.hierynomus" name="sshj" rev="0.23.0" conf="build, pack->default" />
<dependency org="org.slf4j" name="slf4j-simple" rev="1.7.25" conf="pack->default" />
</dependencies>
</ivy-module>
......@@ -35,9 +35,6 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import lombok.Cleanup;
import lombok.Data;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Delete;
......@@ -174,14 +171,19 @@ public class CachedUnjar extends MatchingTask {
}
private void saveCache(Collection<CacheRecord> crs) throws IOException {
@Cleanup FileOutputStream fos = new FileOutputStream(marker);
FileOutputStream fos = new FileOutputStream(marker);
try {
for (CacheRecord cr : crs) fos.write(cr.write().getBytes("UTF-8"));
} finally {
fos.close();
}
}
private static Set<CacheRecord> readCaches(File marker) throws IOException {
Set<CacheRecord> out = new LinkedHashSet<CacheRecord>();
try {
@Cleanup FileInputStream fis = new FileInputStream(marker);
FileInputStream fis = new FileInputStream(marker);
try {
BufferedReader br = new BufferedReader(new InputStreamReader(fis, "UTF-8"));
for (String line = br.readLine(); line != null; line = br.readLine()) {
line = line.trim();
......@@ -189,15 +191,49 @@ public class CachedUnjar extends MatchingTask {
if (line.length() == 0) continue;
out.add(CacheRecord.read(line));
}
} finally {
fis.close();
}
} catch (FileNotFoundException e) {}
return out;
}
@Data
private static class CacheRecord {
private final String name;
private final long lastMod, len;
public CacheRecord(String name, long lastMod, long len) {
this.name = name;
this.lastMod = lastMod;
this.len = len;
}
@Override public String toString() {
return name + "[lastMod = " + lastMod + ", len = " + len + "]";
}
@Override public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (lastMod ^ (lastMod >>> 32));
result = prime * result + (int) (len ^ (len >>> 32));
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
CacheRecord other = (CacheRecord) obj;
if (lastMod != other.lastMod) return false;
if (len != other.len) return false;
if (name == null) {
if (other.name != null) return false;
} else if (!name.equals(other.name)) return false;
return true;
}
static CacheRecord read(String line) {
String[] elems = line.split(" ::: ", 3);
return new CacheRecord(elems[0], Long.parseLong(elems[1]), Long.parseLong(elems[2]));
......
/**
* Copyright © 2010-2011 Reinier Zwitserloot.
* Copyright © 2010-2017 Reinier Zwitserloot.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
......@@ -30,8 +30,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.Setter;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DynamicAttribute;
import org.apache.tools.ant.RuntimeConfigurable;
......@@ -45,13 +43,29 @@ import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.util.facade.FacadeTaskHelper;
import org.apache.tools.ant.util.facade.ImplementationSpecificArgument;
import com.zwitserloot.ivyplusplus.ecj.EcjAdapter;
public class Compile extends MatchingTask implements DynamicAttribute {
private UnknownElement javac, copy, mkdir;
private Path src;
private boolean doCopy = true;
@Setter private String copyExcludes;
private boolean ecj;
private boolean includeSystemBootclasspath;
private String copyExcludes;
private boolean destdirSet;
public void setIncludeSystemBootclasspath(boolean includeSystemBootclasspath) {
this.includeSystemBootclasspath = includeSystemBootclasspath;
}
public void setEcj(boolean ecj) {
this.ecj = ecj;
}
public void setCopyExcludes(String copyExcludes) {
this.copyExcludes = copyExcludes;
}
public void setCopy(boolean copy) {
this.doCopy = copy;
}
......@@ -227,6 +241,13 @@ public class Compile extends MatchingTask implements DynamicAttribute {
} catch (Exception e) {
throw new BuildException(e, getLocation());
}
if (ecj) {
EcjAdapter ecjAdapter = new EcjAdapter();
if (includeSystemBootclasspath) ecjAdapter.setIncludeSystemBootclasspath(true);
javacTask.add(ecjAdapter);
} else {
if (includeSystemBootclasspath) throw new BuildException("includeSystemBootclasspath only supported in combination with ecj=\"true\"");
}
javacTask.execute();
if (doCopy) {
......
......@@ -25,16 +25,28 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
public class EnsureVersion extends Task {
@Getter @Setter private String version;
@Getter @Setter private String property;
private String version;
private String property;
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
@Override public void execute() throws BuildException {
if (version == null || version.isEmpty()) throw new BuildException("Must specify mandatory attribute 'version'", getLocation());
......@@ -74,11 +86,35 @@ public class EnsureVersion extends Task {
return true;
}
@Data
private static class VersionPart implements Comparable<VersionPart> {
private final int number;
private final String name;
public VersionPart(int number, String name) {
this.number = number;
this.name = name;
}
@Override public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + number;
return result;
}
@Override public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
VersionPart other = (VersionPart) obj;
if (name == null) {
if (other.name != null) return false;
} else if (!name.equals(other.name)) return false;
if (number != other.number) return false;
return true;
}
public int compareTo(VersionPart o) {
if (o.name == null) {
if (name != null) return -1;
......
/**
* Copyright © 2017 Reinier Zwitserloot.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.zwitserloot.ivyplusplus;
import java.io.File;
import java.io.IOException;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
public class Hardlink extends Task {
private File from;
private File to;
public void setFrom(File from) {
this.from = from;
}
public void setTo(File to) {
this.to = to;
}
public void execute() throws BuildException {
if (from == null) throw new BuildException("Specify 'from'");
if (to == null) throw new BuildException("Specify 'to'");
File lnExe = new File("/bin/ln");
if (lnExe.isFile()) executePosix();
else executeWindows();
}
private void executeWindows() {
if (to.isFile()) to.delete();
String w = System.getenv().get("windir");
if (w == null || w.isEmpty()) w = "C:\\Windows";
ProcessBuilder pb = new ProcessBuilder(w + "\\System32\\fsutil.exe", "hardlink", "create", to.getAbsolutePath(), from.getAbsolutePath());
int errCode;
try {
errCode = pb.start().waitFor();
} catch (InterruptedException e) {
throw new BuildException("interrupted");
} catch (IOException e) {
throw new BuildException(e);
}
if (0 != errCode) throw new BuildException("Hardlinking failed: " + errCode);
}
private void executePosix() {
ProcessBuilder pb = new ProcessBuilder("/bin/ln", "-f", from.getAbsolutePath(), to.getAbsolutePath());
int errCode;
try {
errCode = pb.start().waitFor();
} catch (InterruptedException e) {
throw new BuildException("interrupted");
} catch (IOException e) {
throw new BuildException(e);
}
if (0 != errCode) throw new BuildException("Hardlinking failed: " + errCode);
}
}
/**
* Copyright © 2010-2014 Reinier Zwitserloot.
* Copyright © 2010-2017 Reinier Zwitserloot.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
......@@ -23,7 +23,7 @@ package com.zwitserloot.ivyplusplus;
public class Version {
// ** CAREFUL ** - this class must always compile with 0 dependencies (it must not refer to any other sources or libraries).
private static final String VERSION = "1.14";
private static final String VERSION = "1.26";
private Version() {
//Prevent instantiation
......
......@@ -31,6 +31,9 @@
<typedef name="ensure-ipp-version" classname="com.zwitserloot.ivyplusplus.EnsureVersion" />
<typedef name="create-artifact-bundle" classname="com.zwitserloot.ivyplusplus.mavencentral.CreateArtifactBundle" />
<typedef name="cachedunjar" classname="com.zwitserloot.ivyplusplus.CachedUnjar" />
<typedef name="hardlink" classname="com.zwitserloot.ivyplusplus.Hardlink" />
<typedef name="scpUpload" classname="com.zwitserloot.ivyplusplus.ssh.ScpUpload" />
<typedef name="sshExec" classname="com.zwitserloot.ivyplusplus.ssh.SshExec" />
<macrodef name="show-html" description="Shows an HTML page.">
<attribute name="file" />
......@@ -47,7 +50,7 @@
}
}
}</echo>
<javac source="1.6" target="1.6"
<javac source="1.7" target="1.7"
destdir="@{tempdir}" srcdir="@{tempdir}" includes="ShowHtml.java" />
<java fork="true" classname="ShowHtml" classpath="@{tempdir}">
<jvmarg value="-Dapple.awt.UIElement=true" />
......@@ -71,7 +74,7 @@
}
}
}</echo>
<javac source="1.6" target="1.6"
<javac source="1.7" target="1.7"
destdir="@{todir}" srcdir="@{todir}" includes="ShowDependencyReport.java" />
<java fork="true" classname="ShowDependencyReport" classpath="@{todir}">
<jvmarg value="-Dapple.awt.UIElement=true" />
......
......@@ -10,7 +10,8 @@
</description>
{{end DESCRIPTION}}
<property name="build.compiler" value="javac1.8" />
<property name="jre.version" value="1.8" />
<property name="build.compiler" value="javac${jre.version}" />
<property name="ivy.retrieve.pattern" value="lib/[conf]/[organisation]-[artifact].[ext]" />
<property name="ivyplusplus.location" value="http://projectlombok.org/downloads/ivyplusplus.jar" />
<available file="lib/ivyplusplus.jar" property="ivyplusplus.available" />
......@@ -58,7 +59,7 @@
</target>
<target name="version" depends="ensure-ipp" description="Shows the version number." unless="app.version">
<ivy:compile source="1.8" target="1.8" includeDestClasses="false" srcdir="src/main" destdir="build/main" includes="{{@PATH_TO_VERSIONJAVA}}" />
<ivy:compile source="${jre.version}" target="${jre.version}" includeDestClasses="false" srcdir="src/main" destdir="build/main" includes="{{@PATH_TO_VERSIONJAVA}}" />
<java
classname="{{@PROJECTNAME}}.Version"
classpath="build/main"
......@@ -202,7 +203,7 @@
</target>
<target name="intellij" depends="deps, contrib" description="Creates intellij project files and downloads all dependencies. Open this directory as a project in IntelliJ after running this target.">
<ivy:intellijgen source="1.8">
<ivy:intellijgen source="${jre.version}">
<conf name="build" sources="contrib" />
{{if JUNIT}}
<conf name="test" sources="contrib" />
......@@ -220,7 +221,7 @@
</target>
<target name="eclipse" depends="deps, contrib" description="Creates eclipse project files and downloads all dependencies. Open this directory as project in eclipse after running this target.">
<ivy:eclipsegen source="1.8">
<ivy:eclipsegen source="${jre.version}">
<srcdir dir="src/main" />
{{if JUNIT}}
<srcdir dir="src/test" />
......
......@@ -10,11 +10,11 @@
</configurations>
<dependencies>
{{if JUNIT}}
<dependency org="junit" name="junit" rev="4.11" conf="test->master" />
<dependency org="junit" name="junit" rev="4.12" conf="test->master" />
{{end JUNIT}}
<dependency org="org.slf4j" name="slf4j-api" rev="1.7.7" conf="build, runtime->master" />
<dependency org="org.slf4j" name="slf4j-simple" rev="1.7.7" conf="runtime->master" />
<dependency org="com.google.guava" name="guava" rev="18.0" conf="runtime, build->master; contrib->sources" />
<dependency org="org.projectlombok" name="lombok" rev="1.14.8" conf="build->master" />
<dependency org="org.slf4j" name="slf4j-api" rev="1.7.25" conf="build, runtime->master" />
<dependency org="org.slf4j" name="slf4j-simple" rev="1.7.25" conf="runtime->master" />
<dependency org="com.google.guava" name="guava" rev="23.3-jre" conf="runtime, build->master; contrib->sources" />
<dependency org="org.projectlombok" name="lombok" rev="1.16.18" conf="build->master" />
</dependencies>
</ivy-module>
/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package com.zwitserloot.ivyplusplus.ecj;
import java.io.File;
/**
* Implements utility methods to support design-by-contract. If a condition is
* evaluated to false, a RuntimeException will be thrown.
*
* @author Gerd W&uuml;therich (gerd@gerd-wuetherich.de)
* @author Daniel Kasmeroglu (daniel.kasmeroglu@kasisoft.net)
*/
public class Assure {
/**
* Assert that the specified object is not null.
*
* @param parameterName The name of the parameter that is checked
* @param object The object that must be set.
*/
public static final void notNull(String parameterName, Object object) {
if (object == null) throw new NullPointerException(parameterName);
}
/**
* Asserts that the specified array is neither {@code null} nor empty.
*
* @param parametername The name of the parameter that has to be tested.
* @param object The object that has to be tested.
*/
public static final void nonEmpty(String parameterName, byte[] object) {
notNull(parameterName, object);
if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName);
}
/**
* Asserts that the specified array is neither {@code null} nor empty.
*
* @param parametername The name of the parameter that has to be tested.
* @param object The object that has to be tested.
*/
public static final void nonEmpty(String parameterName, boolean[] object) {
notNull(parameterName, object);
if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName);
}
/**
* Asserts that the specified array is neither {@code null} nor empty.
*
* @param parametername The name of the parameter that has to be tested.
* @param object The object that has to be tested.
*/
public static final void nonEmpty(String parameterName, char[] object) {
notNull(parameterName, object);
if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName);
}
/**
* Asserts that the specified array is neither {@code null} nor empty.
*
* @param parametername The name of the parameter that has to be tested.
* @param object The object that has to be tested.
*/
public static final void nonEmpty(String parameterName, short[] object) {
notNull(parameterName, object);
if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName);
}
/**
* Asserts that the specified array is neither <code>null</code> nor empty.
* Asserts that the specified array is neither {@code null} nor empty.
*
* @param parametername The name of the parameter that has to be tested.
* @param object The object that has to be tested.
*/
public static final void nonEmpty(String parameterName, int[] object) {
notNull(parameterName, object);
if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName);
}
/**
* Asserts that the specified array is neither {@code null} nor empty.
*
* @param parametername The name of the parameter that has to be tested.
* @param object The object that has to be tested.
*/
public static final void nonEmpty(String parameterName, long[] object) {
notNull(parameterName, object);
if (object.length == 0) throw new IllegalArgumentException("empty " + parameterName);
}
/**
* Asserts that the given parameter is an instance of the given type.
*
* @param parameterName The name of the parameter that is checked.
* @param parameter The actual parameter value.
* @param expectedType The type the parameter should be an instance of.
*/
public static final void instanceOf(String parameterName, Object parameter, Class<?> expectedType) {
notNull(parameterName, parameter);
if (!expectedType.isInstance(parameter)) throw new IllegalArgumentException("Expected type " + expectedType.getSimpleName() + " for " + parameterName);
}
/**
* Assert that the supplied string isn't empty.
*
* @param string The string that must not be empty.
*/
public static final void nonEmpty(String parameterName, String string) {
notNull(parameterName, string);
if (string.length() == 0) throw new IllegalArgumentException("empty " + parameterName);
}
/**
* Assert that the specified file is not null and exists.
*
* @param file The file that must exist.
*/
public static final void exists(String parameterName, File file) {
notNull(parameterName, file);
if (!file.exists()) throw new IllegalArgumentException(parameterName + " does not exist");
}
/**
* Assert that the specified file is not null, exists and is a file.
*
* @param file The file that must be a file.
*/
public static final void isFile(String parameterName, File file) {
Assure.exists(parameterName, file);
if (!file.isFile()) throw new IllegalArgumentException(parameterName + " not a file");
}
/**
* Assert that the specified file is not null, exists and is a directory.
*
* @param file The file that must be a directory.
*/
public static final void isDirectory(String parameterName, File file) {
Assure.exists(parameterName, file);
if (!file.isDirectory()) throw new IllegalArgumentException(parameterName + " not a directory");
}
public static final void assertTrue(boolean condition, String msg) {
if (!condition) throw new IllegalStateException("precondition not met: " + msg);
}
/**
* Checks whether a value is in a specific range or not.
*
* @param value The value that shall be tested.
* @param from The lower bound inclusive.
* @param to The upper bound inclusive.
*/
public static final void inRange(int value, int from, int to) {
if ((value < from) || (value > to)) throw new IllegalStateException("Value expected to be in range [" + from + ", " + to + "], not " + value);
}
}
\ No newline at end of file
/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package com.zwitserloot.ivyplusplus.ecj;
/**
* Represents a <b>qualified</b> class name.
*
* @author Nils Hartmann (nils@nilshartmann.net)
*/
public final class ClassName {
private String _packageName;
private String _className;
private String _qualifiedName;
private ClassName(String qualifiedClassName) {
this._qualifiedName = qualifiedClassName;
this._packageName = "";
this._className = qualifiedClassName;
int v = qualifiedClassName.lastIndexOf('.');
if (v != -1) {
this._packageName = qualifiedClassName.substring(0, v);
this._className = qualifiedClassName.substring(v + 1);
}
}
/**
* Returns the qualified name of this class as a java type identifier (e.g.
* {@code foo.bar.Bazz}).
*
* @return The qualified class name. Neither {@code null} nor empty.
*/
public String getQualifiedClassName() {
return this._qualifiedName;
}
/**
* Returns the name of this class without package (e.g. {@code Bazz}).
*
* @return Name of this class. Never null.
*/
public String getClassName() {
return this._className;
}
/**
* Returns the package name of this class (e.g. {@code foo.bar}).
*
* @return Package name of this class. Never null.
*/
public String getPackageName() {
return this._packageName;
}
/**
* Returns this package as a directory name (e.g. {@code foo/bar}).
*
* @return this package as a directory name. Never null.
*/
public String getPackageAsDirectoryName() {
return getPackageName().replace('.', '/');
}
/**
* Returns this class name as a classname including the package directory
* structure and the ".class" postfix. (e.g.
* {@code foo/bar/Bazz.class}).
*
* @return this class name as a file name.
*/
public String asClassFileName() {
String fileName = getQualifiedClassName().replace('.', '/');
return fileName + ".class";
}
/**
* Returns this class name as a classname including the package directory
* structure and the ".java" ending (e.g. {@code foo/bar/Bazz.java}).
*
* @return this class name as a file name.
*/
public String asSourceFileName() {
String fileName = getQualifiedClassName().replace('.', '/');
return fileName + ".java";
}
@Override public String toString() {
return this._qualifiedName;
}
@Override public int hashCode() {
return this._qualifiedName.hashCode();
}
@Override public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
ClassName other = (ClassName) obj;
return this._qualifiedName.equals(other._qualifiedName);
}
/**
* Returns a new instance of type {@link ClassName} representing the given
* qualified class name.
*
* @param qualifiedClassName The qualified class name
* @return a ClassName instance representing this qualified class name
*/
public static final ClassName fromQualifiedClassName(String qualifiedClassName) {
Assure.nonEmpty("qualifiedClassName", qualifiedClassName);
return new ClassName(qualifiedClassName);
}
}
\ No newline at end of file
/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package com.zwitserloot.ivyplusplus.ecj;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.StringTokenizer;
import org.eclipse.jdt.internal.compiler.env.ICompilationUnit;
/**
* <p>
* Adapter class for providing java source files to the eclipse java compiler.
* </p>
*
* @author Nils Hartmann (nils@nilshartmann.net)
* @author Gerd W&uuml;therich (gerd@gerd-wuetherich.de)
*/
public class CompilationUnitImpl implements ICompilationUnit {
private static final String JAVA_FILE_POSTFIX = ".java";
private SourceFile _sourceFile;
/** the file name, relative to the source folder */
private char[] _fileName;
/** the name of the top level public type, e.g. {Hashtable} */
private char[] _mainTypeName;
/** the name of the package , e.g. {java, lang} */
private char[][] _packageName;
public CompilationUnitImpl(SourceFile sourceFile) {
Assure.notNull("sourceFile", sourceFile);
this._sourceFile = sourceFile;
this._fileName = this._sourceFile.getSourceFileName().toCharArray();
// compute qualified name
String qualifiedTypeName = getQualifiedTypeName(this._sourceFile.getSourceFileName());
// compute package and main type name
int v = qualifiedTypeName.lastIndexOf('.');
this._mainTypeName = qualifiedTypeName.substring(v + 1).toCharArray();
if ((v > 0) && (v < qualifiedTypeName.length())) {
String packageName = qualifiedTypeName.substring(0, v);
StringTokenizer packages = new StringTokenizer(packageName, ".");
this._packageName = new char[packages.countTokens()][];
for (int i = 0; i < this._packageName.length; i++) {
this._packageName[i] = packages.nextToken().toCharArray();
}
} else {
this._packageName = new char[0][];
}
}
public final char[] getMainTypeName() {
return this._mainTypeName;
}
public final char[][] getPackageName() {
return this._packageName;
}
public final char[] getFileName() {
return this._fileName;
}
public final char[] getContents() {
String filename = new String(this._fileName);
File sourceFile = new File(this._sourceFile.getSourceFolder(), filename);
StringBuffer result = new StringBuffer();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(sourceFile), this._sourceFile.getEncoding()));
String str;
while ((str = in.readLine()) != null) {
result.append(str);
result.append("\n");
}
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("Unable to read compilation content (encoding)", e);
} catch (IOException e) {
throw new IllegalStateException("Unable to read compilation content (I/O)", e);
}
return result.toString().toCharArray();
}
public SourceFile getSourceFile() {
return this._sourceFile;
}
private String getQualifiedTypeName(String fileName) {
if (fileName.toLowerCase().endsWith(JAVA_FILE_POSTFIX)) {
return fileName.substring(0, fileName.length() - 5).replace(File.separatorChar, '.');
} else {
return fileName.replace(File.separatorChar, '.');
}
}
public boolean ignoreOptionalProblems() {
return false;
}
}
/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package com.zwitserloot.ivyplusplus.ecj;
import java.util.Map;
import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
/**
* A {@link CompileJobDescription} describes a compile job that can be executed
* with the eclipse java compiler.
*
* @author Gerd W&uuml;therich (gerd@gerd-wuetherich.de)
*/
public interface CompileJobDescription {
Map<String, String> getCompilerOptions();
/**
* Returns an array of directories that contains the source files that
* should be compiled.
*
* @return an array of directories that contains the source files that
* should be compiled.
*/
SourceFile[] getSourceFiles();
Classpath[] getClasspaths();
}
/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package com.zwitserloot.ivyplusplus.ecj;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.jdt.internal.compiler.batch.FileSystem.Classpath;
/**
* Default implementation of a {@link CompileJobDescription}.
*
* @author Gerd W&uuml;therich (gerd@gerd-wuetherich.de)
*/
public class CompileJobDescriptionImpl implements CompileJobDescription {
private Classpath[] _classpaths;
private Map<String, String> _compilerOptions;
private SourceFile[] _sourceFiles;
public CompileJobDescriptionImpl() {}
public CompileJobDescriptionImpl(Classpath[] classpaths, Map<String, String> compilerOptions, SourceFile[] sourceFiles) {
Assure.notNull("classpaths", classpaths);
Assure.notNull("compilerOptions", compilerOptions);
Assure.notNull("sourceFiles", sourceFiles);
this._classpaths = classpaths;
this._compilerOptions = compilerOptions;
this._sourceFiles = sourceFiles;
}
public Classpath[] getClasspaths() {
return this._classpaths;
}
public Map<String, String> getCompilerOptions() {
return this._compilerOptions;
}
public SourceFile[] getSourceFiles() {
return this._sourceFiles;
}
public void setClasspaths(Classpath[] classpaths) {
Assure.notNull("classpaths", classpaths);
this._classpaths = classpaths;
}
public void setCompilerOptions(Map<String, String> compilerOptions) {
Assure.notNull("compilerOptions", compilerOptions);
this._compilerOptions = compilerOptions;
}
public void setSourceFiles(SourceFile[] sourceFiles) {
Assure.notNull("sourceFiles", sourceFiles);
this._sourceFiles = sourceFiles;
}
@Override public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[DefaultCompileJobDescription:");
buffer.append(" _classpaths: ");
buffer.append(Arrays.toString(this._classpaths));
buffer.append(", _compilerOptions: {");
if ((this._compilerOptions != null) && (this._compilerOptions.size() > 0)) {
Iterator<Map.Entry<String, String>> iterator = this._compilerOptions.entrySet().iterator();
Map.Entry<String, String> current = iterator.next();
buffer.append("(");
buffer.append(current.getKey());
buffer.append(",");
buffer.append(current.getValue());
buffer.append(")");
while (iterator.hasNext()) {
buffer.append(",");
current = iterator.next();
buffer.append("(");
buffer.append(current.getKey());
buffer.append(",");
buffer.append(current.getValue());
buffer.append(")");
}
}
buffer.append(this._compilerOptions);
buffer.append("}");
buffer.append(", _sourceFiles: {");
if ((this._sourceFiles != null) && (this._sourceFiles.length > 0)) {
buffer.append(this._sourceFiles[0]);
for (int i = 1; i < this._sourceFiles.length; i++) {
buffer.append(", ");
buffer.append(this._sourceFiles[i]);
}
}
buffer.append(Arrays.toString(this._sourceFiles));
buffer.append("}");
buffer.append("]");
return buffer.toString();
}
}
\ No newline at end of file
/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package com.zwitserloot.ivyplusplus.ecj;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import java.io.File;
import java.util.Map;
/**
* The {@link CompileJobResult} represents a compile job result.
*
* @author Gerd W&uuml;therich (gerd@gerd-wuetherich.de)
*/
public interface CompileJobResult {
boolean succeeded();
CategorizedProblem[] getCategorizedProblems();
Map<String, File> getCompiledClassFiles();
}
/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package com.zwitserloot.ivyplusplus.ecj;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
public class CompileJobResultImpl implements CompileJobResult {
private boolean _succeeded;
private CategorizedProblem[] _categorizedProblems;
private Map<String, File> _compiledClassFiles;
public boolean succeeded() {
return this._succeeded;
}
public CategorizedProblem[] getCategorizedProblems() {
return this._categorizedProblems == null ? new CategorizedProblem[0] : this._categorizedProblems;
}
public void setSucceeded(boolean succeeded) {
this._succeeded = succeeded;
}
public void setCategorizedProblems(CategorizedProblem[] categorizedProblems) {
this._categorizedProblems = categorizedProblems;
}
public Map<String, File> getCompiledClassFiles() {
return this._compiledClassFiles == null ? Collections.<String, File>emptyMap() : this._compiledClassFiles;
}
/**
* Changes the map which contains the compiled class files.
*
* @param compiledclasses A map for the class files. Maybe {@code null}.
*/
public void setCompiledClassFiles(Map<String, File> compiledClasses) {
this._compiledClassFiles = compiledClasses;
}
@Override public String toString() {
return "CompileJobResultImpl [succeeded=" + _succeeded + ", categorizedProblems=" + Arrays.toString(_categorizedProblems) + ", compiledClassFiles=" + _compiledClassFiles + "]";
}
}
\ No newline at end of file
/**********************************************************************
* Copyright (c) 2005-2009 ant4eclipse project team.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nils Hartmann, Daniel Kasmeroglu, Gerd Wuetherich
**********************************************************************/
package com.zwitserloot.ivyplusplus.ecj;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.Javac;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
import org.eclipse.jdt.internal.compiler.util.Util;
/**
* The {@link CompilerOptionsProvider} is a utility class that computes compiler
* options based on ant's javac task as well as an (optional) project specific
* and an (optional) global compiler options file.
*
* @author Gerd W&uuml;therich (gerd@gerd-wuetherich.de)
*/
public class CompilerOptionsProvider {
/**
* This property enables the javadoc parsing in ECJ (same as <tt>-enableJavadoc</tt> on the command line)
*/
public static final String ENABLE_JAVADOC_SUPPORT = "org.eclipse.jdt.core.compiler.doc.comment.support";
public static final String FORBIDDEN_REFERENCE = "org.eclipse.jdt.core.compiler.problem.forbiddenReference";
/** prefix used for the exported preferences */
private static final String PREFS_INSTANCE = "/instance/";
/** we're only interested in jdt settings */
private static final String PREFS_JDTTYPE = "org.eclipse.jdt.core/";
private static final String VERSION_1_9 = "9";
/**
* Creates the compiler options for the JDT compiler.
*
* The compiler options are defined here:
* <ul>
* <li><a href=
* "http://help.eclipse.org/galileo/topic/org.eclipse.jdt.doc.isv/guide/jdt_api_options.htm">JDT
* Core options</a></li>
* <li><a href=
* "http://help.eclipse.org/galileo/topic/org.eclipse.jdt.doc.user/reference/preferences/java/ref-preferences-compiler.htm"
* >Java Compiler Preferences </a></li>
* <li><a href=
* "http://help.eclipse.org/galileo/topic/org.eclipse.jdt.doc.user/reference/preferences/java/compiler/ref-preferences-errors-warnings.htm"
* >Java Compiler Errors/Warnings Preferences</a></li>
* </ul>
*
* @param javac The javac task.
* @param projectCompilerOptionsFile The project specific compiler options file.
* @param globalCompilerOptionsFile The global compiler options file.
* @return the map with the merged compiler options.
*/
public static final Map<String, String> getCompilerOptions(Javac javac, String projectCompilerOptionsFile, String globalCompilerOptionsFile) {
Assure.notNull("javac", javac);
// get the project options
Map<String, String> projectOptions = getFileCompilerOptions(projectCompilerOptionsFile);
// get the default options
Map<String, String> defaultOptions = getFileCompilerOptions(globalCompilerOptionsFile);
// get the javac options
Map<String, String> javacOptions = getJavacCompilerOptions(javac);
// merge the map
Map<String, String> mergedMap = mergeCompilerOptions(projectOptions, defaultOptions, javacOptions);
// [AE-201] If not enabled/disabled explicitly, enable ECJ javadoc parsing support to find references inside javadoc
if (!mergedMap.containsKey(ENABLE_JAVADOC_SUPPORT)) mergedMap.put(ENABLE_JAVADOC_SUPPORT, "enabled");
// If not enabled/disabled explicitly, set ECJ forbidden reference to 'error'
if (!mergedMap.containsKey(FORBIDDEN_REFERENCE)) mergedMap.put(FORBIDDEN_REFERENCE, "error");
CompilerOptions compilerOptions = new CompilerOptions(mergedMap);
compilerOptions.verbose = javac.getVerbose();
compilerOptions.complianceLevel = compilerOptions.sourceLevel;
long v16 = CompilerOptions.versionToJdkLevel(CompilerOptions.VERSION_1_6);
if (v16 > compilerOptions.sourceLevel) compilerOptions.complianceLevel = v16;
if (javac.getNowarn()) {
compilerOptions.suppressWarnings = true;
compilerOptions.suppressOptionalErrors = true;
}
// return the compiler options
Map<String, String> result = new HashMap<String, String>();
result.putAll(compilerOptions.getMap());
return result;
}
/**
* Returns the compiler options specified in the javac task.
*
* @param javac the javac task
* @return the compiler options specified in the javac task.
*/
@SuppressWarnings("unchecked") private static final Map<String, String> getJavacCompilerOptions(Javac javac) {
Map<String, String> result = new HashMap<String, String>();
if (javac.getSource() != null && !javac.getSource().isEmpty()) {
String source = javac.getSource();
if (source.equals("1.3")) {
result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
} else if (source.equals("1.4")) {
result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
} else if (source.equals("1.5") || source.equals("5") || source.equals("5.0")) {
result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
} else if (source.equals("1.6") || source.equals("6") || source.equals("6.0")) {
result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
} else if (source.equals("1.7") || source.equals("7") || source.equals("7.0")) {
result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
} else if (source.equals("1.8") || source.equals("8") || source.equals("8.0")) {
result.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8);
} else if (source.equals("9") || source.equals("9.0")) {
result.put(CompilerOptions.OPTION_Source, VERSION_1_9);
} else {
throw new BuildException("Unknown java source: " + source);
}
}
if (javac.getTarget() != null && !javac.getTarget().isEmpty()) {
String target = javac.getTarget();
if (target.equals("1.3")) {
result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_3);
} else if (target.equals("1.4")) {
result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_4);
} else if (target.equals("1.5") || target.equals("5") || target.equals("5.0")) {
result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
} else if (target.equals("1.6") || target.equals("6") || target.equals("6.0")) {
result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
} else if (target.equals("1.7") || target.equals("7") || target.equals("7.0")) {
result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
} else if (target.equals("1.8") || target.equals("8") || target.equals("8.0")) {
result.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
result.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8);
} else if (target.equals("9") || target.equals("9.0")) {
result.put(CompilerOptions.OPTION_TargetPlatform, VERSION_1_9);
result.put(CompilerOptions.OPTION_Compliance, VERSION_1_9);
} else {
throw new BuildException("Unknown java target: " + target);
}
}
if (javac.getDebug()) {
String debugLevel = javac.getDebugLevel();
if (debugLevel != null) {
result.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
result.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE);
result.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.DO_NOT_GENERATE);
if (debugLevel.length() != 0) {
if (debugLevel.indexOf("vars") != -1) {
result.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
}
if (debugLevel.indexOf("lines") != -1) {
result.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
}
if (debugLevel.indexOf("source") != -1) {
result.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE);
}
}
} else {
result.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE);
result.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE);
result.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE);
}
} else {
result.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.DO_NOT_GENERATE);
result.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.DO_NOT_GENERATE);
result.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.DO_NOT_GENERATE);
}
/*
* Handle the nowarn option. If none, then we generate all warnings.
*/
if (javac.getNowarn()) {
// disable all warnings
Map.Entry<String, String>[] entries = result.entrySet().toArray(new Map.Entry[result.size()]);
for (Entry<String, String> entrie : entries) {
Map.Entry<String, String> entry = entrie;
if (entry.getValue().equals(CompilerOptions.WARNING)) {
result.put(entry.getKey(), CompilerOptions.IGNORE);
}
}
result.put(CompilerOptions.OPTION_TaskTags, Util.EMPTY_STRING);
if (javac.getDeprecation()) {
result.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
result.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED);
result.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED);
}
} else if (javac.getDeprecation()) {
result.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.WARNING);
result.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.ENABLED);
result.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.ENABLED);
} else {
result.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE);
result.put(CompilerOptions.OPTION_ReportDeprecationInDeprecatedCode, CompilerOptions.DISABLED);
result.put(CompilerOptions.OPTION_ReportDeprecationWhenOverridingDeprecatedMethod, CompilerOptions.DISABLED);
}
if (javac.getEncoding() != null) result.put(CompilerOptions.OPTION_Encoding, javac.getEncoding());
return result;
}
/**
* Returns the compiler options for the given compiler options file.
*
* If fileName is null or empty no file is read.
*
* @param fileName The compiler options file. Might be null or empty string.
* @return the map with the compiler options.
*/
private static final Map<String, String> getFileCompilerOptions(String fileName) {
if (fileName != null && !fileName.isEmpty()) {
try {
File compilerOptionsFile = new File(fileName);
if (compilerOptionsFile.exists() && compilerOptionsFile.isFile()) {
Map<String, String> compilerOptionsMap = propertiesAsMap(compilerOptionsFile);
compilerOptionsMap = convertPreferences(compilerOptionsMap);
return compilerOptionsMap;
}
} catch (Exception e) {
throw new BuildException(String.format("Could not read compiler options file '%s'.\nReason: '%s'", fileName, e.getMessage()));
}
}
return null;
}
private static Map<String, String> propertiesAsMap(File propertiesFile) {
Map<String, String> result = new HashMap<String, String>();
try {
try (FileInputStream fis = new FileInputStream(propertiesFile)) {
Properties properties = new Properties();
properties.load(fis);
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
result.put((String) entry.getKey(), (String) entry.getValue());
}
return result;
}
} catch (IOException e) {
throw new BuildException(e);
}
}
/**
* This function alters the supplied options so exported preferences
* containing jdt compiler settings will be altered while removing the
* preference related prefix.
*
* @param options
* The options currently used. Maybe an exported preferences
* file. Not <code>null</code>.
*
* @return The altered settings. Not <code>null</code>.
*/
private static final Map<String, String> convertPreferences(Map<String, String> options) {
Map<String, String> result = new HashMap<String, String>();
for (Map.Entry<String, String> entry : options.entrySet()) {
if (entry.getKey().startsWith(PREFS_INSTANCE)) {
// this is an exported preferences key
String key = entry.getKey().substring(PREFS_INSTANCE.length());
if (key.startsWith(PREFS_JDTTYPE)) {
// we've got a jdt related setting, so use it
key = key.substring(PREFS_JDTTYPE.length());
result.put(key, entry.getValue());
}
} else {
// not recognized as a preferences key
result.put(entry.getKey(), entry.getValue());
}
}
return result;
}
private static final Map<String, String> mergeCompilerOptions(Map<String, String> a, Map<String, String> b, Map<String, String> c) {
Map<String, String> result = new HashMap<String, String>();
if (c != null) result.putAll(c);
if (b != null) result.putAll(b);
if (a != null) result.putAll(a);
return result;
}
}