package zielu.gittoolbox.tag; import com.google.common.base.Preconditions; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; import git4idea.GitUtil; import git4idea.commands.Git; import git4idea.commands.GitCommand; import git4idea.commands.GitCommandResult; import git4idea.commands.GitLineHandler; import git4idea.commands.GitLineHandlerListener; import git4idea.commands.GitStandardProgressAnalyzer; import git4idea.repo.GitBranchTrackInfo; import git4idea.repo.GitRemote; import git4idea.repo.GitRepository; import java.util.Optional; import org.jetbrains.annotations.NotNull; import zielu.gittoolbox.ResBundle; import zielu.gittoolbox.push.GitPushRejectedDetector; import zielu.gittoolbox.push.GtPushResult; public class GitTagsPusher { private final Project myProject; private final ProgressIndicator myProgress; private final Git myGit; private GitTagsPusher(Project project, ProgressIndicator progress) { myProject = project; myProgress = progress; myGit = ServiceManager.getService(Git.class); } public static GitTagsPusher create(@NotNull Project project, @NotNull ProgressIndicator progress) { return new GitTagsPusher(Preconditions.checkNotNull(project), Preconditions.checkNotNull(progress)); } @NotNull public GtPushResult push(@NotNull TagsPushSpec pushSpec) { Preconditions.checkNotNull(pushSpec); GitRepository repository = GitUtil.getRepositoryManager(myProject).getRepositoryForRoot(pushSpec.gitRoot()); Optional<GitBranchTrackInfo> trackInfo = Optional.ofNullable(GitUtil.getTrackInfoForCurrentBranch(repository)); if (trackInfo.isPresent()) { GitRemote remote = trackInfo.get().getRemote(); Optional<String> url = Optional.ofNullable(remote.getFirstUrl()); if (url.isPresent()) { return push(pushSpec, repository, remote, url.get()); } else { return GtPushResult.error(ResBundle.message("message.no.remote.url", remote.getName())); } } else { return GtPushResult.error(ResBundle.getString("message.cannot.push.without.tracking")); } } private GtPushResult push(final TagsPushSpec pushSpec, final GitRepository repository, final GitRemote remote, final String url) { final GitLineHandlerListener progressListener = GitStandardProgressAnalyzer.createListener(myProgress); final GitPushRejectedDetector rejectedDetector = new GitPushRejectedDetector(); GitCommandResult result = myGit.runCommand(new Computable<GitLineHandler>() { @Override public GitLineHandler compute() { final GitLineHandler h = new GitLineHandler(repository.getProject(), repository.getRoot(), GitCommand.PUSH); h.setUrl(url); h.setSilent(false); h.setStdoutSuppressed(false); h.addLineListener(progressListener); h.addLineListener(rejectedDetector); h.addProgressParameter(); h.addParameters(remote.getName()); h.addParameters(pushSpec.specs()); return h; } }); if (rejectedDetector.rejected()) { return GtPushResult.reject(rejectedDetector.getRejectedBranches()); } else { return translate(result); } } private GtPushResult translate(GitCommandResult result) { if (result.success()) { return GtPushResult.success(); } else if (result.cancelled()) { return GtPushResult.cancel(); } else { return GtPushResult.error(result.getErrorOutputAsJoinedString()); } } }