patman: Drop references to __future__
[oweals/u-boot.git] / tools / rmboard.py
1 #! /usr/bin/python3
2 # SPDX-License-Identifier: GPL-2.0+
3 # Copyright 2019 Google LLC
4 #
5
6 """
7 Script to remove boards
8
9 Usage:
10    rmboard.py <board_name>...
11
12 A single commit is created for each board removed.
13
14 Some boards may depend on files provided by another and this will cause
15 problems, generally the removal of files which should not be removed.
16
17 This script works by:
18     - Looking through the MAINTAINERS files which mention a board to find out
19         what files the board uses
20     - Looking through the Kconfig files which mention a board to find one that
21         needs to have material removed
22
23 Search for ## to update the commit message manually.
24 """
25
26 import glob
27 import os
28 import re
29 import sys
30
31 # Bring in the patman libraries
32 our_path = os.path.dirname(os.path.realpath(__file__))
33 sys.path.append(os.path.join(our_path, '../tools/patman'))
34
35 import command
36
37 def rm_kconfig_include(path):
38     """Remove a path from Kconfig files
39
40     This function finds the given path in a 'source' statement in a Kconfig
41     file and removes that line from the file. This is needed because the path
42     is going to be removed, so any reference to it will cause a problem with
43     Kconfig parsing.
44
45     The changes are made locally and then added to the git staging area.
46
47     Args:
48         path: Path to search for and remove
49     """
50     cmd = ['git', 'grep', path]
51     stdout = command.RunPipe([cmd], capture=True, raise_on_error=False).stdout
52     if not stdout:
53         return
54     fname = stdout.split(':')[0]
55
56     print("Fixing up '%s' to remove reference to '%s'" % (fname, path))
57     cmd = ['sed', '-i', '\|%s|d' % path, fname]
58     stdout = command.RunPipe([cmd], capture=True).stdout
59
60     cmd = ['git', 'add', fname]
61     stdout = command.RunPipe([cmd], capture=True).stdout
62
63 def rm_board(board):
64     """Create a commit which removes a single board
65
66     This looks up the MAINTAINERS file to file files that need to be removed,
67     then removes pieces from the Kconfig files that mention the board.
68
69
70     Args:
71         board: Board name to remove
72     """
73
74     # Find all MAINTAINERS and Kconfig files which mention the board
75     cmd = ['git', 'grep', '-l', board]
76     stdout = command.RunPipe([cmd], capture=True).stdout
77     maintain = []
78     kconfig = []
79     for line in stdout.splitlines():
80         line = line.strip()
81         if 'MAINTAINERS' in line:
82             if line not in maintain:
83                 maintain.append(line)
84         elif 'Kconfig' in line:
85             kconfig.append(line)
86     paths = []
87     cc = []
88
89     # Look through the MAINTAINERS file to find things to remove
90     for fname in maintain:
91         with open(fname) as fd:
92             for line in fd:
93                 line = line.strip()
94                 fields = re.split('[ \t]', line, 1)
95                 if len(fields) == 2:
96                     if fields[0] == 'M:':
97                         cc.append(fields[1])
98                     elif fields[0] == 'F:':
99                         paths.append(fields[1].strip())
100
101     # Expand any wildcards in the MAINTAINERS file
102     real = []
103     for path in paths:
104         if path[-1] == '/':
105             path = path[:-1]
106         if '*' in path:
107             globbed = glob.glob(path)
108             print("Expanded '%s' to '%s'" % (path, globbed))
109             real += globbed
110         else:
111             real.append(path)
112
113     # Search for Kconfig files in the resulting list. Remove any 'source' lines
114     # which reference Kconfig files we want to remove
115     for path in real:
116         cmd = ['find', path]
117         stdout = (command.RunPipe([cmd], capture=True, raise_on_error=False).
118                   stdout)
119         for fname in stdout.splitlines():
120             if fname.endswith('Kconfig'):
121                 rm_kconfig_include(fname)
122
123     # Remove unwanted files
124     cmd = ['git', 'rm', '-r'] + real
125     stdout = command.RunPipe([cmd], capture=True).stdout
126
127     ## Change the messages as needed
128     msg = '''arm: Remove %s board
129
130 This board has not been converted to CONFIG_DM_MMC by the deadline.
131 Remove it.
132
133 ''' % board
134     for name in cc:
135         msg += 'Patch-cc: %s\n' % name
136
137     # Create the commit
138     cmd = ['git', 'commit', '-s', '-m', msg]
139     stdout = command.RunPipe([cmd], capture=True).stdout
140
141     # Check if the board is mentioned anywhere else. The user will need to deal
142     # with this
143     cmd = ['git', 'grep', '-il', board]
144     print(command.RunPipe([cmd], capture=True, raise_on_error=False).stdout)
145     print(' '.join(cmd))
146
147 for board in sys.argv[1:]:
148     rm_board(board)