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

Unified Diff: tools/telemetry/third_party/gsutil/third_party/python-gflags/gflags2man.py

Issue 1260493004: Revert "Add gsutil 4.13 to telemetry/third_party" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/third_party/gsutil/third_party/python-gflags/gflags2man.py
diff --git a/tools/telemetry/third_party/gsutil/third_party/python-gflags/gflags2man.py b/tools/telemetry/third_party/gsutil/third_party/python-gflags/gflags2man.py
deleted file mode 100644
index 3a50f9e19fcf0fb6e78ba24daf868bd2068c8bbb..0000000000000000000000000000000000000000
--- a/tools/telemetry/third_party/gsutil/third_party/python-gflags/gflags2man.py
+++ /dev/null
@@ -1,544 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2006, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-"""gflags2man runs a Google flags base program and generates a man page.
-
-Run the program, parse the output, and then format that into a man
-page.
-
-Usage:
- gflags2man <program> [program] ...
-"""
-
-# TODO(csilvers): work with windows paths (\) as well as unix (/)
-
-# This may seem a bit of an end run, but it: doesn't bloat flags, can
-# support python/java/C++, supports older executables, and can be
-# extended to other document formats.
-# Inspired by help2man.
-
-
-
-import os
-import re
-import sys
-import stat
-import time
-
-import gflags
-
-_VERSION = '0.1'
-
-
-def _GetDefaultDestDir():
- home = os.environ.get('HOME', '')
- homeman = os.path.join(home, 'man', 'man1')
- if home and os.path.exists(homeman):
- return homeman
- else:
- return os.environ.get('TMPDIR', '/tmp')
-
-FLAGS = gflags.FLAGS
-gflags.DEFINE_string('dest_dir', _GetDefaultDestDir(),
- 'Directory to write resulting manpage to.'
- ' Specify \'-\' for stdout')
-gflags.DEFINE_string('help_flag', '--help',
- 'Option to pass to target program in to get help')
-gflags.DEFINE_integer('v', 0, 'verbosity level to use for output')
-
-
-_MIN_VALID_USAGE_MSG = 9 # if fewer lines than this, help is suspect
-
-
-class Logging:
- """A super-simple logging class"""
- def error(self, msg): print >>sys.stderr, "ERROR: ", msg
- def warn(self, msg): print >>sys.stderr, "WARNING: ", msg
- def info(self, msg): print msg
- def debug(self, msg): self.vlog(1, msg)
- def vlog(self, level, msg):
- if FLAGS.v >= level: print msg
-logging = Logging()
-class App:
- def usage(self, shorthelp=0):
- print >>sys.stderr, __doc__
- print >>sys.stderr, "flags:"
- print >>sys.stderr, str(FLAGS)
- def run(self):
- main(sys.argv)
-app = App()
-
-
-def GetRealPath(filename):
- """Given an executable filename, find in the PATH or find absolute path.
- Args:
- filename An executable filename (string)
- Returns:
- Absolute version of filename.
- None if filename could not be found locally, absolutely, or in PATH
- """
- if os.path.isabs(filename): # already absolute
- return filename
-
- if filename.startswith('./') or filename.startswith('../'): # relative
- return os.path.abspath(filename)
-
- path = os.getenv('PATH', '')
- for directory in path.split(':'):
- tryname = os.path.join(directory, filename)
- if os.path.exists(tryname):
- if not os.path.isabs(directory): # relative directory
- return os.path.abspath(tryname)
- return tryname
- if os.path.exists(filename):
- return os.path.abspath(filename)
- return None # could not determine
-
-class Flag(object):
- """The information about a single flag."""
-
- def __init__(self, flag_desc, help):
- """Create the flag object.
- Args:
- flag_desc The command line forms this could take. (string)
- help The help text (string)
- """
- self.desc = flag_desc # the command line forms
- self.help = help # the help text
- self.default = '' # default value
- self.tips = '' # parsing/syntax tips
-
-
-class ProgramInfo(object):
- """All the information gleaned from running a program with --help."""
-
- # Match a module block start, for python scripts --help
- # "goopy.logging:"
- module_py_re = re.compile(r'(\S.+):$')
- # match the start of a flag listing
- # " -v,--verbosity: Logging verbosity"
- flag_py_re = re.compile(r'\s+(-\S+):\s+(.*)$')
- # " (default: '0')"
- flag_default_py_re = re.compile(r'\s+\(default:\s+\'(.*)\'\)$')
- # " (an integer)"
- flag_tips_py_re = re.compile(r'\s+\((.*)\)$')
-
- # Match a module block start, for c++ programs --help
- # "google/base/commandlineflags":
- module_c_re = re.compile(r'\s+Flags from (\S.+):$')
- # match the start of a flag listing
- # " -v,--verbosity: Logging verbosity"
- flag_c_re = re.compile(r'\s+(-\S+)\s+(.*)$')
-
- # Match a module block start, for java programs --help
- # "com.google.common.flags"
- module_java_re = re.compile(r'\s+Flags for (\S.+):$')
- # match the start of a flag listing
- # " -v,--verbosity: Logging verbosity"
- flag_java_re = re.compile(r'\s+(-\S+)\s+(.*)$')
-
- def __init__(self, executable):
- """Create object with executable.
- Args:
- executable Program to execute (string)
- """
- self.long_name = executable
- self.name = os.path.basename(executable) # name
- # Get name without extension (PAR files)
- (self.short_name, self.ext) = os.path.splitext(self.name)
- self.executable = GetRealPath(executable) # name of the program
- self.output = [] # output from the program. List of lines.
- self.desc = [] # top level description. List of lines
- self.modules = {} # { section_name(string), [ flags ] }
- self.module_list = [] # list of module names in their original order
- self.date = time.localtime(time.time()) # default date info
-
- def Run(self):
- """Run it and collect output.
-
- Returns:
- 1 (true) If everything went well.
- 0 (false) If there were problems.
- """
- if not self.executable:
- logging.error('Could not locate "%s"' % self.long_name)
- return 0
-
- finfo = os.stat(self.executable)
- self.date = time.localtime(finfo[stat.ST_MTIME])
-
- logging.info('Running: %s %s </dev/null 2>&1'
- % (self.executable, FLAGS.help_flag))
- # --help output is often routed to stderr, so we combine with stdout.
- # Re-direct stdin to /dev/null to encourage programs that
- # don't understand --help to exit.
- (child_stdin, child_stdout_and_stderr) = os.popen4(
- [self.executable, FLAGS.help_flag])
- child_stdin.close() # '</dev/null'
- self.output = child_stdout_and_stderr.readlines()
- child_stdout_and_stderr.close()
- if len(self.output) < _MIN_VALID_USAGE_MSG:
- logging.error('Error: "%s %s" returned only %d lines: %s'
- % (self.name, FLAGS.help_flag,
- len(self.output), self.output))
- return 0
- return 1
-
- def Parse(self):
- """Parse program output."""
- (start_line, lang) = self.ParseDesc()
- if start_line < 0:
- return
- if 'python' == lang:
- self.ParsePythonFlags(start_line)
- elif 'c' == lang:
- self.ParseCFlags(start_line)
- elif 'java' == lang:
- self.ParseJavaFlags(start_line)
-
- def ParseDesc(self, start_line=0):
- """Parse the initial description.
-
- This could be Python or C++.
-
- Returns:
- (start_line, lang_type)
- start_line Line to start parsing flags on (int)
- lang_type Either 'python' or 'c'
- (-1, '') if the flags start could not be found
- """
- exec_mod_start = self.executable + ':'
-
- after_blank = 0
- start_line = 0 # ignore the passed-in arg for now (?)
- for start_line in range(start_line, len(self.output)): # collect top description
- line = self.output[start_line].rstrip()
- # Python flags start with 'flags:\n'
- if ('flags:' == line
- and len(self.output) > start_line+1
- and '' == self.output[start_line+1].rstrip()):
- start_line += 2
- logging.debug('Flags start (python): %s' % line)
- return (start_line, 'python')
- # SWIG flags just have the module name followed by colon.
- if exec_mod_start == line:
- logging.debug('Flags start (swig): %s' % line)
- return (start_line, 'python')
- # C++ flags begin after a blank line and with a constant string
- if after_blank and line.startswith(' Flags from '):
- logging.debug('Flags start (c): %s' % line)
- return (start_line, 'c')
- # java flags begin with a constant string
- if line == 'where flags are':
- logging.debug('Flags start (java): %s' % line)
- start_line += 2 # skip "Standard flags:"
- return (start_line, 'java')
-
- logging.debug('Desc: %s' % line)
- self.desc.append(line)
- after_blank = (line == '')
- else:
- logging.warn('Never found the start of the flags section for "%s"!'
- % self.long_name)
- return (-1, '')
-
- def ParsePythonFlags(self, start_line=0):
- """Parse python/swig style flags."""
- modname = None # name of current module
- modlist = []
- flag = None
- for line_num in range(start_line, len(self.output)): # collect flags
- line = self.output[line_num].rstrip()
- if not line: # blank
- continue
-
- mobj = self.module_py_re.match(line)
- if mobj: # start of a new module
- modname = mobj.group(1)
- logging.debug('Module: %s' % line)
- if flag:
- modlist.append(flag)
- self.module_list.append(modname)
- self.modules.setdefault(modname, [])
- modlist = self.modules[modname]
- flag = None
- continue
-
- mobj = self.flag_py_re.match(line)
- if mobj: # start of a new flag
- if flag:
- modlist.append(flag)
- logging.debug('Flag: %s' % line)
- flag = Flag(mobj.group(1), mobj.group(2))
- continue
-
- if not flag: # continuation of a flag
- logging.error('Flag info, but no current flag "%s"' % line)
- mobj = self.flag_default_py_re.match(line)
- if mobj: # (default: '...')
- flag.default = mobj.group(1)
- logging.debug('Fdef: %s' % line)
- continue
- mobj = self.flag_tips_py_re.match(line)
- if mobj: # (tips)
- flag.tips = mobj.group(1)
- logging.debug('Ftip: %s' % line)
- continue
- if flag and flag.help:
- flag.help += line # multiflags tack on an extra line
- else:
- logging.info('Extra: %s' % line)
- if flag:
- modlist.append(flag)
-
- def ParseCFlags(self, start_line=0):
- """Parse C style flags."""
- modname = None # name of current module
- modlist = []
- flag = None
- for line_num in range(start_line, len(self.output)): # collect flags
- line = self.output[line_num].rstrip()
- if not line: # blank lines terminate flags
- if flag: # save last flag
- modlist.append(flag)
- flag = None
- continue
-
- mobj = self.module_c_re.match(line)
- if mobj: # start of a new module
- modname = mobj.group(1)
- logging.debug('Module: %s' % line)
- if flag:
- modlist.append(flag)
- self.module_list.append(modname)
- self.modules.setdefault(modname, [])
- modlist = self.modules[modname]
- flag = None
- continue
-
- mobj = self.flag_c_re.match(line)
- if mobj: # start of a new flag
- if flag: # save last flag
- modlist.append(flag)
- logging.debug('Flag: %s' % line)
- flag = Flag(mobj.group(1), mobj.group(2))
- continue
-
- # append to flag help. type and default are part of the main text
- if flag:
- flag.help += ' ' + line.strip()
- else:
- logging.info('Extra: %s' % line)
- if flag:
- modlist.append(flag)
-
- def ParseJavaFlags(self, start_line=0):
- """Parse Java style flags (com.google.common.flags)."""
- # The java flags prints starts with a "Standard flags" "module"
- # that doesn't follow the standard module syntax.
- modname = 'Standard flags' # name of current module
- self.module_list.append(modname)
- self.modules.setdefault(modname, [])
- modlist = self.modules[modname]
- flag = None
-
- for line_num in range(start_line, len(self.output)): # collect flags
- line = self.output[line_num].rstrip()
- logging.vlog(2, 'Line: "%s"' % line)
- if not line: # blank lines terminate module
- if flag: # save last flag
- modlist.append(flag)
- flag = None
- continue
-
- mobj = self.module_java_re.match(line)
- if mobj: # start of a new module
- modname = mobj.group(1)
- logging.debug('Module: %s' % line)
- if flag:
- modlist.append(flag)
- self.module_list.append(modname)
- self.modules.setdefault(modname, [])
- modlist = self.modules[modname]
- flag = None
- continue
-
- mobj = self.flag_java_re.match(line)
- if mobj: # start of a new flag
- if flag: # save last flag
- modlist.append(flag)
- logging.debug('Flag: %s' % line)
- flag = Flag(mobj.group(1), mobj.group(2))
- continue
-
- # append to flag help. type and default are part of the main text
- if flag:
- flag.help += ' ' + line.strip()
- else:
- logging.info('Extra: %s' % line)
- if flag:
- modlist.append(flag)
-
- def Filter(self):
- """Filter parsed data to create derived fields."""
- if not self.desc:
- self.short_desc = ''
- return
-
- for i in range(len(self.desc)): # replace full path with name
- if self.desc[i].find(self.executable) >= 0:
- self.desc[i] = self.desc[i].replace(self.executable, self.name)
-
- self.short_desc = self.desc[0]
- word_list = self.short_desc.split(' ')
- all_names = [ self.name, self.short_name, ]
- # Since the short_desc is always listed right after the name,
- # trim it from the short_desc
- while word_list and (word_list[0] in all_names
- or word_list[0].lower() in all_names):
- del word_list[0]
- self.short_desc = '' # signal need to reconstruct
- if not self.short_desc and word_list:
- self.short_desc = ' '.join(word_list)
-
-
-class GenerateDoc(object):
- """Base class to output flags information."""
-
- def __init__(self, proginfo, directory='.'):
- """Create base object.
- Args:
- proginfo A ProgramInfo object
- directory Directory to write output into
- """
- self.info = proginfo
- self.dirname = directory
-
- def Output(self):
- """Output all sections of the page."""
- self.Open()
- self.Header()
- self.Body()
- self.Footer()
-
- def Open(self): raise NotImplementedError # define in subclass
- def Header(self): raise NotImplementedError # define in subclass
- def Body(self): raise NotImplementedError # define in subclass
- def Footer(self): raise NotImplementedError # define in subclass
-
-
-class GenerateMan(GenerateDoc):
- """Output a man page."""
-
- def __init__(self, proginfo, directory='.'):
- """Create base object.
- Args:
- proginfo A ProgramInfo object
- directory Directory to write output into
- """
- GenerateDoc.__init__(self, proginfo, directory)
-
- def Open(self):
- if self.dirname == '-':
- logging.info('Writing to stdout')
- self.fp = sys.stdout
- else:
- self.file_path = '%s.1' % os.path.join(self.dirname, self.info.name)
- logging.info('Writing: %s' % self.file_path)
- self.fp = open(self.file_path, 'w')
-
- def Header(self):
- self.fp.write(
- '.\\" DO NOT MODIFY THIS FILE! It was generated by gflags2man %s\n'
- % _VERSION)
- self.fp.write(
- '.TH %s "1" "%s" "%s" "User Commands"\n'
- % (self.info.name, time.strftime('%x', self.info.date), self.info.name))
- self.fp.write(
- '.SH NAME\n%s \\- %s\n' % (self.info.name, self.info.short_desc))
- self.fp.write(
- '.SH SYNOPSIS\n.B %s\n[\\fIFLAGS\\fR]...\n' % self.info.name)
-
- def Body(self):
- self.fp.write(
- '.SH DESCRIPTION\n.\\" Add any additional description here\n.PP\n')
- for ln in self.info.desc:
- self.fp.write('%s\n' % ln)
- self.fp.write(
- '.SH OPTIONS\n')
- # This shows flags in the original order
- for modname in self.info.module_list:
- if modname.find(self.info.executable) >= 0:
- mod = modname.replace(self.info.executable, self.info.name)
- else:
- mod = modname
- self.fp.write('\n.P\n.I %s\n' % mod)
- for flag in self.info.modules[modname]:
- help_string = flag.help
- if flag.default or flag.tips:
- help_string += '\n.br\n'
- if flag.default:
- help_string += ' (default: \'%s\')' % flag.default
- if flag.tips:
- help_string += ' (%s)' % flag.tips
- self.fp.write(
- '.TP\n%s\n%s\n' % (flag.desc, help_string))
-
- def Footer(self):
- self.fp.write(
- '.SH COPYRIGHT\nCopyright \(co %s Google.\n'
- % time.strftime('%Y', self.info.date))
- self.fp.write('Gflags2man created this page from "%s %s" output.\n'
- % (self.info.name, FLAGS.help_flag))
- self.fp.write('\nGflags2man was written by Dan Christian. '
- ' Note that the date on this'
- ' page is the modification date of %s.\n' % self.info.name)
-
-
-def main(argv):
- argv = FLAGS(argv) # handles help as well
- if len(argv) <= 1:
- app.usage(shorthelp=1)
- return 1
-
- for arg in argv[1:]:
- prog = ProgramInfo(arg)
- if not prog.Run():
- continue
- prog.Parse()
- prog.Filter()
- doc = GenerateMan(prog, FLAGS.dest_dir)
- doc.Output()
- return 0
-
-if __name__ == '__main__':
- app.run()

Powered by Google App Engine
This is Rietveld 408576698