cloudflare/ClickHouse
Publicmirrored fromhttps://github.com/cloudflare/ClickHouse
docs/tools/easy_diff.py
146lines · modecode
6 years ago
| 1 | #!/usr/bin/env python |
| 2 | # -*- coding: utf-8 -*- |
| 3 | |
| 4 | import os, sys |
| 5 | import argparse |
| 6 | import subprocess |
| 7 | import contextlib |
| 8 | from git import cmd |
| 9 | from tempfile import NamedTemporaryFile |
| 10 | |
| 11 | SCRIPT_DESCRIPTION = ''' |
| 12 | usage: ./easy_diff.py language/document path |
| 13 | |
| 14 | Show the difference between a language document and an English document. |
| 15 | |
| 16 | This script is based on the assumption that documents in other languages are fully synchronized with the en document at a commit. |
| 17 | |
| 18 | For example: |
| 19 | Execute: |
| 20 | ./easy_diff.py --no-pager zh/data_types |
| 21 | Output: |
| 22 | Need translate document:~/ClickHouse/docs/en/data_types/uuid.md |
| 23 | Need link document:~/ClickHouse/docs/en/data_types/decimal.md to ~/ClickHouse/docs/zh/data_types/decimal.md |
| 24 | diff --git a/docs/en/data_types/domains/ipv6.md b/docs/en/data_types/domains/ipv6.md |
| 25 | index 1bfbe3400b..e2abaff017 100644 |
| 26 | --- a/docs/en/data_types/domains/ipv6.md |
| 27 | +++ b/docs/en/data_types/domains/ipv6.md |
| 28 | @@ -4,13 +4,13 @@ |
| 29 | |
| 30 | ### Basic Usage |
| 31 | |
| 32 | -``` sql |
| 33 | +```sql |
| 34 | CREATE TABLE hits (url String, from IPv6) ENGINE = MergeTree() ORDER BY url; |
| 35 | |
| 36 | DESCRIBE TABLE hits; |
| 37 | ``` |
| 38 | |
| 39 | -``` |
| 40 | +```text |
| 41 | ┌─name─┬─type───┬─default_type─┬─default_expression─┬─comment─┬─codec_expression─┐ |
| 42 | │ url │ String │ │ │ │ │ |
| 43 | │ from │ IPv6 │ │ │ │ │ |
| 44 | @@ -19,19 +19,19 @@ DESCRIBE TABLE hits; |
| 45 | |
| 46 | OR you can use `IPv6` domain as a key: |
| 47 | |
| 48 | -``` sql |
| 49 | +```sql |
| 50 | CREATE TABLE hits (url String, from IPv6) ENGINE = MergeTree() ORDER BY from; |
| 51 | ... MORE |
| 52 | |
| 53 | OPTIONS: |
| 54 | -h, --help show this help message and exit |
| 55 | --no-pager use stdout as difference result output |
| 56 | ''' |
| 57 | |
| 58 | SCRIPT_PATH = os.path.abspath(__file__) |
| 59 | CLICKHOUSE_REPO_HOME = os.path.join(os.path.dirname(SCRIPT_PATH), '..', '..') |
| 60 | SCRIPT_COMMAND_EXECUTOR = cmd.Git(CLICKHOUSE_REPO_HOME) |
| 61 | |
| 62 | SCRIPT_COMMAND_PARSER = argparse.ArgumentParser(add_help=False) |
| 63 | SCRIPT_COMMAND_PARSER.add_argument('path', type=bytes, nargs='?', default=None) |
| 64 | SCRIPT_COMMAND_PARSER.add_argument('--no-pager', action='store_true', default=False) |
| 65 | SCRIPT_COMMAND_PARSER.add_argument('-h', '--help', action='store_true', default=False) |
| 66 | |
| 67 | |
| 68 | def execute(commands): |
| 69 | return SCRIPT_COMMAND_EXECUTOR.execute(commands) |
| 70 | |
| 71 | |
| 72 | def get_hash(file_name): |
| 73 | return execute(['git', 'log', '-n', '1', '--pretty=format:"%H"', file_name]) |
| 74 | |
| 75 | |
| 76 | def diff_file(reference_file, working_file, out): |
| 77 | if not os.path.exists(reference_file): |
| 78 | raise RuntimeError('reference file [' + os.path.abspath(reference_file) + '] is not exists.') |
| 79 | |
| 80 | if os.path.islink(working_file): |
| 81 | out.writelines(["Need translate document:" + os.path.abspath(reference_file)]) |
| 82 | elif not os.path.exists(working_file): |
| 83 | out.writelines(['Need link document ' + os.path.abspath(reference_file) + ' to ' + os.path.abspath(working_file)]) |
| 84 | elif get_hash(working_file) != get_hash(reference_file): |
| 85 | out.writelines([(execute(['git', 'diff', get_hash(working_file).strip('"'), reference_file]).encode('utf-8'))]) |
| 86 | |
| 87 | return 0 |
| 88 | |
| 89 | |
| 90 | def diff_directory(reference_directory, working_directory, out): |
| 91 | if not os.path.isdir(reference_directory): |
| 92 | return diff_file(reference_directory, working_directory, out) |
| 93 | |
| 94 | for list_item in os.listdir(reference_directory): |
| 95 | working_item = os.path.join(working_directory, list_item) |
| 96 | reference_item = os.path.join(reference_directory, list_item) |
| 97 | if diff_file(reference_item, working_item, out) if os.path.isfile(reference_item) else diff_directory(reference_item, working_item, out) != 0: |
| 98 | return 1 |
| 99 | |
| 100 | return 0 |
| 101 | |
| 102 | |
| 103 | def find_language_doc(custom_document, other_language='en', children=[]): |
| 104 | if len(custom_document) == 0: |
| 105 | raise RuntimeError('The ' + os.path.join(custom_document, *children) + " is not in docs directory.") |
| 106 | |
| 107 | if os.path.samefile(os.path.join(CLICKHOUSE_REPO_HOME, 'docs'), custom_document): |
| 108 | return os.path.join(CLICKHOUSE_REPO_HOME, 'docs', other_language, *children[1:]) |
| 109 | children.insert(0, os.path.split(custom_document)[1]) |
| 110 | return find_language_doc(os.path.split(custom_document)[0], other_language, children) |
| 111 | |
| 112 | |
| 113 | class ToPager: |
| 114 | def __init__(self, temp_named_file): |
| 115 | self.temp_named_file = temp_named_file |
| 116 | |
| 117 | def writelines(self, lines): |
| 118 | self.temp_named_file.writelines(lines) |
| 119 | |
| 120 | def close(self): |
| 121 | self.temp_named_file.flush() |
| 122 | git_pager = execute(['git', 'var', 'GIT_PAGER']) |
| 123 | subprocess.check_call([git_pager, self.temp_named_file.name]) |
| 124 | self.temp_named_file.close() |
| 125 | |
| 126 | |
| 127 | class ToStdOut: |
| 128 | def writelines(self, lines): |
| 129 | self.system_stdout_stream.writelines(lines) |
| 130 | |
| 131 | def close(self): |
| 132 | self.system_stdout_stream.flush() |
| 133 | |
| 134 | def __init__(self, system_stdout_stream): |
| 135 | self.system_stdout_stream = system_stdout_stream |
| 136 | |
| 137 | |
| 138 | if __name__ == '__main__': |
| 139 | arguments = SCRIPT_COMMAND_PARSER.parse_args() |
| 140 | if arguments.help or not arguments.path: |
| 141 | sys.stdout.write(SCRIPT_DESCRIPTION) |
| 142 | sys.exit(0) |
| 143 | |
| 144 | working_language = os.path.join(CLICKHOUSE_REPO_HOME, 'docs', arguments.path) |
| 145 | with contextlib.closing(ToStdOut(sys.stdout) if arguments.no_pager else ToPager(NamedTemporaryFile('r+'))) as writer: |
| 146 | exit(diff_directory(find_language_doc(working_language), working_language, writer)) |