1
0
mirror of https://github.com/kellyjonbrazil/jc.git synced 2026-04-05 17:50:11 +02:00

Compare commits

...

19 Commits

Author SHA1 Message Date
Kelly Brazil
834e52369c update man page 2021-08-16 10:33:26 -07:00
Kelly Brazil
1ce53365de Merge pull request #156 from kellyjonbrazil/dev
Dev v1.16.1
2021-08-16 10:32:03 -07:00
Kelly Brazil
473f70668f Merge branch 'master' into dev
# Conflicts:
#	jc/man/jc.1.gz
#	man/jc.1
#	man/jc.1.gz
2021-08-16 10:28:11 -07:00
Kelly Brazil
0dbd2702f6 reformat doc_text for nicer indentation 2021-08-13 17:17:51 -07:00
Kelly Brazil
01e3764a9b fix join syntax 2021-08-13 16:03:46 -07:00
Kelly Brazil
ff9c81722a try/except for shlex.join since only available in python 3.8 2021-08-13 16:01:45 -07:00
Kelly Brazil
166aef7a02 version bump 2021-08-13 15:22:33 -07:00
Kelly Brazil
78caf7646b add stat fix 2021-08-13 15:19:41 -07:00
Kelly Brazil
1f99d40cec fix filename with spaces for osx/bsd 2021-08-13 15:19:31 -07:00
Kelly Brazil
4c2912d3d5 use shlex.join to quote run_command_str for better error messages 2021-08-13 15:19:17 -07:00
Kelly Brazil
45e6e06be5 add glob and process substitution fixes 2021-08-13 14:19:45 -07:00
Kelly Brazil
fdbe3e05f3 fix issue with globs not including filenames with spaces with magic syntax (introduced during switch to use subprocess to grab process exit code). No longer need to shlex quote arguments. 2021-08-13 14:19:26 -07:00
Kelly Brazil
7cc168f640 add comment 2021-08-12 16:55:07 -07:00
Kelly Brazil
ff2d609c9b add close_fds=False in subprocess.Popen() to allow process substitution in magic syntax. Also check for too many open files exception 2021-08-12 16:36:35 -07:00
Kelly Brazil
2689697b4c formatting 2021-07-22 17:03:00 -07:00
Kelly Brazil
f90a0ea8ab formatting 2021-07-22 12:20:48 -07:00
Kelly Brazil
caabe60f84 fix kv example 2021-07-22 12:20:31 -07:00
Kelly Brazil
2bef4ed603 package updates 2021-07-21 08:47:16 -07:00
Kelly Brazil
ee57be533b fix sfdisk example 2021-07-20 12:35:02 -05:00
17 changed files with 59 additions and 25 deletions

View File

@@ -1,5 +1,11 @@
jc changelog
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 +21,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

View File

@@ -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
[

View File

@@ -1,7 +1,7 @@
![Tests](https://github.com/kellyjonbrazil/jc/workflows/Tests/badge.svg?branch=master)
![Pypi](https://img.shields.io/pypi/v/jc.svg)
> 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` |

View File

@@ -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",

View File

@@ -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)

View File

@@ -86,4 +86,4 @@ Module Example:
"""
name = 'jc'
__version__ = '1.16.0'
__version__ = '1.16.1'

View File

@@ -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

Binary file not shown.

View File

@@ -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",

View File

@@ -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],

View File

@@ -1,4 +1,4 @@
.TH jc 1 2021-07-20 1.16.0 "JSON CLI output utility"
.TH jc 1 2021-08-16 1.16.1 "JSON CLI output utility"
.SH NAME
jc \- JSONifies the output of many CLI tools and file-types
.SH SYNOPSIS

Binary file not shown.

View File

@@ -5,7 +5,7 @@ with open('README.md', 'r') as f:
setuptools.setup(
name='jc',
version='1.16.0',
version='1.16.1',
author='Kelly Brazil',
author_email='kellyjonbrazil@gmail.com',
description='Converts the output of popular command-line tools and file-types to JSON.',

View File

@@ -1,7 +1,7 @@
![Tests](https://github.com/kellyjonbrazil/jc/workflows/Tests/badge.svg?branch=master)
![Pypi](https://img.shields.io/pypi/v/jc.svg)
> 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` |

View 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}]

View 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

View File

@@ -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