1# Copyright 2022 The Pigweed Authors 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may not 4# use this file except in compliance with the License. You may obtain a copy of 5# the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations under 13# the License. 14"""Transforms a JSON list of paths using -ffile-prefix-map style rules.""" 15 16import argparse 17import json 18from typing import Iterator, List, TextIO 19 20# Note: This should be List[Tuple[str, str]], but using string.split() 21# produces Tuple[Any,...], so this permits that typing for convenience. 22PrefixMaps = List[tuple] 23 24 25def _parse_args() -> argparse.Namespace: 26 """Parses and returns the command line arguments.""" 27 28 parser = argparse.ArgumentParser(description=__doc__) 29 parser.add_argument('in_json', 30 type=argparse.FileType('r'), 31 help='The JSON file containing a list of file names ' 32 'that the prefix map operations should be applied to') 33 parser.add_argument( 34 '--prefix-map-json', 35 type=argparse.FileType('r'), 36 required=True, 37 help= 38 'JSON file containing an array of prefix map transformations to apply ' 39 'to the strings before tokenizing. These string literal ' 40 'transformations are of the form "from=to". All strings with the ' 41 'prefix `from` will have the prefix replaced with `to`. ' 42 'Transformations are applied in the order they are listed in the JSON ' 43 'file.') 44 45 parser.add_argument('--output', 46 type=argparse.FileType('w'), 47 help='File path to write transformed paths to.') 48 return parser.parse_args() 49 50 51def remap_paths(paths: List[str], prefix_maps: PrefixMaps) -> Iterator[str]: 52 for path in paths: 53 for from_prefix, to_prefix in prefix_maps: 54 if path.startswith(from_prefix): 55 path = path.replace(from_prefix, to_prefix, 1) 56 yield path 57 58 59def remap_json_paths(in_json: TextIO, output: TextIO, 60 prefix_map_json: TextIO) -> None: 61 paths = json.load(in_json) 62 prefix_maps: PrefixMaps = [ 63 tuple(m.split('=', maxsplit=1)) for m in json.load(prefix_map_json) 64 ] 65 66 json.dump(list(remap_paths(paths, prefix_maps)), output) 67 68 69if __name__ == '__main__': 70 remap_json_paths(**vars(_parse_args())) 71