1#!@PYTHON@ 2# 3# This file is part of LilyPond, the GNU music typesetter. 4# 5# Copyright (C) 2008--2021 John Mandereau <john.mandereau@gmail.com> 6# 7# LilyPond is free software: you can redistribute it and/or modify 8# it under the terms of the GNU General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# LilyPond is distributed in the hope that it will be useful, 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU General Public License for more details. 16# 17# You should have received a copy of the GNU General Public License 18# along with LilyPond. If not, see <http://www.gnu.org/licenses/>. 19 20 21import subprocess 22import re 23import sys 24 25verbose = False 26 27 28def read_pipe(command): 29 child = subprocess.Popen(command, 30 stdout=subprocess.PIPE, 31 stderr=subprocess.PIPE, 32 shell=True) 33 (output, error) = child.communicate() 34 code = str(child.wait()) 35 if not child.stdout or child.stdout.close(): 36 print("pipe failed: %(command)s" % locals()) 37 (output, error) = (output.decode('utf-8'), error.decode('utf-8')) 38 if code != '0': 39 error = code + ' ' + error 40 return (output, error) 41 42 43# Renamed files map to ensure continuity of file history 44# Map of new_name: old_name 45# This is for handling 69f0ec47 ("Docs: reorganize documentation 46# directory structure"), which removed the user/ dir and the topdocs/NEWS.tely file 47renames_map = { 48 'usage.tely': 'user/lilypond-program.tely', 49 'notation.tely': 'user/lilypond.tely', 50 'learning.tely': 'user/lilypond-learning.tely', 51 'changes.tely': 'topdocs/NEWS.tely', 52} 53 54# FIXME: Hardcoded file names!? 55manuals_subdirectories_re = \ 56 re.compile( 57 '(usage|automated-engraving|changes|essay|extending|web|learning|notation)/') 58 59 60def get_old_name(file_path): 61 for new_path in renames_map: 62 if file_path.endswith(new_path): 63 old_file_path = file_path.replace(new_path, 64 renames_map[new_path]) 65 break 66 else: 67 if file_path.endswith('macros.itexi'): 68 old_file_path = file_path.replace('macros.itexi', 69 'user/macros.itexi') 70 elif file_path.endswith('.itely'): 71 old_file_path = manuals_subdirectories_re.sub('user/', 72 file_path) 73 elif 'snippets/' in file_path: 74 old_file_path = file_path.replace('snippets/', 75 '../input/lsr/') 76 else: 77 return file_path 78 return old_file_path 79 80 81def file_exists_at(revision, name): 82 cmd = "git show %s:Documentation/%s" % (revision, name) 83 if verbose: 84 sys.stderr.write('running: %s\n' % cmd) 85 86 child = subprocess.run(cmd, 87 stdout=subprocess.DEVNULL, 88 stderr=subprocess.DEVNULL, 89 shell=True) 90 return not child.returncode 91 92 93revision_re = re.compile(r'GIT [Cc]ommittish:\s+([a-f0-9]+)') 94 95no_committish_fatal_error = """error: %s: no 'GIT committish: <hash>' found. 96Please check the whole file against the original in English, then 97fill in HEAD committish in the header. 98""" 99 100def check_translated_doc(original, translated_file, translated_contents, 101 color=False, upper_revision='HEAD'): 102 """Returns the diff of the original relative to the last translation""" 103 m = revision_re.search(translated_contents) 104 if not m: 105 sys.stderr.write(no_committish_fatal_error % translated_file) 106 sys.exit(1) 107 revision = m.group(1) 108 if revision == '0': 109 return '', 0 110 111 if color: 112 color_flag = '--color --color-words' 113 else: 114 color_flag = '--no-color' 115 116 current_name = original 117 118 if original.startswith("en/") and not file_exists_at(revision, original): 119 # this is to handle the rename in 82d72b7 ("Merge branch doc-build") 120 original = original[3:] 121 if not file_exists_at(revision, original): 122 original = get_old_name(original) 123 124 c = 'git diff -M %(color_flag)s %(revision)s:Documentation/%(original)s \ 125%(upper_revision)s:Documentation/%(current_name)s' % vars() 126 if verbose: 127 sys.stderr.write('running: %s\n' % c) 128 return read_pipe(c) 129