1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-06 00:25:25 +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 CommandLauncherFactoryManager 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
  CommandLauncherFactoryManager 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 CommandLauncherFactoryManager to get
  its ICommandLauncher
- change CommandBuilder to use CommandLauncherFactoryManager 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.managedbuilder.core to 8.5.0
- 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

Change-Id: Id4d202d5eeb0dd52e528a45bf44d3e386f67376d
This commit is contained in:
Jeff Johnston 2017-02-09 18:43:05 -05:00
parent 195ae12776
commit db3ee42b31
39 changed files with 1676 additions and 44 deletions

View file

@ -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[] =
@ -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[] =

View file

@ -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.CommandLauncherFactoryManager;
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 = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
launcher.setProject(project);
OutputStream stdout = new ByteArrayOutputStream();
OutputStream stderr = new ByteArrayOutputStream();

View file

@ -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.CommandLauncherFactoryManager;
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 = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
String[] targets = getTargets(kind, info);
if (targets.length != 0 && targets[targets.length - 1].equals(info.getCleanBuildTarget()))

View file

@ -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.CommandLauncherFactoryManager;
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 = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
launcher.setProject(project);
IPath program = getCommandToLaunch();

View file

@ -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();
}

View file

@ -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.

View file

@ -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$

View file

@ -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$

View file

@ -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();
}

View file

@ -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$

View file

@ -18,7 +18,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.cdt.core.CommandLauncher;
import org.eclipse.cdt.core.CommandLauncherFactoryManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand;
import org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin;
@ -143,7 +143,7 @@ public class CommandBuilder implements IBuildModelBuilder {
}
protected ICommandLauncher createLauncher() {
return new CommandLauncher();
return CommandLauncherFactoryManager.getInstance().getCommandLauncher();
}
public String getErrMsg() {

View file

@ -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.CommandLauncherFactoryManager;
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 = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
return fCommandLauncher;
}

View file

@ -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(props != 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());
}

View file

@ -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();

View file

@ -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) {

View file

@ -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();
}
}

View file

@ -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();

View file

@ -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.CommandLauncherFactoryManager;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.ICommandLauncher;
import org.eclipse.cdt.core.IConsoleParser;
@ -656,7 +656,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
}
console.start(currentProject);
ICommandLauncher launcher = new CommandLauncher();
ICommandLauncher launcher = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
launcher.setProject(currentProject);
IPath program = new Path(""); //$NON-NLS-1$

View file

@ -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; }

View file

@ -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() {

View file

@ -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.CommandLauncherFactoryManager;
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 = CommandLauncherFactoryManager.getInstance().getCommandLauncher();
launcher.showCommand(true);
launcher.setProject(project);
Process p = launcher.execute(commandPath, commandArgs, commandEnv, workingDirectory, new SubProgressMonitor(monitor, 50));

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.core; singleton:=true
Bundle-Version: 6.3.1.qualifier
Bundle-Version: 6.3.0.qualifier
Bundle-Activator: org.eclipse.cdt.core.CCorePlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin

View file

@ -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">

View file

@ -0,0 +1,122 @@
<?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>
<element ref="cextension"/>
</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="cextension">
<complexType>
<sequence>
<element ref="run"/>
</sequence>
</complexType>
</element>
<element name="run">
<complexType>
<attribute name="class" type="string" use="required">
<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.3.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 &lt;samp&gt;org.eclipse.cdt.core.ICommandLauncherFactory&lt;/samp&gt; 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.&lt;br/&gt;
All rights reserved. This program and the accompanying materials&lt;br/&gt;
are made available under the terms of the Eclipse Public License v1.0&lt;br/&gt;
which accompanies this distribution, and is available at&lt;br/&gt;
http://www.eclipse.org/legal/epl-v10.html&lt;br/&gt;
</documentation>
</annotation>
</schema>

View file

@ -147,6 +147,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$

View file

@ -0,0 +1,206 @@
/*******************************************************************************
* 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.List;
import java.util.Properties;
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 CommandLauncherFactoryManager {
private static CommandLauncherFactoryManager instance;
private List<ICommandLauncherFactory> factories = new ArrayList<>();
private CommandLauncherFactoryManager() {
loadCommandLauncherFactoryExtensions();
}
public static synchronized CommandLauncherFactoryManager getInstance() {
if (instance == null) {
instance = new CommandLauncherFactoryManager();
}
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 CommandLauncherFactoryManager manager;
public CommandLauncherWrapper(CommandLauncherFactoryManager 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);
}
@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 - optional input to determine launcher.
* @return an ICommandLauncher for running commands
*/
public ICommandLauncher getCommandLauncher(IProject project) {
// loop through list of factories and return first launcher
// returned
for (ICommandLauncherFactory factory : factories) {
ICommandLauncher launcher = factory.getCommandLauncher(project);
if (launcher != null) {
return launcher;
}
}
// 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[] = extension.getConfigurationElements();
for (IConfigurationElement element2 : element) {
if (element2.getName().equalsIgnoreCase("cextension")) { //$NON-NLS-1$
ICommandLauncherFactory factory = (ICommandLauncherFactory) element2.createExecutableExtension("run"); //$NON-NLS-1$
factories.add(factory);
}
}
} catch (Exception e) {
CCorePlugin.log("Cannot load CommandLauncherFactory extension " + ext.getUniqueIdentifier(), e); //$NON-NLS-1$
}
}
}
}
}

