1#!/usr/bin/env python3 2 3import argparse 4import os 5import sys 6 7def merge(dest, files): 8 ''' 9 Merge the content of all files into the file dest. 10 11 The first line of each file is an optional section header in the form 12 e.g. 13 ! model = keycodes 14 Where two sections have identical headers, the second header is skipped. 15 ''' 16 17 sections = {} 18 section_names = [] # let's write out in the rough order of the Makefile.am 19 for partsfile in files: 20 # files may exist in srcdir or builddir, depending whether they're 21 # generated 22 path = partsfile[0] if os.path.exists(partsfile[0]) else partsfile[1] 23 24 with open(path) as fd: 25 header = fd.readline() 26 if header.startswith('! '): 27 # if we have a file that belongs to a section, 28 # keep it for later sorted writing 29 paths = sections.get(header, []) 30 paths.append(path) 31 sections[header] = paths 32 if header not in section_names: 33 section_names.append(header) 34 else: 35 dest.write(header) 36 dest.write(fd.read()) 37 38 for header in section_names: 39 dest.write('\n') 40 dest.write(header) 41 for f in sections[header]: 42 with open(f) as fd: 43 fd.readline() # drop the header 44 dest.write(fd.read()) 45 46 47if __name__ == '__main__': 48 parser = argparse.ArgumentParser('rules file merge script') 49 parser.add_argument('dest', type=str) 50 parser.add_argument('srcdir', type=str) 51 parser.add_argument('builddir', type=str) 52 parser.add_argument('files', nargs='+', type=str) 53 ns = parser.parse_args() 54 55 with open(ns.dest, 'w') as fd: 56 basename = os.path.basename(sys.argv[0]) 57 fd.write('// DO NOT EDIT THIS FILE - IT WAS AUTOGENERATED BY {} FROM rules/*.part\n'.format(basename)) 58 fd.write('//\n') 59 ftuple = lambda f: (os.path.join(ns.builddir, f), os.path.join(ns.srcdir, f)) 60 merge(fd, [ftuple(f) for f in ns.files]) 61