mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-01 06:05:24 +02:00
Work to support the versioning of the managed build tool definition schema and project files. This work was needed in order to refactor the rather large default tool definitions and to support ongoing enhancements to the managed build system.
This commit is contained in:
parent
e32f63b178
commit
4f86ebbdd4
5 changed files with 137 additions and 41 deletions
|
@ -17,6 +17,7 @@
|
|||
<element ref="tool"/>
|
||||
<element ref="configuration"/>
|
||||
<element ref="dynamicElementProvider"/>
|
||||
<element ref="managedBuildRevision"/>
|
||||
</sequence>
|
||||
<attribute name="point" type="string" use="required">
|
||||
<annotation>
|
||||
|
@ -542,6 +543,31 @@ Additional special types exist to flag options of special relevance to the build
|
|||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="managedBuildRevision">
|
||||
<annotation>
|
||||
<documentation>
|
||||
<p>
|
||||
Version identifier for the managed build extension point. It is a string representation, consisting of three (3) tokens separated by a decimal point. The 3 tokens are positive integer numbers. For example, the following are valid version identifiers:
|
||||
<ul>
|
||||
<li><code>0.0.0</code></li>
|
||||
<li><code>1.0.1234</code></li>
|
||||
<li><code>1.9</code> (interpreted as <code>1.9.0</code>)</li>
|
||||
<li><code>3</code> (interpreted as <code>3.0.0</code>)</li>
|
||||
</ul>
|
||||
</p>
|
||||
</documentation>
|
||||
</annotation>
|
||||
<complexType>
|
||||
<attribute name="fileVersion" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="since"/>
|
||||
|
|
|
@ -56,6 +56,8 @@ import org.eclipse.core.runtime.QualifiedName;
|
|||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.ProcessingInstruction;
|
||||
|
||||
/**
|
||||
* This is the main entry point for getting at the build information
|
||||
|
@ -64,11 +66,15 @@ import org.w3c.dom.Node;
|
|||
public class ManagedBuildManager extends AbstractCExtension implements IScannerInfoProvider {
|
||||
|
||||
private static final QualifiedName buildInfoProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), "managedBuildInfo"); //$NON-NLS-1$
|
||||
private static final String ROOT_ELEM_NAME = "ManagedProjectBuildInfo"; //$NON-NLS-1$
|
||||
private static final String ROOT_NODE_NAME = "ManagedProjectBuildInfo"; //$NON-NLS-1$
|
||||
private static final String FILE_NAME = ".cdtbuild"; //$NON-NLS-1$
|
||||
private static final ITarget[] emptyTargets = new ITarget[0];
|
||||
public static final String INTERFACE_IDENTITY = ManagedBuilderCorePlugin.getUniqueIdentifier() + "." + "ManagedBuildManager"; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
public static final String EXTENSION_POINT_ID = "ManagedBuildInfo"; //$NON-NLS-1$
|
||||
private static final String EXTENSION_POINT_ID = "ManagedBuildInfo"; //$NON-NLS-1$
|
||||
private static final String REVISION_ELEMENT_NAME = "managedBuildRevision"; //$NON-NLS-1$
|
||||
private static final String VERSION_ELEMENT_NAME = "fileVersion"; //$NON-NLS-1$
|
||||
private static final String MANIFEST_VERSION_ERROR ="ManagedBuildManager.error.manifest.version.error"; //$NON-NLS-1$
|
||||
private static final String PROJECT_VERSION_ERROR ="ManagedBuildManager.error.project.version.error"; //$NON-NLS-1$
|
||||
|
||||
// This is the version of the manifest and project files that
|
||||
private static final PluginVersionIdentifier buildInfoVersion = new PluginVersionIdentifier(2, 0, 0);
|
||||
|
@ -311,19 +317,26 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
|
|||
try {
|
||||
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document doc = builder.newDocument();
|
||||
Element rootElement = doc.createElement(ROOT_ELEM_NAME);
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
// Get the build information for the project
|
||||
ManagedBuildInfo buildInfo = (ManagedBuildInfo) getBuildInfo(project);
|
||||
|
||||
// Save the build info
|
||||
ManagedBuildInfo buildInfo = (ManagedBuildInfo) getBuildInfo(project);
|
||||
if (buildInfo != null && (force == true || buildInfo.isDirty())) {
|
||||
// For post-2.0 projects, there will be a version
|
||||
String projectVersion = buildInfo.getVersion();
|
||||
if (projectVersion != null) {
|
||||
ProcessingInstruction instruction = doc.createProcessingInstruction(VERSION_ELEMENT_NAME, projectVersion);
|
||||
doc.appendChild(instruction);
|
||||
}
|
||||
Element rootElement = doc.createElement(ROOT_NODE_NAME);
|
||||
doc.appendChild(rootElement);
|
||||
buildInfo.serialize(doc, rootElement);
|
||||
|
||||
// Transform the document to something we can save in a file
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
|
||||
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
|
||||
DOMSource source = new DOMSource(doc);
|
||||
StreamResult result = new StreamResult(stream);
|
||||
|
@ -331,16 +344,15 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
|
|||
|
||||
// Save the document
|
||||
IFile projectFile = project.getFile(FILE_NAME);
|
||||
InputStream inputStream = new ByteArrayInputStream(stream.toByteArray());
|
||||
String utfString = stream.toString("UTF8");
|
||||
if (projectFile.exists()) {
|
||||
projectFile.setContents(inputStream, IResource.FORCE, null);
|
||||
projectFile.setContents(new ByteArrayInputStream(utfString.getBytes()), IResource.FORCE, null);
|
||||
} else {
|
||||
projectFile.create(inputStream, IResource.FORCE, null);
|
||||
projectFile.create(new ByteArrayInputStream(utfString.getBytes()), IResource.FORCE, null);
|
||||
}
|
||||
|
||||
// Close the streams
|
||||
stream.close();
|
||||
inputStream.close();
|
||||
}
|
||||
} catch (ParserConfigurationException e) {
|
||||
// TODO Auto-generated catch block
|
||||
|
@ -455,16 +467,28 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
|
|||
return new Target(resource, parentTarget);
|
||||
}
|
||||
|
||||
private static boolean isVersionCompatible(IPluginDescriptor descriptor) {
|
||||
// Get the version of the manifest
|
||||
PluginVersionIdentifier plugin = descriptor.getVersionIdentifier();
|
||||
|
||||
private static boolean isVersionCompatible(IExtension extension) {
|
||||
// We can ignore the qualifier
|
||||
PluginVersionIdentifier version = new PluginVersionIdentifier(plugin.getMajorComponent(),
|
||||
plugin.getMinorComponent(),
|
||||
plugin.getServiceComponent());
|
||||
PluginVersionIdentifier version = null;
|
||||
|
||||
// Get the version of the manifest
|
||||
IConfigurationElement[] elements = extension.getConfigurationElements();
|
||||
|
||||
return(buildInfoVersion.isCompatibleWith(version));
|
||||
// Find the version string in the manifest
|
||||
for (int index = 0; index < elements.length; ++index) {
|
||||
IConfigurationElement element = elements[index];
|
||||
if (element.getName().equals(REVISION_ELEMENT_NAME)) {
|
||||
version = new PluginVersionIdentifier(element.getAttribute(VERSION_ELEMENT_NAME));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (version == null) {
|
||||
// This is a 1.2 manifest and we are compatible for now
|
||||
return true;
|
||||
} else {
|
||||
return(buildInfoVersion.isCompatibleWith(version));
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -481,9 +505,35 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
|
|||
InputStream stream = file.getContents();
|
||||
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document document = parser.parse(stream);
|
||||
String fileVersion = null;
|
||||
|
||||
// Get the first element in the project file
|
||||
Node rootElement = document.getFirstChild();
|
||||
if (rootElement.getNodeName().equals(ROOT_ELEM_NAME)) {
|
||||
buildInfo = new ManagedBuildInfo(project, (Element)rootElement);
|
||||
|
||||
// Since 2.0 this will be a processing instruction containing version
|
||||
if (rootElement.getNodeType() != Node.PROCESSING_INSTRUCTION_NODE) {
|
||||
// This is a 1.2 project and it must be updated
|
||||
|
||||
} else {
|
||||
// Make sure that the version is compatible with the manager
|
||||
fileVersion = rootElement.getNodeValue();
|
||||
PluginVersionIdentifier version = new PluginVersionIdentifier(fileVersion);
|
||||
if (!buildInfoVersion.isCompatibleWith(version)) {
|
||||
throw new BuildException(ManagedBuilderCorePlugin.getResourceString(PROJECT_VERSION_ERROR));
|
||||
}
|
||||
if (buildInfoVersion.isGreaterThan(version)) {
|
||||
// TODO Upgrade the project
|
||||
}
|
||||
}
|
||||
|
||||
// Now get the project root element (there should be only one)
|
||||
NodeList nodes = document.getElementsByTagName(ROOT_NODE_NAME);
|
||||
if (nodes.getLength() > 0) {
|
||||
Node node = nodes.item(0);
|
||||
buildInfo = new ManagedBuildInfo(project, (Element)node);
|
||||
if (fileVersion != null) {
|
||||
buildInfo.setVersion(fileVersion);
|
||||
}
|
||||
project.setSessionProperty(buildInfoProperty, buildInfo);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -503,18 +553,17 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
|
|||
|
||||
// Get those extensions
|
||||
IPluginDescriptor descriptor = ManagedBuilderCorePlugin.getDefault().getDescriptor();
|
||||
|
||||
if (!isVersionCompatible(descriptor)) {
|
||||
//The version of the Plug-in is greater than what the manager thinks it understands
|
||||
throw new BuildException(ManagedBuilderCorePlugin.getResourceString("ManagedBuildManager.error.version.higher")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
// We can read the manifest
|
||||
IExtensionPoint extensionPoint = descriptor.getExtensionPoint(EXTENSION_POINT_ID);
|
||||
IExtension[] extensions = extensionPoint.getExtensions();
|
||||
|
||||
// First call the constructors
|
||||
for (int i = 0; i < extensions.length; ++i) {
|
||||
IExtension extension = extensions[i];
|
||||
// Can we read this manifest
|
||||
if (!isVersionCompatible(extension)) {
|
||||
//The version of the Plug-in is greater than what the manager thinks it understands
|
||||
throw new BuildException(ManagedBuilderCorePlugin.getResourceString(MANIFEST_VERSION_ERROR));
|
||||
}
|
||||
IConfigurationElement[] elements = extension.getConfigurationElements();
|
||||
loadConfigElements(DefaultManagedConfigElement.convertArray(elements));
|
||||
}
|
||||
|
@ -600,7 +649,7 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
|
|||
DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document document = parser.parse(stream);
|
||||
Node rootElement = document.getFirstChild();
|
||||
if (rootElement.getNodeName().equals(ROOT_ELEM_NAME)) {
|
||||
if (rootElement.getNodeName().equals(ROOT_NODE_NAME)) {
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -672,8 +721,11 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
|
|||
return (IManagedBuildInfo) findBuildInfo(resource, false);
|
||||
}
|
||||
|
||||
public static String getBuildInfoVersion() {
|
||||
return buildInfoVersion.toString();
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public static PluginVersionIdentifier getBuildInfoVersion() {
|
||||
return buildInfoVersion;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -36,7 +36,7 @@ import org.eclipse.core.runtime.Path;
|
|||
import org.eclipse.core.runtime.QualifiedName;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
|
||||
|
||||
|
@ -53,6 +53,7 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
|
|||
private IResource owner;
|
||||
private Map targetMap;
|
||||
private List targetList;
|
||||
private String version; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Create a new managed build information for the IResource specified in the argument
|
||||
|
@ -94,13 +95,10 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
|
|||
public ManagedBuildInfo(IResource owner, Element element) {
|
||||
this(owner);
|
||||
|
||||
// Read in the top-level info objects
|
||||
Node child = element.getFirstChild();
|
||||
while (child != null) {
|
||||
if (child.getNodeName().equals(ITarget.TARGET_ELEMENT_NAME)) {
|
||||
new Target(this, (Element)child);
|
||||
}
|
||||
child = child.getNextSibling();
|
||||
// Inflate the targets
|
||||
NodeList targetNodes = element.getElementsByTagName(ITarget.TARGET_ELEMENT_NAME);
|
||||
for (int targIndex = targetNodes.getLength() - 1; targIndex >= 0; --targIndex) {
|
||||
new Target(this, (Element)targetNodes.item(targIndex));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -831,6 +829,13 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
|
|||
return (String[])objs.toArray(new String[objs.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo#isDirty()
|
||||
*/
|
||||
|
@ -950,6 +955,7 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
|
|||
// Remember the default target and configurations
|
||||
persistDefaultTarget();
|
||||
persistDefaultConfigurations();
|
||||
|
||||
// I'm clean now
|
||||
setDirty(false);
|
||||
}
|
||||
|
@ -1005,6 +1011,16 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param version
|
||||
*/
|
||||
public void setVersion(String version) {
|
||||
if (version != null && !version.equals(this.version)) {
|
||||
this.version = version;
|
||||
setDirty(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the owner of the receiver to be the <code>IResource</code> specified
|
||||
* in the argument.
|
||||
|
@ -1025,5 +1041,4 @@ public class ManagedBuildInfo implements IManagedBuildInfo, IScannerInfo {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -37,5 +37,5 @@ Option.error.bad_value_type=Bad value for type
|
|||
ManagedBuildManager.error.owner_not_null=addTarget: owner not null
|
||||
ManagedBuildManager.error.null_owner=addTarget: null owner
|
||||
ManagedBuildManager.error.owner_not_project=addTarget: owner not project
|
||||
ManagedBuildManager.error.version.higher=Version of file is higher than version of manager
|
||||
ManagedBuildManager.error.version.lower=Version of file is less than version of manager
|
||||
ManagedBuildManager.error.manifest.version.error=The version of plugin file is higher than version of the build system
|
||||
ManagedBuildManager.error.project.version.error=The version of the project is higher than the build system
|
||||
|
|
|
@ -70,6 +70,9 @@
|
|||
id="cdt.managed.build.info"
|
||||
name="Managed Build Tools Description"
|
||||
point="org.eclipse.cdt.managedbuilder.core.ManagedBuildInfo">
|
||||
<managedBuildRevision
|
||||
fileVersion="2.0.0">
|
||||
</managedBuildRevision>
|
||||
<target
|
||||
name="%TargetName.cygw"
|
||||
id="cygwin"
|
||||
|
|
Loading…
Add table
Reference in a new issue