From 55a837daad1479e36fe9cff9f7c7ed7fb3e5780b Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Wed, 16 Jul 2003 19:41:52 +0000 Subject: [PATCH] - Initial contribution of the nightly build framework. --- releng/org.eclipse.cdt.releng/.classpath | 15 + releng/org.eclipse.cdt.releng/.cvsignore | 1 + releng/org.eclipse.cdt.releng/.project | 36 ++ releng/org.eclipse.cdt.releng/JUNIT.XSL | 455 ++++++++++++++++++ .../org.eclipse.cdt.releng/build.properties | 4 + releng/org.eclipse.cdt.releng/doall | 16 + releng/org.eclipse.cdt.releng/dobuild | 19 + releng/org.eclipse.cdt.releng/doinstall | 32 ++ releng/org.eclipse.cdt.releng/dotests | 28 ++ releng/org.eclipse.cdt.releng/ftp.jar | Bin 0 -> 36057 bytes releng/org.eclipse.cdt.releng/index.html | 7 + releng/org.eclipse.cdt.releng/plugin.xml | 35 ++ .../src/org/eclipse/cdt/releng/DoBuild.java | 427 ++++++++++++++++ .../org/eclipse/cdt/releng/RelengPlugin.java | 63 +++ 14 files changed, 1138 insertions(+) create mode 100644 releng/org.eclipse.cdt.releng/.classpath create mode 100644 releng/org.eclipse.cdt.releng/.cvsignore create mode 100644 releng/org.eclipse.cdt.releng/.project create mode 100644 releng/org.eclipse.cdt.releng/JUNIT.XSL create mode 100644 releng/org.eclipse.cdt.releng/build.properties create mode 100644 releng/org.eclipse.cdt.releng/doall create mode 100644 releng/org.eclipse.cdt.releng/dobuild create mode 100644 releng/org.eclipse.cdt.releng/doinstall create mode 100644 releng/org.eclipse.cdt.releng/dotests create mode 100644 releng/org.eclipse.cdt.releng/ftp.jar create mode 100644 releng/org.eclipse.cdt.releng/index.html create mode 100644 releng/org.eclipse.cdt.releng/plugin.xml create mode 100644 releng/org.eclipse.cdt.releng/src/org/eclipse/cdt/releng/DoBuild.java create mode 100644 releng/org.eclipse.cdt.releng/src/org/eclipse/cdt/releng/RelengPlugin.java diff --git a/releng/org.eclipse.cdt.releng/.classpath b/releng/org.eclipse.cdt.releng/.classpath new file mode 100644 index 00000000000..14133132696 --- /dev/null +++ b/releng/org.eclipse.cdt.releng/.classpath @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/releng/org.eclipse.cdt.releng/.cvsignore b/releng/org.eclipse.cdt.releng/.cvsignore new file mode 100644 index 00000000000..ba077a4031a --- /dev/null +++ b/releng/org.eclipse.cdt.releng/.cvsignore @@ -0,0 +1 @@ +bin diff --git a/releng/org.eclipse.cdt.releng/.project b/releng/org.eclipse.cdt.releng/.project new file mode 100644 index 00000000000..d8f81b89189 --- /dev/null +++ b/releng/org.eclipse.cdt.releng/.project @@ -0,0 +1,36 @@ + + + org.eclipse.cdt.releng + + + org.eclipse.core.boot + org.eclipse.core.resources + org.eclipse.core.runtime + org.eclipse.pde.core + org.eclipse.pde.ui + org.eclipse.team.core + org.eclipse.team.cvs.core + org.eclipse.ui + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/releng/org.eclipse.cdt.releng/JUNIT.XSL b/releng/org.eclipse.cdt.releng/JUNIT.XSL new file mode 100644 index 00000000000..a7dd9abed93 --- /dev/null +++ b/releng/org.eclipse.cdt.releng/JUNIT.XSL @@ -0,0 +1,455 @@ + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + + + + +
+ + + + + + + + +

Packages

+ Note: package statistics are not computed recursively, they only sum up all of its testsuites numbers. + + + + + + + + + + + + + + + + + Failure + Error + + + + + + + + + +
+ + + +
+
+ + + + + + + + + + + + +

