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

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

Issue 12042069: Scripts to download files from google storage based on sha1 sums (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Removed gsutil/tests and gsutil/docs Created 7 years, 10 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
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 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 _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 if 'LINES' in os.environ:
185 ioc = env['LINES']
186 else:
187 ioc = _DEFAULT_LINES
188 return int(ioc)
189
190 def _LoadHelpMaps(self):
191 """Returns tuple (help type -> [HelpProviders],
192 help name->HelpProvider dict,
193 )."""
194 # Walk gslib/commands and gslib/addlhelp to find all HelpProviders.
195 for f in os.listdir(os.path.join(self.gsutil_bin_dir, 'gslib', 'commands')):
196 # Handles no-extension files, etc.
197 (module_name, ext) = os.path.splitext(f)
198 if ext == '.py':
199 __import__('gslib.commands.%s' % module_name)
200 for f in os.listdir(os.path.join(self.gsutil_bin_dir, 'gslib', 'addlhelp')):
201 (module_name, ext) = os.path.splitext(f)
202 if ext == '.py':
203 __import__('gslib.addlhelp.%s' % module_name)
204 help_type_map = {}
205 help_name_map = {}
206 for s in gslib.help_provider.ALL_HELP_TYPES:
207 help_type_map[s] = []
208 # Only include HelpProvider subclasses in the dict.
209 for help_prov in itertools.chain(
210 HelpProvider.__subclasses__(), Command.__subclasses__()):
211 if help_prov is Command:
212 # Skip the Command base class itself; we just want its subclasses,
213 # where the help command text lives (in addition to non-Command
214 # HelpProviders, like naming.py).
215 continue
216 gslib.help_provider.SanityCheck(help_prov, help_name_map)
217 help_name_map[help_prov.help_spec[HELP_NAME]] = help_prov
218 for help_name_aliases in help_prov.help_spec[HELP_NAME_ALIASES]:
219 help_name_map[help_name_aliases] = help_prov
220 help_type_map[help_prov.help_spec[HELP_TYPE]].append(help_prov)
221 return (help_type_map, help_name_map)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698