1#!/usr/bin/env python 2 3# Copyright 2011 by Google, Inc. All rights reserved. 4# This code is governed by the BSD license found in the LICENSE file. 5 6# TODO: resolve differences with common.py and unify into one file. 7 8 9from __future__ import print_function 10 11import os 12import re 13import imp 14 15from _monkeyYaml import load as yamlLoad 16 17#def onerror(message): 18# print(message) 19 20# Matches trailing whitespace and any following blank lines. 21_BLANK_LINES = r"([ \t]*[\r\n]{1,2})*" 22 23# Matches the YAML frontmatter block. 24_YAML_PATTERN = re.compile(r"/\*---(.*)---\*/" + _BLANK_LINES, re.DOTALL) 25 26# Matches all known variants for the license block. 27# https://github.com/tc39/test262/blob/705d78299cf786c84fa4df473eff98374de7135a/tools/lint/lib/checks/license.py 28_LICENSE_PATTERN = re.compile( 29 r'// Copyright( \([C]\))? (\w+) .+\. {1,2}All rights reserved\.[\r\n]{1,2}' + 30 r'(' + 31 r'// This code is governed by the( BSD)? license found in the LICENSE file\.' + 32 r'|' + 33 r'// See LICENSE for details.' + 34 r'|' + 35 r'// Use of this source code is governed by a BSD-style license that can be[\r\n]{1,2}' + 36 r'// found in the LICENSE file\.' + 37 r'|' + 38 r'// See LICENSE or https://github\.com/tc39/test262/blob/(master|HEAD)/LICENSE' + 39 r')' + _BLANK_LINES, re.IGNORECASE) 40 41def yamlAttrParser(testRecord, attrs, name, onerror = print): 42 parsed = yamlLoad(attrs) 43 if parsed is None: 44 onerror("Failed to parse yaml in name %s" % name) 45 return 46 47 for key in parsed: 48 value = parsed[key] 49 if key == "info": 50 key = "commentary" 51 testRecord[key] = value 52 53 if 'flags' in testRecord: 54 for flag in testRecord['flags']: 55 testRecord[flag] = "" 56 57def findLicense(src): 58 match = _LICENSE_PATTERN.search(src) 59 if not match: 60 return None 61 62 return match.group(0) 63 64def findAttrs(src): 65 match = _YAML_PATTERN.search(src) 66 if not match: 67 return (None, None) 68 69 return (match.group(0), match.group(1).strip()) 70 71def parseTestRecord(src, name, onerror = print): 72 # Find the license block. 73 header = findLicense(src) 74 75 # Find the YAML frontmatter. 76 (frontmatter, attrs) = findAttrs(src) 77 78 # YAML frontmatter is required for all tests. 79 if frontmatter is None: 80 onerror("Missing frontmatter: %s" % name) 81 82 # The license shuold be placed before the frontmatter and there shouldn't be 83 # any extra content between the license and the frontmatter. 84 if header is not None and frontmatter is not None: 85 headerIdx = src.index(header) 86 frontmatterIdx = src.index(frontmatter) 87 if headerIdx > frontmatterIdx: 88 onerror("Unexpected license after frontmatter: %s" % name) 89 90 # Search for any extra test content, but ignore whitespace only or comment lines. 91 extra = src[headerIdx + len(header) : frontmatterIdx] 92 if extra and any(line.strip() and not line.lstrip().startswith("//") for line in extra.split("\n")): 93 onerror("Unexpected test content between license and frontmatter: %s" % name) 94 95 # Remove the license and YAML parts from the actual test content. 96 test = src 97 if frontmatter is not None: 98 test = test.replace(frontmatter, '') 99 if header is not None: 100 test = test.replace(header, '') 101 102 testRecord = {} 103 testRecord['header'] = header.strip() if header else '' 104 testRecord['test'] = test 105 106 if attrs: 107 yamlAttrParser(testRecord, attrs, name, onerror) 108 109 # Report if the license block is missing in non-generated tests. 110 if header is None and "generated" not in testRecord and "hashbang" not in name: 111 onerror("No license found in: %s" % name) 112 113 return testRecord 114