backport: 13.2.0
This commit is contained in:
parent
7cdbc443f1
commit
6f20612c5e
26 changed files with 317 additions and 83 deletions
25
CHANGELOG.md
25
CHANGELOG.md
|
@ -18,6 +18,31 @@ Changelog structure reference:
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [13.2.0]
|
||||
|
||||
### Added
|
||||
|
||||
- Debugging
|
||||
- For Zig build tasks, the target executable is now auto-detected in `zig-out/bin` if not specified.
|
||||
Autodetect fails if multiple executables are present for consistency's sake.
|
||||
- You can specify custom command line arguments for the debugged executable.
|
||||
|
||||
- Project
|
||||
- The line marker generated `zig build` now defaults to the `run` step.
|
||||
|
||||
### Changed
|
||||
|
||||
- Project
|
||||
- `zig build` steps are now specified separately from miscellaneous command line arguments.
|
||||
This is needed for the debugger to work properly.
|
||||
- The zig build debug executable target configs are now hidden from Zig build tasks in IDEs without native debugging support.
|
||||
- Native Application (Zig) is now hidden in IDEs without native debugging support.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Debugging
|
||||
- Debugger locks up when trying to debug `zig build run` tasks.
|
||||
|
||||
## [13.1.1]
|
||||
|
||||
### Fixed
|
||||
|
|
62
build.sh
Normal file
62
build.sh
Normal file
|
@ -0,0 +1,62 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Copyright 2023-2024 FalsePattern
|
||||
#
|
||||
# Licensed 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.
|
||||
#
|
||||
|
||||
declare -a branches=("master" "233" "232" "231")
|
||||
|
||||
DEFAULT_BRANCH="${branches[0]}"
|
||||
|
||||
if [[ -z "${PRIVATE_KEY_PASSWORD}" ]]; then
|
||||
echo "Private key password does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f secrets/chain.crt ]; then
|
||||
echo "Certificate chain does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f secrets/private.pem ]; then
|
||||
echo "Plugin signing key does not exist!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git checkout "$DEFAULT_BRANCH" && ./gradlew clean
|
||||
|
||||
RESULT=$?
|
||||
|
||||
if [ $RESULT != 0 ]; then
|
||||
echo "Failed to clean!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
for i in "${branches[@]}"
|
||||
do
|
||||
echo "Building branch $i"
|
||||
git checkout "$i" && ./gradlew :plugin:verifyPluginSignature
|
||||
RESULT=$?
|
||||
if [ $RESULT != 0 ]; then
|
||||
echo "Failed to build plugin on branch $i!"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
git checkout "$DEFAULT_BRANCH"
|
||||
|
||||
mkdir -p build/dist
|
||||
|
||||
cp plugin/build/distributions/*-signed.zip build/dist/
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 2023-2024 FalsePattern
|
||||
*
|
||||
* Licensed 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 com.falsepattern.zigbrains.common;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import lombok.val;
|
||||
|
||||
public interface ZBFeatures {
|
||||
ExtensionPointName<ZBFeatures> EXTENSION_POINT_NAME = ExtensionPointName.create("com.falsepattern.zigbrains.featureProvider");
|
||||
|
||||
static boolean debug() {
|
||||
val extensions = EXTENSION_POINT_NAME.getExtensionList();
|
||||
for (val extension : extensions) {
|
||||
if (extension.getDebug()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean getDebug() {
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -24,15 +24,22 @@ import java.util.List;
|
|||
import java.util.Objects;
|
||||
|
||||
public class CollectionUtil {
|
||||
public static <T> List<T> concat(List<T> a, List<T> b) {
|
||||
val res = new ArrayList<>(a);
|
||||
res.addAll(b);
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> List<T> concat(List<T>... lists) {
|
||||
val res = new ArrayList<T>();
|
||||
for (List<T> list : lists) {
|
||||
res.addAll(list);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static <T> List<T> concat(T[] a, List<T> b) {
|
||||
@SafeVarargs
|
||||
public static <T> List<T> concat(T[] a, List<T>... b) {
|
||||
val res = new ArrayList<>(List.of(a));
|
||||
res.addAll(b);
|
||||
for (List<T> list : b) {
|
||||
res.addAll(list);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -43,28 +50,21 @@ public class CollectionUtil {
|
|||
return res;
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public static <T> List<T> concat(List<T> a, T[]... b) {
|
||||
val res = new ArrayList<>(a);
|
||||
for (val arr: b) {
|
||||
res.addAll(List.of(arr));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T[] concat(T[]... arrays) {
|
||||
if (null != arrays && 0 != arrays.length) {
|
||||
int resultLength = (Integer)java.util.Arrays.stream(arrays).filter(Objects::nonNull).map((e) -> {
|
||||
return e.length;
|
||||
}).reduce(0, Integer::sum);
|
||||
T[] resultArray = (T[]) Array.newInstance(arrays[0].getClass().getComponentType(), resultLength);
|
||||
int i = 0;
|
||||
int n = arrays.length;
|
||||
|
||||
for(int curr = 0; i < n; ++i) {
|
||||
T[] array = arrays[i];
|
||||
if (null != array) {
|
||||
int length = array.length;
|
||||
System.arraycopy(array, 0, resultArray, curr, length);
|
||||
curr += length;
|
||||
}
|
||||
}
|
||||
|
||||
return resultArray;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
public static <T> List<T> concat(T[]... arrays) {
|
||||
val res = new ArrayList<T>();
|
||||
for (val arr: arrays) {
|
||||
res.addAll(List.of(arr));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright 2023-2024 FalsePattern
|
||||
*
|
||||
* Licensed 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 com.falsepattern.zigbrains.debugger;
|
||||
|
||||
import com.falsepattern.zigbrains.common.ZBFeatures;
|
||||
|
||||
public class DebuggerFeatures implements ZBFeatures {
|
||||
@Override
|
||||
public boolean getDebug() {
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.project.execution.binary;
|
||||
package com.falsepattern.zigbrains.debugger.execution.binary;
|
||||
|
||||
import com.falsepattern.zigbrains.zig.Icons;
|
||||
import com.intellij.execution.configurations.ConfigurationFactory;
|
||||
|
@ -27,7 +27,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
public class ConfigTypeBinary extends ConfigurationTypeBase {
|
||||
public static final String IDENTIFIER = "ZIGBRAINS_BINARY";
|
||||
public ConfigTypeBinary() {
|
||||
super(IDENTIFIER, "Zig-compiled native executable", "Binary executable compiled from zig code", Icons.ZIG);
|
||||
super(IDENTIFIER, "Native Application (Zig)", "Binary executable compiled from zig code (useful for debugging on Windows)", Icons.ZIG);
|
||||
addFactory(new ConfigFactoryBinary());
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.project.execution.binary;
|
||||
package com.falsepattern.zigbrains.debugger.execution.binary;
|
||||
|
||||
import com.falsepattern.zigbrains.project.execution.base.ProfileStateBase;
|
||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
|
@ -14,7 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.project.execution.binary;
|
||||
package com.falsepattern.zigbrains.debugger.execution.binary;
|
||||
|
||||
import com.falsepattern.zigbrains.common.util.CollectionUtil;
|
||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigEditor;
|
|
@ -17,7 +17,7 @@
|
|||
package com.falsepattern.zigbrains.debugger.runner.binary;
|
||||
|
||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersBase;
|
||||
import com.falsepattern.zigbrains.project.execution.binary.ProfileStateBinary;
|
||||
import com.falsepattern.zigbrains.debugger.execution.binary.ProfileStateBinary;
|
||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
|
|
|
@ -19,8 +19,8 @@ package com.falsepattern.zigbrains.debugger.runner.binary;
|
|||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersBase;
|
||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugRunnerBase;
|
||||
import com.falsepattern.zigbrains.project.execution.base.ProfileStateBase;
|
||||
import com.falsepattern.zigbrains.project.execution.binary.ProfileStateBinary;
|
||||
import com.falsepattern.zigbrains.project.execution.binary.ZigExecConfigBinary;
|
||||
import com.falsepattern.zigbrains.debugger.execution.binary.ProfileStateBinary;
|
||||
import com.falsepattern.zigbrains.debugger.execution.binary.ZigExecConfigBinary;
|
||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain;
|
||||
import com.falsepattern.zigbrains.project.toolchain.LocalZigToolchain;
|
||||
import com.intellij.execution.configurations.RunProfile;
|
||||
|
|
|
@ -24,15 +24,19 @@ import com.intellij.execution.ExecutionException;
|
|||
import com.intellij.execution.configurations.GeneralCommandLine;
|
||||
import com.jetbrains.cidr.execution.Installer;
|
||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration;
|
||||
import lombok.Cleanup;
|
||||
import lombok.val;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ZigDebugParametersBuild extends ZigDebugParametersBase<ProfileStateBuild> {
|
||||
private static final String BoilerplateNotice = "\nPlease edit this intellij build configuration and specify the path of the executable created by \"zig build\" directly!";
|
||||
public ZigDebugParametersBuild(DebuggerDriverConfiguration driverConfiguration, AbstractZigToolchain toolchain, ProfileStateBuild profileStateBuild) {
|
||||
super(driverConfiguration, toolchain, profileStateBuild);
|
||||
}
|
||||
|
@ -43,11 +47,6 @@ public class ZigDebugParametersBuild extends ZigDebugParametersBase<ProfileState
|
|||
private File executableFile;
|
||||
@Override
|
||||
public @NotNull GeneralCommandLine install() throws ExecutionException {
|
||||
val exePath = profileState.configuration().getExePath().getPath();
|
||||
if (exePath.isEmpty()) {
|
||||
throw new ExecutionException("Please specify the output exe path to debug \"zig build\" tasks!");
|
||||
}
|
||||
Path exe = exePath.get();
|
||||
val commandLine = profileState.getCommandLine(toolchain, true);
|
||||
val outputOpt = CLIUtil.execute(commandLine, Integer.MAX_VALUE);
|
||||
if (outputOpt.isEmpty()) {
|
||||
|
@ -58,16 +57,45 @@ public class ZigDebugParametersBuild extends ZigDebugParametersBase<ProfileState
|
|||
throw new ExecutionException("Zig compilation failed with exit code " + output.getExitCode() + "\nError output:\n" + output.getStdout() + "\n" + output.getStderr());
|
||||
}
|
||||
|
||||
if (!Files.exists(exe) || !Files.isExecutable(exe)) {
|
||||
throw new ExecutionException("File " + exe + " does not exist or is not executable!");
|
||||
val cfg = profileState.configuration();
|
||||
val workingDir = cfg.getWorkingDirectory().getPath().orElse(null);
|
||||
val exePath = profileState.configuration().getExePath().getPath();
|
||||
Path exe;
|
||||
if (exePath.isEmpty()) {
|
||||
//Attempt autodetect, should work for trivial cases, and make basic users happy, while advanced
|
||||
// users can use manual executable paths.
|
||||
if (workingDir == null) {
|
||||
throw new ExecutionException("Cannot find working directory to run debugged executable!" + BoilerplateNotice);
|
||||
}
|
||||
val expectedOutputDir = workingDir.resolve(Path.of("zig-out", "bin"));
|
||||
if (!Files.exists(expectedOutputDir)) {
|
||||
throw new ExecutionException("Could not auto-detect default executable output directory \"zig-out/bin\"!" + BoilerplateNotice);
|
||||
}
|
||||
try (val filesInOutput = Files.list(expectedOutputDir)) {
|
||||
val executables = filesInOutput.filter(Files::isRegularFile).filter(Files::isExecutable).toList();
|
||||
if (executables.size() > 1) {
|
||||
throw new ExecutionException("Multiple executables found!" + BoilerplateNotice);
|
||||
}
|
||||
exe = executables.get(0);
|
||||
} catch (IOException e) {
|
||||
throw new ExecutionException("Could not scan output directory \"" + expectedOutputDir + "\"!" + BoilerplateNotice);
|
||||
}
|
||||
} else {
|
||||
exe = exePath.get();
|
||||
}
|
||||
|
||||
if (!Files.exists(exe)) {
|
||||
throw new ExecutionException("File " + exe + " does not exist!");
|
||||
} else if (!Files.isExecutable(exe)) {
|
||||
throw new ExecutionException("File " + exe + " is not executable!");
|
||||
}
|
||||
|
||||
executableFile = exe.toFile();
|
||||
|
||||
//Construct new command line
|
||||
val cfg = profileState.configuration();
|
||||
val cli = new GeneralCommandLine().withExePath(executableFile.getAbsolutePath());
|
||||
cfg.getWorkingDirectory().getPath().ifPresent(x -> cli.setWorkDirectory(x.toFile()));
|
||||
cli.addParameters(cfg.getExeArgs().args);
|
||||
cli.withCharset(StandardCharsets.UTF_8);
|
||||
cli.withRedirectErrorStream(true);
|
||||
return cli;
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
<resource-bundle>zigbrains.debugger.Bundle</resource-bundle>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<configurationType implementation="com.falsepattern.zigbrains.debugger.execution.binary.ConfigTypeBinary"/>
|
||||
|
||||
<programRunner implementation="com.falsepattern.zigbrains.debugger.runner.run.ZigDebugRunnerRun"
|
||||
id="ZigDebugRunnerRun"/>
|
||||
<programRunner implementation="com.falsepattern.zigbrains.debugger.runner.test.ZigDebugRunnerTest"
|
||||
|
@ -41,6 +43,10 @@
|
|||
displayName="Zig (Windows)"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.falsepattern.zigbrains">
|
||||
<featureProvider implementation="com.falsepattern.zigbrains.debugger.DebuggerFeatures"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="cidr.debugger">
|
||||
<languageSupport language="Zig" implementationClass="com.falsepattern.zigbrains.debugger.ZigDebuggerLanguageSupport"/>
|
||||
<editorsExtension language="Zig" implementationClass="com.falsepattern.zigbrains.debugger.ZigDebuggerEditorsExtension"/>
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.intellij.ui.dsl.builder.AlignX;
|
|||
import com.intellij.ui.dsl.builder.AlignY;
|
||||
import com.intellij.ui.dsl.builder.Panel;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
|
@ -154,7 +155,10 @@ public class ZigConfigEditor<T extends ZigExecConfigBase<T>> extends SettingsEdi
|
|||
@Override
|
||||
public void readExternal(@NotNull Element element) {
|
||||
try {
|
||||
ElementUtil.readString(element, getSerializedName()).map(Paths::get).ifPresent(x -> path = x);
|
||||
ElementUtil.readString(element, getSerializedName())
|
||||
.filter(str -> !str.isBlank())
|
||||
.map(Paths::get)
|
||||
.ifPresent(x -> path = x);
|
||||
} catch (InvalidPathException ignored){}
|
||||
}
|
||||
|
||||
|
@ -175,7 +179,12 @@ public class ZigConfigEditor<T extends ZigExecConfigBase<T>> extends SettingsEdi
|
|||
@Override
|
||||
public void apply(T s) throws ConfigurationException {
|
||||
try {
|
||||
s.setPath(Paths.get(getString()));
|
||||
val str = getString();
|
||||
if (str.isBlank()) {
|
||||
s.setPath(null);
|
||||
} else {
|
||||
s.setPath(Paths.get(str));
|
||||
}
|
||||
} catch (InvalidPathException e) {
|
||||
throw new ConfigurationException(e.getMessage(), e, "Invalid Path");
|
||||
}
|
||||
|
@ -281,56 +290,58 @@ public class ZigConfigEditor<T extends ZigExecConfigBase<T>> extends SettingsEdi
|
|||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public static class ColoredConfigurable implements ZigConfigurable<ColoredConfigurable> {
|
||||
@AllArgsConstructor
|
||||
public static class CheckboxConfigurable implements ZigConfigurable<CheckboxConfigurable> {
|
||||
private transient final String serializedName;
|
||||
public boolean colored = true;
|
||||
private transient final String label;
|
||||
public boolean value;
|
||||
|
||||
@Override
|
||||
public void readExternal(@NotNull Element element) {
|
||||
ElementUtil.readBoolean(element, serializedName).ifPresent(x -> colored = x);
|
||||
ElementUtil.readBoolean(element, serializedName).ifPresent(x -> value = x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeExternal(@NotNull Element element) {
|
||||
ElementUtil.writeBoolean(element, serializedName, colored);
|
||||
ElementUtil.writeBoolean(element, serializedName, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColoredConfigModule createEditor() {
|
||||
return new ColoredConfigModule(serializedName);
|
||||
public CheckboxConfigModule createEditor() {
|
||||
return new CheckboxConfigModule(serializedName, label);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public ColoredConfigurable clone() {
|
||||
return (ColoredConfigurable) super.clone();
|
||||
public CheckboxConfigurable clone() {
|
||||
return (CheckboxConfigurable) super.clone();
|
||||
}
|
||||
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public static class ColoredConfigModule implements ZigConfigModule<ColoredConfigurable> {
|
||||
public static class CheckboxConfigModule implements ZigConfigModule<CheckboxConfigurable> {
|
||||
private final String serializedName;
|
||||
private final String label;
|
||||
private final JBCheckBox checkBox = new JBCheckBox();
|
||||
|
||||
@Override
|
||||
public @Nullable ColoredConfigurable tryMatch(ZigConfigurable<?> cfg) {
|
||||
return cfg instanceof ColoredConfigurable cfg$ && cfg$.serializedName.equals(serializedName) ? cfg$ : null;
|
||||
public @Nullable ZigConfigEditor.CheckboxConfigurable tryMatch(ZigConfigurable<?> cfg) {
|
||||
return cfg instanceof ZigConfigEditor.CheckboxConfigurable cfg$ && cfg$.serializedName.equals(serializedName) ? cfg$ : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(ColoredConfigurable s) throws ConfigurationException {
|
||||
s.colored = checkBox.isSelected();
|
||||
public void apply(CheckboxConfigurable s) throws ConfigurationException {
|
||||
s.value = checkBox.isSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(ColoredConfigurable s) {
|
||||
checkBox.setSelected(s.colored);
|
||||
public void reset(CheckboxConfigurable s) {
|
||||
checkBox.setSelected(s.value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void construct(Panel p) {
|
||||
p.row("Colored terminal", (r) -> {
|
||||
p.row(label, (r) -> {
|
||||
r.cell(checkBox);
|
||||
return null;
|
||||
});
|
||||
|
@ -343,6 +354,10 @@ public class ZigConfigEditor<T extends ZigExecConfigBase<T>> extends SettingsEdi
|
|||
}
|
||||
}
|
||||
|
||||
public static CheckboxConfigurable coloredConfigurable(String serializedName) {
|
||||
return new CheckboxConfigurable(serializedName, "Colored terminal", true);
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public static class OptimizationConfigurable implements ZigConfigurable<OptimizationConfigurable> {
|
||||
private transient final String serializedName;
|
||||
|
|
|
@ -63,9 +63,9 @@ public abstract class ZigExecConfigBase<T extends ZigExecConfigBase<T>> extends
|
|||
getConfigurables().forEach(cfg -> cfg.writeExternal(element));
|
||||
}
|
||||
|
||||
public abstract String[] buildCommandLineArgs();
|
||||
public abstract String[] buildCommandLineArgs() throws ExecutionException;
|
||||
|
||||
public String[] buildDebugCommandLineArgs() {
|
||||
public String[] buildDebugCommandLineArgs() throws ExecutionException {
|
||||
return buildCommandLineArgs();
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@ public class ConfigProducerBuild extends ConfigProducerBase<ZigExecConfigBuild>
|
|||
@Override
|
||||
protected boolean setupConfigurationFromContext(@NotNull ZigExecConfigBuild configuration, PsiElement element, Path filePath, VirtualFile theFile) {
|
||||
if (ZigLineMarkerBuild.UTILITY_INSTANCE.elementMatches(element)) {
|
||||
configuration.setName("Build");
|
||||
configuration.setName("Build and Run");
|
||||
configuration.getBuildSteps().args = new String[]{"run"};
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -33,7 +33,7 @@ public class ConfigTypeBuild extends ConfigurationTypeBase {
|
|||
}
|
||||
|
||||
public ConfigTypeBuild() {
|
||||
super(IDENTIFIER, "ZigBuild", "Zig Build", Icons.ZIG);
|
||||
super(IDENTIFIER, "Zig build", "Execute \"zig build\" with custom steps", Icons.ZIG);
|
||||
addFactory(new ConfigFactoryBuild());
|
||||
}
|
||||
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
|
||||
package com.falsepattern.zigbrains.project.execution.build;
|
||||
|
||||
import com.falsepattern.zigbrains.common.ZBFeatures;
|
||||
import com.falsepattern.zigbrains.common.util.CollectionUtil;
|
||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigEditor;
|
||||
import com.falsepattern.zigbrains.project.execution.base.ZigExecConfigBase;
|
||||
import com.intellij.execution.ExecutionException;
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.configurations.ConfigurationFactory;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
|
@ -28,21 +30,44 @@ import lombok.val;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
public class ZigExecConfigBuild extends ZigExecConfigBase<ZigExecConfigBuild> {
|
||||
private ZigConfigEditor.ArgsConfigurable buildSteps = new ZigConfigEditor.ArgsConfigurable("buildSteps", "Build steps");
|
||||
private ZigConfigEditor.ArgsConfigurable extraArgs = new ZigConfigEditor.ArgsConfigurable("extraArgs", "Extra command line arguments");
|
||||
private ZigConfigEditor.ColoredConfigurable colored = new ZigConfigEditor.ColoredConfigurable("colored");
|
||||
private ZigConfigEditor.FilePathConfigurable exePath = new ZigConfigEditor.FilePathConfigurable("exePath", "Output executable created by the build (for debugging)");
|
||||
private ZigConfigEditor.CheckboxConfigurable colored = ZigConfigEditor.coloredConfigurable("colored");
|
||||
private ZigConfigEditor.FilePathConfigurable exePath = new ZigConfigEditor.FilePathConfigurable("exePath", "Output executable created by the build (debugging, autodetect if empty)");
|
||||
private ZigConfigEditor.ArgsConfigurable exeArgs = new ZigConfigEditor.ArgsConfigurable("exeArgs", "Command line arguments for executable (debugging)");
|
||||
public ZigExecConfigBuild(@NotNull Project project, @NotNull ConfigurationFactory factory) {
|
||||
super(project, factory, "Zig Build");
|
||||
}
|
||||
|
||||
private String[] buildWithSteps(String[] steps) throws ExecutionException {
|
||||
val base = new String[]{"build", "--color", colored.value ? "on" : "off"};
|
||||
return CollectionUtil.concat(base, steps, extraArgs.args).toArray(String[]::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] buildCommandLineArgs() {
|
||||
val base = new String[]{"build", "--color", colored.colored ? "on" : "off"};
|
||||
return CollectionUtil.concat(base, extraArgs.args);
|
||||
public String[] buildCommandLineArgs() throws ExecutionException {
|
||||
return buildWithSteps(buildSteps.args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] buildDebugCommandLineArgs() throws ExecutionException {
|
||||
var steps = buildSteps.args;
|
||||
val truncatedSteps = new ArrayList<String>();
|
||||
for (int i = 0; i < steps.length; i++) {
|
||||
if (steps[i].equals("run")) {
|
||||
continue;
|
||||
}
|
||||
if (steps[i].equals("test")) {
|
||||
throw new ExecutionException("Debugging \"zig build test\" is not supported yet.");
|
||||
}
|
||||
truncatedSteps.add(steps[i]);
|
||||
}
|
||||
return buildWithSteps(truncatedSteps.toArray(String[]::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -52,15 +77,22 @@ public class ZigExecConfigBuild extends ZigExecConfigBase<ZigExecConfigBuild> {
|
|||
|
||||
@Override
|
||||
public @NotNull List<ZigConfigEditor.ZigConfigurable<?>> getConfigurables() {
|
||||
return CollectionUtil.concat(super.getConfigurables(), extraArgs, colored, exePath);
|
||||
val baseCfg = CollectionUtil.concat(super.getConfigurables(), buildSteps, extraArgs, colored);
|
||||
if (ZBFeatures.debug()) {
|
||||
return CollectionUtil.concat(baseCfg, exePath, exeArgs);
|
||||
} else {
|
||||
return baseCfg;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ZigExecConfigBuild clone() {
|
||||
val clone = super.clone();
|
||||
clone.buildSteps = buildSteps.clone();
|
||||
clone.extraArgs = extraArgs.clone();
|
||||
clone.colored = colored.clone();
|
||||
clone.exePath = exePath.clone();
|
||||
clone.exeArgs = exeArgs.clone();
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ public class ConfigTypeRun extends ConfigurationTypeBase {
|
|||
}
|
||||
|
||||
public ConfigTypeRun() {
|
||||
super(IDENTIFIER, "ZigRun", "Zig Run", Icons.ZIG);
|
||||
super(IDENTIFIER, "Zig run", "Execute \"zig run\" on a specific file", Icons.ZIG);
|
||||
addFactory(new ConfigFactoryRun());
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ import java.util.List;
|
|||
@Getter
|
||||
public class ZigExecConfigRun extends ZigExecConfigBase<ZigExecConfigRun> {
|
||||
private ZigConfigEditor.FilePathConfigurable filePath = new ZigConfigEditor.FilePathConfigurable("filePath", "File Path");
|
||||
private ZigConfigEditor.ColoredConfigurable colored = new ZigConfigEditor.ColoredConfigurable("colored");
|
||||
private ZigConfigEditor.CheckboxConfigurable colored = ZigConfigEditor.coloredConfigurable("colored");
|
||||
private ZigConfigEditor.OptimizationConfigurable optimization = new ZigConfigEditor.OptimizationConfigurable("optimization");
|
||||
private ZigConfigEditor.ArgsConfigurable exeArgs = new ZigConfigEditor.ArgsConfigurable("exeArgs", "Arguments for the compile exe");
|
||||
public ZigExecConfigRun(@NotNull Project project, @NotNull ConfigurationFactory factory) {
|
||||
|
@ -42,15 +42,15 @@ public class ZigExecConfigRun extends ZigExecConfigBase<ZigExecConfigRun> {
|
|||
|
||||
@Override
|
||||
public String[] buildCommandLineArgs() {
|
||||
return CollectionUtil.concat(new String[]{"run", "--color", colored.colored ? "on" : "off", filePath.getPathOrThrow().toString(), "-O", optimization.level.name(), "--"}, exeArgs.args);
|
||||
return CollectionUtil.concat(new String[]{"run", "--color", colored.value ? "on" : "off", filePath.getPathOrThrow().toString(), "-O", optimization.level.name(), "--"}, exeArgs.args).toArray(String[]::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] buildDebugCommandLineArgs() {
|
||||
if (optimization.forced) {
|
||||
return new String[]{"build-exe", "--color", colored.colored ? "on" : "off", filePath.getPathOrThrow().toString(), "-O", optimization.level.name()};
|
||||
return new String[]{"build-exe", "--color", colored.value ? "on" : "off", filePath.getPathOrThrow().toString(), "-O", optimization.level.name()};
|
||||
} else {
|
||||
return new String[]{"build-exe", "--color", colored.colored ? "on" : "off", filePath.getPathOrThrow().toString()};
|
||||
return new String[]{"build-exe", "--color", colored.value ? "on" : "off", filePath.getPathOrThrow().toString()};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ public class ConfigTypeTest extends ConfigurationTypeBase {
|
|||
}
|
||||
|
||||
public ConfigTypeTest() {
|
||||
super(IDENTIFIER, "ZigTest", "Zig Test", Icons.ZIG);
|
||||
super(IDENTIFIER, "Zig test", "Execute \"zig test\" on a specific file", Icons.ZIG);
|
||||
addFactory(new ConfigFactoryTest());
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ import java.util.List;
|
|||
@Getter
|
||||
public class ZigExecConfigTest extends ZigExecConfigBase<ZigExecConfigTest> {
|
||||
private ZigConfigEditor.FilePathConfigurable filePath = new ZigConfigEditor.FilePathConfigurable("filePath", "File path");
|
||||
private ZigConfigEditor.ColoredConfigurable colored = new ZigConfigEditor.ColoredConfigurable("colored");
|
||||
private ZigConfigEditor.CheckboxConfigurable colored = ZigConfigEditor.coloredConfigurable("colored");
|
||||
private ZigConfigEditor.OptimizationConfigurable optimization = new ZigConfigEditor.OptimizationConfigurable("optimization");
|
||||
public ZigExecConfigTest(@NotNull Project project, @NotNull ConfigurationFactory factory) {
|
||||
super(project, factory, "Zig Test");
|
||||
|
@ -42,15 +42,15 @@ public class ZigExecConfigTest extends ZigExecConfigBase<ZigExecConfigTest> {
|
|||
|
||||
@Override
|
||||
public String[] buildCommandLineArgs() {
|
||||
return new String[]{"test", "--color", colored.colored ? "on" : "off", filePath.getPathOrThrow().toString(), "-O", optimization.level.name()};
|
||||
return new String[]{"test", "--color", colored.value ? "on" : "off", filePath.getPathOrThrow().toString(), "-O", optimization.level.name()};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] buildDebugCommandLineArgs() {
|
||||
if (optimization.forced) {
|
||||
return new String[]{"test", "--color", colored.colored ? "on" : "off", filePath.getPathOrThrow().toString(), "--test-no-exec", "-O", optimization.level.name()};
|
||||
return new String[]{"test", "--color", colored.value ? "on" : "off", filePath.getPathOrThrow().toString(), "--test-no-exec", "-O", optimization.level.name()};
|
||||
} else {
|
||||
return new String[]{"test", "--color", colored.colored ? "on" : "off", filePath.getPathOrThrow().toString(), "--test-no-exec"};
|
||||
return new String[]{"test", "--color", colored.value ? "on" : "off", filePath.getPathOrThrow().toString(), "--test-no-exec"};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
<runLineMarkerContributor language="Zig"
|
||||
implementationClass="com.falsepattern.zigbrains.project.execution.build.ZigLineMarkerBuild"/>
|
||||
|
||||
<configurationType implementation="com.falsepattern.zigbrains.project.execution.binary.ConfigTypeBinary"/>
|
||||
|
||||
<directoryProjectGenerator implementation="com.falsepattern.zigbrains.project.platform.ZigDirectoryProjectGenerator"/>
|
||||
<newProjectWizard.language implementation="com.falsepattern.zigbrains.project.ide.newproject.ZigNewProjectWizard"/>
|
||||
|
||||
|
|
|
@ -25,5 +25,8 @@
|
|||
<extensionPoint
|
||||
interface="com.falsepattern.zigbrains.debugbridge.DebuggerDriverProvider" dynamic="true"
|
||||
name="debuggerDriverProvider"/>
|
||||
<extensionPoint
|
||||
interface="com.falsepattern.zigbrains.common.ZBFeatures" dynamic="true"
|
||||
name="featureProvider"/>
|
||||
</extensionPoints>
|
||||
</idea-plugin>
|
||||
|
|
Loading…
Add table
Reference in a new issue