Skip to content
This repository was archived by the owner on Oct 3, 2020. It is now read-only.

Commit 151b69f

Browse files
committed
Merge pull request #2 from zalando/feature/real-example
2 parents a9ff40f + f475f8b commit 151b69f

5 files changed

Lines changed: 539 additions & 15 deletions

File tree

README.rst

Lines changed: 174 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,180 @@ Usage
4242
print_table(['col1', 'col2'], rows)
4343
4444
45-
.. _Click library: http://click.pocoo.org/3/
45+
.. _Click library: http://click.pocoo.org/
46+
47+
Working Example
48+
---------------
49+
50+
See this `example script`_ and the `shell script`_.
51+
52+
.. _example script: example.py
53+
54+
.. literalinclude:: example.py
55+
:language: python3
56+
:linenos:
57+
58+
59+
.. _shell script: example.sh
60+
61+
.. literalinclude:: example.sh
62+
:language: bash
63+
:linenos:
64+
65+
::
66+
67+
$ ./example.py
68+
Usage: example.py [OPTIONS] COMMAND [ARGS]...
69+
70+
Options:
71+
-V, --version Print the current version number and exit.
72+
-h, --help Show this message and exit.
73+
74+
Commands:
75+
list Example for Listings
76+
localtime Print the localtime
77+
output Example for all possible Echo Formats You see...
78+
work-in-progress Work untile working is done
79+
work_done Work done in ?? %
80+
81+
::
82+
83+
$ ./example.py l
84+
Usage: example.py [OPTIONS] COMMAND [ARGS]...
85+
86+
Error: Too many matches: list, localtime
87+
88+
::
89+
90+
$ ./example.py lo
91+
Localtime: 2015-08-27 15:47:46.688547
92+
93+
::
94+
95+
$ ./example.py li
96+
Identifier│Name │Status │Creation Date│Description │Without Title
97+
0 Column #0 ERROR -4228033s ago this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.. column without title
98+
1 Column #1 FINE -4228033s ago this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.. column without title
99+
2 Column #2 WARNING -4228033s ago this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.. column without title
100+
101+
::
102+
103+
$ ./example.py li -o tsv
104+
id name state creation_time desc without_title
105+
0 Column #0 ERROR -4228033s ago this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long description column without title
106+
1 Column #1 FINE -4228033s ago this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long description column without title
107+
2 Column #2 WARNING -4228033s ago this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long description column without title
108+
109+
::
110+
111+
$ ./example.py li -o json
112+
[{"creation_time": 1444911300, "desc": "this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long description", "id": 0, "name": "Column #0", "state": "ERROR", "without_title": "column without title"}, {"creation_time": 1444911300, "desc": "this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long description", "id": 1, "name": "Column #1", "state": "FINE", "without_title": "column without title"}, {"creation_time": 1444911300, "desc": "this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long description", "id": 2, "name": "Column #2", "state": "WARNING", "without_title": "column without title"}]
113+
114+
::
115+
116+
$ ./example.py li -o yaml
117+
creation_time: 1444911300
118+
desc: this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long description
119+
id: 0
120+
name: 'Column #0'
121+
state: ERROR
122+
without_title: column without title
123+
---
124+
creation_time: 1444911300
125+
desc: this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long description
126+
id: 1
127+
name: 'Column #1'
128+
state: FINE
129+
without_title: column without title
130+
---
131+
creation_time: 1444911300
132+
desc: this is a verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrry long description
133+
id: 2
134+
name: 'Column #2'
135+
state: WARNING
136+
without_title: column without title
137+
138+
139+
::
140+
141+
$ ./example.py work-
142+
do anything.. OK
143+
create an excption.. EXCEPTION OCCURRED: No active exception to reraise
144+
Start with working.. . . . . OK
145+
Calc 1 + 1.. 2
146+
Oh, I make an error.. work not complete done
147+
Oh, I make a warning.. work is complicated
148+
Start an exception.. EXCEPTION OCCURRED: name 'function_not_found' is not defined
149+
Make a final error.. this is the end..
150+
151+
::
152+
153+
$ ./example.py work_ 15.4
154+
Please select the state of your work
155+
1) Done
156+
2) In Progress
157+
3) unknown
158+
4) lost
159+
Please select (1-4) [4]: 2
160+
Your work is 15.4% In Progress
161+
162+
::
163+
164+
$ ./example.py work_ 15.4
165+
Please select the state of your work
166+
1) Done
167+
2) In Progress
168+
3) unknown
169+
4) lost
170+
Please select (1-4) [4]: 3
171+
Your work is 15.4% unknown
172+
173+
::
174+
175+
$ ./example.py work_ 15.4
176+
Please select the state of your work
177+
1) Done
178+
2) In Progress
179+
3) unknown
180+
4) lost
181+
Please select (1-4) [4]:
182+
Your work is 15.4% lost
183+
184+
::
185+
186+
$ ./example.py output
187+
This is a ok: OK
188+
This is a ok with message:all is fine
189+
This is a warning: please check this
190+
Start with working.. . . . . OK
191+
Id│Name
192+
1 Test #1
193+
2 Test #2
194+
Only FYI
195+
This is a error: this is wrong, please fix
196+
This is a fatal error: this is a fuckup
197+
198+
::
199+
200+
$ ./example.py output -o tsv
201+
id name
202+
1 Test #1
203+
2 Test #2
204+
205+
::
206+
207+
$ ./example.py output -o json
208+
[{"id": 1, "name": "Test #1"}, {"id": 2, "name": "Test #2"}]
209+
210+
::
211+
212+
$ ./example.py output -o yaml
213+
id: 1
214+
name: 'Test #1'
215+
---
216+
id: 2
217+
name: 'Test #2'
218+
46219