View file

@ -0,0 +1,27 @@
/*******************************************************************************
* 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 org.eclipse.core.resources.IProject;
/**
* @since 6.3
*/
public interface ICommandLauncherFactory {
/**
* Get a Command Launcher for a project (optional)
* @param project - optional parameter to help determine appropriate launcher
* @return ICommandLauncher or null if not appropriate for project
*/
public ICommandLauncher getCommandLauncher(IProject project);
}

View file

@ -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;
}

View file

@ -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,9 @@ 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
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.cdt.docker.launcher;x-internal:=true,

View file

@ -16,3 +16,8 @@ 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
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

View file

@ -88,5 +88,25 @@
id="org.eclipse.cdt.docker.launcher.launchConfigurationTypeImage1">
</launchConfigurationTypeImage>
</extension>
<extension
id="ContainerCommandLauncherFactory"
name="%ContainerCommandLauncherFactory.name"
point="org.eclipse.cdt.core.CommandLauncherFactory">
<cextension>
<run
class="org.eclipse.cdt.docker.launcher.ContainerCommandLauncherFactory">
</run>
</cextension>
</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>

View file

@ -0,0 +1,50 @@
/*******************************************************************************
* 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 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.ICConfigurationDescription;
import org.eclipse.cdt.internal.docker.launcher.ContainerCommandLauncher;
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;
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);
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;
}
}

View file

@ -0,0 +1,353 @@
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.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.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 = "org.eclipse.cdt.docker.launcher.containerbuild.property.enablement"; // $NON-NLS-0$
public final static String CONNECTION_ID = "org.eclipse.cdt.docker.launcher.containerbuild.property.connection"; // $NON-NLS-0$
public final static String IMAGE_ID = "org.eclipse.cdt.docker.launcher.containerbuild.property.image"; // $NON-NLS-0$
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<>();
ArrayList<String> commandSegments = new ArrayList<>();
StringBuilder b = new StringBuilder();
b.append(commandPath.toString().trim());
commandSegments.add(commandPath.toString().trim());
for (String arg : args) {
b.append(" "); //$NON-NLS-1$
String realArg = VariablesPlugin.getDefault()
.getStringVariableManager().performStringSubstitution(arg);
b.append(realArg);
if (realArg.startsWith("/")) { //$NON-NLS-1$
// check if file exists and if so, add an additional directory
IPath p = new Path(realArg);
if (p.isValidPath(realArg)) {
p = p.makeAbsolute();
File f = p.toFile();
if (f.exists()) {
if (f.isFile()) {
p = p.removeLastSegments(1);
}
additionalDirs.add(p.toPortableString());
}
}
}
commandSegments.add(realArg);
}
commandArgs = commandSegments.toArray(new String[0]);
String commandDir = commandPath.removeLastSegments(1).toString();
if (commandDir.isEmpty()) {
commandDir = null;
}
IProject[] referencedProjects = fProject.getReferencedProjects();
for (IProject referencedProject : referencedProjects) {
additionalDirs
.add(referencedProject.getLocation().toPortableString());
}
String command = b.toString();
String workingDir = workingDirectory.toPortableString();
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();
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);
}
}

View file

@ -79,7 +79,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;
}

View file

@ -0,0 +1,428 @@
/*******************************************************************************
* 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.internal.docker.launcher;
import java.util.ArrayList;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICMultiConfigDescription;
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
import org.eclipse.cdt.managedbuilder.buildproperties.IOptionalBuildProperties;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IMultiConfiguration;
import org.eclipse.cdt.managedbuilder.internal.core.Configuration;
import org.eclipse.cdt.managedbuilder.ui.properties.AbstractCBuildPropertyTab;
import org.eclipse.linuxtools.docker.core.DockerConnectionManager;
import org.eclipse.linuxtools.docker.core.IDockerConnection;
import org.eclipse.linuxtools.docker.core.IDockerConnectionManagerListener;
import org.eclipse.linuxtools.docker.core.IDockerImage;
import org.eclipse.linuxtools.docker.core.IDockerImageListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
@SuppressWarnings("restriction")
public class ContainerPropertyTab extends AbstractCBuildPropertyTab
implements IDockerConnectionManagerListener, IDockerImageListener {
private Combo imageCombo;
private Combo connectionSelector;
private Button enableButton;
private IDockerConnection connection;
private IDockerConnection[] connections;
private IDockerImageListener containerTab;
private String connectionName;
private String connectionUri = ""; //$NON-NLS-1$
private boolean defaultEnabled;
private String defaultConnection;
private String defaultImage;
private IConfiguration iCfg;
private IOptionalBuildProperties properties;
private ModifyListener connectionModifyListener = new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
int index = connectionSelector.getSelectionIndex();
if (connection != null)
connection.removeImageListener(containerTab);
connection = connections[index];
connectionUri = connection.getUri();
if (!connectionName.equals(connection.getName())) {
imageCombo.setText("");
defaultImage = null;
}
connectionName = connection.getName();
properties.setProperty(ContainerCommandLauncher.CONNECTION_ID,
connectionUri);
properties.setProperty(ContainerCommandLauncher.IMAGE_ID,
imageCombo.getText());
}
};
public ContainerPropertyTab() {
this.containerTab = this;
}
@Override
public void createControls(Composite parent) {
super.createControls(parent);
usercomp.setLayout(new GridLayout(5, false));
usercomp.setFont(parent.getFont());
GridData gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 1;
usercomp.setLayoutData(gd);
enableButton = new Button(usercomp, SWT.CHECK);
enableButton.setText(Messages.ContainerPropertyTab_Enable_Msg);
iCfg = getCfg();
properties = iCfg.getOptionalBuildProperties();
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 5;
enableButton.setLayoutData(gd);
Label connectionSelectorLabel = new Label(usercomp, SWT.NULL);
connectionSelectorLabel
.setText(Messages.ContainerTab_Connection_Selector_Label);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 1;
gd.grabExcessHorizontalSpace = false;
connectionSelectorLabel.setLayoutData(gd);
connectionSelector = new Combo(usercomp, SWT.BORDER | SWT.READ_ONLY);
initializeConnectionSelector(iCfg);
connectionSelector.addModifyListener(connectionModifyListener);
// Following is a kludge so that on Linux the Combo is read-only but
// has a white background.
connectionSelector.addVerifyListener(new VerifyListener() {
@Override
public void verifyText(VerifyEvent e) {
e.doit = false;
}
});
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 4;
gd.grabExcessHorizontalSpace = true;
connectionSelector.setLayoutData(gd);
Label imageSelectorLabel = new Label(usercomp, SWT.NULL);
imageSelectorLabel.setText(Messages.ContainerTab_Image_Selector_Label);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 1;
connectionSelectorLabel.setLayoutData(gd);
imageCombo = new Combo(usercomp, SWT.DROP_DOWN);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.horizontalSpan = 4;
gd.grabExcessHorizontalSpace = true;
imageCombo.setLayoutData(gd);
initializeImageCombo(iCfg);
imageCombo.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
properties.setProperty(ContainerCommandLauncher.IMAGE_ID,
imageCombo.getText());
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
}
});
initializeEnablementButton(iCfg);
enableButton.addSelectionListener(new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent e) {
setControlsEnabled(enableButton.getSelection());
properties.setProperty(
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED,
Boolean.toString(enableButton.getSelection()));
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// ignore
}
});
}
private void setControlsEnabled(boolean enabled) {
imageCombo.setEnabled(enabled);
connectionSelector.setEnabled(enabled);
}
private void initializeEnablementButton(IConfiguration cfg) {
defaultEnabled = false;
IOptionalBuildProperties properties = cfg.getOptionalBuildProperties();
String savedEnabled = properties
.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
if (savedEnabled != null) {
defaultEnabled = Boolean
.parseBoolean(savedEnabled);
}
enableButton.setSelection(defaultEnabled);
setControlsEnabled(defaultEnabled);
}
private void initializeConnectionSelector(IConfiguration cfg) {
int defaultIndex = -1;
defaultConnection = null;
String id = properties
.getProperty(ContainerCommandLauncher.CONNECTION_ID);
if (id != null) {
defaultConnection = id;
}
connections = DockerConnectionManager.getInstance().getConnections();
if (connections.length == 0) {
// setErrorMessage(Messages.ContainerTab_Error_No_Connections);
return;
}
String[] connectionNames = new String[connections.length];
for (int i = 0; i < connections.length; ++i) {
connectionNames[i] = connections[i].getName();
if (connections[i].getUri().equals(defaultConnection))
defaultIndex = i;
}
if (defaultIndex < 0) {
defaultEnabled = false;
defaultIndex = 0;
}
connectionSelector.setItems(connectionNames);
if (connections.length > 0) {
connectionSelector.select(defaultIndex);
connection = connections[defaultIndex];
connectionName = connection.getName();
connectionUri = connection.getUri();
defaultConnection = connectionUri;
}
}
private void initializeImageCombo(IConfiguration cfg) {
defaultImage = null;
String id = properties
.getProperty(ContainerCommandLauncher.IMAGE_ID);
if (id != null) {
defaultImage = id;
}
if (connection != null) {
java.util.List<IDockerImage> images = connection.getImages();
if (images == null || images.size() == 0) {
// setsetErrorMessage(Messages.ContainerTab_Error_No_Images);
return;
}
connection.removeImageListener(containerTab);
ArrayList<String> imageNames = new ArrayList<String>();
for (IDockerImage image : images) {
java.util.List<String> tags = image.repoTags();
if (tags != null) {
for (String tag : tags) {
if (!tag.equals("<none>:<none>")) //$NON-NLS-1$
imageNames.add(tag);
}
}
}
imageCombo.setItems(imageNames.toArray(new String[0]));
if (defaultImage != null) {
int index = imageCombo.indexOf(defaultImage);
if (index > -1) {
imageCombo.getItem(index);
imageCombo.select(index);
} else {
}
}
connection.addImageListener(containerTab);
}
}
@Override
protected void performApply(ICResourceDescription src,
ICResourceDescription dst) {
if (page.isMultiCfg()) {
ICMultiConfigDescription mc1 = (ICMultiConfigDescription) src
.getConfiguration();
ICMultiConfigDescription mc2 = (ICMultiConfigDescription) dst
.getConfiguration();
ICConfigurationDescription[] cds1 = (ICConfigurationDescription[]) mc1
.getItems();
ICConfigurationDescription[] cds2 = (ICConfigurationDescription[]) mc2
.getItems();
for (int i = 0; i < cds1.length; i++)
applyToCfg(cds1[i], cds2[i]);
} else
applyToCfg(src.getConfiguration(), dst.getConfiguration());
}
private void applyToCfg(ICConfigurationDescription c1,
ICConfigurationDescription c2) {
Configuration cfg01 = (Configuration) getCfg(c1);
Configuration cfg02 = (Configuration) getCfg(c2);
IOptionalBuildProperties prop1 = cfg01.getOptionalBuildProperties();
IOptionalBuildProperties prop2 = cfg02.getOptionalBuildProperties();
String enablementProperty = prop1
.getProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED);
prop2.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED,
enablementProperty);
String connectionProperty = prop1
.getProperty(ContainerCommandLauncher.CONNECTION_ID);
prop2.setProperty(ContainerCommandLauncher.CONNECTION_ID,
connectionProperty);
String imageProperty = prop1
.getProperty(ContainerCommandLauncher.IMAGE_ID);
prop2.setProperty(ContainerCommandLauncher.IMAGE_ID, imageProperty);
}
@Override
protected void performDefaults() {
if (iCfg instanceof IMultiConfiguration) {
IConfiguration[] cfs = (IConfiguration[]) ((IMultiConfiguration) iCfg)
.getItems();
for (int i = 0; i < cfs.length; i++) {
IOptionalBuildProperties props = cfs[i]
.getOptionalBuildProperties();
props.setProperty(
ContainerCommandLauncher.CONTAINER_BUILD_ENABLED,
Boolean.toString(false));
if (connections.length > 0) {
props.setProperty(ContainerCommandLauncher.CONNECTION_ID,
connections[0].getUri());
} else {
props.setProperty(ContainerCommandLauncher.CONNECTION_ID,
null);
}
props.setProperty(ContainerCommandLauncher.IMAGE_ID, null);
}
} else {
IOptionalBuildProperties props = iCfg.getOptionalBuildProperties();
props.setProperty(ContainerCommandLauncher.CONTAINER_BUILD_ENABLED,
Boolean.toString(false));
if (connections.length > 0) {
props.setProperty(ContainerCommandLauncher.CONNECTION_ID,
connections[0].getUri());
} else {
props.setProperty(ContainerCommandLauncher.CONNECTION_ID, null);
}
props.setProperty(ContainerCommandLauncher.IMAGE_ID, null);
}
defaultEnabled = false;
if (connections.length > 0) {
connectionSelector.select(0);
}
imageCombo.setText(""); //$NON-NLS-1$
enableButton.setSelection(false);
setControlsEnabled(false);
}
@Override
public void updateData(ICResourceDescription cfgd) {
if (cfgd == null)
return;
iCfg = getCfg(cfgd.getConfiguration());
initializeConnectionSelector(iCfg);
initializeImageCombo(iCfg);
initializeEnablementButton(iCfg);
}
@Override
protected void updateButtons() {
// TODO Auto-generated method stub
}
@Override
public void changeEvent(int type) {
String currUri = null;
int currIndex = 0;
connections = DockerConnectionManager.getInstance().getConnections();
if (connection != null) {
currUri = connection.getUri();
currIndex = connectionSelector.getSelectionIndex();
}
String[] connectionNames = new String[connections.length];
int index = 0;
for (int i = 0; i < connections.length; ++i) {
connectionNames[i] = connections[i].getName();
if (connections[i].getUri().equals(currUri))
index = i;
}
if (type == IDockerConnectionManagerListener.RENAME_EVENT) {
index = currIndex; // no change in connection displayed
}
connectionSelector.removeModifyListener(connectionModifyListener);
connectionSelector.setItems(connectionNames);
if (connectionNames.length > 0) {
connectionSelector.setText(connectionNames[index]);
connection = connections[index];
connectionUri = connection.getUri();
} else {
connection = null;
connectionUri = "";
connectionSelector.setText("");
}
connectionSelector.addModifyListener(connectionModifyListener);
}
@Override
public void listChanged(IDockerConnection c,
java.util.List<IDockerImage> list) {
final IDockerImage[] finalList = list.toArray(new IDockerImage[0]);
if (c.getName().equals(connection.getName())) {
Display.getDefault().syncExec(new Runnable() {
@Override
public void run() {
connection.removeImageListener(containerTab);
ArrayList<String> imageNames = new ArrayList<String>();
for (IDockerImage image : finalList) {
java.util.List<String> tags = image.repoTags();
if (tags != null) {
for (String tag : tags) {
imageNames.add(tag);
}
}
}
if (!imageCombo.isDisposed())
imageCombo.setItems(imageNames.toArray(new String[0]));
connection.addImageListener(containerTab);
}
});
}
}
}

View file

@ -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)

View file

@ -90,6 +90,12 @@ 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;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);

View file

@ -40,6 +40,13 @@ 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
ContainerCommandLauncher_image_msg=[Running in image <{0}>]
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:

View file

@ -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.CommandLauncherFactoryManager;
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 = CommandLauncherFactoryManager.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 = CommandLauncherFactoryManager.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);
}