• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#! /usr/bin/python
2# SPDX-License-Identifier: GPL-2.0+
3# Copyright 2019 Google LLC
4#
5
6"""
7Script to remove boards
8
9Usage:
10   rmboard.py <board_name>...
11
12A single commit is created for each board removed.
13
14Some boards may depend on files provided by another and this will cause
15problems, generally the removal of files which should not be removed.
16
17This 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
23Search for ## to update the commit message manually.
24"""
25
26from __future__ import print_function
27
28import glob
29import os
30import re
31import sys
32
33# Bring in the patman libraries
34our_path = os.path.dirname(os.path.realpath(__file__))
35sys.path.append(os.path.join(our_path, '../tools/patman'))
36
37import command
38
39def 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
65def 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
132This board has not been converted to CONFIG_DM_MMC by the deadline.
133Remove 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
149for board in sys.argv[1:]:
150    rm_board(board)
151