mirror of
https://github.com/kellyjonbrazil/jc.git
synced 2025-06-17 00:07:37 +02:00
add ver parser
This commit is contained in:
@ -1,8 +1,9 @@
|
||||
jc changelog
|
||||
|
||||
20230122 v1.23.0
|
||||
20230125 v1.23.0
|
||||
- Add input slicing as a `jc` command-line option
|
||||
- Add `ssh` configuration file parser
|
||||
- Add input slicing
|
||||
- Add `ver` Version string parser
|
||||
- Fix `acpi` command parser for "will never fully discharge" battery state
|
||||
|
||||
20230111 v1.22.5
|
||||
|
@ -190,6 +190,7 @@ parsers: List[str] = [
|
||||
'upower',
|
||||
'uptime',
|
||||
'url',
|
||||
'ver',
|
||||
'vmstat',
|
||||
'vmstat-s',
|
||||
'w',
|
||||
|
151
jc/parsers/ver.py
Normal file
151
jc/parsers/ver.py
Normal file
@ -0,0 +1,151 @@
|
||||
"""jc - JSON Convert Version string output parser
|
||||
|
||||
Best effort attempt to parse various styles of version numbers. This parser
|
||||
is based off of the version parser included in the CPython distutils
|
||||
libary.
|
||||
|
||||
If the version string conforms to some de facto-standard versioning rules
|
||||
followed by many developers a `strict` key will be present in the output
|
||||
with a value of `true` along with the named parsed components.
|
||||
|
||||
All other version strings will have a `strict` value of `false` and a
|
||||
`components` key will contain a list of detected parts of the version
|
||||
string.
|
||||
|
||||
Usage (cli):
|
||||
|
||||
$ echo '1.2b' | jc --ver
|
||||
|
||||
|
||||
Usage (module):
|
||||
|
||||
import jc
|
||||
result = jc.parse('ver', version_string_output)
|
||||
|
||||
Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"version": string,
|
||||
"bar": boolean,
|
||||
"baz": integer
|
||||
}
|
||||
]
|
||||
|
||||
Examples:
|
||||
|
||||
$ echo '1.2b' | jc --ver -p
|
||||
[]
|
||||
"""
|
||||
import re
|
||||
from typing import List, Dict
|
||||
from jc.jc_types import JSONDictType
|
||||
import jc.utils
|
||||
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.0'
|
||||
description = 'Version string parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
details = 'Based on distutils/version.py from CPython 3.9.5'
|
||||
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
|
||||
tags = ['generic', 'string']
|
||||
|
||||
|
||||
__version__ = info.version
|
||||
|
||||
|
||||
def _process(proc_data: JSONDictType) -> JSONDictType:
|
||||
"""
|
||||
Final processing to conform to the schema.
|
||||
|
||||
Parameters:
|
||||
|
||||
proc_data: (List of Dictionaries) raw structured data to process
|
||||
|
||||
Returns:
|
||||
|
||||
List of Dictionaries. Structured to conform to the schema.
|
||||
"""
|
||||
return proc_data
|
||||
|
||||
|
||||
def strict_parse(vstring):
|
||||
version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$', re.VERBOSE)
|
||||
match = version_re.match(vstring)
|
||||
if not match:
|
||||
raise ValueError("invalid version number '%s'" % vstring)
|
||||
|
||||
(major, minor, patch, prerelease, prerelease_num) = \
|
||||
match.group(1, 2, 4, 5, 6)
|
||||
|
||||
if patch:
|
||||
version = tuple(map(int, [major, minor, patch]))
|
||||
else:
|
||||
version = tuple(map(int, [major, minor])) + (0,)
|
||||
|
||||
if prerelease:
|
||||
prerelease = (prerelease[0], int(prerelease_num))
|
||||
else:
|
||||
prerelease = None
|
||||
|
||||
return {
|
||||
'major': major,
|
||||
'minor': minor,
|
||||
'patch': patch,
|
||||
'prerelease': prerelease,
|
||||
'prerelease_num': prerelease_num
|
||||
}
|
||||
|
||||
|
||||
def loose_parse(vstring):
|
||||
component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE)
|
||||
components = [x for x in component_re.split(vstring) if x and x != '.']
|
||||
|
||||
return components
|
||||
|
||||
|
||||
def parse(
|
||||
data: str,
|
||||
raw: bool = False,
|
||||
quiet: bool = False
|
||||
) -> JSONDictType:
|
||||
"""
|
||||
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:
|
||||
|
||||
List of Dictionaries. Raw or processed structured data.
|
||||
"""
|
||||
jc.utils.compatibility(__name__, info.compatible, quiet)
|
||||
jc.utils.input_type_check(data)
|
||||
|
||||
raw_output: Dict = {}
|
||||
strict = True
|
||||
|
||||
if jc.utils.has_data(data):
|
||||
|
||||
# based on distutils/version.py from CPython 3.9.5
|
||||
# PSF License (see https://opensource.org/licenses/Python-2.0)
|
||||
|
||||
data = data.strip()
|
||||
|
||||
try:
|
||||
raw_output = strict_parse(data)
|
||||
|
||||
except ValueError:
|
||||
raw_output['components'] = loose_parse(data)
|
||||
strict = False
|
||||
|
||||
if raw_output:
|
||||
raw_output['strict'] = strict
|
||||
|
||||
return raw_output if raw else _process(raw_output)
|
Reference in New Issue
Block a user