This is an automated email from the ASF dual-hosted git repository.
vieiro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new dd6da592e1 Rust options panel and Cargo executable selection
new 4d5259a4e7 Merge pull request #5651 from vieiro/rust-options
dd6da592e1 is described below
commit dd6da592e153a12456b4b55f0ff9bccb2bdae2c8
Author: Antonio <[email protected]>
AuthorDate: Sun Mar 5 16:15:23 2023 +0100
Rust options panel and Cargo executable selection
- Rust Option panel with Cargo subpanel.
- Cargo path is used in Cargo commands.
- When cargo path is not found a Notification is shown to the user.
---
.github/workflows/main.yml | 3 +
nbbuild/cluster.properties | 1 +
rust/rust.cargo/nbproject/project.xml | 8 +
.../modules/rust/cargo/impl/CargoBuildImpl.java | 47 +++-
rust/rust.kit/nbproject/project.xml | 8 +
rust/rust.options/build.xml | 25 ++
rust/rust.options/licenseinfo.xml | 30 +++
rust/rust.options/manifest.mf | 5 +
rust/rust.options/nbproject/project.properties | 20 ++
rust/rust.options/nbproject/project.xml | 97 +++++++
.../modules/rust/options/Bundle.properties | 22 ++
.../modules/rust/options/api/CargoOptions.java | 41 +++
.../modules/rust/options/cargo/Bundle.properties | 24 ++
.../options/cargo/CargoOptionsPanelController.java | 101 +++++++
.../modules/rust/options/cargo/CargoPanel.form | 150 +++++++++++
.../modules/rust/options/cargo/CargoPanel.java | 299 +++++++++++++++++++++
.../rust/options/impl/CargoOptionsImpl.java | 148 ++++++++++
.../modules/rust/options/package-info.java | 30 +++
.../modules/rust/options/rust-logo-big.png | Bin 0 -> 2044 bytes
.../rust/options/impl/CargoOptionsImplTest.java | 68 +++++
.../rust/project/RustProjectActionProvider.java | 2 +
21 files changed, 1122 insertions(+), 7 deletions(-)
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 3da769f0f7..05afea0513 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -1874,6 +1874,9 @@ jobs:
- name: rust/rust.grammar
run: ant $OPTS -f rust/rust.grammar test
+ - name: rust/rust.options
+ run: ant $OPTS -f rust/rust.options test
+
- name: Create Test Summary
uses: test-summary/action@v2
if: failure()
diff --git a/nbbuild/cluster.properties b/nbbuild/cluster.properties
index 70cec32db5..04ceee4740 100644
--- a/nbbuild/cluster.properties
+++ b/nbbuild/cluster.properties
@@ -1091,6 +1091,7 @@ nb.cluster.rust=\
rust.cargo,\
rust.grammar,\
rust.kit,\
+ rust.options,\
rust.project,\
rust.project.api,\
rust.sources
diff --git a/rust/rust.cargo/nbproject/project.xml
b/rust/rust.cargo/nbproject/project.xml
index f1797ae8ed..804a7bb7e2 100644
--- a/rust/rust.cargo/nbproject/project.xml
+++ b/rust/rust.cargo/nbproject/project.xml
@@ -95,6 +95,14 @@
<specification-version>1.106</specification-version>
</run-dependency>
</dependency>
+ <dependency>
+
<code-name-base>org.netbeans.modules.rust.options</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>1.11</specification-version>
+ </run-dependency>
+ </dependency>
<dependency>
<code-name-base>org.netbeans.modules.rust.project.api</code-name-base>
<build-prerequisite/>
diff --git
a/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/impl/CargoBuildImpl.java
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/impl/CargoBuildImpl.java
index 2400aa5e2b..1d0ad7f579 100644
---
a/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/impl/CargoBuildImpl.java
+++
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/impl/CargoBuildImpl.java
@@ -22,8 +22,10 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
@@ -41,7 +43,10 @@ import org.openide.windows.IOProvider;
import org.openide.windows.InputOutput;
import org.netbeans.modules.rust.cargo.api.Cargo;
import org.netbeans.modules.rust.cargo.api.RustPackage;
+import org.netbeans.modules.rust.options.api.CargoOptions;
import org.openide.LifecycleManager;
+import org.openide.util.Exceptions;
+import org.openide.util.NbBundle;
/**
* CargoBuildImpl is used to invoke a set of predefined "cargo" commands.
@@ -84,8 +89,8 @@ public class CargoBuildImpl implements Cargo {
File workingDirectory =
FileUtil.toFile(cargotoml.getFileObject()).getParentFile();
pb.setWorkingDirectory(workingDirectory.getAbsolutePath());
pb.setRedirectErrorStream(false);
- // TODO: Parametrize the "cargo" path
- pb.setExecutable("cargo"); // NOI18N
+ Path cargo = CargoOptions.getCargoLocation(false);
+ pb.setExecutable(cargo.toString());
pb.setArguments(arguments);
console.getOut().println(String.format("%n$ cargo %s",
String.join(" ", arguments))); // NOI18N
@@ -97,6 +102,10 @@ public class CargoBuildImpl implements Cargo {
/**
* A Callable used to invoke an array of commands.
*/
+ @NbBundle.Messages({
+ "MSG_WORKING_DIRECTORY=Working directory:",
+ "MSG_CARGO_PATH=Cargo: "
+ })
public static class SequentialCargoProcesses implements Callable<Integer> {
private final CargoTOML cargotoml;
@@ -111,6 +120,10 @@ public class CargoBuildImpl implements Cargo {
@Override
public Integer call() throws Exception {
+ Path cargo = CargoOptions.getCargoLocation(true);
+ if (cargo == null) {
+ return -1;
+ }
// Get a proper console for the input/output
String projectName = cargotoml.getPackageName();
String commandNames =
Arrays.stream(commands).map(CargoCommand::getDisplayName).collect(Collectors.joining(","));
// NOI18N
@@ -118,6 +131,14 @@ public class CargoBuildImpl implements Cargo {
InputOutput console = IOProvider.getDefault().getIO(ioName, false);
console.select();
+ File workingDirectory =
FileUtil.toFile(cargotoml.getFileObject()).getParentFile();
+ console.getOut().format("# %s %s%n", // NOI18N
+ NbBundle.getMessage(CargoBuildImpl.class,
"MSG_WORKING_DIRECTORY"),
+ workingDirectory.getAbsolutePath());
+ console.getOut().format("# %s %s%n", // NOI18N
+ NbBundle.getMessage(CargoBuildImpl.class,
"MSG_CARGO_PATH"),
+ cargo);
+
ExecutionDescriptor ed = new ExecutionDescriptor()
.inputOutput(IOProvider.getDefault().getIO(ioName, false))
.inputVisible(true)
@@ -133,7 +154,12 @@ public class CargoBuildImpl implements Cargo {
CargoProcess process = new CargoProcess(cargotoml, command,
options, console);
ExecutionService service =
ExecutionService.newService(process, ed, ioName);
Future<Integer> resultCodeFuture = service.run();
- resultCode = resultCodeFuture.get();
+ try {
+ resultCode = resultCodeFuture.get();
+ } catch (Exception e) {
+ console.getErr().println(String.format("Cargo execution
failed: %s%n", e.getMessage()));
+ Exceptions.printStackTrace(e);
+ }
if (resultCode != 0) {
console.getErr().println(String.format("Command \"cargo
%s\" failed with exit status %d", // NOI18N
String.join(" ", command.arguments),
@@ -155,11 +181,15 @@ public class CargoBuildImpl implements Cargo {
@Override
public void cargo(CargoTOML cargotoml, CargoCommand[] commands, String...
options) throws IOException {
if (cargotoml == null) {
- throw new NullPointerException("Missing Cargo.tomml file"); //
NOI18N
+ throw new NullPointerException("Missing Cargo.toml file"); //
NOI18N
}
if (commands.length == 0) {
return;
}
+ Path cargo = CargoOptions.getCargoLocation(true);
+ if (cargo == null) {
+ return;
+ }
// Let's save stuff just in case
LifecycleManager.getDefault().saveAll();
requestProcessor.submit(new SequentialCargoProcesses(cargotoml,
commands, options));
@@ -180,17 +210,20 @@ public class CargoBuildImpl implements Cargo {
@Override
public List<RustPackage> call() throws Exception {
+ Path cargo = CargoOptions.getCargoLocation(true);
+ if (cargo == null) {
+ return Collections.emptyList();
+ }
org.netbeans.api.extexecution.base.ProcessBuilder pb =
org.netbeans.api.extexecution.base.ProcessBuilder.getLocal();
File workingDirectory = new File(System.getProperty("user.home"));
// NOI18N
pb.setWorkingDirectory(workingDirectory.getAbsolutePath());
pb.setRedirectErrorStream(false);
- // TODO: Parametrize the "cargo" path
- pb.setExecutable("cargo"); // NOI18N
+ pb.setExecutable(cargo.toString());
String[] arguments = {
"search", // NOI18N
text, // TODO: What happens with spaces?
"--limit", // NOI18N
- "15", // NOI18N
+ "30", // NOI18N
"--color", // NOI18N
"never", // NOI18N
};
diff --git a/rust/rust.kit/nbproject/project.xml
b/rust/rust.kit/nbproject/project.xml
index 7ed8b5d1fb..2d2ab684a1 100644
--- a/rust/rust.kit/nbproject/project.xml
+++ b/rust/rust.kit/nbproject/project.xml
@@ -37,6 +37,14 @@
<specification-version>1.11</specification-version>
</run-dependency>
</dependency>
+ <dependency>
+
<code-name-base>org.netbeans.modules.rust.options</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>1.11</specification-version>
+ </run-dependency>
+ </dependency>
<dependency>
<code-name-base>org.netbeans.modules.rust.project</code-name-base>
<run-dependency>
diff --git a/rust/rust.options/build.xml b/rust/rust.options/build.xml
new file mode 100644
index 0000000000..824d7310de
--- /dev/null
+++ b/rust/rust.options/build.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<project basedir="." default="netbeans" name="rust/rust.options">
+ <description>Builds, tests, and runs the project
org.netbeans.modules.rust.options</description>
+ <import file="../../nbbuild/templates/projectized.xml"/>
+</project>
diff --git a/rust/rust.options/licenseinfo.xml
b/rust/rust.options/licenseinfo.xml
new file mode 100644
index 0000000000..beb0827d2c
--- /dev/null
+++ b/rust/rust.options/licenseinfo.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<licenseinfo>
+ <fileset>
+ <file>src/org/netbeans/modules/rust/options/rust-logo-big.png</file>
+ <license ref="Apache-2.0-ASF" />
+ <comment type="COMMENT_UNSUPPORTED">
+ Icon for Rust Option Dialog.
+ </comment>
+ </fileset>
+</licenseinfo>
diff --git a/rust/rust.options/manifest.mf b/rust/rust.options/manifest.mf
new file mode 100644
index 0000000000..ea3e6fbe69
--- /dev/null
+++ b/rust/rust.options/manifest.mf
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: org.netbeans.modules.rust.options
+OpenIDE-Module-Implementation-Version: 1
+OpenIDE-Module-Localizing-Bundle:
org/netbeans/modules/rust/options/Bundle.properties
+
diff --git a/rust/rust.options/nbproject/project.properties
b/rust/rust.options/nbproject/project.properties
new file mode 100644
index 0000000000..6744a59b1e
--- /dev/null
+++ b/rust/rust.options/nbproject/project.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+javac.source=1.8
+javac.compilerargs=-Xlint -Xlint:-serial
+spec.version.base=1.11
diff --git a/rust/rust.options/nbproject/project.xml
b/rust/rust.options/nbproject/project.xml
new file mode 100644
index 0000000000..85ae51931b
--- /dev/null
+++ b/rust/rust.options/nbproject/project.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<project xmlns="http://www.netbeans.org/ns/project/1">
+ <type>org.netbeans.modules.apisupport.project</type>
+ <configuration>
+ <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+ <code-name-base>org.netbeans.modules.rust.options</code-name-base>
+ <module-dependencies>
+ <dependency>
+
<code-name-base>org.netbeans.modules.options.api</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.65</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+
<code-name-base>org.netbeans.modules.rust.project.api</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>1.11</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.awt</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>7.88</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>9.28</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util.lookup</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>8.54</specification-version>
+ </run-dependency>
+ </dependency>
+ <dependency>
+ <code-name-base>org.openide.util.ui</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>9.29</specification-version>
+ </run-dependency>
+ </dependency>
+ </module-dependencies>
+ <test-dependencies>
+ <test-type>
+ <name>unit</name>
+ <test-dependency>
+
<code-name-base>org.netbeans.libs.junit4</code-name-base>
+ <compile-dependency/>
+ </test-dependency>
+ <test-dependency>
+
<code-name-base>org.netbeans.modules.nbjunit</code-name-base>
+ <recursive/>
+ <compile-dependency/>
+ </test-dependency>
+ </test-type>
+ </test-dependencies>
+ <public-packages>
+ <package>org.netbeans.modules.rust.options.api</package>
+ </public-packages>
+ </data>
+ </configuration>
+</project>
diff --git
a/rust/rust.options/src/org/netbeans/modules/rust/options/Bundle.properties
b/rust/rust.options/src/org/netbeans/modules/rust/options/Bundle.properties
new file mode 100644
index 0000000000..6a861df55d
--- /dev/null
+++ b/rust/rust.options/src/org/netbeans/modules/rust/options/Bundle.properties
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+OpenIDE-Module-Display-Category=Rust
+OpenIDE-Module-Long-Description=\
+ Rust Option Panel.
+OpenIDE-Module-Name=Rust Options
+OpenIDE-Module-Short-Description=Rust Options
diff --git
a/rust/rust.options/src/org/netbeans/modules/rust/options/api/CargoOptions.java
b/rust/rust.options/src/org/netbeans/modules/rust/options/api/CargoOptions.java
new file mode 100644
index 0000000000..883c24e4cf
--- /dev/null
+++
b/rust/rust.options/src/org/netbeans/modules/rust/options/api/CargoOptions.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.rust.options.api;
+
+import java.nio.file.Path;
+import org.netbeans.modules.rust.options.impl.CargoOptionsImpl;
+
+/**
+ * Returns the options for Rust and Cargo.
+ */
+public final class CargoOptions {
+
+ /**
+ * Returns the Path where cargo is installed, or null.
+ *
+ * @param verifying If true then the path is checked for validity (the path
+ * exists and is executable) and if it is incorrect then a notification is
+ * shown to the user.
+ * @return The Path where cargo is installed, or null.
+ */
+ public static final Path getCargoLocation(boolean verifying) {
+ return CargoOptionsImpl.getCargoLocation(verifying);
+ }
+
+}
diff --git
a/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/Bundle.properties
b/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/Bundle.properties
new file mode 100644
index 0000000000..210f11172f
--- /dev/null
+++
b/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/Bundle.properties
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+CargoPanel.lblCargoLocation.text=Cargo executable location:
+CargoPanel.txtCargoPath.text=
+CargoPanel.cmdBrowse.text=Browse...
+CargoPanel.txtCargoPath.toolTipText=The full path pointing to cargo or
cargo.exe executable
+CargoPanel.cmdBrowse.toolTipText=Browse cargo in your filesystem
+CargoPanel.lblCargoVersion.text=
+CargoPanel.cmdGetVersion.text=Get version
diff --git
a/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/CargoOptionsPanelController.java
b/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/CargoOptionsPanelController.java
new file mode 100644
index 0000000000..0474a39e18
--- /dev/null
+++
b/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/CargoOptionsPanelController.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.rust.options.cargo;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.HelpCtx;
+import org.openide.util.Lookup;
+
[email protected](
+ location = "Rust",
+ displayName = "#AdvancedOption_DisplayName_Cargo",
+ keywords = "#AdvancedOption_Keywords_Cargo",
+ keywordsCategory = "Rust/Cargo",
+ position = 1000
+)
[email protected]({"AdvancedOption_DisplayName_Cargo=Cargo",
"AdvancedOption_Keywords_Cargo=rust cargo"})
+public final class CargoOptionsPanelController extends OptionsPanelController {
+
+ private CargoPanel panel;
+ private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+ private boolean changed;
+
+ public void update() {
+ getPanel().load();
+ changed = false;
+ }
+
+ public void applyChanges() {
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ getPanel().store();
+ changed = false;
+ }
+ });
+ }
+
+ public void cancel() {
+ // need not do anything special, if no changes have been persisted yet
+ }
+
+ public boolean isValid() {
+ return getPanel().valid();
+ }
+
+ public boolean isChanged() {
+ return changed;
+ }
+
+ public HelpCtx getHelpCtx() {
+ return null; // new HelpCtx("...ID") if you have a help set
+ }
+
+ public JComponent getComponent(Lookup masterLookup) {
+ return getPanel();
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener l) {
+ pcs.addPropertyChangeListener(l);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener l) {
+ pcs.removePropertyChangeListener(l);
+ }
+
+ private CargoPanel getPanel() {
+ if (panel == null) {
+ panel = new CargoPanel(this);
+ }
+ return panel;
+ }
+
+ void changed() {
+ if (!changed) {
+ changed = true;
+ pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false,
true);
+ }
+ pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
+ }
+
+}
diff --git
a/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/CargoPanel.form
b/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/CargoPanel.form
new file mode 100644
index 0000000000..eeecf5ba0a
--- /dev/null
+++
b/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/CargoPanel.form
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+
+<Form version="1.5" maxVersion="1.9"
type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+ <AuxValues>
+ <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer"
value="1"/>
+ <AuxValue name="FormSettings_autoSetComponentName"
type="java.lang.Boolean" value="false"/>
+ <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean"
value="true"/>
+ <AuxValue name="FormSettings_generateMnemonicsCode"
type="java.lang.Boolean" value="true"/>
+ <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean"
value="true"/>
+ <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer"
value="1"/>
+ <AuxValue name="FormSettings_listenerGenerationStyle"
type="java.lang.Integer" value="0"/>
+ <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean"
value="false"/>
+ <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer"
value="2"/>
+ <AuxValue name="designerSize" type="java.awt.Dimension"
value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,3,113,0,0,2,-22"/>
+ </AuxValues>
+
+ <Layout
class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
+ <SubComponents>
+ <Component class="javax.swing.JLabel" name="lblCargoLocation">
+ <Properties>
+ <Property name="labelFor" type="java.awt.Component"
editor="org.netbeans.modules.form.ComponentChooserEditor">
+ <ComponentRef name="txtCargoPath"/>
+ </Property>
+ <Property name="text" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString
bundle="org/netbeans/modules/rust/options/cargo/Bundle.properties"
key="CargoPanel.lblCargoLocation.text"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"
value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="0" gridWidth="4" gridHeight="1"
fill="2" ipadX="0" ipadY="0" insetsTop="8" insetsLeft="8" insetsBottom="8"
insetsRight="8" anchor="18" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JTextField" name="txtCargoPath">
+ <Properties>
+ <Property name="text" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString
bundle="org/netbeans/modules/rust/options/cargo/Bundle.properties"
key="CargoPanel.txtCargoPath.text"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
+ </Property>
+ <Property name="toolTipText" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString
bundle="org/netbeans/modules/rust/options/cargo/Bundle.properties"
key="CargoPanel.txtCargoPath.toolTipText"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
+ </Property>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed"
listener="java.awt.event.ActionListener"
parameters="java.awt.event.ActionEvent" handler="txtCargoPathActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"
value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="1" gridWidth="1" gridHeight="1"
fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="0"
insetsRight="0" anchor="256" weightX="1.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JButton" name="cmdBrowse">
+ <Properties>
+ <Property name="text" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString
bundle="org/netbeans/modules/rust/options/cargo/Bundle.properties"
key="CargoPanel.cmdBrowse.text"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
+ </Property>
+ <Property name="toolTipText" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString
bundle="org/netbeans/modules/rust/options/cargo/Bundle.properties"
key="CargoPanel.cmdBrowse.toolTipText"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
+ </Property>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed"
listener="java.awt.event.ActionListener"
parameters="java.awt.event.ActionEvent" handler="cmdBrowseActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"
value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1"
fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="0"
insetsRight="0" anchor="256" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JButton" name="cmdGetVersion">
+ <Properties>
+ <Property name="text" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString
bundle="org/netbeans/modules/rust/options/cargo/Bundle.properties"
key="CargoPanel.cmdGetVersion.text"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
+ </Property>
+ <Property name="enabled" type="boolean" value="false"/>
+ </Properties>
+ <Events>
+ <EventHandler event="actionPerformed"
listener="java.awt.event.ActionListener"
parameters="java.awt.event.ActionEvent" handler="cmdGetVersionActionPerformed"/>
+ </Events>
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"
value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="3" gridY="1" gridWidth="1" gridHeight="1"
fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="8" insetsBottom="0"
insetsRight="8" anchor="10" weightX="0.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Component class="javax.swing.JLabel" name="lblCargoVersion">
+ <Properties>
+ <Property name="font" type="java.awt.Font"
editor="org.netbeans.modules.form.editors2.FontEditor">
+ <FontInfo relative="true">
+ <Font bold="true" component="lblCargoVersion" property="font"
relativeSize="true" size="0"/>
+ </FontInfo>
+ </Property>
+ <Property name="text" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+ <ResourceString
bundle="org/netbeans/modules/rust/options/cargo/Bundle.properties"
key="CargoPanel.lblCargoVersion.text"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"
value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="2" gridWidth="4" gridHeight="1"
fill="2" ipadX="0" ipadY="0" insetsTop="8" insetsLeft="8" insetsBottom="8"
insetsRight="8" anchor="11" weightX="1.0" weightY="0.0"/>
+ </Constraint>
+ </Constraints>
+ </Component>
+ <Container class="javax.swing.JPanel" name="jPanel1">
+ <Properties>
+ <Property name="preferredSize" type="java.awt.Dimension"
editor="org.netbeans.beaninfo.editors.DimensionEditor">
+ <Dimension value="[8, 8]"/>
+ </Property>
+ </Properties>
+ <Constraints>
+ <Constraint
layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"
value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
+ <GridBagConstraints gridX="0" gridY="3" gridWidth="4" gridHeight="1"
fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0"
insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
+ </Constraint>
+ </Constraints>
+
+ <Layout>
+ <DimensionLayout dim="0">
+ <Group type="103" groupAlignment="0" attributes="0">
+ <EmptySpace min="0" pref="746" max="32767" attributes="0"/>
+ </Group>
+ </DimensionLayout>
+ <DimensionLayout dim="1">
+ <Group type="103" groupAlignment="0" attributes="0">
+ <EmptySpace min="0" pref="799" max="32767" attributes="0"/>
+ </Group>
+ </DimensionLayout>
+ </Layout>
+ </Container>
+ </SubComponents>
+</Form>
diff --git
a/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/CargoPanel.java
b/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/CargoPanel.java
new file mode 100644
index 0000000000..e120b546d7
--- /dev/null
+++
b/rust/rust.options/src/org/netbeans/modules/rust/options/cargo/CargoPanel.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.rust.options.cargo;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.InputStreamReader;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import javax.swing.JFileChooser;
+import javax.swing.SwingWorker;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.filechooser.FileFilter;
+import org.netbeans.modules.rust.options.impl.CargoOptionsImpl;
+import org.openide.util.NbBundle;
+import org.openide.util.Utilities;
+
+final class CargoPanel extends javax.swing.JPanel implements DocumentListener {
+
+ private final CargoOptionsPanelController controller;
+ private JFileChooser fileChooser;
+ private SwingWorker<String, String> versionWorker;
+
+ CargoPanel(CargoOptionsPanelController controller) {
+ this.controller = controller;
+ initComponents();
+ txtCargoPath.getDocument().addDocumentListener(this);
+ }
+
+ private SwingWorker<String, String> newWorker() {
+ return new SwingWorker<String, String>() {
+ @Override
+ protected String doInBackground() throws Exception {
+ String cargo = txtCargoPath.getText();
+ return getVersionOf(cargo);
+ }
+
+ @Override
+ protected void done() {
+ versionWorker = null;
+ String version;
+ try {
+ version = get();
+ lblCargoVersion.setText(version);
+ } catch (Exception ex) {
+ lblCargoVersion.setText("");
+ }
+ }
+ };
+ }
+
+ private String getVersionOf(String aPossibleCargoPath) throws Exception {
+ File cargo = Paths.get(aPossibleCargoPath).toFile();
+ if (cargo.isFile() && cargo.canExecute()) {
+ return getVersionOf(cargo);
+ }
+ return null;
+ }
+
+ private String getVersionOf(File cargo) throws Exception {
+ Process p = Runtime.getRuntime().exec(new
String[]{cargo.getAbsolutePath(), "-V"});
+ int ok = p.waitFor();
+ if (ok == 0) {
+ String version = null;
+ try (BufferedReader reader = new BufferedReader(new
InputStreamReader(p.getInputStream()))) {
+ do {
+ String line = reader.readLine();
+ if (line == null) {
+ break;
+ }
+ version = line;
+ } while (true);
+ }
+ p.destroy();
+ return version;
+ }
+ return null;
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the
form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc="Generated
Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+ java.awt.GridBagConstraints gridBagConstraints;
+
+ lblCargoLocation = new javax.swing.JLabel();
+ txtCargoPath = new javax.swing.JTextField();
+ cmdBrowse = new javax.swing.JButton();
+ cmdGetVersion = new javax.swing.JButton();
+ lblCargoVersion = new javax.swing.JLabel();
+ jPanel1 = new javax.swing.JPanel();
+
+ setLayout(new java.awt.GridBagLayout());
+
+ lblCargoLocation.setLabelFor(txtCargoPath);
+ org.openide.awt.Mnemonics.setLocalizedText(lblCargoLocation,
org.openide.util.NbBundle.getMessage(CargoPanel.class,
"CargoPanel.lblCargoLocation.text")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 0;
+ gridBagConstraints.gridwidth = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
+ gridBagConstraints.insets = new java.awt.Insets(8, 8, 8, 8);
+ add(lblCargoLocation, gridBagConstraints);
+
+
txtCargoPath.setText(org.openide.util.NbBundle.getMessage(CargoPanel.class,
"CargoPanel.txtCargoPath.text")); // NOI18N
+
txtCargoPath.setToolTipText(org.openide.util.NbBundle.getMessage(CargoPanel.class,
"CargoPanel.txtCargoPath.toolTipText")); // NOI18N
+ txtCargoPath.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ txtCargoPathActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.BASELINE;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 0);
+ add(txtCargoPath, gridBagConstraints);
+
+ org.openide.awt.Mnemonics.setLocalizedText(cmdBrowse,
org.openide.util.NbBundle.getMessage(CargoPanel.class,
"CargoPanel.cmdBrowse.text")); // NOI18N
+
cmdBrowse.setToolTipText(org.openide.util.NbBundle.getMessage(CargoPanel.class,
"CargoPanel.cmdBrowse.toolTipText")); // NOI18N
+ cmdBrowse.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cmdBrowseActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 2;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.BASELINE;
+ gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 0);
+ add(cmdBrowse, gridBagConstraints);
+
+ org.openide.awt.Mnemonics.setLocalizedText(cmdGetVersion,
org.openide.util.NbBundle.getMessage(CargoPanel.class,
"CargoPanel.cmdGetVersion.text")); // NOI18N
+ cmdGetVersion.setEnabled(false);
+ cmdGetVersion.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ cmdGetVersionActionPerformed(evt);
+ }
+ });
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 3;
+ gridBagConstraints.gridy = 1;
+ gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 8);
+ add(cmdGetVersion, gridBagConstraints);
+
+
lblCargoVersion.setFont(lblCargoVersion.getFont().deriveFont(lblCargoVersion.getFont().getStyle()
| java.awt.Font.BOLD));
+ org.openide.awt.Mnemonics.setLocalizedText(lblCargoVersion,
org.openide.util.NbBundle.getMessage(CargoPanel.class,
"CargoPanel.lblCargoVersion.text")); // NOI18N
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 2;
+ gridBagConstraints.gridwidth = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
+ gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.insets = new java.awt.Insets(8, 8, 8, 8);
+ add(lblCargoVersion, gridBagConstraints);
+
+ jPanel1.setPreferredSize(new java.awt.Dimension(8, 8));
+
+ javax.swing.GroupLayout jPanel1Layout = new
javax.swing.GroupLayout(jPanel1);
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 746, Short.MAX_VALUE)
+ );
+ jPanel1Layout.setVerticalGroup(
+
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 799, Short.MAX_VALUE)
+ );
+
+ gridBagConstraints = new java.awt.GridBagConstraints();
+ gridBagConstraints.gridx = 0;
+ gridBagConstraints.gridy = 3;
+ gridBagConstraints.gridwidth = 4;
+ gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
+ gridBagConstraints.weightx = 1.0;
+ gridBagConstraints.weighty = 1.0;
+ add(jPanel1, gridBagConstraints);
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void txtCargoPathActionPerformed(java.awt.event.ActionEvent evt)
{//GEN-FIRST:event_txtCargoPathActionPerformed
+ controller.changed();
+ }//GEN-LAST:event_txtCargoPathActionPerformed
+
+ private void cmdBrowseActionPerformed(java.awt.event.ActionEvent evt)
{//GEN-FIRST:event_cmdBrowseActionPerformed
+
+ showFileChooser();
+
+ }//GEN-LAST:event_cmdBrowseActionPerformed
+
+ private void cmdGetVersionActionPerformed(java.awt.event.ActionEvent evt)
{//GEN-FIRST:event_cmdGetVersionActionPerformed
+ if (versionWorker == null) {
+ versionWorker = newWorker();
+ versionWorker.execute();
+ }
+ }//GEN-LAST:event_cmdGetVersionActionPerformed
+
+ @NbBundle.Messages({
+ "TXT_EXECUTABLE=Executable files"
+ })
+ void showFileChooser() {
+ if (fileChooser == null) {
+ String cargoName = "cargo" + (Utilities.isWindows() ? ".exe" :
""); // NOI18N
+ fileChooser = new JFileChooser(System.getProperty("user.home"));
// NOI18N
+ fileChooser.setFileFilter(new FileFilter() {
+ @Override
+ public boolean accept(File f) {
+ boolean valid = f.isDirectory();
+ valid = valid
+ || (f.isFile() && f.exists() && f.canExecute() &&
cargoName.equals(f.getName()));
+ return valid;
+ }
+
+ @Override
+ public String getDescription() {
+ return Bundle.TXT_EXECUTABLE();
+ }
+ });
+ fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
+ fileChooser.setFileHidingEnabled(false);
+ }
+ fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ int result = fileChooser.showDialog(this, null);
+ if (result == JFileChooser.APPROVE_OPTION) {
+
txtCargoPath.setText(fileChooser.getSelectedFile().getAbsolutePath());
+ }
+ }
+
+ void load() {
+ Path cargoLocation = CargoOptionsImpl.getCargoLocation(true);
+ txtCargoPath.setText(cargoLocation == null ? "" :
cargoLocation.toString());
+ }
+
+ void store() {
+ CargoOptionsImpl.setCargoLocation(txtCargoPath.getText());
+ Path cargoLocation = CargoOptionsImpl.getCargoLocation(true);
+ txtCargoPath.setText(cargoLocation == null ? "" :
cargoLocation.toString());
+ }
+
+ boolean valid() {
+ File cargo = new File(txtCargoPath.getText());
+ return cargo.exists() && cargo.isFile() && cargo.canExecute();
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton cmdBrowse;
+ private javax.swing.JButton cmdGetVersion;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JLabel lblCargoLocation;
+ private javax.swing.JLabel lblCargoVersion;
+ private javax.swing.JTextField txtCargoPath;
+ // End of variables declaration//GEN-END:variables
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ documentChanged(e);
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ documentChanged(e);
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ documentChanged(e);
+ }
+
+ private void documentChanged(DocumentEvent e) {
+ controller.changed();
+ File file = Paths.get(txtCargoPath.getText()).toFile();
+ boolean executable = file.exists() && file.canExecute();
+ cmdGetVersion.setEnabled(executable);
+ }
+
+}
diff --git
a/rust/rust.options/src/org/netbeans/modules/rust/options/impl/CargoOptionsImpl.java
b/rust/rust.options/src/org/netbeans/modules/rust/options/impl/CargoOptionsImpl.java
new file mode 100644
index 0000000000..c4fad5c3e8
--- /dev/null
+++
b/rust/rust.options/src/org/netbeans/modules/rust/options/impl/CargoOptionsImpl.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.rust.options.impl;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.prefs.Preferences;
+import javax.swing.ImageIcon;
+import javax.swing.SwingUtilities;
+import org.netbeans.api.options.OptionsDisplayer;
+import org.netbeans.modules.rust.project.api.RustProjectAPI;
+import org.openide.awt.NotificationDisplayer;
+import org.openide.util.ImageUtilities;
+import org.openide.util.NbBundle;
+import org.openide.util.NbPreferences;
+import org.openide.util.Utilities;
+
+/**
+ * CargoOptions implementation.
+ */
+public final class CargoOptionsImpl {
+
+ private static final String CARGO_LOCATION_KEY = "cargo-location"; //
NOI18N
+
+ /**
+ * Finds "cargo" (or "cargo.exe" on Windows) in any of the directories in
+ * the PATH environment variable.
+ *
+ * @return
+ */
+ private static File findCargoInPath() {
+ String path = System.getenv("PATH"); // NOI18N
+ path = path == null ? "" : path;
+ String[] parts = path.split(File.pathSeparator);
+ String extension = Utilities.isWindows() ? ".exe" : ""; // NOI18N
+ for (String part : parts) {
+ File file = new File(part, "cargo" + extension); // NOI18N
+ if (file.canExecute()) {
+ return file;
+ }
+ }
+ return null;
+ }
+
+ private static Preferences getPreferences() {
+ return NbPreferences.forModule(CargoOptionsImpl.class);
+ }
+
+ /**
+ * Returns the full path to the "cargo" executable, or null if none exists.
+ * If no preferences are present then we try
"$HOME/.cargo/bin/cargo[.exe]",
+ * and set the property.
+ *
+ * @param verifying true to verify that the path is indeed executable
+ * @return The full path to the cargo executable, or null.
+ */
+ public static Path getCargoLocation(boolean verifying) {
+ String cargo = getPreferences().get(CARGO_LOCATION_KEY, null);
+ if (cargo == null) {
+ File cargoExecutable = findCargoInPath();
+ if (cargoExecutable != null) {
+ cargo = cargoExecutable.getAbsolutePath();
+ setCargoLocation(cargo);
+ return Paths.get(cargo);
+ }
+ }
+ // Check if cargo is valid, if not then reset from preferences
+ if (cargo != null && verifying) {
+ File cargoExecutable = new File(cargo);
+ if (cargoExecutable.canExecute()) {
+ return Paths.get(cargo);
+ }
+ // Reset from prefernces
+ deleteCargoLocation();
+ cargo = null;
+ }
+ // Warn the user if cargo cannot be found
+ if (verifying) {
+ showCargoNotFoundNotification();
+ }
+ return cargo == null ? null : Paths.get(cargo);
+ }
+
+ /**
+ * Removes the previously saved cargo location.
+ */
+ public static void deleteCargoLocation() {
+ getPreferences().remove(CARGO_LOCATION_KEY);
+ }
+
+ /**
+ * Sets a new cargo location. It is ignored if this is not a valid cargo
+ * location.
+ *
+ * @param location The location (possibly an absolute path).
+ */
+ public static void setCargoLocation(String location) {
+ if (location == null) {
+ deleteCargoLocation();
+ } else {
+ File cargo = new File(location);
+ if (cargo.canExecute()) {
+ getPreferences().put(CARGO_LOCATION_KEY,
cargo.getAbsolutePath());
+ }
+ }
+ }
+
+ /**
+ * Opens the "Rust" options dialog, focused in the "Cargo" tab.
+ */
+ public static void showRustCargoOptions() {
+ SwingUtilities.invokeLater(() -> {
+ OptionsDisplayer.getDefault().open("Rust/Cargo"); // NOI18N
+ });
+ }
+
+ @NbBundle.Messages({
+ "MISSING_CARGO_TITLE=Cargo command was not found.",
+ "MISSING_CARGO_DETAILS=Cargo could not be found in your PATH. Please
select the cargo executable location"
+ })
+ public static void showCargoNotFoundNotification() {
+ NotificationDisplayer.Priority priority =
NotificationDisplayer.Priority.HIGH;
+ String title = NbBundle.getMessage(CargoOptionsImpl.class,
"MISSING_CARGO_TITLE"); // NOI18N
+ String details = NbBundle.getMessage(CargoOptionsImpl.class,
"MISSING_CARGO_DETAILS"); // NOI18N
+ ImageIcon icon = new
ImageIcon(ImageUtilities.loadImage(RustProjectAPI.ICON));
+ NotificationDisplayer.getDefault().notify(title, icon, details,
(actionEvent) -> {
+ showRustCargoOptions();
+ });
+ }
+
+}
diff --git
a/rust/rust.options/src/org/netbeans/modules/rust/options/package-info.java
b/rust/rust.options/src/org/netbeans/modules/rust/options/package-info.java
new file mode 100644
index 0000000000..48dfafcc7d
--- /dev/null
+++ b/rust/rust.options/src/org/netbeans/modules/rust/options/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
[email protected](
+ id = "Rust",
+ categoryName = "#OptionsCategory_Name_Rust",
+ iconBase = "org/netbeans/modules/rust/options/rust-logo-big.png",
+ keywords = "#OptionsCategory_Keywords_Rust",
+ keywordsCategory = "Rust",
+ position = 10000)
[email protected](value = {"OptionsCategory_Name_Rust=Rust",
"OptionsCategory_Keywords_Rust=rust cargo"})
+package org.netbeans.modules.rust.options;
+
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.NbBundle;
diff --git
a/rust/rust.options/src/org/netbeans/modules/rust/options/rust-logo-big.png
b/rust/rust.options/src/org/netbeans/modules/rust/options/rust-logo-big.png
new file mode 100644
index 0000000000..a70a0eb130
Binary files /dev/null and
b/rust/rust.options/src/org/netbeans/modules/rust/options/rust-logo-big.png
differ
diff --git
a/rust/rust.options/test/unit/src/org/netbeans/modules/rust/options/impl/CargoOptionsImplTest.java
b/rust/rust.options/test/unit/src/org/netbeans/modules/rust/options/impl/CargoOptionsImplTest.java
new file mode 100644
index 0000000000..0be626e687
--- /dev/null
+++
b/rust/rust.options/test/unit/src/org/netbeans/modules/rust/options/impl/CargoOptionsImplTest.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.rust.options.impl;
+
+import java.nio.file.Path;
+import java.util.Objects;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+/**
+ * Tests the CargoOptionsImpl.
+ */
+public class CargoOptionsImplTest {
+
+ @Test
+ public void testShouldNullPathDeleteCargoLocation() {
+ System.out.println("testShouldNullPathDeleteCargoLocation");
+ CargoOptionsImpl.setCargoLocation(null);
+ }
+
+ @Test
+ public void testShouldAutomaticallySetPathWhenAlreadyInstalled() {
+
System.out.println("testShouldAutomaticallySetPathWhenAlreadyInstalled");
+
+ // Given that we're deleting the cargo path from preferences.
+ CargoOptionsImpl.deleteCargoLocation();
+
+ // When we get it again, probably from the default
$HOME/.cargo/bin/cargo path
+ Path cargo = CargoOptionsImpl.getCargoLocation(true);
+
+ // Then if cargo is not null
+ if (cargo != null) {
+ // It must exist and be executable
+ assertTrue(cargo.toFile().canExecute());
+ }
+ }
+
+ @Test
+ public void testShouldFindCargoConsistently() {
+ System.out.println("testShouldFindCargoConsistently");
+
+ // Given a cargo found with verification
+ Path cargo = CargoOptionsImpl.getCargoLocation(true);
+
+ // When we get cargo without verification
+ Path cargo2 = CargoOptionsImpl.getCargoLocation(false);
+
+ // Then these must be equal
+ assertTrue(Objects.equals(cargo, cargo2));
+ }
+
+}
diff --git
a/rust/rust.project/src/org/netbeans/modules/rust/project/RustProjectActionProvider.java
b/rust/rust.project/src/org/netbeans/modules/rust/project/RustProjectActionProvider.java
index e9214a259f..1d61265039 100644
---
a/rust/rust.project/src/org/netbeans/modules/rust/project/RustProjectActionProvider.java
+++
b/rust/rust.project/src/org/netbeans/modules/rust/project/RustProjectActionProvider.java
@@ -73,8 +73,10 @@ public final class RustProjectActionProvider implements
ActionProvider {
break;
case COMMAND_RUN:
commands = new CargoCommand[]{CargoCommand.CARGO_RUN};
+ break;
default:
LOG.log(Level.WARNING, String.format("Invoked action %s
but cannot find a CargoBuild mode for it", command));
+ return;
}
try {
build.cargo(project.getCargoTOML(), commands);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists