1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2025-06-17 00:07:37 +02:00

add multiline value support to env parser

This commit is contained in:
Kelly Brazil
2023-10-02 16:30:56 -07:00
parent 0b8fb31298
commit d4604743d1
7 changed files with 79 additions and 19 deletions

View File

@ -1,10 +1,11 @@
jc changelog jc changelog
20231001 v1.23.5 20231002 v1.23.5
- Add `host` command parser - Add `host` command parser
- Add `nsd-control` command parser - Add `nsd-control` command parser
- Add `lsb_release` command parser - Add `lsb_release` command parser
- Add `/etc/os-release` file parser - Add `/etc/os-release` file parser
- Enhance `env` command parser to support multi-line values
- Enhance `ping` and `ping-s` parsers to add error and corrupted support - Enhance `ping` and `ping-s` parsers to add error and corrupted support
- Enhance `xml` parser to include comments in the JSON output - Enhance `xml` parser to include comments in the JSON output
- Fix `pidstat` command parser when using `-T ALL` - Fix `pidstat` command parser when using `-T ALL`

View File

@ -90,10 +90,10 @@ Parameters:
Returns: Returns:
Dictionary of raw structured data or Dictionary of raw structured data or (default)
List of Dictionaries of processed structured data List of Dictionaries of processed structured data (raw)
### Parser Information ### Parser Information
Compatibility: linux, darwin, cygwin, win32, aix, freebsd Compatibility: linux, darwin, cygwin, win32, aix, freebsd
Version 1.4 by Kelly Brazil (kellyjonbrazil@gmail.com) Version 1.5 by Kelly Brazil (kellyjonbrazil@gmail.com)

View File

@ -67,12 +67,13 @@ Examples:
"_": "/usr/bin/env" "_": "/usr/bin/env"
} }
""" """
import re
import jc.utils import jc.utils
class info(): class info():
"""Provides parser metadata (version, author, etc.)""" """Provides parser metadata (version, author, etc.)"""
version = '1.4' version = '1.5'
description = '`env` command parser' description = '`env` command parser'
author = 'Kelly Brazil' author = 'Kelly Brazil'
author_email = 'kellyjonbrazil@gmail.com' author_email = 'kellyjonbrazil@gmail.com'
@ -83,6 +84,7 @@ class info():
__version__ = info.version __version__ = info.version
VAR_DEF_PATTERN = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*=\S*.*$')
def _process(proc_data): def _process(proc_data):
""" """
@ -96,8 +98,6 @@ def _process(proc_data):
List of Dictionaries. Structured data to conform to the schema. List of Dictionaries. Structured data to conform to the schema.
""" """
# rebuild output for added semantic information
processed = [] processed = []
for k, v in proc_data.items(): for k, v in proc_data.items():
proc_line = {} proc_line = {}
@ -120,24 +120,29 @@ def parse(data, raw=False, quiet=False):
Returns: Returns:
Dictionary of raw structured data or Dictionary of raw structured data or (default)
List of Dictionaries of processed structured data List of Dictionaries of processed structured data (raw)
""" """
jc.utils.compatibility(__name__, info.compatible, quiet) jc.utils.compatibility(__name__, info.compatible, quiet)
jc.utils.input_type_check(data) jc.utils.input_type_check(data)
raw_output = {} raw_output = {}
key = ''
# Clear any blank lines value = None
cleandata = list(filter(None, data.splitlines()))
if jc.utils.has_data(data): if jc.utils.has_data(data):
for line in data.splitlines():
if VAR_DEF_PATTERN.match(line):
if not value is None:
raw_output[key] = value
key, value = line.split('=', maxsplit=1)
continue
for entry in cleandata: if not value is None:
parsed_line = entry.split('=', maxsplit=1) value = value + '\n' + line
raw_output[parsed_line[0]] = parsed_line[1]
if not value is None:
raw_output[key] = value
return raw_output if raw else _process(raw_output)
if raw:
return raw_output
else:
return _process(raw_output)

