Fix blank line issues reported by flake8

- E301 expected 1 blank line
- E302 expected 2 blank lines
- E303 too many blank lines
- E305 expected 2 blank lines after class or function definition
- E306 expected 1 blank line before a nested definition

Fixed automatically with autopep8:

  git ls-files | grep py$ | xargs autopep8 --in-place \
    --select E301,E302,E303,E305,E306

Manually fix issues in project.py caused by misuse of block comments.

Change-Id: Iee840fcaff48aae504ddac9c3e76d2acd484f6a9
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/254599
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: David Pursehouse <dpursehouse@collab.net>
This commit is contained in:
David Pursehouse 2020-02-12 15:20:19 +09:00
parent abdf750061
commit 819827a42d
43 changed files with 148 additions and 12 deletions

View File

@ -84,6 +84,7 @@ def _Color(fg=None, bg=None, attr=None):
code = '' code = ''
return code return code
DEFAULT = None DEFAULT = None

View File

@ -236,6 +236,7 @@ class InteractiveCommand(Command):
"""Command which requires user interaction on the tty and """Command which requires user interaction on the tty and
must not run within a pager, even if the user asks to. must not run within a pager, even if the user asks to.
""" """
def WantPager(self, _opt): def WantPager(self, _opt):
return False return False
@ -244,6 +245,7 @@ class PagedCommand(Command):
"""Command which defaults to output in a pager, as its """Command which defaults to output in a pager, as its
display tends to be larger than one screen full. display tends to be larger than one screen full.
""" """
def WantPager(self, _opt): def WantPager(self, _opt):
return True return True

View File

@ -24,6 +24,7 @@ import tempfile
from error import EditorError from error import EditorError
import platform_utils import platform_utils
class Editor(object): class Editor(object):
"""Manages the user's preferred text editor.""" """Manages the user's preferred text editor."""

View File

@ -14,21 +14,26 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
class ManifestParseError(Exception): class ManifestParseError(Exception):
"""Failed to parse the manifest file. """Failed to parse the manifest file.
""" """
class ManifestInvalidRevisionError(Exception): class ManifestInvalidRevisionError(Exception):
"""The revision value in a project is incorrect. """The revision value in a project is incorrect.
""" """
class ManifestInvalidPathError(Exception): class ManifestInvalidPathError(Exception):
"""A path used in <copyfile> or <linkfile> is incorrect. """A path used in <copyfile> or <linkfile> is incorrect.
""" """
class NoManifestException(Exception): class NoManifestException(Exception):
"""The required manifest does not exist. """The required manifest does not exist.
""" """
def __init__(self, path, reason): def __init__(self, path, reason):
super(NoManifestException, self).__init__() super(NoManifestException, self).__init__()
self.path = path self.path = path
@ -37,9 +42,11 @@ class NoManifestException(Exception):
def __str__(self): def __str__(self):
return self.reason return self.reason
class EditorError(Exception): class EditorError(Exception):
"""Unspecified error from the user's text editor. """Unspecified error from the user's text editor.
""" """
def __init__(self, reason): def __init__(self, reason):
super(EditorError, self).__init__() super(EditorError, self).__init__()
self.reason = reason self.reason = reason
@ -47,9 +54,11 @@ class EditorError(Exception):
def __str__(self): def __str__(self):
return self.reason return self.reason
class GitError(Exception): class GitError(Exception):
"""Unspecified internal error from git. """Unspecified internal error from git.
""" """
def __init__(self, command): def __init__(self, command):
super(GitError, self).__init__() super(GitError, self).__init__()
self.command = command self.command = command
@ -57,9 +66,11 @@ class GitError(Exception):
def __str__(self): def __str__(self):
return self.command return self.command
class UploadError(Exception): class UploadError(Exception):
"""A bundle upload to Gerrit did not succeed. """A bundle upload to Gerrit did not succeed.
""" """
def __init__(self, reason): def __init__(self, reason):
super(UploadError, self).__init__() super(UploadError, self).__init__()
self.reason = reason self.reason = reason
@ -67,9 +78,11 @@ class UploadError(Exception):
def __str__(self): def __str__(self):
return self.reason return self.reason
class DownloadError(Exception): class DownloadError(Exception):
"""Cannot download a repository. """Cannot download a repository.
""" """
def __init__(self, reason): def __init__(self, reason):
super(DownloadError, self).__init__() super(DownloadError, self).__init__()
self.reason = reason self.reason = reason
@ -77,9 +90,11 @@ class DownloadError(Exception):
def __str__(self): def __str__(self):
return self.reason return self.reason
class NoSuchProjectError(Exception): class NoSuchProjectError(Exception):
"""A specified project does not exist in the work tree. """A specified project does not exist in the work tree.
""" """
def __init__(self, name=None): def __init__(self, name=None):
super(NoSuchProjectError, self).__init__() super(NoSuchProjectError, self).__init__()
self.name = name self.name = name
@ -93,6 +108,7 @@ class NoSuchProjectError(Exception):
class InvalidProjectGroupsError(Exception): class InvalidProjectGroupsError(Exception):
"""A specified project is not suitable for the specified groups """A specified project is not suitable for the specified groups
""" """
def __init__(self, name=None): def __init__(self, name=None):
super(InvalidProjectGroupsError, self).__init__() super(InvalidProjectGroupsError, self).__init__()
self.name = name self.name = name
@ -102,15 +118,18 @@ class InvalidProjectGroupsError(Exception):
return 'in current directory' return 'in current directory'
return self.name return self.name
class RepoChangedException(Exception): class RepoChangedException(Exception):
"""Thrown if 'repo sync' results in repo updating its internal """Thrown if 'repo sync' results in repo updating its internal
repo or manifest repositories. In this special case we must repo or manifest repositories. In this special case we must
use exec to re-execute repo with the new code and manifest. use exec to re-execute repo with the new code and manifest.
""" """
def __init__(self, extra_args=None): def __init__(self, extra_args=None):
super(RepoChangedException, self).__init__() super(RepoChangedException, self).__init__()
self.extra_args = extra_args or [] self.extra_args = extra_args or []
class HookError(Exception): class HookError(Exception):
"""Thrown if a 'repo-hook' could not be run. """Thrown if a 'repo-hook' could not be run.

