Eclipseplugins
RepositoryTools.java
1 package com.proalpha.pds.gitutils.checks;
2 
3 import java.io.IOException;
4 import java.nio.file.Paths;
5 import java.util.ArrayList;
6 import java.util.Collections;
7 import java.util.List;
8 import java.util.regex.Matcher;
9 
10 import org.eclipse.core.commands.ExecutionEvent;
11 import org.eclipse.core.commands.ExecutionException;
12 import org.eclipse.core.resources.IProject;
13 import org.eclipse.core.resources.ResourcesPlugin;
14 import org.eclipse.egit.ui.internal.repository.tree.RepositoryTreeNode;
15 import org.eclipse.jface.viewers.ISelection;
16 import org.eclipse.jface.viewers.IStructuredSelection;
17 import org.eclipse.jgit.api.Git;
18 import org.eclipse.jgit.api.Status;
19 import org.eclipse.jgit.api.errors.GitAPIException;
20 import org.eclipse.jgit.diff.DiffEntry;
21 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
22 import org.eclipse.jgit.errors.MissingObjectException;
23 import org.eclipse.jgit.errors.NoWorkTreeException;
24 import org.eclipse.jgit.lib.ObjectReader;
25 import org.eclipse.jgit.lib.Ref;
26 import org.eclipse.jgit.lib.Repository;
27 import org.eclipse.jgit.revwalk.RevCommit;
28 import org.eclipse.jgit.revwalk.RevTree;
29 import org.eclipse.jgit.revwalk.RevWalk;
30 import org.eclipse.jgit.treewalk.AbstractTreeIterator;
31 import org.eclipse.jgit.treewalk.CanonicalTreeParser;
32 import org.eclipse.ui.handlers.HandlerUtil;
33 
34 import com.proalpha.git.util.PaRepository;
35 import com.proalpha.pds.gitutils.Activator;
36 import com.proalpha.pds.paconnector.PaProject;
37 
38 @SuppressWarnings("restriction")
39 public class RepositoryTools {
40 
41  private Repository repository = null;
42 
43  public RepositoryTools(Repository repository) {
44  this.repository = repository;
45  }
46 
47  public RepositoryTools(ExecutionEvent event) {
48  RepositoryTreeNode<?> treenode = null;
49  try {
50  treenode = (RepositoryTreeNode<?>) getSelectedNodes(event).get(0);
51  } catch (ExecutionException e) {
52  Activator.logToConsole(String.format("Error in Constructor of class RepositoryTools: %s", e.getMessage()));
53  }
54  if (treenode != null) {
55  repository = treenode.getRepository();
56  }
57  }
58 
59  public List<?> getSelectedNodes(ExecutionEvent event) throws ExecutionException {
60  ISelection selection = HandlerUtil.getCurrentSelectionChecked(event);
61  if (selection instanceof IStructuredSelection)
62  return ((IStructuredSelection) selection).toList();
63  else {
64  Activator.logToConsole(String.format(
65  "Event %s is no instance of IStructuredSelection. Returning empty list.", event.toString()));
66  return Collections.emptyList();
67  }
68  }
69 
70  public List<String> getStagedFiles() {
71 
72  Status status = null;
73  List<String> stagesFiles = new ArrayList<>();
74 
75  try (Git git = new Git(repository)) {
76  status = git.status().call();
77 
78  for (String file : status.getChanged()) {
79  if (file.contains("/")) {
80  stagesFiles.add(file.substring(file.lastIndexOf('/') + 1));
81  } else {
82  stagesFiles.add(file);
83  }
84  }
85 
86  for (String file : status.getAdded()) {
87  if (file.contains("/")) {
88  stagesFiles.add(file.substring(file.lastIndexOf('/') + 1));
89  } else {
90  stagesFiles.add(file);
91  }
92  }
93 
94  for (String file : status.getRemoved()) {
95 
96  if (file.contains("/")) {
97  stagesFiles.add(file.substring(file.lastIndexOf('/') + 1));
98  } else {
99  stagesFiles.add(file);
100  }
101  }
102  } catch (NoWorkTreeException | GitAPIException e) {
103  Activator.logToConsole(String.format("Error in Method getStagedFiles: %s", e.getMessage()));
104  return Collections.emptyList();
105  }
106 
107  return stagesFiles;
108  }
109 
110  public List<String> getUnstagedFiles() {
111 
112  Status status = null;
113  List<String> unStagesFiles = new ArrayList<>();
114 
115  try (Git git = new Git(repository)) {
116  status = git.status().call();
117 
118  for (String file : status.getUntracked()) {
119  if (file.contains("/")) {
120  unStagesFiles.add(file.substring(file.lastIndexOf('/') + 1));
121  } else {
122  unStagesFiles.add(file);
123  }
124  }
125 
126  for (String file : status.getModified()) {
127  if (file.contains("/")) {
128  unStagesFiles.add(file.substring(file.lastIndexOf('/') + 1));
129  } else {
130  unStagesFiles.add(file);
131  }
132  }
133 
134  for (String file : status.getConflicting()) {
135  if (file.contains("/")) {
136  unStagesFiles.add(file.substring(file.lastIndexOf('/') + 1));
137  } else {
138  unStagesFiles.add(file);
139  }
140  }
141 
142  for (String file : status.getMissing()) {
143  if (file.contains("/")) {
144  unStagesFiles.add(file.substring(file.lastIndexOf('/') + 1));
145  } else {
146  unStagesFiles.add(file);
147  }
148  }
149  } catch (NoWorkTreeException | GitAPIException e) {
150  Activator.logToConsole(String.format("Error in Method getUnstagedFiles: %s", e.getMessage()));
151  return Collections.emptyList();
152  }
153 
154  return unStagesFiles;
155  }
156 
157  public List<String> getChangedFilesWithPath() {
158 
159  Status status = null;
160  List<String> changedFiles = new ArrayList<>();
161 
162  try (Git git = new Git(repository)) {
163  status = git.status().call();
164 
165  for (String file : status.getModified()) {
166 
167  if (file.contains("src/")) {
168  changedFiles.add(file.substring(file.lastIndexOf("src/") + 4));
169  } else {
170  changedFiles.add(file);
171  }
172  }
173 
174  for (String file : status.getConflicting()) {
175 
176  if (file.contains("src/")) {
177  changedFiles.add(file.substring(file.lastIndexOf("src/") + 4));
178  } else {
179  changedFiles.add(file);
180  }
181  }
182  for (String file : status.getAdded()) {
183 
184  if (file.contains("src/")) {
185  changedFiles.add(file.substring(file.lastIndexOf("src/") + 4));
186  } else {
187  changedFiles.add(file);
188  }
189  }
190  } catch (NoWorkTreeException | GitAPIException e) {
191  Activator.logToConsole(String.format("Error in Method getChangedFilesWithPath: %s", e.getMessage()));
192  return Collections.emptyList();
193  }
194 
195  return changedFiles;
196  }
197 
198  public String getDirectory() {
199  return this.repository.getDirectory().getPath();
200  }
201 
202  public String getBranch() {
203  try {
204  return this.repository.getBranch();
205  } catch (IOException e) {
206  Activator.logToConsole(String.format("Error in Method getBranch: %s", e.getMessage()));
207  return "";
208  }
209  }
210 
211  public PaProject getPaProject() {
212 
213  long countSeparator = repository.getDirectory().getAbsolutePath().codePoints()
214  .filter(ch -> ch == System.getProperty("file.separator").toCharArray()[0]).count();
215  String[] filePathArray = repository.getDirectory().getAbsolutePath()
216  .split(Matcher.quoteReplacement(System.getProperty("file.separator")));
217  IProject project = null;
218 
219  if (countSeparator > 3) {
220  project = ResourcesPlugin.getWorkspace().getRoot().getProject(
221  filePathArray[filePathArray.length - 4] + "-" + filePathArray[filePathArray.length - 3]);
222  } else {
223  project = ResourcesPlugin.getWorkspace().getRoot().getProject(
224  filePathArray[filePathArray.length - 2] + "-" + filePathArray[filePathArray.length - 1]);
225  }
226 
227  return com.proalpha.pds.paconnector.Activator.getDefault().getProjectManager().getPaProject(project);
228 
229  }
230 
231  public List<String> getBranchDiffFiles() {
232 
233  // get the diff files between current branch and Master HEAD commit
234 
235  try {
236  // get current branch
237  String branch = extendBanchName(getBranch());
238  // default for the master branch
239  String master_branch = extendBanchName(this.getMasterBranch());
240 
241  AbstractTreeIterator oldTreeParser = prepareTreeParser(repository, branch);
242  AbstractTreeIterator newTreeParser = prepareTreeParser(repository, master_branch);
243 
244  return getTreeDiffs(oldTreeParser, newTreeParser);
245 
246  } catch (IOException e) {
247  Activator.logToConsole(String.format("Error in Method getBranchDiffFiles: %s", e.getMessage()));
248  // return empty list
249  return Collections.emptyList();
250  }
251  }
252 
253  public List<String> getBranchesDiffs(String branch1, String branch2) {
254  try {
255  // get the differences between given branches
256  AbstractTreeIterator oldTreeParser = prepareTreeParser(repository, branch1);
257  AbstractTreeIterator newTreeParser = prepareTreeParser(repository, branch2);
258 
259  return getTreeDiffs(oldTreeParser, newTreeParser);
260 
261  } catch (IOException e) {
262  Activator.logToConsole(String.format("Error in Method getBranchesDiffs: %s", e.getMessage()));
263  // return empty list
264  return Collections.emptyList();
265  }
266  }
267 
268  private List<String> getTreeDiffs(AbstractTreeIterator oldTreeParser, AbstractTreeIterator newTreeParser) {
269  // if one of tree parser is null branch not found. Return a empty list
270  if (oldTreeParser == null || newTreeParser == null)
271  return Collections.emptyList();
272  // create a result list
273  List<DiffEntry> diff;
274  // get the diffs from both tree parser
275  try (Git git = new Git(repository)) {
276 
277  diff = git.diff().setOldTree(oldTreeParser).setNewTree(newTreeParser).call();
278 
279  } catch (GitAPIException e) {
280  Activator.logToConsole(String.format("Error in Method getTreeDiffs: %s" + e.getMessage()));
281  return Collections.emptyList();
282  }
283  List<String> changedFiles = new ArrayList<>();
284 
285  // go over all changed Files
286  for (DiffEntry entry : diff) {
287 
288  // get state of change
289  String change_type = entry.getChangeType().toString();
290 
291  // use new path with changed or new files
292  if (change_type.equals("ADD") || change_type.equals("MODIFY"))
293  changedFiles.add(Paths.get(entry.getNewPath()).getFileName().toString());
294  else
295  // use old path with deleted files
296  changedFiles.add(Paths.get(entry.getOldPath()).getFileName().toString());
297  }
298 
299  return changedFiles;
300  }
301 
302  private static AbstractTreeIterator prepareTreeParser(Repository repository, String branch) throws IOException {
303 
304  // initialize the tree parser with the current commit of a Branch
305 
306  // get the reference of current branch
307  Ref branchref = repository.exactRef(branch);
308 
309  // if branch reference is valid
310  if (branchref != null) {
311 
312  try (RevWalk walk = new RevWalk(repository)) {
313  RevCommit commit = walk.parseCommit(branchref.getObjectId());
314  RevTree tree = walk.parseTree(commit.getTree().getId());
315 
316  CanonicalTreeParser cronTreeParser = new CanonicalTreeParser();
317  try (ObjectReader reader = repository.newObjectReader()) {
318  cronTreeParser.reset(reader, tree.getId());
319  }
320 
321  walk.dispose();
322 
323  return cronTreeParser;
324  }
325  } else {
326  Activator.logToConsole(String.format("Branch not found: %s", branch));
327  return null;
328  }
329 
330  }
331 
332  private AbstractTreeIterator getTreeParserbyCommit(RevCommit commit)
333  throws MissingObjectException, IncorrectObjectTypeException, IOException {
334  // initialize the tree parser with the given commit id
335  if (commit != null) {
336  try (RevWalk walk = new RevWalk(repository)) {
337  RevTree tree = walk.parseTree(commit.getTree().getId());
338 
339  CanonicalTreeParser cronTreeParser = new CanonicalTreeParser();
340  try (ObjectReader reader = repository.newObjectReader()) {
341  cronTreeParser.reset(reader, tree.getId());
342  }
343 
344  walk.dispose();
345 
346  return cronTreeParser;
347  }
348  } else {
349  Activator.logToConsole("commit is null. can not init Tree parser");
350  return null;
351  }
352 
353  }
354 
355  public String extendBanchName(String branch) {
356  if (!branch.startsWith("refs/heads/"))
357  branch = "refs/heads/" + branch;
358  return branch;
359  }
360 
361  private RevCommit getCurrentBranchCommit(String branchName) throws IOException {
362 
363  Ref branchref = repository.exactRef(branchName);
364 
365  // get the start commit of a Branch
366  if (branchref != null) {
367 
368  try (RevWalk walk = new RevWalk(repository)) {
369  return walk.parseCommit(branchref.getObjectId());
370  }
371 
372  } else
373  return null;
374 
375  }
376 
377  public String getMasterBranch() {
378  List<String> branches = PaRepository.getMasterBranches(this.repository);
379 
380  // same code in gitutils CherryPickPage
381  String mainBranch = null;
382 
383  if (branches != null && !branches.isEmpty())
384  mainBranch = branches.get(0);
385  else {
386  branches = PaRepository.getCodeFreezeBranches(this.repository);
387  if (branches != null && !branches.isEmpty())
388  mainBranch = branches.get(0);
389  }
390 
391  return mainBranch;
392 
393  }
394 
395  public Repository getRepository() {
396  // return the repository object
397  return this.repository;
398  }
399 }