Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Side by Side Diff: appengine/findit/common/local_git_repository.py

Issue 2432113002: [Findit] Add local_git_repository (Closed)
Patch Set: . Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import logging
6 import os
7 import subprocess
8 import threading
9
10 from common import local_git_parsers
11 from common import repo_util
12 from common.repository import Repository
13
14 _CHANGELOG_FORMAT_STRING = ('commit %H%n'
15 'author %an%n'
16 'author-mail %ae%n'
17 'author-time %at%n%n'
18 'committer %cn%n'
19 'committer-mail %ce%n'
20 'committer-time %ct%n%n'
21 '--Message start--%n%B%n--Message end--%n')
22 _CHANGELOGS_FORMAT_STRING = ('**Changelog start**%%n%s' %
23 _CHANGELOG_FORMAT_STRING)
24 CHECKOUT_ROOT_DIR = os.path.join(os.path.expanduser('~'), '.local_checkouts')
25
26
27 class LocalGitRepository(Repository):
28 """Represents local checkout of git repository on chromium host.
29
30 Note, to checkout internal repos automatically which you have access to,
31 follow the instructions in ('https://g3doc.corp.google.com/company/teams/
32 chrome/chrome_build_instructions.md?
33 cl=head#authentication-to-git-servers-chrome-internalgooglesourcecom') first.
34 """
35 lock = threading.Lock()
36 # Keep track all the updated repos, so every repo only get updated once.
37 updated_repos = set()
38 def __init__(self, repo_url=None):
39 self._repo_path = None
40 self._repo_url = None
41 self.repo_url = repo_url
42
43 @property
44 def repo_path(self):
45 return self._repo_path
46
47 @property
48 def repo_url(self):
49 return self._repo_url
50
51 @repo_url.setter
52 def repo_url(self, repo_url):
53 if not repo_url or (hasattr(self, '_repo_url') and
stgao 2016/10/22 00:43:35 Why hasattr is needed? Isn't self._repo_url alread
Sharu Jiang 2016/10/25 06:45:16 Oops, should have deleted.
54 self._repo_url == repo_url):
55 return
56
57 self._repo_url = repo_url
58 http_trimmed_url = repo_url.split('https://', 1)[1]
59 host_trimmed_url = '/'.join(http_trimmed_url.split('/')[1:])
60
61 self._repo_path = host_trimmed_url
62 self._CloneOrUpdateRepoIfNeeded()
63
64 def _CloneOrUpdateRepoIfNeeded(self):
65 """Clones repo, or update it if it didn't got updated before."""
66 if self.repo_url in LocalGitRepository.updated_repos:
67 return
68
69 real_repo_path = os.path.join(CHECKOUT_ROOT_DIR, self.repo_path)
70 with LocalGitRepository.lock:
71 # Clone the repo if needed.
72 if not os.path.exists(real_repo_path):
73 subprocess.call(['git', 'clone', self.repo_url, real_repo_path])
74 # Update repo if it's already cloned.
75 else:
76 # Disable verbose of git pull.
77 with open(os.devnull, 'w') as null_handle:
78 subprocess.check_call(
79 'cd %s; git pull' % real_repo_path,
80 stdout=null_handle,
81 stderr=null_handle,
82 shell=True)
83
84 LocalGitRepository.updated_repos.add(self.repo_url)
85
86 def _GetLocalGitCommandOutput(self, command):
87 """Gets the output stream of a git command for a local git repo.
88
89 If the corresponding git repo_path is not downloaded yet, download it from
90 https://chromium.googlesource.com.
91
92 Args:
93 command (str): Command to execute at this repo to get output.
94
95 Return:
96 Output steam of the git command.
97 """
98 real_repo_path = os.path.join(CHECKOUT_ROOT_DIR, self.repo_path)
99 command = 'cd %s; %s' % (real_repo_path, command)
100 p = subprocess.Popen(
101 command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
102 return p.communicate()[0]
103
104 def GetChangeLog(self, revision):
105 """Returns the change log of the given revision."""
106 command = ('git log --pretty=format:"%s" --max-count=1 --raw '
107 '--no-abbrev %s' % (_CHANGELOG_FORMAT_STRING, revision))
108 output = self._GetLocalGitCommandOutput(command)
109 change_log = local_git_parsers.GitChangeLogParser()(output)
110 change_log.commit_url = '%s/+/%s' % (self.repo_url, change_log.revision)
111 return change_log
112
113 def GetChangeLogs(self, start_revision, end_revision): # pylint: disable=W
114 """Returns change log list in (start_revision, end_revision]."""
115 command = ('git log --pretty=format:"%s" --raw '
116 '--no-abbrev %s' % (_CHANGELOGS_FORMAT_STRING,
117 '%s..%s' % (start_revision, end_revision)))
118 output = self._GetLocalGitCommandOutput(command)
119 return local_git_parsers.GitChangeLogsParser()(output)
120
121 def GetChangeDiff(self, revision, path=None): # pylint: disable=W
122 """Returns the diff of the given revision."""
123 command = 'git log --format="" --max-count=1 %s' % revision
124 if path:
125 command += ' -p %s' % path
126 output = self._GetLocalGitCommandOutput(command)
127 return local_git_parsers.GitDiffParser()(output)
128
129 def GetBlame(self, path, revision):
130 """Returns blame of the file at ``path`` of the given revision."""
131 command = 'git blame --porcelain %s %s' % (path, revision)
132 output = self._GetLocalGitCommandOutput(command, path)
133 return local_git_parsers.GitBlameParser()(output)
134
135 def GetSource(self, path, revision):
136 """Returns source code of the file at ``path`` of the given revision."""
137 # Check whether the requested file exist or not.
138 if not os.path.isfile(os.path.join(
139 os.path.join(CHECKOUT_ROOT_DIR, self.repo_path),
140 path)):
141 return None
142
143 command = 'git show %s:%s' % (revision, path)
144 output = self._GetLocalGitCommandOutput(command, path)
145 return local_git_parsers.GitSourceParser()(output)
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/common/repo_util.py » ('j') | appengine/findit/common/repo_util.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698