Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
allegroai committed Jun 11, 2019
1 parent d66f5e1 commit 25a2137
Show file tree
Hide file tree
Showing 9 changed files with 564 additions and 0 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# TRAINS - PyCharm Plugin

PyCharm plugin allow syncing of local repo information to remote debugger machine.

## Usage

Install latest plugin from [Releases](https://github.com/allegroai/trains-pycharm-plugin/releases)

*Optional*, configure TRAINS host and credentials:

0. With PyCharm
1. Open Settings -> Tools -> TRAINS
2. Add your TRAINS host (for example: http://localhost:8008)
3. Add your TRAINS user credentials key/secret

## Known Problems

- None: so far...
- Let us known in the [issues](https://github.com/allegroai/trains-pycharm-plugin/issues) section
13 changes: 13 additions & 0 deletions Trains.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PLUGIN_MODULE" version="4">
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/resources/META-INF/plugin.xml" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
</content>
<orderEntry type="jdk" jdkName="PhpStorm PS-162.1889.1" jdkType="IDEA JDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
13 changes: 13 additions & 0 deletions TrainsPlugin.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PLUGIN_MODULE" version="4">
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/resources/META-INF/plugin.xml" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
43 changes: 43 additions & 0 deletions resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<idea-plugin version="2">
<id>com.trains.plugin</id>
<name>TRAINS</name>
<version>0.1.4</version>
<vendor email="git@allegro.ai" url="https://trainsai.io">trainsai.io</vendor>

<description><![CDATA[
The plugin will automatically sync local configuration with remote debugger.
<ul>
Configure TRAINS credentials:<br/>
Open Settings -> Tools -> TRAINS<br/>
Add your TRAINS user credentials: key & secret<br/>
</ul>
]]></description>

<change-notes><![CDATA[
<ul>
<li> 0.1.1 - Initial beta release</li>
<li> 0.1.2 - Windows support</li>
<li> 0.1.3 - Windows git fix</li>
<li> 0.1.4 - Added: TRAINS host configuration</li>
</ul>
(c) allegro.ai
]]>
</change-notes>

<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
<idea-version since-build="141.0"/>
<depends>com.intellij.modules.lang</depends>
<depends>com.intellij.modules.python</depends>
<depends>com.intellij.modules.platform</depends>
<depends>Git4Idea</depends>

<extensions defaultExtensionNs="Pythonid">
<runConfigurationExtension implementation="TrainsRunExtension"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<projectConfigurable groupId="tools"
displayName="TRAINS"
instance="HookConfigurable" />
</extensions>

</idea-plugin>
32 changes: 32 additions & 0 deletions src/Barrier.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Helps to synchronize between two or more threads that one waits for another.
*
* Usage :
*
* [[waitForDone()]] on the thread that's waiting for the barrier
* [[done()]] on the thread that other threads are waiting for (when done)
*/
class Barrier {

private final Object monitor = new Object();
private volatile boolean open = false;

Barrier(boolean open) {
this.open = open;
}

void waitForDone() throws InterruptedException {
synchronized (monitor) {
while (!open) {
monitor.wait();
}
}
}

void done() {
synchronized (monitor) {
open = true;
monitor.notifyAll();
}
}
}
197 changes: 197 additions & 0 deletions src/HookConfigurable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.awt.*;

public class HookConfigurable implements Configurable {

private static final String PATH_HOST = "trains.host";
private static final String PATH_KEY = "trains.key";
private static final String PATH_SECRET = "trains.secret";

private JTextField userHost;
private JTextField userKey;
private JTextField userSecret;
private static String storedHost = null;
private static String storedKey = null;
private static String storedSecret = null;

private final Project project;

public HookConfigurable(Project project) {
this.project = project;
if (storedHost == null || storedSecret == null || storedKey==null) {
loadFromProperties(project);
}
}

private static void loadFromProperties(Project project){
PropertiesComponent properties = PropertiesComponent.getInstance(project);
storedKey = properties.getValue(PATH_KEY);
storedSecret = properties.getValue(PATH_SECRET);
storedHost = properties.getValue(PATH_HOST);
}

@Nls
@Override
public String getDisplayName() {
return "TRAINS";
}

@Nullable
@Override
public String getHelpTopic() {
return null;
}

@Nullable
@Override
public JComponent createComponent() {
userHost = new JTextField();
userKey = new JTextField();
userSecret = new JTextField();

JPanel container = new JPanel(new GridLayoutManager(4, 2,
new Insets(0, 0, 0, 0), 12, 12));

GridConstraints pathLabelConstraint0 = new GridConstraints();
pathLabelConstraint0.setRow(0);
pathLabelConstraint0.setColumn(0);
pathLabelConstraint0.setFill(GridConstraints.FILL_HORIZONTAL);
pathLabelConstraint0.setVSizePolicy(GridConstraints.SIZEPOLICY_CAN_SHRINK);
container.add(new JLabel("TRAINS server: "), pathLabelConstraint0);

GridConstraints pathFieldConstraint0 = new GridConstraints();
pathFieldConstraint0.setHSizePolicy(GridConstraints.SIZEPOLICY_WANT_GROW);
pathFieldConstraint0.setFill(GridConstraints.FILL_HORIZONTAL);
pathFieldConstraint0.setAnchor(GridConstraints.ANCHOR_WEST);
pathFieldConstraint0.setRow(0);
pathFieldConstraint0.setColumn(1);
pathFieldConstraint0.setVSizePolicy(GridConstraints.SIZEPOLICY_CAN_SHRINK);
container.add(userHost, pathFieldConstraint0);


GridConstraints pathLabelConstraint = new GridConstraints();
pathLabelConstraint.setRow(1);
pathLabelConstraint.setColumn(0);
pathLabelConstraint.setFill(GridConstraints.FILL_HORIZONTAL);
pathLabelConstraint.setVSizePolicy(GridConstraints.SIZEPOLICY_CAN_SHRINK);
container.add(new JLabel("User credentials: Key"), pathLabelConstraint);

GridConstraints pathFieldConstraint = new GridConstraints();
pathFieldConstraint.setHSizePolicy(GridConstraints.SIZEPOLICY_WANT_GROW);
pathFieldConstraint.setFill(GridConstraints.FILL_HORIZONTAL);
pathFieldConstraint.setAnchor(GridConstraints.ANCHOR_WEST);
pathFieldConstraint.setRow(1);
pathFieldConstraint.setColumn(1);
pathFieldConstraint.setVSizePolicy(GridConstraints.SIZEPOLICY_CAN_SHRINK);
container.add(userKey, pathFieldConstraint);


GridConstraints pathLabelConstraint2 = new GridConstraints();
pathLabelConstraint2.setRow(2);
pathLabelConstraint2.setColumn(0);
pathLabelConstraint2.setFill(GridConstraints.FILL_HORIZONTAL);
pathLabelConstraint2.setVSizePolicy(GridConstraints.SIZEPOLICY_CAN_SHRINK);
container.add(new JLabel("User credentials: Secret "), pathLabelConstraint2);

GridConstraints pathFieldConstraint2 = new GridConstraints();
pathFieldConstraint2.setHSizePolicy(GridConstraints.SIZEPOLICY_WANT_GROW);
pathFieldConstraint2.setFill(GridConstraints.FILL_HORIZONTAL);
pathFieldConstraint2.setAnchor(GridConstraints.ANCHOR_WEST);
pathFieldConstraint2.setRow(2);
pathFieldConstraint2.setColumn(1);
pathFieldConstraint2.setVSizePolicy(GridConstraints.SIZEPOLICY_CAN_SHRINK);
container.add(userSecret, pathFieldConstraint2);


JPanel spacer = new JPanel();
GridConstraints spacerConstraints = new GridConstraints();
spacerConstraints.setRow(3);
spacerConstraints.setFill(GridConstraints.FILL_BOTH);
container.add(spacer, spacerConstraints);

return container;
}

@Override
public boolean isModified() {
if (storedKey == null && userKey != null) {
return true;
}

if (storedSecret == null && userSecret != null) {
return true;
}

if (storedHost == null && userHost != null) {
return true;
}

return !storedKey.equals(userKey.getText()) || !storedSecret.equals(userSecret.getText())
|| !storedHost.equals(userHost.getText());
}

@Override
public void apply() throws ConfigurationException {
storedKey = userKey.getText().trim();
storedSecret = userSecret.getText().trim();
storedHost = userHost.getText().trim();

PropertiesComponent properties = PropertiesComponent.getInstance(project);
properties.setValue(PATH_HOST, storedHost);
properties.setValue(PATH_KEY, storedKey);
properties.setValue(PATH_SECRET, storedSecret);
}

@Override
public void reset() {
if (userHost != null) {
userHost.setText(storedHost);
}
if (userKey != null) {
userKey.setText(storedKey);
}
if (userSecret != null) {
userSecret.setText(storedSecret);
}
}

@Override
public void disposeUIResources() {
userKey = null;
userSecret = null;
userHost = null;
}

static String getStoredKey(Project project) {
if (storedKey==null && project!=null){
loadFromProperties(project);
}
return storedKey;
}

static String getStoredSecret(Project project) {
if (storedSecret==null && project!=null){
loadFromProperties(project);
}
return storedSecret;
}

static String getStoredHost(Project project) {
if (storedHost==null && project!=null){
loadFromProperties(project);
}
return storedHost;
}
}
9 changes: 9 additions & 0 deletions src/OsUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class OsUtil {

private OsUtil() {

}

final static boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
final static boolean isMac = System.getProperty("os.name").toLowerCase().startsWith("mac os");
}
30 changes: 30 additions & 0 deletions src/ProcessResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class ProcessResult {

private InterruptedException exception = null;
private int exitCode = -1;
private boolean canceled = false;

boolean isCanceled() {
return canceled;
}

void setCanceled() {
canceled = true;
}

int getExitCode() {
return exitCode;
}

void setExitCode(int exitCode) {
this.exitCode = exitCode;
}

InterruptedException getException() {
return exception;
}

void setException(InterruptedException exception) {
this.exception = exception;
}
}
Loading

0 comments on commit 25a2137

Please # to comment.