Skip to content

Commit

Permalink
initial pacman parser
Browse files Browse the repository at this point in the history
  • Loading branch information
kellyjonbrazil committed Nov 24, 2024
1 parent be1dd03 commit 95cba21
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 0 deletions.
1 change: 1 addition & 0 deletions jc/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
'openvpn',
'os-prober',
'os-release',
'pacman',
'passwd',
'path',
'path-list',
Expand Down
196 changes: 196 additions & 0 deletions jc/parsers/pacman.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
r"""jc - JSON Convert `pacman` command output parser
Supports the following `pacman` arguments:
- `-Si`
- `-Sii`
- `-Qi`
- `-Qii`
Usage (cli):
$ pacman -Si <package> | jc --pacman
or
$ jc pacman -Si <package>
Usage (module):
import jc
result = jc.parse('pacman', pacman_command_output)
Schema:
[
{
"repository": string,
"name": string,
"version": string,
"description": string,
"architecture": string,
"url": string,
"licenses": [
string
],
"groups": [
string
],
"provides": [
string
],
"depends_on": [
string
],
"optional_deps": [
{
"name": string,
"description": string
}
],
"conflicts_with": [
string
],
"replaces": [
string
],
"download_size": string,
"installed_size": string,
"packager": string,
"build_date": string,
"validated_by": [
string
],
"backup_files": [
string
]
}
]
Examples:
$ pacman | jc --pacman -p
[]
$ pacman | jc --pacman -p -r
[]
"""
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 = '`pacman` command parser'
author = 'Kelly Brazil'
author_email = '[email protected]'
compatible = ['linux', 'darwin', 'cygwin', 'win32', 'aix', 'freebsd']
tags = ['command', 'file']
magic_commands = ['pacman']


__version__ = info.version


def _process(proc_data: List[JSONDictType]) -> List[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.
"""
list_list = [
'licenses', 'groups', 'provides', 'depends_on', 'optional_deps',
'conflicts_with', 'replaces', 'validated_by', 'backup_files'
]


return proc_data


def parse(
data: str,
raw: bool = False,
quiet: bool = False
) -> List[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: List[Dict] = []
entry_obj: Dict = {}
multiline_fields = {'required_by', 'optional_deps', 'backup_files'}
multiline_list: List = []
multiline_key = ''

if jc.utils.has_data(data):

for line in filter(None, data.splitlines()):
splitline = line.split(' : ', maxsplit=1)

if len(splitline) == 2:
# this is a key/value pair
key, val = splitline
key = key.strip()
key = jc.utils.normalize_key(key)
val = val.strip()

# new entries can start with "Repository" or "Name"
if (key == 'name' or key == 'repository') and len(entry_obj) > 2:
if multiline_list:
entry_obj[multiline_key] = multiline_list
multiline_list = []
multiline_key = ''
if entry_obj:
raw_output.append(entry_obj)
entry_obj = {}
entry_obj[key] = val
continue

if key in multiline_fields:
multiline_list = []
if val != 'None':
multiline_list.append(val)
multiline_key = key
continue

if key not in multiline_fields:
if multiline_list:
entry_obj[multiline_key] = multiline_list
multiline_list = []
multiline_key = ''
entry_obj[key] = val if val != 'None' else None
continue

# multiline field continuation lines
multiline_list.append(line.strip())
continue

# grab the last entry
if entry_obj:
if multiline_list:
entry_obj[multiline_key] = multiline_list
multiline_list = []
multiline_key = ''
raw_output.append(entry_obj)

return raw_output if raw else _process(raw_output)

0 comments on commit 95cba21

Please sign in to comment.