mirror of
https://github.com/kellyjonbrazil/jc.git
synced 2026-04-05 17:50:11 +02:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab482e521d | ||
|
|
e08b61fa81 | ||
|
|
ce61bd1d2b | ||
|
|
7b708f7518 | ||
|
|
89ca50c7fc | ||
|
|
fb54899dcc | ||
|
|
0a625ad7dd | ||
|
|
d32e45efbe | ||
|
|
c77696bc78 | ||
|
|
736fde9e78 | ||
|
|
9c1ad92fed | ||
|
|
1a9fd2139d | ||
|
|
7661e7f27a | ||
|
|
f857b7fbf7 | ||
|
|
d94d12dbc5 | ||
|
|
700916276a | ||
|
|
834e52369c | ||
|
|
1ce53365de | ||
|
|
473f70668f | ||
|
|
0dbd2702f6 | ||
|
|
01e3764a9b | ||
|
|
ff9c81722a | ||
|
|
166aef7a02 | ||
|
|
78caf7646b | ||
|
|
1f99d40cec | ||
|
|
4c2912d3d5 | ||
|
|
45e6e06be5 | ||
|
|
fdbe3e05f3 | ||
|
|
7cc168f640 | ||
|
|
ff2d609c9b | ||
|
|
2689697b4c | ||
|
|
f90a0ea8ab | ||
|
|
caabe60f84 | ||
|
|
2bef4ed603 | ||
|
|
ee57be533b |
11
CHANGELOG
11
CHANGELOG
@@ -1,5 +1,15 @@
|
||||
jc changelog
|
||||
|
||||
20210830 v1.16.2
|
||||
- Note to Package Maintainers: please see note at 20210720 v1.16.0
|
||||
- Update sfdisk parser to support the -F option and newer versions of sfdisk
|
||||
|
||||
20210813 v1.16.1
|
||||
- Note to Package Maintainers: please see note at 20210720 v1.16.0
|
||||
- Fix issue with process substitution with the magic syntax
|
||||
- Fix issue with globs not including filenames with spaces with magic syntax
|
||||
- Fix stat parser to properly handle filenames with spaces on macOS/BSD
|
||||
|
||||
20210720 v1.16.0
|
||||
- Note to Package Maintainers:
|
||||
TL;DR: `/man/jc.1.gz` and `/jc/man/jc.1.gz` are deprecated and only `/man/jc.1` should be used.
|
||||
@@ -15,6 +25,7 @@ jc changelog
|
||||
- Fix Man page location in source packages
|
||||
- Add sfdisk command parser tested on linux
|
||||
- Update unit test files to change the timezone when needed (POSIX only)
|
||||
- Binaries and DEB/RPM/MSI packages now include Python 3.9.5 interpreter
|
||||
|
||||
20210628 v1.15.6
|
||||
- Fix issue to only load local plugin parsers that have filenames that end in .py
|
||||
|
||||
@@ -15,11 +15,12 @@ Pull requests are the best way to propose changes to the codebase (we use [Githu
|
||||
|
||||
1. Open an issue to discuss the new feature, bug fix, or parser before opening a pull request. For new parsers, it is important to agree upon a schema before developing the parser.
|
||||
2. Fork the repo and create your branch from `dev`, if available, otherwise `master`.
|
||||
3. If you've added code that should be tested, add tests. All new parsers should have several sample outputs and tests.
|
||||
4. Documentation is auto-generated from docstrings, so ensure they are clear and accurate.
|
||||
5. Ensure the test suite passes. (Note: "**America/Los_Angeles**" timezone should be configured on the test system)
|
||||
6. Make sure your code lints.
|
||||
7. Issue that pull request!
|
||||
3. For new parsers: Use the `jc/parsers/foo.py` parser as a [template](https://github.com/kellyjonbrazil/jc/blob/master/jc/parsers/foo.py) to get started. You can even place a new parser python module file in the [parser plugin directory](https://github.com/kellyjonbrazil/jc#custom-parsers) to get started right away with just a standard `jc` installation.
|
||||
4. If you've added code that should be tested, add tests. All new parsers should have several sample outputs and tests.
|
||||
5. Documentation is auto-generated from docstrings, so ensure they are clear and accurate.
|
||||
6. Ensure the test suite passes. (Note: "**America/Los_Angeles**" timezone should be configured on the test system)
|
||||
7. Make sure your code lints.
|
||||
8. Issue that pull request!
|
||||
|
||||
## Parser Schema Guidelines
|
||||
- Try to keep the schema as flat as possible - typically a list of flat dictionaries
|
||||
@@ -34,11 +35,11 @@ Bad:
|
||||
```
|
||||
{
|
||||
"Interface 1": [
|
||||
192.168.1.1,
|
||||
172.16.1.1
|
||||
"192.168.1.1",
|
||||
"172.16.1.1"
|
||||
],
|
||||
"Wifi Interface 1": [
|
||||
10.1.1.1
|
||||
"10.1.1.1"
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -48,14 +49,14 @@ Good:
|
||||
{
|
||||
"interface": "Interface 1",
|
||||
"ip_addresses": [
|
||||
192.168.1.1,
|
||||
172.16.1.1
|
||||
"192.168.1.1",
|
||||
"172.16.1.1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"interface": "Wifi Interface 1",
|
||||
"ip_addresses": [
|
||||
10.1.1.1
|
||||
"10.1.1.1"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -2558,7 +2558,7 @@ rpm_qia | jc --rpm_qi -p # or: jc -p rpm -qia
|
||||
```
|
||||
### sfdisk
|
||||
```bash
|
||||
sfdisk -l | jc --sfdisk -p # or jc -p sfdisk
|
||||
sfdisk -l | jc --sfdisk -p # or jc -p sfdisk -l
|
||||
```
|
||||
```json
|
||||
[
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||

|
||||

|
||||
|
||||
> Try the new `jc` [web demo](https://jc-web-demo.herokuapp.com/)!
|
||||
> Try the `jc` [web demo](https://jc-web-demo.herokuapp.com/)
|
||||
|
||||
> JC is [now available](https://galaxy.ansible.com/community/general) as an Ansible filter plugin in the `community.general` collection! See this [blog post](https://blog.kellybrazil.com/2020/08/30/parsing-command-output-in-ansible-with-jc/) for an example.
|
||||
|
||||
@@ -83,7 +83,7 @@ Use Cases:
|
||||
- [Nornir command output parsing](https://blog.kellybrazil.com/2020/12/09/parsing-command-output-in-nornir-with-jc/)
|
||||
|
||||
## Installation
|
||||
There are several ways to get `jc`. You can install via `pip`; other OS package repositories like `apt-get`, `dnf`, `zypper`, `pacman`, `nix-env`, `guix`, `brew`, or `portsnap`; via DEB, RPM, and MSI packaged binaries for linux and Windows; or by downloading the correct binary for your architecture and running it anywhere on your filesystem.
|
||||
There are several ways to get `jc`. You can install via `pip`, OS package repositories, via DEB/RPM/MSI packaged binaries for linux and Windows, or by downloading the correct binary for your architecture and running it anywhere on your filesystem.
|
||||
|
||||
### Pip (macOS, linux, unix, Windows)
|
||||
```bash
|
||||
@@ -100,7 +100,7 @@ pip3 install jc
|
||||
| Arch linux | `pacman -S jc` |
|
||||
| NixOS linux | `nix-env -iA nixpkgs.jc` or `nix-env -iA nixos.jc` |
|
||||
| Guix System linux | `guix install jc` |
|
||||
| MacOS | `brew install jc` |
|
||||
| macOS | `brew install jc` |
|
||||
| FreeBSD | `portsnap fetch update && cd /usr/ports/textproc/py-jc && make install clean` |
|
||||
| Ansible filter plugin | `ansible-galaxy collection install community.general` |
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ Examples:
|
||||
# but can be preserved with the -r argument
|
||||
occupation:"Engineer"
|
||||
|
||||
$ cat keyvalue.txt | jc --ini -p
|
||||
$ cat keyvalue.txt | jc --kv -p
|
||||
{
|
||||
"name": "John Doe",
|
||||
"address": "555 California Drive",
|
||||
|
||||
@@ -5,11 +5,12 @@ jc - JSON CLI output utility `sfdisk` command output parser
|
||||
|
||||
Supports the following `sfdisk` options:
|
||||
- `-l`
|
||||
- `-d`
|
||||
- `-uM`
|
||||
- `-uC`
|
||||
- `-uS`
|
||||
- `-uB`
|
||||
- `-F`
|
||||
- `-d` (deprecated - only for older versions of util-linux)
|
||||
- `-uM` (deprecated - only for older versions of util-linux)
|
||||
- `-uC` (deprecated - only for older versions of util-linux)
|
||||
- `-uS` (deprecated - only for older versions of util-linux)
|
||||
- `-uB` (deprecated - only for older versions of util-linux)
|
||||
|
||||
Usage (cli):
|
||||
|
||||
@@ -28,24 +29,38 @@ Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"disk": string,
|
||||
"cylinders": integer,
|
||||
"heads": integer,
|
||||
"sectors_per_track": integer,
|
||||
"units": string,
|
||||
"disk": string,
|
||||
"disk_size": string,
|
||||
"free_disk_size": string,
|
||||
"bytes": integer,
|
||||
"free_bytes": integer,
|
||||
"sectors": integer,
|
||||
"free_sectors": integer,
|
||||
"cylinders": integer,
|
||||
"heads": integer,
|
||||
"sectors_per_track": integer,
|
||||
"units": string,
|
||||
"logical_sector_size": integer,
|
||||
"physical_sector_size": integer,
|
||||
"min_io_size": integer,
|
||||
"optimal_io_size": integer,
|
||||
"disk_label_type": string,
|
||||
"disk_identifier": string,
|
||||
"disk_model": string,
|
||||
"partitions": [
|
||||
{
|
||||
"device": string,
|
||||
"boot": boolean,
|
||||
"start": integer,
|
||||
"end": integer,
|
||||
"size": integer,
|
||||
"cyls": integer,
|
||||
"mib": integer,
|
||||
"blocks": integer,
|
||||
"sectors": integer,
|
||||
"id": string,
|
||||
"system": string
|
||||
"device": string,
|
||||
"boot": boolean,
|
||||
"start": integer,
|
||||
"end": integer,
|
||||
"size": string, # Note: will be integer when using deprecated -d sfdisk option
|
||||
"cyls": integer,
|
||||
"mib": integer,
|
||||
"blocks": integer,
|
||||
"sectors": integer,
|
||||
"id": string,
|
||||
"system": string,
|
||||
"type": string
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -118,7 +133,7 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
# sfdisk | jc --sfdisk -p -r
|
||||
# sfdisk -l | jc --sfdisk -p -r
|
||||
[
|
||||
{
|
||||
"disk": "/dev/sda",
|
||||
@@ -210,4 +225,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux
|
||||
|
||||
Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.1 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -193,4 +193,4 @@ Returns:
|
||||
## Parser Information
|
||||
Compatibility: linux, darwin, freebsd
|
||||
|
||||
Version 1.8 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
Version 1.9 by Kelly Brazil (kellyjonbrazil@gmail.com)
|
||||
|
||||
@@ -86,4 +86,4 @@ Module Example:
|
||||
"""
|
||||
|
||||
name = 'jc'
|
||||
__version__ = '1.16.0'
|
||||
__version__ = '1.16.2'
|
||||
|
||||
32
jc/cli.py
32
jc/cli.py
@@ -6,10 +6,10 @@ import sys
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import shlex
|
||||
import importlib
|
||||
import textwrap
|
||||
import signal
|
||||
import shlex
|
||||
import subprocess
|
||||
import json
|
||||
import jc
|
||||
@@ -360,11 +360,10 @@ def help_doc(options):
|
||||
# load parser module just in time so we don't need to load all modules
|
||||
parser = parser_module(arg)
|
||||
compatible = ', '.join(parser.info.compatible)
|
||||
doc_text = f'''{parser.__doc__}
|
||||
Compatibility: {compatible}
|
||||
|
||||
Version {parser.info.version} by {parser.info.author} ({parser.info.author_email})
|
||||
'''
|
||||
doc_text = \
|
||||
f'{parser.__doc__}\n'\
|
||||
f'Compatibility: {compatible}\n\n'\
|
||||
f'Version {parser.info.version} by {parser.info.author} ({parser.info.author_email})\n'
|
||||
|
||||
return doc_text
|
||||
|
||||
@@ -415,8 +414,7 @@ def magic_parser(args):
|
||||
if len(args) <= 1 or args[1].startswith('--'):
|
||||
return False, None, None, []
|
||||
|
||||
# correctly parse escape characters and spaces with shlex
|
||||
args_given = ' '.join(map(shlex.quote, args[1:])).split()
|
||||
args_given = args[1:]
|
||||
options = []
|
||||
|
||||
# find the options
|
||||
@@ -466,7 +464,11 @@ def magic_parser(args):
|
||||
|
||||
def run_user_command(command):
|
||||
"""Use subprocess to run the user's command. Returns the STDOUT, STDERR, and the Exit Code as a tuple."""
|
||||
proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
|
||||
proc = subprocess.Popen(command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
close_fds=False, # Allows inheriting file descriptors. Useful for process substitution
|
||||
universal_newlines=True)
|
||||
stdout, stderr = proc.communicate()
|
||||
|
||||
return (
|
||||
@@ -545,7 +547,10 @@ def main():
|
||||
# if magic syntax used, try to run the command and error if it's not found, etc.
|
||||
magic_stdout, magic_stderr, magic_exit_code = None, None, 0
|
||||
if run_command:
|
||||
run_command_str = ' '.join(run_command)
|
||||
try:
|
||||
run_command_str = shlex.join(run_command) # python 3.8+
|
||||
except AttributeError:
|
||||
run_command_str = ' '.join(run_command) # older python versions
|
||||
|
||||
if valid_command:
|
||||
try:
|
||||
@@ -560,6 +565,13 @@ def main():
|
||||
jc.utils.error_message(f'"{run_command_str}" command could not be found. For details use the -d or -dd option.')
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
except OSError:
|
||||
if debug:
|
||||
raise
|
||||
else:
|
||||
jc.utils.error_message(f'"{run_command_str}" command could not be run due to too many open files. For details use the -d or -dd option.')
|
||||
sys.exit(combined_exit_code(magic_exit_code, JC_ERROR_EXIT))
|
||||
|
||||
except Exception:
|
||||
if debug:
|
||||
raise
|
||||
|
||||
BIN
jc/man/jc.1.gz
BIN
jc/man/jc.1.gz
Binary file not shown.
@@ -35,7 +35,7 @@ Examples:
|
||||
# but can be preserved with the -r argument
|
||||
occupation:"Engineer"
|
||||
|
||||
$ cat keyvalue.txt | jc --ini -p
|
||||
$ cat keyvalue.txt | jc --kv -p
|
||||
{
|
||||
"name": "John Doe",
|
||||
"address": "555 California Drive",
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
Supports the following `sfdisk` options:
|
||||
- `-l`
|
||||
- `-d`
|
||||
- `-uM`
|
||||
- `-uC`
|
||||
- `-uS`
|
||||
- `-uB`
|
||||
- `-F`
|
||||
- `-d` (deprecated - only for older versions of util-linux)
|
||||
- `-uM` (deprecated - only for older versions of util-linux)
|
||||
- `-uC` (deprecated - only for older versions of util-linux)
|
||||
- `-uS` (deprecated - only for older versions of util-linux)
|
||||
- `-uB` (deprecated - only for older versions of util-linux)
|
||||
|
||||
Usage (cli):
|
||||
|
||||
@@ -25,24 +26,38 @@ Schema:
|
||||
|
||||
[
|
||||
{
|
||||
"disk": string,
|
||||
"cylinders": integer,
|
||||
"heads": integer,
|
||||
"sectors_per_track": integer,
|
||||
"units": string,
|
||||
"disk": string,
|
||||
"disk_size": string,
|
||||
"free_disk_size": string,
|
||||
"bytes": integer,
|
||||
"free_bytes": integer,
|
||||
"sectors": integer,
|
||||
"free_sectors": integer,
|
||||
"cylinders": integer,
|
||||
"heads": integer,
|
||||
"sectors_per_track": integer,
|
||||
"units": string,
|
||||
"logical_sector_size": integer,
|
||||
"physical_sector_size": integer,
|
||||
"min_io_size": integer,
|
||||
"optimal_io_size": integer,
|
||||
"disk_label_type": string,
|
||||
"disk_identifier": string,
|
||||
"disk_model": string,
|
||||
"partitions": [
|
||||
{
|
||||
"device": string,
|
||||
"boot": boolean,
|
||||
"start": integer,
|
||||
"end": integer,
|
||||
"size": integer,
|
||||
"cyls": integer,
|
||||
"mib": integer,
|
||||
"blocks": integer,
|
||||
"sectors": integer,
|
||||
"id": string,
|
||||
"system": string
|
||||
"device": string,
|
||||
"boot": boolean,
|
||||
"start": integer,
|
||||
"end": integer,
|
||||
"size": string, # Note: will be integer when using deprecated -d sfdisk option
|
||||
"cyls": integer,
|
||||
"mib": integer,
|
||||
"blocks": integer,
|
||||
"sectors": integer,
|
||||
"id": string,
|
||||
"system": string,
|
||||
"type": string
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -115,7 +130,7 @@ Examples:
|
||||
}
|
||||
]
|
||||
|
||||
# sfdisk | jc --sfdisk -p -r
|
||||
# sfdisk -l | jc --sfdisk -p -r
|
||||
[
|
||||
{
|
||||
"disk": "/dev/sda",
|
||||
@@ -186,7 +201,7 @@ import jc.parsers.universal
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.0'
|
||||
version = '1.1'
|
||||
description = '`sfdisk` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -209,8 +224,9 @@ def _process(proc_data):
|
||||
|
||||
List of Dictionaries. Structured to conform to the schema.
|
||||
"""
|
||||
int_list = ['cylinders', 'heads', 'sectors_per_track', 'start', 'end', 'size', 'cyls', 'mib',
|
||||
'blocks', 'sectors']
|
||||
int_list = ['cylinders', 'heads', 'sectors_per_track', 'start', 'end', 'cyls', 'mib',
|
||||
'blocks', 'sectors', 'bytes', 'logical_sector_size', 'physical_sector_size',
|
||||
'min_io_size', 'optimal_io_size', 'free_bytes', 'free_sectors']
|
||||
bool_list = ['boot']
|
||||
|
||||
for entry in proc_data:
|
||||
@@ -221,6 +237,12 @@ def _process(proc_data):
|
||||
if 'partitions' in entry:
|
||||
for p in entry['partitions']:
|
||||
for key in p:
|
||||
# legacy conversion for -d option
|
||||
if key == 'size':
|
||||
if p[key].isnumeric():
|
||||
p[key] = jc.utils.convert_to_int(p[key])
|
||||
|
||||
# normal conversions
|
||||
if key in int_list:
|
||||
p[key] = jc.utils.convert_to_int(p[key].replace('-', ''))
|
||||
if key in bool_list:
|
||||
@@ -255,6 +277,7 @@ def parse(data, raw=False, quiet=False):
|
||||
if jc.utils.has_data(data):
|
||||
|
||||
for line in data.splitlines():
|
||||
# deprecated - only for older versions of util-linux
|
||||
if line.startswith('# partition table of'):
|
||||
if item:
|
||||
raw_output.append(item)
|
||||
@@ -265,6 +288,7 @@ def parse(data, raw=False, quiet=False):
|
||||
item['disk'] = line.split()[4]
|
||||
continue
|
||||
|
||||
# deprecated - only for older versions of util-linux
|
||||
if option == 'd':
|
||||
if line.startswith('unit: '):
|
||||
item['units'] = line.split()[1]
|
||||
@@ -284,24 +308,78 @@ def parse(data, raw=False, quiet=False):
|
||||
continue
|
||||
|
||||
else:
|
||||
if line.startswith('Disk '):
|
||||
# older versions of util-linux
|
||||
# Disk /dev/sda: 2610 cylinders, 255 heads, 63 sectors/track
|
||||
if line.startswith('Disk ') and 'sectors/track' in line:
|
||||
if item:
|
||||
raw_output.append(item)
|
||||
|
||||
item = {}
|
||||
partitions = []
|
||||
line = line.replace(':', '').replace(',', '')
|
||||
item['disk'] = line.split()[1]
|
||||
item['cylinders'] = line.split()[2]
|
||||
item['heads'] = line.split()[4]
|
||||
item['sectors_per_track'] = line.split()[6]
|
||||
fields = line.split()
|
||||
item['disk'] = fields[1]
|
||||
item['cylinders'] = fields[2]
|
||||
item['heads'] = fields[4]
|
||||
item['sectors_per_track'] = fields[6]
|
||||
continue
|
||||
|
||||
# util-linux v2.32.0+ (?)
|
||||
# Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
|
||||
if line.startswith('Disk ') and line.endswith('sectors'):
|
||||
if item:
|
||||
raw_output.append(item)
|
||||
|
||||
item = {}
|
||||
partitions = []
|
||||
line = line.replace(':', '').replace(',', '')
|
||||
fields = line.split()
|
||||
item['disk'] = fields[1]
|
||||
item['disk_size'] = ' '.join(fields[2:4])
|
||||
item['bytes'] = fields[4]
|
||||
item['sectors'] = fields[6]
|
||||
continue
|
||||
|
||||
if line.startswith('Disk model: '):
|
||||
item['disk_model'] = line.split(':', maxsplit=1)[1].strip()
|
||||
continue
|
||||
|
||||
if line.startswith('Sector size (logical/physical)'):
|
||||
fields = line.split()
|
||||
item['logical_sector_size'] = fields[3]
|
||||
item['physical_sector_size'] = fields[6]
|
||||
continue
|
||||
|
||||
if line.startswith('I/O size (minimum/optimal)'):
|
||||
fields = line.split()
|
||||
item['min_io_size'] = fields[3]
|
||||
item['optimal_io_size'] = fields[6]
|
||||
continue
|
||||
|
||||
if line.startswith('Disklabel type'):
|
||||
item['disk_label_type'] = line.split(':', maxsplit=1)[1].strip()
|
||||
continue
|
||||
|
||||
if line.startswith('Disk identifier'):
|
||||
item['disk_identifier'] = line.split(':', maxsplit=1)[1].strip()
|
||||
continue
|
||||
|
||||
if line.startswith('Units: '):
|
||||
item['units'] = line.split(':')[1].strip()
|
||||
continue
|
||||
|
||||
if 'Device' in line and 'Boot' in line and 'Start' in line and 'End' in line:
|
||||
# sfdisk -F
|
||||
if line.startswith('Unpartitioned space'):
|
||||
line = line.replace(':', '').replace(',', '')
|
||||
fields = line.split()
|
||||
item['disk'] = fields[2]
|
||||
item['free_disk_size'] = ' '.join(fields[3:5])
|
||||
item['free_bytes'] = fields[5]
|
||||
item['free_sectors'] = fields[7]
|
||||
continue
|
||||
|
||||
# partition lines
|
||||
if 'Start' in line and 'End' in line and ('Sectors' in line or 'Device' in line):
|
||||
section = 'partitions'
|
||||
partitions.append(line.lower().replace('#', ' '))
|
||||
continue
|
||||
@@ -316,6 +394,10 @@ def parse(data, raw=False, quiet=False):
|
||||
partitions = []
|
||||
continue
|
||||
|
||||
# get final partitions if there are any left over
|
||||
if section == 'partitions' and option != 'd' and partitions:
|
||||
item['partitions'] = jc.parsers.universal.sparse_table_parse(partitions)
|
||||
|
||||
if item:
|
||||
raw_output.append(item)
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ import jc.utils
|
||||
|
||||
class info():
|
||||
"""Provides parser metadata (version, author, etc.)"""
|
||||
version = '1.8'
|
||||
version = '1.9'
|
||||
description = '`stat` command parser'
|
||||
author = 'Kelly Brazil'
|
||||
author_email = 'kellyjonbrazil@gmail.com'
|
||||
@@ -322,7 +322,7 @@ def parse(data, raw=False, quiet=False):
|
||||
for line in cleandata:
|
||||
value = shlex.split(line)
|
||||
output_line = {
|
||||
'file': value[15],
|
||||
'file': ' '.join(value[15:]),
|
||||
'unix_device': value[0],
|
||||
'inode': value[1],
|
||||
'flags': value[2],
|
||||
|
||||
2
man/jc.1
2
man/jc.1
@@ -1,4 +1,4 @@
|
||||
.TH jc 1 2021-07-20 1.16.0 "JSON CLI output utility"
|
||||
.TH jc 1 2021-08-31 1.16.2 "JSON CLI output utility"
|
||||
.SH NAME
|
||||
jc \- JSONifies the output of many CLI tools and file-types
|
||||
.SH SYNOPSIS
|
||||
|
||||
BIN
man/jc.1.gz
BIN
man/jc.1.gz
Binary file not shown.
2
setup.py
2
setup.py
@@ -5,7 +5,7 @@ with open('README.md', 'r') as f:
|
||||
|
||||
setuptools.setup(
|
||||
name='jc',
|
||||
version='1.16.0',
|
||||
version='1.16.2',
|
||||
author='Kelly Brazil',
|
||||
author_email='kellyjonbrazil@gmail.com',
|
||||
description='Converts the output of popular command-line tools and file-types to JSON.',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||

|
||||

|
||||
|
||||
> Try the new `jc` [web demo](https://jc-web-demo.herokuapp.com/)!
|
||||
> Try the `jc` [web demo](https://jc-web-demo.herokuapp.com/)
|
||||
|
||||
> JC is [now available](https://galaxy.ansible.com/community/general) as an Ansible filter plugin in the `community.general` collection! See this [blog post](https://blog.kellybrazil.com/2020/08/30/parsing-command-output-in-ansible-with-jc/) for an example.
|
||||
|
||||
@@ -83,7 +83,7 @@ Use Cases:
|
||||
- [Nornir command output parsing](https://blog.kellybrazil.com/2020/12/09/parsing-command-output-in-nornir-with-jc/)
|
||||
|
||||
## Installation
|
||||
There are several ways to get `jc`. You can install via `pip`; other OS package repositories like `apt-get`, `dnf`, `zypper`, `pacman`, `nix-env`, `guix`, `brew`, or `portsnap`; via DEB, RPM, and MSI packaged binaries for linux and Windows; or by downloading the correct binary for your architecture and running it anywhere on your filesystem.
|
||||
There are several ways to get `jc`. You can install via `pip`, OS package repositories, via DEB/RPM/MSI packaged binaries for linux and Windows, or by downloading the correct binary for your architecture and running it anywhere on your filesystem.
|
||||
|
||||
### Pip (macOS, linux, unix, Windows)
|
||||
```bash
|
||||
@@ -100,7 +100,7 @@ pip3 install jc
|
||||
| Arch linux | `pacman -S jc` |
|
||||
| NixOS linux | `nix-env -iA nixpkgs.jc` or `nix-env -iA nixos.jc` |
|
||||
| Guix System linux | `guix install jc` |
|
||||
| MacOS | `brew install jc` |
|
||||
| macOS | `brew install jc` |
|
||||
| FreeBSD | `portsnap fetch update && cd /usr/ports/textproc/py-jc && make install clean` |
|
||||
| Ansible filter plugin | `ansible-galaxy collection install community.general` |
|
||||
|
||||
|
||||
1
tests/fixtures/centos-8/sfdisk-F.json
vendored
Normal file
1
tests/fixtures/centos-8/sfdisk-F.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"disk":"/dev/sda","free_disk_size":"0 B","free_bytes":0,"free_sectors":0,"units":"sectors of 1 * 512 = 512 bytes","logical_sector_size":512,"physical_sector_size":512}]
|
||||
9
tests/fixtures/centos-8/sfdisk-F.out
vendored
Normal file
9
tests/fixtures/centos-8/sfdisk-F.out
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
Unpartitioned space /dev/sda: 0 B, 0 bytes, 0 sectors
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1
tests/fixtures/centos-8/sfdisk-l.json
vendored
Normal file
1
tests/fixtures/centos-8/sfdisk-l.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"disk":"/dev/sda","disk_size":"20 GiB","bytes":21474836480,"sectors":41943040,"units":"sectors of 1 * 512 = 512 bytes","logical_sector_size":512,"physical_sector_size":512,"min_io_size":512,"optimal_io_size":512,"disk_label_type":"dos","disk_identifier":"0x94988ac4","partitions":[{"device":"/dev/sda1","boot":true,"start":2048,"end":2099199,"sectors":2097152,"size":"1G","id":"83","type":"Linux"},{"device":"/dev/sda2","boot":false,"start":2099200,"end":41943039,"sectors":39843840,"size":"19G","id":"8e","type":"Linux LVM"}]},{"disk":"/dev/mapper/cl-root","disk_size":"17 GiB","bytes":18249416704,"sectors":35643392,"units":"sectors of 1 * 512 = 512 bytes","logical_sector_size":512,"physical_sector_size":512,"min_io_size":512,"optimal_io_size":512},{"disk":"/dev/mapper/cl-swap","disk_size":"2 GiB","bytes":2147483648,"sectors":4194304,"units":"sectors of 1 * 512 = 512 bytes","logical_sector_size":512,"physical_sector_size":512,"min_io_size":512,"optimal_io_size":512}]
|
||||
24
tests/fixtures/centos-8/sfdisk-l.out
vendored
Normal file
24
tests/fixtures/centos-8/sfdisk-l.out
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
||||
Disklabel type: dos
|
||||
Disk identifier: 0x94988ac4
|
||||
|
||||
Device Boot Start End Sectors Size Id Type
|
||||
/dev/sda1 * 2048 2099199 2097152 1G 83 Linux
|
||||
/dev/sda2 2099200 41943039 39843840 19G 8e Linux LVM
|
||||
|
||||
|
||||
|
||||
|
||||
Disk /dev/mapper/cl-root: 17 GiB, 18249416704 bytes, 35643392 sectors
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
||||
|
||||
|
||||
Disk /dev/mapper/cl-swap: 2 GiB, 2147483648 bytes, 4194304 sectors
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
||||
1
tests/fixtures/debian10/sfdisk-F.json
vendored
Normal file
1
tests/fixtures/debian10/sfdisk-F.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"disk":"/dev/sda","free_disk_size":"0 B","free_bytes":0,"free_sectors":0,"units":"sectors of 1 * 512 = 512 bytes","logical_sector_size":512,"physical_sector_size":512}]
|
||||
3
tests/fixtures/debian10/sfdisk-F.out
vendored
Normal file
3
tests/fixtures/debian10/sfdisk-F.out
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
Unpartitioned space /dev/sda: 0 B, 0 bytes, 0 sectors
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
1
tests/fixtures/debian10/sfdisk-F2.json
vendored
Normal file
1
tests/fixtures/debian10/sfdisk-F2.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"disk":"/dev/sdc","free_disk_size":"1 GiB","free_bytes":1073741824,"free_sectors":2097152,"units":"sectors of 1 * 512 = 512 bytes","logical_sector_size":512,"physical_sector_size":512,"partitions":[{"start":4194304,"end":6291455,"sectors":2097152,"size":"1G"}]}]
|
||||
6
tests/fixtures/debian10/sfdisk-F2.out
vendored
Normal file
6
tests/fixtures/debian10/sfdisk-F2.out
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
Unpartitioned space /dev/sdc: 1 GiB, 1073741824 bytes, 2097152 sectors
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
|
||||
Start End Sectors Size
|
||||
4194304 6291455 2097152 1G
|
||||
1
tests/fixtures/debian10/sfdisk-l.json
vendored
Normal file
1
tests/fixtures/debian10/sfdisk-l.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"disk":"/dev/sda","disk_size":"20 GiB","bytes":21474836480,"sectors":41943040,"disk_model":"VMware Virtual S","units":"sectors of 1 * 512 = 512 bytes","logical_sector_size":512,"physical_sector_size":512,"min_io_size":512,"optimal_io_size":512,"disk_label_type":"dos","disk_identifier":"0x3719ef0f","partitions":[{"device":"/dev/sda1","boot":true,"start":2048,"end":39942143,"sectors":39940096,"size":"19G","id":"83","type":"Linux"},{"device":"/dev/sda2","boot":false,"start":39944190,"end":41940991,"sectors":1996802,"size":"975M","id":"5","type":"Extended"},{"device":"/dev/sda5","boot":false,"start":39944192,"end":41940991,"sectors":1996800,"size":"975M","id":"82","type":"Linux swap / Solaris"}]}]
|
||||
12
tests/fixtures/debian10/sfdisk-l.out
vendored
Normal file
12
tests/fixtures/debian10/sfdisk-l.out
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
|
||||
Disk model: VMware Virtual S
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
||||
Disklabel type: dos
|
||||
Disk identifier: 0x3719ef0f
|
||||
|
||||
Device Boot Start End Sectors Size Id Type
|
||||
/dev/sda1 * 2048 39942143 39940096 19G 83 Linux
|
||||
/dev/sda2 39944190 41940991 1996802 975M 5 Extended
|
||||
/dev/sda5 39944192 41940991 1996800 975M 82 Linux swap / Solaris
|
||||
1
tests/fixtures/debian10/sfdisk-l2.json
vendored
Normal file
1
tests/fixtures/debian10/sfdisk-l2.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"disk":"/dev/sda","disk_size":"32 GiB","bytes":34359738368,"sectors":67108864,"disk_model":"QEMU HARDDISK","units":"sectors of 1 * 512 = 512 bytes","logical_sector_size":512,"physical_sector_size":512,"min_io_size":512,"optimal_io_size":512,"disk_label_type":"dos","disk_identifier":"0x4f1ce2bf","partitions":[{"device":"/dev/sda1","boot":true,"start":2048,"end":13260799,"sectors":13258752,"size":"6.3G","id":"83","type":"Linux"},{"device":"/dev/sda2","boot":false,"start":13262846,"end":67106815,"sectors":53843970,"size":"25.7G","id":"5","type":"Extended"},{"device":"/dev/sda5","boot":false,"start":13262848,"end":18331647,"sectors":5068800,"size":"2.4G","id":"83","type":"Linux"},{"device":"/dev/sda6","boot":false,"start":18333696,"end":20332543,"sectors":1998848,"size":"976M","id":"82","type":"Linux swap / Solaris"},{"device":"/dev/sda7","boot":false,"start":20334592,"end":21352447,"sectors":1017856,"size":"497M","id":"83","type":"Linux"},{"device":"/dev/sda8","boot":false,"start":21354496,"end":67106815,"sectors":45752320,"size":"21.8G","id":"83","type":"Linux"}]}]
|
||||
15
tests/fixtures/debian10/sfdisk-l2.out
vendored
Normal file
15
tests/fixtures/debian10/sfdisk-l2.out
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
Disk /dev/sda: 32 GiB, 34359738368 bytes, 67108864 sectors
|
||||
Disk model: QEMU HARDDISK
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
||||
Disklabel type: dos
|
||||
Disk identifier: 0x4f1ce2bf
|
||||
|
||||
Device Boot Start End Sectors Size Id Type
|
||||
/dev/sda1 * 2048 13260799 13258752 6.3G 83 Linux
|
||||
/dev/sda2 13262846 67106815 53843970 25.7G 5 Extended
|
||||
/dev/sda5 13262848 18331647 5068800 2.4G 83 Linux
|
||||
/dev/sda6 18333696 20332543 1998848 976M 82 Linux swap / Solaris
|
||||
/dev/sda7 20334592 21352447 1017856 497M 83 Linux
|
||||
/dev/sda8 21354496 67106815 45752320 21.8G 83 Linux
|
||||
1
tests/fixtures/debian10/sfdisk-l3.json
vendored
Normal file
1
tests/fixtures/debian10/sfdisk-l3.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"disk":"/dev/sda","disk_size":"238.5 GiB","bytes":256060514304,"sectors":500118192,"disk_model":"NT-256","units":"sectors of 1 * 512 = 512 bytes","logical_sector_size":512,"physical_sector_size":512,"min_io_size":512,"optimal_io_size":512,"disk_label_type":"gpt","disk_identifier":"50DEF501-A333-48D1-B1FC-C2F1CCFD5715","partitions":[{"device":"/dev/sda1","start":2048,"end":526335,"sectors":524288,"size":"256M","type":"Linux root (x86)"},{"device":"/dev/sda2","start":526336,"end":138545151,"sectors":138018816,"size":"65.8G","type":"Linux root (x86)"},{"device":"/dev/sda3","start":483684352,"end":500117503,"sectors":16433152,"size":"7.9G","type":"Linux swap"},{"device":"/dev/sda4","start":138545152,"end":483684351,"sectors":345139200,"size":"164.6G","type":"Linux filesystem"}]}]
|
||||
13
tests/fixtures/debian10/sfdisk-l3.out
vendored
Normal file
13
tests/fixtures/debian10/sfdisk-l3.out
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Disk /dev/sda: 238.5 GiB, 256060514304 bytes, 500118192 sectors
|
||||
Disk model: NT-256
|
||||
Units: sectors of 1 * 512 = 512 bytes
|
||||
Sector size (logical/physical): 512 bytes / 512 bytes
|
||||
I/O size (minimum/optimal): 512 bytes / 512 bytes
|
||||
Disklabel type: gpt
|
||||
Disk identifier: 50DEF501-A333-48D1-B1FC-C2F1CCFD5715
|
||||
|
||||
Device Start End Sectors Size Type
|
||||
/dev/sda1 2048 526335 524288 256M Linux root (x86)
|
||||
/dev/sda2 526336 138545151 138018816 65.8G Linux root (x86)
|
||||
/dev/sda3 483684352 500117503 16433152 7.9G Linux swap
|
||||
/dev/sda4 138545152 483684351 345139200 164.6G Linux filesystem
|
||||
1
tests/fixtures/osx-10.14.6/stat-filename-with-spaces.json
vendored
Normal file
1
tests/fixtures/osx-10.14.6/stat-filename-with-spaces.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
[{"file":"file name with spaces.txt","unix_device":16777220,"inode":161929661,"flags":"-rw-r--r--","links":1,"user":"kbrazil","group":"staff","rdev":0,"size":0,"access_time":"Aug 13 15:03:52 2021","modify_time":"Aug 13 14:37:03 2021","change_time":"Aug 13 14:37:03 2021","birth_time":"Aug 13 14:37:03 2021","block_size":4096,"blocks":0,"unix_flags":"0","access_time_epoch":1628892232,"access_time_epoch_utc":null,"modify_time_epoch":1628890623,"modify_time_epoch_utc":null,"change_time_epoch":1628890623,"change_time_epoch_utc":null,"birth_time_epoch":1628890623,"birth_time_epoch_utc":null}]
|
||||
2
tests/fixtures/osx-10.14.6/stat-filename-with-spaces.out
vendored
Normal file
2
tests/fixtures/osx-10.14.6/stat-filename-with-spaces.out
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
16777220 161929661 -rw-r--r-- 1 kbrazil staff 0 0 "Aug 13 15:03:52 2021" "Aug 13 14:37:03 2021" "Aug 13 14:37:03 2021" "Aug 13 14:37:03 2021" 4096 0 0 file name with spaces.txt
|
||||
|
||||
@@ -31,6 +31,28 @@ class MyTests(unittest.TestCase):
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/sfdisk-luS.out'), 'r', encoding='utf-8') as f:
|
||||
self.centos_7_7_sfdisk_luS = f.read()
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-8/sfdisk-l.out'), 'r', encoding='utf-8') as f:
|
||||
self.centos_8_sfdisk_l = f.read()
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-8/sfdisk-F.out'), 'r', encoding='utf-8') as f:
|
||||
self.centos_8_sfdisk_F = f.read()
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/debian10/sfdisk-l.out'), 'r', encoding='utf-8') as f:
|
||||
self.debian_10_sfdisk_l = f.read()
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/debian10/sfdisk-l2.out'), 'r', encoding='utf-8') as f:
|
||||
self.debian_10_sfdisk_l2 = f.read()
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/debian10/sfdisk-l3.out'), 'r', encoding='utf-8') as f:
|
||||
self.debian_10_sfdisk_l3 = f.read()
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/debian10/sfdisk-F.out'), 'r', encoding='utf-8') as f:
|
||||
self.debian_10_sfdisk_F = f.read()
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/debian10/sfdisk-F2.out'), 'r', encoding='utf-8') as f:
|
||||
self.debian_10_sfdisk_F2 = f.read()
|
||||
|
||||
|
||||
# output
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/sfdisk-l.json'), 'r', encoding='utf-8') as f:
|
||||
self.centos_7_7_sfdisk_l_json = json.loads(f.read())
|
||||
@@ -53,6 +75,28 @@ class MyTests(unittest.TestCase):
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/sfdisk-luS.json'), 'r', encoding='utf-8') as f:
|
||||
self.centos_7_7_sfdisk_luS_json = json.loads(f.read())
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-8/sfdisk-l.json'), 'r', encoding='utf-8') as f:
|
||||
self.centos_8_sfdisk_l_json = json.loads(f.read())
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-8/sfdisk-F.json'), 'r', encoding='utf-8') as f:
|
||||
self.centos_8_sfdisk_F_json = json.loads(f.read())
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/debian10/sfdisk-l.json'), 'r', encoding='utf-8') as f:
|
||||
self.debian_10_sfdisk_l_json = json.loads(f.read())
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/debian10/sfdisk-l2.json'), 'r', encoding='utf-8') as f:
|
||||
self.debian_10_sfdisk_l2_json = json.loads(f.read())
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/debian10/sfdisk-l3.json'), 'r', encoding='utf-8') as f:
|
||||
self.debian_10_sfdisk_l3_json = json.loads(f.read())
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/debian10/sfdisk-F.json'), 'r', encoding='utf-8') as f:
|
||||
self.debian_10_sfdisk_F_json = json.loads(f.read())
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/debian10/sfdisk-F2.json'), 'r', encoding='utf-8') as f:
|
||||
self.debian_10_sfdisk_F2_json = json.loads(f.read())
|
||||
|
||||
|
||||
def test_sfdisk_nodata(self):
|
||||
"""
|
||||
Test 'sfdisk' with no data
|
||||
@@ -101,6 +145,48 @@ class MyTests(unittest.TestCase):
|
||||
"""
|
||||
self.assertEqual(jc.parsers.sfdisk.parse(self.centos_7_7_sfdisk_luS, quiet=True), self.centos_7_7_sfdisk_luS_json)
|
||||
|
||||
def test_sfdisk_l_centos_8(self):
|
||||
"""
|
||||
Test 'sfdisk -l' on Centos 8
|
||||
"""
|
||||
self.assertEqual(jc.parsers.sfdisk.parse(self.centos_8_sfdisk_l, quiet=True), self.centos_8_sfdisk_l_json)
|
||||
|
||||
def test_sfdisk_F_centos_8(self):
|
||||
"""
|
||||
Test 'sfdisk -F' on Centos 8
|
||||
"""
|
||||
self.assertEqual(jc.parsers.sfdisk.parse(self.centos_8_sfdisk_F, quiet=True), self.centos_8_sfdisk_F_json)
|
||||
|
||||
def test_sfdisk_l_debian_10(self):
|
||||
"""
|
||||
Test 'sfdisk -l' on Debian 10
|
||||
"""
|
||||
self.assertEqual(jc.parsers.sfdisk.parse(self.debian_10_sfdisk_l, quiet=True), self.debian_10_sfdisk_l_json)
|
||||
|
||||
def test_sfdisk_l2_debian_10(self):
|
||||
"""
|
||||
Test 'sfdisk -l' on Debian 10 (second example)
|
||||
"""
|
||||
self.assertEqual(jc.parsers.sfdisk.parse(self.debian_10_sfdisk_l2, quiet=True), self.debian_10_sfdisk_l2_json)
|
||||
|
||||
def test_sfdisk_l3_debian_10(self):
|
||||
"""
|
||||
Test 'sfdisk -l' on Debian 10 (third example)
|
||||
"""
|
||||
self.assertEqual(jc.parsers.sfdisk.parse(self.debian_10_sfdisk_l3, quiet=True), self.debian_10_sfdisk_l3_json)
|
||||
|
||||
def test_sfdisk_F_debian10(self):
|
||||
"""
|
||||
Test 'sfdisk -F' on Debian 10
|
||||
"""
|
||||
self.assertEqual(jc.parsers.sfdisk.parse(self.debian_10_sfdisk_F, quiet=True), self.debian_10_sfdisk_F_json)
|
||||
|
||||
def test_sfdisk_F2_debian10(self):
|
||||
"""
|
||||
Test 'sfdisk -F' on Debian 10 (second example)
|
||||
"""
|
||||
self.assertEqual(jc.parsers.sfdisk.parse(self.debian_10_sfdisk_F2, quiet=True), self.debian_10_sfdisk_F2_json)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -26,6 +26,9 @@ class MyTests(unittest.TestCase):
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/stat.out'), 'r', encoding='utf-8') as f:
|
||||
self.osx_10_14_6_stat = f.read()
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/stat-filename-with-spaces.out'), 'r', encoding='utf-8') as f:
|
||||
self.osx_10_14_6_stat_filename_with_spaces = f.read()
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/freebsd12/stat.out'), 'r', encoding='utf-8') as f:
|
||||
self.freebsd12_stat = f.read()
|
||||
|
||||
@@ -39,6 +42,9 @@ class MyTests(unittest.TestCase):
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/stat.json'), 'r', encoding='utf-8') as f:
|
||||
self.osx_10_14_6_stat_json = json.loads(f.read())
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/osx-10.14.6/stat-filename-with-spaces.json'), 'r', encoding='utf-8') as f:
|
||||
self.osx_10_14_6_stat_filename_with_spaces_json = json.loads(f.read())
|
||||
|
||||
with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/freebsd12/stat.json'), 'r', encoding='utf-8') as f:
|
||||
self.freebsd12_stat_json = json.loads(f.read())
|
||||
|
||||
@@ -66,6 +72,12 @@ class MyTests(unittest.TestCase):
|
||||
"""
|
||||
self.assertEqual(jc.parsers.stat.parse(self.osx_10_14_6_stat, quiet=True), self.osx_10_14_6_stat_json)
|
||||
|
||||
def test_stat_filename_with_spaces_osx_10_14_6(self):
|
||||
"""
|
||||
Test 'stat' filename with spaces on OSX 10.14.6
|
||||
"""
|
||||
self.assertEqual(jc.parsers.stat.parse(self.osx_10_14_6_stat_filename_with_spaces, quiet=True), self.osx_10_14_6_stat_filename_with_spaces_json)
|
||||
|
||||
def test_stat_freebsd12(self):
|
||||
"""
|
||||
Test 'stat /foo/*' on FreeBSD12
|
||||
|
||||
Reference in New Issue
Block a user