View File

@ -0,0 +1 @@
{"TERM_PROGRAM":"Apple_Terminal","SHELL":"/bin/zsh","TERM":"xterm-256color","TMPDIR":"/var/folders/8g/r6tdh9kj6z35x9rfmgtt3x6r0000gn/T/","TERM_PROGRAM_VERSION":"447","TERM_SESSION_ID":"A7F0FFB1-C12A-42EA-A8D9-0757BB2D4DDE","USER":"kelly","SSH_AUTH_SOCK":"/private/tmp/com.apple.launchd.6IQJQijqVl/Listeners","PATH":"/Users/kelly/.pyenv/shims:/Users/kelly/.gem/ruby/2.6.0/bin:/Users/kelly/.local/bin:/Users/kelly/.cargo/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin","LaunchInstanceID":"3D00D30B-5C8B-421F-958D-91B196167506","__CFBundleIdentifier":"com.apple.Terminal","PWD":"/Users/kelly/temp","XPC_FLAGS":"0x0","XPC_SERVICE_NAME":"0","SHLVL":"1","HOME":"/Users/kelly","LOGNAME":"kelly","SECURITYSESSIONID":"186a3","OLDPWD":"/Users/kelly/git/jc/tests/fixtures/ubuntu-22.04","JC_COLORS":"cyan,default,default,default","JELLO_COLORS":"cyan,default,default,default","PYENV_ROOT":"/Users/kelly/.pyenv","PYENV_SHELL":"zsh","MYVAR":"hello world","hello":"world","KELLYVAR":"This is a multiline\nvariable that has var=1 a definition\ninside of it","LANG":"en_US.UTF-8","_":"/usr/bin/env"}

View File

@ -0,0 +1 @@
[{"name":"TERM_PROGRAM","value":"Apple_Terminal"},{"name":"SHELL","value":"/bin/zsh"},{"name":"TERM","value":"xterm-256color"},{"name":"TMPDIR","value":"/var/folders/8g/r6tdh9kj6z35x9rfmgtt3x6r0000gn/T/"},{"name":"TERM_PROGRAM_VERSION","value":"447"},{"name":"TERM_SESSION_ID","value":"A7F0FFB1-C12A-42EA-A8D9-0757BB2D4DDE"},{"name":"USER","value":"kelly"},{"name":"SSH_AUTH_SOCK","value":"/private/tmp/com.apple.launchd.6IQJQijqVl/Listeners"},{"name":"PATH","value":"/Users/kelly/.pyenv/shims:/Users/kelly/.gem/ruby/2.6.0/bin:/Users/kelly/.local/bin:/Users/kelly/.cargo/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin"},{"name":"LaunchInstanceID","value":"3D00D30B-5C8B-421F-958D-91B196167506"},{"name":"__CFBundleIdentifier","value":"com.apple.Terminal"},{"name":"PWD","value":"/Users/kelly/temp"},{"name":"XPC_FLAGS","value":"0x0"},{"name":"XPC_SERVICE_NAME","value":"0"},{"name":"SHLVL","value":"1"},{"name":"HOME","value":"/Users/kelly"},{"name":"LOGNAME","value":"kelly"},{"name":"SECURITYSESSIONID","value":"186a3"},{"name":"OLDPWD","value":"/Users/kelly/git/jc/tests/fixtures/ubuntu-22.04"},{"name":"JC_COLORS","value":"cyan,default,default,default"},{"name":"JELLO_COLORS","value":"cyan,default,default,default"},{"name":"PYENV_ROOT","value":"/Users/kelly/.pyenv"},{"name":"PYENV_SHELL","value":"zsh"},{"name":"MYVAR","value":"hello world"},{"name":"hello","value":"world"},{"name":"KELLYVAR","value":"This is a multiline\nvariable that has var=1 a definition\ninside of it"},{"name":"LANG","value":"en_US.UTF-8"},{"name":"_","value":"/usr/bin/env"}]