View File

@ -23,6 +23,7 @@ TASK_COMMAND = 'command'
TASK_SYNC_NETWORK = 'sync-network' TASK_SYNC_NETWORK = 'sync-network'
TASK_SYNC_LOCAL = 'sync-local' TASK_SYNC_LOCAL = 'sync-local'
class EventLog(object): class EventLog(object):
"""Event log that records events that occurred during a repo invocation. """Event log that records events that occurred during a repo invocation.
@ -165,6 +166,7 @@ class EventLog(object):
# An integer id that is unique across this invocation of the program. # An integer id that is unique across this invocation of the program.
_EVENT_ID = multiprocessing.Value('i', 1) _EVENT_ID = multiprocessing.Value('i', 1)
def _NextEventId(): def _NextEventId():
"""Helper function for grabbing the next unique id. """Helper function for grabbing the next unique id.

View File

@ -48,6 +48,7 @@ _ssh_proxy_path = None
_ssh_sock_path = None _ssh_sock_path = None
_ssh_clients = [] _ssh_clients = []
def ssh_sock(create=True): def ssh_sock(create=True):
global _ssh_sock_path global _ssh_sock_path
if _ssh_sock_path is None: if _ssh_sock_path is None:
@ -61,6 +62,7 @@ def ssh_sock(create=True):
'master-%r@%h:%p') 'master-%r@%h:%p')
return _ssh_sock_path return _ssh_sock_path
def _ssh_proxy(): def _ssh_proxy():
global _ssh_proxy_path global _ssh_proxy_path
if _ssh_proxy_path is None: if _ssh_proxy_path is None:
@ -69,15 +71,18 @@ def _ssh_proxy():
'git_ssh') 'git_ssh')
return _ssh_proxy_path return _ssh_proxy_path
def _add_ssh_client(p): def _add_ssh_client(p):
_ssh_clients.append(p) _ssh_clients.append(p)
def _remove_ssh_client(p): def _remove_ssh_client(p):
try: try:
_ssh_clients.remove(p) _ssh_clients.remove(p)
except ValueError: except ValueError:
pass pass
def terminate_ssh_clients(): def terminate_ssh_clients():
global _ssh_clients global _ssh_clients
for p in _ssh_clients: for p in _ssh_clients:
@ -88,8 +93,10 @@ def terminate_ssh_clients():
pass pass
_ssh_clients = [] _ssh_clients = []
_git_version = None _git_version = None
class _GitCall(object): class _GitCall(object):
def version_tuple(self): def version_tuple(self):
global _git_version global _git_version
@ -102,11 +109,14 @@ class _GitCall(object):
def __getattr__(self, name): def __getattr__(self, name):
name = name.replace('_', '-') name = name.replace('_', '-')
def fun(*cmdv): def fun(*cmdv):
command = [name] command = [name]
command.extend(cmdv) command.extend(cmdv)
return GitCommand(None, command).Wait() == 0 return GitCommand(None, command).Wait() == 0
return fun return fun
git = _GitCall() git = _GitCall()
@ -187,8 +197,10 @@ class UserAgent(object):
return self._git_ua return self._git_ua
user_agent = UserAgent() user_agent = UserAgent()
def git_require(min_version, fail=False, msg=''): def git_require(min_version, fail=False, msg=''):
git_version = git.version_tuple() git_version = git.version_tuple()
if min_version <= git_version: if min_version <= git_version:
@ -201,9 +213,11 @@ def git_require(min_version, fail=False, msg=''):
sys.exit(1) sys.exit(1)
return False return False
def _setenv(env, name, value): def _setenv(env, name, value):
env[name] = value.encode() env[name] = value.encode()
class GitCommand(object): class GitCommand(object):
def __init__(self, def __init__(self,
project, project,

View File

@ -59,18 +59,23 @@ ID_RE = re.compile(r'^[0-9a-f]{40}$')
REVIEW_CACHE = dict() REVIEW_CACHE = dict()
def IsChange(rev): def IsChange(rev):
return rev.startswith(R_CHANGES) return rev.startswith(R_CHANGES)
def IsId(rev): def IsId(rev):
return ID_RE.match(rev) return ID_RE.match(rev)
def IsTag(rev): def IsTag(rev):
return rev.startswith(R_TAGS) return rev.startswith(R_TAGS)
def IsImmutable(rev): def IsImmutable(rev):
return IsChange(rev) or IsId(rev) or IsTag(rev) return IsChange(rev) or IsId(rev) or IsTag(rev)
def _key(name): def _key(name):
parts = name.split('.') parts = name.split('.')
if len(parts) < 2: if len(parts) < 2:
@ -79,6 +84,7 @@ def _key(name):
parts[-1] = parts[-1].lower() parts[-1] = parts[-1].lower()
return '.'.join(parts) return '.'.join(parts)
class GitConfig(object): class GitConfig(object):
_ForUser = None _ForUser = None
@ -392,6 +398,7 @@ _master_keys = set()
_ssh_master = True _ssh_master = True
_master_keys_lock = None _master_keys_lock = None
def init_ssh(): def init_ssh():
"""Should be called once at the start of repo to init ssh master handling. """Should be called once at the start of repo to init ssh master handling.
@ -401,6 +408,7 @@ def init_ssh():
assert _master_keys_lock is None, "Should only call init_ssh once" assert _master_keys_lock is None, "Should only call init_ssh once"
_master_keys_lock = _threading.Lock() _master_keys_lock = _threading.Lock()
def _open_ssh(host, port=None): def _open_ssh(host, port=None):
global _ssh_master global _ssh_master
@ -479,6 +487,7 @@ def _open_ssh(host, port=None):
finally: finally:
_master_keys_lock.release() _master_keys_lock.release()
def close_ssh(): def close_ssh():
global _master_keys_lock global _master_keys_lock
@ -503,15 +512,18 @@ def close_ssh():
# We're done with the lock, so we can delete it. # We're done with the lock, so we can delete it.
_master_keys_lock = None _master_keys_lock = None
URI_SCP = re.compile(r'^([^@:]*@?[^:/]{1,}):') URI_SCP = re.compile(r'^([^@:]*@?[^:/]{1,}):')
URI_ALL = re.compile(r'^([a-z][a-z+-]*)://([^@/]*@?[^/]*)/') URI_ALL = re.compile(r'^([a-z][a-z+-]*)://([^@/]*@?[^/]*)/')
def GetSchemeFromUrl(url): def GetSchemeFromUrl(url):
m = URI_ALL.match(url) m = URI_ALL.match(url)
if m: if m:
return m.group(1) return m.group(1)
return None return None
@contextlib.contextmanager @contextlib.contextmanager
def GetUrlCookieFile(url, quiet): def GetUrlCookieFile(url, quiet):
if url.startswith('persistent-'): if url.startswith('persistent-'):
@ -552,6 +564,7 @@ def GetUrlCookieFile(url, quiet):
cookiefile = os.path.expanduser(cookiefile) cookiefile = os.path.expanduser(cookiefile)
yield cookiefile, None yield cookiefile, None
def _preconnect(url): def _preconnect(url):
m = URI_ALL.match(url) m = URI_ALL.match(url)
if m: if m:
@ -572,9 +585,11 @@ def _preconnect(url):
return False return False
class Remote(object): class Remote(object):
"""Configuration options related to a remote. """Configuration options related to a remote.
""" """
def __init__(self, config, name): def __init__(self, config, name):
self._config = config self._config = config
self.name = name self.name = name
@ -735,6 +750,7 @@ class Remote(object):
class Branch(object): class Branch(object):
"""Configuration options related to a single branch. """Configuration options related to a single branch.
""" """
def __init__(self, config, name): def __init__(self, config, name):
self._config = config self._config = config
self.name = name self.name = name

View File

@ -29,12 +29,15 @@ from error import ManifestParseError
NUM_BATCH_RETRIEVE_REVISIONID = 32 NUM_BATCH_RETRIEVE_REVISIONID = 32
def get_gitc_manifest_dir(): def get_gitc_manifest_dir():
return wrapper.Wrapper().get_gitc_manifest_dir() return wrapper.Wrapper().get_gitc_manifest_dir()
def parse_clientdir(gitc_fs_path): def parse_clientdir(gitc_fs_path):
return wrapper.Wrapper().gitc_parse_clientdir(gitc_fs_path) return wrapper.Wrapper().gitc_parse_clientdir(gitc_fs_path)
def _set_project_revisions(projects): def _set_project_revisions(projects):
"""Sets the revisionExpr for a list of projects. """Sets the revisionExpr for a list of projects.
@ -63,6 +66,7 @@ def _set_project_revisions(projects):
(proj.remote.url, proj.revisionExpr)) (proj.remote.url, proj.revisionExpr))
proj.revisionExpr = revisionExpr proj.revisionExpr = revisionExpr
def _manifest_groups(manifest): def _manifest_groups(manifest):
"""Returns the manifest group string that should be synced """Returns the manifest group string that should be synced
@ -77,6 +81,7 @@ def _manifest_groups(manifest):
groups = 'default,platform-' + platform.system().lower() groups = 'default,platform-' + platform.system().lower()
return groups return groups
def generate_gitc_manifest(gitc_manifest, manifest, paths=None): def generate_gitc_manifest(gitc_manifest, manifest, paths=None):
"""Generate a manifest for shafsd to use for this GITC client. """Generate a manifest for shafsd to use for this GITC client.
@ -140,6 +145,7 @@ def generate_gitc_manifest(gitc_manifest, manifest, paths=None):
# Save the manifest. # Save the manifest.
save_manifest(manifest) save_manifest(manifest)
def save_manifest(manifest, client_dir=None): def save_manifest(manifest, client_dir=None):
"""Save the manifest file in the client_dir. """Save the manifest file in the client_dir.

