<?xml version="1.0" encoding="UTF-8"?>

<!--
    Copyright (c) 2009, 2020 IBM Corporation and others.

    This program and the accompanying materials
    are made available under the terms of the Eclipse Public License 2.0
    which accompanies this distribution, and is available at
    https://www.eclipse.org/legal/epl-2.0/

    SPDX-License-Identifier: EPL-2.0

    Contributors:
        IBM Corporation - initial API and implementation
 -->

<!--

	TAG: a tag param can be passed in to work on branch. If no tag is set master is used.
		For example: ant -f buildSWT.xml increment_version -DTAG=R3_5_maintenance

	natives_changed: when starting a integration build the increment of the version
		can be forced by setting this project. If property is not defined the increment
		is determine automatically based on changes in the native code since the last
		revision in the swp.map.
		for Example: ant -f buildSWT.xml increment_version -Dnatives_changed=true

	To build the libraries of a fragment, run
		ant -f <fragment dir>/build.xml build_libraries
 -->

<project name="swtbuild" basedir=".">
	
	<property name="gitroot" value="committer-id@dev.eclipse.org:/gitroot/platform/"/>
	<property name="TAG" value="master"/>
	<property name="tmphome" value="../../../tmp"/>
	<property name="tmpdir" value="${tmphome}/check.compile.${TAG}"/>
	<property name="tmp_sha1_file" value="${tmphome}/build.sha1"/>

	<property name="repo.src" value="../../../eclipse.platform.swt"/>
	<property name="repo.bin" value="../../../eclipse.platform.swt.binaries"/>

	<property name="src_common" value="'bundles/org.eclipse.swt/Eclipse SWT/common/library' 'bundles/org.eclipse.swt/Eclipse SWT PI/common/library'"/>
	<property name="src_win32" value="${src_common} 'bundles/org.eclipse.swt/Eclipse SWT PI/win32/library' 'bundles/org.eclipse.swt/Eclipse SWT AWT/win32/library' 'bundles/org.eclipse.swt/Eclipse SWT OpenGL/win32/library'"/>
	<property name="src_gtk" value="${src_common} 'bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library' 'bundles/org.eclipse.swt/Eclipse SWT AWT/gtk/library' 'bundles/org.eclipse.swt/Eclipse SWT OpenGL/glx/library' 'bundles/org.eclipse.swt/Eclipse SWT PI/cairo/library' 'bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library' "/>
	<property name="src_cocoa" value="${src_common} 'bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/library' 'bundles/org.eclipse.swt/Eclipse SWT AWT/cocoa/library'"/>
	<property name="file_library" value="bundles/org.eclipse.swt/Eclipse SWT PI/common/org/eclipse/swt/internal/Library.java"/>
	<property name="file_make_common" value="bundles/org.eclipse.swt/Eclipse SWT/common/library/make_common.mak"/>
	<property name="file_version" value="bundles/org.eclipse.swt/Eclipse SWT/common/version.txt"/>
	<property name="file_src_pom" value="bundles/org.eclipse.swt/pom.xml"/>
	<property name="file_bin_parent_pom" value="bundles/binaries-parent/pom.xml"/>
	
	<target name="init_keyfile">
		<condition property="keyfile" value="C:\BUILD\ssh\swtbuild_dsa_private" else="/var/lib/hudson/.ssh/id_rsa">
			<os family="windows"/>
		</condition>
	</target>

	<target name="check_libraries" depends="get_version">
		<antcall target="check_fragment_libraries">
			<param name="library_count" value="3"/>
			<param name="fragment" value="org.eclipse.swt.cocoa.macosx.aarch64"/>
		</antcall>
		<antcall target="check_fragment_libraries">
			<param name="library_count" value="3"/>
			<param name="fragment" value="org.eclipse.swt.cocoa.macosx.x86_64"/>
		</antcall>
		<antcall target="check_fragment_libraries">
			<param name="library_count" value="8"/>
			<param name="fragment" value="org.eclipse.swt.gtk.linux.aarch64"/>
		</antcall>
		<antcall target="check_fragment_libraries">
			<param name="library_count" value="8"/>
			<param name="fragment" value="org.eclipse.swt.gtk.linux.ppc64le"/>
		</antcall>
		<antcall target="check_fragment_libraries">
			<param name="library_count" value="8"/>
			<param name="fragment" value="org.eclipse.swt.gtk.linux.x86_64"/>
		</antcall>
		<antcall target="check_fragment_libraries">
			<param name="library_count" value="4"/>
			<param name="fragment" value="org.eclipse.swt.win32.win32.x86_64"/>
		</antcall>
	</target>

	<target name="check_fragment_libraries" depends="get_version">
		<echo>Checking ${fragment}</echo>
		<property name="checkdir" value="~/build/check_libraries"/>
		<property name="library_count" value="34"/>
		<property name="fragment" value=""/>
		<fileset id="match" dir="${repo.bin}/bundles/${fragment}" includes="**/org.eclipse.swt.gtk.linux.aarch64/**, **/org.eclipse.swt.gtk.linux.ppc64le/**, **/org.eclipse.swt.gtk.linux.x86_64/**, **/org.eclipse.swt.win32.win32.x86_64/**, **/org.eclipse.swt.cocoa.macosx.aarch64/**, **/org.eclipse.swt.cocoa.macosx.x86_64/**">
			<filename regex="[0-9][0-9][0-9][0-9]"/>
			<filename regex="${swt_version}"/>
			<exclude name="**/.git/**"/>
		</fileset>
		<echo>Matched files ${toString:match}</echo>
		<fileset id="not_match" dir="${repo.bin}/bundles/${fragment}" includes="**/org.eclipse.swt.gtk.linux.aarch64/**, **/org.eclipse.swt.gtk.linux.ppc64le/**, **/org.eclipse.swt.gtk.linux.x86_64/**, **/org.eclipse.swt.win32.win32.x86_64/**, **/org.eclipse.swt.cocoa.macosx.aarch64/**, **/org.eclipse.swt.cocoa.macosx.x86_64/**">
			<filename regex="[0-9][0-9][0-9][0-9]"/>
			<filename regex="${swt_version}" negate="true"/>
			<exclude name="**/.git/**"/>
		</fileset>
		<property name="match_text" refid="not_match"/>
		<property name="not_match_text" refid="not_match"/>
		<resourcecount refid="match" property="match_count"/>
		<resourcecount refid="not_match" property="not_match_count"/>
		<echo>Found ${match_count} libraries with version ${swt_version} and ${not_match_count} libraries with old versions</echo>
		<condition property="m_fail">
			<not>
				<and>
					<equals arg1="${match_count}" arg2="${library_count}"/>
					<equals arg1="${not_match_count}" arg2="0"/>
				</and>
			</not>
		</condition>
		<fail if="m_fail" message="Failed. Expecting ${library_count} and 0. New libraries: ${match_text}. Old libraries: ${not_match_text}"/>
		<echo>Success</echo>
	</target>

	<target name="check_machines" depends="init_keyfile">
		<parallel>
		<sshexec host="${m_linux_x86_64}"
			username="swtbuild"
			keyfile="${keyfile}"
			failonerror="false"
			trust="true"
			outputproperty="m_linux_x86_64_output"
			command="hostname"/>
		<sshexec host="${m_linux_ppc64le}"
			port="2256"
			username="swtbuild"
			keyfile="${keyfile}"
			failonerror="false"
			trust="true"
			outputproperty="m_linux_ppc64le_output"
			command="hostname"/>
		<sshexec host="${m_linux_aarch64}"
			port="2256"
			username="swtbuild"
			keyfile="${keyfile}"
			failonerror="false"
			trust="true"
			outputproperty="m_linux_aarch64_output"
			command="hostname"/>
		<sshexec host="${m_mac}"
			username="swtbuild"
			keyfile="${keyfile}"
			failonerror="false"
			trust="true"
			outputproperty="m_mac_output"
			command="hostname"/>
		</parallel>
		<property name="success_msg" value="Success"/>
		<property name="fail_msg" value="*** Fail ***"/>
		<condition property="m_linux_x86_64_test" value="${success_msg}" else="${fail_msg}">
			<and>
				<length string="${m_linux_x86_64_output}" when="greater" length="0"/>
				<matches pattern="x${m_linux_x86_64_output}*" string="x${m_linux_x86_64}"/>
			</and>
		</condition>
		<condition property="m_linux_ppc64le_test" value="${success_msg}" else="${fail_msg}">
			<and>
				<length string="${m_linux_ppc64le_output}" when="greater" length="0"/>
				<matches pattern="x${m_linux_ppc64le_output}*" string="x${m_linux_ppc64le}"/>
			</and>
		</condition>
		<condition property="m_linux_aarch64_test" value="${success_msg}" else="${fail_msg}">
			<and>
				<length string="${m_linux_aarch64_output}" when="greater" length="0"/>
				<matches pattern="x${m_linux_aarch64_output}*" string="x${m_linux_aarch64}"/>
			</and>
		</condition>
		<condition property="m_mac_test" value="${success_msg}" else="${fail_msg}">
			<and>
				<length string="${m_mac_output}" when="greater" length="0"/>
				<matches pattern="x${m_mac_output}*" string="x${m_mac}"/>
			</and>
		</condition>
		<echo>-------------------------</echo>
		<echo>Status:</echo>
		<echo></echo>
		<echo>${m_linux_x86_64} - ${m_linux_x86_64_test}</echo>
		<echo>${m_linux_ppc64le} - ${m_linux_ppc64le_test}</echo>
		<echo>${m_linux_aarch64} - ${m_linux_aarch64_test}</echo>
		<echo>${m_mac} - ${m_mac_test}</echo>
		<echo>-------------------------</echo>
		<condition property="m_fail">
			<matches pattern="Fail" string="${m_linux_x86_64_test} ${m_linux_ppc64le_test} ${m_linux_aarch64_test} ${m_mac_test}"/>
		</condition>
		<fail if="m_fail" message="Failed"/>
	</target>

	<target name="check_source_sha1_file" unless="source_changed">
		<condition property="source_changed">
			<not>
				<available file="${tmp_sha1_file}" type="file"/>
			</not>
		</condition>
	</target>

	<target name="check_source_changed" depends="check_source_sha1_file" unless="source_changed">
		<loadproperties srcfile="${tmp_sha1_file}"/>

		<!-- Check for changes -->
		<exec dir="${repo.src}" executable="git" failonerror="true" outputproperty="diffs">
			<arg line="diff ${SHA1}"/>
		</exec>
		<condition property="source_changed">
			<or>
				<length string="${SHA1}" trim="true" when="equal" length="0"/>
				<length string="${diffs}" trim="true" when="greater" length="0"/>
			</or>
		</condition>
		<echo>Has source changes: ${source_changed}, compared against:</echo>
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="log -1 ${SHA1}"/>
		</exec>
	</target>

	<target name="check_preprocessing">
		<property name="projectDir" value="${repo.src}/bundles/org.eclipse.swt"/>
		<fileset id="badfilesid" dir="${projectDir}" includes="**/*.java" excludes="**/.build64/**/*.java">
			<or>
			    <contains text="int /*long*/" casesensitive="yes"/>
			    <contains text="float /*double*/" casesensitive="yes"/>
			    <contains text="int[] /*long[]*/" casesensitive="yes"/>
			    <contains text="float[] /*double[]*/" casesensitive="yes"/>
			</or>
		</fileset>
		<property name="badfiles" refid="badfilesid"/>
		<echo>${badfiles}</echo>
		<condition property="failbadfiles">
			<length string="${badfiles}" trim="true" when="greater" length="0"/>
		</condition>
		<fail if="failbadfiles" message="There are files with the wrong long /*int*/ preprocessing."/>
	</target>

	<target name="check_compilation" depends="check_source_changed" if="source_changed">
		<antcall target="check_compilation_all_platforms"/>
		<antcall target="update_sha1_file"/>
	</target>
	
	<target name="check_compilation_all_platforms">
		<mkdir dir="${tmphome}"/>
		<!-- <property name="tmpdir" value="${tmphome}/check.compile.${TAG}"/> -->
		<property name="buildDir" value="${tmpdir}/build"/>
		<property name="projectDir" value="${repo.src}/bundles/org.eclipse.swt"/>

		<!-- 64 bit -->
		<antcall target="build_classes">
			<param name="cp" value=".classpath_cocoa"/>
		</antcall>
		<antcall target="build_classes">
			<param name="cp" value=".classpath_gtk"/>
		</antcall>
		<antcall target="build_classes">
			<param name="cp" value=".classpath_win32"/>
		</antcall>
		
		<antcall target="check_preprocessing"/>
	</target>
	
	<target name="update_sha1_file">
		<!-- Update build.sha1 file -->
		<exec dir="${repo.src}" executable="git" failonerror="true" outputproperty="HEAD_TAG">
			<arg line="rev-list ${TAG} -1"/>
		</exec>
		<propertyfile file="${tmp_sha1_file}">
			<entry key="SHA1" value="${HEAD_TAG}"/>
		</propertyfile>

		<delete dir="${tmpdir}" quiet="true"/>
	</target>

	<target name="build_classes">
		<echo>Building ${cp}</echo>
		<delete file="${tmpdir}/copy.xml"/>
		<delete dir="${buildDir}"/>

		<xslt style="${projectDir}/tasks/classpath.xls" in="${projectDir}/${cp}" out="${tmpdir}/copy.xml">
			<param name="srcDir" expression="${projectDir}"/>
			<param name="outputDir" expression="${buildDir}"/>
		</xslt>
		<ant antfile="${tmpdir}/copy.xml" target="copy_files"/>

		<javac includeantruntime="false" srcdir="${buildDir}" encoding="utf8"></javac>
	</target>

	<!-- common build tasks -->
	<target name="new_release">
		<property name="natives_changed" value="true"/>
		<property name="increment_version_target" value="increment_release_version"/>
		<antcall target="new_build"/>
	</target>

	<target name="check_build_changed" depends="get_tag" unless="build_changed">
		<!-- Check for changes -->
		<exec dir="${repo.src}" executable="git" failonerror="false" outputproperty="src_diffs">
			<arg line="diff ${swt_tag}"/>
		</exec>
		<exec dir="${repo.bin}" executable="git" failonerror="false" outputproperty="bin_diffs">
			<arg line="diff ${swt_tag}"/>
		</exec>
		<condition property="build_changed">
			<or>
				<length string="${src_diffs}" trim="true" when="greater" length="0"/>
				<length string="${bin_diffs}" trim="true" when="greater" length="0"/>
			</or>
		</condition>
		<echo>Has build changes: ${build_changed} checked against ${swt_tag}</echo>
	</target>

	<target name="new_build" depends="check_build_changed, check_natives_changed" if="build_changed">
		<!-- Update the version files -->
		<property name="increment_version_target" value="increment_version"/>
		<antcall target="${increment_version_target}"/>

		<!-- Commit the files -->
		<antcall target="commit_sources"/>
	</target>

	<target name="commit_sources" depends="get_version" if="natives_changed">
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="add '${file_library}' '${file_version}' '${file_make_common}' "/>
		</exec>
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="status"/>
		</exec>
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="commit -m 'v${swt_version}'"/>
		</exec>
	</target>
	
	<target name="increment_version" depends="get_version" if="natives_changed">
		<antcall target="increment_version_impl"/>
	</target>

	<target name="increment_release_version" depends="get_new_release_version" if="natives_changed">
		<antcall target="increment_version_impl"/>
	</target>

	<target name="increment_version_impl">
		<echo>Incrementing version from ${swt_version} to ${new_version}...</echo>
		<replace file="${repo.src}/${file_library}" token="MAJOR_VERSION = ${maj_ver}" value="MAJOR_VERSION = ${new_maj_ver}"/>
		<replace file="${repo.src}/${file_library}" token="MINOR_VERSION = ${min_ver}" value="MINOR_VERSION = ${new_min_ver}"/>
		<replace file="${repo.src}/${file_library}" token="REVISION = ${rev}" value="REVISION = ${new_rev}"/>
		<replace file="${repo.src}/${file_version}" token="version ${maj_ver}.${min_ver}" value="version ${new_maj_ver}.${new_min_ver}"/>
		<replace file="${repo.src}/${file_make_common}" token="min_ver=${min_ver}" value="min_ver=${new_min_ver}"/>
		<replace file="${repo.src}/${file_make_common}" token="maj_ver=${maj_ver}" value="maj_ver=${new_maj_ver}"/>
		<replace file="${repo.src}/${file_make_common}" token="rev=${rev}" value="rev=${new_rev}"/>
		<replace file="${repo.src}/${file_make_common}" token="comma_ver=${comma_ver}" value="comma_ver=${new_comma_ver}"/>
	</target>

	<!-- Set the last swt_tag -->
	<target name="get_tag" unless="swt_tag">
		<exec dir="${repo.bin}" executable="git" failonerror="true" outputproperty="tags">
			<arg line="describe --abbrev=0 --tags --match v[0-9][0-9][0-9][0-9]*"/>
		</exec>
		<script language="javascript">
			<![CDATA[
				tags = project.getProperty("tags").split("\n");
				project.setProperty("swt_tag", tags[tags.length - 1]);
	   	 	]]>
		</script>
		<echo>Current tag=${swt_tag}.</echo>
	</target>

	<!-- Set swt_new_tag  -->
	<target name="get_new_tag" unless="swt_new_tag" depends="get_version">
		<exec dir="${repo.bin}" executable="git" failonerror="true" outputproperty="tags">
			<arg line="tag"/>
		</exec>
		<script language="javascript">
			<![CDATA[
				tags = project.getProperty("tags");
				swt_version = project.getProperty("swt_version");
				if (!tags.match(swt_version)) {
					project.setProperty("swt_new_tag", swt_version);
				} else {
					for (i=97; i<123; i++) {
						t = swt_version + String.fromCharCode(i);
						if (!tags.match(t)) {
							project.setProperty("swt_new_tag", t);
							break;
						}
					}
				}
	   	 	]]>
		</script>
		<fail message="Unable to determine new tag">
			<condition>
				<not>
					<isset property="swt_new_tag"/>
				</not>
			</condition>
		</fail>
		<echo>New tag=${swt_new_tag}.</echo>
	</target>

	<!-- Set swt_version, new_version, (and rev, min_ver, maj_ver, new_rev, new_min_ver, new_maj_ver) from the make_common.mak  -->
	<target name="get_version" unless="swt_version">
		<loadproperties srcFile="${repo.src}/${file_make_common}"/>
		<script language="javascript">
		<![CDATA[
			rev = project.getProperty("rev");
			min_ver = project.getProperty("min_ver");
			maj_ver = project.getProperty("maj_ver");
			new_rev = parseInt(rev) + 1;
			new_min_ver = min_ver;
			new_maj_ver = maj_ver;
			one = new_maj_ver;
			two = new_min_ver;
			three = new_rev;
			four = 0;
			project.setProperty("new_rev", new_rev);
			project.setProperty("new_min_ver", new_min_ver);
			project.setProperty("new_maj_ver", new_maj_ver);
			project.setProperty("new_comma_ver", one + "," + two + "," + three + "," + four);
   	 	]]>
		</script>
		<property name="swt_version" value="${maj_ver}${min_ver}r${rev}"/>
		<property name="new_version" value="${new_maj_ver}${new_min_ver}r${new_rev}"/>
		<echo>Version=${swt_version}; New=${new_version}; New comma_ver=${new_comma_ver}</echo>
	</target>

	<target name="get_new_release_version" unless="min_ver">
		<loadproperties srcFile="${repo.src}/${file_make_common}"/>
		<script language="javascript">
		<![CDATA[
			rev = project.getProperty("rev");
			min_ver = project.getProperty("min_ver");
			maj_ver = project.getProperty("maj_ver");
			new_rev = 1;
			new_min_ver = parseInt(min_ver) + 2;
			new_maj_ver = maj_ver;
			if (new_min_ver >= 1000) {
				new_min_ver = "000";
				new_maj_ver = parseInt(new_maj_ver) + 1;
			}
			one = new_maj_ver;
			two = new_min_ver;
			three = new_rev;
			four = 0;
			project.setProperty("new_rev", new_rev);
			project.setProperty("new_min_ver", new_min_ver);
			project.setProperty("new_maj_ver", new_maj_ver);
			project.setProperty("new_comma_ver", one + "," + two + "," + three + "," + four);
   	 	]]>
		</script>
		<property name="swt_version" value="${maj_ver}${min_ver}r${rev}"/>
		<property name="new_version" value="${new_maj_ver}${new_min_ver}r${new_rev}"/>
		<echo>Version=${swt_version}; New=${new_version}; New comma_ver=${new_comma_ver}</echo>
	</target>
	
	<target name="get_new_maintenance_release_version" unless="min_ver">
			<loadproperties srcFile="${repo.src}/${file_make_common}"/>
			<script language="javascript">
			<![CDATA[
				rev = project.getProperty("rev");
				min_ver = project.getProperty("min_ver");
				maj_ver = project.getProperty("maj_ver");
				new_rev = 1;
				new_min_ver = parseInt(min_ver) + 1;
				new_maj_ver = maj_ver;
				if (new_min_ver >= 1000) {
					new_min_ver = "000";
					new_maj_ver = parseInt(new_maj_ver) + 1;
				}
				one = new_maj_ver;
				two = new_min_ver;
				three = new_rev;
				four = 0;
				project.setProperty("new_rev", new_rev);
				project.setProperty("new_min_ver", new_min_ver);
				project.setProperty("new_maj_ver", new_maj_ver);
				project.setProperty("new_comma_ver", one + "," + two + "," + three + "," + four);
	   	 	]]>
			</script>
			<property name="swt_version" value="${maj_ver}${min_ver}r${rev}"/>
			<property name="new_version" value="${new_maj_ver}${new_min_ver}r${new_rev}"/>
			<echo>Version=${swt_version}; New=${new_version}; New comma_ver=${new_comma_ver}</echo>
		</target>

	<!-- Set natives_changed if there are changes in the C code -->
	<target name="check_natives_changed" unless="natives_changed" depends="get_tag">
		<exec dir="${repo.src}" executable="git" failonerror="true" outputproperty="diffs">
			<arg line="diff ${TAG} ${swt_tag}"/>
			<arg line="${src_win32}"/>
			<arg line="${src_gtk}"/>
			<arg line="${src_cocoa}"/>
		</exec>
		<condition property="natives_changed">
			<length string="${diffs}" trim="true" when="greater" length="0"/>
		</condition>
		<echo>Natives changed: ${natives_changed} since ${swt_tag}</echo>
	</target>

	<!-- depends on 'get_new_tag' to define swt_new_tag, swt_version, maj_ver and min_ver -->
	<target name="tag_projects" depends="get_new_tag">
		<!-- These two lines perform the same check. check_libraries is slower because it checks each fragment separetely  -->
		<!--antcall target="check_libraries"/-->
		<antcall target="check_fragment_libraries"/>

		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="tag v${swt_new_tag}"/>
		</exec>
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="tag v${swt_new_tag}"/>
		</exec>
	</target>

	<target name="check_sha1_file" unless="natives_changed">
		<condition property="natives_changed">
			<not>
				<available file="${sha1_file}" type="file"/>
			</not>
		</condition>
	</target>

	<target name="check_sha1_changed" depends="check_sha1_file" unless="natives_changed">
		<loadproperties srcfile="${sha1_file}"/>

		<!-- Check for changes -->
		<exec dir="${repo.src}" executable="git" failonerror="true" outputproperty="diffs">
			<arg line="diff ${SHA1} ${library_src}"/>
		</exec>
		<condition property="natives_changed">
			<or>
				<length string="${SHA1}" trim="true" when="equal" length="0"/>
				<length string="${diffs}" trim="true" when="greater" length="0"/>
			</or>
		</condition>
		<echo>Has native changes: ${natives_changed}, compared against:</echo>
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="log -1 ${SHA1}"/>
		</exec>
	</target>

	<target name="init_fragment">
		<condition property="m_fail">
			<not><and>
				<isset property="swt.ws"/>
				<isset property="swt.os"/>
			</and></not>
		</condition>
		<fail if="m_fail" message="Failed: ${swt.ws} and ${swt.os} not set"/>
		<condition property="fragment" value="org.eclipse.swt.${swt.ws}.${swt.os}.${swt.arch}" else="org.eclipse.swt.${swt.ws}.${swt.os}">
			<isset property="swt.arch"/>
		</condition>
		<property name="fragment_dir" value="${repo.bin}/bundles/${fragment}"/>
		<property name="sha1_file" value="${fragment_dir}/build.sha1"/>
		<script language="javascript">
			<![CDATA[
				project.setProperty("library_src", project.getProperty("src_" + project.getProperty("swt.ws")));
			]]>
		</script>
	</target>
	
	<target name="update_sha1_file_in_fragment">
		<!-- Update build.sha1 file -->
		<exec dir="${repo.src}" executable="git" failonerror="true" outputproperty="HEAD_TAG">
			<arg line="rev-list ${TAG} -1"/>
		</exec>
		<echo file="${fragment_dir}/build.sha1" append="false">SHA1=${HEAD_TAG}</echo>
	</target>

	<!-- Params: swt.ws, swt.os, swt.arch
	Note that the build.sha1 file is updated even if the libraries are not built to ensure there is a change
	in the GIT repo (see bug#407624).
	-->
	<target name="build_fragment" depends="init_fragment,check_sha1_changed">
		<!-- Build natives -->
		<antcall target="build_fragment_libraries"/>

		<!-- Update build.sha1 file -->
		<antcall target="update_sha1_file_in_fragment"/>
	</target>
	<target name="build_fragment_libraries" if="natives_changed">
		<antcall target="build_libraries"/>
	</target>

	<target name="commit_poms_and_binaries">
		<antcall target="commit_poms"/>
		<property name="commit_pom_changes" value="true"/>
		<antcall target="commit_binaries"/>
	</target>
	
	<target name="commit_poms">
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="add '${file_src_pom}'"/>
		</exec>
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="add '${file_bin_parent_pom}'"/>
		</exec>
	</target>
	
	<!-- Params: fragment, swt_version -->
	<target name="commit_binaries" depends="get_version">
		<!-- Get libraries to remove from repo -->
		<echo>swt_version is ${swt_version}</echo>
		<fileset id="removeid" dir="${repo.bin}">
			<filename regex="[0-9][0-9][0-9][0-9]r[0-9]"/>
			<filename regex="${swt_version}" negate="true"/>
			<exclude name="**/.git/**"/>
		</fileset>
		
		<echo>Files to remove is ${toString:removeid}</echo>

		<!-- Rename libraries that were not built -->
		<copy todir="${repo.bin}" overwrite="false">
			<fileset refid="removeid"/>
			<regexpmapper from="(.*)[0-9][0-9][0-9][0-9]r[0-9]+(.*)" to="\1${swt_version}\2"/>
		</copy>
		<property name="rfiles" refid="removeid"/>

		<!-- Get list of files to commit -->
		<fileset id="addid" dir="${repo.bin}">
			<include name="bundles/*/*${swt_version}*"/>
			<include name="bundles/*/webkitextensions${swt_version}/*${swt_version}*"/>
			<include name="bundles/*/build.sha1"/>
			<exclude name="**/.git/**"/>
			<exclude name="**/tmpdir/**"/>
		</fileset>
		<property name="afiles" refid="addid"/>
		
		<echo>Files to add is ${toString:addid}</echo>

		<script language="javascript">
		<![CDATA[
			rfiles = project.getProperty("rfiles");
			if (rfiles.length() > 0) {
				project.setProperty("removed_files", rfiles.replaceAll(";", " "));
			}
			project.setProperty("added_files", project.getProperty("afiles").replaceAll(";", " "));
   	 	]]>
		</script>

		<chmod perm="755">
			<fileset dir="${repo.bin}" includes="*${swt_version}*"/>
		</chmod>

		<echo>Removing files</echo>
		<antcall target="git_rm"/>
		
		<echo>Adding files</echo>
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="add ${added_files}"/>
		</exec>
		
		<exec dir="${repo.bin}" executable="git" failonerror="true" outputproperty="diffs">
			<arg line="diff HEAD"/>
		</exec>
		
		<condition property="commit_bin_changes">
			<length string="${diffs}" trim="true" when="greater" length="0"/>
		</condition>
		<antcall target="git_commit"/>
	</target>

	<target name="git_rm" if="removed_files">
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="rm ${removed_files}"/>
		</exec>
	</target>

	<target name="git_commit">
		<antcall target="git_commit_src"/>
		<antcall target="git_commit_bin"/>
	</target>
		
	<target name="git_commit_src" if="commit_pom_changes">
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="status"/>
		</exec>
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="commit -m 'v${swt_version}'"/>
		</exec>
	</target>
		
	<target name="git_commit_bin" if="commit_bin_changes">
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="status"/>
		</exec>
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="commit -m 'v${swt_version}'"/>
		</exec>
	</target>

	<target name="init_build" if="eclipse.running">
		<eclipse.refreshLocal resource="org.eclipse.swt" depth="infinite"/>
		<eclipse.incrementalBuild project="org.eclipse.swt" kind="incr"/>
	</target>

	<target name="refresh_fragment" if="eclipse.running">
		<echo>refreshing ${fragment}</echo>
		<eclipse.refreshLocal resource="${fragment}" depth="infinite"/>
	</target>

	<target name="copy.library.src">
		<script language="javascript">
			<![CDATA[
				var File = java.io.File;
				var StreamTokenizer = java.io.StreamTokenizer;
				var StringReader = java.io.StringReader;
				task = project.createTask("copy");
				projectDir = project.getProperty("project_dir");
				task.setTodir(new File(project.getProperty("build_dir")));
				tk = new StreamTokenizer(new StringReader(project.getProperty("library_src")));
				while ((token = tk.nextToken()) != StreamTokenizer.TT_EOF) {
					fileset = project.createDataType("fileset");
					fileset.setDir(new File(projectDir + "/" + tk.sval + "/"));
					task.addFileset(fileset);
				}
				task.execute();
			]]>
		</script>
	</target>

	<!-- Params: swt.ws, swt.os, swt.arch -->
	<target name="build_libraries" depends="init_fragment,init_keyfile,get_version">
		<property name="swt.arch" value=""/>
		<property name="clean" value="clean"/>
		<property name="targets" value="install"/>
		<property name="project_dir" value="${basedir}/${repo.src}"/>
		<property name="output_dir" value="${basedir}/${fragment_dir}"/>
		<property name="build_dir" value="${basedir}/${fragment_dir}/tmpdir"/>
		<delete dir="${build_dir}" quiet="true"/>
		<antcall target="copy.library.src"/>
		<condition property="build_task" value="build_local_win">
			<and>
				<not>
					<isset property="machine"/>
				</not>
				<or>
					<equals arg1="${swt.ws}" arg2="win32"/>
				</or>
			</and>
		</condition>
		<condition property="build_task" value="build_remote" else="build_local">
			<isset property="machine"/>
		</condition>
		<condition property="port" value="22">
			<not>
				<isset property="port"/>
			</not>
		</condition>
		<antcall target="init_build"/>
		<antcall target="${build_task}">
			<param name="build_targets" value="${targets}"/>
			<param name="build_machine" value="${machine}"/>
			<param name="port" value="${port}"/>
			<param name="keyfile" value="${keyfile}"/>
		</antcall>
		<delete dir="${build_dir}" quiet="true"/>
		<antcall target="refresh_fragment"/>
	</target>

	<target name="build_remote" depends="init_keyfile">
		<property name="libs" value="*"/>
		<property name="exports" value=""/>

		<condition property="remotebuilddir" value="c:/build" else="~/build/">
			<equals arg1="${swt.os}" arg2="win32"/>
		</condition>
		<condition property="exit_cmd" value="exit;" else="">
			<equals arg1="${swt.os}" arg2="win32"/>
		</condition>
		<condition property="build_cmd" value="unix2dos *; if cmd /c build.bat ${build_targets};" else="if sh build.sh ${build_targets};">
			<equals arg1="${swt.os}" arg2="win32"/>
		</condition>

		<property name="remotetmpdir" value="${remotebuilddir}/${fragment}.${TAG}"/>
		<property name="lib_output" value="${remotetmpdir}/libs"/>
		<property name="zip_file" value="${fragment}.${TAG}.zip"/>
		<zip destfile="${build_dir}/${zip_file}" basedir="${build_dir}" excludes="${zip_file}"/>
		<scp file="${build_dir}/${zip_file}"
			todir="swtbuild@${build_machine}:${remotebuilddir}"
			port="${port}"
			keyfile="${keyfile}"
			trust="true"/>
		<sshexec host="${build_machine}"
			username="swtbuild"
			port="${port}"
			keyfile="${keyfile}"
			trust="true"
	 		command="rm -rf ${remotetmpdir}; mkdir ${remotetmpdir}; mkdir ${lib_output}; cd ${remotetmpdir}; unzip -aa ${remotebuilddir}/${zip_file}; ${exports} export MODEL=${swt.arch}; export OUTPUT_DIR=${lib_output}; ${build_cmd} then ${exit_cmd} cd; else ${exit_cmd} cd; rm -rf ${remotetmpdir}; rm ${remotebuilddir}/${zip_file}; exit 1; fi"/>
		<scp file="swtbuild@${build_machine}:${lib_output}/${libs}"
			todir="${output_dir}"
			port="${port}"
			keyfile="${keyfile}"
			trust="true"/>
		<scp file="swtbuild@${build_machine}:${lib_output}/webkitextensions${swt_version}/*"
			todir="${output_dir}/webkitextensions${swt_version}/"
			port="${port}"
			keyfile="${keyfile}"
			trust="true"
			failonerror="false"/>
		<sshexec host="${build_machine}"
			username="swtbuild"
			port="${port}"
			keyfile="${keyfile}"
			trust="true"
	 		command="rm -rf ${remotetmpdir}; rm ${remotebuilddir}/${zip_file}"/>
	</target>

	<target name="build_local">
		<property name="gtk_version" value="3.0" />
		<exec executable="mkdir">
			<arg value="-p"/>
			<arg value="${output_dir}/webkitextensions${swt_version}/"/>
		</exec>
		<exec dir="${build_dir}" executable="sh" failonerror="true">
			<arg line="build.sh"/>
			<env key="GTK_VERSION" value="${gtk_version}"/>
			<env key="MODEL" value="${swt.arch}"/>
			<env key="OUTPUT_DIR" value="${output_dir}"/>
			<arg line="${targets}"/>
			<arg line="${clean}"/>
		</exec>
	</target>

	<target name="build_local_win">
		<pathconvert property="win_output_dir">
			<path location="${output_dir}"></path>
		</pathconvert>
		<exec dir="${build_dir}" executable="${build_dir}/build.bat" failonerror="true">
			<env key="OUTPUT_DIR" value="${win_output_dir}"/>
			<arg line="${targets}"/>
			<arg line="${clean}"/>
		</exec>
	</target>

	<target name="check_repo">
		<echo>Check ${repo}</echo>
		 <condition property="${repo.exists}">
		 	<available file="../../../../${TAG}/${repo}" type="dir"/>
		 </condition>
	</target>

	<target name="init_repo" depends="check_repo" unless="${repo.exists}" >
		<delete dir="../../../../${TAG}/${repo}" quiet="true"/>
		<mkdir dir="../../../../${TAG}"/>
		<exec dir="../../../../${TAG}" executable="git" failonerror="true">
			<arg line="clone ${gitroot}/${repo}"/>
		</exec>
		<condition property="perform.checkout">
			<not>
				<equals arg1="${checkout_tag}" arg2="master"/>
			</not>
		</condition>
		<antcall target="checkout_repo"/>
	</target>

	<target name="checkout_repo" if="perform.checkout">
		<echo>Checking out ${repo}=${checkout_tag}</echo>
		<exec dir="../../../../${TAG}/${repo}" executable="git" failonerror="true">
			<arg line="checkout -b ${checkout_tag} origin/${checkout_tag}"/>
		</exec>
	</target>

	<target name="pull_remote">
		<antcall target="init_repo">
			<param name="repo" value="eclipse.platform.swt"/>
			<param name="repo.exists" value="repo.src.exists"/>
			<param name="checkout_tag" value="${TAG}"/>
		</antcall>
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git"  failonerror="true" timeout="900000">
			<arg line="fetch"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git"  failonerror="true" timeout="900000">
			<arg line="reset --hard origin/${TAG}"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git"  failonerror="true" timeout="900000">
			<arg line="clean -fd"/>
		</exec>
		<antcall target="init_repo">
			<param name="repo" value="eclipse.platform.swt.binaries"/>
			<param name="repo.exists" value="repo.bin.exists"/>
			<param name="checkout_tag" value="${TAG}"/>
		</antcall>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true" timeout="900000">
			<arg line="fetch"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true" timeout="900000">
			<arg line="reset --hard origin/${TAG}"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true" timeout="900000">
			<arg line="clean -fd"/>
		</exec>
	</target>

	<target name="push_remote" depends="get_tag">
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git" failonerror="true">
			<arg line="fetch"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git" failonerror="true">
			<arg line="rebase origin/${TAG}"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git" failonerror="true">
			<arg line="push origin ${TAG}"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true">
			<arg line="fetch"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true">
			<arg line="rebase origin/${TAG}"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true">
			<arg line="push origin ${TAG}"/>
		</exec>
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="push origin refs/tags/${swt_tag}"/>
		</exec>
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="push origin refs/tags/${swt_tag}"/>
		</exec>
	</target>

	<target name="push_integration">
		<property name="TAG" value="master"/>
		<!-- src -->
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git" failonerror="true">
			<arg line="checkout master"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git" failonerror="true">
			<arg line="reset --hard origin/${TAG}"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git" failonerror="true">
			<arg line="checkout integration"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git" failonerror="true">
			<arg line="merge master"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git" failonerror="true">
			<arg line="push origin integration"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt" executable="git" failonerror="true">
			<arg line="checkout master"/>
		</exec>
		<!-- bin -->
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true">
			<arg line="checkout master"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true">
			<arg line="reset --hard origin/${TAG}"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true">
			<arg line="checkout integration"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true">
			<arg line="merge master"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true">
			<arg line="push origin integration"/>
		</exec>
		<exec dir="../../../../${TAG}/eclipse.platform.swt.binaries" executable="git" failonerror="true">
			<arg line="checkout master"/>
		</exec>
	</target>
	
	<!-- ******************************************************************************** -->
	<!-- targets to run the builds on the Eclipse Foundation Hudson in master-slave setup -->
	<!-- ******************************************************************************** -->
	
	<target name="push_remote_from_workspace" depends="get_tag">
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="fetch"/>
		</exec>
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="status"/>
		</exec>
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="rebase origin/${TAG}"/>
		</exec>
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="push origin ${TAG}"/>
		</exec>
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="fetch"/>
		</exec>
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="status"/>
		</exec>
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="rebase origin/${TAG}"/>
		</exec>
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="push origin ${TAG}"/>
		</exec>
		<exec dir="${repo.src}" executable="git" failonerror="true">
			<arg line="push origin refs/tags/${swt_tag}"/>
		</exec>
		<exec dir="${repo.bin}" executable="git" failonerror="true">
			<arg line="push origin refs/tags/${swt_tag}"/>
		</exec>
	</target>
	
	<target name="new_build_with_create_file" depends="check_build_changed, check_natives_changed" if="build_changed">
		<!-- Update the version files -->
		<property name="increment_version_target" value="increment_version"/>
		<antcall target="${increment_version_target}"/>

		<!-- Commit the files -->
		<antcall target="commit_sources"/>
		
		<!-- Create tmp files if the properties are set -->
		<antcall target="create_file_if_property_exists">
			<param name="property" value="${build_changed}"/>
			<param name="fileName" value="${tmphome}/build_changed.txt"/>
		</antcall>
		<antcall target="create_file_if_property_exists">
			<param name="property" value="${natives_changed}"/>
			<param name="fileName" value="${tmphome}/natives_changed.txt"/>
		</antcall>
	</target>
	
	<target name="create_file_if_property_exists" if="${property}">
		<echo>"Creating file ${fileName}"</echo>
		<echo file="${fileName}" append="false">true</echo>
	</target>
	
	<target name="copy_library_src_and_create_zip" depends="init_fragment,check_sha1_changed" if="natives_changed">
		<property name="swt.arch" value=""/>
		<property name="project_dir" value="${basedir}/${repo.src}"/>
		<property name="output_dir" value="${basedir}/${fragment_dir}"/>
		<property name="build_dir" value="${basedir}/${fragment_dir}/tmpdir"/>
		<property name="zip_file" value="${fragment}.${TAG}.zip"/>
		<delete dir="${build_dir}" quiet="true"/>
		
		<!-- copy the library source files -->
		<antcall target="copy.library.src"/>
		
		<!-- create a zip of the native source files to be sent to the build machine -->
		<zip destfile="${build_dir}/${zip_file}" basedir="${build_dir}" excludes="${zip_file}"/>
	</target>
	
	<target name="build_libraries_slave" depends="init_fragment">
		<property name="swt.arch" value=""/>
		<property name="clean" value="clean"/>
		<property name="targets" value="install"/>
		<property name="libs" value="*"/>
		<property name="src_zip_file" value="${fragment}.${TAG}.zip"/>
		<property name="lib_zip_file" value="${fragment}.${TAG}.zip"/>
		
		<condition property="remotebuilddir" value="c:/build" else="build/">
			<equals arg1="${swt.os}" arg2="win32"/>
		</condition>	
		<property name="remotetmpdir" value="${remotebuilddir}/${fragment}.${TAG}"/>
		<property name="lib_output" value="${remotetmpdir}/libs"/>
		<condition property="build_task" value="build_win_slave" else="build_remote_slave">
			<equals arg1="${swt.ws}" arg2="win32"/>
		</condition>
			
		<!-- This target doesn't copy the src zip, it expects that the zip file is already be copied to remotebuilddir -->
		
		<echo>${remotebuilddir}</echo>
		<delete dir="${remotetmpdir}" quiet="false"/>
		<mkdir dir="${remotetmpdir}"/>
		<mkdir dir="${lib_output}"/>
		<unzip src="${remotebuilddir}/${src_zip_file}" dest="${remotetmpdir}"/>
		<delete file="${remotebuilddir}/${zip_file}"/>
			
		<antcall target="${build_task}">
			<param name="build_targets" value="${targets}"/>
		</antcall>
		
		<antcall target="build_gtk3"/>
		
		<zip destfile="${remotetmpdir}/${lib_zip_file}" basedir="${lib_output}" excludes="${zip_file}" compress="false"/>
	</target>
		
	<target name="build_win_slave">
		<echo>${remotetmpdir}</echo>
		<pathconvert property="win_output_dir">
			<path location="${lib_output}"></path>
		</pathconvert>
		<exec dir="${remotetmpdir}" executable="${remotetempdir}/build.bat" failonerror="true">
			<env key="OUTPUT_DIR" value="${win_output_dir}"/>
			<arg line="${build_targets}"/>
			<arg line="${clean}"/>
		</exec>
	</target>
		
	<target name="build_remote_slave">
		<echo>${remotetmpdir}</echo>
		<exec dir="${remotetmpdir}" executable="sh" failonerror="true">
			<arg line="build.sh"/>
			<env key="GTK_VERSION" value="${gtk_version}"/>
			<env key="MODEL" value="${swt.arch}"/>
			<env key="OUTPUT_DIR" value="${lib_output}"/>
			<arg line="${build_targets}"/>
			<arg line="${clean}"/>
		</exec>
	</target>
</project>
