From f19a1f23a9a551b0cc12e6ebb92a583ed49d23a2 Mon Sep 17 00:00:00 2001 From: solomonleang <124934439+solomonleang@users.noreply.github.com> Date: Fri, 23 Jun 2023 11:38:56 -0400 Subject: [PATCH] Added find parser and tests for Centos 7.7 and Ubuntu 18.04 (#430) * Added find parser and tests for Centos 7.7 and Ubuntu 18.04 * Added a test file, changed logic, and included a case for permission denied returned by find. * Added a few more lines to the tests * Changed logic for setting values to null and updated test cases. --- jc/lib.py | 1 + jc/parsers/find.py | 133 ++++++++++++++++++++++++++ tests/fixtures/centos-7.7/find.json | 13 +++ tests/fixtures/centos-7.7/find.out | 13 +++ tests/fixtures/ubuntu-18.04/find.json | 13 +++ tests/fixtures/ubuntu-18.04/find.out | 13 +++ tests/test_find.py | 43 +++++++++ 7 files changed, 229 insertions(+) create mode 100644 jc/parsers/find.py create mode 100644 tests/fixtures/centos-7.7/find.json create mode 100644 tests/fixtures/centos-7.7/find.out create mode 100644 tests/fixtures/ubuntu-18.04/find.json create mode 100644 tests/fixtures/ubuntu-18.04/find.out create mode 100644 tests/test_find.py diff --git a/jc/lib.py b/jc/lib.py index 526a8606..790265e9 100644 --- a/jc/lib.py +++ b/jc/lib.py @@ -43,6 +43,7 @@ parsers: List[str] = [ 'email-address', 'env', 'file', + 'find', 'findmnt', 'finger', 'free', diff --git a/jc/parsers/find.py b/jc/parsers/find.py new file mode 100644 index 00000000..9b03cbc5 --- /dev/null +++ b/jc/parsers/find.py @@ -0,0 +1,133 @@ +"""jc - JSON Convert `find` command output parser + +Usage (cli): + + $ find | jc --find + +Usage (module): + + import jc + result = jc.parse('find', find_command_output) + +Schema: + + [ + { + "path": string, + "node": string, + "error": string + } + ] + +Examples: + + $ find | jc --find -p + [ + { + "path": "./directory" + "node": "filename" + }, + { + "path": "./anotherdirectory" + "node": "anotherfile" + }, + { + "path": null + "node": null + "error": "find: './inaccessible': Permission denied" + } + ... + ] + + $ find | jc --find -p -r + [ + "./templates/readme_template", + "./templates/manpage_template", + "./.github/workflows/pythonapp.yml", + ... + ] +""" +import jc.utils + + +class info(): + """Provides parser metadata (version, author, etc.)""" + version = '1.0' + description = '`find` command parser' + author = 'Solomon Leang' + author_email = 'solomonleang@gmail.com' + compatible = ['linux'] + tags = ['command'] + + +__version__ = info.version + + +def _process(proc_data): + """ + Final processing to conform to the schema. + + Parameters: + + proc_data: (Dictionary) raw structured data to process + + Returns: + + List of Dictionaries. Structured data to conform to the schema. + """ + + processed = [] + for index in proc_data: + path, node, error = "", "", "" + + if (index == "."): + node = "." + elif index.startswith('find: '): + error = index + else: + try: + path, node = index.rsplit('/', maxsplit=1) + except ValueError: + pass + + proc_line = { + 'path': path if path else None, + 'node': node if node else None + } + if error: + proc_line.update( + {'error': error} + ) + + processed.append(proc_line) + return processed + + + +def parse(data, raw=False, quiet=False): + """ + Main text parsing function + + Parameters: + + data: (string) text data to parse + raw: (boolean) unprocessed output if True + quiet: (boolean) suppress warning messages if True + + Returns: + + Dictionary of raw structured data or + List of Dictionaries of processed structured data + """ + jc.utils.compatibility(__name__, info.compatible, quiet) + jc.utils.input_type_check(data) + + raw_output = [] + + if jc.utils.has_data(data): + raw_output = data.splitlines() + + if raw: + return raw_output + else: + return _process(raw_output) \ No newline at end of file diff --git a/tests/fixtures/centos-7.7/find.json b/tests/fixtures/centos-7.7/find.json new file mode 100644 index 00000000..4ae23e90 --- /dev/null +++ b/tests/fixtures/centos-7.7/find.json @@ -0,0 +1,13 @@ +[{"path": null, "node": "."}, +{"path":".","node":null}, +{"path": ".","node": "jc"}, +{"path": "./jc","node": "tests"}, +{"path": "./jc/tests","node": "test_find.py"}, +{"path": "./jc/tests","node": "test_history.py"}, +{"path": "./jc/tests","node": "test_hosts.py"}, +{"path": "./jc","node": "anotherdirectory"}, +{"path": null,"node": null,"error": "find: './inaccessible': Permission denied"}, +{"path": "./jc","node": "directory2"}, +{"path": "./jc/directory2","node": "file.txt"}, +{"path": "./jc/directory2","node": "file2.txt"}, +{"path": ".","node": "newfile.txt"}] \ No newline at end of file diff --git a/tests/fixtures/centos-7.7/find.out b/tests/fixtures/centos-7.7/find.out new file mode 100644 index 00000000..d7526181 --- /dev/null +++ b/tests/fixtures/centos-7.7/find.out @@ -0,0 +1,13 @@ +. +./ +./jc +./jc/tests +./jc/tests/test_find.py +./jc/tests/test_history.py +./jc/tests/test_hosts.py +./jc/anotherdirectory +find: './inaccessible': Permission denied +./jc/directory2 +./jc/directory2/file.txt +./jc/directory2/file2.txt +./newfile.txt \ No newline at end of file diff --git a/tests/fixtures/ubuntu-18.04/find.json b/tests/fixtures/ubuntu-18.04/find.json new file mode 100644 index 00000000..4ae23e90 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/find.json @@ -0,0 +1,13 @@ +[{"path": null, "node": "."}, +{"path":".","node":null}, +{"path": ".","node": "jc"}, +{"path": "./jc","node": "tests"}, +{"path": "./jc/tests","node": "test_find.py"}, +{"path": "./jc/tests","node": "test_history.py"}, +{"path": "./jc/tests","node": "test_hosts.py"}, +{"path": "./jc","node": "anotherdirectory"}, +{"path": null,"node": null,"error": "find: './inaccessible': Permission denied"}, +{"path": "./jc","node": "directory2"}, +{"path": "./jc/directory2","node": "file.txt"}, +{"path": "./jc/directory2","node": "file2.txt"}, +{"path": ".","node": "newfile.txt"}] \ No newline at end of file diff --git a/tests/fixtures/ubuntu-18.04/find.out b/tests/fixtures/ubuntu-18.04/find.out new file mode 100644 index 00000000..d7526181 --- /dev/null +++ b/tests/fixtures/ubuntu-18.04/find.out @@ -0,0 +1,13 @@ +. +./ +./jc +./jc/tests +./jc/tests/test_find.py +./jc/tests/test_history.py +./jc/tests/test_hosts.py +./jc/anotherdirectory +find: './inaccessible': Permission denied +./jc/directory2 +./jc/directory2/file.txt +./jc/directory2/file2.txt +./newfile.txt \ No newline at end of file diff --git a/tests/test_find.py b/tests/test_find.py new file mode 100644 index 00000000..b7dca7d4 --- /dev/null +++ b/tests/test_find.py @@ -0,0 +1,43 @@ +import os +import unittest +import json +import jc.parsers.find + +THIS_DIR = os.path.dirname(os.path.abspath(__file__)) + +class MyTests(unittest.TestCase): + + # input + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/find.out'), 'r', encoding='utf-8') as f: + centos_7_7_find = f.read() + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/find.out'), 'r', encoding='utf-8') as f: + ubuntu_18_4_find = f.read() + + #output + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/find.json'), 'r', encoding='utf-8') as f: + centos_7_7_find_json = json.loads(f.read()) + + with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/find.json'), 'r', encoding='utf-8') as f: + ubuntu_18_4_find_json = json.loads(f.read()) + + def test_find_nodata(self): + """ + Test 'find' with no data + """ + self.assertEqual(jc.parsers.find.parse('', quiet=True), []) + + def test_find_centos_7_7(self): + """ + Test 'find' on Centos 7.7 + """ + self.assertEqual(jc.parsers.find.parse(self.centos_7_7_find, quiet=True), self.centos_7_7_find_json) + + def test_find_ubuntu_18_4(self): + """ + Test 'find' on Ubuntu 18.4 + """ + self.assertEqual(jc.parsers.find.parse(self.ubuntu_18_4_find, quiet=True), self.ubuntu_18_4_find_json) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file