13
main.py
View File

@ -101,6 +101,7 @@ global_options.add_option('--event-log',
dest='event_log', action='store', dest='event_log', action='store',
help='filename of event log to append timeline to') help='filename of event log to append timeline to')
class _Repo(object): class _Repo(object):
def __init__(self, repodir): def __init__(self, repodir):
self.repodir = repodir self.repodir = repodir
@ -300,11 +301,13 @@ repo: error:
cp %s %s cp %s %s
""" % (exp_str, WrapperPath(), repo_path), file=sys.stderr) """ % (exp_str, WrapperPath(), repo_path), file=sys.stderr)
def _CheckRepoDir(repo_dir): def _CheckRepoDir(repo_dir):
if not repo_dir: if not repo_dir:
print('no --repo-dir argument', file=sys.stderr) print('no --repo-dir argument', file=sys.stderr)
sys.exit(1) sys.exit(1)
def _PruneOptions(argv, opt): def _PruneOptions(argv, opt):
i = 0 i = 0
while i < len(argv): while i < len(argv):
@ -320,6 +323,7 @@ def _PruneOptions(argv, opt):
continue continue
i += 1 i += 1
class _UserAgentHandler(urllib.request.BaseHandler): class _UserAgentHandler(urllib.request.BaseHandler):
def http_request(self, req): def http_request(self, req):
req.add_header('User-Agent', user_agent.repo) req.add_header('User-Agent', user_agent.repo)
@ -329,6 +333,7 @@ class _UserAgentHandler(urllib.request.BaseHandler):
req.add_header('User-Agent', user_agent.repo) req.add_header('User-Agent', user_agent.repo)
return req return req
def _AddPasswordFromUserInput(handler, msg, req): def _AddPasswordFromUserInput(handler, msg, req):
# If repo could not find auth info from netrc, try to get it from user input # If repo could not find auth info from netrc, try to get it from user input
url = req.get_full_url() url = req.get_full_url()
@ -342,6 +347,7 @@ def _AddPasswordFromUserInput(handler, msg, req):
return return
handler.passwd.add_password(None, url, user, password) handler.passwd.add_password(None, url, user, password)
class _BasicAuthHandler(urllib.request.HTTPBasicAuthHandler): class _BasicAuthHandler(urllib.request.HTTPBasicAuthHandler):
def http_error_401(self, req, fp, code, msg, headers): def http_error_401(self, req, fp, code, msg, headers):
_AddPasswordFromUserInput(self, msg, req) _AddPasswordFromUserInput(self, msg, req)
@ -351,6 +357,7 @@ class _BasicAuthHandler(urllib.request.HTTPBasicAuthHandler):
def http_error_auth_reqed(self, authreq, host, req, headers): def http_error_auth_reqed(self, authreq, host, req, headers):
try: try:
old_add_header = req.add_header old_add_header = req.add_header
def _add_header(name, val): def _add_header(name, val):
val = val.replace('\n', '') val = val.replace('\n', '')
old_add_header(name, val) old_add_header(name, val)
@ -365,6 +372,7 @@ class _BasicAuthHandler(urllib.request.HTTPBasicAuthHandler):
self.retried = 0 self.retried = 0
raise raise
class _DigestAuthHandler(urllib.request.HTTPDigestAuthHandler): class _DigestAuthHandler(urllib.request.HTTPDigestAuthHandler):
def http_error_401(self, req, fp, code, msg, headers): def http_error_401(self, req, fp, code, msg, headers):
_AddPasswordFromUserInput(self, msg, req) _AddPasswordFromUserInput(self, msg, req)
@ -374,6 +382,7 @@ class _DigestAuthHandler(urllib.request.HTTPDigestAuthHandler):
def http_error_auth_reqed(self, auth_header, host, req, headers): def http_error_auth_reqed(self, auth_header, host, req, headers):
try: try:
old_add_header = req.add_header old_add_header = req.add_header
def _add_header(name, val): def _add_header(name, val):
val = val.replace('\n', '') val = val.replace('\n', '')
old_add_header(name, val) old_add_header(name, val)
@ -388,6 +397,7 @@ class _DigestAuthHandler(urllib.request.HTTPDigestAuthHandler):
self.retried = 0 self.retried = 0
raise raise
class _KerberosAuthHandler(urllib.request.BaseHandler): class _KerberosAuthHandler(urllib.request.BaseHandler):
def __init__(self): def __init__(self):
self.retried = 0 self.retried = 0
@ -468,6 +478,7 @@ class _KerberosAuthHandler(urllib.request.BaseHandler):
kerberos.authGSSClientClean(self.context) kerberos.authGSSClientClean(self.context)
self.context = None self.context = None
def init_http(): def init_http():
handlers = [_UserAgentHandler()] handlers = [_UserAgentHandler()]
@ -495,6 +506,7 @@ def init_http():
handlers.append(urllib.request.HTTPSHandler(debuglevel=1)) handlers.append(urllib.request.HTTPSHandler(debuglevel=1))
urllib.request.install_opener(urllib.request.build_opener(*handlers)) urllib.request.install_opener(urllib.request.build_opener(*handlers))
def _Main(argv): def _Main(argv):
result = 0 result = 0
@ -551,5 +563,6 @@ def _Main(argv):
TerminatePager() TerminatePager()
sys.exit(result) sys.exit(result)
if __name__ == '__main__': if __name__ == '__main__':
_Main(sys.argv[1:]) _Main(sys.argv[1:])