47220
License
48221
=======

clickclick/console.py

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
import json
44
import sys
55
import time
6-
6+
import yaml
7+
import numbers
78

89
# global state is evil!
910
# anyway, we are using this as a convenient hack to switch output formats
@@ -14,12 +15,20 @@ def is_json_output():
1415
return GLOBAL_STATE.get('output_format') == 'json'
1516

1617

18+
def is_yaml_output():
19+
return GLOBAL_STATE.get('output_format') == 'yaml'
20+
21+
1722
def is_tsv_output():
1823
return GLOBAL_STATE.get('output_format') == 'tsv'
1924

2025

26+
def is_text_output():
27+
return GLOBAL_STATE.get('output_format') == 'text'
28+
29+
2130
def secho(*args, **kwargs):
22-
if not is_json_output():
31+
if is_text_output():
2332
click.secho(*args, **kwargs)
2433

2534

@@ -69,6 +78,7 @@ def __init__(self, msg, **kwargs):
6978
self.msg_args = kwargs
7079
self.errors = []
7180
self._suppress_exception = False
81+
self.ok_msg = ' OK'
7282

7383
def __enter__(self):
7484
action(self.msg, **self.msg_args)
@@ -77,7 +87,7 @@ def __enter__(self):
7787
def __exit__(self, exc_type, exc_val, exc_tb):
7888
if exc_type is None:
7989
if not self.errors:
80-
ok()
90+
ok(self.ok_msg)
8191
elif not self._suppress_exception:
8292
error('EXCEPTION OCCURRED: {}'.format(exc_val))
8393

@@ -90,7 +100,14 @@ def error(self, msg, **kwargs):
90100
self.errors.append(msg)
91101

92102
def progress(self):
93-
click.secho(' .', nl=False)
103+
secho(' .', nl=False)
104+
105+
def warning(self, msg, **kwargs):
106+
warning(msg, **kwargs)
107+
self.errors.append(msg)
108+
109+
def ok(self, msg):
110+
self.ok_msg = ' {}'.format(msg)
94111

95112

96113
def get_now():
@@ -145,25 +162,28 @@ def print_tsv_table(cols, rows):
145162

146163

147164
def print_table(cols, rows, styles=None, titles=None, max_column_widths=None):
148-
if is_json_output():
165+
if is_json_output() or is_yaml_output():
149166
new_rows = []
150167
for row in rows:
151168
new_row = {}
152169
for col in cols:
153170
new_row[col] = row.get(col)
154171
new_rows.append(new_row)
155-
print(json.dumps(new_rows, sort_keys=True))
172+
if is_json_output():
173+
print(json.dumps(new_rows, sort_keys=True))
174+
else:
175+
print(yaml.safe_dump_all(new_rows, default_flow_style=False))
156176
return
157177
elif is_tsv_output():
158178
return print_tsv_table(cols, rows)
159179

160-
if not styles:
180+
if not styles or type(styles) != dict:
161181
styles = {}
162182

163-
if not titles:
183+
if not titles or type(titles) != dict:
164184
titles = {}
165185

166-
if not max_column_widths:
186+
if not max_column_widths or type(max_column_widths) != dict:
167187
max_column_widths = {}
168188

169189
colwidths = {}
@@ -192,7 +212,7 @@ def print_table(cols, rows, styles=None, titles=None, max_column_widths=None):
192212
except:
193213
# val might not be hashable
194214
style = {}
195-
if val is not None and col.endswith('_time'):
215+
if val is not None and col.endswith('_time') and isinstance(val, numbers.Number):
196216
align = '>'
197217
diff = time.time() - val
198218
if diff < 900:
@@ -210,19 +230,22 @@ def print_table(cols, rows, styles=None, titles=None, max_column_widths=None):
210230
click.echo('')
211231

212232

213-
def choice(prompt: str, options: list):
233+
def choice(prompt: str, options: list, default=None):
214234
"""
215235
Ask to user to select one option and return it
216236
"""
217237
click.secho(prompt)
238+
promptdefault = None
218239
for i, option in enumerate(options):
219240
if isinstance(option, tuple):
220241
value, label = option
221242
else:
222243
value = label = option
244+
if value == default:
245+
promptdefault = i + 1
223246
click.secho('{}) {}'.format(i+1, label))
224247
while True:
225-
selection = click.prompt('Please select (1-{})'.format(len(options)), type=int)
248+
selection = click.prompt('Please select (1-{})'.format(len(options)), type=int, default=promptdefault)
226249
try:
227250
result = options[int(selection)-1]
228251
if isinstance(result, tuple):

0 commit comments

Comments
 (0)