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