Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additional format options #107

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,16 +431,19 @@ formatting tool. If that is what you are looking for, then you may want to
look writing your own using crossplane's Python API.

```
usage: crossplane format [-h] [-o OUT] [-i NUM | -t] filename
usage: crossplane format [-h] [--align] [--spacious] [-o OUT | -w] [-i NUM | -t] filename

formats an nginx config file

positional arguments:
filename the nginx config file

optional arguments:
options:
-h, --help show this help message and exit
--align align directives within blocks
--spacious add line breaks after blocks
-o OUT, --out OUT write output to a file
-w, --write write output to a source file
-i NUM, --indent NUM number of spaces to indent output
-t, --tabs indent with tabs instead of spaces
```
Expand Down
18 changes: 14 additions & 4 deletions crossplane/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,15 @@ def write_block(block):
o.close()


def format(filename, out, indent=4, tabs=False):
output = format_file(filename, indent=indent, tabs=tabs)
o = sys.stdout if out is None else io.open(out, 'w', encoding='utf-8')
def format(filename, out, indent=4, tabs=False, align=False, spacious=False, write=False):
output = format_file(filename, indent=indent, tabs=tabs, align=align, spacious=spacious)

o = sys.stdout
if write:
o = io.open(filename, 'w', encoding='utf-8')
elif out is not None:
o = io.open(out, 'w', encoding='utf-8')

try:
o.write(output + u'\n')
finally:
Expand Down Expand Up @@ -226,7 +232,11 @@ def create_subparser(function, help):

p = create_subparser(format, 'formats an nginx config file')
p.add_argument('filename', help='the nginx config file')
p.add_argument('-o', '--out', type=str, help='write output to a file')
p.add_argument('--align', action='store_true', help='align directives within blocks')
p.add_argument('--spacious', action='store_true', help="add line breaks after blocks")
g = p.add_mutually_exclusive_group()
g.add_argument('-o', '--out', type=str, help='write output to a file')
g.add_argument('-w', '--write', action='store_true', help='write output to a source file')
g = p.add_mutually_exclusive_group()
g.add_argument('-i', '--indent', type=int, metavar='NUM', help='number of spaces to indent output', default=4)
g.add_argument('-t', '--tabs', action='store_true', help='indent with tabs instead of spaces')
Expand Down
16 changes: 14 additions & 2 deletions crossplane/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def _enquote(arg):
return arg


def build(payload, indent=4, tabs=False, header=False):
def build(payload, indent=4, tabs=False, header=False, align=False, spacious=False):
padding = '\t' if tabs else ' ' * indent

head = ''
Expand All @@ -84,10 +84,19 @@ def build(payload, indent=4, tabs=False, header=False):
def _build_block(output, block, depth, last_line):
margin = padding * depth

if len(block) > 0:
max_directive_length = max(len(stmt['directive']) for stmt in block)

for stmt in block:
directive = _enquote(stmt['directive'])
line = stmt.get('line', 0)

directive_padding = (
(max_directive_length + 1 - len(directive)) * ' '
if align and stmt.get('block') is None
else ' '
)

if directive == '#' and line == last_line:
output += ' #' + stmt['comment']
continue
Expand All @@ -102,7 +111,7 @@ def _build_block(output, block, depth, last_line):
if directive == 'if':
built = 'if (' + ' '.join(args) + ')'
elif args:
built = directive + ' ' + ' '.join(args)
built = directive + directive_padding + ' '.join(args)
else:
built = directive

Expand All @@ -113,6 +122,9 @@ def _build_block(output, block, depth, last_line):
built = _build_block(built, stmt['block'], depth+1, line)
built += '\n' + margin + '}'

if spacious and stmt.get('block') is not None and line - 1 != last_line:
output += '\n'

output += ('\n' if output else '') + margin + built
last_line = line

Expand Down
5 changes: 3 additions & 2 deletions crossplane/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .parser import parse


def format(filename, indent=4, tabs=False):
def format(filename, indent=4, tabs=False, align=False, spacious=False):
payload = parse(
filename,
comments=True,
Expand All @@ -18,5 +18,6 @@ def format(filename, indent=4, tabs=False):
raise NgxParserBaseException(e['error'], e['file'], e['line'])

parsed = payload['config'][0]['parsed']
output = build(parsed, indent=indent, tabs=tabs)
output = build(parsed, indent=indent, tabs=tabs,
align=align, spacious=spacious)
return output
10 changes: 10 additions & 0 deletions tests/configs/many-directives/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
server {
listen 443 ssl;
ssl_certificate fullchain.pem;
ssl_certificate_key privite.pem;
server_name _;
index index.html;
root /public;
charset utf-8;
expires $expires;
}
11 changes: 11 additions & 0 deletions tests/configs/many-directives/with-blocks.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
server {
location ~ \d {
image_filter_buffer 5M;
image_filter_interlace on;
image_filter_jpeg_quality 75;
} location ~ \d {
image_filter_buffer 5M;
image_filter_interlace on;
image_filter_jpeg_quality 75;
}
}
60 changes: 60 additions & 0 deletions tests/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,66 @@ def test_format_not_main_file():
])


def test_format_align_option():
dirname = os.path.join(here, 'configs', 'many-directives')
config = os.path.join(dirname, 'nginx.conf')
output = crossplane.format(config, align=True)
assert output == '\n'.join([
'server {',
' listen 443 ssl;',
' ssl_certificate fullchain.pem;',
' ssl_certificate_key privite.pem;',
' server_name _;',
' index index.html;',
' root /public;',
' charset utf-8;',
' expires $expires;',
'}',
])


def test_format_just_spacious_option():
dirname = os.path.join(here, 'configs', 'many-directives')
config = os.path.join(dirname, 'with-blocks.conf')
output = crossplane.format(config, spacious=True)
assert output == '\n'.join([
'server {',
' location ~ \d {',
' image_filter_buffer 5M;',
' image_filter_interlace on;',
' image_filter_jpeg_quality 75;',
' }',
'',
' location ~ \d {',
' image_filter_buffer 5M;',
' image_filter_interlace on;',
' image_filter_jpeg_quality 75;',
' }',
'}',
])


def test_format_spacious_option_with_align():
dirname = os.path.join(here, 'configs', 'many-directives')
config = os.path.join(dirname, 'with-blocks.conf')
output = crossplane.format(config, align=True, spacious=True)
assert output == '\n'.join([
'server {',
' location ~ \d {',
' image_filter_buffer 5M;',
' image_filter_interlace on;',
' image_filter_jpeg_quality 75;',
' }',
'',
' location ~ \d {',
' image_filter_buffer 5M;',
' image_filter_interlace on;',
' image_filter_jpeg_quality 75;',
' }',
'}',
])


def test_format_args_not_analyzed():
dirname = os.path.join(here, 'configs', 'bad-args')
config = os.path.join(dirname, 'nginx.conf')
Expand Down