Skip to content

Commit

Permalink
Issue #99 Preference page for dotnet path and future developments
Browse files Browse the repository at this point in the history
Will stop users from using features requiring dotnet if the path is not
found and point them towards the preference page

Signed-off-by: Lucas Bullen <lbullen@redhat.com>
  • Loading branch information
Lucas Bullen authored and mickaelistria committed Nov 18, 2017
1 parent 2c8a663 commit ff46e87
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 16 deletions.
14 changes: 14 additions & 0 deletions org.eclipse.acute/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,18 @@
type="java.lang.Object">
</propertyTester>
</extension>
<extension
point="org.eclipse.core.runtime.preferences">
<initializer
class="org.eclipse.acute.AcutePreferenceInitializer">
</initializer>
</extension>
<extension
point="org.eclipse.ui.preferencePages">
<page
class="org.eclipse.acute.AcutePreferencePage"
id="org.eclipse.acute.preferencePage"
name=".NET Core">
</page>
</extension>
</plugin>
38 changes: 38 additions & 0 deletions org.eclipse.acute/src/org/eclipse/acute/AcutePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,19 @@
*
* Contributors:
* Mickael Istria (Red Hat Inc.) - Initial implementation
* Lucas Bullen (Red Hat Inc.) - Issue #99 - Specify dotnet path
*******************************************************************************/
package org.eclipse.acute;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

Expand Down Expand Up @@ -57,4 +65,34 @@ public static void logError(Throwable t) {
getDefault().getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, t.getMessage(), t));
}

/**
* Used to retrieve the path to the <code>dotnet</code> command. If no path has
* been set, then a warning will be given allowing the opening the preferences
* view and throws the {@link IllegalStateException} exception
*
* @return Path to the <code>dotnet</code> command specified in the preferences
* @throws IllegalStateException
* If no path has been set
*/
public static String getDotnetCommand() {
String path = plugin.getPreferenceStore().getString(AcutePreferenceInitializer.explicitDotnetPathPreference);
if (path.isEmpty()) {
Display.getDefault().asyncExec(() -> {
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
int dialogResponse = MessageDialog.open(MessageDialog.CONFIRM, shell, "No `dotnet` Path Set",
"There is no path to the `dotnet` command, please specify the correct path in the preferences.",
SWT.NONE, "Open Preferences", "Cancel");
if (dialogResponse == 0) {
PreferenceDialog preferenceDialog = PreferencesUtil.createPreferenceDialogOn(shell,
AcutePreferencePage.PAGE_ID,
new String[] { AcutePreferencePage.PAGE_ID }, null);
preferenceDialog.setBlockOnOpen(false);
preferenceDialog.open();
}
});
throw new IllegalStateException();
} else {
return path;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*******************************************************************************
* 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:
* Lucas Bullen (Red Hat Inc.) - Initial implementation
*******************************************************************************/
package org.eclipse.acute;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.jface.preference.IPreferenceStore;

public class AcutePreferenceInitializer extends AbstractPreferenceInitializer {

public static String explicitDotnetPathPreference = "dotnet.explicitPath";

@Override
public void initializeDefaultPreferences() {
IPreferenceStore store = AcutePlugin.getDefault().getPreferenceStore();

store.setDefault(explicitDotnetPathPreference, getBestDotnetPathGuess());
}

private String getBestDotnetPathGuess() {
try {
String[] command = new String[] { "/bin/bash", "-c", "which dotnet" };
if (Platform.getOS().equals(Platform.OS_WIN32)) {
command = new String[] { "cmd", "/c", "which dotnet" };
}
ProcessBuilder builder = new ProcessBuilder(command);
Process process = builder.start();

if (process.waitFor() == 0) {
try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
return in.readLine();
}
}
} catch (IOException | InterruptedException e) {
// Error will be caught with empty response
}
return "";
}

}
118 changes: 118 additions & 0 deletions org.eclipse.acute/src/org/eclipse/acute/AcutePreferencePage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*******************************************************************************
* 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:
* Lucas Bullen (Red Hat Inc.) - Initial implementation
*******************************************************************************/
package org.eclipse.acute;

import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;

import java.io.File;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
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.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;

public class AcutePreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
public static String PAGE_ID = "org.eclipse.acute.preferencePage";
private IPreferenceStore store;

private Text explicitDotnetPathText;

@Override
public void init(IWorkbench workbench) {
store = doGetPreferenceStore();
}

@Override
protected Control createContents(Composite parent) {
Composite container = new Composite(parent, SWT.NULL);
container.setLayout(new GridLayout(2, false));

createDotnetPathPart(container);

initializeContent();
return container;
}

private void initializeContent() {
explicitDotnetPathText.setText(store.getString(AcutePreferenceInitializer.explicitDotnetPathPreference));
}

@Override
protected IPreferenceStore doGetPreferenceStore() {
return AcutePlugin.getDefault().getPreferenceStore();
}

private boolean isPageValid() {
if (explicitDotnetPathText.getText().isEmpty()) {
setErrorMessage("Path cannot be empty");
return false;
}
File dotnetCommand = new File(explicitDotnetPathText.getText());
if (!dotnetCommand.exists() || !dotnetCommand.isFile()) {
setErrorMessage("Input a valid path to `dotnet` command");
return false;
} else if (!dotnetCommand.canExecute()) {
setErrorMessage("Inputted command is not executable");
return false;
}
setErrorMessage(null);
return true;
}

@Override
protected void performDefaults() {
explicitDotnetPathText.setText(store.getDefaultString(AcutePreferenceInitializer.explicitDotnetPathPreference));
super.performDefaults();
}

@Override
public boolean performOk() {
store.setValue(AcutePreferenceInitializer.explicitDotnetPathPreference, explicitDotnetPathText.getText());
return super.performOk();
}

private void createDotnetPathPart(Composite container) {
Label infoLabel = new Label(container, SWT.WRAP);
infoLabel.setText(
"Direct path to the `dotnet` command for .NET Core features:");
infoLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));

