diff --git a/io.cucumber.eclipse.python/META-INF/MANIFEST.MF b/io.cucumber.eclipse.python/META-INF/MANIFEST.MF index 334c7d23..e5f0c872 100644 --- a/io.cucumber.eclipse.python/META-INF/MANIFEST.MF +++ b/io.cucumber.eclipse.python/META-INF/MANIFEST.MF @@ -21,7 +21,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.debug.core, org.eclipse.core.variables, io.cucumber.messages;bundle-version="13.2.1", - io.cucumber.tag-expressions;bundle-version="3.0.0" + io.cucumber.tag-expressions;bundle-version="3.0.0", + org.eclipse.jdt.debug.ui Bundle-RequiredExecutionEnvironment: JavaSE-21 Automatic-Module-Name: io.cucumber.eclipse.python Bundle-ActivationPolicy: lazy diff --git a/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLaunchConstants.java b/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLaunchConstants.java index f0f4ca80..88a09a29 100644 --- a/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLaunchConstants.java +++ b/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLaunchConstants.java @@ -4,6 +4,7 @@ public interface CucumberBehaveLaunchConstants { public static final String TYPE_ID = "cucumber.eclipse.python.launching.localCucumberBehave"; + public static final String ATTR_PROJECT = "project"; public static final String ATTR_FEATURE_PATH = "cucumber feature"; public static final String ATTR_FEATURE_WITH_LINE = "cucumber feature_with_line"; public static final String ATTR_TAGS = "cucumber tags"; diff --git a/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLaunchUtils.java b/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLaunchUtils.java new file mode 100644 index 00000000..92ac0eef --- /dev/null +++ b/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLaunchUtils.java @@ -0,0 +1,62 @@ +package io.cucumber.eclipse.python.launching; + +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IFileEditorInput; +import org.eclipse.ui.IWorkbenchPage; + +public class CucumberBehaveLaunchUtils { + + private CucumberBehaveLaunchUtils() { + // NO ENTRY NO INSTANCES + } + + protected static IProject getProject() { + IWorkbenchPage page = JDIDebugUIPlugin.getActivePage(); + if (page != null) { + IEditorPart part = page.getActiveEditor(); + if (part != null) { + IFileEditorInput input = (IFileEditorInput) part.getEditorInput(); + IFile file = input.getFile(); + IProject activeProject = file.getProject(); + return activeProject; + } + } + return null; + } + + protected static String getFeaturePath() { + IWorkbenchPage page = JDIDebugUIPlugin.getActivePage(); + if (page != null) { + IEditorPart part = page.getActiveEditor(); + if (part != null) { + IFileEditorInput input = (IFileEditorInput) part.getEditorInput(); + return input.getFile().getLocation().toString(); + } + } + return null; + } + + public static void updateFromConfig(ILaunchConfiguration config, String attrib, Text text) { + String s = ""; + try { + s = config.getAttribute(attrib, ""); + } catch (CoreException e) { + e.printStackTrace(); + } + text.setText(s); + } + + public static boolean getAttribute(ILaunchConfiguration config, String attrib, boolean defaultValue) { + try { + return config.getAttribute(attrib, defaultValue); + } catch (CoreException e) { + } + return defaultValue; + } +} diff --git a/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLauncher.java b/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLauncher.java index 7826d402..8b84a7bb 100644 --- a/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLauncher.java +++ b/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveLauncher.java @@ -111,6 +111,7 @@ private ILaunchConfiguration getLaunchConfiguration(IProject project, IResource ILaunchConfigurationWorkingCopy wc = type.newInstance(null, lm.generateLaunchConfigurationName(resource.getName())); + wc.setAttribute(CucumberBehaveLaunchConstants.ATTR_PROJECT, project.getName()); wc.setAttribute(CucumberBehaveLaunchConstants.ATTR_FEATURE_PATH, featurePath); wc.setAttribute(CucumberBehaveLaunchConstants.ATTR_WORKING_DIRECTORY, project.getLocation().toOSString()); diff --git a/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveMainTab.java b/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveMainTab.java index c5934203..c8284b6d 100644 --- a/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveMainTab.java +++ b/io.cucumber.eclipse.python/src/io/cucumber/eclipse/python/launching/CucumberBehaveMainTab.java @@ -9,6 +9,8 @@ import org.eclipse.debug.internal.ui.SWTFactory; import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.jdt.internal.debug.ui.launcher.LauncherMessages; +import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; @@ -23,14 +25,18 @@ import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.dialogs.ElementListSelectionDialog; +import org.eclipse.ui.model.WorkbenchLabelProvider; public class CucumberBehaveMainTab extends AbstractLaunchConfigurationTab implements ILaunchConfigurationTab { + protected Text projectText; protected Text featurePathText; protected Text workingDirectoryText; protected Text pythonInterpreterText; protected Text tagsText; private WidgetListener listener = new WidgetListener(); + private Button projectButton; private Button featureButton; private Button workingDirectoryButton; private Button verboseCheckbox; @@ -51,7 +57,9 @@ public void widgetDefaultSelected(SelectionEvent e) { @Override public void widgetSelected(SelectionEvent e) { Object source = e.getSource(); - if (source == featureButton) { + if (source == projectButton) { + handleProjectButtonSelected(); + } else if (source == featureButton) { FileDialog fileDialog = new FileDialog(getShell()); fileDialog.setText("Select Feature File"); fileDialog.setFilterExtensions(new String[] { "*.feature" }); @@ -77,6 +85,7 @@ public void widgetSelected(SelectionEvent e) { @Override public void createControl(Composite parent) { Composite comp = SWTFactory.createComposite(parent, parent.getFont(), 1, 1, GridData.FILL_BOTH); + createProjectEditor(comp); createFeaturePathEditor(comp); createWorkingDirectoryEditor(comp); createPythonInterpreterEditor(comp); @@ -85,6 +94,27 @@ public void createControl(Composite parent) { setControl(comp); } + private void createProjectEditor(Composite comp) { + Font font = comp.getFont(); + Group group = new Group(comp, SWT.NONE); + group.setText("Project:"); + GridData gd = new GridData(GridData.FILL_HORIZONTAL); + group.setLayoutData(gd); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + group.setLayout(layout); + group.setFont(font); + + projectText = new Text(group, SWT.SINGLE | SWT.BORDER); + gd = new GridData(GridData.FILL_HORIZONTAL); + projectText.setLayoutData(gd); + projectText.setFont(font); + projectText.addModifyListener(listener); + + projectButton = createPushButton(group, LauncherMessages.AbstractJavaMainTab_1, null); + projectButton.addSelectionListener(listener); + } + private void createFeaturePathEditor(Composite comp) { Font font = comp.getFont(); Group group = new Group(comp, SWT.NONE); @@ -194,6 +224,7 @@ public String getName() { @Override public void performApply(ILaunchConfigurationWorkingCopy config) { + config.setAttribute(CucumberBehaveLaunchConstants.ATTR_PROJECT, projectText.getText().trim()); config.setAttribute(CucumberBehaveLaunchConstants.ATTR_FEATURE_PATH, featurePathText.getText().trim()); config.setAttribute(CucumberBehaveLaunchConstants.ATTR_WORKING_DIRECTORY, workingDirectoryText.getText().trim()); config.setAttribute(CucumberBehaveLaunchConstants.ATTR_PYTHON_INTERPRETER, pythonInterpreterText.getText().trim()); @@ -205,9 +236,21 @@ public void performApply(ILaunchConfigurationWorkingCopy config) { @Override public void setDefaults(ILaunchConfigurationWorkingCopy config) { - // Set default values - config.setAttribute(CucumberBehaveLaunchConstants.ATTR_FEATURE_PATH, ""); - config.setAttribute(CucumberBehaveLaunchConstants.ATTR_WORKING_DIRECTORY, getDefaultWorkingDirectory()); + IProject project = CucumberBehaveLaunchUtils.getProject(); + String featurePath = CucumberBehaveLaunchUtils.getFeaturePath(); + + if (project != null && featurePath != null) { + // Auto-fill project and feature path based on active editor + config.setAttribute(CucumberBehaveLaunchConstants.ATTR_PROJECT, project.getName()); + config.setAttribute(CucumberBehaveLaunchConstants.ATTR_FEATURE_PATH, featurePath); + config.setAttribute(CucumberBehaveLaunchConstants.ATTR_WORKING_DIRECTORY, + project.getLocation().toOSString()); + } else { + // Set default empty values + config.setAttribute(CucumberBehaveLaunchConstants.ATTR_PROJECT, ""); + config.setAttribute(CucumberBehaveLaunchConstants.ATTR_FEATURE_PATH, ""); + config.setAttribute(CucumberBehaveLaunchConstants.ATTR_WORKING_DIRECTORY, getDefaultWorkingDirectory()); + } config.setAttribute(CucumberBehaveLaunchConstants.ATTR_PYTHON_INTERPRETER, "python"); config.setAttribute(CucumberBehaveLaunchConstants.ATTR_TAGS, ""); config.setAttribute(CucumberBehaveLaunchConstants.ATTR_IS_VERBOSE, false); @@ -217,6 +260,7 @@ public void setDefaults(ILaunchConfigurationWorkingCopy config) { @Override public void initializeFrom(ILaunchConfiguration config) { + updateFromConfig(config, CucumberBehaveLaunchConstants.ATTR_PROJECT, projectText); updateFromConfig(config, CucumberBehaveLaunchConstants.ATTR_FEATURE_PATH, featurePathText); updateFromConfig(config, CucumberBehaveLaunchConstants.ATTR_WORKING_DIRECTORY, workingDirectoryText); updateFromConfig(config, CucumberBehaveLaunchConstants.ATTR_PYTHON_INTERPRETER, pythonInterpreterText); @@ -254,6 +298,41 @@ private String getDefaultWorkingDirectory() { return ""; } + private void handleProjectButtonSelected() { + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + IProject[] projects = root.getProjects(); + + ElementListSelectionDialog dialog = new ElementListSelectionDialog( + getShell(), + WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider()); + dialog.setTitle("Project Selection"); + dialog.setMessage("Select a project:"); + dialog.setElements(projects); + + // Set currently selected project if any + String currentProject = projectText.getText().trim(); + if (!currentProject.isEmpty()) { + for (IProject project : projects) { + if (project.getName().equals(currentProject)) { + dialog.setInitialSelections(new Object[] { project }); + break; + } + } + } + + if (dialog.open() == Window.OK) { + IProject project = (IProject) dialog.getFirstResult(); + if (project != null) { + projectText.setText(project.getName()); + + // Auto-fill working directory if not already set + if (workingDirectoryText.getText().trim().isEmpty()) { + workingDirectoryText.setText(project.getLocation().toOSString()); + } + } + } + } + @Override public boolean isValid(ILaunchConfiguration config) { setErrorMessage(null);