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

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

Issue 2280023003: depot_tools: Remove third_party/gsutil (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « third_party/gsutil/gslib/commands/getwebcfg.py ('k') | third_party/gsutil/gslib/commands/ls.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2011 Google Inc. All Rights Reserved.
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 : ['?', 'man'],
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 return 0
137
138 def _OutputHelp(self, str):
139 """Outputs simply formatted string, paginating if long and PAGER defined"""
140 # Replace <B> and </B> with terminal formatting strings.
141 str = re.sub('<B>', '\033[1m', str)
142 str = re.sub('</B>', '\033[0;0m', str)
143 num_lines = len(str.split('\n'))
144 if 'PAGER' in os.environ and num_lines >= self.getTermLines():
145 # Use -r option for less to make bolding work right.
146 pager = os.environ['PAGER'].split(' ')
147 if pager[0].endswith('less'):
148 pager.append('-r')
149 try:
150 Popen(pager, stdin=PIPE).communicate(input=str)
151 except OSError, e:
152 raise CommandException('Unable to open pager (%s): %s' %
153 (' '.join(pager), e))
154 else:
155 print str
156
157 _DEFAULT_LINES = 25
158
159 def getTermLines(self):
160 """Returns number of terminal lines"""
161 # fcntl isn't supported in Windows.
162 try:
163 import fcntl
164 import termios
165 except ImportError:
166 return self._DEFAULT_LINES
167 def ioctl_GWINSZ(fd):
168 try:
169 return struct.unpack(
170 'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))[0]
171 except:
172 return 0 # Failure (so will retry on different file descriptor below).
173 # Try to find a valid number of lines from termio for stdin, stdout,
174 # or stderr, in that order.
175 ioc = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
176 if not ioc:
177 try:
178 fd = os.open(os.ctermid(), os.O_RDONLY)
179 ioc = ioctl_GWINSZ(fd)
180 os.close(fd)
181 except:
182 pass
183 if not ioc:
184 ioc = os.environ.get('LINES', self._DEFAULT_LINES)
185 return int(ioc)
186
187 def _LoadHelpMaps(self):
188 """Returns tuple (help type -> [HelpProviders],
189 help name->HelpProvider dict,
190 )."""
191 # Walk gslib/commands and gslib/addlhelp to find all HelpProviders.
192 for f in os.listdir(os.path.join(self.gsutil_bin_dir, 'gslib', 'commands')):
193 # Handles no-extension files, etc.
194 (module_name, ext) = os.path.splitext(f)
195 if ext == '.py':
196 __import__('gslib.commands.%s' % module_name)
197 for f in os.listdir(os.path.join(self.gsutil_bin_dir, 'gslib', 'addlhelp')):
198 (module_name, ext) = os.path.splitext(f)
199 if ext == '.py':
200 __import__('gslib.addlhelp.%s' % module_name)
201 help_type_map = {}
202 help_name_map = {}
203 for s in gslib.help_provider.ALL_HELP_TYPES:
204 help_type_map[s] = []
205 # Only include HelpProvider subclasses in the dict.
206 for help_prov in itertools.chain(
207 HelpProvider.__subclasses__(), Command.__subclasses__()):
208 if help_prov is Command:
209 # Skip the Command base class itself; we just want its subclasses,
210 # where the help command text lives (in addition to non-Command
211 # HelpProviders, like naming.py).
212 continue
213 gslib.help_provider.SanityCheck(help_prov, help_name_map)
214 help_name_map[help_prov.help_spec[HELP_NAME]] = help_prov
215 for help_name_aliases in help_prov.help_spec[HELP_NAME_ALIASES]:
216 help_name_map[help_name_aliases] = help_prov
217 help_type_map[help_prov.help_spec[HELP_TYPE]].append(help_prov)
218 return (help_type_map, help_name_map)
OLDNEW
« no previous file with comments | « third_party/gsutil/gslib/commands/getwebcfg.py ('k') | third_party/gsutil/gslib/commands/ls.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698