1 # Copyright 2015 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.
8 from file_system
import FileNotFoundError
11 # This provides utilities for extracting information from the local git
12 # repository to which it belongs.
15 # Regex to match ls-tree output.
16 _LS_TREE_REGEX
= re
.compile(
17 '\d+\s(?P<type>\w+)\s(?P<id>[0-9a-f]{40})\s(?P<name>.*)')
21 return os
.path
.join(os
.path
.dirname(os
.path
.realpath(__file__
)),
22 os
.pardir
, os
.pardir
, os
.pardir
, os
.pardir
, os
.pardir
)
25 def _RelativePath(path
):
26 return os
.path
.join(_GetRoot(), path
)
29 def RunGit(command
, args
=[]):
30 # We import subprocess symbols lazily because they aren't available on
31 # AppEngine, and the frontend may load (but should never execute) this module.
32 from subprocess
import check_output
33 with
open(os
.devnull
, 'w') as dev_null
:
34 return check_output(['git', command
] + args
, stderr
=dev_null
,
38 def ParseRevision(name
):
39 return RunGit('rev-parse', [name
]).rstrip()
42 def GetParentRevision(revision
):
43 return RunGit('show', ['-s', '--format=%P', revision
]).rstrip()
46 def GetRootTree(revision
):
47 return RunGit('show', ['-s', '--format=%T', revision
]).rstrip()
50 def ListDir(path
, revision
='HEAD'):
51 '''Retrieves a directory listing for the specified path and optional revision
52 (default is HEAD.) Returns a list of objects with the following properties:
54 |type|: the type of entry; 'blob' (file) or 'tree' (directory)
55 |id|: the hash of the directory entry. This is either tree hash or blob hash
56 |name|: the name of the directory entry.
58 from subprocess
import CalledProcessError
60 ref
= '%s:%s' % (ParseRevision(revision
), path
.lstrip('/'))
61 listing
= RunGit('ls-tree', [ref
]).rstrip().splitlines()
62 except CalledProcessError
:
63 raise FileNotFoundError('%s not found in revision %s' % (path
, revision
))
66 return re
.match(_LS_TREE_REGEX
, line
).groupdict()
68 return map(parse_line
, listing
)
71 def ReadFile(path
, revision
='HEAD'):
72 '''Retrieves the contents of a file at the specified path and optional
73 revision (default is HEAD.) Returns its contents as a string.
75 from subprocess
import CalledProcessError
77 return RunGit('show', ['%s:%s' % (ParseRevision(revision
), path
)])
78 except CalledProcessError
:
79 raise FileNotFoundError('%s not found in revision %s' % (path
, revision
))