Package

+ + + + + + +
+ Back to top +

+

+ + + + + + + + +

TestCase

+ + + + + + + + + + +
+ +

+ + Back to top + + + + +

Summary

+ + + + + + + + + + + + + + + + + Failure + Error + + + + + + + + + +
TestsFailuresErrorsSuccess rateTime
+ + + + + + + +
+ + + + +
+ Note: failures are anticipated and checked for with assertions while errors are unanticipated. +
+
+ + + + cur = TestCases['.'] = new Array(); + + + cur[''] = ''; + + + + + +

Unit Test Results

+ + + + + +
Designed for use with JUnit and Ant.
+
+
+ + + + Name + Tests + Errors + Failures + Time(s) + + + + + + + Name + Tests + Errors + Failures + Time(s) + + + + + + + Name + Status + Type + Time(s) + + + + + + + + + + + Failure + Error + + + + + + + + + + + + + + + + + + + + + Error + + + + + + Failure + + + + Error + + + + Success + + + + + + + + + + + + + + + + + + + + + + + + N/A + + + + + + +

+ + + + + + + + + + + + + \\ + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+
+ + + + + + + + + + + + + diff --git a/releng/org.eclipse.cdt.releng/build.properties b/releng/org.eclipse.cdt.releng/build.properties new file mode 100644 index 00000000000..08e19c0dc85 --- /dev/null +++ b/releng/org.eclipse.cdt.releng/build.properties @@ -0,0 +1,4 @@ +source.releng.jar = src/ +bin.includes = plugin.xml,\ + *.jar,\ + releng.jar diff --git a/releng/org.eclipse.cdt.releng/doall b/releng/org.eclipse.cdt.releng/doall new file mode 100644 index 00000000000..5e8fc349ef1 --- /dev/null +++ b/releng/org.eclipse.cdt.releng/doall @@ -0,0 +1,16 @@ +# +# The main build script +# - The assumption is that the scripts start off in the root directory +# of the eclipse install doing the build +# + +if [ -n "$CDT_ROOT" ]; then cd $CDT_ROOT; fi + +for i in dobuild doinstall dotest +do + if ! $i + then + echo $i failed + exit 1 + fi +done diff --git a/releng/org.eclipse.cdt.releng/dobuild b/releng/org.eclipse.cdt.releng/dobuild new file mode 100644 index 00000000000..e30ec4a7fdf --- /dev/null +++ b/releng/org.eclipse.cdt.releng/dobuild @@ -0,0 +1,19 @@ +# +# Main build script +# - the following environment variables need to be set +# - $CDT_USER - the username to use on the eclipse download machine +# - $CDT_PASSWD - the password for that account +# + +# +# Run Build +# + +if [ -z "$CDT_USER" ] +then + echo CDT_USER environment variable not set + exit 1 +fi + +./eclipse -nosplash -application org.eclipse.cdt.releng.build \ + -vmargs -Dcdt.build.user=$CDT_USER -Dcdt.build.passwd=$CDT_PASSWD diff --git a/releng/org.eclipse.cdt.releng/doinstall b/releng/org.eclipse.cdt.releng/doinstall new file mode 100644 index 00000000000..461bcf590dd --- /dev/null +++ b/releng/org.eclipse.cdt.releng/doinstall @@ -0,0 +1,32 @@ +# +# Set up test environment +# - the assumption is that the necessary zip files are in a zip file +# in the eclipse install +# + +rm -fr testspace +mkdir testspace +cd testspace +unzip -qq ../zip/eclipse-SDK-2.1.1-linux-gtk.zip + +cd eclipse/plugins +unzip -qq ../../../zip/org.eclipse.test_2.1.0.zip +unzip -qq ../../../zip/org.eclipse.ant.optional.junit_2.1.0.zip +cd .. + +export BUILD_SITE=../../workspace/build.site + +for d in plugins features +do + for i in $BUILD_SITE/$d/* + do + export DEST=$d/`echo $i | sed -e s:$BUILD_SITE/$d/:: -e s/.jar//` + mkdir $DEST + cd $DEST + jar xf $i + cd ../.. + done +done + +# Back up to the top dir +cd ../.. diff --git a/releng/org.eclipse.cdt.releng/dotests b/releng/org.eclipse.cdt.releng/dotests new file mode 100644 index 00000000000..d854272f2e3 --- /dev/null +++ b/releng/org.eclipse.cdt.releng/dotests @@ -0,0 +1,28 @@ +# +# Run Tests +# + +export RESULTS=`pwd`/results +rm -fr $RESULTS +mkdir $RESULTS + +cd testspace/eclipse + +# TODO - add in the rest of the test plugins +export PLUGINS='org.eclipse.cdt.core.tests' +for i in $PLUGINS +do + ./eclipse -nosplash -application org.eclipse.ant.core.antRunner \ + -f plugins/$i*/test.xml -Declipse-home=`pwd` \ + -Dorg.eclipse.test=org.eclipse.test_2.1.0\ + -Dos=linux -Dws=gtk -Darch=x86 + mv $i*.xml $RESULTS +done + +cd $RESULTS +for i in $PLUGINS +do + xsltproc ../workspace/org.eclipse.cdt.releng/JUNIT.XSL $i.xml > $i.html +done + +cd .. diff --git a/releng/org.eclipse.cdt.releng/ftp.jar b/releng/org.eclipse.cdt.releng/ftp.jar new file mode 100644 index 0000000000000000000000000000000000000000..4c19ff79f83358edc27c06893924ecf132810e2d GIT binary patch literal 36057 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 jPM^O9{^w})ZbU9@nx5 literal 0 HcmV?d00001 diff --git a/releng/org.eclipse.cdt.releng/index.html b/releng/org.eclipse.cdt.releng/index.html new file mode 100644 index 00000000000..e8e0ea1a479 --- /dev/null +++ b/releng/org.eclipse.cdt.releng/index.html @@ -0,0 +1,7 @@ + + + +Hi there. + + + diff --git a/releng/org.eclipse.cdt.releng/plugin.xml b/releng/org.eclipse.cdt.releng/plugin.xml new file mode 100644 index 00000000000..c7be26fca19 --- /dev/null +++ b/releng/org.eclipse.cdt.releng/plugin.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/releng/org.eclipse.cdt.releng/src/org/eclipse/cdt/releng/DoBuild.java b/releng/org.eclipse.cdt.releng/src/org/eclipse/cdt/releng/DoBuild.java new file mode 100644 index 00000000000..f7d4b3500cc --- /dev/null +++ b/releng/org.eclipse.cdt.releng/src/org/eclipse/cdt/releng/DoBuild.java @@ -0,0 +1,427 @@ +package org.eclipse.cdt.releng; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.ArrayList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.eclipse.core.boot.IPlatformRunnable; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.pde.core.plugin.IFragment; +import org.eclipse.pde.core.plugin.IPlugin; +import org.eclipse.pde.internal.core.feature.WorkspaceFeatureModel; +import org.eclipse.pde.internal.core.ifeature.IFeature; +import org.eclipse.pde.internal.core.ifeature.IFeatureChild; +import org.eclipse.pde.internal.core.ifeature.IFeatureImport; +import org.eclipse.pde.internal.core.ifeature.IFeaturePlugin; +import org.eclipse.pde.internal.core.isite.ISite; +import org.eclipse.pde.internal.core.isite.ISiteBuild; +import org.eclipse.pde.internal.core.isite.ISiteBuildFeature; +import org.eclipse.pde.internal.core.isite.ISiteCategory; +import org.eclipse.pde.internal.core.isite.ISiteCategoryDefinition; +import org.eclipse.pde.internal.core.isite.ISiteFeature; +import org.eclipse.pde.internal.core.isite.ISiteModelFactory; +import org.eclipse.pde.internal.core.plugin.WorkspaceFragmentModel; +import org.eclipse.pde.internal.core.plugin.WorkspacePluginModel; +import org.eclipse.pde.internal.core.site.WorkspaceSiteBuildModel; +import org.eclipse.pde.internal.core.site.WorkspaceSiteModel; +import org.eclipse.pde.internal.ui.editor.site.FeatureBuildOperation; +import org.eclipse.team.core.TeamException; +import org.eclipse.team.internal.ccvs.core.CVSException; +import org.eclipse.team.internal.ccvs.core.CVSTag; +import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; +import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation; +import org.eclipse.team.internal.ccvs.core.resources.CVSWorkspaceRoot; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import com.enterprisedt.net.ftp.FTPClient; +import com.enterprisedt.net.ftp.FTPConnectMode; +import com.enterprisedt.net.ftp.FTPException; +import com.enterprisedt.net.ftp.FTPTransferType; + +/** + * @see IPlatformRunnable + */ +public class DoBuild implements IPlatformRunnable { + + private IWorkspace workspace; + private String version; + private IProgressMonitor monitor; + + private static String locstr = ":pserver:anonymous@dev.eclipse.org:/home/tools"; + + private static final String ftpHost = "download.eclipse.org"; + private static final String ftpPath = "cdt/updates/builds/1.2"; + private static final String ftpUser = System.getProperty("cdt.build.user"); + private static final String ftpPassword = System.getProperty("cdt.build.passwd"); + + private static final String[] plugins = { + // Code + "org.eclipse.cdt.core", + "org.eclipse.cdt.core.tests", + "org.eclipse.cdt.ui", + "org.eclipse.cdt.ui.tests", + "org.eclipse.cdt.debug.core", + "org.eclipse.cdt.debug.ui", + "org.eclipse.cdt.debug.ui.tests", + "org.eclipse.cdt.debug.mi.core", + "org.eclipse.cdt.debug.mi.ui", + "org.eclipse.cdt.launch", + // Docs + "org.eclipse.cdt.doc.user", + // Features + "org.eclipse.cdt", + "org.eclipse.cdt.linux.gtk", + "org.eclipse.cdt.linux.motif", + "org.eclipse.cdt.qnx.photon", + "org.eclipse.cdt.solaris.motif", + "org.eclipse.cdt.win32", + "org.eclipse.cdt.source", + "org.eclipse.cdt.testing" + }; + + private static final String[] fragments = { + "org.eclipse.cdt.core.linux", + "org.eclipse.cdt.core.qnx", + "org.eclipse.cdt.core.solaris", + "org.eclipse.cdt.core.win32", + }; + + private static final String[] featureProjects = { + "org.eclipse.cdt-feature", + "org.eclipse.cdt.linux.gtk-feature", + "org.eclipse.cdt.linux.motif-feature", + "org.eclipse.cdt.qnx.photon-feature", + "org.eclipse.cdt.solaris.motif-feature", + "org.eclipse.cdt.win32-feature", + "org.eclipse.cdt.source-feature", + "org.eclipse.cdt.testing-feature" + }; + + private static final String[] buildFeatures = { + "org.eclipse.cdt", + "org.eclipse.cdt.linux.gtk", + "org.eclipse.cdt.linux.motif", + "org.eclipse.cdt.qnx.photon", + "org.eclipse.cdt.solaris.motif", + "org.eclipse.cdt.win32", + "org.eclipse.cdt.source", + "org.eclipse.cdt.testing" + }; + + private static final boolean[] externalFeatures = { + false, //"org.eclipse.cdt" + true, //"org.eclipse.cdt.linux.gtk" + true, //"org.eclipse.cdt.linux.motif" + true, //"org.eclipse.cdt.qnx.photon" + true, //"org.eclipse.cdt.solaris.motif" + true, //"org.eclipse.cdt.win32" + true, //"org.eclipse.cdt.source" + true, //"org.eclipse.cdt.testing" + + }; + + private static String[] projects; + + static { + // Create the projects array + projects = new String[plugins.length + fragments.length + featureProjects.length]; + System.arraycopy(plugins, 0, projects, 0, plugins.length); + int i = plugins.length; + System.arraycopy(fragments, 0, projects, i, fragments.length); + i += fragments.length; + System.arraycopy(featureProjects, 0, projects, i, featureProjects.length); + } + + /** + * @see IPlatformRunnable#run + */ + public Object run(Object args) throws Exception { + long start = System.currentTimeMillis(); + workspace = ResourcesPlugin.getWorkspace(); + monitor = new NullProgressMonitor(); + + deleteOldProjects(); + downloadNewProjects(); + downloadUpdateSite(); + updateVersions(); + buildUpdateSite(); + uploadUpdateSite(); + + long time = System.currentTimeMillis() - start; + long minutes = time / 60000; + time -= minutes * 60000; + long seconds = time / 1000; + time -= seconds * 1000; + + System.out.println("Done: " + + minutes + ":" + (seconds < 10 ? "0" : "") + seconds + + "." + time); + return null; + } + + private void deleteOldProjects() throws CoreException { + System.out.println("Deleting old projects"); + for (int i = 0; i < projects.length; ++i) { + IProject project = workspace.getRoot().getProject(projects[i]); + if (project.exists()) { + project.delete(false, monitor); + } + } + } + + private void downloadNewProjects() throws CVSException, TeamException { + // Download the new projects + ICVSRepositoryLocation location = CVSRepositoryLocation.fromString(locstr); + for (int i = 0; i < projects.length; ++i) { + System.out.println("Downloading " + projects[i]); + CVSWorkspaceRoot.checkout( + location, + null, + projects[i], + CVSTag.DEFAULT, + monitor); + } + } + + private void downloadUpdateSite() throws IOException, CoreException, FTPException { + System.out.println("Downloading update site"); + + // Find and create the local location to download to + IProject buildSite = workspace.getRoot().getProject("build.site"); + + // Download from the FTP site + FTPClient ftp = new FTPClient(ftpHost); + ftp.setConnectMode(FTPConnectMode.ACTIVE); + ftp.login(ftpUser, ftpPassword); + ftp.chdir(ftpPath); + + IFile file = buildSite.getFile("version.xml"); + OutputStream stream = new FileOutputStream(file.getRawLocation().toOSString()); + ftp.get(stream, "version.xml"); + stream.close(); + + file = buildSite.getFile("site.xml"); + stream = new FileOutputStream(file.getRawLocation().toOSString()); + ftp.get(stream, "site.xml"); + stream.close(); + + IFolder folder = buildSite.getFolder(".sitebuild"); + file = folder.getFile("sitebuild.xml"); + stream = new FileOutputStream(file.getRawLocation().toOSString()); + ftp.chdir(".sitebuild"); + ftp.get(stream, "sitebuild.xml"); + stream.close(); + + ftp.quit(); + buildSite.refreshLocal(IResource.DEPTH_INFINITE, monitor); + } + + private void updateVersions() throws Exception { + System.out.println("Setting versions"); + + // Get and increment the version + IProject siteProject = workspace.getRoot().getProject("build.site"); + IFile versionFile = siteProject.getFile("version.xml"); + versionFile.refreshLocal(IResource.DEPTH_ONE, monitor); + DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = builderFactory.newDocumentBuilder(); + Document versionDoc = builder.parse(versionFile.getContents()); + Element versionElem = versionDoc.getDocumentElement(); + String versionId = versionElem.getAttribute("id"); + String buildNum = versionElem.getAttribute("build"); + buildNum = String.valueOf(Integer.decode(buildNum).intValue() + 1); + versionElem.setAttribute("build", buildNum); + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + File versionResult = new File(versionFile.getRawLocation().toOSString()); + transformer.transform(new DOMSource(versionDoc), new StreamResult(versionResult)); + versionFile.refreshLocal(IResource.DEPTH_ONE, monitor); + version = versionId + "." + buildNum; + System.out.println("Version: " + version); + + // Go through the projects and update the version info + for (int i = 0; i < plugins.length; ++i) { + IProject project = workspace.getRoot().getProject(plugins[i]); + IFile pluginxml = project.getFile("plugin.xml"); + pluginxml.refreshLocal(IResource.DEPTH_ONE, monitor); + WorkspacePluginModel pluginModel = new WorkspacePluginModel(pluginxml); + pluginModel.load(); + IPlugin plugin = pluginModel.getPlugin(); + plugin.setVersion(version); + pluginModel.save(); + pluginxml.refreshLocal(IResource.DEPTH_ONE, monitor); + } + + for (int i = 0; i < fragments.length; ++i) { + IProject project = workspace.getRoot().getProject(fragments[i]); + IFile fragmentxml = project.getFile("fragment.xml"); + fragmentxml.refreshLocal(IResource.DEPTH_ONE, monitor); + WorkspaceFragmentModel fragmentModel = new WorkspaceFragmentModel(fragmentxml); + fragmentModel.load(); + IFragment fragment = fragmentModel.getFragment(); + fragment.setVersion(version); + fragment.setPluginVersion(version); + fragmentModel.save(); + fragmentxml.refreshLocal(IResource.DEPTH_ONE, monitor); + } + + for (int i = 0; i < featureProjects.length; ++i) { + IProject project = workspace.getRoot().getProject(featureProjects[i]); + IFile featurexml = project.getFile("feature.xml"); + featurexml.refreshLocal(IResource.DEPTH_ONE, monitor); + WorkspaceFeatureModel featureModel = new WorkspaceFeatureModel(featurexml); + featureModel.load(); + IFeature feature = featureModel.getFeature(); + feature.setVersion(version); + IFeaturePlugin[] plugins = feature.getPlugins(); + for (int j = 0; j < plugins.length; ++j) + if (plugins[j].getId().startsWith("org.eclipse.cdt")) + plugins[j].setVersion(version); + IFeatureChild[] children = feature.getIncludedFeatures(); + for (int j = 0; j < children.length; ++j) + if (children[j].getId().startsWith("org.eclipse.cdt")) + children[j].setVersion(version); + IFeatureImport[] imports = feature.getImports(); + for (int j = 0; j < imports.length; ++j) + if (imports[j].getId().startsWith("org.eclipse.cdt")) + imports[j].setVersion(version); + featureModel.save(); + featurexml.refreshLocal(IResource.DEPTH_ONE, monitor); + } + } + + private void buildUpdateSite() throws Exception { + System.out.println("Seting up build site"); + + // Get the models set up. + IProject siteProject = workspace.getRoot().getProject("build.site"); + IFile siteFile = siteProject.getFile("site.xml"); + siteFile.refreshLocal(IResource.DEPTH_ONE, monitor); + WorkspaceSiteModel siteModel = new WorkspaceSiteModel(siteFile); + siteModel.load(); + ISiteModelFactory siteModelFactory = siteModel.getFactory(); + ISite site = siteModel.getSite(); + IFile siteBuildFile = siteProject.getFile(".sitebuild/sitebuild.xml"); + siteBuildFile.refreshLocal(IResource.DEPTH_ONE, monitor); + WorkspaceSiteBuildModel buildModel = new WorkspaceSiteBuildModel(siteBuildFile); + buildModel.load(); + ISiteBuild siteBuild = buildModel.getSiteBuild(); + + // Add in the features + ISiteCategoryDefinition categoryDef = siteModelFactory.createCategoryDefinition(); + String categoryName = "CDT Build " + version; + categoryDef.setLabel(categoryName); + categoryDef.setName(categoryName); + site.addCategoryDefinitions(new ISiteCategoryDefinition[] {categoryDef}); + + ArrayList buildList = new ArrayList(); + ArrayList externalList = new ArrayList(); + for (int i = 0; i < buildFeatures.length; ++i) { + ISiteBuildFeature buildFeature = buildModel.createFeature(); + buildFeature.setId(buildFeatures[i]); + buildFeature.setVersion(version); + buildList.add(buildFeature); + + if (externalFeatures[i]) { + ISiteFeature feature = siteModelFactory.createFeature(); + feature.setId(buildFeatures[i]); + feature.setVersion(version); + feature.setURL("features/" + buildFeatures[i] + "_" + version + ".jar"); + ISiteCategory category = siteModelFactory.createCategory(feature); + category.setName(categoryName); + feature.addCategories(new ISiteCategory[] {category}); + externalList.add(feature); + } + } + + siteBuild.addFeatures((ISiteBuildFeature[])buildList.toArray(new ISiteBuildFeature[buildList.size()])); + site.addFeatures((ISiteFeature[])externalList.toArray(new ISiteFeature[externalList.size()])); + + // Save the models + siteModel.save(); + siteFile.refreshLocal(IResource.DEPTH_ONE, monitor); + buildModel.save(); + siteBuildFile.refreshLocal(IResource.DEPTH_ONE, monitor); + + // Do the build + System.out.println("Building"); + FeatureBuildOperation op + = new FeatureBuildOperation( + buildList, null, true, true); + op.run(monitor); + } + + private void uploadUpdateSite() throws Exception { + System.out.println("Uploading to site"); + + IProject buildSite = workspace.getRoot().getProject("build.site"); + buildSite.refreshLocal(IResource.DEPTH_INFINITE, monitor); + + // Open the ftp site + FTPClient ftp = new FTPClient(ftpHost); + ftp.setConnectMode(FTPConnectMode.ACTIVE); + ftp.login(ftpUser, ftpPassword); + ftp.setType(FTPTransferType.BINARY); + ftp.chdir(ftpPath); + + IFile file = buildSite.getFile("version.xml"); + ftp.put(file.getContents(), "version.xml"); + + file = buildSite.getFile("site.xml"); + ftp.put(file.getContents(), "site.xml"); + + IFolder folder = buildSite.getFolder(".sitebuild"); + ftp.chdir(".sitebuild"); + + file = folder.getFile("sitebuild.xml"); + ftp.put(file.getContents(), "sitebuild.xml"); + + folder = buildSite.getFolder("plugins"); + ftp.chdir("../plugins"); + + for (int i = 0; i < plugins.length; ++i) { + String name = plugins[i] + "_" + version + ".jar"; + System.out.println("Uploading plugin: " + name); + file = folder.getFile(name); + ftp.put(file.getContents(), name); + } + + for (int i = 0; i < fragments.length; ++i) { + String name = fragments[i] + "_" + version + ".jar"; + System.out.println("Uploading fragment: " + name); + file = folder.getFile(name); + ftp.put(file.getContents(), name); + } + + folder = buildSite.getFolder("features"); + ftp.chdir("../features"); + + for (int i = 0; i < buildFeatures.length; ++i) { + String name = buildFeatures[i] + "_" + version + ".jar"; + System.out.println("Uploading feature: " + name); + file = folder.getFile(name); + ftp.put(file.getContents(), name); + } + + ftp.quit(); + } + +} diff --git a/releng/org.eclipse.cdt.releng/src/org/eclipse/cdt/releng/RelengPlugin.java b/releng/org.eclipse.cdt.releng/src/org/eclipse/cdt/releng/RelengPlugin.java new file mode 100644 index 00000000000..42569895088 --- /dev/null +++ b/releng/org.eclipse.cdt.releng/src/org/eclipse/cdt/releng/RelengPlugin.java @@ -0,0 +1,63 @@ +package org.eclipse.cdt.releng; + +import org.eclipse.ui.plugin.*; +import org.eclipse.core.runtime.*; +import org.eclipse.core.resources.*; +import java.util.*; + +/** + * The main plugin class to be used in the desktop. + */ +public class RelengPlugin extends AbstractUIPlugin { + //The shared instance. + private static RelengPlugin plugin; + //Resource bundle. + private ResourceBundle resourceBundle; + + /** + * The constructor. + */ + public RelengPlugin(IPluginDescriptor descriptor) { + super(descriptor); + plugin = this; + try { + resourceBundle= ResourceBundle.getBundle("org.eclipse.cdt.releng.RelengPluginResources"); + } catch (MissingResourceException x) { + resourceBundle = null; + } + } + + /** + * Returns the shared instance. + */ + public static RelengPlugin getDefault() { + return plugin; + } + + /** + * Returns the workspace instance. + */ + public static IWorkspace getWorkspace() { + return ResourcesPlugin.getWorkspace(); + } + + /** + * Returns the string from the plugin's resource bundle, + * or 'key' if not found. + */ + public static String getResourceString(String key) { + ResourceBundle bundle= RelengPlugin.getDefault().getResourceBundle(); + try { + return bundle.getString(key); + } catch (MissingResourceException e) { + return key; + } + } + + /** + * Returns the plugin's resource bundle, + */ + public ResourceBundle getResourceBundle() { + return resourceBundle; + } +}