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
|
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 `ssh` configuration file parser
|
||||||
- Add input slicing
|
- Add `ver` Version string parser
|
||||||
- Fix `acpi` command parser for "will never fully discharge" battery state
|
- Fix `acpi` command parser for "will never fully discharge" battery state
|
||||||
|
|
||||||
20230111 v1.22.5
|
20230111 v1.22.5
|
||||||
|
@ -190,6 +190,7 @@ parsers: List[str] = [
|
|||||||
'upower',
|
'upower',
|
||||||
'uptime',
|
'uptime',
|
||||||
'url',
|
'url',
|
||||||
|
'ver',
|
||||||
'vmstat',
|
'vmstat',
|
||||||
'vmstat-s',
|
'vmstat-s',
|
||||||
'w',
|
'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