View File

@ -56,6 +56,7 @@ urllib.parse.uses_netloc.extend([
'sso', 'sso',
'rpc']) 'rpc'])
class _Default(object): class _Default(object):
"""Project defaults within the manifest.""" """Project defaults within the manifest."""
@ -74,6 +75,7 @@ class _Default(object):
def __ne__(self, other): def __ne__(self, other):
return self.__dict__ != other.__dict__ return self.__dict__ != other.__dict__
class _XmlRemote(object): class _XmlRemote(object):
def __init__(self, def __init__(self,
name, name,
@ -127,6 +129,7 @@ class _XmlRemote(object):
orig_name=self.name, orig_name=self.name,
fetchUrl=self.fetchUrl) fetchUrl=self.fetchUrl)
class XmlManifest(object): class XmlManifest(object):
"""manages the repo configuration file""" """manages the repo configuration file"""
@ -655,7 +658,6 @@ class XmlManifest(object):
if self._repo_hooks_project and (self._repo_hooks_project.name == name): if self._repo_hooks_project and (self._repo_hooks_project.name == name):
self._repo_hooks_project = None self._repo_hooks_project = None
def _AddMetaProjectMirror(self, m): def _AddMetaProjectMirror(self, m):
name = None name = None
m_url = m.GetRemote(m.remote.name).url m_url = m.GetRemote(m.remote.name).url

View File

@ -27,6 +27,7 @@ pager_process = None
old_stdout = None old_stdout = None
old_stderr = None old_stderr = None
def RunPager(globalConfig): def RunPager(globalConfig):
if not os.isatty(0) or not os.isatty(1): if not os.isatty(0) or not os.isatty(1):
return return
@ -39,6 +40,7 @@ def RunPager(globalConfig):
else: else:
_ForkPager(pager) _ForkPager(pager)
def TerminatePager(): def TerminatePager():
global pager_process, old_stdout, old_stderr global pager_process, old_stdout, old_stderr
if pager_process: if pager_process:
@ -52,6 +54,7 @@ def TerminatePager():
sys.stdout = old_stdout sys.stdout = old_stdout
sys.stderr = old_stderr sys.stderr = old_stderr
def _PipePager(pager): def _PipePager(pager):
global pager_process, old_stdout, old_stderr global pager_process, old_stdout, old_stderr
assert pager_process is None, "Only one active pager process at a time" assert pager_process is None, "Only one active pager process at a time"
@ -62,6 +65,7 @@ def _PipePager(pager):
sys.stdout = pager_process.stdin sys.stdout = pager_process.stdin
sys.stderr = pager_process.stdin sys.stderr = pager_process.stdin
def _ForkPager(pager): def _ForkPager(pager):
global active global active
# This process turns into the pager; a child it forks will # This process turns into the pager; a child it forks will
@ -88,6 +92,7 @@ def _ForkPager(pager):
print("fatal: cannot start pager '%s'" % pager, file=sys.stderr) print("fatal: cannot start pager '%s'" % pager, file=sys.stderr)
sys.exit(255) sys.exit(255)
def _SelectPager(globalConfig): def _SelectPager(globalConfig):
try: try:
return os.environ['GIT_PAGER'] return os.environ['GIT_PAGER']
@ -105,6 +110,7 @@ def _SelectPager(globalConfig):
return 'less' return 'less'
def _BecomePager(pager): def _BecomePager(pager):
# Delaying execution of the pager until we have output # Delaying execution of the pager until we have output
# ready works around a long-standing bug in popularly # ready works around a long-standing bug in popularly

