From 27d07dfe50550255ec18ab8783c9217dd56bff4c Mon Sep 17 00:00:00 2001 From: Maris Date: Thu, 16 Nov 2017 14:45:00 +0200 Subject: [PATCH 1/3] Added profile support for modules in Hydra Settings Panel --- .../META-INF/scala-plugin-common.xml | 4 +- .../compiler/HydraCompilerConfigurable.scala | 20 +- .../compiler/HydraCompilerConfiguration.scala | 123 ++++++ .../HydraCompilerConfigurationPanel.form | 84 ++-- .../HydraCompilerConfigurationPanel.java | 289 +++++++------ .../compiler/HydraCompilerProfilePanel.java | 378 ++++++++++++++++++ .../compiler/HydraCompilerSettings.scala | 75 ++-- .../HydraCompilerSettingsManager.scala | 4 +- .../compiler/HydraCompilerSettingsPanel.form | 53 +++ .../compiler/HydraCompilerSettingsPanel.java | 68 ++++ .../HydraCompilerSettingsProfile.java | 55 +++ ...ScalaHydraCompilerConfigurationPanel.scala | 17 +- .../ScalaHydraCompilerSettingsPanel.scala | 43 ++ .../HydraArtifactsNotificationProvider.scala | 4 +- 14 files changed, 929 insertions(+), 288 deletions(-) create mode 100644 scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfiguration.scala create mode 100644 scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerProfilePanel.java create mode 100644 scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsPanel.form create mode 100644 scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsPanel.java create mode 100644 scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsProfile.java create mode 100644 scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/ScalaHydraCompilerSettingsPanel.scala diff --git a/scala/scala-impl/resources/META-INF/scala-plugin-common.xml b/scala/scala-impl/resources/META-INF/scala-plugin-common.xml index 22faddbfcd4..67abdf66947 100644 --- a/scala/scala-impl/resources/META-INF/scala-plugin-common.xml +++ b/scala/scala-impl/resources/META-INF/scala-plugin-common.xml @@ -425,8 +425,8 @@ - + diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurable.scala b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurable.scala index beabc95af34..07c55d6cad9 100644 --- a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurable.scala +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurable.scala @@ -7,46 +7,48 @@ import com.intellij.openapi.project.Project import com.intellij.ui.EditorNotifications import org.jetbrains.plugins.hydra.settings.HydraApplicationSettings import org.jetbrains.plugins.scala.project.AbstractConfigurable +import scala.collection.JavaConverters._ /** * @author Maris Alexandru */ class HydraCompilerConfigurable (project: Project) extends AbstractConfigurable("Hydra Compiler"){ - private val settings = HydraCompilerSettings.getInstance(project) + private val settings = HydraCompilerConfiguration.getInstance(project) private val hydraGlobalSettings = HydraApplicationSettings.getInstance() private val form = new ScalaHydraCompilerConfigurationPanel(project, settings, hydraGlobalSettings) + private val profiles = form.getHydraProfilesPanel + override def createComponent(): JPanel = form.getContentPanel override def isModified: Boolean = form.isHydraEnabled != settings.isHydraEnabled || form.getUsername != HydraCredentialsManager.getLogin || form.getPassword != HydraCredentialsManager.getPlainPassword || form.getHydraVersion != settings.hydraVersion || - form.selectedNoOfCores != settings.noOfCores || - form.selectedSourcePartitioner != settings.sourcePartitioner || form.getHydraRepository != hydraGlobalSettings.getHydraRepositoryUrl || - form.getHydraRepositoryRealm != hydraGlobalSettings.hydraRepositoryRealm + form.getHydraRepositoryRealm != hydraGlobalSettings.hydraRepositoryRealm || + profiles.getDefaultProfile.getSettings.getState != settings.defaultProfile.getSettings.getState || + !profiles.getModuleProfiles.asScala.corresponds(settings.customProfiles)(_.getSettings.getState == _.getSettings.getState) override def reset() { form.setUsername(HydraCredentialsManager.getLogin) form.setPassword(HydraCredentialsManager.getPlainPassword) form.setIsHydraEnabled(settings.isHydraEnabled) - form.setSelectedNoOfCores(settings.noOfCores) form.setHydraVersion(settings.hydraVersion) - form.setSelectedSourcePartitioner(settings.sourcePartitioner) form.setHydraRepository(hydraGlobalSettings.getHydraRepositoryUrl) form.setHydraRepositoryRealm(hydraGlobalSettings.hydraRepositoryRealm) + profiles.initProfiles(settings.defaultProfile, settings.customProfiles.asJava) } override def apply() { - BuildManager.getInstance().clearState(project) + settings.defaultProfile = profiles.getDefaultProfile + settings.customProfiles = profiles.getModuleProfiles.asScala settings.hydraVersion = form.getHydraVersion settings.isHydraEnabled = form.isHydraEnabled - settings.noOfCores = form.selectedNoOfCores - settings.sourcePartitioner = form.selectedSourcePartitioner hydraGlobalSettings.setHydraRepositopryUrl(form.getHydraRepository) hydraGlobalSettings.hydraRepositoryRealm = form.getHydraRepositoryRealm HydraCredentialsManager.setCredentials(form.getUsername, form.getPassword) EditorNotifications.updateAll() + BuildManager.getInstance().clearState(project) } } \ No newline at end of file diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfiguration.scala b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfiguration.scala new file mode 100644 index 00000000000..2ffcb56ab6e --- /dev/null +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfiguration.scala @@ -0,0 +1,123 @@ +package org.jetbrains.plugins.hydra.compiler + +import java.nio.file.Paths + +import com.intellij.openapi.components.PersistentStateComponent +import com.intellij.openapi.components._ +import com.intellij.openapi.project.Project +import com.intellij.openapi.module.Module +import com.intellij.util.xmlb.{SkipDefaultValuesSerializationFilters, XmlSerializer} +import org.jdom.Element + +import scala.collection.JavaConverters._ +import scala.beans.BeanProperty + +/** + * @author Maris Alexandru + */ +@State( + name = "HydraSettings", + storages = Array(new Storage("hydra.xml")) +) +class HydraCompilerConfiguration(project: Project) extends PersistentStateComponent[Element] { + + private val ProjectRoot: String = getProjectRootPath + + var isHydraSettingsEnabled: Boolean = false + + var isHydraEnabled: Boolean = false + + var hydraVersion: String = "" + + var defaultProfile: HydraCompilerSettingsProfile = new HydraCompilerSettingsProfile("Default") + + var customProfiles: Seq[HydraCompilerSettingsProfile] = Seq.empty + + var hydraLogLocation: String = Paths.get(getDefaultHydraStorePath, "hydra.log").toString + + var hydraStorePath: String = getDefaultHydraStorePath + + def getSettingsForModule(module: Module): HydraCompilerSettings = { + val profile = customProfiles.find(_.getModuleNames.contains(module.getName)).getOrElse(defaultProfile) + profile.getSettings + } + + override def getState: Element = { + val configurationElement = XmlSerializer.serialize(defaultProfile.getSettings.getState) + val projectSettingsElement = XmlSerializer.serialize(getSettingsState) + configurationElement.addContent(projectSettingsElement) + + customProfiles.foreach { profile => + val profileElement = XmlSerializer.serialize(profile.getSettings.getState) + profileElement.setName("profile") + profileElement.setAttribute("name", profile.getName) + profileElement.setAttribute("modules", profile.getModuleNames.asScala.mkString(",")) + + configurationElement.addContent(profileElement) + } + + configurationElement + } + + override def loadState(configurationElement: Element): Unit = { + val state = XmlSerializer.deserialize(configurationElement, classOf[HydraCompilerConfigurationState]) + setFromState(state) + + defaultProfile.setSettings(new HydraCompilerSettings(XmlSerializer.deserialize(configurationElement, classOf[HydraCompilerSettingsState]))) + + customProfiles = configurationElement.getChildren("profile").asScala.map { profileElement => + val profile = new HydraCompilerSettingsProfile(profileElement.getAttributeValue("name")) + + val settings = XmlSerializer.deserialize(profileElement, classOf[HydraCompilerSettingsState]) + profile.setSettings(new HydraCompilerSettings(settings)) + + val moduleNames = profileElement.getAttributeValue("modules").split(",").filter(!_.isEmpty) + moduleNames.foreach(profile.addModuleName) + + profile + } + } + + private def getSettingsState: HydraCompilerConfigurationState = { + val state = new HydraCompilerConfigurationState + state.setIsHydraEnabled(isHydraEnabled) + state.setIsHydraSettingsEnabled(isHydraSettingsEnabled) + state.setHydraVersion(hydraVersion) + state.setHydraStorePath(hydraStorePath) + state.setProjectRoot(ProjectRoot) + + state + } + + private def setFromState(state: HydraCompilerConfigurationState): Unit = { + isHydraEnabled = state.getIsHydraEnabled + isHydraSettingsEnabled = state.getIsHydraSettingsEnabled + hydraVersion = state.getHydraVersion + hydraStorePath = state.getHydraStorePath + } + + def getProjectRootPath: String = project.getBaseDir.getPresentableUrl + + def getDefaultHydraStorePath: String = Paths.get(ProjectRoot, ".hydra", "idea").toString +} + +object HydraCompilerConfiguration { + def getInstance(project: Project): HydraCompilerConfiguration = ServiceManager.getService(project, classOf[HydraCompilerConfiguration]) +} + +class HydraCompilerConfigurationState { + @BeanProperty + var isHydraEnabled: Boolean = false + + @BeanProperty + var isHydraSettingsEnabled: Boolean = false + + @BeanProperty + var hydraVersion: String = "" + + @BeanProperty + var hydraStorePath: String = "" + + @BeanProperty + var projectRoot: String = "" +} diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurationPanel.form b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurationPanel.form index a85fdb404af..2a59d33d014 100644 --- a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurationPanel.form +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurationPanel.form @@ -8,7 +8,7 @@ - + @@ -16,22 +16,9 @@ - - - - - - - - - - - - - - + @@ -39,7 +26,7 @@ - + @@ -49,7 +36,7 @@ - + @@ -57,7 +44,7 @@ - + @@ -67,7 +54,7 @@ - + @@ -77,25 +64,15 @@ - + - - - - - - - - - - - + @@ -105,7 +82,7 @@ - + @@ -115,39 +92,21 @@ - + - - - - - - - - - - - - - - - - - - - + - + @@ -155,7 +114,7 @@ - + @@ -163,7 +122,7 @@ - + @@ -172,7 +131,7 @@ - + @@ -180,7 +139,7 @@ - + @@ -188,17 +147,20 @@ - + - + - + - + + + + diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurationPanel.java b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurationPanel.java index 8b6d12ccd3c..147c82fff0f 100644 --- a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurationPanel.java +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfigurationPanel.java @@ -15,161 +15,150 @@ * @author Maris Alexandru */ public class HydraCompilerConfigurationPanel { - protected JPanel contentPanel; - protected JTextField userTextField; - protected JPasswordField passwordTextField; - protected JCheckBox enableHydraCheckBox; - protected JButton downloadButton; - protected SComboBox noOfCoresComboBox; - protected SComboBox sourcePartitionerComboBox; - protected JTextField hydraRepository; - protected JTextField realmTextField; - protected JTextField versionTextField; - protected JButton checkConnectionButton; - - public HydraCompilerConfigurationPanel() { - - } - - public JPanel getContentPanel() { - return contentPanel; - } - - public String getUsername() { - return userTextField.getText(); - } - - public void setUsername(String text) { - userTextField.setText(text); - } - - public String getPassword() { - return new String(passwordTextField.getPassword()); - } - - public void setPassword(String password) { - passwordTextField.setText(password); - } - - public void setIsHydraEnabled(boolean enable) { - enableHydraCheckBox.setSelected(enable); + protected HydraCompilerProfilePanel hydraProfilesPanel; + protected JPanel contentPanel; + protected JTextField userTextField; + protected JPasswordField passwordTextField; + protected JCheckBox enableHydraCheckBox; + protected JButton downloadButton; + protected SComboBox noOfCoresComboBox; + protected SComboBox sourcePartitionerComboBox; + protected JTextField hydraRepository; + protected JTextField realmTextField; + protected JTextField versionTextField; + protected JButton checkConnectionButton; + protected JPanel profilesPanel; + + public HydraCompilerConfigurationPanel() { + + } + + public JPanel getContentPanel() { + return contentPanel; + } + + public String getUsername() { + return userTextField.getText(); + } + + public void setUsername(String text) { + userTextField.setText(text); + } + + public String getPassword() { + return new String(passwordTextField.getPassword()); + } + + public void setPassword(String password) { + passwordTextField.setText(password); + } + + public void setIsHydraEnabled(boolean enable) { + enableHydraCheckBox.setSelected(enable); + } + + public boolean isHydraEnabled() { + return enableHydraCheckBox.isSelected(); + } + + public Color getDefaultValueColor() { + return findColorByKey("TextField.inactiveForeground", "nimbusDisabledText"); + } + + public Color getChangedValueColor() { + return findColorByKey("TextField.foreground"); + } + + @NotNull + private static Color findColorByKey(String... colorKeys) { + Color c = null; + for (String key : colorKeys) { + c = UIManager.getColor(key); + if (c != null) { + break; + } } - public boolean isHydraEnabled() { - return enableHydraCheckBox.isSelected(); - } - - public Color getDefaultValueColor() { - return findColorByKey("TextField.inactiveForeground", "nimbusDisabledText"); - } + assert c != null : "Can't find color for keys " + Arrays.toString(colorKeys); + return c; + } - public Color getChangedValueColor() { - return findColorByKey("TextField.foreground"); - } + private void createUIComponents() { + // TODO: place custom component creation code here + } - @NotNull - private static Color findColorByKey(String... colorKeys) { - Color c = null; - for (String key : colorKeys) { - c = UIManager.getColor(key); - if (c != null) { - break; - } - } - - assert c != null : "Can't find color for keys " + Arrays.toString(colorKeys); - return c; - } - - private void createUIComponents() { - // TODO: place custom component creation code here - } - - { + { // GUI initializer generated by IntelliJ IDEA GUI Designer // >>> IMPORTANT!! <<< // DO NOT EDIT OR ADD ANY CODE HERE! - $$$setupUI$$$(); - } - - /** - * Method generated by IntelliJ IDEA GUI Designer - * >>> IMPORTANT!! <<< - * DO NOT edit this method OR call it in your code! - * - * @noinspection ALL - */ - private void $$$setupUI$$$() { - contentPanel = new JPanel(); - contentPanel.setLayout(new GridLayoutManager(3, 1, new Insets(0, 0, 0, 0), -1, -1)); - final JPanel panel1 = new JPanel(); - panel1.setLayout(new GridLayoutManager(11, 9, new Insets(0, 0, 0, 0), -1, -1)); - contentPanel.add(panel1, new GridConstraints(0, 0, 3, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - final JLabel label1 = new JLabel(); - label1.setText("Number of cores"); - panel1.add(label1, new GridConstraints(8, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 1, false)); - final Spacer spacer1 = new Spacer(); - panel1.add(spacer1, new GridConstraints(10, 0, 1, 6, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); - final TitledSeparator titledSeparator1 = new TitledSeparator(); - titledSeparator1.setText("Options"); - panel1.add(titledSeparator1, new GridConstraints(7, 0, 1, 9, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - final JLabel label2 = new JLabel(); - label2.setText("Username"); - panel1.add(label2, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 16), null, 1, false)); - realmTextField = new JTextField(); - panel1.add(realmTextField, new GridConstraints(3, 8, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); - final JLabel label3 = new JLabel(); - label3.setText("Repository Realm"); - panel1.add(label3, new GridConstraints(3, 7, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(78, 16), null, 0, false)); - final JLabel label4 = new JLabel(); - label4.setText("Hydra version"); - panel1.add(label4, new GridConstraints(6, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 16), null, 1, false)); - versionTextField = new JTextField(); - panel1.add(versionTextField, new GridConstraints(6, 2, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(120, -1), null, 0, false)); - final JLabel label5 = new JLabel(); - label5.setText("Source partitioner"); - panel1.add(label5, new GridConstraints(9, 0, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 16), null, 1, false)); - final JLabel label6 = new JLabel(); - label6.setText("Password"); - panel1.add(label6, new GridConstraints(3, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 16), null, 1, false)); - final JLabel label7 = new JLabel(); - label7.setText("Repository URL"); - panel1.add(label7, new GridConstraints(2, 7, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(78, 16), null, 0, false)); - hydraRepository = new JTextField(); - panel1.add(hydraRepository, new GridConstraints(2, 8, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); - noOfCoresComboBox = new SComboBox(); - final DefaultComboBoxModel defaultComboBoxModel1 = new DefaultComboBoxModel(); - noOfCoresComboBox.setModel(defaultComboBoxModel1); - panel1.add(noOfCoresComboBox, new GridConstraints(8, 3, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(94, 26), null, 0, false)); - sourcePartitionerComboBox = new SComboBox(); - panel1.add(sourcePartitionerComboBox, new GridConstraints(9, 3, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(94, 26), null, 0, false)); - final JSeparator separator1 = new JSeparator(); - panel1.add(separator1, new GridConstraints(5, 0, 1, 9, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - final TitledSeparator titledSeparator2 = new TitledSeparator(); - titledSeparator2.setText("Repository Configuration"); - panel1.add(titledSeparator2, new GridConstraints(1, 0, 1, 9, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); - enableHydraCheckBox = new JCheckBox(); - enableHydraCheckBox.setText("Enable Hydra"); - panel1.add(enableHydraCheckBox, new GridConstraints(0, 0, 1, 6, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - downloadButton = new JButton(); - downloadButton.setEnabled(true); - downloadButton.setText("Download"); - panel1.add(downloadButton, new GridConstraints(6, 5, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - userTextField = new JTextField(); - panel1.add(userTextField, new GridConstraints(2, 1, 1, 4, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); - passwordTextField = new JPasswordField(); - panel1.add(passwordTextField, new GridConstraints(3, 1, 1, 4, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); - checkConnectionButton = new JButton(); - checkConnectionButton.setText("Check connection"); - panel1.add(checkConnectionButton, new GridConstraints(4, 1, 1, 3, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); - final Spacer spacer2 = new Spacer(); - panel1.add(spacer2, new GridConstraints(10, 8, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); - } - - /** - * @noinspection ALL - */ - public JComponent $$$getRootComponent$$$() { - return contentPanel; - } + $$$setupUI$$$(); + } + + /** + * Method generated by IntelliJ IDEA GUI Designer + * >>> IMPORTANT!! <<< + * DO NOT edit this method OR call it in your code! + * + * @noinspection ALL + */ + private void $$$setupUI$$$() { + contentPanel = new JPanel(); + contentPanel.setLayout(new GridLayoutManager(3, 1, new Insets(0, 0, 0, 0), -1, -1)); + final JPanel panel1 = new JPanel(); + panel1.setLayout(new GridLayoutManager(9, 10, new Insets(0, 0, 0, 0), -1, -1)); + contentPanel.add(panel1, new GridConstraints(0, 0, 3, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); + final TitledSeparator titledSeparator1 = new TitledSeparator(); + titledSeparator1.setText("Options"); + panel1.add(titledSeparator1, new GridConstraints(7, 0, 1, 10, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label1 = new JLabel(); + label1.setText("Username"); + panel1.add(label1, new GridConstraints(2, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 16), null, 1, false)); + realmTextField = new JTextField(); + panel1.add(realmTextField, new GridConstraints(3, 9, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + final JLabel label2 = new JLabel(); + label2.setText("Repository Realm"); + panel1.add(label2, new GridConstraints(3, 8, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(78, 16), null, 0, false)); + final JLabel label3 = new JLabel(); + label3.setText("Hydra version"); + panel1.add(label3, new GridConstraints(6, 0, 1, 3, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 16), null, 1, false)); + versionTextField = new JTextField(); + panel1.add(versionTextField, new GridConstraints(6, 3, 1, 3, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(120, -1), null, 0, false)); + final JLabel label4 = new JLabel(); + label4.setText("Password"); + panel1.add(label4, new GridConstraints(3, 0, 1, 2, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(-1, 16), null, 1, false)); + final JLabel label5 = new JLabel(); + label5.setText("Repository URL"); + panel1.add(label5, new GridConstraints(2, 8, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(78, 16), null, 0, false)); + hydraRepository = new JTextField(); + panel1.add(hydraRepository, new GridConstraints(2, 9, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + final JSeparator separator1 = new JSeparator(); + panel1.add(separator1, new GridConstraints(5, 0, 1, 10, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final TitledSeparator titledSeparator2 = new TitledSeparator(); + titledSeparator2.setText("Repository Configuration"); + panel1.add(titledSeparator2, new GridConstraints(1, 0, 1, 10, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + enableHydraCheckBox = new JCheckBox(); + enableHydraCheckBox.setText("Enable Hydra"); + panel1.add(enableHydraCheckBox, new GridConstraints(0, 0, 1, 7, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + downloadButton = new JButton(); + downloadButton.setEnabled(true); + downloadButton.setText("Download"); + panel1.add(downloadButton, new GridConstraints(6, 6, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + userTextField = new JTextField(); + panel1.add(userTextField, new GridConstraints(2, 2, 1, 4, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + passwordTextField = new JPasswordField(); + panel1.add(passwordTextField, new GridConstraints(3, 2, 1, 4, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false)); + checkConnectionButton = new JButton(); + checkConnectionButton.setText("Check connection"); + panel1.add(checkConnectionButton, new GridConstraints(4, 2, 1, 3, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + profilesPanel = new JPanel(); + profilesPanel.setLayout(new BorderLayout(0, 0)); + panel1.add(profilesPanel, new GridConstraints(8, 0, 1, 10, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false)); + } + + /** + * @noinspection ALL + */ + public JComponent $$$getRootComponent$$$() { + return contentPanel; + } } diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerProfilePanel.java b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerProfilePanel.java new file mode 100644 index 00000000000..9c7ab76e4f0 --- /dev/null +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerProfilePanel.java @@ -0,0 +1,378 @@ +package org.jetbrains.plugins.hydra.compiler; + +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.ShortcutSet; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.InputValidatorEx; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.ui.Splitter; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.*; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.components.JBList; +import com.intellij.ui.treeStructure.Tree; +import com.intellij.util.ui.EditableTreeModel; +import com.intellij.util.ui.tree.TreeUtil; + +import javax.swing.*; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.util.*; +import java.util.List; + +/** + * @author Maris Alexandru + */ +@SuppressWarnings({"unchecked", "UseOfObsoleteCollectionType"}) +public class HydraCompilerProfilePanel extends JPanel { + private final HydraCompilerSettingsProfile myDefaultProfile = new HydraCompilerSettingsProfile("Default"); + private final List myModuleProfiles = new ArrayList<>(); + private final Map myAllModulesMap = new HashMap<>(); + private final Project myProject; + private final Tree myTree; + private final ScalaHydraCompilerSettingsPanel mySettingsPanel; + private HydraCompilerSettingsProfile mySelectedProfile = null; + + public HydraCompilerProfilePanel(Project project) { + super(new BorderLayout()); + Splitter splitter = new Splitter(false, 0.3f); + add(splitter, BorderLayout.CENTER); + myProject = project; + for (Module module : ModuleManager.getInstance(project).getModules()) { + myAllModulesMap.put(module.getName(), module); + } + myTree = new Tree(new MyTreeModel()); + myTree.setRootVisible(false); + final JPanel treePanel = + ToolbarDecorator.createDecorator(myTree).addExtraAction(new AnActionButton("Move to", AllIcons.Actions.Nextfile) { + @Override + public void actionPerformed(AnActionEvent e) { + final MyModuleNode node = (MyModuleNode)myTree.getSelectionPath().getLastPathComponent(); + final TreePath[] selectedNodes = myTree.getSelectionPaths(); + final HydraCompilerSettingsProfile nodeProfile = ((ProfileNode)node.getParent()).myProfile; + final List profiles = new ArrayList<>(); + profiles.add(myDefaultProfile); + for (HydraCompilerSettingsProfile profile : myModuleProfiles) { + profiles.add(profile); + } + profiles.remove(nodeProfile); + final JBList list = new JBList(profiles); + final JBPopup popup = JBPopupFactory.getInstance().createListPopupBuilder(list) + .setTitle("Move to") + .setItemChoosenCallback(new Runnable() { + @Override + public void run() { + final Object value = list.getSelectedValue(); + if (value instanceof HydraCompilerSettingsProfile) { + final HydraCompilerSettingsProfile chosenProfile = (HydraCompilerSettingsProfile)value; + final Module toSelect = (Module)node.getUserObject(); + if (selectedNodes != null) { + for (TreePath selectedNode : selectedNodes) { + final Object node = selectedNode.getLastPathComponent(); + if (node instanceof MyModuleNode) { + final Module module = (Module)((MyModuleNode)node).getUserObject(); + if (nodeProfile != myDefaultProfile) { + nodeProfile.removeModuleName(module.getName()); + } + if (chosenProfile != myDefaultProfile) { + chosenProfile.addModuleName(module.getName()); + } + } + } + } + + final RootNode root = (RootNode)myTree.getModel().getRoot(); + root.sync(); + final DefaultMutableTreeNode node = TreeUtil.findNodeWithObject(root, toSelect); + if (node != null) { + TreeUtil.selectNode(myTree, node); + } + } + } + }) + .createPopup(); + RelativePoint point = + e.getInputEvent() instanceof MouseEvent ? getPreferredPopupPoint() : TreeUtil.getPointForSelection(myTree); + popup.show(point); + } + + @Override + public ShortcutSet getShortcut() { + return ActionManager.getInstance().getAction("Move").getShortcutSet(); + } + + @Override + public boolean isEnabled() { + return myTree.getSelectionPath() != null + && myTree.getSelectionPath().getLastPathComponent() instanceof MyModuleNode + && !myModuleProfiles.isEmpty(); + } + }).createPanel(); + splitter.setFirstComponent(treePanel); + myTree.setCellRenderer(new MyCellRenderer()); + + myTree.addTreeSelectionListener(new TreeSelectionListener() { + @Override + public void valueChanged(TreeSelectionEvent e) { + final TreePath path = myTree.getSelectionPath(); + if (path != null) { + Object node = path.getLastPathComponent(); + if (node instanceof MyModuleNode) { + node = ((MyModuleNode)node).getParent(); + } + if (node instanceof ProfileNode) { + final HydraCompilerSettingsProfile nodeProfile = ((ProfileNode)node).myProfile; + final HydraCompilerSettingsProfile selectedProfile = mySelectedProfile; + if (nodeProfile != selectedProfile) { + if (selectedProfile != null) { + mySettingsPanel.saveTo(selectedProfile); + } + mySelectedProfile = nodeProfile; + mySettingsPanel.setProfile(nodeProfile); + } + } + } + } + }); + mySettingsPanel = new ScalaHydraCompilerSettingsPanel(myProject); + JPanel settingsComponent = mySettingsPanel.getComponent(); + settingsComponent.setBorder(IdeBorderFactory.createEmptyBorder(0, 6, 0, 0)); + splitter.setSecondComponent(settingsComponent); + + final TreeSpeedSearch search = new TreeSpeedSearch(myTree); + search.setComparator(new SpeedSearchComparator(false)); + } + + public void initProfiles(HydraCompilerSettingsProfile defaultProfile, Collection moduleProfiles) { + myDefaultProfile.initFrom(defaultProfile); + myModuleProfiles.clear(); + for (HydraCompilerSettingsProfile profile : moduleProfiles) { + HydraCompilerSettingsProfile copy = new HydraCompilerSettingsProfile(""); + copy.initFrom(profile); + myModuleProfiles.add(copy); + } + final RootNode root = (RootNode)myTree.getModel().getRoot(); + root.sync(); + final DefaultMutableTreeNode node = TreeUtil.findNodeWithObject(root, myDefaultProfile); + if (node != null) { + TreeUtil.selectNode(myTree, node); + } + + } + + public HydraCompilerSettingsProfile getDefaultProfile() { + final HydraCompilerSettingsProfile selectedProfile = mySelectedProfile; + if (myDefaultProfile == selectedProfile) { + mySettingsPanel.saveTo(selectedProfile); + } + return myDefaultProfile; + } + + public List getModuleProfiles() { + final HydraCompilerSettingsProfile selectedProfile = mySelectedProfile; + if (myDefaultProfile != selectedProfile) { + mySettingsPanel.saveTo(selectedProfile); + } + return myModuleProfiles; + } + + private static void expand(JTree tree) { + int oldRowCount = 0; + do { + int rowCount = tree.getRowCount(); + if (rowCount == oldRowCount) break; + oldRowCount = rowCount; + for (int i = 0; i < rowCount; i++) { + tree.expandRow(i); + } + } + while (true); + } + + private class MyTreeModel extends DefaultTreeModel implements EditableTreeModel { + public MyTreeModel() { + super(new RootNode()); + } + + @Override + public TreePath addNode(TreePath parentOrNeighbour) { + final String newProfileName = Messages.showInputDialog( + myProject, "Profile name", "Create new profile", null, "", + new InputValidatorEx() { + @Override + public boolean checkInput(String inputString) { + if (StringUtil.isEmpty(inputString) || + Comparing.equal(inputString, myDefaultProfile.getName())) { + return false; + } + for (HydraCompilerSettingsProfile profile : myModuleProfiles) { + if (Comparing.equal(inputString, profile.getName())) { + return false; + } + } + return true; + } + + @Override + public boolean canClose(String inputString) { + return checkInput(inputString); + } + + @Override + public String getErrorText(String inputString) { + if (checkInput(inputString)) { + return null; + } + return StringUtil.isEmpty(inputString) + ? "Profile name shouldn't be empty" + : "Profile " + inputString + " already exists"; + } + }); + if (newProfileName != null) { + final HydraCompilerSettingsProfile profile = new HydraCompilerSettingsProfile(newProfileName); + myModuleProfiles.add(profile); + ((DataSynchronizable)getRoot()).sync(); + final DefaultMutableTreeNode object = TreeUtil.findNodeWithObject((DefaultMutableTreeNode)getRoot(), profile); + if (object != null) { + TreeUtil.selectNode(myTree, object); + } + } + return null; + } + + @Override + public void removeNode(TreePath nodePath) { + Object node = nodePath.getLastPathComponent(); + if (node instanceof ProfileNode) { + final HydraCompilerSettingsProfile nodeProfile = ((ProfileNode)node).myProfile; + if (nodeProfile != myDefaultProfile) { + if (mySelectedProfile == nodeProfile) { + mySelectedProfile = null; + } + myModuleProfiles.remove(nodeProfile); + ((DataSynchronizable)getRoot()).sync(); + final DefaultMutableTreeNode object = TreeUtil.findNodeWithObject((DefaultMutableTreeNode)getRoot(), myDefaultProfile); + if (object != null) { + TreeUtil.selectNode(myTree, object); + } + } + } + } + + @Override + public void removeNodes(Collection path) { + // TODO looks like we don't need it + } + + @Override + public void moveNodeTo(TreePath parentOrNeighbour) { + } + + } + + + private class RootNode extends DefaultMutableTreeNode implements DataSynchronizable { + @Override + public DataSynchronizable sync() { + final Vector newKids = new Vector(); + newKids.add(new ProfileNode(myDefaultProfile, this, true).sync()); + for (HydraCompilerSettingsProfile profile : myModuleProfiles) { + newKids.add(new ProfileNode(profile, this, false).sync()); + } + children = newKids; + ((DefaultTreeModel)myTree.getModel()).reload(); + expand(myTree); + return this; + } + } + + private interface DataSynchronizable { + DataSynchronizable sync(); + } + + private class ProfileNode extends DefaultMutableTreeNode implements DataSynchronizable { + private final HydraCompilerSettingsProfile myProfile; + private final boolean myIsDefault; + + public ProfileNode(HydraCompilerSettingsProfile profile, RootNode parent, boolean isDefault) { + super(profile); + setParent(parent); + myIsDefault = isDefault; + myProfile = profile; + } + + @Override + public DataSynchronizable sync() { + final List nodeModules = new ArrayList(); + if (myIsDefault) { + final Set nonDefaultProfileModules = new HashSet(); + for (HydraCompilerSettingsProfile profile : myModuleProfiles) { + nonDefaultProfileModules.addAll(profile.getModuleNames()); + } + for (Map.Entry entry : myAllModulesMap.entrySet()) { + if (!nonDefaultProfileModules.contains(entry.getKey())) { + nodeModules.add(entry.getValue()); + } + } + } + else { + for (String moduleName : myProfile.getModuleNames()) { + final Module module = myAllModulesMap.get(moduleName); + if (module != null) { + nodeModules.add(module); + } + } + } + Collections.sort(nodeModules, ModuleComparator.INSTANCE); + final Vector vector = new Vector(); + for (Module module : nodeModules) { + vector.add(new MyModuleNode(module, this)); + } + children = vector; + return this; + } + + } + + private static class MyModuleNode extends DefaultMutableTreeNode { + public MyModuleNode(Module module, ProfileNode parent) { + super(module); + setParent(parent); + setAllowsChildren(false); + } + } + + private static class MyCellRenderer extends ColoredTreeCellRenderer { + @Override + public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + if (value instanceof ProfileNode) { + append(((ProfileNode)value).myProfile.getName()); + } + else if (value instanceof MyModuleNode) { + final Module module = (Module)((MyModuleNode)value).getUserObject(); + setIcon(AllIcons.Nodes.Module); + append(module.getName()); + } + } + } + + private static class ModuleComparator implements Comparator { + static final ModuleComparator INSTANCE = new ModuleComparator(); + @Override + public int compare(Module o1, Module o2) { + return o1.getName().compareTo(o2.getName()); + } + } +} \ No newline at end of file diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettings.scala b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettings.scala index 73d06319da9..19691cf667d 100644 --- a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettings.scala +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettings.scala @@ -1,9 +1,5 @@ package org.jetbrains.plugins.hydra.compiler -import java.nio.file.Paths - -import com.intellij.openapi.components._ -import com.intellij.openapi.project.Project import org.jetbrains.plugins.hydra.compiler.SourcePartitioner.Auto import scala.beans.BeanProperty @@ -11,72 +7,48 @@ import scala.beans.BeanProperty /** * @author Maris Alexandru */ -@State( - name = "HydraSettings", - storages = Array(new Storage("hydra.xml")) -) -class HydraCompilerSettings(project: Project) extends PersistentStateComponent[HydraCompilerSettingsState] { - - private val ProjectRoot: String = getProjectRootPath - - var isHydraEnabled: Boolean = false +class HydraCompilerSettings(state: HydraCompilerSettingsState) { + def this() { + this(new HydraCompilerSettingsState()) + } - var hydraVersion: String = "" + loadState(state) var noOfCores: String = Math.ceil(Runtime.getRuntime.availableProcessors()/2D).toInt.toString - var hydraStorePath: String = getDefaultHydraStorePath - - var hydraLogLocation: String = Paths.get(getDefaultHydraStorePath, "hydra.log").toString - var sourcePartitioner: String = Auto.value - override def getState: HydraCompilerSettingsState = { - val state = new HydraCompilerSettingsState() - state.hydraVersion = hydraVersion - state.noOfCores = noOfCores - state.isHydraEnabled = isHydraEnabled - state.hydraStorePath = hydraStorePath - state.sourcePartitioner = sourcePartitioner - state.projectRoot = ProjectRoot - state - } - - override def loadState(state: HydraCompilerSettingsState): Unit = { - isHydraEnabled = state.isHydraEnabled - hydraVersion = state.hydraVersion - noOfCores = state.noOfCores - hydraStorePath = state.hydraStorePath - sourcePartitioner = state.sourcePartitioner + def loadState(state: HydraCompilerSettingsState): Unit = { + noOfCores = state.getNoOfCores + sourcePartitioner = state.getSourcePartitioner } - def getDefaultHydraStorePath: String = Paths.get(ProjectRoot, ".hydra", "idea").toString + def getState: HydraCompilerSettingsState = { + val state = new HydraCompilerSettingsState() - private def getProjectRootPath: String = project.getBaseDir.getPresentableUrl -} + state.setNoOfCores(noOfCores) + state.setSourcePartitioner(sourcePartitioner) -object HydraCompilerSettings { - def getInstance(project: Project): HydraCompilerSettings = ServiceManager.getService(project, classOf[HydraCompilerSettings]) + state + } } class HydraCompilerSettingsState { - @BeanProperty - var isHydraEnabled: Boolean = false - - @BeanProperty - var hydraVersion: String = "" - @BeanProperty var noOfCores: String = "" - @BeanProperty - var hydraStorePath: String = "" - @BeanProperty var sourcePartitioner: String = "" - @BeanProperty - var projectRoot: String = "" + def canEqual(other: Any): Boolean = other.isInstanceOf[HydraCompilerSettingsState] + + override def equals(other: Any): Boolean = other match { + case that: HydraCompilerSettingsState => + (that canEqual this) && + noOfCores == that.noOfCores && + sourcePartitioner == that.sourcePartitioner + case _ => false + } } object SourcePartitioner { @@ -89,3 +61,4 @@ object SourcePartitioner { val values: Seq[SourcePartitioner] = Seq(Auto, Explicit, Plain, Package) } + diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsManager.scala b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsManager.scala index c7eb5641f73..f8aa975f68c 100644 --- a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsManager.scala +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsManager.scala @@ -13,7 +13,7 @@ object HydraCompilerSettingsManager { def showHydraCompileSettingsDialog(project: Project): Unit = ShowSettingsUtil.getInstance().showSettingsDialog(project, "Hydra Compiler") def getHydraLogJvmParameter(project: Project): String = { - val settings = HydraCompilerSettings.getInstance(project) + val settings = HydraCompilerConfiguration.getInstance(project) if (settings.isHydraEnabled) s"-Dhydra.logFile=${settings.hydraLogLocation}" else @@ -22,7 +22,7 @@ object HydraCompilerSettingsManager { def setHydraLogSystemProperty(project: Project): Unit = { if (System.getProperty(HydraLogKey) == null) { - val settings = HydraCompilerSettings.getInstance(project) + val settings = HydraCompilerConfiguration.getInstance(project) System.setProperty(HydraLogKey, settings.hydraLogLocation) } } diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsPanel.form b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsPanel.form new file mode 100644 index 00000000000..017323296a6 --- /dev/null +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsPanel.form @@ -0,0 +1,53 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsPanel.java b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsPanel.java new file mode 100644 index 00000000000..5e7c65f9c16 --- /dev/null +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsPanel.java @@ -0,0 +1,68 @@ +package org.jetbrains.plugins.hydra.compiler; + +import com.intellij.uiDesigner.core.GridConstraints; +import com.intellij.uiDesigner.core.GridLayoutManager; +import com.intellij.uiDesigner.core.Spacer; +import org.jetbrains.sbt.project.template.SComboBox; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Maris Alexandru + */ +public class HydraCompilerSettingsPanel { + private JPanel contentPanel; + protected SComboBox noOfCoresComboBox; + protected SComboBox sourcePartitionerComboBox; + + public HydraCompilerSettingsPanel() { + + } + + public JPanel getComponent() { + return contentPanel; + } + + { +// GUI initializer generated by IntelliJ IDEA GUI Designer +// >>> IMPORTANT!! <<< +// DO NOT EDIT OR ADD ANY CODE HERE! + $$$setupUI$$$(); + } + + /** + * Method generated by IntelliJ IDEA GUI Designer + * >>> IMPORTANT!! <<< + * DO NOT edit this method OR call it in your code! + * + * @noinspection ALL + */ + private void $$$setupUI$$$() { + contentPanel = new JPanel(); + contentPanel.setLayout(new GridLayoutManager(3, 3, new Insets(0, 0, 0, 0), -1, -1)); + final JLabel label1 = new JLabel(); + label1.setText("Number of cores"); + contentPanel.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final Spacer spacer1 = new Spacer(); + contentPanel.add(spacer1, new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_VERTICAL, 1, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false)); + noOfCoresComboBox = new SComboBox(); + final DefaultComboBoxModel defaultComboBoxModel1 = new DefaultComboBoxModel(); + noOfCoresComboBox.setModel(defaultComboBoxModel1); + contentPanel.add(noOfCoresComboBox, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + sourcePartitionerComboBox = new SComboBox(); + contentPanel.add(sourcePartitionerComboBox, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final JLabel label2 = new JLabel(); + label2.setText("Source Partitioner"); + contentPanel.add(label2, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false)); + final Spacer spacer2 = new Spacer(); + contentPanel.add(spacer2, new GridConstraints(1, 2, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false)); + } + + /** + * @noinspection ALL + */ + public JComponent $$$getRootComponent$$$() { + return contentPanel; + } +} diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsProfile.java b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsProfile.java new file mode 100644 index 00000000000..d126f877286 --- /dev/null +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerSettingsProfile.java @@ -0,0 +1,55 @@ +package org.jetbrains.plugins.hydra.compiler; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Maris Alexandru + */ +public class HydraCompilerSettingsProfile { + private String name; + private List moduleNames = new ArrayList<>(); + private HydraCompilerSettings settings; + + public HydraCompilerSettingsProfile(String name) { + this.name = name; + this.settings = new HydraCompilerSettings(); + } + + public String getName() { + return name; + } + + public void initFrom(HydraCompilerSettingsProfile profile) { + name = profile.getName(); + settings = profile.getSettings(); + moduleNames = new ArrayList<>(profile.getModuleNames()); + } + + public List getModuleNames() { + return Collections.unmodifiableList(moduleNames); + } + + public void addModuleName(String name) { + moduleNames.add(name); + } + + public void removeModuleName(String name) { + moduleNames.remove(name); + } + + public HydraCompilerSettings getSettings() { + return settings; + } + + public void setSettings(HydraCompilerSettings settigns) { + settings = settigns; + } + + @Override + public String toString() { + return name; + } +} diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/ScalaHydraCompilerConfigurationPanel.scala b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/ScalaHydraCompilerConfigurationPanel.scala index 5c7b16e22e1..b213ebe0b04 100644 --- a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/ScalaHydraCompilerConfigurationPanel.scala +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/ScalaHydraCompilerConfigurationPanel.scala @@ -1,5 +1,6 @@ package org.jetbrains.plugins.hydra.compiler +import java.awt.BorderLayout import java.awt.event.ActionEvent import java.net.URL import javax.swing.SwingUtilities @@ -19,7 +20,7 @@ import scala.util.{Failure, Success, Try} /** * @author Maris Alexandru */ -class ScalaHydraCompilerConfigurationPanel(project: Project, settings: HydraCompilerSettings, hydraGlobalSettings: HydraApplicationSettings) extends HydraCompilerConfigurationPanel { +class ScalaHydraCompilerConfigurationPanel(project: Project, settings: HydraCompilerConfiguration, hydraGlobalSettings: HydraApplicationSettings) extends HydraCompilerConfigurationPanel { private val documentAdapter = new DocumentAdapter { override def textChanged(documentEvent: DocumentEvent): Unit = @@ -45,16 +46,8 @@ class ScalaHydraCompilerConfigurationPanel(project: Project, settings: HydraComp downloadButton.addActionListener((_: ActionEvent) => onDownload()) checkConnectionButton.addActionListener((_: ActionEvent) => onCheck()) - noOfCoresComboBox.setItems(Array.range(1, Runtime.getRuntime.availableProcessors() + 1).map(_.toString).sortWith(_ > _)) - sourcePartitionerComboBox.setItems(SourcePartitioner.values.map(_.value).toArray) - - def selectedNoOfCores: String = noOfCoresComboBox.getSelectedItem.toString - - def setSelectedNoOfCores(numberOfCores: String): Unit = noOfCoresComboBox.setSelectedItem(numberOfCores) - - def selectedSourcePartitioner: String = sourcePartitionerComboBox.getSelectedItem.toString - - def setSelectedSourcePartitioner(sourcePartitioner: String): Unit = sourcePartitionerComboBox.setSelectedItem(sourcePartitioner) + hydraProfilesPanel = new HydraCompilerProfilePanel(project) + profilesPanel.add(hydraProfilesPanel, BorderLayout.CENTER) def getHydraRepository: String = hydraRepository.getText @@ -73,6 +66,8 @@ class ScalaHydraCompilerConfigurationPanel(project: Project, settings: HydraComp def setHydraVersion(version: String) = versionTextField.setText(version) + def getHydraProfilesPanel: HydraCompilerProfilePanel = hydraProfilesPanel + def onDownload(): Unit = { Try(new URL(hydraGlobalSettings.getHydraRepositoryUrl)) match { case Success(_) => downloadHydraForProjectScalaVersions() diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/ScalaHydraCompilerSettingsPanel.scala b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/ScalaHydraCompilerSettingsPanel.scala new file mode 100644 index 00000000000..239511f08aa --- /dev/null +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/ScalaHydraCompilerSettingsPanel.scala @@ -0,0 +1,43 @@ +package org.jetbrains.plugins.hydra.compiler + +import com.intellij.openapi.project.Project + +/** + * @author Maris Alexandru + */ +class ScalaHydraCompilerSettingsPanel(project: Project) extends HydraCompilerSettingsPanel { + + noOfCoresComboBox.setItems(Array.range(1, Runtime.getRuntime.availableProcessors() + 1).map(_.toString).sortWith(_ > _)) + sourcePartitionerComboBox.setItems(SourcePartitioner.values.map(_.value).toArray) + + def getState: HydraCompilerSettings = { + val state = new HydraCompilerSettings() + + state.noOfCores = selectedNoOfCores + state.sourcePartitioner = selectedSourcePartitioner + + state + } + + def setState(state: HydraCompilerSettings): Unit = { + setSelectedNoOfCores(state.noOfCores) + setSelectedSourcePartitioner(state.sourcePartitioner) + } + + def saveTo(profile: HydraCompilerSettingsProfile): Unit = { + profile.setSettings(getState) + } + + def setProfile(profile: HydraCompilerSettingsProfile): Unit = { + setState(profile.getSettings) + } + + def selectedNoOfCores: String = noOfCoresComboBox.getSelectedItem.toString + + def setSelectedNoOfCores(numberOfCores: String): Unit = noOfCoresComboBox.setSelectedItem(numberOfCores) + + def selectedSourcePartitioner: String = sourcePartitionerComboBox.getSelectedItem.toString + + def setSelectedSourcePartitioner(sourcePartitioner: String): Unit = sourcePartitionerComboBox.setSelectedItem(sourcePartitioner) + +} diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/notification/HydraArtifactsNotificationProvider.scala b/scala/scala-impl/src/org/jetbrains/plugins/hydra/notification/HydraArtifactsNotificationProvider.scala index 86dafca4310..119c57fc0c7 100644 --- a/scala/scala-impl/src/org/jetbrains/plugins/hydra/notification/HydraArtifactsNotificationProvider.scala +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/notification/HydraArtifactsNotificationProvider.scala @@ -5,7 +5,7 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.util.Key import com.intellij.ui.{EditorNotificationPanel, EditorNotifications} import org.jetbrains.plugins.hydra.HydraVersions -import org.jetbrains.plugins.hydra.compiler.{HydraCompilerSettings, HydraCompilerSettingsManager} +import org.jetbrains.plugins.hydra.compiler.{HydraCompilerConfiguration, HydraCompilerSettingsManager} import org.jetbrains.plugins.hydra.settings.HydraApplicationSettings import org.jetbrains.plugins.scala.project.notification.AbstractNotificationProvider import org.jetbrains.plugins.hydra.notification.HydraArtifactsNotificationProvider._ @@ -20,7 +20,7 @@ class HydraArtifactsNotificationProvider(project: Project, notifications: Editor override protected def hasDeveloperKit(module: Module): Boolean = { val downloadedScalaVersions = HydraApplicationSettings.getInstance().getDownloadedScalaVersions - val hydraSettings = HydraCompilerSettings.getInstance(project) + val hydraSettings = HydraCompilerConfiguration.getInstance(project) val scalaVersions = HydraVersions.getSupportedScalaVersions(project) if(hydraSettings.isHydraEnabled) { From d6e85dae318e91b7cdc4e8783bb5dac8089aadee Mon Sep 17 00:00:00 2001 From: Maris Date: Mon, 20 Nov 2017 12:21:58 +0200 Subject: [PATCH 2/3] Added Hydra profile settings to compiler arguments --- .../scala/HydraSerializerService.java | 42 ++++++++++++++- .../scala/data/CompilationData.scala | 10 ++-- .../scala/model/HydraCompilerSettings.java | 8 +++ .../model/HydraCompilerSettingsImpl.java | 53 +++++++++++++++++++ .../scala/model/HydraSettings.java | 4 +- .../scala/model/HydraSettingsImpl.java | 45 +++++++++++----- .../compiler/HydraCompilerConfiguration.scala | 7 ++- 7 files changed, 148 insertions(+), 21 deletions(-) create mode 100644 scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraCompilerSettings.java create mode 100644 scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraCompilerSettingsImpl.java diff --git a/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/HydraSerializerService.java b/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/HydraSerializerService.java index fae2bb3a9b4..44e9d7f2d46 100644 --- a/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/HydraSerializerService.java +++ b/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/HydraSerializerService.java @@ -1,9 +1,12 @@ package org.jetbrains.jps.incremental.scala; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.xmlb.XmlSerializer; import org.jdom.Element; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.incremental.scala.model.CompilerSettingsImpl; import org.jetbrains.jps.incremental.scala.model.GlobalHydraSettingsImpl; +import org.jetbrains.jps.incremental.scala.model.HydraCompilerSettingsImpl; import org.jetbrains.jps.incremental.scala.model.HydraSettingsImpl; import org.jetbrains.jps.model.JpsGlobal; import org.jetbrains.jps.model.JpsProject; @@ -12,7 +15,9 @@ import org.jetbrains.jps.model.serialization.JpsProjectExtensionSerializer; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * @author Maris Alexandru @@ -38,8 +43,25 @@ private HydraSettingsSerializer() { @Override public void loadExtension(@NotNull JpsProject jpsProject, @NotNull Element componentTag) { - HydraSettingsImpl.State state = XmlSerializer.deserialize(componentTag, HydraSettingsImpl.State.class); - HydraSettingsImpl settings = new HydraSettingsImpl(state == null ? new HydraSettingsImpl.State() : state); + HydraSettingsImpl.State state = getHydraSettingsState(componentTag); + + HydraCompilerSettingsImpl defaultSettings = loadSettings(componentTag); + + Map moduleToProfile = new HashMap(); + Map profileToSettings = new HashMap(); + + for (Element profileElement : componentTag.getChildren("profile")) { + String profile = profileElement.getAttributeValue("name"); + HydraCompilerSettingsImpl settings = loadSettings(profileElement); + profileToSettings.put(profile, settings); + + List modules = StringUtil.split(profileElement.getAttributeValue("modules"), ","); + for (String module : modules) { + moduleToProfile.put(module, profile); + } + } + + HydraSettingsImpl settings = new HydraSettingsImpl(state == null ? new HydraSettingsImpl.State() : state, defaultSettings, profileToSettings, moduleToProfile); SettingsManager.setHydraSettings(jpsProject, settings); } @@ -47,6 +69,22 @@ public void loadExtension(@NotNull JpsProject jpsProject, @NotNull Element compo public void saveExtension(@NotNull JpsProject jpsProject, @NotNull Element componentTag) { // do nothing } + + private static HydraCompilerSettingsImpl loadSettings(Element componentTag) { + HydraCompilerSettingsImpl.State state = XmlSerializer.deserialize(componentTag, HydraCompilerSettingsImpl.State.class); + return new HydraCompilerSettingsImpl(state == null ? new HydraCompilerSettingsImpl.State() : state); + } + + private HydraSettingsImpl.State getHydraSettingsState(Element componentTag) { + Element stateConfiguration = componentTag.getChild("HydraCompilerConfigurationState"); + HydraSettingsImpl.State state = new HydraSettingsImpl.State(); + + if (stateConfiguration != null) { + state = XmlSerializer.deserialize(stateConfiguration, HydraSettingsImpl.State.class); + } + + return state; + } } private static class GlobalHydraSettingsSerializer extends JpsGlobalExtensionSerializer { diff --git a/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/data/CompilationData.scala b/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/data/CompilationData.scala index c9c2c730cd5..85bfd46acad 100644 --- a/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/data/CompilationData.scala +++ b/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/data/CompilationData.scala @@ -84,7 +84,7 @@ object CompilationData { !JavaBuilderUtil.isCompileJavaIncrementally(context) && !JavaBuilderUtil.isForcedRecompilationAllJavaModules(context) - val hydraOptions = getHydraCompilerOptions(target, context, module, outputGroups) + val hydraOptions = getHydraCompilerOptions(target, context, module, chunk, outputGroups) CompilationData(canonicalSources, classpath, output, commonOptions ++ scalaOptions ++ hydraOptions, commonOptions ++ javaOptions, order, cacheFile, relevantOutputToCacheMap, outputGroups, @@ -219,15 +219,17 @@ object CompilationData { "\nTIP: you can use Project Artifacts to combine compiled classes if needed.") } - private def getHydraCompilerOptions(target: ModuleBuildTarget, context: CompileContext, module: JpsModule, outputGroups: Seq[(File, File)]) = { + private def getHydraCompilerOptions(target: ModuleBuildTarget, context: CompileContext, module: JpsModule, chunk: ModuleChunk, outputGroups: Seq[(File, File)]): Seq[String] = { val hydraSettings = SettingsManager.getHydraSettings(context.getProjectDescriptor.getProject) + val hydraProfileCompilerSettings = hydraSettings.getCompilerSettings(chunk) val hydraGlobalSettings = SettingsManager.getGlobalHydraSettings(context.getProjectDescriptor.getModel.getGlobal) val scalaVersion = CompilerData.compilerVersion(module) val hydraConfigFolder = if (target.isTests) "test" else "main" val hydraOptions = if (hydraSettings.isHydraEnabled && scalaVersion.nonEmpty && hydraGlobalSettings.containsArtifactsFor(scalaVersion.get, hydraSettings.getHydraVersion)) - Seq("-sourcepath", outputGroups.map(_._1).mkString(File.pathSeparator), "-cpus", hydraSettings.getNumberOfCores, - "-YsourcePartitioner:" + hydraSettings.getSourcePartitioner, "-YhydraStore", Paths.get(hydraSettings.getHydraStorePath, module.getName, hydraConfigFolder).toString, + hydraProfileCompilerSettings.getCompilerOptions.toSeq ++ + Seq("-sourcepath", outputGroups.map(_._1).mkString(File.pathSeparator), "-cpus", "4", + "-YhydraStore", Paths.get(hydraSettings.getHydraStorePath, module.getName, hydraConfigFolder).toString, "-YpartitionFile", Paths.get(hydraSettings.getHydraStorePath, module.getName).toString, "-YrootDirectory", hydraSettings.getProjectRoot, "-YtimingsFile", Paths.get(hydraSettings.getHydraStorePath, "timings.csv").toString, "-YhydraTag", s"${module.getName}/${hydraConfigFolder}") else diff --git a/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraCompilerSettings.java b/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraCompilerSettings.java new file mode 100644 index 00000000000..3246c057264 --- /dev/null +++ b/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraCompilerSettings.java @@ -0,0 +1,8 @@ +package org.jetbrains.jps.incremental.scala.model; + +/** + * @author Maris Alexandru + */ +public interface HydraCompilerSettings { + String[] getCompilerOptions(); +} diff --git a/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraCompilerSettingsImpl.java b/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraCompilerSettingsImpl.java new file mode 100644 index 00000000000..491c6c0ce8d --- /dev/null +++ b/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraCompilerSettingsImpl.java @@ -0,0 +1,53 @@ +package org.jetbrains.jps.incremental.scala.model; + +import com.intellij.util.xmlb.XmlSerializerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.ex.JpsElementBase; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Maris Alexandru + */ +public class HydraCompilerSettingsImpl extends JpsElementBase implements HydraCompilerSettings { + public static final HydraCompilerSettingsImpl DEFAULT = new HydraCompilerSettingsImpl(new State()); + + private State state; + + public HydraCompilerSettingsImpl(State state) { + this.state = state; + } + + @Override + public String[] getCompilerOptions() { + List list = new ArrayList(); + + if (state.noOfCores != null) { + list.add("-cpus"); + list.add(state.noOfCores); + } + + if (state.sourcePartitioner != null) { + list.add("-YsourcePartitioner:" + state.sourcePartitioner); + } + + return list.toArray(new String[list.size()]); + } + + @NotNull + @Override + public HydraCompilerSettingsImpl createCopy() { + return new HydraCompilerSettingsImpl(XmlSerializerUtil.createCopy(state)); + } + + @Override + public void applyChanges(@NotNull HydraCompilerSettingsImpl hydraCompilerSettings) { + // do nothing + } + + public static class State { + public String noOfCores; + public String sourcePartitioner; + } +} diff --git a/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraSettings.java b/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraSettings.java index ce95d9e1aa2..3f5566421ff 100644 --- a/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraSettings.java +++ b/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraSettings.java @@ -1,5 +1,6 @@ package org.jetbrains.jps.incremental.scala.model; +import org.jetbrains.jps.ModuleChunk; import org.jetbrains.jps.model.JpsElement; import java.util.List; @@ -10,9 +11,8 @@ */ public interface HydraSettings extends JpsElement { boolean isHydraEnabled(); - String getNumberOfCores(); String getHydraVersion(); - String getSourcePartitioner(); String getHydraStorePath(); String getProjectRoot(); + HydraCompilerSettings getCompilerSettings(ModuleChunk chunk); } diff --git a/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraSettingsImpl.java b/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraSettingsImpl.java index efee23cd0b6..6f90a976281 100644 --- a/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraSettingsImpl.java +++ b/scala/compiler-shared/src/org/jetbrains/jps/incremental/scala/model/HydraSettingsImpl.java @@ -2,20 +2,33 @@ import com.intellij.util.xmlb.XmlSerializerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.ModuleChunk; import org.jetbrains.jps.model.ex.JpsElementBase; import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; /** * @author Maris Alexandru */ public class HydraSettingsImpl extends JpsElementBase implements HydraSettings{ - public static final HydraSettings DEFAULT = new HydraSettingsImpl(new State()); + public static final HydraSettings DEFAULT = new HydraSettingsImpl(new State(), HydraCompilerSettingsImpl.DEFAULT, + new HashMap(), new HashMap()); private final State state; - public HydraSettingsImpl(State state) { + private HydraCompilerSettingsImpl myDefaultSettings; + + private Map myProfileToSettings; + + private Map myModuleToProfile; + + public HydraSettingsImpl(State state, HydraCompilerSettingsImpl defaultSettings, Map profileToSettings, Map moduleToProfile) { this.state = state; + this.myDefaultSettings = defaultSettings; + this.myProfileToSettings = profileToSettings; + this.myModuleToProfile = moduleToProfile; } @Override @@ -26,24 +39,32 @@ public String getHydraVersion() { return state.hydraVersion; } - @Override - public String getNumberOfCores() { - return state.noOfCores; - } - @Override public String getHydraStorePath() { return Paths.get(state.hydraStorePath).toString(); } @Override - public String getSourcePartitioner() { return state.sourcePartitioner; } + public String getProjectRoot() { return Paths.get(state.projectRoot).toString(); } @Override - public String getProjectRoot() { return Paths.get(state.projectRoot).toString(); } + public HydraCompilerSettings getCompilerSettings(ModuleChunk chunk) { + String module = chunk.representativeTarget().getModule().getName(); + String profile = myModuleToProfile.get(module); + return profile == null ? myDefaultSettings : myProfileToSettings.get(profile); + } @NotNull @Override public HydraSettingsImpl createCopy() { - return new HydraSettingsImpl(XmlSerializerUtil.createCopy(state)); + HydraCompilerSettingsImpl defaultSettings = myDefaultSettings.createCopy(); + + Map profileToSettings = new HashMap(); + for (Map.Entry entry : myProfileToSettings.entrySet()) { + profileToSettings.put(entry.getKey(), entry.getValue().createCopy()); + } + + HashMap moduleToProfile = new HashMap(myModuleToProfile); + + return new HydraSettingsImpl(XmlSerializerUtil.createCopy(state), defaultSettings, profileToSettings, moduleToProfile); } @Override @@ -54,9 +75,9 @@ public void applyChanges(@NotNull HydraSettingsImpl hydraSettings) { public static class State { public boolean isHydraEnabled = false; public String hydraVersion = ""; - public String noOfCores = Integer.toString((int) Math.ceil(Runtime.getRuntime().availableProcessors()/2D)); + //public String noOfCores = Integer.toString((int) Math.ceil(Runtime.getRuntime().availableProcessors()/2D)); public String hydraStorePath = ""; - public String sourcePartitioner = ""; + //public String sourcePartitioner = ""; public String projectRoot = ""; } } diff --git a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfiguration.scala b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfiguration.scala index 2ffcb56ab6e..79de5b20c45 100644 --- a/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfiguration.scala +++ b/scala/scala-impl/src/org/jetbrains/plugins/hydra/compiler/HydraCompilerConfiguration.scala @@ -60,7 +60,12 @@ class HydraCompilerConfiguration(project: Project) extends PersistentStateCompon } override def loadState(configurationElement: Element): Unit = { - val state = XmlSerializer.deserialize(configurationElement, classOf[HydraCompilerConfigurationState]) + val stateConfiguration = configurationElement.getChild("HydraCompilerConfigurationState") + var state = new HydraCompilerConfigurationState + + if (stateConfiguration != null) + state = XmlSerializer.deserialize(stateConfiguration, classOf[HydraCompilerConfigurationState]) + setFromState(state) defaultProfile.setSettings(new HydraCompilerSettings(XmlSerializer.deserialize(configurationElement, classOf[HydraCompilerSettingsState]))) From 2755a70c8e4099d24ca9a8e39730db8e24d9df53 Mon Sep 17 00:00:00 2001 From: Maris Date: Mon, 20 Nov 2017 12:29:35 +0200 Subject: [PATCH 3/3] Removed Hardcoded cpus option --- .../jetbrains/jps/incremental/scala/data/CompilationData.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/data/CompilationData.scala b/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/data/CompilationData.scala index 85bfd46acad..e1ab45dd3b5 100644 --- a/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/data/CompilationData.scala +++ b/scala/compiler-jps/src/org/jetbrains/jps/incremental/scala/data/CompilationData.scala @@ -228,7 +228,7 @@ object CompilationData { val hydraOptions = if (hydraSettings.isHydraEnabled && scalaVersion.nonEmpty && hydraGlobalSettings.containsArtifactsFor(scalaVersion.get, hydraSettings.getHydraVersion)) hydraProfileCompilerSettings.getCompilerOptions.toSeq ++ - Seq("-sourcepath", outputGroups.map(_._1).mkString(File.pathSeparator), "-cpus", "4", + Seq("-sourcepath", outputGroups.map(_._1).mkString(File.pathSeparator), "-YhydraStore", Paths.get(hydraSettings.getHydraStorePath, module.getName, hydraConfigFolder).toString, "-YpartitionFile", Paths.get(hydraSettings.getHydraStorePath, module.getName).toString, "-YrootDirectory", hydraSettings.getProjectRoot, "-YtimingsFile", Paths.get(hydraSettings.getHydraStorePath, "timings.csv").toString, "-YhydraTag", s"${module.getName}/${hydraConfigFolder}")