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 1a0954d3f5 Rust output improvements
new 5f2c2262f6 Merge pull request #5764 from
vieiro/feature/rust-output-coloring
1a0954d3f5 is described below
commit 1a0954d3f52ec56ee5a94c64a8866bb192e9dade
Author: Antonio <[email protected]>
AuthorDate: Sun Apr 2 12:38:47 2023 +0200
Rust output improvements
---
rust/rust.cargo/licenseinfo.xml | 29 ++++
rust/rust.cargo/manifest.mf | 2 +-
rust/rust.cargo/nbproject/project.xml | 17 ++
.../org/netbeans/modules/rust/cargo/api/Cargo.java | 1 +
.../modules/rust/cargo/impl/CargoBuildImpl.java | 52 +++---
.../modules/rust/cargo/output/RustConsole.java | 182 +++++++++++++++++++++
.../output/RustErrorHyperlinkConvertorFactory.java | 113 +++++++++++++
.../rust/cargo/output/resources/options.png | Bin 0 -> 926 bytes
.../modules/rust/cargo/output/resources/rerun.png | Bin 0 -> 539 bytes
.../test/unit/data/rust-output-with-errors-1.txt | 108 ++++++++++++
.../output/RustErrorLineConvertorFactoryTest.java | 112 +++++++++++++
.../modules/rust/options/api/CargoOptions.java | 7 +
12 files changed, 597 insertions(+), 26 deletions(-)
diff --git a/rust/rust.cargo/licenseinfo.xml b/rust/rust.cargo/licenseinfo.xml
new file mode 100644
index 0000000000..e7a9715259
--- /dev/null
+++ b/rust/rust.cargo/licenseinfo.xml
@@ -0,0 +1,29 @@
+<?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/cargo/output/resources/options.png</file>
+
<file>src/org/netbeans/modules/rust/cargo/output/resources/rerun.png</file>
+ <license ref="Apache-2.0-ASF" />
+ <comment type="COMMENT_UNSUPPORTED" />
+ </fileset>
+</licenseinfo>
diff --git a/rust/rust.cargo/manifest.mf b/rust/rust.cargo/manifest.mf
index f1cbe21b6a..64d3f4c6c8 100644
--- a/rust/rust.cargo/manifest.mf
+++ b/rust/rust.cargo/manifest.mf
@@ -2,5 +2,5 @@ Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.modules.rust.cargo
OpenIDE-Module-Layer: org/netbeans/modules/rust/cargo/layer.xml
OpenIDE-Module-Localizing-Bundle:
org/netbeans/modules/rust/cargo/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.11
+OpenIDE-Module-Specification-Version: 1.12
diff --git a/rust/rust.cargo/nbproject/project.xml
b/rust/rust.cargo/nbproject/project.xml
index 804a7bb7e2..693c953866 100644
--- a/rust/rust.cargo/nbproject/project.xml
+++ b/rust/rust.cargo/nbproject/project.xml
@@ -25,6 +25,15 @@
<data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
<code-name-base>org.netbeans.modules.rust.cargo</code-name-base>
<module-dependencies>
+ <dependency>
+
<code-name-base>org.netbeans.api.annotations.common</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <release-version>1</release-version>
+ <specification-version>1.48</specification-version>
+ </run-dependency>
+ </dependency>
<dependency>
<code-name-base>org.netbeans.api.io</code-name-base>
<build-prerequisite/>
@@ -159,6 +168,14 @@
<specification-version>7.65</specification-version>
</run-dependency>
</dependency>
+ <dependency>
+ <code-name-base>org.openide.text</code-name-base>
+ <build-prerequisite/>
+ <compile-dependency/>
+ <run-dependency>
+ <specification-version>6.88</specification-version>
+ </run-dependency>
+ </dependency>
<dependency>
<code-name-base>org.openide.util</code-name-base>
<build-prerequisite/>
diff --git a/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/api/Cargo.java
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/api/Cargo.java
index 9276d2612a..8f7456d657 100644
--- a/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/api/Cargo.java
+++ b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/api/Cargo.java
@@ -36,6 +36,7 @@ public interface Cargo {
* @param cargotoml The Cargo.toml affected by the cargo.
* @param commands The array of cargo commands, to be executed one after
* another.
+ * @param options optional list of options (verbose, for instance).
* @throws IOException If a problem happens.
*/
public void cargo(CargoTOML cargotoml, CargoCommand[] commands, String...
options) throws IOException;
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 1d0ad7f579..7e09758cd1 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
@@ -39,10 +39,10 @@ import org.netbeans.modules.rust.cargo.api.CargoTOML;
import org.openide.filesystems.FileUtil;
import org.openide.util.RequestProcessor;
import org.openide.util.lookup.ServiceProvider;
-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.cargo.output.RustConsole;
+import
org.netbeans.modules.rust.cargo.output.RustErrorHyperlinkConvertorFactory;
import org.netbeans.modules.rust.options.api.CargoOptions;
import org.openide.LifecycleManager;
import org.openide.util.Exceptions;
@@ -66,10 +66,10 @@ public class CargoBuildImpl implements Cargo {
private final CargoTOML cargotoml;
private final CargoCommand command;
- private final InputOutput console;
+ private final RustConsole console;
private final String[] options;
- CargoProcess(CargoTOML cargotoml, CargoCommand command, String[]
options, InputOutput console) {
+ CargoProcess(CargoTOML cargotoml, CargoCommand command, String[]
options, RustConsole console) {
this.cargotoml = cargotoml;
this.command = command;
this.console = console;
@@ -93,7 +93,7 @@ public class CargoBuildImpl implements Cargo {
pb.setExecutable(cargo.toString());
pb.setArguments(arguments);
- console.getOut().println(String.format("%n$ cargo %s",
String.join(" ", arguments))); // NOI18N
+ console.printInformationMessage(String.format("%n$ cargo %s",
String.join(" ", arguments))); // NOI18N
return pb.call();
}
@@ -111,11 +111,14 @@ public class CargoBuildImpl implements Cargo {
private final CargoTOML cargotoml;
private final CargoCommand[] commands;
private final String[] options;
+ private final RequestProcessor requestProcessor;
+ private RustConsole console;
- SequentialCargoProcesses(CargoTOML cargotoml, CargoCommand[] commands,
String[] options) {
+ SequentialCargoProcesses(RequestProcessor requestProcessor, CargoTOML
cargotoml, CargoCommand[] commands, String[] options) {
this.cargotoml = cargotoml;
this.commands = commands;
this.options = options;
+ this.requestProcessor = requestProcessor;
}
@Override
@@ -127,41 +130,35 @@ public class CargoBuildImpl implements Cargo {
// Get a proper console for the input/output
String projectName = cargotoml.getPackageName();
String commandNames =
Arrays.stream(commands).map(CargoCommand::getDisplayName).collect(Collectors.joining(","));
// NOI18N
- String ioName = String.format("%s (%s)", projectName,
commandNames); // NOI18N
- InputOutput console = IOProvider.getDefault().getIO(ioName, false);
- console.select();
+ String consoleTabName = String.format("%s (%s)", projectName,
commandNames); // NOI18N
- 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);
+ console = new RustConsole(cargotoml, consoleTabName, this::run);
ExecutionDescriptor ed = new ExecutionDescriptor()
- .inputOutput(IOProvider.getDefault().getIO(ioName, false))
+ .controllable(false)
+ .inputOutput(console.getInputOutput())
.inputVisible(true)
.frontWindow(false)
.frontWindowOnError(true)
- .noReset(true)
.showProgress(false)
- .controllable(true);
+ .noReset(true)
+ .errConvertorFactory(new
RustErrorHyperlinkConvertorFactory(cargotoml, console.getInputOutput()))
+ ;
int resultCode = 0;
for (CargoCommand command : commands) {
CargoProcess process = new CargoProcess(cargotoml, command,
options, console);
- ExecutionService service =
ExecutionService.newService(process, ed, ioName);
+ ExecutionService service =
ExecutionService.newService(process, ed, consoleTabName);
Future<Integer> resultCodeFuture = service.run();
try {
resultCode = resultCodeFuture.get();
} catch (Exception e) {
- console.getErr().println(String.format("Cargo execution
failed: %s%n", e.getMessage()));
+ console.printErrorMessage(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
+ console.printErrorMessage(String.format("Command \"cargo
%s\" failed with exit status %d", // NOI18N
String.join(" ", command.arguments),
resultCode));
break;
@@ -170,6 +167,11 @@ public class CargoBuildImpl implements Cargo {
return resultCode;
}
+ public void run() {
+ LifecycleManager.getDefault().saveAll();
+ requestProcessor.submit(this);
+ }
+
}
private final RequestProcessor requestProcessor;
@@ -190,11 +192,11 @@ public class CargoBuildImpl implements Cargo {
if (cargo == null) {
return;
}
- // Let's save stuff just in case
- LifecycleManager.getDefault().saveAll();
- requestProcessor.submit(new SequentialCargoProcesses(cargotoml,
commands, options));
+ SequentialCargoProcesses sequentialCommands = new
SequentialCargoProcesses(requestProcessor, cargotoml, commands, options);
+ sequentialCommands.run();
}
+
/**
* Runs `cargo search [text] --limit 15 --color never`
*/
diff --git
a/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/RustConsole.java
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/RustConsole.java
new file mode 100644
index 0000000000..756267c7d7
--- /dev/null
+++
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/RustConsole.java
@@ -0,0 +1,182 @@
+/*
+ * 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.cargo.output;
+
+import java.awt.event.ActionEvent;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import org.netbeans.api.annotations.common.StaticResource;
+import org.netbeans.modules.rust.cargo.api.CargoTOML;
+import org.netbeans.modules.rust.cargo.impl.CargoBuildImpl;
+import org.netbeans.modules.rust.options.api.CargoOptions;
+import org.openide.filesystems.FileUtil;
+import org.openide.util.ImageUtilities;
+import org.openide.util.NbBundle;
+import org.openide.windows.IOColorLines;
+import org.openide.windows.IOColors;
+import org.openide.windows.IOContainer;
+import org.openide.windows.IOProvider;
+import org.openide.windows.InputOutput;
+
+/**
+ * Responsible for handling the Rust inputOutput.
+ */
[email protected]({
+ "MSG_WORKING_DIRECTORY=Working directory:",
+ "MSG_CARGO_PATH=Cargo: ",
+ "MSG_RERUN=Re-run",
+ "MSG_RERUN_SHORT=Re-runs these same commands again",
+ "MSG_RUST_OPTIONS=Options",
+ "MSG_RUST_OPTIONS_SHORT=Open Rust options panel",
+})
+public final class RustConsole {
+
+ private static final class ReRunAction extends AbstractAction {
+
+ @StaticResource
+ private static final String RERUN_ICON =
"org/netbeans/modules/rust/cargo/output/resources/rerun.png"; // NOI18N
+
+ private final Runnable reRunCommand;
+
+ private ReRunAction(Runnable reRunCommand) {
+ super(Bundle.MSG_RERUN(),
ImageUtilities.image2Icon(ImageUtilities.loadImage(RERUN_ICON)));
+ this.reRunCommand = reRunCommand;
+ putValue(Action.SHORT_DESCRIPTION, Bundle.MSG_RERUN_SHORT());
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ reRunCommand.run();
+ }
+
+ }
+ private static final class OptionsAction extends AbstractAction { // #59396
+
+ @StaticResource
+ private static final String OPTIONS_ICON =
"org/netbeans/modules/rust/cargo/output/resources/options.png"; // NOI18N
+
+ @Override
+ public Object getValue(String key) {
+ if (key.equals(Action.SMALL_ICON)) {
+ return
ImageUtilities.image2Icon(ImageUtilities.loadImage(OPTIONS_ICON));
+ } else if (key.equals(Action.SHORT_DESCRIPTION)) {
+ return Bundle.MSG_RUST_OPTIONS_SHORT();
+ } else {
+ return super.getValue(key);
+ }
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ CargoOptions.showRustCargoOptions();
+ }
+
+ }
+ private final CargoTOML cargotoml;
+ private final InputOutput inputOutput;
+ private final String name;
+ private final Runnable reRunAction;
+
+ /**
+ * Creates a new RustConsole that prints out Cargo command results.
+ *
+ * @param cargotoml The Cargo.toml for the project.
+ * @param name The name of the console (that name of the tab)
+ * @param reRunCommand an action to be invoked if the user wants to re-run
+ * something, or null.
+ * @throws IOException if an I/O error happens.
+ */
+ public RustConsole(CargoTOML cargotoml, String name, Runnable
reRunCommand) throws IOException {
+ this.cargotoml = cargotoml;
+ this.name = name;
+ this.reRunAction = reRunCommand;
+
+ ArrayList<Action> actions = new ArrayList<>();
+
+ if (reRunCommand != null) {
+ actions.add(new ReRunAction(reRunCommand));
+ }
+
+ actions.add(new OptionsAction());
+
+ inputOutput = IOProvider.getDefault().getIO(name, false,
actions.toArray(new Action[0]), IOContainer.getDefault());
+ inputOutput.select();
+ inputOutput.getOut().reset();
+
+ // Print working directory and cargo path
+ File workingDirectory =
FileUtil.toFile(cargotoml.getFileObject()).getParentFile();
+ Path cargo = CargoOptions.getCargoLocation(false);
+
+ String message = String.format("# %s %s", // NOI18N
+ NbBundle.getMessage(CargoBuildImpl.class,
"MSG_WORKING_DIRECTORY"),
+ workingDirectory.getAbsolutePath());
+ printInformationMessage(message);
+ message = String.format("# %s %s", // NOI18N
+ NbBundle.getMessage(CargoBuildImpl.class, "MSG_CARGO_PATH"),
+ cargo);
+ printInformationMessage(message);
+ }
+
+ /**
+ * Returns the underlying InputOutput object used for printing out
messages.
+ *
+ * @return The InputOutput object.
+ */
+ public InputOutput getInputOutput() {
+ return inputOutput;
+ }
+
+ /**
+ * The name of this console.
+ *
+ * @return As shown in the Output tab.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Prints a (possibly colored) information message.
+ *
+ * @param message The message to print
+ * @throws IOException On error
+ */
+ public void printInformationMessage(String message) throws IOException {
+ if (IOColorLines.isSupported(inputOutput)) {
+ IOColorLines.println(inputOutput, message,
IOColors.getColor(inputOutput, IOColors.OutputType.LOG_DEBUG));
+ } else {
+ inputOutput.getOut().println(message);
+ }
+ }
+
+ /**
+ * Prints a (possibly colored) error message.
+ *
+ * @param message The message to print
+ * @throws IOException On error
+ */
+ public void printErrorMessage(String message) throws IOException {
+ inputOutput.getErr().println(message);
+ }
+
+}
diff --git
a/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/RustErrorHyperlinkConvertorFactory.java
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/RustErrorHyperlinkConvertorFactory.java
new file mode 100644
index 0000000000..a13acebfc2
--- /dev/null
+++
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/RustErrorHyperlinkConvertorFactory.java
@@ -0,0 +1,113 @@
+/*
+ * 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.cargo.output;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.netbeans.api.extexecution.ExecutionDescriptor;
+import org.netbeans.api.extexecution.print.ConvertedLine;
+import org.netbeans.api.extexecution.print.LineConvertor;
+import org.netbeans.modules.rust.cargo.api.CargoTOML;
+import org.openide.cookies.LineCookie;
+import org.openide.filesystems.FileObject;
+import org.openide.text.Line;
+import org.openide.windows.InputOutput;
+import org.openide.windows.OutputEvent;
+import org.openide.windows.OutputListener;
+
+/**
+ * An LineConvertorFactory that adds hyperlinks in Rust error messages to go
+ * directly to the origin of a problem.
+ */
+public class RustErrorHyperlinkConvertorFactory implements OutputListener,
LineConvertor, ExecutionDescriptor.LineConvertorFactory {
+
+ private static final Pattern RUST_ERROR_HYPERLINK =
Pattern.compile("^[\\s]+--> ([^:]+):([\\d]+):([\\d]+)$");
+
+ static Matcher matchesSourcePosition(String line) {
+ return RUST_ERROR_HYPERLINK.matcher(line);
+ }
+
+ private final CargoTOML cargo;
+ private final InputOutput inputOutput;
+
+ public RustErrorHyperlinkConvertorFactory(CargoTOML cargo, InputOutput
inputOutput) {
+ this.cargo = cargo;
+ this.inputOutput = inputOutput;
+ }
+
+ // ExecutionDescriptor.LineConverterFactory
+ @Override
+ public LineConvertor newLineConvertor() {
+ return this;
+ }
+
+ // LineConverter
+ @Override
+ public List<ConvertedLine> convert(String line) {
+ Matcher errorLocationLineMatcher = matchesSourcePosition(line);
+ if (errorLocationLineMatcher.matches()) {
+ ConvertedLine cline = ConvertedLine.forText(line, this);
+ return Collections.singletonList(cline);
+ }
+ return null;
+ }
+
+ // OutputListener
+ @Override
+ public void outputLineSelected(OutputEvent ev) {
+ }
+
+ // OutputListener
+ @Override
+ public void outputLineCleared(OutputEvent ev) {
+ }
+
+ // OutputListener
+ @Override
+ public void outputLineAction(OutputEvent ev) {
+ // Invoked to show a given position in the source code
+ Matcher m = matchesSourcePosition(ev.getLine());
+ if (m.matches()) {
+ String dirAndFile = m.group(1);
+ int lineNumber = Integer.parseInt(m.group(2));
+ int column = Integer.parseInt(m.group(3));
+ openFile(dirAndFile, lineNumber, column);
+ }
+ }
+
+ private void openFile(String dirAndFile, int lineNumber, int column) {
+ FileObject projectDirectory = cargo.getFileObject().getParent();
+ FileObject file = projectDirectory.getFileObject(dirAndFile);
+
+ if (file != null) {
+ LineCookie lineCookie = file.getLookup().lookup(LineCookie.class);
+ if (lineCookie != null) {
+ Line theLine = lineCookie.getLineSet().getCurrent(lineNumber -
1);
+ if (theLine != null) {
+ theLine.show(Line.ShowOpenType.OPEN,
+ Line.ShowVisibilityType.FOCUS,
+ column - 1);
+ }
+ }
+ }
+ }
+
+}
diff --git
a/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/resources/options.png
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/resources/options.png
new file mode 100644
index 0000000000..d532dedd64
Binary files /dev/null and
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/resources/options.png
differ
diff --git
a/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/resources/rerun.png
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/resources/rerun.png
new file mode 100644
index 0000000000..1e06be9c9e
Binary files /dev/null and
b/rust/rust.cargo/src/org/netbeans/modules/rust/cargo/output/resources/rerun.png
differ
diff --git a/rust/rust.cargo/test/unit/data/rust-output-with-errors-1.txt
b/rust/rust.cargo/test/unit/data/rust-output-with-errors-1.txt
new file mode 100644
index 0000000000..0d568d72c4
--- /dev/null
+++ b/rust/rust.cargo/test/unit/data/rust-output-with-errors-1.txt
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+// This file used to detect errors in Rust build output
+
+$ cargo run
+Hello, world!: Another thing!!
+warning: unused variable: `z`
+ --> src/main.rs:8:17
+ |
+8 | let z="Hello, world!";
+ | ^ help: if this is intentional, prefix it with an
underscore: `_z`
+ |
+ = note: `#[warn(unused_variables)]` on by default
+
+warning: struct `Val` is never constructed
+ --> src/main.rs:17:12
+ |
+17 | struct Val {
+ | ^^^
+ |
+ = note: `#[warn(dead_code)]` on by default
+
+warning: function `private_function` is never used
+ --> src/main.rs:29:8
+ |
+29 | fn private_function() {
+ | ^^^^^^^^^^^^^^^^
+
+warning: function `function` is never used
+ --> src/main.rs:34:12
+ |
+34 | pub fn function() {
+ | ^^^^^^^^
+
+warning: function `indirect_access` is never used
+ --> src/main.rs:40:12
+ |
+40 | pub fn indirect_access() {
+ | ^^^^^^^^^^^^^^^
+
+warning: function `call_public_function_in_my_mod` is never used
+ --> src/main.rs:76:12
+ |
+76 | pub fn call_public_function_in_my_mod() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: function `public_function_in_crate` is never used
+ --> src/main.rs:84:19
+ |
+84 | pub(crate) fn public_function_in_crate() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: associated function `value` is never used
+ --> src/main.rs:22:12
+ |
+22 | fn value(&self) -> &f64 {
+ | ^^^^^
+
+warning: function `whatever` is never used
+ --> src/main.rs:7:12
+ |
+7 | fn whatever() {
+ | ^^^^^^^^
+
+warning: function `function` is never used
+ --> src/main.rs:47:16
+ |
+47 | pub fn function() {
+ | ^^^^^^^^
+
+warning: function `public_function_in_my_mod` is never used
+ --> src/main.rs:58:34
+ |
+58 | pub(in crate::my_mod) fn public_function_in_my_mod() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: function `public_function_in_nested` is never used
+ --> src/main.rs:65:22
+ |
+65 | pub(self) fn public_function_in_nested() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: function `public_function_in_super_mod` is never used
+ --> src/main.rs:71:23
+ |
+71 | pub(super) fn public_function_in_super_mod() {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+warning: `rust1` (bin "rust1") generated 13 warnings
+ Finished dev [unoptimized + debuginfo] target(s) in 0.04s
+ Running `target/debug/rust1`
diff --git
a/rust/rust.cargo/test/unit/src/org/netbeans/modules/rust/cargo/output/RustErrorLineConvertorFactoryTest.java
b/rust/rust.cargo/test/unit/src/org/netbeans/modules/rust/cargo/output/RustErrorLineConvertorFactoryTest.java
new file mode 100644
index 0000000000..75ddd2a454
--- /dev/null
+++
b/rust/rust.cargo/test/unit/src/org/netbeans/modules/rust/cargo/output/RustErrorLineConvertorFactoryTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.cargo.output;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.regex.Matcher;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.netbeans.junit.NbTestCase;
+
+/**
+ *
+ * @author antonio
+ */
+public class RustErrorLineConvertorFactoryTest extends NbTestCase {
+
+ public RustErrorLineConvertorFactoryTest() {
+ super("RustErrorLineConvertorFactoryTest");
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ @Test
+ public void testShouldDetectHyperlinks() throws Exception {
+ System.out.println("testShouldDetectHyperlinks");
+
+ // Given some error lines with a proper source position
+ String[] lines = {
+ " --> src/main.rs:8:17",
+ " --> src/main.rs:17:12",
+ " --> src/main.rs:29:8"
+ };
+
+ for (String line : lines) {
+ // When we try to find the position
+ Matcher matcher =
RustErrorHyperlinkConvertorFactory.matchesSourcePosition(line);
+
+ // Then the position is found
+ assertTrue("This line could not be detected: " + line,
matcher.matches());
+ assertEquals(
+ "src/main.rs", matcher.group(1));
+ int nLine = Integer.parseInt(matcher.group(2));
+ assertEquals("" + nLine, matcher.group(2));
+ int nCol = Integer.parseInt(matcher.group(3));
+ assertEquals("" + nCol, matcher.group(3));
+ }
+ }
+
+ @Test
+ public void testShouldDetectHyperlinksInTestFile() throws Exception {
+ System.out.println("testShouldDetectHyperlinksInTestFile");
+ File test = new File(getDataDir(), "rust-output-with-errors-1.txt");
+
+ int hyperlinkCount = 0;
+ int lineNumber = 0;
+
+ try (BufferedReader reader = new BufferedReader(new
InputStreamReader(new FileInputStream(test), StandardCharsets.UTF_8))) {
+ do {
+ String line = reader.readLine();
+ if (line == null) {
+ break;
+ }
+ lineNumber ++;
+ if
(RustErrorHyperlinkConvertorFactory.matchesSourcePosition(line).matches()) {
+ hyperlinkCount++;
+ // DEBUG:
+ // System.out.format("LINE %3d:'%s'%n", lineNumber, line);
+ }
+ } while (true);
+ }
+ assertEquals(13, hyperlinkCount);
+
+ }
+
+}
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
index 883c24e4cf..0489202185 100644
---
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
@@ -38,4 +38,11 @@ public final class CargoOptions {
return CargoOptionsImpl.getCargoLocation(verifying);
}
+ /**
+ * Opens the Cargo options panel.
+ */
+ public static void showRustCargoOptions() {
+ CargoOptionsImpl.showRustCargoOptions();
+ }
+
}
---------------------------------------------------------------------
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