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