Merge tag 'u-boot-rockchip-20200531' of https://gitlab.denx.de/u-boot/custodians...
[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
34 from patman import command
35
36 def rm_kconfig_include(path):
37     """Remove a path from Kconfig files
38
39     This function finds the given path in a 'source' statement in a Kconfig
40     file and removes that line from the file. This is needed because the path
41     is going to be removed, so any reference to it will cause a problem with
42     Kconfig parsing.
43
44     The changes are made locally and then added to the git staging area.
45
46     Args:
47         path: Path to search for and remove
48     """
49     cmd = ['git', 'grep', path]
50     stdout = command.RunPipe([cmd], capture=True, raise_on_error=False).stdout
51     if not stdout:
52         return
53     fname = stdout.split(':')[0]
54
55     print("Fixing up '%s' to remove reference to '%s'" % (fname, path))
56     cmd = ['sed', '-i', '\|%s|d' % path, fname]
57     stdout = command.RunPipe([cmd], capture=True).stdout
58
59     cmd = ['git', 'add', fname]
60     stdout = command.RunPipe([cmd], capture=True).stdout
61
62 def rm_board(board):
63     """Create a commit which removes a single board
64
65     This looks up the MAINTAINERS file to file files that need to be removed,
66     then removes pieces from the Kconfig files that mention the board.
67
68
69     Args:
70         board: Board name to remove
71     """
72
73     # Find all MAINTAINERS and Kconfig files which mention the board
74     cmd = ['git', 'grep', '-l', board]
75     stdout = command.RunPipe([cmd], capture=True).stdout
76     maintain = []
77     kconfig = []
78     for line in stdout.splitlines():
79         line = line.strip()
80         if 'MAINTAINERS' in line:
81             if line not in maintain:
82                 maintain.append(line)
83         elif 'Kconfig' in line:
84             kconfig.append(line)
85     paths = []
86     cc = []
87
88     # Look through the MAINTAINERS file to find things to remove
89     for fname in maintain:
90         with open(fname) as fd:
91             for line in fd:
92                 line = line.strip()
93                 fields = re.split('[ \t]', line, 1)
94                 if len(fields) == 2:
95                     if fields[0] == 'M:':
96                         cc.append(fields[1])
97                     elif fields[0] == 'F:':
98                         paths.append(fields[1].strip())
99
100     # Expand any wildcards in the MAINTAINERS file
101     real = []
102     for path in paths:
103         if path[-1] == '/':
104             path = path[:-1]
105         if '*' in path:
106             globbed = glob.glob(path)
107             print("Expanded '%s' to '%s'" % (path, globbed))
108             real += globbed
109         else:
110             real.append(path)
111
112     # Search for Kconfig files in the resulting list. Remove any 'source' lines
113     # which reference Kconfig files we want to remove
114     for path in real:
115         cmd = ['find', path]
116         stdout = (command.RunPipe([cmd], capture=True, raise_on_error=False).
117                   stdout)
118         for fname in stdout.splitlines():
119             if fname.endswith('Kconfig'):
120                 rm_kconfig_include(fname)
121
122     # Remove unwanted files
123     cmd = ['git', 'rm', '-r'] + real
124     stdout = command.RunPipe([cmd], capture=True).stdout
125
126     ## Change the messages as needed
127     msg = '''arm: Remove %s board
128
129 This board has not been converted to CONFIG_DM_MMC by the deadline.
130 Remove it.
131
132 ''' % board
133     for name in cc:
134         msg += 'Patch-cc: %s\n' % name
135
136     # Create the commit
137     cmd = ['git', 'commit', '-s', '-m', msg]
138     stdout = command.RunPipe([cmd], capture=True).stdout
139
140     # Check if the board is mentioned anywhere else. The user will need to deal
141     # with this
142     cmd = ['git', 'grep', '-il', board]
143     print(command.RunPipe([cmd], capture=True, raise_on_error=False).stdout)
144     print(' '.join(cmd))
145
146 for board in sys.argv[1:]:
147     rm_board(board)