Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.usebruno.plugin.bruno;

import com.intellij.openapi.util.IconLoader;

import javax.swing.*;

public class BrunoIcons {

public static final Icon RUN_CONFIG = IconLoader.getIcon("/icons/runConfig.svg", BrunoIcons.class);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.usebruno.plugin.bruno.execution;

import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.*;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.process.ProcessHandlerFactory;
import com.intellij.execution.process.ProcessTerminatedListener;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.usebruno.plugin.bruno.settings.BrunoSettingsState;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class BrunoRunConfiguration extends RunConfigurationBase<BrunoRunConfigurationOptions> {
protected BrunoRunConfiguration(
@NotNull Project project,
@Nullable ConfigurationFactory factory,
@Nullable String name
) {
super(project, factory, name);
}

@NotNull
@Override
protected BrunoRunConfigurationOptions getOptions() {
return (BrunoRunConfigurationOptions) super.getOptions();
}

@NotNull
@Override
public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
return new BrunoRunConfigurationEditor();
}

@Override
public void checkSettingsBeforeRun() throws RuntimeConfigurationException {
File brunoCliExecutable = BrunoSettingsState.getBrunoCliExecutable();
if (null == brunoCliExecutable) {
throw new RuntimeConfigurationException("No Bruno CLI executable configured.");
}

File brunoCollectionRoot = new File(getOptions().getCollectionRoot());
if (!brunoCollectionRoot.isDirectory()) {
throw new RuntimeConfigurationException("Bruno collection root is not a directory.");
}

File brunoCollectionJson = brunoCollectionRoot.toPath().resolve("bruno.json").toFile();
if (!brunoCollectionJson.isFile() || !brunoCollectionJson.canRead()) {
throw new RuntimeConfigurationException("Bruno collection json must be a readable file.");
}
}

@Override
public RunProfileState getState(
@NotNull Executor executor,
@NotNull ExecutionEnvironment environment
) {
return new CommandLineState(environment) {
@NotNull
@Override
protected ProcessHandler startProcess() throws ExecutionException {
ArrayList<String> cliParams = new ArrayList<>(List.of(
Objects.requireNonNull(BrunoSettingsState.getBrunoCliExecutable()).getAbsolutePath(),
"run"
));
getOptions().addCliParameters(cliParams);
GeneralCommandLine commandLine = new GeneralCommandLine(cliParams)
.withWorkDirectory(getOptions().getCollectionRoot());
OSProcessHandler processHandler = ProcessHandlerFactory.getInstance()
.createColoredProcessHandler(commandLine);
ProcessTerminatedListener.attach(processHandler);
return processHandler;
}
};
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.usebruno.plugin.bruno.execution;

import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.util.ui.FormBuilder;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.io.File;
import java.nio.file.Path;
import java.util.Objects;

import static com.usebruno.plugin.bruno.execution.BrunoRunConfigurationOptions.ENV_NONE_OPTION;

final class BrunoRunConfigurationEditor extends SettingsEditor<BrunoRunConfiguration> {
private final JPanel mainPanel;
private final TextFieldWithBrowseButton collectionPathField;
private final ComboBox<String> environmentSelection;

public BrunoRunConfigurationEditor() {
collectionPathField = new TextFieldWithBrowseButton();
collectionPathField.addBrowseFolderListener(
"Select Collection Root Directory",
null,
null,
FileChooserDescriptorFactory.createSingleFolderDescriptor()
);

environmentSelection = new ComboBox<>(new DefaultComboBoxModel<String>(new String[]{ENV_NONE_OPTION}) {
{
collectionPathField.getTextField().getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent documentEvent) {
refreshOptions();
}

@Override
public void removeUpdate(DocumentEvent documentEvent) {
refreshOptions();
}

@Override
public void changedUpdate(DocumentEvent documentEvent) {
refreshOptions();
}
});
}

void refreshOptions() {
while (getSize() > 1) {
removeElementAt(1);
}
Path collectionRootPath = Path.of(collectionPathField.getText());
File environmentDir = collectionRootPath.resolve("environments").toFile();
if (environmentDir.isDirectory() && environmentDir.canRead()) {
for (File file : Objects.requireNonNull(environmentDir.listFiles())) {
if (file.isFile() && file.canRead() && file.getName().endsWith(".bru")) {
addElement(file.getName().replaceAll("\\.bru$", ""));
}
}
}
}
});

mainPanel = FormBuilder.createFormBuilder()
.addLabeledComponent("Collection root directory", collectionPathField)
.addLabeledComponent("Environment", environmentSelection)
.getPanel();
}

@Override
protected void resetEditorFrom(BrunoRunConfiguration brunoRunConfiguration) {
collectionPathField.setText(brunoRunConfiguration.getOptions().getCollectionRoot());
environmentSelection.setItem(brunoRunConfiguration.getOptions().getEnvironment());
}

