1 // Copyright 2008-2010 Victor Iacoban
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software distributed under
10 // the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11 // either express or implied. See the License for the specific language governing permissions and
12 // limitations under the License.
13 package org.zmlx.hg4idea.command;
15 import com.intellij.openapi.diagnostic.Logger;
16 import com.intellij.openapi.project.Project;
17 import com.intellij.openapi.vcs.FilePath;
18 import com.intellij.openapi.vfs.VirtualFile;
19 import com.intellij.vcsUtil.VcsFileUtil;
20 import org.apache.commons.lang.StringUtils;
21 import org.jetbrains.annotations.Nullable;
22 import org.zmlx.hg4idea.HgChange;
23 import org.zmlx.hg4idea.HgFile;
24 import org.zmlx.hg4idea.HgFileStatusEnum;
25 import org.zmlx.hg4idea.HgRevisionNumber;
26 import org.zmlx.hg4idea.execution.HgCommandExecutor;
27 import org.zmlx.hg4idea.execution.HgCommandResult;
32 public class HgStatusCommand {
34 private static final Logger LOG = Logger.getInstance(HgStatusCommand.class.getName());
36 private static final int ITEM_COUNT = 3;
37 private static final int STATUS_INDEX = 0;
39 private final Project project;
41 private boolean includeAdded = true;
42 private boolean includeModified = true;
43 private boolean includeRemoved = true;
44 private boolean includeDeleted = true;
45 private boolean includeUnknown = true;
46 private boolean includeIgnored = true;
47 private boolean includeCopySource = true;
48 private HgRevisionNumber baseRevision;
49 private HgRevisionNumber targetRevision;
51 public HgStatusCommand(Project project) {
52 this.project = project;
55 public void setIncludeAdded(boolean includeAdded) {
56 this.includeAdded = includeAdded;
59 public void setIncludeModified(boolean includeModified) {
60 this.includeModified = includeModified;
63 public void setIncludeRemoved(boolean includeRemoved) {
64 this.includeRemoved = includeRemoved;
67 public void setIncludeDeleted(boolean includeDeleted) {
68 this.includeDeleted = includeDeleted;
71 public void setIncludeUnknown(boolean includeUnknown) {
72 this.includeUnknown = includeUnknown;
75 public void setIncludeIgnored(boolean includeIgnored) {
76 this.includeIgnored = includeIgnored;
79 public void setIncludeCopySource(boolean includeCopySource) {
80 this.includeCopySource = includeCopySource;
83 public void setBaseRevision(HgRevisionNumber base) {
87 public void setTargetRevision(HgRevisionNumber target) {
88 targetRevision = target;
91 public Set<HgChange> execute(VirtualFile repo) {
92 return execute(repo, null);
95 public Set<HgChange> execute(VirtualFile repo, @Nullable Collection<FilePath> paths) {
97 return Collections.emptySet();
100 HgCommandExecutor executor = new HgCommandExecutor(project);
101 executor.setSilent(true);
103 List<String> options = new LinkedList<String>();
105 options.add("--added");
107 if (includeModified) {
108 options.add("--modified");
110 if (includeRemoved) {
111 options.add("--removed");
113 if (includeDeleted) {
114 options.add("--deleted");
116 if (includeUnknown) {
117 options.add("--unknown");
119 if (includeIgnored) {
120 options.add("--ignored");
122 if (includeCopySource) {
123 options.add("--copies");
125 if (baseRevision != null) {
126 options.add("--rev");
127 options.add(baseRevision.getChangeset());
128 if (targetRevision != null) {
129 options.add("--rev");
130 options.add(targetRevision.getChangeset());
134 final Set<HgChange> changes = new HashSet<HgChange>();
137 final List<List<String>> chunked = VcsFileUtil.chunkPaths(repo, paths);
138 for (List<String> chunk : chunked) {
139 List<String> args = new ArrayList<String>();
140 args.addAll(options);
142 HgCommandResult result = executor.executeInCurrentThread(repo, "status", args);
143 changes.addAll(parseChangesFromResult(repo, result));
146 HgCommandResult result = executor.executeInCurrentThread(repo, "status", options);
147 changes.addAll(parseChangesFromResult(repo, result));
152 private static Collection<HgChange> parseChangesFromResult(VirtualFile repo, HgCommandResult result) {
153 final Set<HgChange> changes = new HashSet<HgChange>();
154 HgChange previous = null;
155 if (result == null) {
158 for (String line : result.getOutputLines()) {
159 if (StringUtils.isBlank(line) || line.length() < ITEM_COUNT) {
160 LOG.warn("Unexpected line in status '" + line + '\'');
163 HgFileStatusEnum status = HgFileStatusEnum.valueOf(line.charAt(STATUS_INDEX));
164 File ioFile = new File(repo.getPath(), line.substring(2));
165 if (HgFileStatusEnum.COPY == status && previous != null
166 && previous.getStatus() == HgFileStatusEnum.ADDED) {
167 previous.setStatus(HgFileStatusEnum.COPY);
168 previous.setBeforeFile(new HgFile(repo, ioFile));
171 previous = new HgChange(new HgFile(repo, ioFile), status);
172 changes.add(previous);