mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'svn1_8_new'
This commit is contained in:
@@ -101,6 +101,10 @@ public enum WorkingCopyFormat {
|
||||
return myFormat;
|
||||
}
|
||||
|
||||
public boolean isOrGreater(@NotNull WorkingCopyFormat format) {
|
||||
return myVersion.isOrGreaterThan(format.getVersion().major, format.getVersion().minor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static WorkingCopyFormat from(@NotNull Version version) {
|
||||
WorkingCopyFormat result = UNKNOWN;
|
||||
|
||||
@@ -3,10 +3,17 @@ package org.jetbrains.idea.svn.api;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.WorkingCopyFormat;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnBindException;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.wc.ISVNEventHandler;
|
||||
import org.tmatesoft.svn.core.wc.SVNEvent;
|
||||
import org.tmatesoft.svn.core.wc.SVNEventAction;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
@@ -56,4 +63,20 @@ public abstract class BaseSvnClient implements SvnClient {
|
||||
String.format("%s format is not supported. Supported formats are: %s.", format.getName(), StringUtil.join(supported, ",")));
|
||||
}
|
||||
}
|
||||
|
||||
protected static void callHandler(@Nullable ISVNEventHandler handler, @NotNull SVNEvent event) throws VcsException {
|
||||
if (handler != null) {
|
||||
try {
|
||||
handler.handleEvent(event, 0);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new SvnBindException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected static SVNEvent createEvent(@NotNull File path, @Nullable SVNEventAction action) {
|
||||
return new SVNEvent(path, null, null, 0, null, null, null, null, action, null, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.idea.svn.portable.SvnWcClientI;
|
||||
import org.jetbrains.idea.svn.properties.PropertyClient;
|
||||
import org.jetbrains.idea.svn.revert.RevertClient;
|
||||
import org.jetbrains.idea.svn.update.RelocateClient;
|
||||
import org.jetbrains.idea.svn.upgrade.UpgradeClient;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
@@ -51,6 +52,7 @@ public abstract class ClientFactory {
|
||||
protected VersionClient myVersionClient;
|
||||
protected ImportClient myImportClient;
|
||||
protected ExportClient myExportClient;
|
||||
protected UpgradeClient myUpgradeClient;
|
||||
|
||||
protected ClientFactory(@NotNull SvnVcs vcs) {
|
||||
myVcs = vcs;
|
||||
@@ -166,6 +168,11 @@ public abstract class ClientFactory {
|
||||
return prepare(myExportClient);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public UpgradeClient createUpgradeClient() {
|
||||
return prepare(myUpgradeClient);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected <T extends SvnClient> T prepare(@NotNull T client) {
|
||||
client.setVcs(myVcs);
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.idea.svn.update.UpdateClient;
|
||||
import org.jetbrains.idea.svn.properties.CmdPropertyClient;
|
||||
import org.jetbrains.idea.svn.revert.CmdRevertClient;
|
||||
import org.jetbrains.idea.svn.update.CmdRelocateClient;
|
||||
import org.jetbrains.idea.svn.upgrade.CmdUpgradeClient;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
@@ -53,6 +54,7 @@ public class CmdClientFactory extends ClientFactory {
|
||||
myVersionClient = new CmdVersionClient();
|
||||
myImportClient = new CmdImportClient();
|
||||
myExportClient = new CmdExportClient();
|
||||
myUpgradeClient = new CmdUpgradeClient();
|
||||
statusClient = new SvnCommandLineStatusClient(myVcs);
|
||||
infoClient = new SvnCommandLineInfoClient(myVcs);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.jetbrains.idea.svn.api;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class Repository {
|
||||
|
||||
@NotNull private final SVNURL myUrl;
|
||||
|
||||
public Repository(@NotNull SVNURL url) {
|
||||
myUrl = url;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SVNURL getUrl() {
|
||||
return myUrl;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.idea.svn.portable.SvnkitSvnWcClient;
|
||||
import org.jetbrains.idea.svn.properties.SvnKitPropertyClient;
|
||||
import org.jetbrains.idea.svn.revert.SvnKitRevertClient;
|
||||
import org.jetbrains.idea.svn.update.SvnKitRelocateClient;
|
||||
import org.jetbrains.idea.svn.upgrade.SvnKitUpgradeClient;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
@@ -53,6 +54,7 @@ public class SvnKitClientFactory extends ClientFactory {
|
||||
myVersionClient = new SvnKitVersionClient();
|
||||
myImportClient = new SvnKitImportClient();
|
||||
myExportClient = new SvnKitExportClient();
|
||||
myUpgradeClient = new SvnKitUpgradeClient();
|
||||
statusClient = new SvnkitSvnStatusClient(myVcs, null);
|
||||
infoClient = new SvnkitSvnWcClient(myVcs);
|
||||
}
|
||||
|
||||
@@ -63,6 +63,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
public class SvnCheckoutProvider implements CheckoutProvider {
|
||||
|
||||
public void doCheckout(@NotNull final Project project, Listener listener) {
|
||||
// TODO: Several dialogs is invoked while dialog.show() - seems code should be rewritten to be more transparent
|
||||
CheckoutDialog dialog = new CheckoutDialog(project, listener);
|
||||
dialog.show();
|
||||
}
|
||||
@@ -308,8 +309,9 @@ public class SvnCheckoutProvider implements CheckoutProvider {
|
||||
|
||||
private WorkingCopyFormat displayUpgradeDialog(@NotNull WorkingCopyFormat defaultSelection) {
|
||||
final UpgradeFormatDialog dialog = new UpgradeFormatDialog(myProject, myPath, false);
|
||||
dialog.startLoading();
|
||||
final ModalityState dialogState = ModalityState.any();
|
||||
|
||||
dialog.startLoading();
|
||||
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -331,7 +333,7 @@ public class SvnCheckoutProvider implements CheckoutProvider {
|
||||
dialog.stopLoading();
|
||||
}
|
||||
}
|
||||
}, ModalityState.stateForComponent(dialog.getWindow()));
|
||||
}, dialogState);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.List;
|
||||
*/
|
||||
public class SvnKitCheckoutClient extends BaseSvnClient implements CheckoutClient {
|
||||
|
||||
private static final List<WorkingCopyFormat> SUPPORTED_FORMATS;
|
||||
public static final List<WorkingCopyFormat> SUPPORTED_FORMATS;
|
||||
|
||||
static {
|
||||
List<WorkingCopyFormat> supportedFormats = new ArrayList<WorkingCopyFormat>();
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.RootUrlInfo;
|
||||
import org.jetbrains.idea.svn.SvnVcs;
|
||||
import org.jetbrains.idea.svn.api.Repository;
|
||||
import org.jetbrains.idea.svn.checkin.IdeaSvnkitBasedAuthenticationCallback;
|
||||
import org.tmatesoft.svn.core.SVNDepth;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
@@ -215,19 +216,15 @@ public class CommandUtil {
|
||||
}
|
||||
|
||||
private static SVNURL resolveRepositoryUrl(@NotNull SvnVcs vcs, @NotNull SvnCommandName name, @NotNull SvnTarget target) {
|
||||
RootUrlInfo rootInfo = target.isFile()
|
||||
? vcs.getSvnFileUrlMapping().getWcRootForFilePath(target.getFile())
|
||||
: vcs.getSvnFileUrlMapping().getWcRootForUrl(target.getURL().toDecodedString());
|
||||
SVNURL repositoryUrl = rootInfo != null ? rootInfo.getRepositoryUrlUrl() : null;
|
||||
UrlMappingRepositoryProvider urlMappingProvider = new UrlMappingRepositoryProvider(vcs, target);
|
||||
InfoCommandRepositoryProvider infoCommandProvider = new InfoCommandRepositoryProvider(vcs, target);
|
||||
|
||||
// resolve repository url using "svn info" command except the case when that command is executing right now.
|
||||
if (repositoryUrl == null && !SvnCommandName.info.equals(name)) {
|
||||
SVNInfo info = getInfo(vcs, target);
|
||||
|
||||
repositoryUrl = info != null ? info.getRepositoryRootURL() : null;
|
||||
Repository repository = urlMappingProvider.get();
|
||||
if (repository == null && !SvnCommandName.info.equals(name)) {
|
||||
repository = infoCommandProvider.get();
|
||||
}
|
||||
|
||||
return repositoryUrl;
|
||||
return repository != null ? repository.getUrl() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -296,4 +293,67 @@ public class CommandUtil {
|
||||
}
|
||||
return contentsStatus;
|
||||
}
|
||||
|
||||
public interface RepositoryProvider {
|
||||
|
||||
@Nullable
|
||||
Repository get();
|
||||
}
|
||||
|
||||
public static abstract class BaseRepositoryProvider implements RepositoryProvider {
|
||||
|
||||
@NotNull protected final SvnVcs myVcs;
|
||||
@NotNull protected final SvnTarget myTarget;
|
||||
|
||||
protected BaseRepositoryProvider(@NotNull SvnVcs vcs, @NotNull SvnTarget target) {
|
||||
myVcs = vcs;
|
||||
myTarget = target;
|
||||
}
|
||||
}
|
||||
|
||||
public static class UrlMappingRepositoryProvider extends BaseRepositoryProvider {
|
||||
|
||||
public UrlMappingRepositoryProvider(@NotNull SvnVcs vcs, @NotNull SvnTarget target) {
|
||||
super(vcs, target);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Repository get() {
|
||||
RootUrlInfo rootInfo = null;
|
||||
|
||||
if (!myVcs.getProject().isDefault()) {
|
||||
rootInfo = myTarget.isFile()
|
||||
? myVcs.getSvnFileUrlMapping().getWcRootForFilePath(myTarget.getFile())
|
||||
: myVcs.getSvnFileUrlMapping().getWcRootForUrl(myTarget.getURL().toDecodedString());
|
||||
}
|
||||
|
||||
return rootInfo != null ? new Repository(rootInfo.getRepositoryUrlUrl()) : null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class InfoCommandRepositoryProvider extends BaseRepositoryProvider {
|
||||
|
||||
public InfoCommandRepositoryProvider(@NotNull SvnVcs vcs, @NotNull SvnTarget target) {
|
||||
super(vcs, target);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Repository get() {
|
||||
Repository result;
|
||||
|
||||
if (myTarget.isURL()) {
|
||||
// TODO: Also could still execute info when target is url - either to use info for authentication or to just get correct repository
|
||||
// TODO: url in case of "read" operations are allowed anonymously.
|
||||
result = new Repository(myTarget.getURL());
|
||||
}
|
||||
else {
|
||||
SVNInfo info = getInfo(myVcs, myTarget);
|
||||
result = info != null ? new Repository(info.getRepositoryRootURL()) : null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ public enum SvnCommandName {
|
||||
lock("lock", true),
|
||||
unlock("unlock", true),
|
||||
importFolder("import", false),
|
||||
export("export", false);
|
||||
export("export", false),
|
||||
upgrade("upgrade", true);
|
||||
|
||||
private final String myName;
|
||||
private final boolean myWriteable;
|
||||
|
||||
@@ -17,12 +17,14 @@ package org.jetbrains.idea.svn.dialogs;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.vcs.ObjectsConvertor;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
@@ -61,11 +63,13 @@ import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
public class CopiesPanel {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(CopiesPanel.class);
|
||||
|
||||
private final Project myProject;
|
||||
private MessageBusConnection myConnection;
|
||||
private SvnVcs myVcs;
|
||||
@@ -98,6 +102,7 @@ public class CopiesPanel {
|
||||
@Override
|
||||
public void run() {
|
||||
final List<WCInfo> infoList = myVcs.getAllWcInfos();
|
||||
final List<WorkingCopyFormat> supportedFormats = getSupportedFormats();
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -117,7 +122,7 @@ public class CopiesPanel {
|
||||
myCurrentInfoList = newList;
|
||||
}
|
||||
Collections.sort(infoList, WCComparator.getInstance());
|
||||
updateList(infoList);
|
||||
updateList(infoList, supportedFormats);
|
||||
myRefreshLabel.setEnabled(true);
|
||||
SwingUtilities.invokeLater(focus);
|
||||
}
|
||||
@@ -178,7 +183,7 @@ public class CopiesPanel {
|
||||
return myRefreshLabel;
|
||||
}
|
||||
|
||||
private void updateList(final List<WCInfo> infoList) {
|
||||
private void updateList(@NotNull final List<WCInfo> infoList, @NotNull final List<WorkingCopyFormat> supportedFormats) {
|
||||
myPanel.removeAll();
|
||||
final Insets nullIndent = new Insets(1, 3, 1, 0);
|
||||
final GridBagConstraints gb =
|
||||
@@ -217,7 +222,7 @@ public class CopiesPanel {
|
||||
SVNDepth.INFINITY, false, null, wcInfo.getFormat());
|
||||
}
|
||||
} else if (CHANGE_FORMAT.equals(e.getDescription())) {
|
||||
changeFormat(wcInfo);
|
||||
changeFormat(wcInfo, supportedFormats);
|
||||
} else if (MERGE_FROM.equals(e.getDescription())) {
|
||||
if (! checkRoot(root, wcInfo.getPath(), " invoke Merge From")) return;
|
||||
mergeFrom(wcInfo, root, editorPane);
|
||||
@@ -237,7 +242,7 @@ public class CopiesPanel {
|
||||
}
|
||||
});
|
||||
editorPane.setBorder(null);
|
||||
editorPane.setText(formatWc(wcInfo));
|
||||
editorPane.setText(formatWc(wcInfo, supportedFormats));
|
||||
|
||||
final JPanel copyPanel = new JPanel(new GridBagLayout());
|
||||
|
||||
@@ -263,14 +268,14 @@ public class CopiesPanel {
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
private String formatWc(WCInfo info) {
|
||||
private String formatWc(@NotNull WCInfo info, @NotNull List<WorkingCopyFormat> supportedFormats) {
|
||||
final StringBuilder sb = new StringBuilder().append("<html><head>").append(UIUtil.getCssFontDeclaration(UIUtil.getLabelFont()))
|
||||
.append("</head><body><table bgColor=\"").append(ColorUtil.toHex(UIUtil.getPanelBackground())).append("\">");
|
||||
|
||||
sb.append("<tr valign=\"top\"><td colspan=\"3\"><b>").append(info.getPath()).append("</b></td></tr>");
|
||||
sb.append("<tr valign=\"top\"><td>URL:</td><td colspan=\"2\">").append(info.getRootUrl()).append("</td></tr>");
|
||||
if (! WorkingCopyFormat.ONE_DOT_SEVEN.equals(info.getFormat())) {
|
||||
// can convert
|
||||
Collection<WorkingCopyFormat> upgradeFormats = getUpgradeFormats(info, supportedFormats);
|
||||
if (upgradeFormats.size() > 1) {
|
||||
sb.append("<tr valign=\"top\"><td>Format:</td><td>").append(info.getFormat().getName()).append("</td><td><a href=\"").
|
||||
append(CHANGE_FORMAT).append("\">Change</a></td></tr>");
|
||||
} else {
|
||||
@@ -302,6 +307,33 @@ public class CopiesPanel {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<WorkingCopyFormat> getSupportedFormats() {
|
||||
List<WorkingCopyFormat> result = Collections.emptyList();
|
||||
|
||||
try {
|
||||
result = myVcs.getFactory().createUpgradeClient().getSupportedFormats();
|
||||
}
|
||||
catch (VcsException e) {
|
||||
LOG.info(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Set<WorkingCopyFormat> getUpgradeFormats(@NotNull WCInfo info, @NotNull List<WorkingCopyFormat> supportedFormats) {
|
||||
Set<WorkingCopyFormat> canUpgradeTo = EnumSet.noneOf(WorkingCopyFormat.class);
|
||||
|
||||
for (WorkingCopyFormat format : supportedFormats) {
|
||||
if (format.isOrGreater(info.getFormat())) {
|
||||
canUpgradeTo.add(format);
|
||||
}
|
||||
}
|
||||
canUpgradeTo.add(info.getFormat());
|
||||
|
||||
return canUpgradeTo;
|
||||
}
|
||||
|
||||
private void mergeFrom(@NotNull final WCInfo wcInfo, @NotNull final VirtualFile root, @Nullable final Component mergeLabel) {
|
||||
SelectBranchPopup.showForBranchRoot(myProject, root, new SelectBranchPopup.BranchSelectedCallback() {
|
||||
@Override
|
||||
@@ -338,8 +370,10 @@ public class CopiesPanel {
|
||||
});
|
||||
}
|
||||
|
||||
private void changeFormat(final WCInfo wcInfo) {
|
||||
private void changeFormat(@NotNull final WCInfo wcInfo, @NotNull final List<WorkingCopyFormat> supportedFormats) {
|
||||
ChangeFormatDialog dialog = new ChangeFormatDialog(myProject, new File(wcInfo.getPath()), false, ! wcInfo.isIsWcRoot());
|
||||
|
||||
dialog.setSupported(supportedFormats);
|
||||
dialog.setData(wcInfo.getFormat());
|
||||
dialog.show();
|
||||
if (! dialog.isOK()) {
|
||||
|
||||
@@ -37,7 +37,6 @@ import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.wc.ISVNEventHandler;
|
||||
import org.tmatesoft.svn.core.wc.SVNEvent;
|
||||
import org.tmatesoft.svn.core.wc.SVNEventAction;
|
||||
import org.tmatesoft.svn.core.wc.SVNWCClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@@ -122,20 +121,7 @@ public class SvnFormatWorker extends Task.Backgroundable {
|
||||
if (supportsChangelists) {
|
||||
myBeforeChangeLists = ChangeListManager.getInstance(myProject).getChangeListsCopy();
|
||||
}
|
||||
final SVNWCClient wcClient = myVcs.createWCClient();
|
||||
wcClient.setEventHandler(new ISVNEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(SVNEvent event, double progress) throws SVNException {
|
||||
if (SVNEventAction.UPGRADED_PATH.equals(event.getAction()) && event.getFile() != null) {
|
||||
indicator.setText2("Upgraded path " + VcsUtil.getPathForProgressPresentation(event.getFile()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCancelled() throws SVNCancelException {
|
||||
indicator.checkCanceled();
|
||||
}
|
||||
});
|
||||
try {
|
||||
for (WCInfo wcInfo : myWcInfos) {
|
||||
File path = new File(wcInfo.getPath());
|
||||
@@ -143,13 +129,13 @@ public class SvnFormatWorker extends Task.Backgroundable {
|
||||
path = SvnUtil.getWorkingCopyRoot(path);
|
||||
}
|
||||
try {
|
||||
if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(myNewFormat)) {
|
||||
indicator.setText(SvnBundle.message("action.Subversion.cleanup.progress.text", path.getAbsolutePath()));
|
||||
wcClient.doCleanup(path);
|
||||
}
|
||||
indicator.setText(SvnBundle.message("action.change.wcopy.format.task.progress.text", path.getAbsolutePath(),
|
||||
SvnUtil.formatRepresentation(wcInfo.getFormat()), SvnUtil.formatRepresentation(myNewFormat)));
|
||||
wcClient.doSetWCFormat(path, myNewFormat.getFormat());
|
||||
String cleanupMessage = SvnBundle.message("action.Subversion.cleanup.progress.text", path.getAbsolutePath());
|
||||
String upgradeMessage = SvnBundle.message("action.change.wcopy.format.task.progress.text", path.getAbsolutePath(),
|
||||
SvnUtil.formatRepresentation(wcInfo.getFormat()),
|
||||
SvnUtil.formatRepresentation(myNewFormat));
|
||||
ISVNEventHandler handler = createUpgradeHandler(indicator, cleanupMessage, upgradeMessage);
|
||||
|
||||
myVcs.getFactory(path).createUpgradeClient().upgrade(path, myNewFormat, handler);
|
||||
} catch (Throwable e) {
|
||||
myExceptions.add(e);
|
||||
}
|
||||
@@ -166,4 +152,32 @@ public class SvnFormatWorker extends Task.Backgroundable {
|
||||
ApplicationManager.getApplication().getMessageBus().syncPublisher(SvnVcs.WC_CONVERTED).run();
|
||||
}
|
||||
}
|
||||
|
||||
private static ISVNEventHandler createUpgradeHandler(@NotNull final ProgressIndicator indicator,
|
||||
@NotNull final String cleanupMessage,
|
||||
@NotNull final String upgradeMessage) {
|
||||
return new ISVNEventHandler() {
|
||||
@Override
|
||||
public void handleEvent(SVNEvent event, double progress) throws SVNException {
|
||||
if (event.getFile() != null) {
|
||||
if (SVNEventAction.UPGRADED_PATH.equals(event.getAction())) {
|
||||
indicator.setText2("Upgraded path " + VcsUtil.getPathForProgressPresentation(event.getFile()));
|
||||
}
|
||||
// fake event indicating cleanup start
|
||||
if (SVNEventAction.UPDATE_STARTED.equals(event.getAction())) {
|
||||
indicator.setText(cleanupMessage);
|
||||
}
|
||||
// fake event indicating upgrade start
|
||||
if (SVNEventAction.UPDATE_COMPLETED.equals(event.getAction())) {
|
||||
indicator.setText(upgradeMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkCancelled() throws SVNCancelException {
|
||||
indicator.checkCanceled();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,8 +60,7 @@ public class CmdRevertClient extends BaseSvnClient implements RevertClient {
|
||||
String statusMessage = matcher.group(1);
|
||||
String path = matcher.group(2);
|
||||
|
||||
return new SVNEvent(new File(path), null, null, 0, null, null, null, null, createAction(statusMessage), null, null, null, null, null,
|
||||
null);
|
||||
return createEvent(new File(path), createAction(statusMessage));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package org.jetbrains.idea.svn.upgrade;
|
||||
|
||||
import com.intellij.execution.process.ProcessOutputTypes;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.WorkingCopyFormat;
|
||||
import org.jetbrains.idea.svn.api.BaseSvnClient;
|
||||
import org.jetbrains.idea.svn.api.FileStatusResultParser;
|
||||
import org.jetbrains.idea.svn.commandLine.CommandUtil;
|
||||
import org.jetbrains.idea.svn.commandLine.LineCommandListener;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnCommandName;
|
||||
import org.tmatesoft.svn.core.wc.ISVNEventHandler;
|
||||
import org.tmatesoft.svn.core.wc.SVNEvent;
|
||||
import org.tmatesoft.svn.core.wc.SVNEventAction;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class CmdUpgradeClient extends BaseSvnClient implements UpgradeClient {
|
||||
|
||||
private static final String STATUS = "\\s*(.+?)\\s*";
|
||||
private static final String PATH = "\\s*\'(.*?)\'\\s*";
|
||||
private static final Pattern CHANGED_PATH = Pattern.compile(STATUS + PATH);
|
||||
|
||||
@Override
|
||||
public void upgrade(@NotNull File path, @NotNull WorkingCopyFormat format, @Nullable ISVNEventHandler handler) throws VcsException {
|
||||
validateFormat(format, getSupportedFormats());
|
||||
|
||||
// fake event indicating upgrade start
|
||||
callHandler(handler, createEvent(path, SVNEventAction.UPDATE_COMPLETED));
|
||||
|
||||
List<String> parameters = new ArrayList<String>();
|
||||
|
||||
CommandUtil.put(parameters, path);
|
||||
|
||||
// TODO: Add general possibility to invoke "handler.checkCancelled" (process should be killed). But currently upgrade process is not
|
||||
// TODO: cancellable from UI - and this makes sense.
|
||||
// for 1.8 - no output
|
||||
// for 1.7 - output in format "Upgraded '<path>'"
|
||||
FileStatusResultParser parser = new FileStatusResultParser(CHANGED_PATH, handler, new UpgradeStatusConvertor());
|
||||
UpgradeLineCommandListener listener = new UpgradeLineCommandListener(parser);
|
||||
|
||||
CommandUtil.execute(myVcs, SvnTarget.fromFile(path), SvnCommandName.upgrade, parameters, listener);
|
||||
listener.throwIfException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WorkingCopyFormat> getSupportedFormats() throws VcsException {
|
||||
List<WorkingCopyFormat> result = new ArrayList<WorkingCopyFormat>();
|
||||
|
||||
result.add(WorkingCopyFormat.from(myFactory.createVersionClient().getVersion()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static class UpgradeStatusConvertor implements Convertor<Matcher, SVNEvent> {
|
||||
|
||||
public SVNEvent convert(@NotNull Matcher matcher) {
|
||||
String statusMessage = matcher.group(1);
|
||||
String path = matcher.group(2);
|
||||
|
||||
return createEvent(new File(path), createAction(statusMessage));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static SVNEventAction createAction(@NotNull String code) {
|
||||
SVNEventAction result = null;
|
||||
|
||||
if ("Upgraded".equals(code)) {
|
||||
result = SVNEventAction.UPGRADED_PATH;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static class UpgradeLineCommandListener extends LineCommandListener {
|
||||
|
||||
@NotNull private final FileStatusResultParser parser;
|
||||
@NotNull private final AtomicReference<VcsException> exception;
|
||||
|
||||
private UpgradeLineCommandListener(@NotNull FileStatusResultParser parser) {
|
||||
this.parser = parser;
|
||||
exception = new AtomicReference<VcsException>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLineAvailable(String line, Key outputType) {
|
||||
if (ProcessOutputTypes.STDOUT.equals(outputType)) {
|
||||
try {
|
||||
parser.onLine(line);
|
||||
}
|
||||
catch (VcsException e) {
|
||||
exception.set(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void throwIfException() throws VcsException {
|
||||
VcsException e = exception.get();
|
||||
|
||||
if (e != null) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.jetbrains.idea.svn.upgrade;
|
||||
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.WorkingCopyFormat;
|
||||
import org.jetbrains.idea.svn.api.BaseSvnClient;
|
||||
import org.jetbrains.idea.svn.checkout.SvnKitCheckoutClient;
|
||||
import org.jetbrains.idea.svn.commandLine.SvnBindException;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.wc.ISVNEventHandler;
|
||||
import org.tmatesoft.svn.core.wc.SVNEventAction;
|
||||
import org.tmatesoft.svn.core.wc.SVNWCClient;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public class SvnKitUpgradeClient extends BaseSvnClient implements UpgradeClient {
|
||||
|
||||
@Override
|
||||
public void upgrade(@NotNull File path, @NotNull WorkingCopyFormat format, @Nullable ISVNEventHandler handler) throws VcsException {
|
||||
validateFormat(format, getSupportedFormats());
|
||||
|
||||
SVNWCClient client = myVcs.createWCClient();
|
||||
|
||||
client.setEventHandler(handler);
|
||||
try {
|
||||
cleanupIfNecessary(path, format, client, handler);
|
||||
upgrade(path, format, client, handler);
|
||||
}
|
||||
catch (SVNException e) {
|
||||
throw new SvnBindException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WorkingCopyFormat> getSupportedFormats() throws VcsException {
|
||||
return SvnKitCheckoutClient.SUPPORTED_FORMATS;
|
||||
}
|
||||
|
||||
private static void cleanupIfNecessary(@NotNull File path,
|
||||
@NotNull WorkingCopyFormat format,
|
||||
@NotNull SVNWCClient client,
|
||||
@Nullable ISVNEventHandler handler) throws SVNException, VcsException {
|
||||
// cleanup is executed only for SVNKit as it could handle both 1.6 and 1.7 formats
|
||||
if (WorkingCopyFormat.ONE_DOT_SEVEN.equals(format)) {
|
||||
// fake event indicating cleanup start
|
||||
callHandler(handler, createEvent(path, SVNEventAction.UPDATE_STARTED));
|
||||
client.doCleanup(path);
|
||||
}
|
||||
}
|
||||
|
||||
private static void upgrade(@NotNull File path,
|
||||
@NotNull WorkingCopyFormat format,
|
||||
@NotNull SVNWCClient client,
|
||||
@Nullable ISVNEventHandler handler) throws SVNException, VcsException {
|
||||
// fake event indicating upgrade start
|
||||
callHandler(handler, createEvent(path, SVNEventAction.UPDATE_COMPLETED));
|
||||
client.doSetWCFormat(path, format.getFormat());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.jetbrains.idea.svn.upgrade;
|
||||
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.svn.WorkingCopyFormat;
|
||||
import org.jetbrains.idea.svn.api.SvnClient;
|
||||
import org.tmatesoft.svn.core.wc.ISVNEventHandler;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Konstantin Kolosovsky.
|
||||
*/
|
||||
public interface UpgradeClient extends SvnClient {
|
||||
|
||||
void upgrade(@NotNull File path, @NotNull WorkingCopyFormat format, @Nullable ISVNEventHandler handler) throws VcsException;
|
||||
|
||||
List<WorkingCopyFormat> getSupportedFormats() throws VcsException;
|
||||
}
|
||||
Reference in New Issue
Block a user