View File

@ -92,6 +92,7 @@ class _FileDescriptorStreamsNonBlocking(FileDescriptorStreams):
""" """
class Stream(object): class Stream(object):
""" Encapsulates a file descriptor """ """ Encapsulates a file descriptor """
def __init__(self, fd, dest, std_name): def __init__(self, fd, dest, std_name):
self.fd = fd self.fd = fd
self.dest = dest self.dest = dest
@ -125,6 +126,7 @@ class _FileDescriptorStreamsThreads(FileDescriptorStreams):
non blocking I/O. This implementation requires creating threads issuing non blocking I/O. This implementation requires creating threads issuing
blocking read operations on file descriptors. blocking read operations on file descriptors.
""" """
def __init__(self): def __init__(self):
super(_FileDescriptorStreamsThreads, self).__init__() super(_FileDescriptorStreamsThreads, self).__init__()
# The queue is shared accross all threads so we can simulate the # The queue is shared accross all threads so we can simulate the
@ -144,12 +146,14 @@ class _FileDescriptorStreamsThreads(FileDescriptorStreams):
class QueueItem(object): class QueueItem(object):
""" Item put in the shared queue """ """ Item put in the shared queue """
def __init__(self, stream, data): def __init__(self, stream, data):
self.stream = stream self.stream = stream
self.data = data self.data = data
class Stream(object): class Stream(object):
""" Encapsulates a file descriptor """ """ Encapsulates a file descriptor """
def __init__(self, fd, dest, std_name, queue): def __init__(self, fd, dest, std_name, queue):
self.fd = fd self.fd = fd
self.dest = dest self.dest = dest

View File

@ -26,6 +26,7 @@ _NOT_TTY = not os.isatty(2)
# column 0. # column 0.
CSI_ERASE_LINE = '\x1b[2K' CSI_ERASE_LINE = '\x1b[2K'
class Progress(object): class Progress(object):
def __init__(self, title, total=0, units='', print_newline=False, def __init__(self, title, total=0, units='', print_newline=False,
always_print_percentage=False): always_print_percentage=False):

View File

@ -85,6 +85,7 @@ def not_rev(r):
def sq(r): def sq(r):
return "'" + r.replace("'", "'\''") + "'" return "'" + r.replace("'", "'\''") + "'"
_project_hook_list = None _project_hook_list = None
@ -1256,9 +1257,7 @@ class Project(object):
print(line[:-1]) print(line[:-1])
return p.Wait() == 0 return p.Wait() == 0
# Publish / Upload ## # Publish / Upload ##
def WasPublished(self, branch, all_refs=None): def WasPublished(self, branch, all_refs=None):
"""Was the branch published (uploaded) for code review? """Was the branch published (uploaded) for code review?
If so, returns the SHA-1 hash of the last published If so, returns the SHA-1 hash of the last published
@ -1410,9 +1409,7 @@ class Project(object):
R_HEADS + branch.name, R_HEADS + branch.name,
message=msg) message=msg)
# Sync ## # Sync ##
def _ExtractArchive(self, tarpath, path=None): def _ExtractArchive(self, tarpath, path=None):
"""Extract the given tar on its current location """Extract the given tar on its current location
@ -1819,9 +1816,7 @@ class Project(object):
patch_id, patch_id,
self.bare_git.rev_parse('FETCH_HEAD')) self.bare_git.rev_parse('FETCH_HEAD'))
# Branch Management ## # Branch Management ##
def GetHeadPath(self): def GetHeadPath(self):
"""Return the full path to the HEAD ref.""" """Return the full path to the HEAD ref."""
dotgit = os.path.join(self.worktree, '.git') dotgit = os.path.join(self.worktree, '.git')
@ -2019,9 +2014,7 @@ class Project(object):
kept.append(ReviewableBranch(self, branch, base)) kept.append(ReviewableBranch(self, branch, base))
return kept return kept
# Submodule Management ## # Submodule Management ##
def GetRegisteredSubprojects(self): def GetRegisteredSubprojects(self):
result = [] result = []
@ -2172,7 +2165,6 @@ class Project(object):
result.extend(subproject.GetDerivedSubprojects()) result.extend(subproject.GetDerivedSubprojects())
return result return result
# Direct Git Commands ## # Direct Git Commands ##
def _CheckForImmutableRevision(self): def _CheckForImmutableRevision(self):
try: try:

View File

@ -16,5 +16,6 @@
import sys import sys
def is_python3(): def is_python3():
return sys.version_info[0] == 3 return sys.version_info[0] == 3

View File

@ -28,13 +28,16 @@ REPO_TRACE = 'REPO_TRACE'
_TRACE = os.environ.get(REPO_TRACE) == '1' _TRACE = os.environ.get(REPO_TRACE) == '1'
def IsTrace(): def IsTrace():
return _TRACE return _TRACE
def SetTrace(): def SetTrace():
global _TRACE global _TRACE
_TRACE = True _TRACE = True
def Trace(fmt, *args): def Trace(fmt, *args):
if IsTrace(): if IsTrace():
print(fmt % args, file=sys.stderr) print(fmt % args, file=sys.stderr)

View File

