ExecutableValidator: allow to reset error description during validation (there could be different reasons why executable is not valid)
private final NotificationGroup myNotificationGroup = new NotificationGroup(NOTIFICATION_ID, NotificationDisplayType.TOOL_WINDOW, true,
ToolWindowId.VCS);
- private final Project myProject;
+ protected final Project myProject;
private final String myNotificationErrorTitle;
- private final String myNotificationErrorDescription;
+ private String myNotificationErrorDescription;
/**
* Configures notification and dialog by setting text messages and titles specific to the whoever uses the validator.
}
}
+ public void setNotificationErrorDescription(String notificationErrorDescription) {
+ myNotificationErrorDescription = notificationErrorDescription;
+ }
+
/**
* Shows a notification about not configured executable with a link to the Settings to fix it.
* Expires the notification if user fixes the path from the opened Settings dialog.
<text value="with command line client"/>
</properties>
</component>
+ <component id="44a8" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myCommandLineClient">
+ <constraints>
+ <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties/>
+ </component>
</children>
</grid>
</children>
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
private JRadioButton myNoAcceleration;
private JLabel myJavaHLInfo;
private JRadioButton myWithCommandLineClient;
+ private TextFieldWithBrowseButton myCommandLineClient;
@NonNls private static final String HELP_ID = "project.propSubversion";
}
}
});
+ myCommandLineClient.addBrowseFolderListener("Subversion", "Select path to Subversion executable (1.7+)", project,
+ FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor());
myClearAuthButton.addActionListener(new ActionListener(){
public void actionPerformed(final ActionEvent e) {
if (configuration.mySSHReadTimeout/1000 != ((SpinnerNumberModel) mySSHReadTimeout.getModel()).getNumber().longValue()) {
return true;
}
+ final SvnApplicationSettings17 applicationSettings17 = SvnApplicationSettings17.getInstance();
+ if (! Comparing.equal(applicationSettings17.getCommandLinePath(), myCommandLineClient.getText().trim())) return true;
return !configuration.getConfigurationDirectory().equals(myConfigurationDirectoryText.getText().trim());
}
configuration.setConfigurationDirectory(myConfigurationDirectoryText.getText());
configuration.setUseDefaultConfiguation(myUseDefaultCheckBox.isSelected());
configuration.setIsUseDefaultProxy(myUseCommonProxy.isSelected());
+ final SvnVcs17 vcs17 = SvnVcs17.getInstance(myProject);
if ((! configuration.DETECT_NESTED_COPIES) && (configuration.DETECT_NESTED_COPIES != myDetectNestedWorkingCopiesCheckBox.isSelected())) {
- SvnVcs17.getInstance(myProject).invokeRefreshSvnRoots(true);
+ vcs17.invokeRefreshSvnRoots(true);
}
configuration.DETECT_NESTED_COPIES = myDetectNestedWorkingCopiesCheckBox.isSelected();
configuration.CHECK_NESTED_FOR_QUICK_MERGE = myCheckNestedInQuickMerge.isSelected();
configuration.mySSHConnectionTimeout = ((SpinnerNumberModel) mySSHConnectionTimeout.getModel()).getNumber().longValue() * 1000;
configuration.mySSHReadTimeout = ((SpinnerNumberModel) mySSHReadTimeout.getModel()).getNumber().longValue() * 1000;
configuration.myUseAcceleration = acceleration();
+
+ final SvnApplicationSettings17 applicationSettings17 = SvnApplicationSettings17.getInstance();
+ applicationSettings17.setCommandLinePath(myCommandLineClient.getText().trim());
+ vcs17.checkCommandLineVersion();
}
public void reset() {
mySSHConnectionTimeout.setValue(Long.valueOf(configuration.mySSHConnectionTimeout / 1000));
mySSHReadTimeout.setValue(Long.valueOf(configuration.mySSHReadTimeout / 1000));
setAcceleration(configuration.myUseAcceleration);
+ final SvnApplicationSettings17 applicationSettings17 = SvnApplicationSettings17.getInstance();
+ myCommandLineClient.setText(applicationSettings17.getCommandLinePath());
}
public void disposeUIResources() {
import org.jetbrains.idea.svn17.actions.SvnMergeProvider;
import org.jetbrains.idea.svn17.annotate.SvnAnnotationProvider;
import org.jetbrains.idea.svn17.checkin.SvnCheckinEnvironment17;
+import org.jetbrains.idea.svn17.commandLine.SvnExecutableChecker;
import org.jetbrains.idea.svn17.dialogs.SvnBranchPointsCalculator;
import org.jetbrains.idea.svn17.dialogs.SvnFormatWorker;
import org.jetbrains.idea.svn17.dialogs.WCInfo;
private final SvnLoadedBrachesStorage17 myLoadedBranchesStorage;
public static final String SVNKIT_HTTP_SSL_PROTOCOLS = "svnkit.http.sslProtocols";
+ private final SvnExecutableChecker myChecker;
+
+ public void checkCommandLineVersion() {
+ myChecker.checkExecutableAndNotifyIfNeeded();
+ }
static {
SVNJNAUtil.setJNAEnabled(true);
// remove used some time before old notification group ids
correctNotificationIds();
+ myChecker = new SvnExecutableChecker(myProject);
}
private void correctNotificationIds() {
}
}
- if (SvnConfiguration17.UseAcceleration.javaHL.equals(SvnConfiguration17.getInstance(myProject).myUseAcceleration)) {
+ final SvnConfiguration17.UseAcceleration accelerationType = SvnConfiguration17.getInstance(myProject).myUseAcceleration;
+ if (SvnConfiguration17.UseAcceleration.javaHL.equals(accelerationType)) {
CheckJavaHL.runtimeCheck(myProject);
+ } else if (SvnConfiguration17.UseAcceleration.commandLine.equals(accelerationType) && ! ApplicationManager.getApplication().isHeadlessEnvironment()) {
+ myChecker.checkExecutableAndNotifyIfNeeded();
}
// do one time after project loaded
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.svn17.SvnApplicationSettings17;
+import org.jetbrains.idea.svn17.SvnVcs17;
import java.io.File;
import java.io.OutputStream;
try {
myProcess = startProcess();
- startHandlingStreams();
+ if (myProcess != null) {
+ startHandlingStreams();
+ } else {
+ SvnVcs17.getInstance(myProject).checkCommandLineVersion();
+ myListeners.getMulticaster().startFailed(null);
+ }
} catch (Throwable t) {
- // todo check executable
+ SvnVcs17.getInstance(myProject).checkCommandLineVersion();
myListeners.getMulticaster().startFailed(t);
}
}
--- /dev/null
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.idea.svn17.commandLine;
+
+import com.intellij.execution.ExecutableValidator;
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.process.CapturingProcessHandler;
+import com.intellij.execution.process.ProcessOutput;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.idea.svn17.SvnApplicationSettings17;
+import org.jetbrains.idea.svn17.SvnVcs17;
+
+import java.text.MessageFormat;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: Irina.Chernushina
+ * Date: 1/31/12
+ * Time: 3:02 PM
+ */
+public class SvnExecutableChecker extends ExecutableValidator {
+ private final static String ourPath = "Probably the path to Subversion executable is wrong.";
+ private static final String ourVersion = "Subversion command line client version is too old ({0}).";
+
+ public SvnExecutableChecker(Project project) {
+ super(project, "Can't use Subversion command line client", ourPath);
+ }
+
+ @Override
+ protected String getCurrentExecutable() {
+ return SvnApplicationSettings17.getInstance().getCommandLinePath();
+ }
+
+ @NotNull
+ @Override
+ protected Configurable getConfigurable() {
+ return SvnVcs17.getInstance(myProject).getConfigurable();
+ }
+
+ @Override
+ protected boolean isExecutableValid(String executable) {
+ setNotificationErrorDescription(ourPath);
+ try {
+ GeneralCommandLine commandLine = new GeneralCommandLine();
+ commandLine.setExePath(executable);
+ commandLine.addParameter("--version");
+ commandLine.addParameter("--quiet");
+ CapturingProcessHandler handler = new CapturingProcessHandler(commandLine.createProcess(), CharsetToolkit.getDefaultSystemCharset());
+ ProcessOutput result = handler.runProcess(30 * 1000);
+ if (! result.isTimeout() && (result.getExitCode() == 0) && result.getStderr().isEmpty()) {
+ final String stdout = result.getStdout().trim();
+ final String[] parts = stdout.split("\\.");
+ if (parts.length < 3 || ! "1".equals(parts[0])) {
+ setNotificationErrorDescription(MessageFormat.format(ourVersion, stdout));
+ return false;
+ }
+ try {
+ final int second = Integer.parseInt(parts[1]);
+ if (second >= 7) return true;
+ } catch (NumberFormatException e) {
+ //
+ }
+ setNotificationErrorDescription(MessageFormat.format(ourVersion, stdout));
+ return false;
+ } else {
+ return false;
+ }
+ } catch (Throwable e) {
+ return false;
+ }
+ }
+}
}
});
start();
- waitFor();
+ if (myProcess != null) {
+ waitFor();
+ }
if (ex[0] != null) {
throw ex[0];
}