@Override
protected void applyEditorTo(@NotNull BrunoRunConfiguration brunoRunConfiguration) {
brunoRunConfiguration.getOptions().setCollectionRoot(collectionPathField.getText());
brunoRunConfiguration.getOptions().setEnvironment(environmentSelection.getItem());
}

@NotNull
@Override
protected JComponent createEditor() {
return mainPanel;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.usebruno.plugin.bruno.execution;

import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.execution.configurations.RunConfiguration;
import com.intellij.openapi.components.BaseState;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;

final class BrunoRunConfigurationFactory extends ConfigurationFactory {
BrunoRunConfigurationFactory(ConfigurationType type) {
super(type);
}

@Override
public @NotNull String getId() {
return BrunoRunConfigurationType.ID;
}

@NotNull
@Override
public RunConfiguration createTemplateConfiguration(@NotNull Project project) {
return new BrunoRunConfiguration(project, this, "Bruno");
}

@Override
public Class<? extends BaseState> getOptionsClass() {
return BrunoRunConfigurationOptions.class;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.usebruno.plugin.bruno.execution;

import com.intellij.execution.configurations.RunConfigurationOptions;
import com.intellij.openapi.components.StoredProperty;

import java.util.List;

final public class BrunoRunConfigurationOptions extends RunConfigurationOptions {
final static String ENV_NONE_OPTION = "<None>";

private final StoredProperty<String> collectionRoot = string("").provideDelegate(this, "collectionRoot");
private final StoredProperty<String> environment = string("").provideDelegate(this, "environment");

public String getCollectionRoot() {
return collectionRoot.getValue(this);
}

public void setCollectionRoot(String collectionRoot) {
this.collectionRoot.setValue(this, collectionRoot);
}

public String getEnvironment() {
return environment.getValue(this);
}

public void setEnvironment(String environment) {
this.environment.setValue(this, environment);
}

public void addCliParameters(List<String> cliParameters) {
if (!getEnvironment().equals(ENV_NONE_OPTION)) {
cliParameters.add("--env");
cliParameters.add(getEnvironment());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.usebruno.plugin.bruno.execution;

import com.intellij.execution.Location;
import com.intellij.execution.actions.ConfigurationContext;
import com.intellij.execution.actions.LazyRunConfigurationProducer;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.ConfigurationTypeUtil;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;

public class BrunoRunConfigurationProducer extends LazyRunConfigurationProducer<BrunoRunConfiguration> {
@NotNull
@Override
public ConfigurationFactory getConfigurationFactory() {
return Objects.requireNonNull(ConfigurationTypeUtil.findConfigurationType(BrunoRunConfigurationType.ID)).getConfigurationFactories()[0];
}

@Override
protected boolean setupConfigurationFromContext(
@NotNull BrunoRunConfiguration configuration,
@NotNull ConfigurationContext context,
@NotNull Ref<PsiElement> sourceElement
) {
VirtualFile collectionFile = contextToCollectionFile(context);
if (collectionFile == null) {
return false;
}

configuration.setName("Run Collection " + collectionFile.getName());
configuration.getOptions().setCollectionRoot(collectionFile.getPath());
return true;
}

@Override
public boolean isConfigurationFromContext(@NotNull BrunoRunConfiguration configuration, @NotNull ConfigurationContext context) {
VirtualFile collectionFile = contextToCollectionFile(context);
if (collectionFile == null) {
return false;
}

return configuration.getOptions().getCollectionRoot().equals(collectionFile.getPath());
}

@Nullable
private VirtualFile contextToCollectionFile(@NotNull ConfigurationContext context) {
//noinspection rawtypes
Location location = context.getLocation();
if (location == null) {
return null;
}

PsiFile psiFile = location.getPsiElement().getContainingFile();
if (psiFile == null) {
return null;
}


VirtualFile virtualFile = psiFile.getVirtualFile();
String fileName = virtualFile.getName();
if (!fileName.equals("bruno.json") && !fileName.equals("collection.bru")) {
return null;
}

return virtualFile.getParent();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.usebruno.plugin.bruno.execution;

import com.intellij.execution.configurations.ConfigurationTypeBase;
import com.intellij.openapi.util.NotNullLazyValue;
import com.usebruno.plugin.bruno.BrunoIcons;

final public class BrunoRunConfigurationType extends ConfigurationTypeBase {
static final String ID = "BrunoRunConfiguration";

BrunoRunConfigurationType() {
super(
ID,
"Bruno",
"Bruno runner to execute bruno collections and requests",
NotNullLazyValue.createValue(() -> BrunoIcons.RUN_CONFIG)
);
addFactory(new BrunoRunConfigurationFactory(this));
}

}
Loading