@ -21,6 +21,7 @@ from collections import defaultdict
from git_command import git from git_command import git
from progress import Progress from progress import Progress
class Abandon(Command): class Abandon(Command):
common = True common = True
helpSummary = "Permanently abandon a development branch" helpSummary = "Permanently abandon a development branch"
@ -32,6 +33,7 @@ deleting it (and all its history) from your local repository.
It is equivalent to "git branch -D <branchname>". It is equivalent to "git branch -D <branchname>".
""" """
def _Options(self, p): def _Options(self, p):
p.add_option('--all', p.add_option('--all',
dest='all', action='store_true', dest='all', action='store_true',

View File

@ -19,6 +19,7 @@ import sys
from color import Coloring from color import Coloring
from command import Command from command import Command
class BranchColoring(Coloring): class BranchColoring(Coloring):
def __init__(self, config): def __init__(self, config):
Coloring.__init__(self, config, 'branch') Coloring.__init__(self, config, 'branch')
@ -26,6 +27,7 @@ class BranchColoring(Coloring):
self.local = self.printer('local') self.local = self.printer('local')
self.notinproject = self.printer('notinproject', fg='red') self.notinproject = self.printer('notinproject', fg='red')
class BranchInfo(object): class BranchInfo(object):
def __init__(self, name): def __init__(self, name):
self.name = name self.name = name

View File

@ -19,6 +19,7 @@ import sys
from command import Command from command import Command
from progress import Progress from progress import Progress
class Checkout(Command): class Checkout(Command):
common = True common = True
helpSummary = "Checkout a branch for development" helpSummary = "Checkout a branch for development"

View File

@ -22,6 +22,7 @@ from git_command import GitCommand
CHANGE_ID_RE = re.compile(r'^\s*Change-Id: I([0-9a-f]{40})\s*$') CHANGE_ID_RE = re.compile(r'^\s*Change-Id: I([0-9a-f]{40})\s*$')
class CherryPick(Command): class CherryPick(Command):
common = True common = True
helpSummary = "Cherry-pick a change." helpSummary = "Cherry-pick a change."

View File

@ -16,6 +16,7 @@
from command import PagedCommand from command import PagedCommand
class Diff(PagedCommand): class Diff(PagedCommand):
common = True common = True
helpSummary = "Show changes between commit and working tree" helpSummary = "Show changes between commit and working tree"

View File

@ -18,10 +18,12 @@ from color import Coloring
from command import PagedCommand from command import PagedCommand
from manifest_xml import XmlManifest from manifest_xml import XmlManifest
class _Coloring(Coloring): class _Coloring(Coloring):
def __init__(self, config): def __init__(self, config):
Coloring.__init__(self, config, "status") Coloring.__init__(self, config, "status")
class Diffmanifests(PagedCommand): class Diffmanifests(PagedCommand):
""" A command to see logs in projects represented by manifests """ A command to see logs in projects represented by manifests

View File

@ -23,6 +23,7 @@ from error import GitError
CHANGE_RE = re.compile(r'^([1-9][0-9]*)(?:[/\.-]([1-9][0-9]*))?$') CHANGE_RE = re.compile(r'^([1-9][0-9]*)(?:[/\.-]([1-9][0-9]*))?$')
class Download(Command): class Download(Command):
common = True common = True
helpSummary = "Download and checkout a change" helpSummary = "Download and checkout a change"

View File

@ -277,6 +277,7 @@ without iterating through the remaining projects.
return return
yield [mirror, opt, cmd, shell, cnt, config, project] yield [mirror, opt, cmd, shell, cnt, config, project]
class WorkerKeyboardInterrupt(Exception): class WorkerKeyboardInterrupt(Exception):
""" Keyboard interrupt exception for worker processes. """ """ Keyboard interrupt exception for worker processes. """
pass pass
@ -285,6 +286,7 @@ class WorkerKeyboardInterrupt(Exception):
def InitWorker(): def InitWorker():
signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGINT, signal.SIG_IGN)
def DoWorkWrapper(args): def DoWorkWrapper(args):
""" A wrapper around the DoWork() method. """ A wrapper around the DoWork() method.
@ -303,6 +305,7 @@ def DoWorkWrapper(args):
def DoWork(project, mirror, opt, cmd, shell, cnt, config): def DoWork(project, mirror, opt, cmd, shell, cnt, config):
env = os.environ.copy() env = os.environ.copy()
def setenv(name, val): def setenv(name, val):
if val is None: if val is None:
val = '' val = ''

View File

@ -24,6 +24,7 @@ from pyversion import is_python3
if not is_python3(): if not is_python3():
input = raw_input input = raw_input
class GitcDelete(Command, GitcClientCommand): class GitcDelete(Command, GitcClientCommand):
common = True common = True
visible_everywhere = False visible_everywhere = False

View File

@ -23,12 +23,14 @@ from command import PagedCommand
from error import GitError from error import GitError
from git_command import git_require, GitCommand from git_command import git_require, GitCommand
class GrepColoring(Coloring): class GrepColoring(Coloring):
def __init__(self, config): def __init__(self, config):
Coloring.__init__(self, config, 'grep') Coloring.__init__(self, config, 'grep')
self.project = self.printer('project', attr='bold') self.project = self.printer('project', attr='bold')
self.fail = self.printer('fail', fg='red') self.fail = self.printer('fail', fg='red')
class Grep(PagedCommand): class Grep(PagedCommand):
common = True common = True
helpSummary = "Print lines matching a pattern" helpSummary = "Print lines matching a pattern"
@ -156,7 +158,6 @@ contain a line that matches both expressions:
action='callback', callback=carry, action='callback', callback=carry,
help='Show only file names not containing matching lines') help='Show only file names not containing matching lines')
def Execute(self, opt, args): def Execute(self, opt, args):
out = GrepColoring(self.manifest.manifestProject.config) out = GrepColoring(self.manifest.manifestProject.config)

View File

@ -23,6 +23,7 @@ from color import Coloring
from command import PagedCommand, MirrorSafeCommand, GitcAvailableCommand, GitcClientCommand from command import PagedCommand, MirrorSafeCommand, GitcAvailableCommand, GitcClientCommand
import gitc_utils import gitc_utils
class Help(PagedCommand, MirrorSafeCommand): class Help(PagedCommand, MirrorSafeCommand):
common = False common = False
helpSummary = "Display detailed help on a command" helpSummary = "Display detailed help on a command"

View File

