diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml index dc6a6c4..bc44836 100644 --- a/.github/workflows/pythonapp.yml +++ b/.github/workflows/pythonapp.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: os: [macos-latest, ubuntu-latest, windows-latest] - python-version: [3.6, 3.7, 3.8, 3.9, 3.10.0] + python-version: [3.7, 3.8, 3.9, 3.10.0] steps: - uses: actions/checkout@v2 diff --git a/CHANGELOG b/CHANGELOG index 9b0a8e6..5b7d322 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ jello changelog +20211208 v1.5.0 +- Note to Package Maintainers: `/jello/man/jello.1` no longer exists. Please use `/man/jello.1` +- Wrap warning messages that exceed the terminal width +- Add support for the NO_COLOR environment variable to set mono (http://no-color.org/) +- Add -C option (opts.force_color) to force color output even when using pipes (overrides -m and NO_COLOR) + 20211129 v1.4.6 - Note to Package Maintainers: TLDR: `/jello/man/jello.1` is deprecated and only `/man/jello.1` should be used. diff --git a/README.md b/README.md index d1bbcb9..17f5cef 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ cat data.json | jello '_["foo"]' #### Options - `-c` compact print JSON output instead of pretty printing +- `-C` force color output even when using pipes (overrides `-m` and the `NO_COLOR` env variable) - `-i` initialize environment with a custom config file - `-l` lines output (suitable for bash array assignment) - `-m` monochrome output @@ -153,6 +154,10 @@ or JELLO_COLORS=default,default,default,default ``` +### Disable Colors via Environment Variable +You can set the [`NO_COLOR`](http://no-color.org/) environment variable to any value to disable color output in `jello`. Note that using the `-C` option to force color output will override both the `NO_COLOR` environment variable and the `-m` option. + +### Advanced Usage Here is more [Advanced Usage](https://github.com/kellyjonbrazil/jello/blob/master/ADVANCED_USAGE.md) information. > To accelerate filter development and testing, try [`jellex`](https://github.com/kellyjonbrazil/jellex). `jellex` is an interactive front-end TUI built on `jello` that allows you to see your filter results in real-time along with any errors. diff --git a/jello/__init__.py b/jello/__init__.py index 379637b..f29d78f 100644 --- a/jello/__init__.py +++ b/jello/__init__.py @@ -1,7 +1,7 @@ """jello - query JSON at the command line with python syntax""" -__version__ = '1.4.6' +__version__ = '1.5.0' AUTHOR = 'Kelly Brazil' WEBSITE = 'https://github.com/kellyjonbrazil/jello' COPYRIGHT = '© 2020-2021 Kelly Brazil' diff --git a/jello/cli.py b/jello/cli.py index 1e4dddf..b27abdb 100644 --- a/jello/cli.py +++ b/jello/cli.py @@ -28,6 +28,7 @@ def print_help(): Usage: cat data.json | jello [OPTIONS] [QUERY] -c compact JSON output + -C force color output even when using pipes (overrides -m) -i initialize environment with .jelloconf.py in ~ (linux) or %appdata% (Windows) -l output as lines suitable for assignment to a bash array -m monochrome output @@ -130,7 +131,8 @@ def main(data=None, query='_'): opts.compact = opts.compact or 'c' in options opts.initialize = opts.initialize or 'i' in options opts.lines = opts.lines or 'l' in options - opts.mono = opts.mono or 'm' in options + opts.force_color = opts.force_color or 'C' in options + opts.mono = opts.mono or ('m' in options or bool(os.getenv('NO_COLOR'))) opts.nulls = opts.nulls or 'n' in options opts.raw = opts.raw or 'r' in options opts.schema = opts.schema or 's' in options @@ -174,6 +176,10 @@ def main(data=None, query='_'): except Exception as e: print_exception(e, list_dict_data, query, ex_type='Query') + # reset opts.mono after pyquery since initialization in pyquery can change values + if opts.force_color: + opts.mono = False + # Create and print schema or JSON/JSON-Lines/Lines output = '' try: @@ -181,7 +187,7 @@ def main(data=None, query='_'): schema = Schema() output = schema.create_schema(response) - if not opts.mono and sys.stdout.isatty(): + if not opts.mono and (sys.stdout.isatty() or opts.force_color): schema.set_colors() output = schema.color_output(output) @@ -189,7 +195,7 @@ def main(data=None, query='_'): json_out = Json() output = json_out.create_json(response) - if not opts.mono and not opts.raw and sys.stdout.isatty(): + if (not opts.mono and not opts.raw) and (sys.stdout.isatty() or opts.force_color): json_out.set_colors() output = json_out.color_output(output) @@ -200,4 +206,4 @@ def main(data=None, query='_'): if __name__ == '__main__': - main() + pass diff --git a/jello/lib.py b/jello/lib.py index 006204f..0e8a456 100644 --- a/jello/lib.py +++ b/jello/lib.py @@ -4,6 +4,8 @@ import sys import ast import json +import shutil +from textwrap import TextWrapper from jello.dotmap import DotMap # make pygments import optional @@ -28,6 +30,7 @@ class opts: nulls = None raw = None lines = None + force_color = None mono = None schema = None types = None @@ -40,10 +43,10 @@ class opts: class JelloTheme: if PYGMENTS_INSTALLED: theme = { - Name: f'bold ansiblue', - Keyword: f'ansibrightblack', - Number: f'ansimagenta', - String: f'ansigreen' + Name: 'bold ansiblue', + Keyword: 'ansibrightblack', + Number: 'ansimagenta', + String: 'ansigreen' } def set_colors(self): @@ -85,7 +88,7 @@ def set_colors(self): # if there is an issue with the env variable, just set all colors to default and move on if input_error: - print('jello: Warning: could not parse JELLO_COLORS environment variable\n', file=sys.stderr) + warning_message(['could not parse JELLO_COLORS environment variable']) color_list = ['default', 'default', 'default', 'default'] if PYGMENTS_INSTALLED: @@ -191,12 +194,9 @@ def _schema_gen(self, src, path='_'): self._schema_gen(item, path=f'{path}.{k}[{i}]') elif isinstance(v, dict): - if not opts.mono: - k = f'{k}' self._schema_gen(v, path=f'{path}.{k}') else: - k = f'{k}' val = json.dumps(v, ensure_ascii=False) val_type = '' padding = '' @@ -338,6 +338,38 @@ def load_json(data): return json_dict +def warning_message(message_lines): + """ + Prints warning message for non-fatal issues. The first line is prepended with + 'jello: Warning - ' and subsequent lines are indented. Wraps text as needed + based on the terminal width. + + Parameters: + + message: (list) list of string lines + + Returns: + + None - just prints output to STDERR + """ + columns = shutil.get_terminal_size().columns + + first_wrapper = TextWrapper(width=columns, subsequent_indent=' ' * 12) + next_wrapper = TextWrapper(width=columns, initial_indent=' ' * 8, + subsequent_indent=' ' * 12) + + first_line = message_lines.pop(0) + first_str = f'jello: Warning - {first_line}' + first_str = first_wrapper.fill(first_str) + print(first_str, file=sys.stderr) + + for line in message_lines: + if line == '': + continue + message = next_wrapper.fill(line) + print(message, file=sys.stderr) + + def pyquery(_θ_data, _θ_query): """Sets options and runs the user's query. This function uses odd variable names so they don't collide with user defined names.""" @@ -380,9 +412,9 @@ def pyquery(_θ_data, _θ_query): _θ_i_block = ast.parse(_θ_jelloconf, mode='exec') exec(compile(_θ_i_block, '', mode='exec')) - for _θ_option in [opts.compact, opts.raw, opts.lines, opts.nulls, opts.mono, opts.schema, opts.types]: + for _θ_option in [opts.compact, opts.raw, opts.lines, opts.nulls, opts.force_color, opts.mono, opts.schema, opts.types]: if not isinstance(_θ_option, bool) and _θ_option is not None: - opts.compact = opts.raw = opts.lines = opts.nulls = opts.mono = opts.schema = opts.types = False + opts.compact = opts.raw = opts.lines = opts.nulls = opts.force_color = opts.mono = opts.schema = opts.types = False _θ_warn_options = True for _θ_color_config in [opts.keyname_color, opts.keyword_color, opts.number_color, opts.string_color]: @@ -395,11 +427,17 @@ def pyquery(_θ_data, _θ_query): _θ_warn_colors = True if _θ_warn_options: - print(f'Jello: Warning: Options must be set to True or False in {_θ_conf_file}\n Unsetting all options.\n', file=sys.stderr) + warning_message([ + f'Options must be set to True or False in {_θ_conf_file}', + 'Unsetting all options.' + ]) if _θ_warn_colors: _θ_valid_colors_string = ', '.join(_θ_valid_colors) - print(f'Jello: Warning: Colors must be set to one of: {_θ_valid_colors_string} in {_θ_conf_file}\n Unsetting all colors.\n', file=sys.stderr) + warning_message([ + f'Colors must be set to one of: {_θ_valid_colors_string} in {_θ_conf_file}', + 'Unsetting all colors.' + ]) # clean up variables del _θ_color_config diff --git a/jello/man/jello.1 b/jello/man/jello.1 deleted file mode 100644 index 52dfc45..0000000 --- a/jello/man/jello.1 +++ /dev/null @@ -1,475 +0,0 @@ -.TH jello 1 2021-11-29 1.4.6 "Jello JSON Filter" -.SH NAME -Jello \- Filter JSON and JSON Lines data with Python syntax -.SH SYNOPSIS -.PP -Jello is similar to jq in that it processes JSON and -JSON Lines data except jello uses standard python dict and -list syntax. -.PP -JSON or JSON Lines can be piped into jello (JSON Lines are -automatically slurped into a list of dictionaries) and are available as -the variable `\fB_\fP`. -Processed data can be output as JSON, JSON Lines, bash array lines, or a -grep-able schema. -.PP - -.SH USAGE - -cat data.json | jello [OPTIONS] [QUERY] - -.fi -.PP -QUERY is optional and can be most any valid python code. -`\fB_\fP` is the sanitized JSON from \fBSTDIN\fP presented as a python dict -or list of dicts. -If QUERY is omitted then the original JSON input will simply -be pretty printed. -You can use dot notation or traditional python bracket notation to -access key names. -.RS -.PP -Note: Reserved key names that cannot be accessed using dot notation can -be accessed via standard python dictionary notation. -(e.g. -_.foo[\[dq]get\[dq]] instead of _.foo.get) -.RE -.PP -A simple query: -.IP -.nf - -$ cat data.json | jello _.foo - -.fi -.PP -or -.IP -.nf - -$ cat data.json | jello \[aq]_[\[dq]foo\[dq]]\[aq] - -.fi -.SS Options -.IP -\fB-c\fP compact print JSON output instead of pretty printing -.IP -\fB-i\fP initialize environment with a custom config file -.IP -\fB-l\fP lines output (suitable for bash array assignment) -.IP -\fB-m\fP monochrome output -.IP -\fB-n\fP print selected null values -.IP -\fB-r\fP raw output of selected strings (no quotes) -.IP -\fB-s\fP print the JSON schema in grep-able format -.IP -\fB-t\fP print type annotations in schema view -.IP -\fB-h\fP help -.IP -\fB-v\fP version info - -.SS Simple Examples -.PP -Jello simply pretty prints the JSON if there are no options -passed: -.IP -.nf - -$ echo \[aq]{\[dq]foo\[dq]:\[dq]bar\[dq],\[dq]baz\[dq]:[1,2,3]}\[aq] | jello -{ - \[dq]foo\[dq]: \[dq]bar\[dq], - \[dq]baz\[dq]: [ - 1, - 2, - 3 - ] -} - -.fi -.PP -If you prefer compact output, use the \fB-c\fP option: -.IP -.nf - -$ echo \[aq]{\[dq]foo\[dq]:\[dq]bar\[dq],\[dq]baz\[dq]:[1,2,3]}\[aq] | jello -c -{\[dq]foo\[dq]:\[dq]bar\[dq],\[dq]baz\[dq]:[1,2,3]} - -.fi -.PP -Use the \fB-l\fP option to convert lists/arrays into lines: -.IP -.nf - -$ echo \[aq]{\[dq]foo\[dq]:\[dq]bar\[dq],\[dq]baz\[dq]:[1,2,3]}\[aq] | jello -l _.baz -1 -2 -3 - -.fi -.PP -The \fB-l\fP option also allows you to create JSON Lines: -.IP -.nf - -$ echo \[aq][{\[dq]foo\[dq]:\[dq]bar\[dq],\[dq]baz\[dq]:[1,2,3]},{\[dq]fiz\[dq]:\[dq]boo\[dq],\[dq]buz\[dq]:[4,5,6]}]\[aq] | jello -l -{\[dq]foo\[dq]:\[dq]bar\[dq],\[dq]baz\[dq]:[1,2,3]} -{\[dq]fiz\[dq]:\[dq]boo\[dq],\[dq]buz\[dq]:[4,5,6]} - -.fi -.PP -You can print a grep-able schema by using the \fB-s\fP option: -.IP -.nf - -$ echo \[aq]{\[dq]foo\[dq]:\[dq]bar\[dq],\[dq]baz\[dq]:[1,2,3]}\[aq] | jello -s -\&_ = {}; -\&_.foo = \[dq]bar\[dq]; -\&_.baz = []; -\&_.baz[0] = 1; -\&_.baz[1] = 2; -\&_.baz[2] = 3; - -.fi -.SS Assigning Results to a Bash Array -.PP -Use the \fB-l\fP option to print JSON array output in a manner suitable to be assigned to a bash array. -The \fB-r\fP option can be used to remove quotation marks around strings. If you want null values to be printed as null, use the \fB-n\fP option, otherwise they are printed as blank lines. -.PP -Bash variable: -.IP -.nf - -variable=($(cat data.json | jello -rl _.foo)) - -.fi -.PP -Bash array variable: -.IP -.nf - -variable=() -while read -r value; do - variable+=(\[dq]$value\[dq]) -done < <(cat data.json | jello -rl _.foo) - -.fi -.PP -.SS Examples: -.SS Printing the Grep-able Schema -.IP -.nf - -$ jc -a | jello -s -\&_ = {}; -\&_.name = "jc"; -\&_.version = "1.17.2"; -\&_.description = "JSON CLI output utility"; -\&_.author = "Kelly Brazil"; -\&_.author_email = "kellyjonbrazil@gmail.com"; -\&_.website = "https://github.com/kellyjonbrazil/jc"; -\&_.copyright = "(C) 2019-2021 Kelly Brazil"; -\&_.license = "MIT License"; -\&_.parser_count = 80; -\&_.parsers = []; -\&... - -.fi -.SS Printing the Grep-able Schema with Type Annotations -.IP -.nf - -$ jc -a | jello -st -\&_ = {}; // (object) -\&_.name = "jc"; // (string) -\&_.version = "1.17.2"; // (string) -\&_.description = "JSON CLI output utility"; // (string) -\&_.author = "Kelly Brazil"; // (string) -\&_.author_email = "kellyjonbrazil@gmail.com"; // (string) -\&_.website = "https://github.com/kellyjonbrazil/jc"; // (string) -\&_.copyright = "(C) 2019-2021 Kelly Brazil"; // (string) -\&_.license = "MIT License"; // (string) -\&_.parser_count = 80; // (number) -\&_.parsers = []; // (array) -\&... - -.fi -.SS Printing the JSON Structure -.IP -.nf - -$ jc dig example.com | jello -st | grep '(object)\e|(array)' -\&_ = []; // (array) -\&_[0] = {}; // (object) -\&_[0].flags = []; // (array) -\&_[0].opt_pseudosection = {}; // (object) -\&_[0].opt_pseudosection.edns = {}; // (object) -\&_[0].opt_pseudosection.edns.flags = []; // (array) -\&_[0].question = {}; // (object) -\&_[0].answer = []; // (array) -\&_[0].answer[0] = {}; // (object) -\&... - -.fi -.SS Lambda Functions and Math -.IP -.nf - -$ echo \[aq]{\[dq]t1\[dq]:-30, \[dq]t2\[dq]:-20, \[dq]t3\[dq]:-10, \[dq]t4\[dq]:0}\[aq] | jello \[aq]\[rs] -keys = _.keys() -vals = _.values() -cel = list(map(lambda x: (float(5)/9)*(x-32), vals)) -dict(zip(keys, cel))\[aq] -{ - \[dq]t1\[dq]: -34.44444444444444, - \[dq]t2\[dq]: -28.88888888888889, - \[dq]t3\[dq]: -23.333333333333336, - \[dq]t4\[dq]: -17.77777777777778 -} - - -.fi -.IP -.nf - -$ jc -a | jello \[aq]len([entry for entry in _.parsers if \[dq]darwin\[dq] in entry.compatible])\[aq] -45 - -.fi -.SS For Loops -.PP -Output as JSON array -.IP -.nf - -$ jc -a | jello \[aq]\[rs] -result = [] -for entry in _.parsers: - if \[dq]darwin\[dq] in entry.compatible: - result.append(entry.name) -result\[aq] -[ - \[dq]airport\[dq], - \[dq]airport_s\[dq], - \[dq]arp\[dq], - \[dq]crontab\[dq], - \[dq]crontab_u\[dq], - ... -] - -.fi -.PP -Output as bash array -.IP -.nf - -$ jc -a | jello -rl \[aq]\[rs] -result = [] -for entry in _.parsers: - if \[dq]darwin\[dq] in entry.compatible: - result.append(entry.name) -result\[aq] -airport -airport_s -arp -crontab -crontab_u -\&... - -.fi -.SS List and Dictionary Comprehension -.PP -Output as JSON array -.IP -.nf - -$ jc -a | jello \[aq][entry.name for entry in _.parsers if \[dq]darwin\[dq] in entry.compatible]\[aq] -[ - \[dq]airport\[dq], - \[dq]airport_s\[dq], - \[dq]arp\[dq], - \[dq]crontab\[dq], - \[dq]crontab_u\[dq], - ... -] - -.fi -.PP -Output as bash array -.IP -.nf - -$ jc -a | jello -rl \[aq][entry.name for entry in _.parsers if \[dq]darwin\[dq] in entry.compatible]\[aq] -airport -airport_s -arp -crontab -crontab_u -\&... - -.fi -.SS Environment Variables -.IP -.nf - -$ echo \[aq]{\[dq]login_name\[dq]: \[dq]joeuser\[dq]}\[aq] | jello \[aq]\[rs] -True if os.getenv(\[dq]LOGNAME\[dq]) == _.login_name else False\[aq] -true - -.fi -.SS Using 3rd Party Modules -.PP -You can import and use your favorite modules to manipulate the data. For example, using \fBglom\fP: -.IP -.nf - -$ jc -a | jello \[aq]\[rs] -from glom import * -glom(_, (\[dq]parsers\[dq], [\[dq]name\[dq]]))\[aq] -[ - \[dq]airport\[dq], - \[dq]airport_s\[dq], - \[dq]arp\[dq], - \[dq]blkid\[dq], - \[dq]crontab\[dq], - \[dq]crontab_u\[dq], - \[dq]csv\[dq], - ... -] - -.fi - -.SH ADVANCED USAGE -.SS Custom Configuration File -.PP -You can use the \fB-i\fP option to initialize the jello environment with your own configuration file. The configuration file accepts valid python code where you can enable/disable \f[C]jello\f[R] options, customize your colors, add \fBimport\fP statements for your favorite modules, and define your own functions. -.PP -The file must be named \fB.jelloconf.py\fP and must be located in the proper directory based on the OS platform: -.IP -Linux, unix, macOS: \fB\[ti]/\fP -.IP -Windows: \fB%appdata%/\fP -.SS Setting Options -.PP -To set jello options in the \fB.jelloconf.py\fP file, import the \fBjello.lib.opts\fP class, add any of the following and set to \fBTrue\fP or \fBFalse\fP: -.IP -.nf -from jello.lib import opts -opts.mono = True # -m option -opts.compact = True # -c option -opts.lines = True # -l option -opts.raw = True # -r option -opts.nulls = True # -n option -opts.schema = True # -s option -opts.types = True # -t option -.fi -.SS Setting Colors -.PP -You can customize the colors by importing the \fBjello.lib.opts\fP class and setting the following variables to one of the following string values: \fBblack\fP, \fBred\fP, \fBgreen\fP, \fByellow\fP, \fBblue\fP, \fBmagenta\fP, \fBcyan\fP, \fBgray\fP, \fBbrightblack\fP, \fBbrightred\fP, \fBbrightgreen\fP, \fBbrightyellow\fP, \fBbrightblue\fP, \fBbrightmagenta\fP, \fBbrightcyan\fP, or \fBwhite\fP. -.IP -.nf -\f[C] -from jello.lib import opts -opts.keyname_color = \[aq]blue\[aq] # Key names -opts.keyword_color = \[aq]brightblack\[aq] # true, false, null -opts.number_color = \[aq]magenta\[aq] # integers, floats -opts.string_color = \[aq]green\[aq] # strings -\f[R] -.fi -.RS -.PP -Note: Any colors set via the \fBJELLO_COLORS\fP environment variable will take precedence over any color values set in the \fB.jelloconf.py\fP configuration file -.RE -.SS Importing Modules -.PP -To import a module (e.g. \fBglom\fP) during initialization, just add the \fBimport\fP statement to your \fB.jelloconf.py\fP file: -.IP -.nf -\f[C] -from glom import * -\f[R] -.fi -.PP -Then you can use \fBglom\fP in your jello filters without importing: -.IP -.nf -\f[C] -$ jc -a | jello -i \[aq]glom(_, \[dq]parsers.25.name\[dq])\[aq] -\[dq]lsblk\[dq] -\f[R] -.fi -.SS Adding Functions -.PP -You can also add functions to your initialization file. For example, you could simplify \fBglom\fP use by adding the following function to \fB.jelloconf.py\fP: -.IP -.nf -\f[C] -def g(q, data=_): - import glom - return glom.glom(data, q) -\f[R] -.fi -.PP -Then you can use the following syntax to filter the JSON data: -.IP -.nf -\f[C] -$ jc -a | jello -i \[aq]g(\[dq]parsers.6.compatible\[dq])\[aq] -[ - \[dq]linux\[dq], - \[dq]darwin\[dq], - \[dq]cygwin\[dq], - \[dq]win32\[dq], - \[dq]aix\[dq], - \[dq]freebsd\[dq] -] -\f[R] -.fi -.SS Setting Custom Colors via Environment Variable -.PP -In addition to setting custom colors in the \fB.jelloconf.py\fP initialization file, you can also set them via the \fBJELLO_COLORS\fP environment variable. Any colors set in the environment variable will take precedence over any -colors set in the initialization file. -.PP -The \fBJELLO_COLORS\fP environment variable takes four comma separated string values in the following format: -.IP -.nf -\f[C] -JELLO_COLORS=,,, -\f[R] -.fi -.PP -Where colors are: \fBblack\fP, \fBred\fP, \fBgreen\fP, -\fByellow\fP, \fBblue\fP, \fBmagenta\fP, \fBcyan\fP, -\fBgray\fP, \fBbrightblack\fP, \fBbrightred\fP, -\fBbrightgreen\fP, \fBbrightyellow\fP, \fBbrightblue\fP, -\fBbrightmagenta\fP, \fBbrightcyan\fP, \fBwhite\fP, or -\fBdefault\fP -.PP -For example, to set to the default colors: -.IP -.nf -\f[C] -JELLO_COLORS=blue,brightblack,magenta,green -\f[R] -.fi -.PP -or -.IP -.nf -\f[C] -JELLO_COLORS=default,default,default,default -\f[R] -.fi - -.SH AUTHOR -Kelly Brazil (kellyjonbrazil@gmail.com) - -https://github.com/kellyjonbrazil/jello - -.SH COPYRIGHT -Copyright (c) 2020-2021 Kelly Brazil - -License: MIT License diff --git a/man/jello.1 b/man/jello.1 index 52dfc45..79932ba 100644 --- a/man/jello.1 +++ b/man/jello.1 @@ -1,4 +1,4 @@ -.TH jello 1 2021-11-29 1.4.6 "Jello JSON Filter" +.TH jello 1 2021-12-08 1.5.0 "Jello JSON Filter" .SH NAME Jello \- Filter JSON and JSON Lines data with Python syntax .SH SYNOPSIS @@ -54,6 +54,8 @@ $ cat data.json | jello \[aq]_[\[dq]foo\[dq]]\[aq] .IP \fB-c\fP compact print JSON output instead of pretty printing .IP +\fB-C\fP force color output even when using pipes (overrides \fB-m\fP and the \fBNO_COLOR\fP env variable) +.IP \fB-i\fP initialize environment with a custom config file .IP \fB-l\fP lines output (suitable for bash array assignment) @@ -362,6 +364,7 @@ opts.mono = True # -m option opts.compact = True # -c option opts.lines = True # -l option opts.raw = True # -r option +opts.force_color = True # -C option opts.nulls = True # -n option opts.schema = True # -s option opts.types = True # -t option @@ -464,6 +467,10 @@ JELLO_COLORS=default,default,default,default \f[R] .fi +.SS Disable Colors via Environment Variable +.PP +You can set the \fBNO_COLOR\fP environment variable to any value to disable color output in \fBjello\fP. Note that using the \fB-C\fP option to force color output will override both the \fBNO_COLOR\fP environment variable and the \fB-m\fP option. + .SH AUTHOR Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/setup.py b/setup.py index ab41b96..2e4997a 100755 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name='jello', - version='1.4.6', + version='1.5.0', author='Kelly Brazil', author_email='kellyjonbrazil@gmail.com', description='Filter JSON and JSON Lines data with Python syntax.', diff --git a/tests/test_main.py b/tests/test_main.py index 865e226..43ac2d2 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -24,6 +24,7 @@ def setUp(self): opts.nulls = None opts.raw = None opts.lines = None + opts.force_color = None opts.mono = None opts.schema = None opts.types = None