Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(400)

Side by Side Diff: third_party/gsutil/gslib/commands/help.py

Issue 10199002: Upgrade gsutil to 3.4 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright 2011 Google Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import gslib
16 import itertools
17 import os
18 import re
19 import struct
20 import sys
21
22 from gslib.command import Command
23 from gslib.command import COMMAND_NAME
24 from gslib.command import COMMAND_NAME_ALIASES
25 from gslib.command import CONFIG_REQUIRED
26 from gslib.command import FILE_URIS_OK
27 from gslib.command import MAX_ARGS
28 from gslib.command import MIN_ARGS
29 from gslib.command import PROVIDER_URIS_OK
30 from gslib.command import SUPPORTED_SUB_ARGS
31 from gslib.command import URIS_START_ARG
32 from gslib.exception import CommandException
33 from gslib.help_provider import ALL_HELP_TYPES
34 from gslib.help_provider import HELP_NAME
35 from gslib.help_provider import HELP_NAME_ALIASES
36 from gslib.help_provider import HELP_ONE_LINE_SUMMARY
37 from gslib.help_provider import HelpProvider
38 from gslib.help_provider import HELP_TEXT
39 from gslib.help_provider import HelpType
40 from gslib.help_provider import HELP_TYPE
41 from gslib.help_provider import MAX_HELP_NAME_LEN
42 from subprocess import PIPE
43 from subprocess import Popen
44
45 _detailed_help_text = ("""
46 <B>SYNOPSIS</B>
47 gsutil help [command or topic]
48
49
50 <B>DESCRIPTION</B>
51 Running:
52 gsutil help
53 will provide a summary of all commands and additional topics on which
54 help is available.
55
56 Running:
57 gsutil help command or topic
58 will provide help about the specified command or topic.
59
60 If you set the PAGER environment variable to the path to a pager program
61 (such as /bin/less on Linux), long help sections will be piped through
62 the specified pager.
63 """)
64
65 top_level_usage_string = (
66 "Usage: gsutil [-d][-D] [-h header]... [-m] [command [opts...] args...]"
67 )
68
69 class HelpCommand(Command):
70 """Implementation of gsutil help command."""
71
72 # Command specification (processed by parent class).
73 command_spec = {
74 # Name of command.
75 COMMAND_NAME : 'help',
76 # List of command name aliases.
77 COMMAND_NAME_ALIASES : ['?'],
78 # Min number of args required by this command.
79 MIN_ARGS : 0,
80 # Max number of args required by this command, or NO_MAX.
81 MAX_ARGS : 1,
82 # Getopt-style string specifying acceptable sub args.
83 SUPPORTED_SUB_ARGS : '',
84 # True if file URIs acceptable for this command.
85 FILE_URIS_OK : True,
86 # True if provider-only URIs acceptable for this command.
87 PROVIDER_URIS_OK : False,
88 # Index in args of first URI arg.
89 URIS_START_ARG : 0,
90 # True if must configure gsutil before running command.
91 CONFIG_REQUIRED : False,
92 }
93 help_spec = {
94 # Name of command or auxiliary help info for which this help applies.
95 HELP_NAME : 'help',
96 # List of help name aliases.
97 HELP_NAME_ALIASES : ['?'],
98 # Type of help:
99 HELP_TYPE : HelpType.COMMAND_HELP,
100 # One line summary of this help.
101 HELP_ONE_LINE_SUMMARY : 'Get help about commands and topics',
102 # The full help text.
103 HELP_TEXT : _detailed_help_text,
104 }
105
106 # Command entry point.
107 def RunCommand(self):
108 (help_type_map, help_name_map) = self._LoadHelpMaps()
109 output = []
110 if not len(self.args):
111 output.append('%s\nAvailable commands:\n' % top_level_usage_string)
112 format_str = ' %-' + str(MAX_HELP_NAME_LEN) + 's%s\n'
113 for help_prov in sorted(help_type_map[HelpType.COMMAND_HELP],
114 key=lambda hp: hp.help_spec[HELP_NAME]):
115 output.append(format_str % (help_prov.help_spec[HELP_NAME],
116 help_prov.help_spec[HELP_ONE_LINE_SUMMARY]))
117 output.append('\nAdditional help topics:\n')
118 for help_prov in sorted(help_type_map[HelpType.ADDITIONAL_HELP],
119 key=lambda hp: hp.help_spec[HELP_NAME]):
120 output.append(format_str % (help_prov.help_spec[HELP_NAME],
121 help_prov.help_spec[HELP_ONE_LINE_SUMMARY]))
122 output.append('\nUse gsutil help <command or topic> for detailed help.')
123 else:
124 arg = self.args[0]
125 if arg not in help_name_map:
126 output.append('No help available for "%s"' % arg)
127 else:
128 help_prov = help_name_map[self.args[0]]
129 output.append('<B>NAME</B>\n')
130 output.append(' %s - %s\n' % (
131 help_prov.help_spec[HELP_NAME],
132 help_prov.help_spec[HELP_ONE_LINE_SUMMARY]))
133 output.append('\n\n')
134 output.append(help_prov.help_spec[HELP_TEXT].strip('\n'))
135 self._OutputHelp(''.join(output))
136
137 def _OutputHelp(self, str):
138 """Outputs simply formatted string, paginating if long and PAGER defined"""
139 # Replace <B> and </B> with terminal formatting strings.
140 str = re.sub('<B>', '\033[1m', str)
141 str = re.sub('</B>', '\033[0;0m', str)
142 num_lines = len(str.split('\n'))
143 if 'PAGER' in os.environ and num_lines >= self.getTermLines():
144 # Use -r option for less to make bolding work right.
145 pager = os.environ['PAGER'].split(' ')
146 if pager[0].endswith('less'):
147 pager.append('-r')
148 try:
149 Popen(pager, stdin=PIPE).communicate(input=str)
150 except OSError, e:
151 raise CommandException('Unable to open pager (%s): %s' %
152 (' '.join(pager), e))
153 else:
154 print str
155
156 _DEFAULT_LINES = 25
157
158 def getTermLines(self):
159 """Returns number of terminal lines"""
160 # fcntl isn't supported in Windows.
161 try:
162 import fcntl
163 import termios
164 except ImportError:
165 return _DEFAULT_LINES
166 def ioctl_GWINSZ(fd):
167 try:
168 return struct.unpack(
169 'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))[0]
170 except:
171 return 0 # Failure (so will retry on different file descriptor below).
172 # Try to find a valid number of lines from termio for stdin, stdout,
173 # or stderr, in that order.
174 ioc = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
175 if not ioc:
176 try:
177 fd = os.open(os.ctermid(), os.O_RDONLY)
178 ioc = ioctl_GWINSZ(fd)
179 os.close(fd)
180 except:
181 pass
182 if not ioc:
183 if 'LINES' in os.environ:
184 ioc = env['LINES']
185 else:
186 ioc = _DEFAULT_LINES
187 return int(ioc)
188
189 def _LoadHelpMaps(self):
190 """Returns tuple (help type -> [HelpProviders],
191 help name->HelpProvider dict,
192 )."""
193 # Walk gslib/commands and gslib/addlhelp to find all HelpProviders.
194 for f in os.listdir(os.path.join(self.gsutil_bin_dir, 'gslib', 'commands')):
195 # Handles no-extension files, etc.
196 (module_name, ext) = os.path.splitext(f)
197 if ext == '.py':
198 __import__('gslib.commands.%s' % module_name)
199 for f in os.listdir(os.path.join(self.gsutil_bin_dir, 'gslib', 'addlhelp')):
200 (module_name, ext) = os.path.splitext(f)
201 if ext == '.py':
202 __import__('gslib.addlhelp.%s' % module_name)
203 help_type_map = {}
204 help_name_map = {}
205 for s in gslib.help_provider.ALL_HELP_TYPES:
206 help_type_map[s] = []
207 # Only include HelpProvider subclasses in the dict.
208 for help_prov in itertools.chain(
209 HelpProvider.__subclasses__(), Command.__subclasses__()):
210 if help_prov is Command:
211 # Skip the Command base class itself; we just want its subclasses,
212 # where the help command text lives (in addition to non-Command
213 # HelpProviders, like naming.py).
214 continue
215 gslib.help_provider.SanityCheck(help_prov, help_name_map)
216 help_name_map[help_prov.help_spec[HELP_NAME]] = help_prov
217 for help_name_aliases in help_prov.help_spec[HELP_NAME_ALIASES]:
218 help_name_map[help_name_aliases] = help_prov
219 help_type_map[help_prov.help_spec[HELP_TYPE]].append(help_prov)
220 return (help_type_map, help_name_map)
OLDNEW
« no previous file with comments | « third_party/gsutil/gslib/commands/getlogging.py ('k') | third_party/gsutil/gslib/commands/ls.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698