@ -18,10 +18,12 @@ from command import PagedCommand
from color import Coloring from color import Coloring
from git_refs import R_M from git_refs import R_M
class _Coloring(Coloring): class _Coloring(Coloring):
def __init__(self, config): def __init__(self, config):
Coloring.__init__(self, config, "status") Coloring.__init__(self, config, "status")
class Info(PagedCommand): class Info(PagedCommand):
common = True common = True
helpSummary = "Get info on the manifest branch, current branch or unmerged branches" helpSummary = "Get info on the manifest branch, current branch or unmerged branches"
@ -41,7 +43,6 @@ class Info(PagedCommand):
dest="local", action="store_true", dest="local", action="store_true",
help="Disable all remote operations") help="Disable all remote operations")
def Execute(self, opt, args): def Execute(self, opt, args):
self.out = _Coloring(self.manifest.globalConfig) self.out = _Coloring(self.manifest.globalConfig)
self.heading = self.out.printer('heading', attr='bold') self.heading = self.out.printer('heading', attr='bold')

View File

@ -37,6 +37,7 @@ from git_config import GitConfig
from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD from git_command import git_require, MIN_GIT_VERSION_SOFT, MIN_GIT_VERSION_HARD
import platform_utils import platform_utils
class Init(InteractiveCommand, MirrorSafeCommand): class Init(InteractiveCommand, MirrorSafeCommand):
common = True common = True
helpSummary = "Initialize repo in the current directory" helpSummary = "Initialize repo in the current directory"

View File

@ -18,6 +18,7 @@ from __future__ import print_function
from command import Command, MirrorSafeCommand from command import Command, MirrorSafeCommand
class List(Command, MirrorSafeCommand): class List(Command, MirrorSafeCommand):
common = True common = True
helpSummary = "List projects and their associated directories" helpSummary = "List projects and their associated directories"

View File

@ -20,6 +20,7 @@ import sys
from command import PagedCommand from command import PagedCommand
class Manifest(PagedCommand): class Manifest(PagedCommand):
common = False common = False
helpSummary = "Manifest inspection utility" helpSummary = "Manifest inspection utility"

View File

@ -18,6 +18,7 @@ from __future__ import print_function
from color import Coloring from color import Coloring
from command import PagedCommand from command import PagedCommand
class Prune(PagedCommand): class Prune(PagedCommand):
common = True common = True
helpSummary = "Prune (delete) already merged topics" helpSummary = "Prune (delete) already merged topics"

View File

@ -22,6 +22,7 @@ from command import Command, MirrorSafeCommand
from subcmds.sync import _PostRepoUpgrade from subcmds.sync import _PostRepoUpgrade
from subcmds.sync import _PostRepoFetch from subcmds.sync import _PostRepoFetch
class Selfupdate(Command, MirrorSafeCommand): class Selfupdate(Command, MirrorSafeCommand):
common = False common = False
helpSummary = "Update repo to the latest version" helpSummary = "Update repo to the latest version"

View File

@ -16,6 +16,7 @@
from subcmds.sync import Sync from subcmds.sync import Sync
class Smartsync(Sync): class Smartsync(Sync):
common = True common = True
helpSummary = "Update working tree to the latest known good revision" helpSummary = "Update working tree to the latest known good revision"

View File

@ -21,6 +21,7 @@ from color import Coloring
from command import InteractiveCommand from command import InteractiveCommand
from git_command import GitCommand from git_command import GitCommand
class _ProjectList(Coloring): class _ProjectList(Coloring):
def __init__(self, gc): def __init__(self, gc):
Coloring.__init__(self, gc, 'interactive') Coloring.__init__(self, gc, 'interactive')
@ -28,6 +29,7 @@ class _ProjectList(Coloring):
self.header = self.printer('header', attr='bold') self.header = self.printer('header', attr='bold')
self.help = self.printer('help', fg='red', attr='bold') self.help = self.printer('help', fg='red', attr='bold')
class Stage(InteractiveCommand): class Stage(InteractiveCommand):
common = True common = True
helpSummary = "Stage file(s) for commit" helpSummary = "Stage file(s) for commit"
@ -105,6 +107,7 @@ The '%prog' command stages files to prepare the next commit.
continue continue
print('Bye.') print('Bye.')
def _AddI(project): def _AddI(project):
p = GitCommand(project, ['add', '--interactive'], bare=False) p = GitCommand(project, ['add', '--interactive'], bare=False)
p.Wait() p.Wait()

View File

@ -25,6 +25,7 @@ import gitc_utils
from progress import Progress from progress import Progress
from project import SyncBuffer from project import SyncBuffer
class Start(Command): class Start(Command):
common = True common = True
helpSummary = "Start a new branch for development" helpSummary = "Start a new branch for development"

View File

@ -31,6 +31,7 @@ import os
from color import Coloring from color import Coloring
import platform_utils import platform_utils
class Status(PagedCommand): class Status(PagedCommand):
common = True common = True
helpSummary = "Show the working tree status" helpSummary = "Show the working tree status"

View File