View File

@ -0,0 +1,30 @@
TERM_PROGRAM=Apple_Terminal
SHELL=/bin/zsh
TERM=xterm-256color
TMPDIR=/var/folders/8g/r6tdh9kj6z35x9rfmgtt3x6r0000gn/T/
TERM_PROGRAM_VERSION=447
TERM_SESSION_ID=A7F0FFB1-C12A-42EA-A8D9-0757BB2D4DDE
USER=kelly
SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.6IQJQijqVl/Listeners
PATH=/Users/kelly/.pyenv/shims:/Users/kelly/.gem/ruby/2.6.0/bin:/Users/kelly/.local/bin:/Users/kelly/.cargo/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin
LaunchInstanceID=3D00D30B-5C8B-421F-958D-91B196167506
__CFBundleIdentifier=com.apple.Terminal
PWD=/Users/kelly/temp
XPC_FLAGS=0x0
XPC_SERVICE_NAME=0
SHLVL=1
HOME=/Users/kelly
LOGNAME=kelly
SECURITYSESSIONID=186a3
OLDPWD=/Users/kelly/git/jc/tests/fixtures/ubuntu-22.04
JC_COLORS=cyan,default,default,default
JELLO_COLORS=cyan,default,default,default
PYENV_ROOT=/Users/kelly/.pyenv
PYENV_SHELL=zsh
MYVAR=hello world
hello=world
KELLYVAR=This is a multiline
variable that has var=1 a definition
inside of it
LANG=en_US.UTF-8
_=/usr/bin/env

View File

@ -7,6 +7,7 @@ THIS_DIR = os.path.dirname(os.path.abspath(__file__))
class MyTests(unittest.TestCase): class MyTests(unittest.TestCase):
maxDiff = None
# input # input
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/env.out'), 'r', encoding='utf-8') as f: with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/env.out'), 'r', encoding='utf-8') as f:
@ -15,6 +16,9 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/env.out'), 'r', encoding='utf-8') as f: with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/env.out'), 'r', encoding='utf-8') as f:
ubuntu_18_4_env = f.read() ubuntu_18_4_env = f.read()
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/env-multiline.out'), 'r', encoding='utf-8') as f:
env_multiline = f.read()
# output # output
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/env.json'), 'r', encoding='utf-8') as f: with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/env.json'), 'r', encoding='utf-8') as f:
centos_7_7_env_json = json.loads(f.read()) centos_7_7_env_json = json.loads(f.read())
@ -22,6 +26,12 @@ class MyTests(unittest.TestCase):
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/env.json'), 'r', encoding='utf-8') as f: with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/ubuntu-18.04/env.json'), 'r', encoding='utf-8') as f:
ubuntu_18_4_env_json = json.loads(f.read()) ubuntu_18_4_env_json = json.loads(f.read())
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/env-multiline.json'), 'r', encoding='utf-8') as f:
env_multiline_json = json.loads(f.read())
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/generic/env-multiline-raw.json'), 'r', encoding='utf-8') as f:
env_multiline_raw_json = json.loads(f.read())
def test_env_nodata(self): def test_env_nodata(self):
""" """
@ -41,6 +51,18 @@ class MyTests(unittest.TestCase):
""" """
self.assertEqual(jc.parsers.env.parse(self.ubuntu_18_4_env, quiet=True), self.ubuntu_18_4_env_json) self.assertEqual(jc.parsers.env.parse(self.ubuntu_18_4_env, quiet=True), self.ubuntu_18_4_env_json)
def test_env_multiline(self):
"""
Test 'env' with multiline value
"""
self.assertEqual(jc.parsers.env.parse(self.env_multiline, quiet=True), self.env_multiline_json)
def test_env_multiline_raw(self):
"""
Test 'env' with multiline value with raw output
"""
self.assertEqual(jc.parsers.env.parse(self.env_multiline, quiet=True, raw=True), self.env_multiline_raw_json)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()