blob: c17bbbb20854afaa54070b2c17258c19cdf0a951 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
A script to convert cassandra.yaml into ReStructuredText for
the online documentation.
Usage:
convert_yaml_to_rest.py conf/cassandra.yaml docs/source/conf.rst
"""
import sys
import re
# Detects options, whether commented or uncommented.
# Group 1 will be non-empty if the option is commented out.
# Group 2 will contain the option name.
# Group 3 will contain the default value, if one exists.
option_re = re.compile(r"^(# ?)?([a-z0-9_]+): ?([^/].*)")
# Detects normal comment lines.
commented_re = re.compile(r"^# ?(.*)")
# A set of option names that have complex values (i.e. lists or dicts).
# This list is hardcoded because there did not seem to be another
# good way to reliably detect this case, especially considering
# that these can be commented out (making it useless to use a yaml parser).
COMPLEX_OPTIONS = (
'seed_provider',
'request_scheduler_options',
'data_file_directories',
'commitlog_compression',
'hints_compression',
'server_encryption_options',
'client_encryption_options',
'transparent_data_encryption_options',
'hinted_handoff_disabled_datacenters'
)
def convert(yaml_file, dest_file):
with open(yaml_file, 'r') as f:
# Trim off the boilerplate header
lines = f.readlines()[7:]
with open(dest_file, 'w') as outfile:
outfile.write(".. _cassandra-yaml:\n")
outfile.write("\n")
outfile.write("Cassandra Configuration File\n")
outfile.write("============================\n")
# since comments preceed an option, this holds all of the comment
# lines we've seen since the last option
comments_since_last_option = []
line_iter = iter(lines)
while True:
try:
line = next(line_iter)
except StopIteration:
break
match = option_re.match(line)
if match:
option_name = match.group(2)
is_commented = bool(match.group(1))
is_complex = option_name in COMPLEX_OPTIONS
complex_option = read_complex_option(line_iter) if is_complex else None
write_section_header(option_name, outfile)
write_comments(comments_since_last_option, is_commented, outfile)
if is_complex:
write_complex_option(complex_option, outfile)
else:
maybe_write_default_value(match, outfile)
comments_since_last_option = []
else:
comment_match = commented_re.match(line)
if comment_match:
comments_since_last_option.append(comment_match.group(1))
elif line == "\n":
comments_since_last_option.append('')
def write_section_header(option_name, outfile):
outfile.write("\n")
outfile.write("``%s``\n" % (option_name,))
outfile.write("-" * (len(option_name) + 4) + "\n")
def write_comments(comment_lines, is_commented, outfile):
if is_commented:
outfile.write("*This option is commented out by default.*\n")
for comment in comment_lines:
if "SAFETY THRESHOLDS" not in comment_lines:
outfile.write(comment + "\n")
def maybe_write_default_value(option_match, outfile):
default_value = option_match.group(3)
if default_value and default_value != "\n":
outfile.write("\n*Default Value:* %s\n" % (default_value,))
def read_complex_option(line_iter):
option_lines = []
try:
while True:
line = next(line_iter)
if line == '\n':
return option_lines
else:
option_lines.append(line)
except StopIteration:
return option_lines
def write_complex_option(lines, outfile):
outfile.write("\n*Default Value (complex option)*::\n\n")
for line in lines:
outfile.write((" " * 4) + line)
if __name__ == '__main__':
if len(sys.argv) != 3:
print >> sys.stderr, "Usage: %s <yaml source file> <rst dest file>" % (sys.argv[0],)
sys.exit(1)
yaml_file = sys.argv[1]
dest_file = sys.argv[2]
convert(yaml_file, dest_file)