@ -53,6 +53,7 @@ except ImportError:
try: try:
import resource import resource
def _rlimit_nofile(): def _rlimit_nofile():
return resource.getrlimit(resource.RLIMIT_NOFILE) return resource.getrlimit(resource.RLIMIT_NOFILE)
except ImportError: except ImportError:
@ -81,13 +82,16 @@ from manifest_xml import GitcManifest
_ONE_DAY_S = 24 * 60 * 60 _ONE_DAY_S = 24 * 60 * 60
class _FetchError(Exception): class _FetchError(Exception):
"""Internal error thrown in _FetchHelper() when we don't want stack trace.""" """Internal error thrown in _FetchHelper() when we don't want stack trace."""
pass pass
class _CheckoutError(Exception): class _CheckoutError(Exception):
"""Internal error thrown in _CheckoutOne() when we don't want stack trace.""" """Internal error thrown in _CheckoutOne() when we don't want stack trace."""
class Sync(Command, MirrorSafeCommand): class Sync(Command, MirrorSafeCommand):
jobs = 1 jobs = 1
common = True common = True
@ -1044,6 +1048,7 @@ later is required to fix a server side protocol bug.
file=sys.stderr) file=sys.stderr)
sys.exit(1) sys.exit(1)
def _PostRepoUpgrade(manifest, quiet=False): def _PostRepoUpgrade(manifest, quiet=False):
wrapper = Wrapper() wrapper = Wrapper()
if wrapper.NeedSetupGnuPG(): if wrapper.NeedSetupGnuPG():
@ -1052,6 +1057,7 @@ def _PostRepoUpgrade(manifest, quiet=False):
if project.Exists: if project.Exists:
project.PostRepoUpgrade() project.PostRepoUpgrade()
def _PostRepoFetch(rp, no_repo_verify=False, verbose=False): def _PostRepoFetch(rp, no_repo_verify=False, verbose=False):
if rp.HasChanges: if rp.HasChanges:
print('info: A new version of repo is available', file=sys.stderr) print('info: A new version of repo is available', file=sys.stderr)
@ -1070,6 +1076,7 @@ def _PostRepoFetch(rp, no_repo_verify=False, verbose=False):
print('repo version %s is current' % rp.work_git.describe(HEAD), print('repo version %s is current' % rp.work_git.describe(HEAD),
file=sys.stderr) file=sys.stderr)
def _VerifyTag(project): def _VerifyTag(project):
gpg_dir = os.path.expanduser('~/.repoconfig/gnupg') gpg_dir = os.path.expanduser('~/.repoconfig/gnupg')
if not os.path.exists(gpg_dir): if not os.path.exists(gpg_dir):
@ -1174,6 +1181,8 @@ class _FetchTimes(object):
# and supporting persistent-http[s]. It cannot change hosts from # and supporting persistent-http[s]. It cannot change hosts from
# request to request like the normal transport, the real url # request to request like the normal transport, the real url
# is passed during initialization. # is passed during initialization.
class PersistentTransport(xmlrpc.client.Transport): class PersistentTransport(xmlrpc.client.Transport):
def __init__(self, orig_host): def __init__(self, orig_host):
self.orig_host = orig_host self.orig_host = orig_host

View File

@ -33,6 +33,7 @@ else:
UNUSUAL_COMMIT_THRESHOLD = 5 UNUSUAL_COMMIT_THRESHOLD = 5
def _ConfirmManyUploads(multiple_branches=False): def _ConfirmManyUploads(multiple_branches=False):
if multiple_branches: if multiple_branches:
print('ATTENTION: One or more branches has an unusually high number ' print('ATTENTION: One or more branches has an unusually high number '
@ -44,17 +45,20 @@ def _ConfirmManyUploads(multiple_branches=False):
answer = input("If you are sure you intend to do this, type 'yes': ").strip() answer = input("If you are sure you intend to do this, type 'yes': ").strip()
return answer == "yes" return answer == "yes"
def _die(fmt, *args): def _die(fmt, *args):
msg = fmt % args msg = fmt % args
print('error: %s' % msg, file=sys.stderr) print('error: %s' % msg, file=sys.stderr)
sys.exit(1) sys.exit(1)
def _SplitEmails(values): def _SplitEmails(values):
result = [] result = []
for value in values: for value in values:
result.extend([s.strip() for s in value.split(',')]) result.extend([s.strip() for s in value.split(',')])
return result return result
class Upload(InteractiveCommand): class Upload(InteractiveCommand):
common = True common = True
helpSummary = "Upload changes for code review" helpSummary = "Upload changes for code review"

View File

@ -20,6 +20,7 @@ from command import Command, MirrorSafeCommand
from git_command import git, RepoSourceVersion, user_agent from git_command import git, RepoSourceVersion, user_agent
from git_refs import HEAD from git_refs import HEAD
class Version(Command, MirrorSafeCommand): class Version(Command, MirrorSafeCommand):
wrapper_version = None wrapper_version = None
wrapper_path = None wrapper_path = None

View File

@ -23,14 +23,17 @@ import unittest
import git_config import git_config
def fixture(*paths): def fixture(*paths):
"""Return a path relative to test/fixtures. """Return a path relative to test/fixtures.
""" """
return os.path.join(os.path.dirname(__file__), 'fixtures', *paths) return os.path.join(os.path.dirname(__file__), 'fixtures', *paths)
class GitConfigUnitTest(unittest.TestCase): class GitConfigUnitTest(unittest.TestCase):
"""Tests the GitConfig class. """Tests the GitConfig class.
""" """
def setUp(self): def setUp(self):
"""Create a GitConfig object using the test.gitconfig fixture. """Create a GitConfig object using the test.gitconfig fixture.
""" """
@ -68,5 +71,6 @@ class GitConfigUnitTest(unittest.TestCase):
val = config.GetString('empty') val = config.GetString('empty')
self.assertEqual(val, None) self.assertEqual(val, None)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -23,14 +23,17 @@ import unittest
import wrapper import wrapper
def fixture(*paths): def fixture(*paths):
"""Return a path relative to tests/fixtures. """Return a path relative to tests/fixtures.
""" """
return os.path.join(os.path.dirname(__file__), 'fixtures', *paths) return os.path.join(os.path.dirname(__file__), 'fixtures', *paths)
class RepoWrapperUnitTest(unittest.TestCase): class RepoWrapperUnitTest(unittest.TestCase):
"""Tests helper functions in the repo wrapper """Tests helper functions in the repo wrapper
""" """
def setUp(self): def setUp(self):
"""Load the wrapper module every time """Load the wrapper module every time
""" """
@ -76,5 +79,6 @@ class RepoWrapperUnitTest(unittest.TestCase):
self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/'), None) self.assertEqual(self.wrapper.gitc_parse_clientdir('/gitc/manifest-rw/'), None)
self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/'), None) self.assertEqual(self.wrapper.gitc_parse_clientdir('/test/usr/local/google/gitc/'), None)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -27,7 +27,10 @@ import os
def WrapperPath(): def WrapperPath():
return os.path.join(os.path.dirname(__file__), 'repo') return os.path.join(os.path.dirname(__file__), 'repo')
_wrapper_module = None _wrapper_module = None
def Wrapper(): def Wrapper():
global _wrapper_module global _wrapper_module
if not _wrapper_module: if not _wrapper_module: