1478d9372SMasahiro Yamada#!/usr/bin/env python2 2*83d290c5STom Rini# SPDX-License-Identifier: GPL-2.0+ 3478d9372SMasahiro Yamada# 4478d9372SMasahiro Yamada# Author: Masahiro Yamada <yamada.m@jp.panasonic.com> 5478d9372SMasahiro Yamada# 6478d9372SMasahiro Yamada 7478d9372SMasahiro Yamada""" 8478d9372SMasahiro YamadaFill the "Commit" and "Removed" fields of doc/README.scrapyard 9478d9372SMasahiro Yamada 10478d9372SMasahiro YamadaThe file doc/README.scrapyard is used to keep track of removed boards. 11478d9372SMasahiro Yamada 12478d9372SMasahiro YamadaWhen we remove support for boards, we are supposed to add entries to 13478d9372SMasahiro Yamadadoc/README.scrapyard leaving "Commit" and "Removed" fields blank. 14478d9372SMasahiro Yamada 15478d9372SMasahiro YamadaThe "Commit" field is the commit hash in which the board was removed 16478d9372SMasahiro Yamadaand the "Removed" is the date at which the board was removed. Those 17478d9372SMasahiro Yamadatwo are known only after the board removal patch was applied, thus they 18478d9372SMasahiro Yamadaneed to be filled in later. 19478d9372SMasahiro Yamada 20478d9372SMasahiro YamadaThis effectively means that the person who removes other boards is 21478d9372SMasahiro Yamadasupposed to fill in the blank fields before adding new entries to 22478d9372SMasahiro Yamadadoc/README.scrapyard. 23478d9372SMasahiro Yamada 24478d9372SMasahiro YamadaThat is a really tedious task that should be automated. 25478d9372SMasahiro YamadaThis script fills the blank fields of doc/README.scrapyard for you! 26478d9372SMasahiro Yamada 27478d9372SMasahiro YamadaUsage: 28478d9372SMasahiro Yamada 29478d9372SMasahiro YamadaThe "Commit" and "Removed" fields must be "-". The other fields should 30478d9372SMasahiro Yamadahave already been filled in by a former commit. 31478d9372SMasahiro Yamada 32478d9372SMasahiro YamadaRun 33478d9372SMasahiro Yamada scripts/fill_scrapyard.py 34478d9372SMasahiro Yamada""" 35478d9372SMasahiro Yamada 36478d9372SMasahiro Yamadaimport os 37478d9372SMasahiro Yamadaimport subprocess 38478d9372SMasahiro Yamadaimport sys 39478d9372SMasahiro Yamadaimport tempfile 40478d9372SMasahiro Yamada 41478d9372SMasahiro YamadaDOC='doc/README.scrapyard' 42478d9372SMasahiro Yamada 43478d9372SMasahiro Yamadadef get_last_modify_commit(file, line_num): 44478d9372SMasahiro Yamada """Get the commit that last modified the given line. 45478d9372SMasahiro Yamada 46478d9372SMasahiro Yamada This function runs "git blame" against the given line of the given 47478d9372SMasahiro Yamada file and returns the commit hash that last modified it. 48478d9372SMasahiro Yamada 49478d9372SMasahiro Yamada Arguments: 50478d9372SMasahiro Yamada file: the file to be git-blame'd. 51478d9372SMasahiro Yamada line_num: the line number to be git-blame'd. This line number 52478d9372SMasahiro Yamada starts from 1, not 0. 53478d9372SMasahiro Yamada 54478d9372SMasahiro Yamada Returns: 55478d9372SMasahiro Yamada Commit hash that last modified the line. The number of digits is 56478d9372SMasahiro Yamada long enough to form a unique commit. 57478d9372SMasahiro Yamada """ 58478d9372SMasahiro Yamada result = subprocess.check_output(['git', 'blame', '-L', 59478d9372SMasahiro Yamada '%d,%d' % (line_num, line_num), file]) 60478d9372SMasahiro Yamada commit = result.split()[0] 61478d9372SMasahiro Yamada 62478d9372SMasahiro Yamada if commit[0] == '^': 63478d9372SMasahiro Yamada sys.exit('%s: line %d: ' % (file, line_num) + 64478d9372SMasahiro Yamada 'this line was modified before the beginning of git history') 65478d9372SMasahiro Yamada 66478d9372SMasahiro Yamada if commit == '0' * len(commit): 67478d9372SMasahiro Yamada sys.exit('%s: line %d: locally modified\n' % (file, line_num) + 68478d9372SMasahiro Yamada 'Please run this script in a clean repository.') 69478d9372SMasahiro Yamada 70478d9372SMasahiro Yamada return commit 71478d9372SMasahiro Yamada 72478d9372SMasahiro Yamadadef get_committer_date(commit): 73478d9372SMasahiro Yamada """Get the committer date of the given commit. 74478d9372SMasahiro Yamada 75478d9372SMasahiro Yamada This function returns the date when the given commit was applied. 76478d9372SMasahiro Yamada 77478d9372SMasahiro Yamada Arguments: 78478d9372SMasahiro Yamada commit: commit-ish object. 79478d9372SMasahiro Yamada 80478d9372SMasahiro Yamada Returns: 81478d9372SMasahiro Yamada The committer date of the given commit in the form YY-MM-DD. 82478d9372SMasahiro Yamada """ 83478d9372SMasahiro Yamada committer_date = subprocess.check_output(['git', 'show', '-s', 84478d9372SMasahiro Yamada '--format=%ci', commit]) 85478d9372SMasahiro Yamada return committer_date.split()[0] 86478d9372SMasahiro Yamada 87478d9372SMasahiro Yamadadef move_to_topdir(): 88478d9372SMasahiro Yamada """Change directory to the top of the git repository. 89478d9372SMasahiro Yamada 90478d9372SMasahiro Yamada Or, exit with an error message if called out of a git repository. 91478d9372SMasahiro Yamada """ 92478d9372SMasahiro Yamada try: 93478d9372SMasahiro Yamada toplevel = subprocess.check_output(['git', 'rev-parse', 94478d9372SMasahiro Yamada '--show-toplevel']) 95478d9372SMasahiro Yamada except subprocess.CalledProcessError: 96478d9372SMasahiro Yamada sys.exit('Please run in a git repository.') 97478d9372SMasahiro Yamada 98478d9372SMasahiro Yamada # strip '\n' 99478d9372SMasahiro Yamada toplevel = toplevel.rstrip() 100478d9372SMasahiro Yamada 101478d9372SMasahiro Yamada # Change the current working directory to the toplevel of the respository 102478d9372SMasahiro Yamada # for our easier life. 103478d9372SMasahiro Yamada os.chdir(toplevel) 104478d9372SMasahiro Yamada 105478d9372SMasahiro Yamadaclass TmpFile: 106478d9372SMasahiro Yamada 107478d9372SMasahiro Yamada """Useful class to handle a temporary file. 108478d9372SMasahiro Yamada 109478d9372SMasahiro Yamada tempfile.mkstemp() is often used to create a unique temporary file, 110478d9372SMasahiro Yamada but what is inconvenient is that the caller is responsible for 111478d9372SMasahiro Yamada deleting the file when done with it. 112478d9372SMasahiro Yamada 113478d9372SMasahiro Yamada Even when the caller errors out on the way, the temporary file must 114478d9372SMasahiro Yamada be deleted somehow. The idea here is that we delete the file in 115478d9372SMasahiro Yamada the destructor of this class because the destructor is always 116478d9372SMasahiro Yamada invoked when the instance of the class is freed. 117478d9372SMasahiro Yamada """ 118478d9372SMasahiro Yamada 119478d9372SMasahiro Yamada def __init__(self): 120478d9372SMasahiro Yamada """Constructor - create a temporary file""" 121478d9372SMasahiro Yamada fd, self.filename = tempfile.mkstemp() 122478d9372SMasahiro Yamada self.file = os.fdopen(fd, 'w') 123478d9372SMasahiro Yamada 124478d9372SMasahiro Yamada def __del__(self): 125478d9372SMasahiro Yamada """Destructor - delete the temporary file""" 126478d9372SMasahiro Yamada try: 127478d9372SMasahiro Yamada os.remove(self.filename) 128478d9372SMasahiro Yamada except: 129478d9372SMasahiro Yamada pass 130478d9372SMasahiro Yamada 131478d9372SMasahiro Yamadadef main(): 132478d9372SMasahiro Yamada move_to_topdir() 133478d9372SMasahiro Yamada 134478d9372SMasahiro Yamada line_num = 1 135478d9372SMasahiro Yamada 136478d9372SMasahiro Yamada tmpfile = TmpFile() 137478d9372SMasahiro Yamada for line in open(DOC): 138478d9372SMasahiro Yamada tmp = line.split(None, 5) 139478d9372SMasahiro Yamada modified = False 140478d9372SMasahiro Yamada 141478d9372SMasahiro Yamada if len(tmp) >= 5: 142478d9372SMasahiro Yamada # fill "Commit" field 143478d9372SMasahiro Yamada if tmp[3] == '-': 144478d9372SMasahiro Yamada tmp[3] = get_last_modify_commit(DOC, line_num) 145478d9372SMasahiro Yamada modified = True 146478d9372SMasahiro Yamada # fill "Removed" field 147478d9372SMasahiro Yamada if tmp[4] == '-': 148478d9372SMasahiro Yamada tmp[4] = get_committer_date(tmp[3]) 149478d9372SMasahiro Yamada if modified: 150478d9372SMasahiro Yamada line = tmp[0].ljust(17) 151478d9372SMasahiro Yamada line += tmp[1].ljust(12) 152478d9372SMasahiro Yamada line += tmp[2].ljust(15) 153478d9372SMasahiro Yamada line += tmp[3].ljust(12) 154478d9372SMasahiro Yamada line += tmp[4].ljust(12) 155478d9372SMasahiro Yamada if len(tmp) >= 6: 156478d9372SMasahiro Yamada line += tmp[5] 157478d9372SMasahiro Yamada line = line.rstrip() + '\n' 158478d9372SMasahiro Yamada 159478d9372SMasahiro Yamada tmpfile.file.write(line) 160478d9372SMasahiro Yamada line_num += 1 161478d9372SMasahiro Yamada 162478d9372SMasahiro Yamada os.rename(tmpfile.filename, DOC) 163478d9372SMasahiro Yamada 164478d9372SMasahiro Yamadaif __name__ == '__main__': 165478d9372SMasahiro Yamada main() 166