• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Protocol Buffers - Google's data interchange format
3# Copyright 2008 Google Inc.  All rights reserved.
4#
5# Use of this source code is governed by a BSD-style
6# license that can be found in the LICENSE file or at
7# https://developers.google.com/open-source/licenses/bsd
8
9"""Script to update a failure list file to add/remove failures.
10
11When adding, will attempt to place them in their correct lexicographical
12position relative to other test names. This requires that the failure list is
13already sorted. This does not guarantee that the tests will appear neatly one
14after the other, as there may be comments in between. If the failure list
15is not sorted, sorted blocks may be produced, but the list as a whole will not.
16Lastly, be wary of lists that have tests stripped from OSS; if you catch that
17a test was added inside a stripped block, you may need to move it out.
18
19This is sort of like comm(1), except it recognizes comments and ignores them.
20"""
21
22import argparse
23
24parser = argparse.ArgumentParser(
25    description='Adds/removes failures from the failure list.')
26parser.add_argument('filename', type=str, help='failure list file to update')
27parser.add_argument('--add', dest='add_list', action='append')
28parser.add_argument('--remove', dest='remove_list', action='append')
29
30DEFAULT_ALIGNMENT = 114
31args = parser.parse_args()
32
33add_set = set()
34remove_set = set()
35
36# Adds test + failure message
37for add_file in (args.add_list or []):
38  with open(add_file) as f:
39    for line in f:
40      add_set.add(line)
41
42# We only remove by name
43for remove_file in (args.remove_list or []):
44  with open(remove_file) as f:
45    for line in f:
46      if line in add_set:
47        raise Exception("Asked to both add and remove test: " + line)
48      remove_set.add(line.split('#')[0].strip())
49
50add_list = sorted(add_set, reverse=True)
51
52with open(args.filename) as in_file:
53  existing_list = in_file.read()
54
55with open(args.filename, 'w') as f:
56  split_lines = existing_list.splitlines(True)
57  # Make sure that we have one newline for potential tests that have to be
58  # added at the end.
59  split_lines[-1] = split_lines[-1].rstrip() + '\n'
60  for line in split_lines:
61    test = line.split('#')[0].strip()
62    # As long as the tests we are adding appear lexicographically before our
63    # read test, put them first followed by our read test.
64    while add_list and test > add_list[-1]:
65      f.write(add_list.pop())
66    if test not in remove_set:
67      f.write(line)
68  # Any remaining tests are added at the end
69  while add_list:
70    f.write(add_list.pop())
71
72# Update our read of the existing file
73with open(args.filename, 'r') as f:
74  existing_list = f.read()
75
76# Actual alignment of failure messages to 'DEFAULT_ALIGNMENT'
77# If test name exceeds DEFAULT_ALIGNMENT, it cannot and will not be aligned.
78with open(args.filename, 'w') as f:
79  for line in existing_list.splitlines(True):
80    split = line.split('#', 1)
81    test = split[0].strip()
82    if len(split) > 1 and test:
83      message = split[1].lstrip()
84      spaces = ' ' * (DEFAULT_ALIGNMENT - len(test))
85      line = test + spaces + ' # ' + message
86      f.write(line)
87    else:  # ignore blank lines/lines that do not have '#'/comments
88      f.write(line)
89