#!@PYTHON@ # # This file is part of LilyPond, the GNU music typesetter. # # Copyright (C) 2008--2020 John Mandereau # # LilyPond is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # LilyPond is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with LilyPond. If not, see . import subprocess import re import sys verbose = False def read_pipe(command): child = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) (output, error) = child.communicate() code = str(child.wait()) if not child.stdout or child.stdout.close(): print("pipe failed: %(command)s" % locals()) (output, error) = (output.decode('utf-8'), error.decode('utf-8')) if code != '0': error = code + ' ' + error return (output, error) # Renamed files map to ensure continuity of file history # Map of new_name: old_name # This is for handling 69f0ec47 ("Docs: reorganize documentation # directory structure"), which removed the user/ dir and the topdocs/NEWS.tely file renames_map = { 'usage.tely': 'user/lilypond-program.tely', 'notation.tely': 'user/lilypond.tely', 'learning.tely': 'user/lilypond-learning.tely', 'changes.tely': 'topdocs/NEWS.tely', } # FIXME: Hardcoded file names!? manuals_subdirectories_re = \ re.compile( '(usage|automated-engraving|changes|essay|extending|web|learning|notation)/') def get_old_name(file_path): for new_path in renames_map: if file_path.endswith(new_path): old_file_path = file_path.replace(new_path, renames_map[new_path]) break else: if file_path.endswith('macros.itexi'): old_file_path = file_path.replace('macros.itexi', 'user/macros.itexi') elif file_path.endswith('.itely'): old_file_path = manuals_subdirectories_re.sub('user/', file_path) elif 'snippets/' in file_path: old_file_path = file_path.replace('snippets/', '../input/lsr/') else: return file_path return old_file_path def file_exists_at(revision, name): cmd = "git show %s:Documentation/%s" % (revision, name) if verbose: sys.stderr.write('running: %s\n' % cmd) child = subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True) return not child.returncode revision_re = re.compile(r'GIT [Cc]ommittish:\s+([a-f0-9]+)') no_committish_fatal_error = """error: %s: no 'GIT committish: ' found. Please check the whole file against the original in English, then fill in HEAD committish in the header. """ def check_translated_doc(original, translated_file, translated_contents, color=False, upper_revision='HEAD'): """Returns the diff of the original relative to the last translation""" m = revision_re.search(translated_contents) if not m: sys.stderr.write(no_committish_fatal_error % translated_file) sys.exit(1) revision = m.group(1) if revision == '0': return '', 0 if color: color_flag = '--color --color-words' else: color_flag = '--no-color' current_name = original if original.startswith("en/") and not file_exists_at(revision, original): # this is to handle the rename in 82d72b7 ("Merge branch doc-build") original = original[3:] if not file_exists_at(revision, original): original = get_old_name(original) c = 'git diff -M %(color_flag)s %(revision)s:Documentation/%(original)s \ %(upper_revision)s:Documentation/%(current_name)s' % vars() if verbose: sys.stderr.write('running: %s\n' % c) return read_pipe(c)