diff --git a/os_doc_tools/index.py b/os_doc_tools/index.py deleted file mode 100644 index 297ac303..00000000 --- a/os_doc_tools/index.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python - -# Licensed 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. - -import argparse -import glob -import os -import sys - - -def get_pdf_link(root, publish_path): - p = '%s/*.pdf' % root - re = glob.glob(p) - if len(re) == 0: - return '' - filename = os.path.basename(re[0]) - path = os.path.relpath(root, publish_path) - return ' (pdf)' % (path, filename) - - -def generate_index_file(publish_path): - """Generate index.html file in publish_path.""" - - if not os.path.isdir(publish_path): - os.mkdir(publish_path) - - index_file = open(os.path.join(publish_path, 'index.html'), 'w') - - index_file.write( - '\n' - '\n' - '\n' - '

Generated documents

\n') - - links = {} - for root, dirs, files in os.walk(publish_path): - - dirs[:] = [d for d in dirs if d not in ['common', 'webapp', 'content', - 'www', 'samples']] - - # Ignore top-level index.html files - if root == publish_path: - continue - - pdf_link = get_pdf_link(root, publish_path) - - if os.path.isfile(os.path.join(root, 'index.html')): - path = os.path.relpath(root, publish_path) - links[path] = ('%s%s\n' % - (path, path.replace('draft/', ''), pdf_link)) - - for entry in sorted([s for s in links if not s.startswith('draft/')]): - index_file.write(links[entry]) - index_file.write('
\n') - - drafts = [s for s in links if s.startswith('draft/')] - if drafts: - index_file.write('

Draft guides

\n') - for entry in sorted(drafts): - index_file.write(links[entry]) - index_file.write('
\n') - - if os.path.isfile(os.path.join(publish_path, 'www-index.html')): - index_file.write('

WWW index pages

