/* * Copyright 2015 Ritesh Kapoor * * 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 com.ritesh.idea.plugin.diff; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.VcsDataKeys; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.ChangeList; import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; import com.intellij.openapi.vfs.VirtualFile; import org.jetbrains.idea.svn.SvnVcs; import org.jetbrains.idea.svn.api.BaseSvnClient; import org.jetbrains.idea.svn.commandLine.Command; import org.jetbrains.idea.svn.commandLine.CommandExecutor; import org.jetbrains.idea.svn.commandLine.SvnCommandName; import org.jetbrains.idea.svn.history.LogEntry; import org.jetbrains.idea.svn.history.LogEntryConsumer; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.wc.SVNRevision; import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * @author ritesh */ public class SvnDiffProvider extends BaseSvnClient implements IVcsDiffProvider { private static final Logger LOG = Logger.getInstance(SvnDiffProvider.class); @Override public boolean isFromRevision(Project project, AnActionEvent action) throws VcsException { ChangeList[] data = action.getData(VcsDataKeys.CHANGE_LISTS); if (data != null && data.length > 0 && data[0] instanceof CommittedChangeList) { return true; } else { return false; } } @Override public String generateDiff(Project project, AnActionEvent action) throws VcsException { String diffContent; if (isFromRevision(project, action)) { ChangeList[] data = action.getData(VcsDataKeys.CHANGE_LISTS); diffContent = fromRevisions(project, project.getBaseDir(), ((CommittedChangeList) data[data.length - 1]).getNumber(), ((CommittedChangeList) data[0]).getNumber()); } else { final Change[] changes = action.getData(VcsDataKeys.CHANGES); diffContent = fromHead(project, project.getBaseDir(), changes); } return diffContent; } private String fromRevisions(Project project, VirtualFile root, long beforeRevisionNumber, long afterRevisionNumber) throws VcsException { SvnVcs svnVcs = SvnVcs.getInstance(project); SvnTarget svnTarget = SvnTarget.fromFile(new File(root.getPath())); final long[] lastRevisionNumber = new long[1]; svnVcs.getFactory().createHistoryClient().doLog(svnTarget, SVNRevision.create(beforeRevisionNumber) , SVNRevision.create(0), false, true, false, 2, null, new LogEntryConsumer() { @Override public void consume(LogEntry logEntry) throws SVNException { lastRevisionNumber[0] = logEntry.getRevision(); } }); List<String> parameters = Arrays.asList("-r", lastRevisionNumber[0] + ":" + afterRevisionNumber, "--patch-compatible"); Command command = new Command(SvnCommandName.diff); command.setWorkingDirectory(new File(root.getPath())); command.setTarget(svnTarget); command.put(parameters); LOG.info("Executing svn command : Parameters : " + parameters + " ,target :" + svnTarget); CommandExecutor commandExecutor = newRuntime(svnVcs).runWithAuthenticationAttempt(command); String output = commandExecutor.getBinaryOutput().toString(); return output; } private String fromHead(Project project, VirtualFile root, Change[] changes) throws VcsException { //TODO: publish only selected changes attribute (need to handle deleted files) SvnVcs svnVcs = SvnVcs.getInstance(project); SvnTarget svnTarget = SvnTarget.fromFile(new File(root.getPath())); List<String> parameters = new ArrayList<>(); /*for (Change change : changes) { if (change.getVirtualFile() != null) { String path = new File(root.getPath()).toURI() .relativize(new File(change.getVirtualFile().getPath()).toURI()).getPath(); parameters.add(path); } }*/ parameters.add("-r"); parameters.add("HEAD"); parameters.add("--patch-compatible"); Command command = new Command(SvnCommandName.diff); command.setWorkingDirectory(new File(root.getPath())); command.setTarget(svnTarget); command.put(parameters); LOG.info("Executing svn command : Parameters : " + parameters + " ,target :" + svnTarget); CommandExecutor commandExecutor = newRuntime(svnVcs).runWithAuthenticationAttempt(command); String output = commandExecutor.getBinaryOutput().toString(); return output; } }