Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/sqlparse/cli.py: 12%
62 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1#!/usr/bin/env python
2#
3# Copyright (C) 2009-2020 the sqlparse authors and contributors
4# <see AUTHORS file>
5#
6# This module is part of python-sqlparse and is released under
7# the BSD License: https://opensource.org/licenses/BSD-3-Clause
9"""Module that contains the command line app.
11Why does this file exist, and why not put this in __main__?
12 You might be tempted to import things from __main__ later, but that will
13 cause problems: the code will get executed twice:
14 - When you run `python -m sqlparse` python will execute
15 ``__main__.py`` as a script. That means there won't be any
16 ``sqlparse.__main__`` in ``sys.modules``.
17 - When you import __main__ it will get executed again (as a module) because
18 there's no ``sqlparse.__main__`` in ``sys.modules``.
19 Also see (1) from http://click.pocoo.org/5/setuptools/#setuptools-integration
20"""
22import argparse
23import sys
24from io import TextIOWrapper
26import sqlparse
27from sqlparse.exceptions import SQLParseError
30# TODO: Add CLI Tests
31# TODO: Simplify formatter by using argparse `type` arguments
32def create_parser():
33 _CASE_CHOICES = ['upper', 'lower', 'capitalize']
35 parser = argparse.ArgumentParser(
36 prog='sqlformat',
37 description='Format FILE according to OPTIONS. Use "-" as FILE '
38 'to read from stdin.',
39 usage='%(prog)s [OPTIONS] FILE, ...',
40 )
42 parser.add_argument('filename')
44 parser.add_argument(
45 '-o', '--outfile',
46 dest='outfile',
47 metavar='FILE',
48 help='write output to FILE (defaults to stdout)')
50 parser.add_argument(
51 '--version',
52 action='version',
53 version=sqlparse.__version__)
55 group = parser.add_argument_group('Formatting Options')
57 group.add_argument(
58 '-k', '--keywords',
59 metavar='CHOICE',
60 dest='keyword_case',
61 choices=_CASE_CHOICES,
62 help='change case of keywords, CHOICE is one of {}'.format(
63 ', '.join('"{}"'.format(x) for x in _CASE_CHOICES)))
65 group.add_argument(
66 '-i', '--identifiers',
67 metavar='CHOICE',
68 dest='identifier_case',
69 choices=_CASE_CHOICES,
70 help='change case of identifiers, CHOICE is one of {}'.format(
71 ', '.join('"{}"'.format(x) for x in _CASE_CHOICES)))
73 group.add_argument(
74 '-l', '--language',
75 metavar='LANG',
76 dest='output_format',
77 choices=['python', 'php'],
78 help='output a snippet in programming language LANG, '
79 'choices are "python", "php"')
81 group.add_argument(
82 '--strip-comments',
83 dest='strip_comments',
84 action='store_true',
85 default=False,
86 help='remove comments')
88 group.add_argument(
89 '-r', '--reindent',
90 dest='reindent',
91 action='store_true',
92 default=False,
93 help='reindent statements')
95 group.add_argument(
96 '--indent_width',
97 dest='indent_width',
98 default=2,
99 type=int,
100 help='indentation width (defaults to 2 spaces)')
102 group.add_argument(
103 '--indent_after_first',
104 dest='indent_after_first',
105 action='store_true',
106 default=False,
107 help='indent after first line of statement (e.g. SELECT)')
109 group.add_argument(
110 '--indent_columns',
111 dest='indent_columns',
112 action='store_true',
113 default=False,
114 help='indent all columns by indent_width instead of keyword length')
116 group.add_argument(
117 '-a', '--reindent_aligned',
118 action='store_true',
119 default=False,
120 help='reindent statements to aligned format')
122 group.add_argument(
123 '-s', '--use_space_around_operators',
124 action='store_true',
125 default=False,
126 help='place spaces around mathematical operators')
128 group.add_argument(
129 '--wrap_after',
130 dest='wrap_after',
131 default=0,
132 type=int,
133 help='Column after which lists should be wrapped')
135 group.add_argument(
136 '--comma_first',
137 dest='comma_first',
138 default=False,
139 type=bool,
140 help='Insert linebreak before comma (default False)')
142 group.add_argument(
143 '--encoding',
144 dest='encoding',
145 default='utf-8',
146 help='Specify the input encoding (default utf-8)')
148 return parser
151def _error(msg):
152 """Print msg and optionally exit with return code exit_."""
153 sys.stderr.write('[ERROR] {}\n'.format(msg))
154 return 1
157def main(args=None):
158 parser = create_parser()
159 args = parser.parse_args(args)
161 if args.filename == '-': # read from stdin
162 wrapper = TextIOWrapper(sys.stdin.buffer, encoding=args.encoding)
163 try:
164 data = wrapper.read()
165 finally:
166 wrapper.detach()
167 else:
168 try:
169 with open(args.filename, encoding=args.encoding) as f:
170 data = ''.join(f.readlines())
171 except OSError as e:
172 return _error(
173 'Failed to read {}: {}'.format(args.filename, e))
175 close_stream = False
176 if args.outfile:
177 try:
178 stream = open(args.outfile, 'w', encoding=args.encoding)
179 close_stream = True
180 except OSError as e:
181 return _error('Failed to open {}: {}'.format(args.outfile, e))
182 else:
183 stream = sys.stdout
185 formatter_opts = vars(args)
186 try:
187 formatter_opts = sqlparse.formatter.validate_options(formatter_opts)
188 except SQLParseError as e:
189 return _error('Invalid options: {}'.format(e))
191 s = sqlparse.format(data, **formatter_opts)
192 stream.write(s)
193 stream.flush()
194 if close_stream:
195 stream.close()
196 return 0