\n') - index_file.write('List of generated ' - 'WWW pages\n') - index_file.write('\n' - '\n') - index_file.close() - - -def main(): - parser = argparse.ArgumentParser(description="Generate index file.") - parser.add_argument('directory', metavar='DIR', - help="Directory to search.") - args = parser.parse_args() - - generate_index_file(args.directory) - -if __name__ == "__main__": - sys.exit(main()) diff --git a/os_doc_tools/jsoncheck.py b/os_doc_tools/jsoncheck.py deleted file mode 100644 index 755052c1..00000000 --- a/os_doc_tools/jsoncheck.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env python - -# Licensed 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. - -""" - -Usage: - jsoncheck.py [-f] FILES - -Checks JSON syntax and optionally reformats (pretty-prints) the valid files. - -Optional: - - demjson Python library (better diagnostics for invalid JSON synax) - -""" - -from __future__ import print_function - -import argparse -import collections -import json -import sys -import textwrap - -try: - import demjson -except ImportError: - demjson = None - sys.stderr.write("Cannot import the demjson Python module. Diagnostics " - "for invalid JSON files\nwill be limited.\n") - -# ----------------------------------------------------------------------------- -# Public interface -# ----------------------------------------------------------------------------- - - -def check_syntax(path): - """Check syntax of one JSON file.""" - _process_file(path) - - -def check_formatting(path): - """Check formatting of one JSON file.""" - _process_file(path, formatting='check') - - -def fix_formatting(path, verbose=False): - """Fix formatting of one JSON file.""" - _process_file(path, formatting='fix', verbose=verbose) - -# ----------------------------------------------------------------------------- -# Implementation details -# ----------------------------------------------------------------------------- - - -def _indent_note(note): - """Indents and wraps a string.""" - indented_note = [] - # Split into single lines in case the argument is pre-formatted. - for line in note.splitlines(): - indented_note.append(textwrap.fill(line, initial_indent=4 * ' ', - subsequent_indent=12 * ' ', - width=80)) - return "\n".join(indented_note) - - -def _get_demjson_diagnostics(raw): - """Get diagnostics string for invalid JSON files from demjson.""" - errstr = None - try: - demjson.decode(raw, strict=True) - except demjson.JSONError as err: - errstr = err.pretty_description() - return errstr - - -class ParserException(Exception): - pass - - -def _parse_json(raw): - """Parse raw JSON file.""" - try: - parsed = json.loads(raw, object_pairs_hook=collections.OrderedDict) - except ValueError as err: - note = str(err) - # if demjson is available, print its diagnostic string as well - if demjson: - demerr = _get_demjson_diagnostics(raw) - if demerr: - note += "\n" + demerr - raise ParserException(note) - else: - return parsed - - -def _format_parsed_json(parsed): - """Pretty-print JSON file content while retaining key order.""" - return json.dumps(parsed, sort_keys=False, separators=(',', ': '), - indent=4) + "\n" - - -def _process_file(path, formatting=None, verbose=False): - """Check syntax/formatting and fix formatting of a JSON file. - - :param formatting: one of 'check' or 'fix' (default: None) - - Raises ValueError if JSON syntax is invalid or reformatting needed. - """ - with open(path, 'r') as infile: - raw = infile.read() - try: - parsed = _parse_json(raw) - except ParserException as err: - raise ValueError(err) - else: - if formatting in ('check', 'fix'): - formatted = _format_parsed_json(parsed) - if formatted != raw: - if formatting == "fix": - with open(path, 'w') as outfile: - outfile.write(formatted) - if verbose: - print("%s\n%s" % (path, - _indent_note("Reformatted"))) - else: - raise ValueError("Reformatting needed") - elif formatting is not None: - # for the benefit of external callers - raise ValueError("Called with invalid formatting value.") - - -def main(): - parser = argparse.ArgumentParser(description="Validate and reformat JSON" - "files.") - parser.add_argument('files', metavar='FILES', nargs='+') - parser.add_argument('-f', '--formatting', choices=['check', 'fix'], - help='check or fix formatting of JSON files') - args = parser.parse_args() - - exit_status = 0 - for path in args.files: - try: - _process_file(path, args.formatting, verbose=True) - except ValueError as err: - print("%s\n%s" % (path, _indent_note(str(err)))) - exit_status = 1 - - return exit_status - -if __name__ == "__main__": - sys.exit(main()) diff --git a/releasenotes/notes/indexpage-ed235f8665f398d7.yaml b/releasenotes/notes/indexpage-ed235f8665f398d7.yaml new file mode 100644 index 00000000..63d9b0f5 --- /dev/null +++ b/releasenotes/notes/indexpage-ed235f8665f398d7.yaml @@ -0,0 +1,4 @@ +upgrade: + - | + The helpers `openstack-indexpage` and `openstack-jsoncheck` are not used + anymore and thus have been removed. diff --git a/setup.cfg b/setup.cfg index ceff14df..a684e935 100644 --- a/setup.cfg +++ b/setup.cfg @@ -32,10 +32,5 @@ scripts = setup-hooks = pbr.hooks.setup_hook -[entry_points] -console_scripts = - openstack-jsoncheck = os_doc_tools.jsoncheck:main - openstack-indexpage = os_doc_tools.index:main - [wheel] universal = 1 diff --git a/test/test_index.py b/test/test_index.py deleted file mode 100644 index e5adade7..00000000 --- a/test/test_index.py +++ /dev/null @@ -1,37 +0,0 @@ -# Licensed 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. - -import mock -from os_doc_tools import index -import unittest - - -class TestGenerateIndex(unittest.TestCase): - def test_dir_created(self): - path = 'path' - with mock.patch.object(index, 'open'): - with mock.patch.object(index.os, 'mkdir') as mock_mkdir: - index.generate_index_file(path) - self.assertTrue(mock_mkdir.called) - - def test_dir_not_created_when_exists(self): - path = 'path' - with mock.patch.object(index, 'open'): - with mock.patch.object(index.os, 'mkdir') as mock_mkdir: - with mock.patch.object(index.os.path, 'isdir', - returned_value=True): - index.generate_index_file(path) - self.assertFalse(mock_mkdir.called) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/test_jsoncheck.py b/test/test_jsoncheck.py deleted file mode 100644 index 09bbd823..00000000 --- a/test/test_jsoncheck.py +++ /dev/null @@ -1,98 +0,0 @@ -# Licensed 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. - -import mock -from os_doc_tools import jsoncheck -import unittest - - -class MockOpen(object): - - def read(self): - return "raw" - - def write(self): - return True - - -class TestFileFunctions(unittest.TestCase): - - def test_indent_note(self): - note = "Hello\nWorld" - with mock.patch.object(jsoncheck.textwrap, 'fill') as mock_fill: - mock_fill.return_value = "Hello World" - jsoncheck._indent_note(note) - mock_fill.assert_any_call('Hello', initial_indent=' ', - subsequent_indent=' ', - width=80) - mock_fill.assert_any_call('World', initial_indent=' ', - subsequent_indent=' ', - width=80) - - def test_get_demjson_diagnostics(self): - raw = "raw" - - with mock.patch.object(jsoncheck.demjson, 'decode', return_value=True): - errstr = jsoncheck._get_demjson_diagnostics(raw) - self.assertTrue(errstr is None) - - with mock.patch.object(jsoncheck.demjson, 'decode') as mock_decode: - mock_decode.side_effect = jsoncheck.demjson.JSONError(raw) - errstr = jsoncheck._get_demjson_diagnostics(raw) - expected_error_str = " Error: raw" - self.assertEqual(errstr, expected_error_str) - - def test_parse_json(self): - raw = "raw" - with mock.patch.object(jsoncheck.json, 'loads', - return_value="Success"): - parsed = jsoncheck._parse_json(raw) - self.assertEqual(parsed, "Success") - - with mock.patch.object(jsoncheck.json, 'loads') as mock_loads: - mock_loads.side_effect = ValueError() - with self.assertRaises(jsoncheck.ParserException): - parsed = jsoncheck._parse_json(raw) - - def test_format_parsed_json(self): - with mock.patch.object(jsoncheck.json, 'dumps') as mock_dumps: - mock_dumps.return_value = "Success" - returned_value = jsoncheck._format_parsed_json('raw') - self.assertEqual(returned_value, "Success\n") - self.assertTrue(mock_dumps.called) - - def test_process_file(self): - with mock.patch.object(jsoncheck, 'open', returned_value=MockOpen()): - with mock.patch.object(jsoncheck, '_parse_json') as mock_parse: - mock_parse.side_effect = jsoncheck.ParserException - with self.assertRaises(ValueError): - jsoncheck._process_file('path') - - with mock.patch.object(jsoncheck, 'open', returned_value=MockOpen()): - with mock.patch.object(jsoncheck, '_parse_json', - returned_value="Success"): - with mock.patch.object(jsoncheck, '_format_parsed_json', - returned_value="not_raw"): - with self.assertRaises(ValueError): - jsoncheck._process_file('path', 'check') - - with mock.patch.object(jsoncheck, 'open', returned_value=MockOpen()): - with mock.patch.object(jsoncheck, '_parse_json', - returned_value="Success"): - with mock.patch.object(jsoncheck, '_format_parsed_json', - returned_value="not_raw"): - with self.assertRaises(ValueError): - jsoncheck._process_file('path', 'formatting') - - -if __name__ == '__main__': - unittest.main()