| # 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 use nodetool to generate documentation for nodetool |
| """ |
| from __future__ import print_function |
| |
| import os |
| import re |
| import sys |
| import subprocess |
| from subprocess import PIPE |
| from subprocess import Popen |
| from itertools import islice |
| from threading import Thread |
| |
| batch_size = 3 |
| |
| if(os.environ.get("SKIP_NODETOOL") == "1"): |
| sys.exit(0) |
| |
| |
| nodetool = "../bin/nodetool" |
| outdir = "modules/cassandra/pages/tools/nodetool" |
| examplesdir = "modules/cassandra/examples/TEXT/NODETOOL" |
| helpfilename = outdir + "/nodetool.txt" |
| command_re = re.compile("( )([_a-z]+)") |
| commandADOCContent = "== {0}\n\n== Usage\n[source,plaintext]\n----\ninclude::example$TEXT/NODETOOL/{0}.txt[]\n----\n" |
| |
| # https://docs.python.org/3/library/itertools.html#itertools-recipes |
| def batched(iterable, n): |
| "Batch data into tuples of length n. The last batch may be shorter." |
| # batched('ABCDEFG', 3) --> ABC DEF G |
| if n < 1: |
| raise ValueError('n must be at least one') |
| it = iter(iterable) |
| batch = tuple(islice(it, n)) |
| while (batch): |
| yield batch |
| batch = tuple(islice(it, n)) |
| |
| # create the documentation directory |
| if not os.path.exists(outdir): |
| os.makedirs(outdir) |
| |
| # create the base help file to use for discovering the commands |
| def create_help_file(): |
| with open(helpfilename, "w+") as output_file: |
| try: |
| subprocess.check_call([nodetool, "help"], stdout=output_file) |
| except subprocess.CalledProcessError as cpe: |
| print( |
| 'ERROR: Nodetool failed to run, you likely need to build ' |
| 'cassandra using ant jar from the top level directory' |
| ) |
| raise cpe |
| |
| # for a given command, create the help file and an ADOC file to contain it |
| def create_adoc(command): |
| if command: |
| cmdName = command.group(0).strip() |
| cmdFilename = examplesdir + "/" + cmdName + ".txt" |
| adocFilename = outdir + "/" + cmdName + ".adoc" |
| with open(cmdFilename, "wb+") as cmdFile: |
| proc = Popen([nodetool, "help", cmdName], stdin=PIPE, stdout=PIPE) |
| (out, err) = proc.communicate() |
| cmdFile.write(out) |
| with open(adocFilename, "w+") as adocFile: |
| adocFile.write(commandADOCContent.format(cmdName,cmdName,cmdName)) |
| |
| # create base file |
| create_help_file() |
| |
| # create the main usage page |
| with open(outdir + "/nodetool.adoc", "w+") as output: |
| with open(helpfilename, "r+") as helpfile: |
| output.write("== Nodetool\n\n== Usage\n\n") |
| for commandLine in helpfile: |
| command = command_re.sub(r'\nxref:tools/nodetool/\2.adoc[\2] - ',commandLine) |
| output.write(command) |
| |
| # create the command usage pages |
| with open(helpfilename, "r+") as helpfile: |
| for clis in batched(helpfile, batch_size): |
| threads = [] |
| for commandLine in clis: |
| command = command_re.match(commandLine) |
| t = Thread(target=create_adoc, args=[command]) |
| threads.append(t) |
| t.start() |
| for t in threads: |
| t.join() |