mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26:01 +02:00
Bug 513589 - Add support to build CDT projects in a Docker Container
- add IOptionalBuildObjectPropertiesContainer interface to use for objects that supply optional build properties - add new IOptionalBuildProperties interface that defines optional build properties donated by external plug-ins - add new - change IConfiguration to an IOptionalBuildObjectPropertiesContainer - change IManagedProject to be an IOptionalBuildObjectPropertiesContainer - fix ProcessClosure to ensure that readers are not null before accessing them - fix Container launch delegate to look at project optional build properties for active configuration to fetch connection and image info and use said info to find a matching launch or create a new one - have Container launch delegate use the image name as part of the launch config name - have Container launch short-cut also use the project's optional build properties for the active config to get connection and image information before any defaulting - change AutotoolsNewMarkerGenerator to store the command launcher as an ICommandLauncher - add new CommandLauncherFactory extension to cdt.core that allows plug-ins to specify a CommandLauncherFactory that will return an ICommandLauncher based on the project - add macros for new extension to CCorePlugin - add new CommandLauncherManager class that loads CommandLauncherFactory extensions and is used to give an ICommandLauncher wrapper that will go through the list of CommandLauncherFactory extensions until one returns non-null ICommandLauncher - add code to RemoteCommandLauncher so it will use the CommandLauncherManager to get the local launcher - also change RemoteCommandLauncher to check at execution time whether the command is local and in that case use the local command launcher - add new ICommandLauncherFactory interface - add new ContainerCommandLauncher to launch - add new ContainerCommandLauncherFactory class for returning a ContainerCommandLauncher instance to launch commands in a Docker Container - change MakeBuilder to use CommandLauncherManager to get its ICommandLauncher - change CommandBuilder to use CommandLauncherManager too - ditto for Builder and AbstractBuiltinSpecsDetector and ExternalToolInvoker - change Configuration to load/store optional build properties as well as return the properties to get/set - ditto for MultiConfiguration - change ManagedProject to implement IOptionalBuildOptionProperties interface - ditto for ProjectType - create new OptionalBuildProperties class to store optional build properties for a configuration - bump cdt.docker.launcher to 1.1.0 - use CommandLauncherFactory extension to define ContainerCommandLauncherFactory - add optional ContainerPropertyTab which allows the end-user to optionally choose to build a C/C++ project in a Container and specify the connection/image to use - in LanguageSettingsSerializableSettings class, call the CommandLauncherManager getLanguageSettingEntries method to get the massaged language setting entries based on the current list - in LanguageSettingsProviderSerializer, try and get the pooled entries using the cfg description so that it will have the project and can use the CommandLauncherManager to get entries from image - in ContainerCommandLauncherFactory move cached headers under a HEADERS directory in the plug-in area - create a sub-directory for the connection and a sub-directory for the image based on cleansed names - store the real names of the connection and image to use later in the DockerHeaderPreferencePage - modify LanguageSettingsEntriesTab to force the horizontal scroll bar to appear (this is a bug in SWT SashForm support and the fix here isn't quite correct, but is better) - add new DockerHeaderPreferencePage that allows user to remove cached headers from images - change C/C++ Docker preferences to be titled: Docker Container - fix LanguageSettingsWorkspaceProvider.getSettingEntries method to use the CommandLauncherManager so entries will be transformed to use cached headers - add BaseDatabindingModel class - add DataVolumeModel class to model a volume mount - add ContainerPropertyVolumes model to model volume specification and selected volumes - add properties to ContainerCommandLauncher to represent volumes and selected volumes for a configuration - add ContainerDataVolumeDialog for specifying a volume mount by the end-user - add a null detector for cfgDescription in LanguageSettingsSerializableProvider - fix AutotoolsNewMakeGenerator.getWinOSType to not specify "." for working dir - fix GCCBuiltinSpecsDetectorCygwin to not map paths to Cygwin if the current configuration is enabled for container build - add logic to ContainerCommandLauncher to look for Windows file formats and change them to unix format and map any "." working dir to be /tmp - fix ContainerLauncherConfigurationDelegate similarly - fix AbstractBuiltinSpecsDetector to pass in the current configuration description when getting the CommandLauncher since the current configuration may not be the active configuration - change ContainerPropertyTab to add Elf and GNU Elf binary parsers when build in Container is chosen so that output executables are treated as Binaries by the CDT project - add documentationl for the ContainerPropertyTab in Build Settings and the Data Volume dialog pop-up it brings up - change CommandBuilder to accept a project as an argument to its constructor and to pass this as an argument to the CommandLauncherManager - have StepBuilder pass project when creating a CommandBuilder Change-Id: Ia78488b93056e6ec7ca83a6c87b3a9d2b9424943
This commit is contained in:
parent
4c1a6e0ccd
commit
c96d126b86
67 changed files with 4543 additions and 66 deletions
|
@ -893,7 +893,7 @@ public class AutotoolsNewMakeGenerator extends MarkerGenerator {
|
|||
consoleOutStream.flush();
|
||||
|
||||
// Get a launcher for the config command
|
||||
RemoteCommandLauncher launcher = new RemoteCommandLauncher();
|
||||
ICommandLauncher launcher = new RemoteCommandLauncher();
|
||||
launcher.setProject(project);
|
||||
// Set the environment
|
||||
IEnvironmentVariable variables[] =
|
||||
|
@ -1042,7 +1042,7 @@ public class AutotoolsNewMakeGenerator extends MarkerGenerator {
|
|||
new Path(SHELL_COMMAND), //$NON-NLS-1$
|
||||
new String[] { "-c", "echo $OSTYPE" }, //$NON-NLS-1$ //$NON-NLS-2$
|
||||
env,
|
||||
new Path("."), //$NON-NLS-1$
|
||||
buildLocation,
|
||||
SubMonitor.convert(monitor));
|
||||
if (launcher.waitAndRead(out, out) == ICommandLauncher.OK)
|
||||
winOSType = out.toString().trim();
|
||||
|
@ -1207,7 +1207,7 @@ public class AutotoolsNewMakeGenerator extends MarkerGenerator {
|
|||
consoleOutStream.flush();
|
||||
|
||||
// Get a launcher for the config command
|
||||
RemoteCommandLauncher launcher = new RemoteCommandLauncher();
|
||||
ICommandLauncher launcher = new RemoteCommandLauncher();
|
||||
launcher.setProject(project);
|
||||
// Set the environment
|
||||
IEnvironmentVariable variables[] =
|
||||
|
|
|
@ -18,6 +18,8 @@ import java.util.zip.ZipFile;
|
|||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CommandLauncher;
|
||||
import org.eclipse.cdt.core.CommandLauncherManager;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.internal.autotools.core.configure.AutotoolsConfigurationManager;
|
||||
import org.eclipse.cdt.internal.autotools.core.configure.IAConfiguration;
|
||||
|
@ -129,7 +131,8 @@ public class ProjectTools {
|
|||
*/
|
||||
public static boolean markExecutable(IProject project, String filePath) {
|
||||
// Get a launcher for the config command
|
||||
CommandLauncher launcher = new CommandLauncher();
|
||||
ICommandLauncher launcher = CommandLauncherManager.getInstance().getCommandLauncher();
|
||||
launcher.setProject(project);
|
||||
OutputStream stdout = new ByteArrayOutputStream();
|
||||
OutputStream stderr = new ByteArrayOutputStream();
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CommandLauncher;
|
||||
import org.eclipse.cdt.core.CommandLauncherManager;
|
||||
import org.eclipse.cdt.core.ErrorParserManager;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.IConsoleParser;
|
||||
|
@ -180,7 +180,7 @@ public class MakeBuilder extends ACBuilder {
|
|||
console.start(project);
|
||||
|
||||
// Prepare launch parameters for BuildRunnerHelper
|
||||
ICommandLauncher launcher = new CommandLauncher();
|
||||
ICommandLauncher launcher = CommandLauncherManager.getInstance().getCommandLauncher();
|
||||
|
||||
String[] targets = getTargets(kind, info);
|
||||
if (targets.length != 0 && targets[targets.length - 1].equals(info.getCleanBuildTarget()))
|
||||
|
|
|
@ -19,7 +19,7 @@ import java.util.List;
|
|||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CommandLauncher;
|
||||
import org.eclipse.cdt.core.CommandLauncherManager;
|
||||
import org.eclipse.cdt.core.ErrorParserManager;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.IConsoleParser;
|
||||
|
@ -120,7 +120,7 @@ public class DefaultRunSIProvider implements IExternalScannerInfoProvider {
|
|||
}
|
||||
console.start(project);
|
||||
|
||||
ICommandLauncher launcher = new CommandLauncher();
|
||||
ICommandLauncher launcher = CommandLauncherManager.getInstance().getCommandLauncher();
|
||||
launcher.setProject(project);
|
||||
|
||||
IPath program = getCommandToLaunch();
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Red Hat Inc. and others.
|
||||
* 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:
|
||||
* Red Hat Inc. - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.managedbuilder.buildproperties;
|
||||
|
||||
/**
|
||||
* @noextend This class is not intended to be subclassed by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
* @since 8.5
|
||||
*/
|
||||
public interface IOptionalBuildProperties extends Cloneable {
|
||||
String[] getProperties();
|
||||
|
||||
String getProperty(String id);
|
||||
|
||||
void setProperty(String propertyId, String propertyValue);
|
||||
|
||||
void removeProperty(String id);
|
||||
|
||||
void clear();
|
||||
|
||||
Object clone();
|
||||
}
|
|
@ -10,7 +10,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.managedbuilder.core;
|
||||
|
||||
|
||||
/**
|
||||
* @noextend This class is not intended to be subclassed by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
|
|
|
@ -36,7 +36,7 @@ import org.eclipse.core.runtime.IPath;
|
|||
* @noextend This class is not intended to be subclassed by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesContainer {
|
||||
public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesContainer, IOptionalBuildObjectPropertiesContainer {
|
||||
public static final String ARTIFACT_NAME = "artifactName"; //$NON-NLS-1$
|
||||
public static final String CLEAN_COMMAND = "cleanCommand"; //$NON-NLS-1$
|
||||
public static final String PREBUILD_STEP = "prebuildStep"; //$NON-NLS-1$
|
||||
|
@ -54,6 +54,10 @@ public interface IConfiguration extends IBuildObject, IBuildObjectPropertiesCont
|
|||
public static final String DESCRIPTION = "description"; //$NON-NLS-1$
|
||||
|
||||
public static final String BUILD_PROPERTIES = "buildProperties"; //$NON-NLS-1$
|
||||
/**
|
||||
* @since 8.5
|
||||
*/
|
||||
public static final String OPTIONAL_BUILD_PROPERTIES = "optionalBuildProperties"; //$NON-NLS-1$
|
||||
public static final String BUILD_ARTEFACT_TYPE = "buildArtefactType"; //$NON-NLS-1$
|
||||
public static final String IS_SYSTEM = "isSystem"; //$NON-NLS-1$
|
||||
|
||||
|
|
|
@ -38,10 +38,14 @@ import org.eclipse.core.resources.IResource;
|
|||
* @noextend This class is not intended to be subclassed by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IManagedProject extends IBuildObject, IBuildObjectPropertiesContainer {
|
||||
public interface IManagedProject extends IBuildObject, IBuildObjectPropertiesContainer, IOptionalBuildObjectPropertiesContainer {
|
||||
public static final String MANAGED_PROJECT_ELEMENT_NAME = "project"; //$NON-NLS-1$
|
||||
public static final String PROJECTTYPE = "projectType"; //$NON-NLS-1$
|
||||
public static final String BUILD_PROPERTIES = "buildProperties"; //$NON-NLS-1$
|
||||
/**
|
||||
* @since 8.5
|
||||
*/
|
||||
public static final String OPTIONAL_BUILD_PROPERTIES = "optionalBuildProperties"; //$NON-NLS-1$
|
||||
public static final String BUILD_ARTEFACT_TYPE = "buildArtefactType"; //$NON-NLS-1$
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Red Hat Inc and others.
|
||||
* 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:
|
||||
* Red Hat Inc. - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.managedbuilder.core;
|
||||
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
|
||||
/**
|
||||
* @since 8.5
|
||||
*/
|
||||
public interface IOptionalBuildObjectPropertiesContainer {
|
||||
IOptionalBuildProperties getOptionalBuildProperties();
|
||||
|
||||
}
|
|
@ -44,7 +44,7 @@ import org.eclipse.cdt.managedbuilder.macros.IProjectBuildMacroSupplier;
|
|||
* @noextend This class is not intended to be subclassed by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface IProjectType extends IBuildObject, IBuildObjectPropertiesContainer {
|
||||
public interface IProjectType extends IBuildObject, IBuildObjectPropertiesContainer, IOptionalBuildObjectPropertiesContainer {
|
||||
public static final String PROJECTTYPE_ELEMENT_NAME = "projectType"; //$NON-NLS-1$
|
||||
public static final String SUPERCLASS = "superClass"; //$NON-NLS-1$
|
||||
public static final String IS_ABSTRACT = "isAbstract"; //$NON-NLS-1$
|
||||
|
|
|
@ -18,11 +18,12 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.CommandLauncher;
|
||||
import org.eclipse.cdt.core.CommandLauncherManager;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
|
||||
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
|
||||
import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
|
@ -47,6 +48,8 @@ public class CommandBuilder implements IBuildModelBuilder {
|
|||
private Process fProcess;
|
||||
private String fErrMsg;
|
||||
|
||||
private IProject fProject;
|
||||
|
||||
protected class OutputStreamWrapper extends OutputStream {
|
||||
private OutputStream fOut;
|
||||
|
||||
|
@ -80,8 +83,9 @@ public class CommandBuilder implements IBuildModelBuilder {
|
|||
|
||||
}
|
||||
|
||||
public CommandBuilder(IBuildCommand cmd, IResourceRebuildStateContainer cr){
|
||||
public CommandBuilder(IBuildCommand cmd, IResourceRebuildStateContainer cr, IProject project){
|
||||
fCmd = cmd;
|
||||
fProject = project;
|
||||
}
|
||||
|
||||
protected OutputStream wrap(OutputStream out){
|
||||
|
@ -143,7 +147,7 @@ public class CommandBuilder implements IBuildModelBuilder {
|
|||
}
|
||||
|
||||
protected ICommandLauncher createLauncher() {
|
||||
return new CommandLauncher();
|
||||
return CommandLauncherManager.getInstance().getCommandLauncher(fProject);
|
||||
}
|
||||
|
||||
public String getErrMsg() {
|
||||
|
|
|
@ -17,7 +17,9 @@ import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
|
|||
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildDescription;
|
||||
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildResource;
|
||||
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildStep;
|
||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
|
@ -223,8 +225,10 @@ public class StepBuilder implements IBuildModelBuilder {
|
|||
fCommandBuilders = new CommandBuilder[0];
|
||||
else {
|
||||
fCommandBuilders = new CommandBuilder[cmds.length];
|
||||
IConfiguration cfg = fStep.getBuildDescription().getConfiguration();
|
||||
IProject project = (IProject)cfg.getOwner();
|
||||
for(int i = 0; i < cmds.length; i++){
|
||||
fCommandBuilders[i] = new CommandBuilder(cmds[i], fRebuildStateContainer);
|
||||
fCommandBuilders[i] = new CommandBuilder(cmds[i], fRebuildStateContainer, project);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import java.util.SortedMap;
|
|||
import java.util.StringTokenizer;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CommandLauncher;
|
||||
import org.eclipse.cdt.core.CommandLauncherManager;
|
||||
import org.eclipse.cdt.core.ErrorParserManager;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
|
||||
|
@ -2858,7 +2858,7 @@ public class Builder extends HoldsOptions implements IBuilder, IMatchKeyProvider
|
|||
return getSuperClass().getCommandLauncher();
|
||||
|
||||
else if(fCommandLauncher == null) // catch all for backwards compatibility
|
||||
fCommandLauncher = new CommandLauncher();
|
||||
fCommandLauncher = CommandLauncherManager.getInstance().getCommandLauncher();
|
||||
|
||||
return fCommandLauncher;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.eclipse.cdt.internal.core.SafeStringInterner;
|
|||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyType;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.BuildException;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildObject;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
|
||||
|
@ -114,6 +115,7 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
|
|||
private String description;
|
||||
private ICSourceEntry[] sourceEntries;
|
||||
private BuildObjectProperties buildProperties;
|
||||
private OptionalBuildProperties optionalBuildProperties;
|
||||
private boolean isTest;
|
||||
private SupportedProperties supportedProperties;
|
||||
|
||||
|
@ -261,6 +263,10 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
|
|||
if(props != null)
|
||||
buildProperties = new BuildObjectProperties(props, this, this);
|
||||
|
||||
String optionalProps = SafeStringInterner.safeIntern(element.getAttribute(OPTIONAL_BUILD_PROPERTIES));
|
||||
if(optionalProps != null)
|
||||
optionalBuildProperties = new OptionalBuildProperties(optionalProps);
|
||||
|
||||
String artType = SafeStringInterner.safeIntern(element.getAttribute(BUILD_ARTEFACT_TYPE));
|
||||
if(artType != null){
|
||||
if(buildProperties == null)
|
||||
|
@ -482,6 +488,9 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
|
|||
if(baseCfg.buildProperties != null)
|
||||
this.buildProperties = new BuildObjectProperties(baseCfg.buildProperties, this, this);
|
||||
|
||||
if (baseCfg.optionalBuildProperties != null)
|
||||
this.optionalBuildProperties = new OptionalBuildProperties(baseCfg.optionalBuildProperties);
|
||||
|
||||
// set managedBuildRevision
|
||||
setManagedBuildRevision(baseCfg.getManagedBuildRevision());
|
||||
|
||||
|
@ -626,6 +635,10 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
|
|||
this.buildProperties = new BuildObjectProperties(cloneConfig.buildProperties, this, this);
|
||||
}
|
||||
|
||||
if (cloneConfig.optionalBuildProperties != null) {
|
||||
this.optionalBuildProperties = new OptionalBuildProperties(cloneConfig.optionalBuildProperties);
|
||||
}
|
||||
|
||||
this.description = cloneConfig.getDescription();
|
||||
|
||||
// set managedBuildRevision
|
||||
|
@ -819,6 +832,10 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
|
|||
if(props != null)
|
||||
buildProperties = new BuildObjectProperties(props, this, this);
|
||||
|
||||
String optionalProps = element.getAttribute(OPTIONAL_BUILD_PROPERTIES);
|
||||
if (optionalProps != null)
|
||||
optionalBuildProperties = new OptionalBuildProperties(optionalProps);
|
||||
|
||||
String artType = SafeStringInterner.safeIntern(element.getAttribute(BUILD_ARTEFACT_TYPE));
|
||||
if(artType != null){
|
||||
if(buildProperties == null)
|
||||
|
@ -908,6 +925,10 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
|
|||
}
|
||||
}
|
||||
|
||||
if(optionalBuildProperties != null){
|
||||
element.setAttribute(OPTIONAL_BUILD_PROPERTIES, optionalBuildProperties.toString());
|
||||
}
|
||||
|
||||
if (parent != null)
|
||||
element.setAttribute(IConfiguration.PARENT, parent.getId());
|
||||
|
||||
|
@ -2398,6 +2419,18 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
|
|||
return buildProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOptionalBuildProperties getOptionalBuildProperties() {
|
||||
if (optionalBuildProperties == null){
|
||||
OptionalBuildProperties parentProps = findOptionalBuildProperties();
|
||||
if(parentProps != null)
|
||||
optionalBuildProperties = new OptionalBuildProperties(parentProps);
|
||||
else
|
||||
optionalBuildProperties = new OptionalBuildProperties();
|
||||
}
|
||||
return optionalBuildProperties;
|
||||
}
|
||||
|
||||
private BuildObjectProperties findBuildProperties(){
|
||||
if(buildProperties == null){
|
||||
if(parent != null){
|
||||
|
@ -2408,6 +2441,16 @@ public class Configuration extends BuildObject implements IConfiguration, IBuild
|
|||
return buildProperties;
|
||||
}
|
||||
|
||||
private OptionalBuildProperties findOptionalBuildProperties(){
|
||||
if (optionalBuildProperties == null){
|
||||
if (parent != null){
|
||||
return ((Configuration)parent).findOptionalBuildProperties();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return optionalBuildProperties;
|
||||
}
|
||||
|
||||
public boolean supportsType(IBuildPropertyType type) {
|
||||
return supportsType(type.getId());
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.eclipse.cdt.core.settings.model.ICStorageElement;
|
|||
import org.eclipse.cdt.internal.core.cdtvariables.StorableCdtVariables;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyType;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildObject;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildPropertiesRestriction;
|
||||
|
@ -57,6 +58,7 @@ public class ManagedProject extends BuildObject implements IManagedProject, IBui
|
|||
// private StorableEnvironment userDefinedEnvironment;
|
||||
|
||||
private BuildObjectProperties buildProperties;
|
||||
private OptionalBuildProperties optionalBuildProperties;
|
||||
|
||||
/*
|
||||
* C O N S T R U C T O R S
|
||||
|
@ -192,6 +194,10 @@ public class ManagedProject extends BuildObject implements IManagedProject, IBui
|
|||
if(props != null && props.length() != 0)
|
||||
buildProperties = new BuildObjectProperties(props, this, this);
|
||||
|
||||
String optionalProps = element.getAttribute(OPTIONAL_BUILD_PROPERTIES);
|
||||
if (optionalProps != null && optionalProps.length() != 0)
|
||||
optionalBuildProperties = new OptionalBuildProperties(optionalProps);
|
||||
|
||||
String artType = element.getAttribute(BUILD_ARTEFACT_TYPE);
|
||||
if(artType != null){
|
||||
if(buildProperties == null)
|
||||
|
@ -576,6 +582,18 @@ public class ManagedProject extends BuildObject implements IManagedProject, IBui
|
|||
return buildProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOptionalBuildProperties getOptionalBuildProperties() {
|
||||
if(optionalBuildProperties == null){
|
||||
OptionalBuildProperties parentProps = findOptionalBuildProperties();
|
||||
if(parentProps != null)
|
||||
optionalBuildProperties = new OptionalBuildProperties(parentProps);
|
||||
else
|
||||
optionalBuildProperties = new OptionalBuildProperties();
|
||||
}
|
||||
return optionalBuildProperties;
|
||||
}
|
||||
|
||||
private BuildObjectProperties findBuildProperties(){
|
||||
if(buildProperties == null){
|
||||
if(projectType != null){
|
||||
|
@ -586,6 +604,16 @@ public class ManagedProject extends BuildObject implements IManagedProject, IBui
|
|||
return buildProperties;
|
||||
}
|
||||
|
||||
private OptionalBuildProperties findOptionalBuildProperties(){
|
||||
if(optionalBuildProperties == null){
|
||||
if(projectType != null){
|
||||
return ((ProjectType)projectType).findOptionalBuildProperties();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return optionalBuildProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertiesChanged() {
|
||||
IConfiguration cfgs[] = getConfigurations();
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.eclipse.cdt.core.settings.model.extension.CBuildData;
|
|||
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.BuildException;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuilder;
|
||||
|
@ -1204,6 +1205,14 @@ public class MultiConfiguration extends MultiItemsHolder implements
|
|||
return curr().getBuildProperties();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.managedbuilder.core.IBuildObjectPropertiesContainer#getOptionalBuildProperties()
|
||||
*/
|
||||
@Override
|
||||
public IOptionalBuildProperties getOptionalBuildProperties() {
|
||||
return curr().getOptionalBuildProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getParallelDef() {
|
||||
for (IConfiguration cfg : fCfgs) {
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Red Hat Inc. and others.
|
||||
* 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
|
||||
*
|
||||
* Red Hat Inc. - initial contribution
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.managedbuilder.internal.core;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.eclipse.cdt.internal.core.SafeStringInterner;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
|
||||
public class OptionalBuildProperties implements IOptionalBuildProperties {
|
||||
|
||||
public static final String PROPERTY_VALUE_SEPARATOR = "="; //$NON-NLS-1$
|
||||
public static final String PROPERTIES_SEPARATOR = ","; //$NON-NLS-1$
|
||||
|
||||
private Map<String, String> fProperties = new HashMap<>();
|
||||
|
||||
public OptionalBuildProperties() {
|
||||
}
|
||||
|
||||
public OptionalBuildProperties(String properties) {
|
||||
StringTokenizer t = new StringTokenizer(properties, PROPERTIES_SEPARATOR);
|
||||
while(t.hasMoreTokens()){
|
||||
String property = t.nextToken();
|
||||
int index = property.indexOf(PROPERTY_VALUE_SEPARATOR);
|
||||
String id, value;
|
||||
if(index != -1){
|
||||
id = SafeStringInterner.safeIntern(property.substring(0, index));
|
||||
value = SafeStringInterner.safeIntern(property.substring(index + 1));
|
||||
} else {
|
||||
id = SafeStringInterner.safeIntern(property);
|
||||
value = null;
|
||||
}
|
||||
fProperties.put(id, value);
|
||||
}
|
||||
}
|
||||
|
||||
public OptionalBuildProperties(OptionalBuildProperties properties) {
|
||||
fProperties.putAll(properties.fProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProperty(String id) {
|
||||
return fProperties.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(String id, String value) {
|
||||
fProperties.put(id, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getProperties(){
|
||||
return fProperties.values().toArray(new String[fProperties.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeProperty(String id) {
|
||||
fProperties.remove(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
int size = fProperties.size();
|
||||
Set<Entry<String,String>> entries = fProperties.entrySet();
|
||||
if(size == 0)
|
||||
return ""; //$NON-NLS-1$
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
Iterator<Entry<String,String>> iterator = entries.iterator();
|
||||
Entry<String,String> entry = iterator.next();
|
||||
buf.append(entry.getKey() + PROPERTY_VALUE_SEPARATOR + entry.getValue());
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
buf.append(PROPERTIES_SEPARATOR);
|
||||
entry = iterator.next();
|
||||
buf.append(entry.getKey() + PROPERTY_VALUE_SEPARATOR + entry.getValue());
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new OptionalBuildProperties(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
fProperties.clear();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@ import org.eclipse.cdt.internal.core.SafeStringInterner;
|
|||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildProperty;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyType;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildPropertiesRestriction;
|
||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||
|
@ -66,6 +67,7 @@ public class ProjectType extends BuildObject implements IProjectType, IBuildProp
|
|||
private IProjectBuildMacroSupplier buildMacroSupplier = null;
|
||||
|
||||
BuildObjectProperties buildProperties;
|
||||
OptionalBuildProperties optionalBuildProperties;
|
||||
|
||||
|
||||
// Miscellaneous
|
||||
|
@ -707,6 +709,28 @@ public class ProjectType extends BuildObject implements IProjectType, IBuildProp
|
|||
return buildProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOptionalBuildProperties getOptionalBuildProperties() {
|
||||
if(optionalBuildProperties == null){
|
||||
OptionalBuildProperties parentProps = findOptionalBuildProperties();
|
||||
if(parentProps != null)
|
||||
optionalBuildProperties = new OptionalBuildProperties(parentProps);
|
||||
else
|
||||
optionalBuildProperties = new OptionalBuildProperties();
|
||||
}
|
||||
return optionalBuildProperties;
|
||||
}
|
||||
|
||||
OptionalBuildProperties findOptionalBuildProperties(){
|
||||
if(optionalBuildProperties == null){
|
||||
if(superClass != null){
|
||||
return ((ProjectType)superClass).findOptionalBuildProperties();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return optionalBuildProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void propertiesChanged() {
|
||||
List<Configuration> list = getConfigurationList();
|
||||
|
|
|
@ -12,11 +12,17 @@
|
|||
package org.eclipse.cdt.managedbuilder.internal.language.settings.providers;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.cdt.core.EFSExtensionProvider;
|
||||
import org.eclipse.cdt.internal.core.Cygwin;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
|
||||
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
|
||||
import org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
/**
|
||||
* Class to detect built-in compiler settings for Cygwin toolchain.
|
||||
|
@ -26,6 +32,7 @@ public class GCCBuiltinSpecsDetectorCygwin extends GCCBuiltinSpecsDetector {
|
|||
// ID must match the tool-chain definition in org.eclipse.cdt.managedbuilder.core.buildDefinitions extension point
|
||||
private static final String GCC_TOOLCHAIN_ID_CYGWIN = "cdt.managedbuild.toolchain.gnu.cygwin.base"; //$NON-NLS-1$
|
||||
private static final String ENV_PATH = "PATH"; //$NON-NLS-1$
|
||||
public static final String CONTAINER_ENABLEMENT_PROPERTY = "org.eclipse.cdt.docker.launcher.containerbuild.property.enablement"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* EFSExtensionProvider for Cygwin translations
|
||||
|
@ -46,7 +53,14 @@ public class GCCBuiltinSpecsDetectorCygwin extends GCCBuiltinSpecsDetector {
|
|||
String windowsPath = null;
|
||||
try {
|
||||
String cygwinPath = getPathFromURI(locationURI);
|
||||
IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription(currentCfgDescription);
|
||||
if (cfg != null) {
|
||||
IOptionalBuildProperties bp = cfg.getOptionalBuildProperties();
|
||||
String ep = bp.getProperty(CONTAINER_ENABLEMENT_PROPERTY);
|
||||
if (ep == null || !Boolean.parseBoolean(ep)) {
|
||||
windowsPath = Cygwin.cygwinToWindowsPath(cygwinPath, envPathValue);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ManagedBuilderCorePlugin.log(e);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import java.util.Map.Entry;
|
|||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CommandLauncher;
|
||||
import org.eclipse.cdt.core.CommandLauncherManager;
|
||||
import org.eclipse.cdt.core.ErrorParserManager;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.IConsoleParser;
|
||||
|
@ -542,6 +542,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
|
|||
boolean isChanged = false;
|
||||
|
||||
List<String> languageIds = getLanguageScope();
|
||||
|
||||
if (languageIds != null) {
|
||||
monitor.beginTask(ManagedMakeMessages.getResourceString("AbstractBuiltinSpecsDetector.ScannerDiscoveryTaskTitle"), //$NON-NLS-1$
|
||||
TICKS_REMOVE_MARKERS + languageIds.size()*TICKS_RUN_FOR_ONE_LANGUAGE + TICKS_SERIALIZATION);
|
||||
|
@ -656,7 +657,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
|
|||
}
|
||||
console.start(currentProject);
|
||||
|
||||
ICommandLauncher launcher = new CommandLauncher();
|
||||
ICommandLauncher launcher = CommandLauncherManager.getInstance().getCommandLauncher(currentCfgDescription);
|
||||
launcher.setProject(currentProject);
|
||||
|
||||
IPath program = new Path(""); //$NON-NLS-1$
|
||||
|
@ -765,7 +766,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
|
|||
// so collect them to save later when output finishes
|
||||
if (entries != null) {
|
||||
for (ICLanguageSettingEntry entry : entries) {
|
||||
if (!detectedSettingEntries.contains(entry)) {
|
||||
if (detectedSettingEntries != null && !detectedSettingEntries.contains(entry)) {
|
||||
detectedSettingEntries.add(entry);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.eclipse.cdt.core.settings.model.ICSourceEntry;
|
|||
import org.eclipse.cdt.core.settings.model.extension.CBuildData;
|
||||
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.BuildException;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuilder;
|
||||
|
@ -632,6 +633,13 @@ public class TestConfiguration implements IConfiguration {
|
|||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IOptionalBuildProperties getOptionalBuildProperties() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IResource getOwner() { return null; }
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
package org.eclipse.cdt.managedbuilder.ui.tests.util;
|
||||
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IBuildPropertyValue;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IBuildObjectProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||
import org.eclipse.cdt.managedbuilder.core.IConfigurationNameProvider;
|
||||
|
@ -76,6 +77,8 @@ public class TestProjectType implements IProjectType {
|
|||
public void setVersion(Version version) {}
|
||||
@Override
|
||||
public IBuildObjectProperties getBuildProperties() { return null; }
|
||||
@Override
|
||||
public IOptionalBuildProperties getOptionalBuildProperties() { return null; }
|
||||
|
||||
@Override
|
||||
public IBuildPropertyValue getBuildArtefactType() {
|
||||
|
|
|
@ -18,7 +18,7 @@ import org.eclipse.cdt.codan.core.cxx.externaltool.ConfigurationSettings;
|
|||
import org.eclipse.cdt.codan.core.cxx.externaltool.InvocationFailure;
|
||||
import org.eclipse.cdt.codan.core.cxx.externaltool.InvocationParameters;
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CommandLauncher;
|
||||
import org.eclipse.cdt.core.CommandLauncherManager;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.IConsoleParser;
|
||||
import org.eclipse.cdt.core.resources.IConsole;
|
||||
|
@ -85,7 +85,7 @@ public class ExternalToolInvoker {
|
|||
final OutputStream out = sniffer.getOutputStream();
|
||||
final OutputStream err = sniffer.getErrorStream();
|
||||
try {
|
||||
ICommandLauncher launcher = new CommandLauncher();
|
||||
ICommandLauncher launcher = CommandLauncherManager.getInstance().getCommandLauncher();
|
||||
launcher.showCommand(true);
|
||||
launcher.setProject(project);
|
||||
Process p = launcher.execute(commandPath, commandArgs, commandEnv, workingDirectory, new SubProgressMonitor(monitor, 50));
|
||||
|
|
|
@ -221,9 +221,11 @@ public class CModelMock {
|
|||
*/
|
||||
public static class DummyCConfigurationDescription implements ICConfigurationDescription {
|
||||
private String id;
|
||||
private ICProjectDescription projectDescription;
|
||||
|
||||
public DummyCConfigurationDescription(String id) {
|
||||
this.id = id;
|
||||
this.projectDescription = new DummyCProjectDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -302,7 +304,7 @@ public class CModelMock {
|
|||
|
||||
@Override
|
||||
public ICProjectDescription getProjectDescription() {
|
||||
return null;
|
||||
return projectDescription;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CommandLauncherManager;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
import org.eclipse.cdt.internal.core.XmlUtil;
|
||||
|
@ -146,6 +147,9 @@ public class LanguageSettingsSerializableProvider extends LanguageSettingsBasePr
|
|||
List<? extends ICLanguageSettingEntry> entries) {
|
||||
String rcProjectPath = rc!=null ? rc.getProjectRelativePath().toString() : null;
|
||||
fStorage.setSettingEntries(rcProjectPath, languageId, entries);
|
||||
if (cfgDescription != null) {
|
||||
CommandLauncherManager.getInstance().setLanguageSettingEntries(cfgDescription.getProjectDescription().getProject(), entries);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -168,6 +172,10 @@ public class LanguageSettingsSerializableProvider extends LanguageSettingsBasePr
|
|||
}
|
||||
}
|
||||
|
||||
if (cfgDescription != null) {
|
||||
entries = CommandLauncherManager.getInstance().getLanguageSettingEntries(cfgDescription.getProjectDescription().getProject(), entries);
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CommandLauncherManager;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ICListenerAgent;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsBroadcastingProvider;
|
||||
import org.eclipse.cdt.core.language.settings.providers.ILanguageSettingsChangeEvent;
|
||||
|
@ -178,6 +179,10 @@ public class LanguageSettingsProvidersSerializer {
|
|||
public List<ICLanguageSettingEntry> getSettingEntries(ICConfigurationDescription cfgDescription, IResource rc, String languageId) {
|
||||
ILanguageSettingsProvider rawProvider = getRawProvider();
|
||||
List<ICLanguageSettingEntry> entries = rawProvider!=null ? rawProvider.getSettingEntries(cfgDescription, rc, languageId) : null;
|
||||
if (cfgDescription != null) {
|
||||
IProject project = cfgDescription.getProjectDescription().getProject();
|
||||
entries = CommandLauncherManager.getInstance().getLanguageSettingEntries(project, entries);
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
@ -1456,6 +1461,10 @@ public class LanguageSettingsProvidersSerializer {
|
|||
return getSettingEntriesUpResourceTree(provider, cfgDescription, parentFolder, languageId);
|
||||
}
|
||||
// if out of parent resources - get default entries
|
||||
entries = getSettingEntriesPooled(provider, cfgDescription, null, languageId);
|
||||
if (entries != null) {
|
||||
return entries;
|
||||
}
|
||||
entries = getSettingEntriesPooled(provider, null, null, languageId);
|
||||
if (entries != null) {
|
||||
return entries;
|
||||
|
|
|
@ -692,6 +692,7 @@
|
|||
<extension-point id="ProblemMarkerFilter" name="%problemMarkerFilter.name" schema="schema/ProblemMarkerFilter.exsd"/>
|
||||
<extension-point id="buildConfigProvider" name="buildConfigProvider" schema="schema/buildConfigProvider.exsd"/>
|
||||
<extension-point id="toolChainProvider" name="Tool Chain Provider" schema="schema/toolChainProvider.exsd"/>
|
||||
<extension-point id="CommandLauncherFactory" name="CommandLauncherFactory" schema="schema/CommandLauncherFactory.exsd"/>
|
||||
|
||||
<extension
|
||||
point="org.eclipse.cdt.core.templateProcessTypes">
|
||||
|
|
128
core/org.eclipse.cdt.core/schema/CommandLauncherFactory.exsd
Normal file
128
core/org.eclipse.cdt.core/schema/CommandLauncherFactory.exsd
Normal file
|
@ -0,0 +1,128 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!-- Schema file written by PDE -->
|
||||
<schema targetNamespace="org.eclipse.cdt.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.schema plugin="org.eclipse.cdt.core" id="CommandLauncherFactory" name="CommandLauncherFactory"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
This extension point is used to contribute a Command Launcher factory to CDT. A Command Launcher factory creates a Command Launcher for running commands.
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<element name="extension">
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.element />
|
||||
</appInfo>
|
||||
</annotation>
|
||||
<complexType>
|
||||
<sequence minOccurs="1" maxOccurs="unbounded">
|
||||
<element ref="factory"/>
|
||||
</sequence>
|
||||
<attribute name="point" type="string" use="required">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="id" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="name" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute translatable="true"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<element name="factory">
|
||||
<complexType>
|
||||
<attribute name="id" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="priority" type="string" use="default" value="0">
|
||||
<annotation>
|
||||
<documentation>
|
||||
Integer priority of factory. Default is 0. Use higher values if you want to override an existing factory.
|
||||
</documentation>
|
||||
</annotation>
|
||||
</attribute>
|
||||
<attribute name="class" type="string">
|
||||
<annotation>
|
||||
<documentation>
|
||||
Command Launcher factory class that implements org.eclipse.cdt.core.ICommandLauncherFactory.
|
||||
</documentation>
|
||||
<appInfo>
|
||||
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.core.ICommandLauncherFactory"/>
|
||||
</appInfo>
|
||||
</annotation>
|
||||
</attribute>
|
||||
</complexType>
|
||||
</element>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="since"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
CDT 9.4.0
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="examples"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter extension point usage example here.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="apiinfo"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
Plug-ins that want to extend this extension point must implement <samp>org.eclipse.cdt.core.ICommandLauncherFactory</samp> interface.
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="implementation"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
[Enter information about supplied implementation of this extension point.]
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
<annotation>
|
||||
<appInfo>
|
||||
<meta.section type="copyright"/>
|
||||
</appInfo>
|
||||
<documentation>
|
||||
Copyright (c) 2017 Red Hat Inc. and others.<br/>
|
||||
All rights reserved. This program and the accompanying materials<br/>
|
||||
are made available under the terms of the Eclipse Public License v1.0<br/>
|
||||
which accompanies this distribution, and is available at<br/>
|
||||
http://www.eclipse.org/legal/epl-v10.html<br/>
|
||||
</documentation>
|
||||
</annotation>
|
||||
|
||||
</schema>
|
|
@ -156,6 +156,17 @@ public class CCorePlugin extends Plugin {
|
|||
*/
|
||||
public static final String ERROR_PARSER_UNIQ_ID = PLUGIN_ID + "." + ERROR_PARSER_SIMPLE_ID; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Name of the extension point for contributing a Command Launcher factory
|
||||
* @since 6.3
|
||||
*/
|
||||
public static final String COMMAND_LAUNCHER_FACTORY_SIMPLE_ID = "CommandLauncherFactory"; //$NON-NLS-1$
|
||||
/**
|
||||
* Full unique name of the extension point for contributing a Command Launcher factory
|
||||
* @since 6.3
|
||||
*/
|
||||
public static final String COMMAND_LAUNCHER_FACTORY_UNIQ_ID = PLUGIN_ID + "." + COMMAND_LAUNCHER_FACTORY_SIMPLE_ID; //$NON-NLS-1$
|
||||
|
||||
// default store for pathentry
|
||||
public static final String DEFAULT_PATHENTRY_STORE_ID = PLUGIN_ID + ".cdtPathEntryStore"; //$NON-NLS-1$
|
||||
|
||||
|
|
|
@ -0,0 +1,288 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Red Hat Inc. and others.
|
||||
* 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:
|
||||
* Red Hat Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IConfigurationElement;
|
||||
import org.eclipse.core.runtime.IExtension;
|
||||
import org.eclipse.core.runtime.IExtensionPoint;
|
||||
import org.eclipse.core.runtime.IExtensionRegistry;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
/**
|
||||
* @since 6.3
|
||||
*/
|
||||
public class CommandLauncherManager {
|
||||
|
||||
private static CommandLauncherManager instance;
|
||||
|
||||
private List<ICommandLauncherFactory> factories = new ArrayList<>();
|
||||
private Map<ICommandLauncherFactory, Integer> priorityMapping = new HashMap<>();
|
||||
|
||||
private CommandLauncherManager() {
|
||||
loadCommandLauncherFactoryExtensions();
|
||||
}
|
||||
|
||||
public static synchronized CommandLauncherManager getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new CommandLauncherManager();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public ICommandLauncher getCommandLauncher() {
|
||||
return new CommandLauncherWrapper(this);
|
||||
}
|
||||
|
||||
|
||||
private class CommandLauncherWrapper implements ICommandLauncher {
|
||||
|
||||
private ICommandLauncher launcher;
|
||||
private IProject fProject;
|
||||
private boolean fShowCommand;
|
||||
private String fErrorMessage;
|
||||
private CommandLauncherManager manager;
|
||||
|
||||
public CommandLauncherWrapper(CommandLauncherManager manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProject(IProject project) {
|
||||
if (launcher != null) {
|
||||
launcher.setProject(project);
|
||||
} else {
|
||||
fProject = project;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProject getProject() {
|
||||
if (launcher != null) {
|
||||
return launcher.getProject();
|
||||
}
|
||||
return fProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCommand(boolean show) {
|
||||
if (launcher != null) {
|
||||
launcher.showCommand(show);
|
||||
} else {
|
||||
fShowCommand = show;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage() {
|
||||
if (launcher != null) {
|
||||
return launcher.getErrorMessage();
|
||||
}
|
||||
return fErrorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorMessage(String error) {
|
||||
if (launcher != null) {
|
||||
launcher.setErrorMessage(error);
|
||||
} else {
|
||||
fErrorMessage = error;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getCommandArgs() {
|
||||
if (launcher != null) {
|
||||
return launcher.getCommandArgs();
|
||||
}
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getEnvironment() {
|
||||
if (launcher != null) {
|
||||
return launcher.getEnvironment();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandLine() {
|
||||
if (launcher != null) {
|
||||
return launcher.getCommandLine();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process execute(IPath commandPath, String[] args, String[] env, IPath workingDirectory,
|
||||
IProgressMonitor monitor) throws CoreException {
|
||||
if (launcher == null) {
|
||||
launcher = manager.getCommandLauncher(fProject);
|
||||
launcher.setProject(fProject);
|
||||
launcher.showCommand(fShowCommand);
|
||||
launcher.setErrorMessage(fErrorMessage);
|
||||
}
|
||||
return launcher.execute(commandPath, args, env, workingDirectory, monitor);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public int waitAndRead(OutputStream out, OutputStream err) {
|
||||
if (launcher != null) {
|
||||
return launcher.waitAndRead(out, err);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int waitAndRead(OutputStream output, OutputStream err, IProgressMonitor monitor) {
|
||||
if (launcher != null) {
|
||||
return launcher.waitAndRead(output, err, monitor);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a command launcher.
|
||||
*
|
||||
* @param project - IProject to determine launcher for.
|
||||
* @return an ICommandLauncher for running commands
|
||||
*/
|
||||
public ICommandLauncher getCommandLauncher(IProject project) {
|
||||
// loop through list of factories and return launcher returned with
|
||||
// highest priority
|
||||
int highestPriority = -1;
|
||||
ICommandLauncher bestLauncher = null;
|
||||
for (ICommandLauncherFactory factory : factories) {
|
||||
ICommandLauncher launcher = factory.getCommandLauncher(project);
|
||||
if (launcher != null) {
|
||||
if (priorityMapping.get(factory) > highestPriority) {
|
||||
bestLauncher = launcher;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestLauncher != null) {
|
||||
return bestLauncher;
|
||||
}
|
||||
// default to local CommandLauncher
|
||||
return new CommandLauncher();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a command launcher.
|
||||
*
|
||||
* @param cfgd - ICConfigurationDescription to get command launcher for.
|
||||
* @return an ICommandLauncher for running commands
|
||||
*/
|
||||
public ICommandLauncher getCommandLauncher(ICConfigurationDescription cfgd) {
|
||||
// loop through list of factories and return launcher returned with
|
||||
// highest priority
|
||||
int highestPriority = -1;
|
||||
ICommandLauncher bestLauncher = null;
|
||||
for (ICommandLauncherFactory factory : factories) {
|
||||
ICommandLauncher launcher = factory.getCommandLauncher(cfgd);
|
||||
if (launcher != null) {
|
||||
if (priorityMapping.get(factory) > highestPriority) {
|
||||
bestLauncher = launcher;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestLauncher != null) {
|
||||
return bestLauncher;
|
||||
}
|
||||
// default to local CommandLauncher
|
||||
return new CommandLauncher();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load command launcher factory contributed extensions from extension registry.
|
||||
*
|
||||
*/
|
||||
private void loadCommandLauncherFactoryExtensions() {
|
||||
IExtensionRegistry registry = Platform.getExtensionRegistry();
|
||||
IExtensionPoint extension = registry.getExtensionPoint(CCorePlugin.PLUGIN_ID, CCorePlugin.COMMAND_LAUNCHER_FACTORY_SIMPLE_ID);
|
||||
if (extension != null) {
|
||||
IExtension[] extensions = extension.getExtensions();
|
||||
for (IExtension ext : extensions) {
|
||||
try {
|
||||
IConfigurationElement element[] = ext.getConfigurationElements();
|
||||
for (IConfigurationElement element2 : element) {
|
||||
if (element2.getName().equalsIgnoreCase("factory")) { //$NON-NLS-1$
|
||||
ICommandLauncherFactory factory = (ICommandLauncherFactory) element2.createExecutableExtension("class"); //$NON-NLS-1$
|
||||
String priorityAttr = element2.getAttribute("priority"); //$NON-NLS-1$
|
||||
int priority = Integer.valueOf(0);
|
||||
if (priorityAttr != null) {
|
||||
try {
|
||||
priority = Integer.valueOf(priorityAttr);
|
||||
} catch (NumberFormatException e) {
|
||||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
factories.add(factory);
|
||||
priorityMapping.put(factory, priority);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CCorePlugin.log("Cannot load CommandLauncherFactory extension " + ext.getUniqueIdentifier(), e); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ICommandLauncherFactory getBestFactory(IProject project) {
|
||||
// loop through list of factories and return launcher returned with
|
||||
// highest priority
|
||||
int highestPriority = -1;
|
||||
ICommandLauncherFactory bestLauncherFactory = null;
|
||||
for (ICommandLauncherFactory factory : factories) {
|
||||
ICommandLauncher launcher = factory.getCommandLauncher(project);
|
||||
if (launcher != null) {
|
||||
if (priorityMapping.get(factory) > highestPriority) {
|
||||
bestLauncherFactory = factory;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestLauncherFactory;
|
||||
}
|
||||
|
||||
public void setLanguageSettingEntries(IProject project, List<? extends ICLanguageSettingEntry> entries) {
|
||||
ICommandLauncherFactory factory = getBestFactory(project);
|
||||
if (factory != null) {
|
||||
factory.registerLanguageSettingEntries(project, entries);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ICLanguageSettingEntry> getLanguageSettingEntries(IProject project, List<ICLanguageSettingEntry> entries) {
|
||||
List<ICLanguageSettingEntry> verifiedEntries = entries;
|
||||
ICommandLauncherFactory factory = getBestFactory(project);
|
||||
if (factory != null) {
|
||||
verifiedEntries = factory.verifyLanguageSettingEntries(project, entries);
|
||||
}
|
||||
return verifiedEntries;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Red Hat Inc. and others.
|
||||
* 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:
|
||||
* Red Hat Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
|
||||
/**
|
||||
* @since 6.3
|
||||
*/
|
||||
public interface ICommandLauncherFactory {
|
||||
|
||||
/**
|
||||
* Get a Command Launcher for a project (based on active configuration)
|
||||
* @param project - IProject to get command launcher for
|
||||
* @return ICommandLauncher
|
||||
*/
|
||||
public ICommandLauncher getCommandLauncher(IProject project);
|
||||
|
||||
/**
|
||||
* Get a Command Launcher for a build configuration descriptor
|
||||
* @param cfgd - ICConfigurationDescription to get command launcher for
|
||||
* @return ICommandLauncher
|
||||
*/
|
||||
public ICommandLauncher getCommandLauncher(ICConfigurationDescription cfgd);
|
||||
|
||||
/**
|
||||
* Register language setting entries for a project
|
||||
* @param project - IProject used in obtaining language setting entries
|
||||
* @param entries - List of language setting entries
|
||||
*/
|
||||
public void registerLanguageSettingEntries(IProject project, List<? extends ICLanguageSettingEntry> entries);
|
||||
|
||||
/**
|
||||
* Verify language setting entries for a project and change any entries that
|
||||
* have been copied to a local location
|
||||
* @param project - IProject used in obtaining language setting entries
|
||||
* @param entries - List of language setting entries
|
||||
* @return modified List of language setting entries
|
||||
*/
|
||||
public List<ICLanguageSettingEntry> verifyLanguageSettingEntries(IProject project, List<ICLanguageSettingEntry> entries);
|
||||
|
||||
}
|
|
@ -217,14 +217,18 @@ public class ProcessClosure {
|
|||
fProcess.destroy();
|
||||
fProcess = null;
|
||||
}
|
||||
if (fOutputReader != null) {
|
||||
if (!fOutputReader.finished()) {
|
||||
fOutputReader.waitFor();
|
||||
}
|
||||
fOutputReader.close();
|
||||
}
|
||||
if (fErrorReader != null) {
|
||||
if (!fErrorReader.finished()) {
|
||||
fErrorReader.waitFor();
|
||||
}
|
||||
fOutputReader.close();
|
||||
fErrorReader.close();
|
||||
}
|
||||
fOutputReader = null;
|
||||
fErrorReader = null;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.core.resources.IResource;
|
|||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.jface.layout.PixelConverter;
|
||||
import org.eclipse.jface.viewers.IDecoration;
|
||||
import org.eclipse.jface.viewers.ITreeContentProvider;
|
||||
import org.eclipse.jface.viewers.TreeViewer;
|
||||
|
@ -39,6 +40,7 @@ import org.eclipse.swt.events.PaintListener;
|
|||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
|
@ -375,7 +377,7 @@ public class LanguageSettingsEntriesTab extends AbstractCPropertyTab {
|
|||
*/
|
||||
private void createTreeForEntries(Composite parent) {
|
||||
treeEntries = new Tree(parent, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
|
||||
treeEntries.setLayoutData(new GridData(GridData.FILL_VERTICAL));
|
||||
treeEntries.setLayoutData(new GridData(GridData.FILL_VERTICAL | GridData.GRAB_HORIZONTAL));
|
||||
treeEntries.setHeaderVisible(true);
|
||||
treeEntries.setLinesVisible(true);
|
||||
|
||||
|
@ -383,13 +385,14 @@ public class LanguageSettingsEntriesTab extends AbstractCPropertyTab {
|
|||
treeEntries.addPaintListener(new PaintListener() {
|
||||
@Override
|
||||
public void paintControl(PaintEvent e) {
|
||||
int x = treeEntries.getClientArea().width;
|
||||
if (treeCol.getWidth() != x)
|
||||
treeCol.setWidth(x);
|
||||
Point p = treeEntries.computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
||||
if (treeCol.getWidth() != p.x)
|
||||
treeCol.setWidth(p.x);
|
||||
}
|
||||
});
|
||||
|
||||
treeCol.setText(Messages.LanguageSettingsProviderTab_SettingEntries);
|
||||
|
||||
treeCol.setWidth(200);
|
||||
treeCol.setResizable(false);
|
||||
treeCol.setToolTipText(Messages.LanguageSettingsProviderTab_SettingEntriesTooltip);
|
||||
|
|
BIN
doc/org.eclipse.cdt.doc.user/images/prop_container.png
Normal file
BIN
doc/org.eclipse.cdt.doc.user/images/prop_container.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
BIN
doc/org.eclipse.cdt.doc.user/images/prop_datavolumes.png
Normal file
BIN
doc/org.eclipse.cdt.doc.user/images/prop_datavolumes.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
|
@ -178,6 +178,7 @@ and, moreover, change the visibility of other property pages.
|
|||
<li>Settings page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_build_settings_tool.htm"> Tool Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_container.htm">Container Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_steps.htm"> Build Steps tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_artifact.htm"> Build Artifact tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_binparser.htm">Binary Parsers tab</a>
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
<li>Settings page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_build_settings_tool.htm"> Tool Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_container.htm">Container Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_steps.htm"> Build Steps tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_artifact.htm"> Build Artifact tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_binparser.htm">Binary Parsers tab</a>
|
||||
|
|
|
@ -85,6 +85,7 @@ symbols of the object file using the C/C++ Projects view.</p>
|
|||
<li>Settings page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_build_settings_tool.htm"> Tool Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_container.htm">Container Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_steps.htm"> Build Steps tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_artifact.htm"> Build Artifact tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_binparser.htm">Binary Parsers tab</a>
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>C/C++ Project Properties, Build, Settings, Container Settings</title>
|
||||
<link rel="stylesheet" type="text/css" href="../help.css">
|
||||
</head>
|
||||
<body>
|
||||
<div role="main"><h1>C/C++ Project Properties, Build, Settings, Container Settings</h1>
|
||||
<p>Use the <strong>Container Settings</strong> properties tab to
|
||||
specify options for building the project in a Docker Container. This properties tab is
|
||||
provided with the optional Docker C/C++ Launch feature. By default,
|
||||
project configurations will build locally, however, if you want to have a particular
|
||||
configuration build the project in a Container, use the enablement check-box.
|
||||
After enabling building in a Container, you need to select an active Docker Connection and
|
||||
a down-loaded Image in that Connection to run the build in. The Image must have whatever
|
||||
tools are necessary to perform the build already installed. Docker Images will be linux-based so the build
|
||||
will use linux appropriate toolsets and create a linux-compatible executable.</p>
|
||||
<p>By default, the C/C++ project and all dependent project contents will be mounted
|
||||
into the Container where the build is occurring. This allows the build to find project source and
|
||||
header files. If additional host directories are needed to
|
||||
build the project (e.g. a local header file directory that is not part of an
|
||||
installed package in the Docker Image), such directories can be added to the Data Volumes table and they
|
||||
will be mounted in the Container before the build occurs. If the Docker daemon is running locally, this
|
||||
will be a simple mount. If the Docker daemon is remote,
|
||||
mounting will involve automatically copying the directory contents over to the Container since system mounting cannot
|
||||
occur across machines.</p>
|
||||
<p>To accommodate indexing, build-specs discovery will be performed in the Docker Container. Directories found
|
||||
by specs detection will be copied locally for use by the indexer. This copying process also occurs for any
|
||||
header file directories discovered while building. The
|
||||
header files are stored within the workspace and are only uploaded once per Docker Image. These header files
|
||||
can be removed from the Preferences page if, for example, the project no longer needs to build/index for that
|
||||
particular Docker Image.</p>
|
||||
|
||||
<p><img img="" src="../images/prop_container.png"
|
||||
alt="C/C++ Project Properties, Build, Settings, Container Settings"></p>
|
||||
|
||||
|
||||
<table cellpadding="5" cellspacing="0" border="1" width="600px" bordercolor="#DDDDDD" >
|
||||
<caption><strong>Container settings options</strong></caption>
|
||||
<colgroup>
|
||||
<col width="30%" valign="top" >
|
||||
<col width="70%" valign="top" >
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr style="text-align:center;">
|
||||
<th id="group"><strong>Group</strong></th>
|
||||
<th id="description"><strong>Description</strong></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Configuration</strong></td>
|
||||
<td headers="description"><a href="cdt_u_prop_all.htm">Click here for a description.</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Manage Configurations...</strong></td>
|
||||
<td headers="description"><a href="cdt_u_prop_all.htm">Click here for a description.</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Build inside Docker Image</strong> (check-box)</td>
|
||||
<td headers="description">Enables the build to occur inside a Container.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Connection</strong></td>
|
||||
<td headers="description">Pull-down that contains a list of known Docker daemon connections to run the build in if enablement button is checked.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Image</strong></td>
|
||||
<td headers="description">Pull-down that contains Docker Image names to use to create the Container the build will run in. This list is enabled by
|
||||
a Docker Connection selection and the enablement check-box.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Data Volumes</strong></td>
|
||||
<td headers="description">Optional list of directories to mount into the Container prior to building. By default, the C/C++ project and any refererenced
|
||||
projects are mounted automatically in the Container. Directories can be added, edited, or removed using the buttons to the
|
||||
right of the list.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Add...</strong></td>
|
||||
<td headers="description">Button to bring up the <a href="cdt_u_prop_data_volumes.htm">Data Volume</a> dialog for specifying a
|
||||
data volume to mount in the Docker Container. This usually involves selecting a directory from the local system. Once finished,
|
||||
the mount will be shown in the Data Volumes list.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Edit...</strong></td>
|
||||
<td headers="description">Button to edit the currently selected data volume in the Data Volumes list.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Remove</strong></td>
|
||||
<td headers="description">Button to remove the currently selected data volume(s) in the Data Volumes list.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
<p><strong>Available for:</strong> CDT projects.</p>
|
||||
|
||||
<p><img src="../images/ngtasks.gif" alt="Related tasks"
|
||||
width="143" height="21">
|
||||
<br>
|
||||
</p>
|
||||
|
||||
|
||||
<p style="margin-top: 0pt; margin-bottom: 0pt;"><img
|
||||
src="../images/ngref.gif" alt="Related reference" width="143"
|
||||
height="21"><br>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_resource.htm">Project Properties, Resource page</a>
|
||||
<li><a href="cdt_u_prop_builders.htm">Project Properties, Builders page</a>
|
||||
<li><a href="cdt_u_prop_all.htm">Project Properties, common C/C++ Configurations handling</a>
|
||||
<ul style="list-style-type: disc">
|
||||
<li><a href="cdt_u_prop_manage_dialog.htm">Manage Configurations dialog</a>
|
||||
<li><a href="cdt_u_prop_manage_newdialog.htm">Create Configuration dialog</a>
|
||||
<li><a href="cdt_u_prop_manage_rendialog.htm">Rename Configuration dialog</a>
|
||||
</ul>
|
||||
<li><a href="cdt_u_prop_build.htm">Project Properties, C/C++ Build category</a>
|
||||
<ul style="list-style-type: disc">
|
||||
<li><a href="cdt_u_prop_build_discovery.htm">Discovery options page</a>
|
||||
<li><a href="cdt_u_prop_build_environment.htm">Environment page</a>
|
||||
<li>Settings page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_build_settings_tool.htm"> Tool Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_container.htm">ContainerSettings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_steps.htm"> Build Steps tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_artifact.htm"> Build Artifact tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_binparser.htm">Binary Parsers tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_errparser.htm">Error Parsers tab</a>
|
||||
</ul>
|
||||
<li><a href="cdt_u_prop_build_toolchain.htm">Tool chain editor page</a>
|
||||
<li><a href="cdt_u_prop_build_variables.htm">Variables page</a>
|
||||
</ul>
|
||||
<li>Project Properties, <a href="cdt_u_prop_general.htm">C/C++ General category</a>
|
||||
<ul style="list-style-type: disc">
|
||||
<li><a href="cdt_u_prop_general_doc.htm">Documentation page</a>
|
||||
<li><a href="cdt_u_prop_general_exp.htm">Export Settings page</a>
|
||||
<!--ul>
|
||||
<li><a href="cdt_u_prop_general_exp_inc.htm">Includes tab</a>
|
||||
<li><a href="cdt_u_prop_general_exp_sym.htm">Symbols tab</a>
|
||||
<li><a href="cdt_u_prop_general_exp_lib.htm">Libraries tab</a>
|
||||
<li><a href="cdt_u_prop_general_exp_libpath.htm">Libraries path tab</a>
|
||||
</ul-->
|
||||
<li><a href="cdt_u_prop_general_typ.htm">File Types page</a>
|
||||
<li><a href="cdt_u_prop_general_idx.htm">Indexer page</a>
|
||||
<li><a href="cdt_u_prop_general_lng.htm">Language Mapping page</a>
|
||||
<li>Paths and Symbols page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_general_pns_inc.htm">Includes tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_sym.htm">Symbols tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_lib.htm">Libraries tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_libpath.htm">Libraries path tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_src.htm">Source Location tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_out.htm">Output Location tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_ref.htm">References tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_hier.htm">Data Hierarchy tab</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<li><a href="cdt_u_prop_ref.htm">C/C++ Project Properties, Project References page</a>
|
||||
<li><a href="cdt_u_prop_rundebug.htm">C/C++ Project Properties, Run/Debug Settings page</a>
|
||||
</ul>
|
||||
</p>
|
||||
<hr >
|
||||
<p><img src="../images/intl_07.gif" ALT="Intel Copyright Statement" ></p>
|
||||
|
||||
</div></body>
|
||||
</html>
|
|
@ -88,6 +88,7 @@ build output log.</p>
|
|||
<li>Settings page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_build_settings_tool.htm"> Tool Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_container.htm">Container Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_steps.htm"> Build Steps tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_artifact.htm"> Build Artifact tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_binparser.htm">Binary Parsers tab</a>
|
||||
|
|
|
@ -99,6 +99,7 @@ including pre-build or post-build steps.<br>
|
|||
<li>Settings page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_build_settings_tool.htm"> Tool Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_container.htm">Container Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_steps.htm"> Build Steps tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_artifact.htm"> Build Artifact tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_binparser.htm">Binary Parsers tab</a>
|
||||
|
|
|
@ -65,6 +65,7 @@ Use the <strong>Tool Settings</strong> properties tab to customize the tools and
|
|||
<li>Settings page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_build_settings_tool.htm"> Tool Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_container.htm">Container Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_steps.htm"> Build Steps tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_artifact.htm"> Build Artifact tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_binparser.htm">Binary Parsers tab</a>
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>C/C++ Project Properties, Build, Settings, Data Volume Dialog</title>
|
||||
<link rel="stylesheet" type="text/css" href="../help.css">
|
||||
</head>
|
||||
<body>
|
||||
<div role="main"><h1>C/C++ Project Properties, Build, Settings, Data Volume Dialog</h1>
|
||||
<p>The <strong>Data Volume</strong> dialog is brought up when a user selects the
|
||||
Add... button from the Container Settings Data Volumes table. Like the properties tab,
|
||||
this dialog is only available if the optional Docker C/C++ Launch feature is installed.</p>
|
||||
<p>Data volumes can be specified from the local file system, another Container, or created
|
||||
as empty, in the Docker Container where the build will be performed.</p>
|
||||
|
||||
<p><img img="" src="../images/prop_datavolumes.png"
|
||||
alt="C/C++ Project Properties, Build, Settings, Data Volume Dialog"></p>
|
||||
|
||||
|
||||
<table cellpadding="5" cellspacing="0" border="1" width="600px" bordercolor="#DDDDDD" >
|
||||
<caption><strong>Data Volume Dialog</strong></caption>
|
||||
<colgroup>
|
||||
<col width="30%" valign="top" >
|
||||
<col width="70%" valign="top" >
|
||||
</colgroup>
|
||||
<tbody>
|
||||
<tr style="text-align:center;">
|
||||
<th id="group"><strong>Group</strong></th>
|
||||
<th id="description"><strong>Description</strong></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Container path</strong></td>
|
||||
<td headers="description">This defines the path that the data volume will be mounted as within the Docker Container.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>No external mount</strong></td>
|
||||
<td headers="description">Use this option to create a new empty directory in the Docker Container that is not mounted
|
||||
to any external directory.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Mount a host directory or host file</strong></td>
|
||||
<td headers="description">Use this to specify a local system path that will be mounted in the Docker Container with
|
||||
the given Container path.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Path</strong></td>
|
||||
<td headers="description">This is the local path of the directory or file to mount in the Docker Container. This
|
||||
can be specified manually or via the Directory/File buttons.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Directory</strong></td>
|
||||
<td headers="description">Use this button to bring up a local directory browser to fill in the Path text field
|
||||
when mounting a local directory in the Docker Container.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>File</strong></td>
|
||||
<td headers="description">Use this button to bring up a local file browser to fill in the Path text field
|
||||
when mounting a local file in the Docker Container.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Read-only access</strong></td>
|
||||
<td headers="description">Check this button if mounting a local directory or file and you do not wish the
|
||||
Container to modify it.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Mount a data volume container</strong></td>
|
||||
<td headers="description">Check this button if mounting the volumes of another Container.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td headers="group"><strong>Container</strong></td>
|
||||
<td headers="description">This is a pull-down containing actively running Containers to use data volumes from if
|
||||
the option above is chosen.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
<p><strong>Available for:</strong> CDT projects.</p>
|
||||
|
||||
<p><img src="../images/ngtasks.gif" alt="Related tasks"
|
||||
width="143" height="21">
|
||||
<br>
|
||||
</p>
|
||||
|
||||
|
||||
<p style="margin-top: 0pt; margin-bottom: 0pt;"><img
|
||||
src="../images/ngref.gif" alt="Related reference" width="143"
|
||||
height="21"><br>
|
||||
|
||||
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_resource.htm">Project Properties, Resource page</a>
|
||||
<li><a href="cdt_u_prop_builders.htm">Project Properties, Builders page</a>
|
||||
<li><a href="cdt_u_prop_all.htm">Project Properties, common C/C++ Configurations handling</a>
|
||||
<ul style="list-style-type: disc">
|
||||
<li><a href="cdt_u_prop_manage_dialog.htm">Manage Configurations dialog</a>
|
||||
<li><a href="cdt_u_prop_manage_newdialog.htm">Create Configuration dialog</a>
|
||||
<li><a href="cdt_u_prop_manage_rendialog.htm">Rename Configuration dialog</a>
|
||||
</ul>
|
||||
<li><a href="cdt_u_prop_build.htm">Project Properties, C/C++ Build category</a>
|
||||
<ul style="list-style-type: disc">
|
||||
<li><a href="cdt_u_prop_build_discovery.htm">Discovery options page</a>
|
||||
<li><a href="cdt_u_prop_build_environment.htm">Environment page</a>
|
||||
<li>Settings page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_build_settings_tool.htm"> Tool Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_container.htm">ContainerSettings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_steps.htm"> Build Steps tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_artifact.htm"> Build Artifact tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_binparser.htm">Binary Parsers tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_errparser.htm">Error Parsers tab</a>
|
||||
</ul>
|
||||
<li><a href="cdt_u_prop_build_toolchain.htm">Tool chain editor page</a>
|
||||
<li><a href="cdt_u_prop_build_variables.htm">Variables page</a>
|
||||
</ul>
|
||||
<li>Project Properties, <a href="cdt_u_prop_general.htm">C/C++ General category</a>
|
||||
<ul style="list-style-type: disc">
|
||||
<li><a href="cdt_u_prop_general_doc.htm">Documentation page</a>
|
||||
<li><a href="cdt_u_prop_general_exp.htm">Export Settings page</a>
|
||||
<!--ul>
|
||||
<li><a href="cdt_u_prop_general_exp_inc.htm">Includes tab</a>
|
||||
<li><a href="cdt_u_prop_general_exp_sym.htm">Symbols tab</a>
|
||||
<li><a href="cdt_u_prop_general_exp_lib.htm">Libraries tab</a>
|
||||
<li><a href="cdt_u_prop_general_exp_libpath.htm">Libraries path tab</a>
|
||||
</ul-->
|
||||
<li><a href="cdt_u_prop_general_typ.htm">File Types page</a>
|
||||
<li><a href="cdt_u_prop_general_idx.htm">Indexer page</a>
|
||||
<li><a href="cdt_u_prop_general_lng.htm">Language Mapping page</a>
|
||||
<li>Paths and Symbols page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_general_pns_inc.htm">Includes tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_sym.htm">Symbols tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_lib.htm">Libraries tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_libpath.htm">Libraries path tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_src.htm">Source Location tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_out.htm">Output Location tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_ref.htm">References tab</a>
|
||||
<li><a href="cdt_u_prop_general_pns_hier.htm">Data Hierarchy tab</a>
|
||||
</ul>
|
||||
</ul>
|
||||
<li><a href="cdt_u_prop_ref.htm">C/C++ Project Properties, Project References page</a>
|
||||
<li><a href="cdt_u_prop_rundebug.htm">C/C++ Project Properties, Run/Debug Settings page</a>
|
||||
</ul>
|
||||
</p>
|
||||
<hr >
|
||||
<p><img src="../images/intl_07.gif" ALT="Intel Copyright Statement" ></p>
|
||||
|
||||
</div></body>
|
||||
</html>
|
|
@ -39,6 +39,7 @@ To select object properties, right click on object in view and select <strong>Pr
|
|||
<li>Settings page
|
||||
<ul>
|
||||
<li><a href="cdt_u_prop_build_settings_tool.htm"> Tool Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_container.htm">Container Settings tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_steps.htm"> Build Steps tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_artifact.htm"> Build Artifact tab</a>
|
||||
<li><a href="cdt_u_prop_build_settings_binparser.htm">Binary Parsers tab</a>
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %Plugin.name
|
||||
Bundle-SymbolicName: org.eclipse.cdt.docker.launcher;singleton:=true
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Version: 1.1.0.qualifier
|
||||
Bundle-Activator: org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin
|
||||
Bundle-Vendor: %Plugin.vendor
|
||||
Bundle-Localization: plugin
|
||||
|
@ -20,7 +20,14 @@ Require-Bundle: org.eclipse.ui,
|
|||
org.eclipse.cdt.debug.ui;bundle-version="7.5.0",
|
||||
org.eclipse.cdt.dsf.gdb;bundle-version="4.6.0",
|
||||
org.eclipse.cdt.dsf.gdb.ui;bundle-version="2.4.0",
|
||||
org.eclipse.core.variables
|
||||
org.eclipse.core.variables,
|
||||
org.eclipse.cdt.managedbuilder.ui,
|
||||
org.eclipse.cdt.managedbuilder.core,
|
||||
org.eclipse.core.databinding.observable,
|
||||
org.eclipse.core.databinding.beans,
|
||||
org.eclipse.jface.databinding,
|
||||
org.eclipse.core.databinding;bundle-version="1.6.0",
|
||||
org.eclipse.core.databinding.property;bundle-version="1.6.0"
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: org.eclipse.cdt.docker.launcher;x-internal:=true,
|
||||
|
|
BIN
launch/org.eclipse.cdt.docker.launcher/icons/error_obj.gif
Normal file
BIN
launch/org.eclipse.cdt.docker.launcher/icons/error_obj.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 339 B |
BIN
launch/org.eclipse.cdt.docker.launcher/icons/file_obj.gif
Normal file
BIN
launch/org.eclipse.cdt.docker.launcher/icons/file_obj.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 349 B |
BIN
launch/org.eclipse.cdt.docker.launcher/icons/folder_closed.gif
Normal file
BIN
launch/org.eclipse.cdt.docker.launcher/icons/folder_closed.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 219 B |
BIN
launch/org.eclipse.cdt.docker.launcher/icons/warning_obj.gif
Normal file
BIN
launch/org.eclipse.cdt.docker.launcher/icons/warning_obj.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 337 B |
|
@ -1,5 +1,5 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2015 Red Hat Inc. and others.
|
||||
# Copyright (c) 2015,2017 Red Hat Inc. and others.
|
||||
# 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
|
||||
|
@ -15,4 +15,10 @@ Delegate.desc=This launcher runs C/C++ applications in a specified Docker Contai
|
|||
must be set-up to supply the C/C++ application what it needs to run.
|
||||
LaunchConfigurationType.name=C/C++ Container Launcher
|
||||
Shortcut.label=C/C++ Container Application
|
||||
DockerLaunchPreferencePage.name=Docker Container Launch
|
||||
DockerLaunchPreferencePage.name=Docker Container
|
||||
DockerHeaderPreferencePage.name=Cached Headers
|
||||
ContainerCommandLauncherFactory.name=Container Command Launcher Factory
|
||||
Container.settings=Container Settings
|
||||
ContainerBuild.property.enablement=Container Build Enablement
|
||||
ContainerBuild.property.connection=Container Build Connection
|
||||
ContainerBuild.property.image=Container Build Image
|
||||
|
|
|
@ -65,6 +65,12 @@
|
|||
id="org.eclipse.cdt.docker.launcher.page1"
|
||||
name="%DockerLaunchPreferencePage.name">
|
||||
</page>
|
||||
<page
|
||||
category="org.eclipse.cdt.docker.launcher.page1"
|
||||
class="org.eclipse.cdt.internal.docker.launcher.ui.preferences.DockerHeaderPreferencePage"
|
||||
id="org.eclipse.cdt.docker.launcher.page2"
|
||||
name="%DockerHeaderPreferencePage.name">
|
||||
</page>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.launchConfigurationTabGroups">
|
||||
|
@ -88,5 +94,24 @@
|
|||
id="org.eclipse.cdt.docker.launcher.launchConfigurationTypeImage1">
|
||||
</launchConfigurationTypeImage>
|
||||
</extension>
|
||||
<extension
|
||||
id="CommandLauncherFactories"
|
||||
name="%ContainerCommandLauncherFactory.name"
|
||||
point="org.eclipse.cdt.core.CommandLauncherFactory">
|
||||
<factory
|
||||
id="ContainerCommandLauncherFactory"
|
||||
class="org.eclipse.cdt.docker.launcher.ContainerCommandLauncherFactory">
|
||||
</factory>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.cdt.ui.cPropertyTab">
|
||||
<tab
|
||||
class="org.eclipse.cdt.internal.docker.launcher.ContainerPropertyTab"
|
||||
icon="icons/repository-middle.gif"
|
||||
name="%Container.settings"
|
||||
parent="org.eclipse.cdt.managedbuilder.ui.properties.Page_BuildSettings"
|
||||
weight="020">
|
||||
</tab>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Red Hat Inc. and others.
|
||||
* 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:
|
||||
* Red Hat Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.docker.launcher;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.ICommandLauncherFactory;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.settings.model.CIncludePathEntry;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.core.settings.model.ICIncludePathEntry;
|
||||
import org.eclipse.cdt.core.settings.model.ICLanguageSettingEntry;
|
||||
import org.eclipse.cdt.internal.docker.launcher.ContainerCommandLauncher;
|
||||
import org.eclipse.cdt.internal.docker.launcher.Messages;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.linuxtools.docker.ui.launch.ContainerLauncher;
|
||||
|
||||
public class ContainerCommandLauncherFactory
|
||||
implements ICommandLauncherFactory {
|
||||
|
||||
@Override
|
||||
public ICommandLauncher getCommandLauncher(IProject project) {
|
||||
// check if container build enablement has been checked
|
||||
ICConfigurationDescription cfgd = CoreModel.getDefault()
|
||||
.getProjectDescription(project)
|
||||
.getActiveConfiguration();
|
||||
IConfiguration cfg = ManagedBuildManager
|
||||
.getConfigurationForDescription(cfgd);
|
||||
// TODO: figure out why this occurs
|
||||
if (cfg == null) {
|
||||
return null;
|
||||
}
|
||||
IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
|
||||
if (props != null) {
|
||||
String enablementProperty = props.getProperty(
|
||||
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
|
||||
if (enablementProperty != null) {
|
||||
boolean enableContainer = Boolean
|
||||
.parseBoolean(enablementProperty);
|
||||
// enablement has occurred, we can return a
|
||||
// ContainerCommandLauncher
|
||||
if (enableContainer) {
|
||||
return new ContainerCommandLauncher();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICommandLauncher getCommandLauncher(
|
||||
ICConfigurationDescription cfgd) {
|
||||
// check if container build enablement has been checked
|
||||
IConfiguration cfg = ManagedBuildManager
|
||||
.getConfigurationForDescription(cfgd);
|
||||
// TODO: figure out why this occurs
|
||||
if (cfg == null) {
|
||||
return null;
|
||||
}
|
||||
IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
|
||||
if (props != null) {
|
||||
String enablementProperty = props.getProperty(
|
||||
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
|
||||
if (enablementProperty != null) {
|
||||
boolean enableContainer = Boolean
|
||||
.parseBoolean(enablementProperty);
|
||||
// enablement has occurred, we can return a
|
||||
// ContainerCommandLauncher
|
||||
if (enableContainer) {
|
||||
return new ContainerCommandLauncher();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerLanguageSettingEntries(IProject project,
|
||||
List<? extends ICLanguageSettingEntry> langEntries) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<ICLanguageSettingEntry> entries = (List<ICLanguageSettingEntry>) langEntries;
|
||||
ICConfigurationDescription cfgd = CoreModel.getDefault()
|
||||
.getProjectDescription(project).getActiveConfiguration();
|
||||
IConfiguration cfg = ManagedBuildManager
|
||||
.getConfigurationForDescription(cfgd);
|
||||
IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
|
||||
if (props != null) {
|
||||
String enablementProperty = props.getProperty(
|
||||
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
|
||||
if (enablementProperty != null) {
|
||||
boolean enableContainer = Boolean
|
||||
.parseBoolean(enablementProperty);
|
||||
if (enableContainer) {
|
||||
String connectionName = props.getProperty(
|
||||
ContainerCommandLauncher.CONNECTION_ID);
|
||||
String imageName = props
|
||||
.getProperty(ContainerCommandLauncher.IMAGE_ID);
|
||||
if (connectionName == null || connectionName.isEmpty()
|
||||
|| imageName == null || imageName.isEmpty()) {
|
||||
DockerLaunchUIPlugin.logErrorMessage(
|
||||
Messages.ContainerCommandLauncher_invalid_values);
|
||||
return;
|
||||
}
|
||||
ContainerLauncher launcher = new ContainerLauncher();
|
||||
List<String> paths = new ArrayList<>();
|
||||
for (ICLanguageSettingEntry entry : entries) {
|
||||
if (entry instanceof ICIncludePathEntry) {
|
||||
paths.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
if (paths.size() > 0) {
|
||||
// Create a directory to put the header files for
|
||||
// the image. Use the connection name to form
|
||||
// the directory name as the connection may be
|
||||
// connected to a different repo using the same
|
||||
// image name.
|
||||
IPath pluginPath = Platform.getStateLocation(Platform
|
||||
.getBundle(DockerLaunchUIPlugin.PLUGIN_ID))
|
||||
.append("HEADERS"); //$NON-NLS-1$
|
||||
pluginPath.toFile().mkdir();
|
||||
pluginPath = pluginPath
|
||||
.append(getCleanName(connectionName));
|
||||
pluginPath.toFile().mkdir();
|
||||
// To allow the user to later manage the headers, store
|
||||
// the
|
||||
// real connection name in a file.
|
||||
IPath connectionNamePath = pluginPath.append(".name"); //$NON-NLS-1$
|
||||
File f = connectionNamePath.toFile();
|
||||
try {
|
||||
f.createNewFile();
|
||||
try (FileWriter writer = new FileWriter(f);
|
||||
BufferedWriter bufferedWriter = new BufferedWriter(
|
||||
writer);) {
|
||||
bufferedWriter.write(connectionName);
|
||||
bufferedWriter.newLine();
|
||||
} catch (IOException e) {
|
||||
DockerLaunchUIPlugin.log(e);
|
||||
return;
|
||||
}
|
||||
pluginPath = pluginPath
|
||||
.append(getCleanName(imageName));
|
||||
pluginPath.toFile().mkdir();
|
||||
// To allow the user to later manage the headers,
|
||||
// store the
|
||||
// real image name in a file.
|
||||
IPath imageNamePath = pluginPath.append(".name"); //$NON-NLS-1$
|
||||
f = imageNamePath.toFile();
|
||||
f.createNewFile();
|
||||
try (FileWriter writer = new FileWriter(f);
|
||||
BufferedWriter bufferedWriter = new BufferedWriter(
|
||||
writer);) {
|
||||
bufferedWriter.write(imageName);
|
||||
bufferedWriter.newLine();
|
||||
} catch (IOException e) {
|
||||
DockerLaunchUIPlugin.log(e);
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
DockerLaunchUIPlugin.log(e);
|
||||
return;
|
||||
}
|
||||
IPath hostDir = pluginPath;
|
||||
@SuppressWarnings("unused")
|
||||
int status = launcher.fetchContainerDirs(connectionName,
|
||||
imageName,
|
||||
paths, hostDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ICLanguageSettingEntry> verifyLanguageSettingEntries(
|
||||
IProject project, List<ICLanguageSettingEntry> entries) {
|
||||
if (entries == null) {
|
||||
return null;
|
||||
}
|
||||
ICConfigurationDescription cfgd = CoreModel.getDefault()
|
||||
.getProjectDescription(project).getActiveConfiguration();
|
||||
IConfiguration cfg = ManagedBuildManager
|
||||
.getConfigurationForDescription(cfgd);
|
||||
IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
|
||||
if (props != null) {
|
||||
String enablementProperty = props.getProperty(
|
||||
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
|
||||
if (enablementProperty != null) {
|
||||
boolean enableContainer = Boolean
|
||||
.parseBoolean(enablementProperty);
|
||||
if (enableContainer) {
|
||||
String connectionName = props.getProperty(
|
||||
ContainerCommandLauncher.CONNECTION_ID);
|
||||
String imageName = props
|
||||
.getProperty(ContainerCommandLauncher.IMAGE_ID);
|
||||
if (connectionName == null || connectionName.isEmpty()
|
||||
|| imageName == null || imageName.isEmpty()) {
|
||||
DockerLaunchUIPlugin.logErrorMessage(
|
||||
Messages.ContainerCommandLauncher_invalid_values);
|
||||
return entries;
|
||||
}
|
||||
|
||||
ContainerLauncher launcher = new ContainerLauncher();
|
||||
Set<String> copiedVolumes = launcher
|
||||
.getCopiedVolumes(connectionName, imageName);
|
||||
List<ICLanguageSettingEntry> newEntries = new ArrayList<>();
|
||||
IPath pluginPath = Platform.getStateLocation(
|
||||
Platform.getBundle(DockerLaunchUIPlugin.PLUGIN_ID));
|
||||
IPath hostDir = pluginPath.append("HEADERS") //$NON-NLS-1$
|
||||
.append(getCleanName(connectionName))
|
||||
.append(getCleanName(imageName));
|
||||
|
||||
for (ICLanguageSettingEntry entry : entries) {
|
||||
if (entry instanceof ICIncludePathEntry) {
|
||||
if (copiedVolumes
|
||||
.contains(((ICIncludePathEntry) entry)
|
||||
.getName().toString())) {
|
||||
// //$NON-NLS-2$
|
||||
IPath newPath = hostDir.append(entry.getName());
|
||||
CIncludePathEntry newEntry = new CIncludePathEntry(
|
||||
newPath.toString(),
|
||||
entry.getFlags());
|
||||
newEntries.add(newEntry);
|
||||
continue;
|
||||
} else {
|
||||
newEntries.add(entry);
|
||||
}
|
||||
} else {
|
||||
newEntries.add(entry);
|
||||
}
|
||||
}
|
||||
return newEntries;
|
||||
}
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
private String getCleanName(String name) {
|
||||
String cleanName = name.replace("unix:///", "unix_"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
cleanName = cleanName.replace("tcp://", "tcp_"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
return cleanName.replaceAll("[:/.]", "_"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2014, 2015 Red Hat.
|
||||
* 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:
|
||||
* Red Hat - Initial Contribution
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.docker.launcher;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
|
||||
/**
|
||||
* Base class for all model classes that need Databinding support
|
||||
*
|
||||
*/
|
||||
public abstract class BaseDatabindingModel {
|
||||
|
||||
private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener) {
|
||||
changeSupport.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener) {
|
||||
changeSupport.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||
changeSupport.addPropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
|
||||
changeSupport.removePropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
|
||||
changeSupport.firePropertyChange(propertyName, oldValue, newValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,429 @@
|
|||
package org.eclipse.cdt.internal.docker.launcher;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
|
||||
import org.eclipse.cdt.internal.core.ProcessClosure;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||
import org.eclipse.core.variables.VariablesPlugin;
|
||||
import org.eclipse.linuxtools.docker.ui.launch.ContainerLauncher;
|
||||
import org.eclipse.linuxtools.docker.ui.launch.IErrorMessageHolder;
|
||||
import org.eclipse.linuxtools.internal.docker.ui.launch.ContainerCommandProcess;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
import org.osgi.service.prefs.Preferences;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class ContainerCommandLauncher
|
||||
implements ICommandLauncher, IErrorMessageHolder {
|
||||
|
||||
public final static String CONTAINER_BUILD_ENABLED = DockerLaunchUIPlugin.PLUGIN_ID
|
||||
+ ".containerbuild.property.enablement"; //$NON-NLS-1$
|
||||
public final static String CONNECTION_ID = DockerLaunchUIPlugin.PLUGIN_ID
|
||||
+ ".containerbuild.property.connection"; //$NON-NLS-1$
|
||||
public final static String IMAGE_ID = DockerLaunchUIPlugin.PLUGIN_ID
|
||||
+ ".containerbuild.property.image"; //$NON-NLS-1$
|
||||
public final static String VOLUMES_ID = DockerLaunchUIPlugin.PLUGIN_ID
|
||||
+ ".containerbuild.property.volumes"; //$NON-NLS-1$
|
||||
public final static String SELECTED_VOLUMES_ID = DockerLaunchUIPlugin.PLUGIN_ID
|
||||
+ ".containerbuild.property.selectedvolumes"; //$NON-NLS-1$
|
||||
|
||||
public final static String VOLUME_SEPARATOR_REGEX = "[|]"; //$NON-NLS-1$
|
||||
|
||||
private IProject fProject;
|
||||
private Process fProcess;
|
||||
private boolean fShowCommand;
|
||||
private String fErrorMessage;
|
||||
private Properties fEnvironment;
|
||||
|
||||
private String[] commandArgs;
|
||||
private String fImageName = ""; //$NON-NLS-1$
|
||||
|
||||
public final static int COMMAND_CANCELED = ICommandLauncher.COMMAND_CANCELED;
|
||||
public final static int ILLEGAL_COMMAND = ICommandLauncher.ILLEGAL_COMMAND;
|
||||
public final static int OK = ICommandLauncher.OK;
|
||||
|
||||
private static final String NEWLINE = System.getProperty("line.separator", //$NON-NLS-1$
|
||||
"\n"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* The number of milliseconds to pause between polling.
|
||||
*/
|
||||
protected static final long DELAY = 50L;
|
||||
|
||||
@Override
|
||||
public void setProject(IProject project) {
|
||||
this.fProject = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IProject getProject() {
|
||||
return fProject;
|
||||
}
|
||||
|
||||
private String getImageName() {
|
||||
return fImageName;
|
||||
}
|
||||
|
||||
private void setImageName(String imageName) {
|
||||
fImageName = imageName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showCommand(boolean show) {
|
||||
this.fShowCommand = show;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorMessage() {
|
||||
return fErrorMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setErrorMessage(String error) {
|
||||
fErrorMessage = error;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getCommandArgs() {
|
||||
return commandArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Properties getEnvironment() {
|
||||
return fEnvironment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandLine() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process execute(IPath commandPath, String[] args, String[] env,
|
||||
IPath workingDirectory, IProgressMonitor monitor)
|
||||
throws CoreException {
|
||||
|
||||
HashMap<String, String> labels = new HashMap<>();
|
||||
labels.put("org.eclipse.cdt.container-command", ""); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
String projectName = fProject.getName();
|
||||
labels.put("org.eclipse.cdt.project-name", projectName); //$NON-NLS-1$
|
||||
|
||||
List<String> additionalDirs = new ArrayList<>();
|
||||
|
||||
//
|
||||
IPath projectLocation = fProject.getLocation();
|
||||
String projectPath = projectLocation.toPortableString();
|
||||
if (projectLocation.getDevice() != null) {
|
||||
projectPath = "/" + projectPath.replace(':', '/'); //$NON-NLS-1$
|
||||
}
|
||||
additionalDirs.add(projectPath);
|
||||
|
||||
ArrayList<String> commandSegments = new ArrayList<>();
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
String commandString = commandPath.toPortableString();
|
||||
if (commandPath.getDevice() != null) {
|
||||
commandString = "/" + commandString.replace(':', '/'); //$NON-NLS-1$
|
||||
}
|
||||
b.append(commandString);
|
||||
commandSegments.add(commandString);
|
||||
for (String arg : args) {
|
||||
b.append(" "); //$NON-NLS-1$
|
||||
String realArg = VariablesPlugin.getDefault()
|
||||
.getStringVariableManager().performStringSubstitution(arg);
|
||||
if (Platform.getOS().equals(Platform.OS_WIN32)) {
|
||||
// check if file exists and if so, add an additional directory
|
||||
IPath p = new Path(realArg);
|
||||
if (p.isValidPath(realArg) && p.getDevice() != null) {
|
||||
File f = p.toFile();
|
||||
String modifiedArg = realArg;
|
||||
// if the directory of the arg as a file exists, we mount it
|
||||
// and modify the argument to be unix-style
|
||||
if (f.isFile()) {
|
||||
f = f.getParentFile();
|
||||
modifiedArg = "/" //$NON-NLS-1$
|
||||
+ p.toPortableString().replace(':', '/');
|
||||
p = p.removeLastSegments(1);
|
||||
}
|
||||
if (f != null && f.exists()) {
|
||||
additionalDirs.add(
|
||||
"/" + p.toPortableString().replace(':', '/')); //$NON-NLS-1$
|
||||
realArg = modifiedArg;
|
||||
}
|
||||
}
|
||||
} else if (realArg.startsWith("/")) { //$NON-NLS-1$
|
||||
// check if file directory exists and if so, add an additional
|
||||
// directory
|
||||
IPath p = new Path(realArg);
|
||||
if (p.isValidPath(realArg)) {
|
||||
File f = p.toFile();
|
||||
if (f.isFile()) {
|
||||
f = f.getParentFile();
|
||||
}
|
||||
if (f != null && f.exists()) {
|
||||
additionalDirs.add(f.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
b.append(realArg);
|
||||
commandSegments.add(realArg);
|
||||
}
|
||||
|
||||
commandArgs = commandSegments.toArray(new String[0]);
|
||||
|
||||
String commandDir = commandPath.removeLastSegments(1).toString();
|
||||
if (commandDir.isEmpty()) {
|
||||
commandDir = null;
|
||||
} else if (commandPath.getDevice() != null) {
|
||||
commandDir = "/" + commandDir.replace(':', '/'); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
IProject[] referencedProjects = fProject.getReferencedProjects();
|
||||
for (IProject referencedProject : referencedProjects) {
|
||||
String referencedProjectPath = referencedProject.getLocation()
|
||||
.toPortableString();
|
||||
if (referencedProject.getLocation().getDevice() != null) {
|
||||
referencedProjectPath = "/" //$NON-NLS-1$
|
||||
+ referencedProjectPath.replace(':', '/');
|
||||
}
|
||||
additionalDirs
|
||||
.add(referencedProjectPath);
|
||||
}
|
||||
|
||||
String command = b.toString();
|
||||
|
||||
String workingDir = workingDirectory.makeAbsolute().toPortableString();
|
||||
if (workingDirectory.toPortableString().equals(".")) { //$NON-NLS-1$
|
||||
workingDir = "/tmp"; //$NON-NLS-1$
|
||||
} else if (workingDirectory.getDevice() != null) {
|
||||
workingDir = "/" + workingDir.replace(':', '/'); //$NON-NLS-1$
|
||||
}
|
||||
parseEnvironment(env);
|
||||
Map<String, String> origEnv = null;
|
||||
|
||||
boolean supportStdin = false;
|
||||
|
||||
boolean privilegedMode = false;
|
||||
|
||||
ContainerLauncher launcher = new ContainerLauncher();
|
||||
|
||||
Preferences prefs = InstanceScope.INSTANCE
|
||||
.getNode(DockerLaunchUIPlugin.PLUGIN_ID);
|
||||
|
||||
boolean keepContainer = prefs.getBoolean(
|
||||
PreferenceConstants.KEEP_CONTAINER_AFTER_LAUNCH, false);
|
||||
|
||||
ICConfigurationDescription cfgd = CoreModel.getDefault()
|
||||
.getProjectDescription(fProject).getActiveConfiguration();
|
||||
IConfiguration cfg = ManagedBuildManager
|
||||
.getConfigurationForDescription(cfgd);
|
||||
if (cfg == null) {
|
||||
return null;
|
||||
}
|
||||
IOptionalBuildProperties props = cfg.getOptionalBuildProperties();
|
||||
|
||||
// Add any specified volumes to additional dir list
|
||||
String selectedVolumeString = props.getProperty(SELECTED_VOLUMES_ID);
|
||||
if (selectedVolumeString != null && !selectedVolumeString.isEmpty()) {
|
||||
String[] selectedVolumes = selectedVolumeString
|
||||
.split(VOLUME_SEPARATOR_REGEX);
|
||||
if (Platform.getOS().equals(Platform.OS_WIN32)) {
|
||||
for (String selectedVolume : selectedVolumes) {
|
||||
IPath path = new Path(selectedVolume);
|
||||
String selectedPath = path.toPortableString();
|
||||
if (path.getDevice() != null) {
|
||||
selectedPath = "/" + selectedPath.replace(':', '/'); //$NON-NLS-1$
|
||||
}
|
||||
additionalDirs.add(selectedPath);
|
||||
}
|
||||
} else {
|
||||
additionalDirs.addAll(Arrays.asList(selectedVolumes));
|
||||
}
|
||||
}
|
||||
|
||||
String connectionName = props
|
||||
.getProperty(ContainerCommandLauncher.CONNECTION_ID);
|
||||
if (connectionName == null) {
|
||||
return null;
|
||||
}
|
||||
String imageName = props
|
||||
.getProperty(ContainerCommandLauncher.IMAGE_ID);
|
||||
if (imageName == null) {
|
||||
return null;
|
||||
}
|
||||
setImageName(imageName);
|
||||
|
||||
fProcess = launcher.runCommand(connectionName, imageName, fProject,
|
||||
this,
|
||||
command,
|
||||
commandDir,
|
||||
workingDir,
|
||||
additionalDirs,
|
||||
origEnv, fEnvironment, supportStdin, privilegedMode,
|
||||
labels, keepContainer);
|
||||
|
||||
return fProcess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse array of "ENV=value" pairs to Properties.
|
||||
*/
|
||||
private void parseEnvironment(String[] env) {
|
||||
fEnvironment = null;
|
||||
if (env != null) {
|
||||
fEnvironment = new Properties();
|
||||
for (String envStr : env) {
|
||||
// Split "ENV=value" and put in Properties
|
||||
int pos = envStr.indexOf('='); // $NON-NLS-1$
|
||||
if (pos < 0)
|
||||
pos = envStr.length();
|
||||
String key = envStr.substring(0, pos);
|
||||
String value = envStr.substring(pos + 1);
|
||||
fEnvironment.put(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int waitAndRead(OutputStream out, OutputStream err) {
|
||||
printImageHeader(out);
|
||||
|
||||
if (fShowCommand) {
|
||||
printCommandLine(out);
|
||||
}
|
||||
|
||||
if (fProcess == null) {
|
||||
return ILLEGAL_COMMAND;
|
||||
}
|
||||
ProcessClosure closure = new ProcessClosure(fProcess, out, err);
|
||||
closure.runBlocking(); // a blocking call
|
||||
return OK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int waitAndRead(OutputStream output, OutputStream err,
|
||||
IProgressMonitor monitor) {
|
||||
printImageHeader(output);
|
||||
|
||||
if (fShowCommand) {
|
||||
printCommandLine(output);
|
||||
}
|
||||
|
||||
if (fProcess == null) {
|
||||
return ILLEGAL_COMMAND;
|
||||
}
|
||||
|
||||
ProcessClosure closure = new ProcessClosure(fProcess, output, err);
|
||||
closure.runNonBlocking();
|
||||
Runnable watchProcess = () -> {
|
||||
try {
|
||||
fProcess.waitFor();
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
closure.terminate();
|
||||
};
|
||||
Thread t = new Thread(watchProcess);
|
||||
t.start();
|
||||
while (!monitor.isCanceled() && closure.isAlive()) {
|
||||
try {
|
||||
Thread.sleep(DELAY);
|
||||
} catch (InterruptedException ie) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
t.join(500);
|
||||
} catch (InterruptedException e1) {
|
||||
// ignore
|
||||
}
|
||||
int state = OK;
|
||||
|
||||
// Operation canceled by the user, terminate abnormally.
|
||||
if (monitor.isCanceled()) {
|
||||
closure.terminate();
|
||||
state = COMMAND_CANCELED;
|
||||
setErrorMessage(Messages.CommandLauncher_CommandCancelled);
|
||||
}
|
||||
try {
|
||||
fProcess.waitFor();
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
monitor.done();
|
||||
return state;
|
||||
}
|
||||
|
||||
protected void printImageHeader(OutputStream os) {
|
||||
if (os != null) {
|
||||
try {
|
||||
os.write(NLS
|
||||
.bind(Messages.ContainerCommandLauncher_image_msg,
|
||||
((ContainerCommandProcess) fProcess).getImage())
|
||||
.getBytes());
|
||||
os.write(NEWLINE.getBytes());
|
||||
os.flush();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void printCommandLine(OutputStream os) {
|
||||
if (os != null) {
|
||||
try {
|
||||
os.write(getCommandLineQuoted(getCommandArgs(), true)
|
||||
.getBytes());
|
||||
os.flush();
|
||||
} catch (IOException e) {
|
||||
// ignore;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("nls")
|
||||
private String getCommandLineQuoted(String[] commandArgs, boolean quote) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (commandArgs != null) {
|
||||
for (String commandArg : commandArgs) {
|
||||
if (quote && (commandArg.contains(" ")
|
||||
|| commandArg.contains("\"")
|
||||
|| commandArg.contains("\\"))) {
|
||||
commandArg = '"' + commandArg.replaceAll("\\\\", "\\\\\\\\")
|
||||
.replaceAll("\"", "\\\\\"") + '"';
|
||||
}
|
||||
buf.append(commandArg);
|
||||
buf.append(' ');
|
||||
}
|
||||
buf.append(NEWLINE);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
protected String getCommandLine(String[] commandArgs) {
|
||||
return getCommandLineQuoted(commandArgs, false);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,466 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015, 2016 Red Hat Inc. and others.
|
||||
* 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:
|
||||
* Red Hat - Initial Contribution
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.docker.launcher;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.internal.docker.launcher.ContainerPropertyVolumesModel.MountType;
|
||||
import org.eclipse.core.databinding.Binding;
|
||||
import org.eclipse.core.databinding.DataBindingContext;
|
||||
import org.eclipse.core.databinding.UpdateValueStrategy;
|
||||
import org.eclipse.core.databinding.beans.BeanProperties;
|
||||
import org.eclipse.core.databinding.observable.IChangeListener;
|
||||
import org.eclipse.core.databinding.observable.value.IObservableValue;
|
||||
import org.eclipse.core.databinding.validation.ValidationStatus;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
|
||||
import org.eclipse.jface.databinding.swt.WidgetProperties;
|
||||
import org.eclipse.jface.dialogs.Dialog;
|
||||
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||
import org.eclipse.jface.fieldassist.ComboContentAdapter;
|
||||
import org.eclipse.jface.fieldassist.ContentProposal;
|
||||
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
|
||||
import org.eclipse.jface.fieldassist.ControlDecoration;
|
||||
import org.eclipse.jface.fieldassist.IContentProposal;
|
||||
import org.eclipse.jface.fieldassist.IContentProposalProvider;
|
||||
import org.eclipse.jface.layout.GridDataFactory;
|
||||
import org.eclipse.jface.layout.GridLayoutFactory;
|
||||
import org.eclipse.jface.viewers.ArrayContentProvider;
|
||||
import org.eclipse.jface.viewers.ComboViewer;
|
||||
import org.eclipse.linuxtools.docker.core.IDockerConnection;
|
||||
import org.eclipse.linuxtools.docker.core.IDockerContainer;
|
||||
import org.eclipse.linuxtools.docker.core.IDockerContainerInfo;
|
||||
import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardMessages;
|
||||
import org.eclipse.linuxtools.internal.docker.ui.wizards.WizardUtils;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Combo;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.DirectoryDialog;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.FileDialog;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
/**
|
||||
* @author xcoulon
|
||||
*
|
||||
*/
|
||||
public class ContainerDataVolumeDialog extends Dialog {
|
||||
|
||||
private final DataVolumeModel model;
|
||||
|
||||
private final DataBindingContext dbc = new DataBindingContext();
|
||||
|
||||
private final List<String> containerNames;
|
||||
|
||||
private final IDockerConnection connection;
|
||||
|
||||
public ContainerDataVolumeDialog(final Shell parentShell,
|
||||
final IDockerConnection connection,
|
||||
final DataVolumeModel selectedDataVolume) {
|
||||
super(parentShell);
|
||||
this.connection = connection;
|
||||
this.model = new DataVolumeModel(selectedDataVolume);
|
||||
this.containerNames = WizardUtils.getContainerNames(connection);
|
||||
}
|
||||
|
||||
public ContainerDataVolumeDialog(final Shell parentShell,
|
||||
final IDockerConnection connection) {
|
||||
super(parentShell);
|
||||
this.connection = connection;
|
||||
this.model = new DataVolumeModel();
|
||||
this.containerNames = WizardUtils.getContainerNames(connection);
|
||||
}
|
||||
|
||||
public DataVolumeModel getDataVolume() {
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureShell(final Shell shell) {
|
||||
super.configureShell(shell);
|
||||
setShellStyle(getShellStyle() | SWT.RESIZE);
|
||||
shell.setText(
|
||||
WizardMessages.getString("ContainerDataVolumeDialog.title")); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the 'OK' button by default
|
||||
*/
|
||||
@Override
|
||||
protected Button createButton(Composite parent, int id, String label,
|
||||
boolean defaultButton) {
|
||||
final Button button = super.createButton(parent, id, label,
|
||||
defaultButton);
|
||||
if (id == IDialogConstants.OK_ID) {
|
||||
button.setEnabled(false);
|
||||
}
|
||||
return button;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Point getInitialSize() {
|
||||
return new Point(450, super.getInitialSize().y);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Control createDialogArea(final Composite parent) {
|
||||
final Composite container = new Composite(parent, SWT.NONE);
|
||||
final int COLUMNS = 3;
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL).span(1, 1)
|
||||
.grab(true, true).applyTo(container);
|
||||
GridLayoutFactory.fillDefaults().margins(10, 10).numColumns(COLUMNS)
|
||||
.applyTo(container);
|
||||
|
||||
// Container path
|
||||
final Label containerPathLabel = new Label(container, SWT.NONE);
|
||||
containerPathLabel.setText(WizardMessages
|
||||
.getString("ContainerDataVolumeDialog.containerPathLabel")); //$NON-NLS-1$
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.grab(false, false).applyTo(containerPathLabel);
|
||||
final Text containerPathText = new Text(container, SWT.BORDER);
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.grab(true, false).applyTo(containerPathText);
|
||||
final IObservableValue containerPathObservable = BeanProperties
|
||||
.value(DataVolumeModel.class, DataVolumeModel.CONTAINER_PATH)
|
||||
.observe(model);
|
||||
dbc.bindValue(
|
||||
WidgetProperties.text(SWT.Modify).observe(containerPathText),
|
||||
containerPathObservable);
|
||||
// mount type
|
||||
final Label explanationLabel = new Label(container, SWT.NONE);
|
||||
explanationLabel.setText(WizardMessages
|
||||
.getString("ContainerDataVolumeDialog.explanationLabel")); //$NON-NLS-1$
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.span(COLUMNS, 1).grab(true, false).applyTo(explanationLabel);
|
||||
final int INDENT = 20;
|
||||
// No mount
|
||||
final Button noMountButton = new Button(container, SWT.RADIO);
|
||||
noMountButton.setText(WizardMessages
|
||||
.getString("ContainerDataVolumeDialog.noMountButton")); //$NON-NLS-1$
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.indent(INDENT, 0).span(COLUMNS, 1).grab(true, false)
|
||||
.applyTo(noMountButton);
|
||||
bindButton(noMountButton, MountType.NONE);
|
||||
// File System mount
|
||||
final Button fileSystemMountButton = new Button(container, SWT.RADIO);
|
||||
fileSystemMountButton.setText(WizardMessages
|
||||
.getString("ContainerDataVolumeDialog.fileSystemMountButton")); //$NON-NLS-1$
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.indent(INDENT, 0).span(COLUMNS, 1).grab(true, false)
|
||||
.applyTo(fileSystemMountButton);
|
||||
final Label hostPathLabel = new Label(container, SWT.NONE);
|
||||
hostPathLabel.setText(WizardMessages
|
||||
.getString("ContainerDataVolumeDialog.hostPathLabel")); //$NON-NLS-1$
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.indent(2 * INDENT, SWT.DEFAULT).grab(false, false)
|
||||
.applyTo(hostPathLabel);
|
||||
final Text hostPathText = new Text(container, SWT.BORDER);
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.grab(true, false).applyTo(hostPathText);
|
||||
final IObservableValue hostPathObservable = BeanProperties
|
||||
.value(DataVolumeModel.class, DataVolumeModel.HOST_PATH_MOUNT)
|
||||
.observe(model);
|
||||
dbc.bindValue(WidgetProperties.text(SWT.Modify).observe(hostPathText),
|
||||
hostPathObservable);
|
||||
// browse for directory
|
||||
final Button hostPathDirectoryButton = new Button(container, SWT.NONE);
|
||||
hostPathDirectoryButton.setText(WizardMessages
|
||||
.getString("ContainerDataVolumeDialog.directoryButton")); //$NON-NLS-1$
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.grab(false, false).applyTo(hostPathDirectoryButton);
|
||||
hostPathDirectoryButton.addSelectionListener(onHostDirectoryPath());
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.grab(false, false).applyTo(new Label(container, SWT.NONE));
|
||||
// optional read-only access
|
||||
final Button readOnlyButton = new Button(container, SWT.CHECK);
|
||||
readOnlyButton.setText(WizardMessages
|
||||
.getString("ContainerDataVolumeDialog.readOnlyButton")); //$NON-NLS-1$
|
||||
readOnlyButton.setToolTipText(WizardMessages
|
||||
.getString("ContainerDataVolumeDialog.readOnlyButtonTooltip")); //$NON-NLS-1$
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.span(COLUMNS - 2, 1).grab(true, false).applyTo(readOnlyButton);
|
||||
final ISWTObservableValue readOnlyButtonObservable = WidgetProperties
|
||||
.selection().observe(readOnlyButton);
|
||||
dbc.bindValue(readOnlyButtonObservable,
|
||||
BeanProperties
|
||||
.value(DataVolumeModel.class,
|
||||
DataVolumeModel.READ_ONLY_VOLUME)
|
||||
.observe(model));
|
||||
// browse for file
|
||||
final Button hostPathFileButton = new Button(container, SWT.NONE);
|
||||
hostPathFileButton.setText(WizardMessages
|
||||
.getString("ContainerDataVolumeDialog.fileButton")); //$NON-NLS-1$
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.grab(false, false).applyTo(hostPathFileButton);
|
||||
hostPathFileButton.addSelectionListener(onHostFilePath());
|
||||
bindButton(fileSystemMountButton, MountType.HOST_FILE_SYSTEM,
|
||||
hostPathText, hostPathDirectoryButton, hostPathFileButton,
|
||||
readOnlyButton);
|
||||
|
||||
// Container mount
|
||||
final Button containerMountButton = new Button(container, SWT.RADIO);
|
||||
containerMountButton.setText(WizardMessages
|
||||
.getString("ContainerDataVolumeDialog.containerMountButton")); //$NON-NLS-1$
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.indent(INDENT, 0).span(COLUMNS, 1).grab(true, false)
|
||||
.applyTo(containerMountButton);
|
||||
final Label containerSelectionLabel = new Label(container, SWT.NONE);
|
||||
containerSelectionLabel.setText(WizardMessages.getString(
|
||||
"ContainerDataVolumeDialog.containerSelectionLabel")); //$NON-NLS-1$
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.indent(2 * INDENT, SWT.DEFAULT)
|
||||
.applyTo(containerSelectionLabel);
|
||||
final Combo containerSelectionCombo = new Combo(container, SWT.BORDER);
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.grab(true, false).span(1, 1).applyTo(containerSelectionCombo);
|
||||
new ControlDecoration(containerSelectionCombo, SWT.TOP | SWT.LEFT);
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.grab(false, false).applyTo(new Label(container, SWT.NONE));
|
||||
bindButton(containerMountButton, MountType.CONTAINER,
|
||||
containerSelectionCombo);
|
||||
final ComboViewer containerSelectionComboViewer = new ComboViewer(
|
||||
containerSelectionCombo);
|
||||
containerSelectionComboViewer
|
||||
.setContentProvider(new ArrayContentProvider());
|
||||
containerSelectionComboViewer.setInput(this.containerNames);
|
||||
final IObservableValue selectedContainerObservable = BeanProperties
|
||||
.value(DataVolumeModel.class, DataVolumeModel.CONTAINER_MOUNT)
|
||||
.observe(model);
|
||||
dbc.bindValue(
|
||||
WidgetProperties.selection().observe(containerSelectionCombo),
|
||||
selectedContainerObservable);
|
||||
new ContentProposalAdapter(containerSelectionCombo,
|
||||
new ComboContentAdapter() {
|
||||
@Override
|
||||
public void insertControlContents(Control control,
|
||||
String text, int cursorPosition) {
|
||||
final Combo combo = (Combo) control;
|
||||
final Point selection = combo.getSelection();
|
||||
combo.setText(text);
|
||||
selection.x = text.length();
|
||||
selection.y = selection.x;
|
||||
combo.setSelection(selection);
|
||||
}
|
||||
}, getContainerNameContentProposalProvider(
|
||||
containerSelectionCombo),
|
||||
null, null);
|
||||
|
||||
// error message
|
||||
final Composite errorContainer = new Composite(container, SWT.NONE);
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.FILL)
|
||||
.span(COLUMNS, 1).grab(true, true).applyTo(errorContainer);
|
||||
GridLayoutFactory.fillDefaults().margins(6, 6).numColumns(2)
|
||||
.applyTo(errorContainer);
|
||||
|
||||
final Label errorMessageIcon = new Label(errorContainer, SWT.NONE);
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.hint(20, SWT.DEFAULT)
|
||||
.applyTo(errorMessageIcon);
|
||||
final Label errorMessageLabel = new Label(errorContainer, SWT.NONE);
|
||||
GridDataFactory.fillDefaults().align(SWT.FILL, SWT.CENTER)
|
||||
.grab(true, false)
|
||||
.applyTo(errorMessageLabel);
|
||||
setupValidationSupport(errorMessageIcon, errorMessageLabel);
|
||||
return container;
|
||||
}
|
||||
|
||||
private void setupValidationSupport(final Label errorMessageIcon,
|
||||
final Label errorMessageLabel) {
|
||||
for (@SuppressWarnings("unchecked")
|
||||
Iterator<Binding> iterator = dbc.getBindings().iterator(); iterator
|
||||
.hasNext();) {
|
||||
final Binding binding = iterator.next();
|
||||
binding.getModel().addChangeListener(onDataVolumeSettingsChanged(
|
||||
errorMessageIcon, errorMessageLabel));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the given {@link MountType} to the given {@link Button} when it is
|
||||
* selected, and set the enablement of the associated {@link Control} at the
|
||||
* same time (ie: the {@link Control} are only enabled when the given
|
||||
* {@link Button} is selected.
|
||||
*
|
||||
* @param button
|
||||
* the {@link Button} to bind
|
||||
* @param mountType
|
||||
* the {@link MountType} to bind to the {@link Button}
|
||||
* @param controls
|
||||
* the {@link Control}s to enable or disable when the Button is
|
||||
* selected/unselected.
|
||||
* @return
|
||||
*/
|
||||
private Binding bindButton(final Button button, final MountType mountType,
|
||||
final Control... controls) {
|
||||
return dbc.bindValue(WidgetProperties.selection().observe(button),
|
||||
BeanProperties.value(DataVolumeModel.class,
|
||||
DataVolumeModel.MOUNT_TYPE).observe(model),
|
||||
new UpdateValueStrategy() {
|
||||
@Override
|
||||
public Object convert(Object value) {
|
||||
if (value.equals(Boolean.TRUE)) {
|
||||
setEnabled(controls, true);
|
||||
return mountType;
|
||||
}
|
||||
setEnabled(controls, false);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void setEnabled(final Control[] controls,
|
||||
final boolean enabled) {
|
||||
for (Control control : controls) {
|
||||
control.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
}, new UpdateValueStrategy() {
|
||||
@Override
|
||||
public Object convert(final Object value) {
|
||||
if (mountType.equals(value)) {
|
||||
button.setEnabled(true);
|
||||
}
|
||||
return mountType.equals(value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private SelectionListener onHostDirectoryPath() {
|
||||
return SelectionListener.widgetSelectedAdapter(e -> {
|
||||
final DirectoryDialog directoryDialog = new DirectoryDialog(
|
||||
getShell());
|
||||
final String selectedPath = directoryDialog.open();
|
||||
if (selectedPath != null) {
|
||||
model.setHostPathMount(selectedPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private SelectionListener onHostFilePath() {
|
||||
return SelectionListener.widgetSelectedAdapter(e -> {
|
||||
final FileDialog fileDialog = new FileDialog(getShell());
|
||||
final String selectedPath = fileDialog.open();
|
||||
if (selectedPath != null) {
|
||||
model.setHostPathMount(selectedPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link IContentProposalProvider} to propose
|
||||
* {@link IDockerContainer} names based on the current text.
|
||||
*
|
||||
* @param items
|
||||
* @return
|
||||
*/
|
||||
private IContentProposalProvider getContainerNameContentProposalProvider(
|
||||
final Combo containerSelectionCombo) {
|
||||
return (contents, position) -> {
|
||||
final List<IContentProposal> proposals = new ArrayList<>();
|
||||
for (String containerName : containerSelectionCombo.getItems()) {
|
||||
if (containerName.contains(contents)) {
|
||||
proposals.add(new ContentProposal(containerName,
|
||||
containerName, containerName, position));
|
||||
}
|
||||
}
|
||||
return proposals.toArray(new IContentProposal[0]);
|
||||
};
|
||||
}
|
||||
|
||||
private IChangeListener onDataVolumeSettingsChanged(
|
||||
final Label errorMessageIcon, final Label errorMessageLabel) {
|
||||
|
||||
return event -> {
|
||||
// skip if dialog has been closed
|
||||
if (Display.getCurrent() == null || getShell().isDisposed()) {
|
||||
return;
|
||||
}
|
||||
final IStatus status = validateInput();
|
||||
Display.getCurrent().syncExec(() -> {
|
||||
if (status.isOK()) {
|
||||
errorMessageIcon.setVisible(false);
|
||||
errorMessageLabel.setVisible(false);
|
||||
setOkButtonEnabled(true);
|
||||
} else if (status.matches(IStatus.WARNING)) {
|
||||
errorMessageIcon.setVisible(true);
|
||||
errorMessageIcon.setImage(
|
||||
SWTImagesFactory.DESC_WARNING.createImage());
|
||||
errorMessageLabel.setVisible(true);
|
||||
errorMessageLabel.setText(status.getMessage());
|
||||
setOkButtonEnabled(true);
|
||||
} else if (status.matches(IStatus.ERROR)) {
|
||||
if (status.getMessage() != null
|
||||
&& !status.getMessage().isEmpty()) {
|
||||
errorMessageIcon.setVisible(true);
|
||||
errorMessageIcon.setImage(
|
||||
SWTImagesFactory.DESC_ERROR.createImage());
|
||||
errorMessageLabel.setVisible(true);
|
||||
errorMessageLabel.setText(status.getMessage());
|
||||
}
|
||||
setOkButtonEnabled(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
private IStatus validateInput() {
|
||||
final String containerPath = model.getContainerPath();
|
||||
final MountType mountType = model.getMountType();
|
||||
final String hostPath = model.getHostPathMount();
|
||||
if (containerPath == null || containerPath.isEmpty()) {
|
||||
return ValidationStatus.error(null);
|
||||
} else if (mountType == null) {
|
||||
return ValidationStatus.error(null);
|
||||
} else if (mountType == MountType.HOST_FILE_SYSTEM
|
||||
&& (hostPath == null || hostPath.isEmpty())) {
|
||||
return ValidationStatus.error(null);
|
||||
} else if (mountType == MountType.HOST_FILE_SYSTEM
|
||||
&& !new File(hostPath).exists()) {
|
||||
return ValidationStatus
|
||||
.warning("The specified path does not exist on the host."); //$NON-NLS-1$
|
||||
} else if (mountType == MountType.CONTAINER) {
|
||||
final IDockerContainer container = WizardUtils
|
||||
.getContainer(connection, model.getContainerMount());
|
||||
if (container == null) {
|
||||
// just make sure that the dialog cannot complete
|
||||
return ValidationStatus.error(null);
|
||||
}
|
||||
final IDockerContainerInfo selectedContainerInfo = container.info();
|
||||
if (selectedContainerInfo != null
|
||||
&& selectedContainerInfo.volumes() != null
|
||||
&& !selectedContainerInfo.volumes()
|
||||
.containsKey(model.getContainerPath())) {
|
||||
return ValidationStatus
|
||||
.warning(WizardMessages.getFormattedString(
|
||||
"ContainerDataVolumeDialog.volumeWarning", //$NON-NLS-1$
|
||||
model.getContainerPath()));
|
||||
}
|
||||
}
|
||||
return ValidationStatus.ok();
|
||||
}
|
||||
|
||||
private void setOkButtonEnabled(final boolean enabled) {
|
||||
final Button okButton = getButton(IDialogConstants.OK_ID);
|
||||
// skip if 'OK' button does not exist yet.
|
||||
if (okButton != null) {
|
||||
okButton.setEnabled(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.docker.launcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -80,7 +81,8 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
|
|||
|
||||
@Override
|
||||
public void newOutput(String output) {
|
||||
if (output.contains(Messages.Gdbserver_up)) {
|
||||
if (output.contains(Messages.Gdbserver_up)
|
||||
|| output.contains("gdbserver:")) { //$NON-NLS-1$
|
||||
started = true;
|
||||
}
|
||||
|
||||
|
@ -137,10 +139,16 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
|
|||
labels.put("org.eclipse.cdt.project-name", projectName); //$NON-NLS-1$
|
||||
if (mode.equals(ILaunchManager.RUN_MODE)) {
|
||||
String commandDir = commandPath.removeLastSegments(1)
|
||||
.toString();
|
||||
.toPortableString();
|
||||
String commandString = commandPath.toPortableString();
|
||||
|
||||
if (commandPath.getDevice() != null) {
|
||||
commandDir = "/" + commandDir.replace(':', '/'); //$NON-NLS-1$
|
||||
commandString = "/" + commandString.replace(':', '/'); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(commandPath.toString().trim());
|
||||
b.append(commandString);
|
||||
|
||||
String arguments = getProgramArguments(configuration);
|
||||
if (arguments.trim().length() > 0) {
|
||||
|
@ -154,6 +162,13 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
|
|||
.getAttribute(
|
||||
ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
|
||||
(String) null);
|
||||
if (workingDir != null) {
|
||||
IPath workingPath = new Path(workingDir);
|
||||
if (workingPath.getDevice() != null) {
|
||||
workingDir = "/" + workingPath.toPortableString() //$NON-NLS-1$
|
||||
.replace(':', '/');
|
||||
}
|
||||
}
|
||||
Map<String, String> envMap = configuration.getAttribute(
|
||||
ILaunchManager.ATTR_ENVIRONMENT_VARIABLES,
|
||||
(Map<String, String>) null);
|
||||
|
@ -168,6 +183,18 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
|
|||
List<String> additionalDirs = configuration.getAttribute(
|
||||
ILaunchConstants.ATTR_ADDITIONAL_DIRS,
|
||||
(List<String>) null);
|
||||
if (additionalDirs != null) {
|
||||
List<String> dirs = new ArrayList<>();
|
||||
for (String additionalDir : additionalDirs) {
|
||||
IPath path = new Path(additionalDir);
|
||||
String dir = path.toPortableString();
|
||||
if (path.getDevice() != null) {
|
||||
dir = "/" + dir.replace(':', '/');
|
||||
}
|
||||
dirs.add(dir);
|
||||
}
|
||||
additionalDirs = dirs;
|
||||
}
|
||||
String image = configuration.getAttribute(
|
||||
ILaunchConstants.ATTR_IMAGE, (String) null);
|
||||
String connectionUri = configuration.getAttribute(
|
||||
|
@ -196,11 +223,18 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
|
|||
String gdbserverCommand = configuration.getAttribute(
|
||||
ILaunchConstants.ATTR_GDBSERVER_COMMAND,
|
||||
ILaunchConstants.ATTR_GDBSERVER_COMMAND_DEFAULT);
|
||||
String commandArguments = ":" + gdbserverPortNumber + " " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ spaceEscapify(commandPath.toString());
|
||||
|
||||
String commandString = commandPath.toPortableString();
|
||||
String commandDir = commandPath.removeLastSegments(1)
|
||||
.toString();
|
||||
.toPortableString();
|
||||
|
||||
if (commandPath.getDevice() != null) {
|
||||
commandDir = "/" + commandDir.replace(':', '/'); //$NON-NLS-1$
|
||||
commandString = "/" + commandString.replace(':', '/'); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
String commandArguments = ":" + gdbserverPortNumber + " " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ spaceEscapify(commandString);
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
||||
|
@ -217,6 +251,14 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
|
|||
.getAttribute(
|
||||
ICDTLaunchConfigurationConstants.ATTR_WORKING_DIRECTORY,
|
||||
(String) null);
|
||||
if (workingDir != null) {
|
||||
IPath workingPath = new Path(workingDir);
|
||||
if (workingPath.getDevice() != null) {
|
||||
workingDir = "/" + workingPath.toPortableString() //$NON-NLS-1$
|
||||
.replace(':', '/');
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, String> envMap = configuration.getAttribute(
|
||||
ILaunchManager.ATTR_ENVIRONMENT_VARIABLES,
|
||||
(Map<String, String>) null);
|
||||
|
@ -231,6 +273,19 @@ public class ContainerLaunchConfigurationDelegate extends GdbLaunchDelegate
|
|||
List<String> additionalDirs = configuration.getAttribute(
|
||||
ILaunchConstants.ATTR_ADDITIONAL_DIRS,
|
||||
(List<String>) null);
|
||||
if (additionalDirs != null) {
|
||||
List<String> dirs = new ArrayList<>();
|
||||
for (String additionalDir : additionalDirs) {
|
||||
IPath path = new Path(additionalDir);
|
||||
String dir = path.toPortableString();
|
||||
if (path.getDevice() != null) {
|
||||
dir = "/" + dir.replace(':', '/');
|
||||
}
|
||||
dirs.add(dir);
|
||||
}
|
||||
additionalDirs = dirs;
|
||||
}
|
||||
|
||||
String image = configuration.getAttribute(
|
||||
ILaunchConstants.ATTR_IMAGE, (String) null);
|
||||
String connectionUri = configuration.getAttribute(
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,142 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015, 2016 Red Hat.
|
||||
* 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:
|
||||
* Red Hat - Initial Contribution
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.docker.launcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.databinding.observable.list.WritableList;
|
||||
import org.eclipse.linuxtools.docker.core.DockerException;
|
||||
import org.eclipse.linuxtools.docker.core.IDockerConnection;
|
||||
import org.eclipse.linuxtools.docker.core.IDockerImage;
|
||||
import org.eclipse.linuxtools.docker.core.IDockerImageInfo;
|
||||
|
||||
/**
|
||||
* Databinding model for the {@link ContainerPropertyTab}
|
||||
*
|
||||
*/
|
||||
public class ContainerPropertyVolumesModel
|
||||
extends BaseDatabindingModel {
|
||||
|
||||
public enum MountType {
|
||||
NONE, HOST_FILE_SYSTEM, CONTAINER;
|
||||
}
|
||||
|
||||
|
||||
public static final String DATA_VOLUMES = "dataVolumes"; //$NON-NLS-1$
|
||||
|
||||
public static final String SELECTED_DATA_VOLUMES = "selectedDataVolumes"; //$NON-NLS-1$
|
||||
|
||||
private IDockerConnection connection;
|
||||
|
||||
private IDockerImageInfo imageInfo = null;
|
||||
|
||||
private Set<DataVolumeModel> selectedDataVolumes = new HashSet<>();
|
||||
|
||||
private WritableList<DataVolumeModel> dataVolumes = new WritableList<>();
|
||||
|
||||
private List<DataVolumeModel> previousVolumes = new ArrayList<>();
|
||||
|
||||
private IDockerImage selectedImage;
|
||||
|
||||
public ContainerPropertyVolumesModel(
|
||||
final IDockerConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public ContainerPropertyVolumesModel(
|
||||
final IDockerImage selectedImage) throws DockerException {
|
||||
this(selectedImage.getConnection());
|
||||
this.selectedImage = selectedImage;
|
||||
}
|
||||
|
||||
public void setConnection(IDockerConnection connection) {
|
||||
this.connection = connection;
|
||||
setSelectedImage(null);
|
||||
}
|
||||
|
||||
public IDockerConnection getConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refreshes the list of Volumes to display in the for the given
|
||||
*
|
||||
* @param selectedImage
|
||||
*/
|
||||
public void setSelectedImage(final IDockerImage selectedImage) {
|
||||
if (this.selectedImage == null
|
||||
|| !this.selectedImage.equals(selectedImage)) {
|
||||
this.selectedImage = selectedImage;
|
||||
if (selectedImage != null) {
|
||||
this.imageInfo = selectedImage.getConnection()
|
||||
.getImageInfo(selectedImage.id());
|
||||
if (this.imageInfo.config() != null
|
||||
&& this.imageInfo.config().volumes() != null) {
|
||||
for (DataVolumeModel dvm : previousVolumes) {
|
||||
removeDataVolume(dvm);
|
||||
selectedDataVolumes.remove(dvm);
|
||||
}
|
||||
final List<DataVolumeModel> volumes = new ArrayList<>();
|
||||
for (String volume : this.imageInfo.config().volumes()) {
|
||||
volumes.add(new DataVolumeModel(volume));
|
||||
}
|
||||
setDataVolumes(volumes);
|
||||
previousVolumes = volumes;
|
||||
}
|
||||
} else {
|
||||
setDataVolumes(Collections.<DataVolumeModel> emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public IDockerImage getSelectedImage() {
|
||||
return selectedImage;
|
||||
}
|
||||
|
||||
public IDockerImageInfo getSelectedImageInfo() {
|
||||
return imageInfo;
|
||||
}
|
||||
|
||||
public WritableList<DataVolumeModel> getDataVolumes() {
|
||||
return dataVolumes;
|
||||
}
|
||||
|
||||
public void setDataVolumes(final Collection<DataVolumeModel> volumes) {
|
||||
if (volumes != null) {
|
||||
this.dataVolumes.addAll(volumes);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearDataVolumes() {
|
||||
this.dataVolumes.clear();
|
||||
}
|
||||
|
||||
public void removeDataVolume(final DataVolumeModel dataVolume) {
|
||||
this.dataVolumes.remove(dataVolume);
|
||||
}
|
||||
|
||||
public Set<DataVolumeModel> getSelectedDataVolumes() {
|
||||
return selectedDataVolumes;
|
||||
}
|
||||
|
||||
public void setSelectedDataVolumes(
|
||||
final Set<DataVolumeModel> selectedDataVolumes) {
|
||||
firePropertyChange(SELECTED_DATA_VOLUMES, this.selectedDataVolumes,
|
||||
this.selectedDataVolumes = selectedDataVolumes);
|
||||
}
|
||||
|
||||
}
|
|
@ -517,7 +517,8 @@ public class ContainerTab extends AbstractLaunchConfigurationTab implements
|
|||
return SWTImagesFactory.get(SWTImagesFactory.IMG_CONTAINER);
|
||||
}
|
||||
|
||||
public void changeEvent(int type) {
|
||||
@Override
|
||||
public void changeEvent(IDockerConnection changedConnection, int type) {
|
||||
String currUri = null;
|
||||
int currIndex = 0;
|
||||
connections = DockerConnectionManager.getInstance().getConnections();
|
||||
|
@ -549,10 +550,6 @@ public class ContainerTab extends AbstractLaunchConfigurationTab implements
|
|||
connectionSelector.addModifyListener(connectionModifyListener);
|
||||
}
|
||||
|
||||
public void changeEvent(IDockerConnection connection, int event) {
|
||||
changeEvent(event);
|
||||
}
|
||||
|
||||
public void listChanged(IDockerConnection c,
|
||||
java.util.List<IDockerImage> list) {
|
||||
final IDockerImage[] finalList = list.toArray(new IDockerImage[0]);
|
||||
|
|
|
@ -0,0 +1,347 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2015 Red Hat.
|
||||
* 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:
|
||||
* Red Hat - Initial Contribution
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.docker.launcher;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.cdt.internal.docker.launcher.ContainerPropertyVolumesModel.MountType;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
|
||||
/**
|
||||
* Data binding model for container data volumes
|
||||
*
|
||||
*/
|
||||
public class DataVolumeModel extends BaseDatabindingModel
|
||||
implements Comparable<DataVolumeModel> {
|
||||
|
||||
private static final String SEPARATOR = ":"; //$NON-NLS-1$
|
||||
|
||||
public static final String CONTAINER_PATH = "containerPath"; //$NON-NLS-1$
|
||||
|
||||
public static final String MOUNT_TYPE = "mountType"; //$NON-NLS-1$
|
||||
|
||||
public static final String MOUNT = "mount"; //$NON-NLS-1$
|
||||
|
||||
public static final String HOST_PATH_MOUNT = "hostPathMount"; //$NON-NLS-1$
|
||||
|
||||
public static final String READ_ONLY_VOLUME = "readOnly"; //$NON-NLS-1$
|
||||
|
||||
public static final String CONTAINER_MOUNT = "containerMount"; //$NON-NLS-1$
|
||||
|
||||
public static final String SELECTED = "selected"; //$NON-NLS-1$
|
||||
|
||||
private final String id = UUID.randomUUID().toString();
|
||||
|
||||
private String containerPath;
|
||||
|
||||
private MountType mountType;
|
||||
|
||||
private String mount;
|
||||
|
||||
private String hostPathMount;
|
||||
|
||||
private String containerMount;
|
||||
|
||||
private boolean readOnly = false;
|
||||
|
||||
private boolean selected;
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public DataVolumeModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param containerPath
|
||||
* the container path
|
||||
*/
|
||||
public DataVolumeModel(final String containerPath) {
|
||||
this.containerPath = containerPath;
|
||||
this.mountType = MountType.NONE;
|
||||
}
|
||||
|
||||
public DataVolumeModel(final String containerPath, final String hostPath,
|
||||
final boolean readOnly) {
|
||||
this.containerPath = containerPath;
|
||||
this.mountType = MountType.HOST_FILE_SYSTEM;
|
||||
this.hostPathMount = hostPath;
|
||||
this.mount = this.hostPathMount;
|
||||
this.readOnly = readOnly;
|
||||
}
|
||||
|
||||
public DataVolumeModel(final DataVolumeModel selectedDataVolume) {
|
||||
this.containerPath = selectedDataVolume.getContainerPath();
|
||||
this.mountType = selectedDataVolume.getMountType();
|
||||
if (this.mountType != null) {
|
||||
switch (this.mountType) {
|
||||
case CONTAINER:
|
||||
this.containerMount = selectedDataVolume.getMount();
|
||||
break;
|
||||
case HOST_FILE_SYSTEM:
|
||||
this.hostPathMount = selectedDataVolume.getMount();
|
||||
this.readOnly = selectedDataVolume.isReadOnly();
|
||||
break;
|
||||
case NONE:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.mountType = MountType.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a DataVolumeModel from a toString() output.
|
||||
*
|
||||
* @param fromString
|
||||
* @return DataVolumeModel
|
||||
*/
|
||||
public static DataVolumeModel parseString(
|
||||
final String fromString) {
|
||||
final DataVolumeModel model = new DataVolumeModel();
|
||||
final String[] items = fromString.split(SEPARATOR); // $NON-NLS-1$
|
||||
model.containerPath = items[0];
|
||||
model.mountType = MountType.valueOf(items[1]);
|
||||
switch (model.mountType) {
|
||||
case CONTAINER:
|
||||
model.setContainerMount(items[2]);
|
||||
model.setSelected(Boolean.valueOf(items[3]));
|
||||
break;
|
||||
case HOST_FILE_SYSTEM:
|
||||
// For Windows, there are multiple formats. If a user has specified
|
||||
// a windows drive using the : separator, we have to form the
|
||||
// host path by merging the path back together. If the user
|
||||
// has specified an alternate format, we don't do this.
|
||||
if (Platform.OS_WIN32.equals(Platform.getOS())
|
||||
&& items.length > 5) {
|
||||
model.setHostPathMount(items[2] + SEPARATOR + items[3]);
|
||||
model.setReadOnly(Boolean.valueOf(items[4]));
|
||||
model.setSelected(Boolean.valueOf(items[5]));
|
||||
} else {
|
||||
model.setHostPathMount(items[2]);
|
||||
model.setReadOnly(Boolean.valueOf(items[3]));
|
||||
model.setSelected(Boolean.valueOf(items[4]));
|
||||
}
|
||||
break;
|
||||
case NONE:
|
||||
model.setSelected(Boolean.valueOf(items[2]));
|
||||
break;
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a {@link DataVolumeModel} from the 'volumeFrom' container info
|
||||
*
|
||||
* @param volumeFrom
|
||||
* the value to parse.
|
||||
*
|
||||
* Format: <code><containerName></code>
|
||||
*
|
||||
* @See <a href="https://docs.docker.com/engine/userguide/dockervolumes/">
|
||||
* https://docs.docker.com/engine/userguide/dockervolumes/</a>
|
||||
*/
|
||||
public static DataVolumeModel parseVolumeFrom(String volumeFrom) {
|
||||
final DataVolumeModel model = new DataVolumeModel();
|
||||
model.mountType = MountType.CONTAINER;
|
||||
model.containerMount = volumeFrom;
|
||||
model.selected = true;
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a {@link DataVolumeModel} from the 'volumeFrom' container info
|
||||
*
|
||||
* @param volumeFrom
|
||||
* the value to parse. Format:
|
||||
* <code><host_path>:<container_path>:<label_suffix_flag></code>
|
||||
*
|
||||
* @See <a href="https://docs.docker.com/engine/userguide/dockervolumes/">
|
||||
* https://docs.docker.com/engine/userguide/dockervolumes/</a>
|
||||
*/
|
||||
public static DataVolumeModel parseHostBinding(String volumeFrom) {
|
||||
final DataVolumeModel model = new DataVolumeModel();
|
||||
final String[] items = volumeFrom.split(SEPARATOR); // $NON-NLS-1$
|
||||
// converts the host path to a valid Win32 path if Platform OS is Win32
|
||||
model.setHostPathMount(convertToWin32Path(Platform.getOS(), items[0]));
|
||||
model.containerPath = items[1];
|
||||
model.mountType = MountType.HOST_FILE_SYSTEM;
|
||||
if (items[2].equals("ro")) {
|
||||
model.setReadOnly(true);
|
||||
} else {
|
||||
model.setReadOnly(false);
|
||||
}
|
||||
model.selected = true;
|
||||
return model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given path to a portable form, replacing all "\" and ": "
|
||||
* with "/" if the given <code>os</code> is {@link Platform#OS_WIN32}.
|
||||
*
|
||||
* @param os
|
||||
* the current OS
|
||||
* @param path
|
||||
* the path to convert
|
||||
* @return the converted path or the given path
|
||||
* @see {@link Platform#getOS()}
|
||||
*/
|
||||
public static String convertToWin32Path(final String os,
|
||||
final String path) {
|
||||
if (os != null && os.equals(Platform.OS_WIN32)) {
|
||||
// replace all "/" with "\" and then drive info (eg "/c/" to "C:/")
|
||||
final Matcher m = Pattern.compile("^/([a-zA-Z])/").matcher(path); //$NON-NLS-1$
|
||||
if (m.find()) {
|
||||
final StringBuffer b = new StringBuffer();
|
||||
m.appendReplacement(b, m.group(1).toUpperCase());
|
||||
b.append(":\\"); //$NON-NLS-1$
|
||||
m.appendTail(b);
|
||||
return b.toString().replace('/', '\\'); // $NON-NLS-1$
|
||||
// //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
public String getContainerPath() {
|
||||
return this.containerPath;
|
||||
}
|
||||
|
||||
public void setContainerPath(final String containerPath) {
|
||||
firePropertyChange(CONTAINER_PATH, this.containerPath,
|
||||
this.containerPath = containerPath);
|
||||
}
|
||||
|
||||
public String getMount() {
|
||||
return mount;
|
||||
}
|
||||
|
||||
public void setMount(final String mount) {
|
||||
firePropertyChange(MOUNT, this.mount, this.mount = mount);
|
||||
}
|
||||
|
||||
public MountType getMountType() {
|
||||
return mountType;
|
||||
}
|
||||
|
||||
public void setMountType(final MountType mountType) {
|
||||
// ignore 'null' assignments that may come from the UpdateStrategy
|
||||
// in
|
||||
// the EditDataVolumePage when a radion button is unselected.
|
||||
if (mountType == null) {
|
||||
return;
|
||||
}
|
||||
firePropertyChange(MOUNT_TYPE, this.mountType,
|
||||
this.mountType = mountType);
|
||||
if (this.mountType == MountType.NONE) {
|
||||
setMount("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getHostPathMount() {
|
||||
return hostPathMount;
|
||||
}
|
||||
|
||||
public void setHostPathMount(final String hostPathMount) {
|
||||
firePropertyChange(HOST_PATH_MOUNT, this.hostPathMount,
|
||||
this.hostPathMount = hostPathMount);
|
||||
if (this.mountType == MountType.HOST_FILE_SYSTEM) {
|
||||
setMount(this.hostPathMount);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isReadOnly() {
|
||||
return readOnly;
|
||||
}
|
||||
|
||||
public void setReadOnly(final boolean readOnly) {
|
||||
firePropertyChange(READ_ONLY_VOLUME, this.readOnly,
|
||||
this.readOnly = readOnly);
|
||||
}
|
||||
|
||||
public String getContainerMount() {
|
||||
return this.containerMount;
|
||||
}
|
||||
|
||||
public void setContainerMount(final String containerMount) {
|
||||
firePropertyChange(CONTAINER_MOUNT, this.containerMount,
|
||||
this.containerMount = containerMount);
|
||||
if (this.mountType == MountType.CONTAINER) {
|
||||
setMount(this.containerMount);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getSelected() {
|
||||
return selected;
|
||||
}
|
||||
|
||||
public void setSelected(final boolean selected) {
|
||||
firePropertyChange(SELECTED, this.selected, this.selected = selected);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final DataVolumeModel other) {
|
||||
return this.getContainerPath().compareTo(other.getContainerPath());
|
||||
}
|
||||
|
||||
// FIXME we should have a dedicated method to serialize the bean
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer buffer = new StringBuffer();
|
||||
buffer.append(
|
||||
this.containerPath + SEPARATOR + getMountType() + SEPARATOR);
|
||||
switch (getMountType()) {
|
||||
case CONTAINER:
|
||||
buffer.append(getContainerMount());
|
||||
break;
|
||||
case HOST_FILE_SYSTEM:
|
||||
buffer.append(getHostPathMount() + SEPARATOR); // $NON-NLS-1$
|
||||
buffer.append(isReadOnly());
|
||||
break;
|
||||
case NONE:
|
||||
break;
|
||||
}
|
||||
buffer.append(SEPARATOR).append(this.selected);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((id == null) ? 0 : id.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;
|
||||
DataVolumeModel other = (DataVolumeModel) obj;
|
||||
if (id == null) {
|
||||
if (other.id != null)
|
||||
return false;
|
||||
} else if (!id.equals(other.id))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,13 +19,18 @@ import org.eclipse.cdt.core.model.CModelException;
|
|||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.IBinary;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||
import org.eclipse.cdt.debug.core.CDebugUtils;
|
||||
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
|
||||
import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
|
||||
import org.eclipse.cdt.dsf.gdb.IGDBLaunchConfigurationConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.IGdbDebugPreferenceConstants;
|
||||
import org.eclipse.cdt.dsf.gdb.internal.ui.GdbUIPlugin;
|
||||
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
|
||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
|
||||
import org.eclipse.cdt.ui.CElementLabelProvider;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IAdaptable;
|
||||
|
@ -253,6 +258,31 @@ public class LaunchShortcut implements ILaunchShortcut {
|
|||
ILaunchConfiguration configuration = null;
|
||||
ILaunchConfigurationType configType = getLaunchConfigType();
|
||||
List<ILaunchConfiguration> candidateConfigs = Collections.emptyList();
|
||||
IProject project = bin.getCProject().getProject();
|
||||
ICConfigurationDescription cfgd = CoreModel.getDefault()
|
||||
.getProjectDescription(project).getActiveConfiguration();
|
||||
String connectionUri = null;
|
||||
String imageName = null;
|
||||
if (cfgd != null) {
|
||||
IConfiguration cfg = ManagedBuildManager
|
||||
.getConfigurationForDescription(cfgd);
|
||||
if (cfg != null) {
|
||||
IOptionalBuildProperties props = cfg
|
||||
.getOptionalBuildProperties();
|
||||
String containerBuild = props.getProperty(
|
||||
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
|
||||
if (containerBuild != null) {
|
||||
boolean containerBuildEnabled = Boolean
|
||||
.parseBoolean(containerBuild);
|
||||
if (containerBuildEnabled) {
|
||||
connectionUri = props.getProperty(
|
||||
ContainerCommandLauncher.CONNECTION_ID);
|
||||
imageName = props
|
||||
.getProperty(ContainerCommandLauncher.IMAGE_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
ILaunchConfiguration[] configs = DebugPlugin.getDefault()
|
||||
.getLaunchManager().getLaunchConfigurations(configType);
|
||||
|
@ -265,10 +295,20 @@ public class LaunchShortcut implements ILaunchShortcut {
|
|||
if (projectName != null
|
||||
&& projectName.equals(bin.getCProject()
|
||||
.getProject().getName())) {
|
||||
// if we have an active configuration with container
|
||||
// build properties, make sure they match, otherwise
|
||||
// add the launch config as a candidate
|
||||
if (connectionUri.equals(config.getAttribute(
|
||||
ILaunchConstants.ATTR_CONNECTION_URI,
|
||||
connectionUri))) {
|
||||
if (imageName.equals(config.getAttribute(
|
||||
ILaunchConstants.ATTR_IMAGE, imageName))) {
|
||||
candidateConfigs.add(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
DockerLaunchUIPlugin.log(e);
|
||||
}
|
||||
|
@ -312,11 +352,40 @@ public class LaunchShortcut implements ILaunchShortcut {
|
|||
String binaryPath = bin.getResource().getProjectRelativePath()
|
||||
.toString();
|
||||
|
||||
IProject project = bin.getResource().getProject();
|
||||
|
||||
ICConfigurationDescription cfgd = CoreModel.getDefault()
|
||||
.getProjectDescription(project).getActiveConfiguration();
|
||||
IConfiguration cfg = ManagedBuildManager
|
||||
.getConfigurationForDescription(cfgd);
|
||||
|
||||
IOptionalBuildProperties options = cfg.getOptionalBuildProperties();
|
||||
boolean containerBuild = false;
|
||||
String connectionId = null;
|
||||
String imageName = null;
|
||||
|
||||
if (options != null) {
|
||||
String containerBuildString = options.getProperty(
|
||||
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
|
||||
if (containerBuildString != null) {
|
||||
containerBuild = Boolean.parseBoolean(options.getProperty(
|
||||
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED));
|
||||
}
|
||||
if (containerBuild) {
|
||||
connectionId = options.getProperty(
|
||||
ContainerCommandLauncher.CONNECTION_ID);
|
||||
imageName = options
|
||||
.getProperty(ContainerCommandLauncher.IMAGE_ID);
|
||||
}
|
||||
}
|
||||
|
||||
ILaunchConfigurationType configType = getLaunchConfigType();
|
||||
ILaunchConfigurationWorkingCopy wc = configType.newInstance(
|
||||
null,
|
||||
getLaunchManager().generateLaunchConfigurationName(
|
||||
bin.getElementName()));
|
||||
bin.getResource().getName() + (imageName != null
|
||||
? ("[" + imageName + "]") //$NON-NLS-1$ //$NON-NLS-2$
|
||||
: ""))); //$NON-NLS-1$
|
||||
|
||||
// DSF settings...use GdbUIPlugin preference store for defaults
|
||||
IPreferenceStore preferenceStore = GdbUIPlugin.getDefault()
|
||||
|
@ -357,19 +426,25 @@ public class LaunchShortcut implements ILaunchShortcut {
|
|||
Preferences prefs = InstanceScope.INSTANCE
|
||||
.getNode(DockerLaunchUIPlugin.PLUGIN_ID);
|
||||
|
||||
// get the connection from the ConnectionListener which waits for
|
||||
// any activity
|
||||
// from the DockerExplorerView
|
||||
IDockerConnection connection = ConnectionListener.getInstance()
|
||||
// get the connection using following order:
|
||||
// 1. connection used in build of project
|
||||
// 2. current connection
|
||||
// 3. first connection
|
||||
IDockerConnection connection = null;
|
||||
if (connectionId != null) {
|
||||
connection = DockerConnectionManager.getInstance()
|
||||
.getConnectionByUri(connectionId);
|
||||
}
|
||||
if (connection == null) {
|
||||
connection = ConnectionListener.getInstance()
|
||||
.getCurrentConnection();
|
||||
}
|
||||
if (connection == null) {
|
||||
IDockerConnection[] connections = DockerConnectionManager
|
||||
.getInstance().getConnections();
|
||||
if (connections != null && connections.length > 0)
|
||||
connection = DockerConnectionManager.getInstance()
|
||||
.getConnections()[0];
|
||||
connection = connections[0];
|
||||
}
|
||||
|
||||
// issue error message if no connections exist
|
||||
if (connection == null) {
|
||||
Display.getDefault().syncExec(new Runnable() {
|
||||
|
@ -389,9 +464,14 @@ public class LaunchShortcut implements ILaunchShortcut {
|
|||
wc.setAttribute(ILaunchConstants.ATTR_CONNECTION_URI,
|
||||
connection.getUri());
|
||||
|
||||
// get any default image if specified, otherwise use first
|
||||
// use build image if one is specified, otherwise, see if a default
|
||||
// image is set in preferences, otherwise find first image in image
|
||||
// list
|
||||
// image in image list for connection
|
||||
String image = prefs.get(PreferenceConstants.DEFAULT_IMAGE, null);
|
||||
String image = imageName;
|
||||
if (image == null) {
|
||||
image = prefs.get(PreferenceConstants.DEFAULT_IMAGE, null);
|
||||
}
|
||||
if (image == null) {
|
||||
List<IDockerImage> images = connection.getImages();
|
||||
if (images != null && images.size() > 0)
|
||||
|
|
|
@ -47,6 +47,13 @@ public class Messages extends NLS {
|
|||
public static String ContainerTab_Warning_Connection_Not_Found;
|
||||
public static String ContainerTab_Warning_Image_Not_Found;
|
||||
|
||||
public static String HeaderPreferencePage_Connection_Label;
|
||||
public static String HeaderPreferencePage_Image_Label;
|
||||
public static String HeaderPreferencePage_Remove_Label;
|
||||
public static String HeaderPreferencePage_Remove_Tooltip;
|
||||
public static String HeaderPreferencePage_Confirm_Removal_Title;
|
||||
public static String HeaderPreferencePage_Confirm_Removal_Msg;
|
||||
|
||||
public static String Remote_GDB_Debugger_Options;
|
||||
public static String Gdbserver_Settings_Tab_Name;
|
||||
public static String Gdbserver_name_textfield_label;
|
||||
|
@ -90,6 +97,14 @@ public class Messages extends NLS {
|
|||
|
||||
public static String StandardGDBDebuggerPage14;
|
||||
|
||||
public static String ContainerPropertyTab_Title;
|
||||
public static String ContainerPropertyTab_Enable_Msg;
|
||||
|
||||
public static String ContainerCommandLauncher_image_msg;
|
||||
public static String CommandLauncher_CommandCancelled;
|
||||
|
||||
public static String ContainerCommandLauncher_invalid_values;
|
||||
|
||||
static {
|
||||
// initialize resource bundle
|
||||
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
|
||||
|
|
|
@ -44,8 +44,21 @@ public class SWTImagesFactory {
|
|||
private static final int NAME_PREFIX_LENGTH = NAME_PREFIX.length();
|
||||
public static final String IMG_CONTAINER = NAME_PREFIX
|
||||
+ "repository-middle.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_FOLDER_CLOSED = NAME_PREFIX
|
||||
+ "folder_closed.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_FILE = NAME_PREFIX + "file_obj.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_WARNING = NAME_PREFIX + "warning_obj.gif"; //$NON-NLS-1$
|
||||
public static final String IMG_ERROR = NAME_PREFIX + "error_obj.gif"; //$NON-NLS-1$
|
||||
|
||||
public static final ImageDescriptor DESC_CONTAINER = createManaged("",
|
||||
IMG_CONTAINER);
|
||||
public static final ImageDescriptor DESC_FOLDER_CLOSED = createManaged("",
|
||||
IMG_FOLDER_CLOSED);
|
||||
public static final ImageDescriptor DESC_FILE = createManaged("", IMG_FILE);
|
||||
public static final ImageDescriptor DESC_WARNING = createManaged("",
|
||||
IMG_WARNING);
|
||||
public static final ImageDescriptor DESC_ERROR = createManaged("",
|
||||
IMG_ERROR);
|
||||
|
||||
private static ImageDescriptor createManaged(String prefix, String name) {
|
||||
return createManaged(imageRegistry, prefix, name);
|
||||
|
|
|
@ -40,6 +40,21 @@ ContainerTab_Error_No_Images=No Docker Images exist
|
|||
ContainerTab_Warning_Connection_Not_Found=Docker Connection: {0} for Launch Configuration not found: defaulting to {1}
|
||||
ContainerTab_Warning_Image_Not_Found=Docker Image: {0} is not a valid pulled image in current Connection: {1}
|
||||
|
||||
ContainerPropertyTab_Title=Container Settings
|
||||
ContainerPropertyTab_Enable_Msg=Build inside Docker Image
|
||||
|
||||
HeaderPreferencePage_Connection_Label=Connection
|
||||
HeaderPreferencePage_Image_Label=Image
|
||||
HeaderPreferencePage_Remove_Label=Remove
|
||||
HeaderPreferencePage_Remove_Tooltip=Remove headers cached from Docker image
|
||||
HeaderPreferencePage_Confirm_Removal_Title=Confirm Header File Removal
|
||||
HeaderPreferencePage_Confirm_Removal_Msg=Confirm removal of specified cached header files
|
||||
|
||||
ContainerCommandLauncher_image_msg=[Running in image <{0}>]
|
||||
ContainerCommandLauncher_invalid_values=Invalid values for Connection and/or Image name
|
||||
|
||||
CommandLauncher_CommandCancelled=Command cancelled
|
||||
|
||||
Remote_GDB_Debugger_Options=Docker Container GDB Debugger Options
|
||||
Gdbserver_Settings_Tab_Name=Gdbserver Settings
|
||||
Gdbserver_name_textfield_label=Gdbserver path:
|
||||
|
|
|
@ -0,0 +1,356 @@
|
|||
package org.eclipse.cdt.internal.docker.launcher.ui.preferences;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin;
|
||||
import org.eclipse.cdt.internal.docker.launcher.Messages;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jface.dialogs.MessageDialog;
|
||||
import org.eclipse.jface.preference.PreferencePage;
|
||||
import org.eclipse.jface.viewers.ColumnWeightData;
|
||||
import org.eclipse.jface.viewers.ILabelProviderListener;
|
||||
import org.eclipse.jface.viewers.IStructuredContentProvider;
|
||||
import org.eclipse.jface.viewers.ITableLabelProvider;
|
||||
import org.eclipse.jface.viewers.TableLayout;
|
||||
import org.eclipse.jface.viewers.TableViewer;
|
||||
import org.eclipse.jface.viewers.Viewer;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.TableColumn;
|
||||
import org.eclipse.ui.IWorkbench;
|
||||
import org.eclipse.ui.IWorkbenchPreferencePage;
|
||||
|
||||
public class DockerHeaderPreferencePage extends PreferencePage
|
||||
implements IWorkbenchPreferencePage, Listener {
|
||||
|
||||
// SWT Widgets and content providers
|
||||
private Table hdrTable;
|
||||
private TableViewer hdrTableViewer;
|
||||
private HeaderContentProvider provider;
|
||||
private Button removeButton;
|
||||
private List<IPath> directories;
|
||||
|
||||
private final class HeaderContentProvider
|
||||
implements IStructuredContentProvider, ITableLabelProvider {
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(Object)
|
||||
*/
|
||||
@Override
|
||||
public Object[] getElements(Object inputElement) {
|
||||
return directories.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jface.viewers.IContentProvider#dispose()
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jface.viewers.IContentProvider#inputChanged(Viewer,
|
||||
* Object, Object)
|
||||
*/
|
||||
@Override
|
||||
public void inputChanged(Viewer viewer, Object oldInput,
|
||||
Object newInput) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(Object,
|
||||
* int)
|
||||
*/
|
||||
@Override
|
||||
public Image getColumnImage(Object element, int columnIndex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String readNameFile(IPath path) {
|
||||
// try and read real name from special .name file found in
|
||||
// directory.
|
||||
IPath namePath = path.append(".name"); //$NON-NLS-1$
|
||||
// default to use last directory segment if any problems occur.
|
||||
String name = path.lastSegment();
|
||||
if (namePath.toFile().exists()) {
|
||||
try (FileReader reader = new FileReader(namePath.toFile());
|
||||
BufferedReader bufferReader = new BufferedReader(
|
||||
reader);) {
|
||||
name = bufferReader.readLine();
|
||||
} catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(Object,
|
||||
* int)
|
||||
*/
|
||||
@Override
|
||||
public String getColumnText(Object element, int columnIndex) {
|
||||
IPath path = (IPath) element;
|
||||
if (columnIndex == 0) {
|
||||
IPath connectionPath = path.removeLastSegments(1);
|
||||
String connectionName = readNameFile(connectionPath);
|
||||
return connectionName;
|
||||
}
|
||||
String imageName = readNameFile(path);
|
||||
return imageName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(ILabelProviderListener)
|
||||
*/
|
||||
@Override
|
||||
public void addListener(ILabelProviderListener listener) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(Object,
|
||||
* String)
|
||||
*/
|
||||
@Override
|
||||
public boolean isLabelProperty(Object element, String property) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(ILabelProviderListener)
|
||||
*/
|
||||
@Override
|
||||
public void removeListener(ILabelProviderListener listener) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public DockerHeaderPreferencePage() {
|
||||
noDefaultAndApplyButton();
|
||||
provider = new HeaderContentProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(IWorkbench workbench) {
|
||||
directories = new ArrayList<>();
|
||||
IPath pluginPath = Platform
|
||||
.getStateLocation(
|
||||
Platform.getBundle(DockerLaunchUIPlugin.PLUGIN_ID))
|
||||
.append("HEADERS"); //$NON-NLS-1$
|
||||
File d = pluginPath.toFile();
|
||||
|
||||
if (d.exists() && d.isDirectory()) {
|
||||
File[] connections = d.listFiles();
|
||||
for (File connection : connections) {
|
||||
if (connection.isDirectory()) {
|
||||
File[] images = connection.listFiles();
|
||||
for (File image : images) {
|
||||
if (image.isDirectory()) {
|
||||
directories
|
||||
.add(pluginPath.append(connection.getName())
|
||||
.append(image.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Control createContents(Composite parent) {
|
||||
Composite page = createComposite(parent, 1, 2, false, null, -1, -1,
|
||||
GridData.FILL);
|
||||
GridData gd = (GridData) page.getLayoutData();
|
||||
gd.grabExcessHorizontalSpace = true;
|
||||
gd.grabExcessVerticalSpace = true;
|
||||
|
||||
// SystemWidgetHelpers.createLabel(page,
|
||||
// SystemResources.RESID_PREF_SIGNON_DESCRIPTION, 2);
|
||||
|
||||
// Header table
|
||||
hdrTable = new Table(page, SWT.FULL_SELECTION | SWT.MULTI | SWT.V_SCROLL
|
||||
| SWT.H_SCROLL | SWT.BORDER);
|
||||
hdrTable.setLinesVisible(true);
|
||||
hdrTable.setHeaderVisible(true);
|
||||
hdrTable.addListener(SWT.Selection, this);
|
||||
|
||||
TableLayout tableLayout = new TableLayout();
|
||||
tableLayout.addColumnData(new ColumnWeightData(60, true));
|
||||
tableLayout.addColumnData(new ColumnWeightData(40, true));
|
||||
hdrTable.setLayout(tableLayout);
|
||||
|
||||
gd = new GridData(GridData.FILL_BOTH);
|
||||
gd.grabExcessHorizontalSpace = true;
|
||||
gd.grabExcessVerticalSpace = true;
|
||||
|
||||
hdrTable.setLayoutData(gd);
|
||||
|
||||
// Connection column
|
||||
TableColumn connectionColumn = new TableColumn(hdrTable, SWT.NONE);
|
||||
connectionColumn
|
||||
.setText(Messages.HeaderPreferencePage_Connection_Label);
|
||||
|
||||
// Image column
|
||||
TableColumn imageColumn = new TableColumn(hdrTable, SWT.NONE);
|
||||
imageColumn.setText(Messages.HeaderPreferencePage_Image_Label);
|
||||
|
||||
hdrTableViewer = new TableViewer(hdrTable);
|
||||
hdrTableViewer.setContentProvider(provider);
|
||||
hdrTableViewer.setLabelProvider(provider);
|
||||
hdrTableViewer.setInput(directories);
|
||||
|
||||
// Create the Button bar for add, change and remove
|
||||
Composite buttonBar = createComposite(page, 1, 1, false, null, -1, -1,
|
||||
GridData.FILL);
|
||||
gd = (GridData) buttonBar.getLayoutData();
|
||||
gd.grabExcessHorizontalSpace = false;
|
||||
gd.grabExcessVerticalSpace = true;
|
||||
|
||||
removeButton = createPushButton(buttonBar, this,
|
||||
Messages.HeaderPreferencePage_Remove_Label,
|
||||
Messages.HeaderPreferencePage_Remove_Tooltip);
|
||||
|
||||
removeButton.setEnabled(false);
|
||||
return parent;
|
||||
}
|
||||
|
||||
private static Composite createComposite(Composite parent, int parentSpan,
|
||||
int numColumns, boolean border, String label, int marginSize,
|
||||
int spacingSize, int verticalAlignment) {
|
||||
// border = true;
|
||||
boolean borderNeeded = border;
|
||||
if (label != null)
|
||||
borderNeeded = true; // force the case
|
||||
int style = SWT.NULL;
|
||||
if (borderNeeded)
|
||||
style |= SWT.SHADOW_ETCHED_IN;
|
||||
Composite composite = null;
|
||||
if (borderNeeded) {
|
||||
composite = new Group(parent, style);
|
||||
if (label != null)
|
||||
((Group) composite).setText(label);
|
||||
} else {
|
||||
composite = new Composite(parent, style);
|
||||
}
|
||||
// GridLayout
|
||||
GridLayout layout = new GridLayout();
|
||||
layout.numColumns = numColumns;
|
||||
if (marginSize != -1) {
|
||||
layout.marginWidth = 0;
|
||||
layout.marginHeight = 0;
|
||||
}
|
||||
if (spacingSize != -1) {
|
||||
layout.horizontalSpacing = 0;
|
||||
layout.verticalSpacing = 0;
|
||||
}
|
||||
composite.setLayout(layout);
|
||||
// GridData
|
||||
GridData data = new GridData();
|
||||
data.horizontalSpan = parentSpan;
|
||||
data.horizontalAlignment = GridData.FILL;
|
||||
data.grabExcessHorizontalSpace = true;
|
||||
|
||||
data.verticalAlignment = verticalAlignment;
|
||||
data.grabExcessVerticalSpace = false;
|
||||
|
||||
composite.setLayoutData(data);
|
||||
return composite;
|
||||
}
|
||||
|
||||
public static Button createPushButton(Composite group, Listener listener,
|
||||
String label, String tooltip) {
|
||||
Button button = new Button(group, SWT.PUSH);
|
||||
button.setText(label);
|
||||
if (listener != null)
|
||||
button.addListener(SWT.Selection, listener);
|
||||
GridData data = new GridData();
|
||||
data.horizontalAlignment = GridData.FILL;
|
||||
data.grabExcessHorizontalSpace = true;
|
||||
button.setLayoutData(data);
|
||||
if (tooltip != null)
|
||||
button.setToolTipText(tooltip);
|
||||
return button;
|
||||
}
|
||||
|
||||
private class DialogStatus {
|
||||
private boolean status;
|
||||
|
||||
public DialogStatus(boolean status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public void setStatus(boolean status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public boolean getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.swt.widgets.Listener#handleEvent(Event)
|
||||
*/
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
if (event.type == SWT.Selection) {
|
||||
if (event.widget == removeButton) {
|
||||
final DialogStatus confirmed = new DialogStatus(false);
|
||||
Display.getDefault().syncExec(() -> {
|
||||
boolean status = MessageDialog.openConfirm(getShell(),
|
||||
Messages.HeaderPreferencePage_Confirm_Removal_Title,
|
||||
Messages.HeaderPreferencePage_Confirm_Removal_Msg);
|
||||
confirmed.setStatus(status);
|
||||
});
|
||||
if (!confirmed.getStatus()) {
|
||||
return;
|
||||
}
|
||||
int[] indicies = hdrTable.getSelectionIndices();
|
||||
for (int idx = indicies.length - 1; idx >= 0; idx--) {
|
||||
IPath dirPath = directories.get(idx);
|
||||
File f = dirPath.toFile();
|
||||
if (f.exists() && f.isDirectory()) {
|
||||
recursiveDelete(f);
|
||||
}
|
||||
directories.remove(idx);
|
||||
}
|
||||
|
||||
hdrTableViewer.refresh();
|
||||
}
|
||||
|
||||
// Update table buttons based on changes
|
||||
if (hdrTable.getSelectionCount() > 0) {
|
||||
removeButton.setEnabled(true);
|
||||
} else {
|
||||
removeButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void recursiveDelete(File dir) {
|
||||
File[] contents = dir.listFiles();
|
||||
if (contents != null) {
|
||||
for (File f : contents) {
|
||||
recursiveDelete(f);
|
||||
}
|
||||
}
|
||||
dir.delete();
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ import java.net.URI;
|
|||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.cdt.core.CommandLauncher;
|
||||
import org.eclipse.cdt.core.CommandLauncherManager;
|
||||
import org.eclipse.cdt.core.ICommandLauncher;
|
||||
import org.eclipse.cdt.remote.internal.core.Activator;
|
||||
import org.eclipse.cdt.remote.internal.core.messages.Messages;
|
||||
|
@ -41,6 +41,8 @@ public class RemoteCommandLauncher implements ICommandLauncher {
|
|||
|
||||
private static final String CYGWIN_PREFIX = "cygdrive"; //$NON-NLS-1$
|
||||
|
||||
private boolean usingLocalLauncher = false;
|
||||
|
||||
/**
|
||||
* Convert a local (workspace) path into the remote equivalent. If the local path is not
|
||||
* absolute, then do nothing.
|
||||
|
@ -102,7 +104,7 @@ public class RemoteCommandLauncher implements ICommandLauncher {
|
|||
return s;
|
||||
}
|
||||
|
||||
private final ICommandLauncher fLocalLauncher = new CommandLauncher();
|
||||
private ICommandLauncher fLocalLauncher = CommandLauncherManager.getInstance().getCommandLauncher();
|
||||
private boolean fShowCommand;
|
||||
private String[] fCommandArgs;
|
||||
private IRemoteConnection fConnection;
|
||||
|
@ -129,13 +131,18 @@ public class RemoteCommandLauncher implements ICommandLauncher {
|
|||
@Override
|
||||
public Process execute(IPath commandPath, String[] args, String[] env, IPath workingDirectory, IProgressMonitor monitor)
|
||||
throws CoreException {
|
||||
ICommandLauncher localLauncher = CommandLauncherManager.getInstance().getCommandLauncher(getProject());
|
||||
localLauncher.setProject(getProject());
|
||||
localLauncher.setErrorMessage(getErrorMessage());
|
||||
usingLocalLauncher = false;
|
||||
fLocalLauncher = localLauncher;
|
||||
if (getProject() != null) {
|
||||
IRemoteResource remRes = (IRemoteResource) getProject().getAdapter(IRemoteResource.class);
|
||||
if (remRes != null) {
|
||||
URI uri = remRes.getActiveLocationURI();
|
||||
IRemoteServicesManager remoteServicesManager = Activator.getService(IRemoteServicesManager.class);
|
||||
IRemoteConnectionType connectionType = remoteServicesManager.getConnectionType(uri);
|
||||
if (connectionType != null) {
|
||||
if (connectionType != null && !connectionType.getScheme().equals("file")) { //$NON-NLS-1$
|
||||
fConnection = connectionType.getConnection(uri);
|
||||
if (fConnection != null) {
|
||||
parseEnvironment(env);
|
||||
|
@ -163,16 +170,23 @@ public class RemoteCommandLauncher implements ICommandLauncher {
|
|||
}
|
||||
}
|
||||
}
|
||||
usingLocalLauncher = true;
|
||||
return fLocalLauncher.execute(commandPath, args, env, workingDirectory, monitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getCommandArgs() {
|
||||
if (usingLocalLauncher) {
|
||||
return fLocalLauncher.getCommandArgs();
|
||||
}
|
||||
return fCommandArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandLine() {
|
||||
if (usingLocalLauncher) {
|
||||
return fLocalLauncher.getCommandLine();
|
||||
}
|
||||
return getCommandLine(fCommandArgs);
|
||||
}
|
||||
|
||||
|
@ -202,6 +216,9 @@ public class RemoteCommandLauncher implements ICommandLauncher {
|
|||
|
||||
@Override
|
||||
public Properties getEnvironment() {
|
||||
if (usingLocalLauncher) {
|
||||
return fLocalLauncher.getEnvironment();
|
||||
}
|
||||
return fEnvironment;
|
||||
}
|
||||
|
||||
|
@ -261,8 +278,15 @@ public class RemoteCommandLauncher implements ICommandLauncher {
|
|||
fShowCommand = show;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public int waitAndRead(OutputStream out, OutputStream err) {
|
||||
|
||||
if (usingLocalLauncher) {
|
||||
return fLocalLauncher.waitAndRead(out, err);
|
||||
}
|
||||
|
||||
// otherwise remote process
|
||||
if (fShowCommand) {
|
||||
printCommandLine(out);
|
||||
}
|
||||
|
@ -278,6 +302,11 @@ public class RemoteCommandLauncher implements ICommandLauncher {
|
|||
|
||||
@Override
|
||||
public int waitAndRead(OutputStream out, OutputStream err, IProgressMonitor monitor) {
|
||||
if (usingLocalLauncher) {
|
||||
return fLocalLauncher.waitAndRead(out, err, monitor);
|
||||
}
|
||||
|
||||
// otherwise remote process
|
||||
if (fShowCommand) {
|
||||
printCommandLine(out);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue