github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-tools-src/grumpy_tools/diffrange.py (about) 1 #!/usr/bin/env python 2 3 # Copyright 2016 Google Inc. All Rights Reserved. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 """Convert a unified diff into a list of modified files and line numbers.""" 18 19 from __future__ import print_function 20 21 import sys 22 23 24 class _LineBuffer(object): 25 """Iterator over lines in a file supporting one-step rewind.""" 26 27 def __init__(self, f): 28 self._f = f 29 self._prev = None 30 self._next = None 31 32 def __iter__(self): 33 return self 34 35 def next(self): 36 if self._next is not None: 37 cur = self._next 38 else: 39 cur = self._f.readline() 40 if not cur: 41 raise StopIteration 42 self._next = None 43 self._prev = cur 44 return cur 45 46 def Rewind(self): 47 assert self._prev is not None 48 self._next = self._prev 49 self._prev = None 50 51 52 def _ReadHunks(buf): 53 for line in buf: 54 if not line.startswith('@@'): 55 break 56 base = int(line.split()[2].split(',')[0]) 57 for offset in _ReadHunkBody(buf): 58 yield base + offset 59 60 61 def _ReadHunkBody(buf): 62 n = 0 63 for line in buf: 64 prefix = line[0] 65 if prefix == ' ': 66 n += 1 67 elif prefix == '+': 68 yield n 69 n += 1 70 elif prefix != '-' or line.startswith('---'): 71 buf.Rewind() 72 break 73 74 75 def main(): 76 buf = _LineBuffer(sys.stdin) 77 for line in buf: 78 if line.startswith('+++'): 79 filename = line.split()[1] 80 for n in _ReadHunks(buf): 81 print('{}:{}'.format(filename, n)) 82 83 84 if __name__ == '__main__': 85 main()