GridData textIndent = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
textIndent.horizontalIndent = 25;

explicitDotnetPathText = new Text(container, SWT.BORDER);
explicitDotnetPathText.setLayoutData(textIndent);
explicitDotnetPathText.addModifyListener(e -> {
setValid(isPageValid());
});

Button browseButton = new Button(container, SWT.NONE);
browseButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
browseButton.setText("Browse...");
browseButton.addSelectionListener(widgetSelectedAdapter(e -> {
FileDialog dialog = new FileDialog(browseButton.getShell());
String path = dialog.open();
if (path != null) {
explicitDotnetPathText.setText(path);
}
}));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
import java.io.IOException;
import java.io.InputStreamReader;

import org.eclipse.acute.AcutePlugin;

public class DotnetExportAccessor {

public static String getDefaultRuntime() {
String listCommand = "dotnet --info";

Runtime runtime = Runtime.getRuntime();
try {
String listCommand = AcutePlugin.getDotnetCommand() + " --info";
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(listCommand);

try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
Expand All @@ -32,7 +33,7 @@ public static String getDefaultRuntime() {
}
}
}
} catch (IOException e) {
} catch (IllegalStateException | IOException e) {
return "";
}
return "";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Iterator;
import java.util.List;

import org.eclipse.acute.AcutePlugin;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
Expand Down Expand Up @@ -76,16 +77,23 @@ public boolean performFinish() {
if (!exportLocation.exists()) {
exportLocation.mkdirs();
}
String dotnetPath;
try {
dotnetPath = AcutePlugin.getDotnetCommand();
} catch (IllegalStateException e) {
return false;
}

List<String> restoreCommandList = new ArrayList<>();
restoreCommandList.add("dotnet");
restoreCommandList.add(dotnetPath);
restoreCommandList.add("restore");
if (isSCD) {
restoreCommandList.add("-r");
restoreCommandList.add(runtime);
}

List<String> exportCommandList = new ArrayList<>();
exportCommandList.add("dotnet");
exportCommandList.add(dotnetPath);
exportCommandList.add("publish");
if (isSCD) {
exportCommandList.add("-r");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Collections;
import java.util.List;

import org.eclipse.acute.AcutePlugin;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;

Expand Down Expand Up @@ -65,7 +66,7 @@ public List<String> getCLIOptions() {
public static List<Template> getTemplates() {
try {
List<Template> templates = new ArrayList<>();
String listCommand = "dotnet new --list";
String listCommand = AcutePlugin.getDotnetCommand() + " new --list";

Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(listCommand);
Expand Down Expand Up @@ -101,7 +102,7 @@ public static List<Template> getTemplates() {
}
return templates;
}
} catch (IOException e) {
} catch (IllegalStateException | IOException e) {
return Collections.emptyList();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.eclipse.acute.AcutePlugin;
import org.eclipse.acute.builder.IncrementalDotnetBuilder;
import org.eclipse.acute.dotnetnew.DotnetNewAccessor.Template;
import org.eclipse.core.resources.ICommand;
Expand Down Expand Up @@ -112,7 +113,7 @@ public boolean performFinish() {
getContainer().run(true, true, monitor -> {
monitor.beginTask("Creating .NET Core project", 0);
List<String> commandLine = new ArrayList<>();
commandLine.add("dotnet");
commandLine.add(AcutePlugin.getDotnetCommand());
commandLine.add("new");
if (template != null) {
commandLine.addAll(template.getCLIOptions());
Expand Down Expand Up @@ -150,6 +151,8 @@ public boolean performFinish() {
} catch (InvocationTargetException | InterruptedException e) {
MessageDialog.openError(getShell(), "Cannot create .NET Core template",
"The 'dotnet new' command failed: " + e);
} catch (IllegalStateException e) {
// handled by getDotnetCommand()
}
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun
CompletableFuture.runAsync(() -> {
try {
if (buildProject) {
String[] cmdLine = new String[] { "dotnet", "build" };
String[] cmdLine = new String[] { AcutePlugin.getDotnetCommand(), "build" };
Process restoreProcess = DebugPlugin.exec(cmdLine, projectFileLocation);
IProcess process = DebugPlugin.newProcess(launch, restoreProcess, "dotnet build");
process.setAttribute(IProcess.ATTR_CMDLINE, String.join(" ", cmdLine));
Expand All @@ -166,7 +166,7 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun

if (binaryFile.exists() && binaryFile.isFile()) {
List<String> commandList = new ArrayList<>();
commandList.add("dotnet");
commandList.add(AcutePlugin.getDotnetCommand());
commandList.add("exec");
commandList.add(binaryFile.getAbsolutePath());
if (!finalProjectArguments.isEmpty()) {
Expand All @@ -190,6 +190,8 @@ public void launch(ILaunchConfiguration configuration, String mode, ILaunch laun
MessageDialog.openError(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
"Exception in Launch", e.getLocalizedMessage());
});
} catch (IllegalStateException e) {
// handled by getDotnetCommand()
}
});
}
Expand Down
Loading

0 comments on commit ff46e87

Please sign in to comment.