github.com/grumpyhome/grumpy@v0.3.1-0.20201208125205-7b775405bdf1/grumpy-tools-src/grumpy_tools/cli.py (about)

     1  # -*- coding: utf-8 -*-
     2  
     3  """Console script for grumpy_tools."""
     4  import os
     5  import sys
     6  from StringIO import StringIO
     7  from pkg_resources import resource_filename, Requirement, DistributionNotFound
     8  import logging
     9  logger = logging.getLogger(__package__)
    10  
    11  import click
    12  import click_log
    13  from click_log.core import ColorFormatter
    14  from click_default_group import DefaultGroup
    15  
    16  ColorFormatter.colors['info'] = {'fg': 'green'}
    17  click_log.basic_config(logger)
    18  logger.propagate = True
    19  
    20  from . import grumpc, grumprun, pydeps
    21  
    22  
    23  @click.group('grumpy', cls=DefaultGroup, default='run', default_if_no_args=True)
    24  @click_log.simple_verbosity_option(logger, default='WARNING')
    25  def main(args=None):
    26      """
    27      Console script for grumpy_tools.
    28  
    29      The default command `grumpy run` will ran if no other selected.
    30      It mimics the CPython options, when possible and applicable.
    31      Please take a look on `grumpy run --help` for its implemented options.
    32  
    33      Example: all the following lines outputs Hello on the STDOUT\n
    34          $ python -c 'print("Hello")'\n
    35          $ grumpy -c 'print("Hello")'\n
    36          $ grumpy run -c 'print("Hello")'
    37      """
    38  
    39  
    40  @main.command('transpile')
    41  @click.argument('script', type=click.File('rb'))
    42  @click.option('-m', '-modname', '--modname', default='__main__', help='Python module name')
    43  @click.option('--pep3147', is_flag=True, help='Put the transpiled outputs on a __pycache__ folder')
    44  def transpile(script=None, modname=None, pep3147=False):
    45      """
    46      Translates the python SCRIPT file to Go, then prints to stdout
    47      """
    48      _ensure_gopath(raises=False)
    49  
    50      output = grumpc.main(stream=script, modname=modname, pep3147=pep3147)['gocode']
    51      click.echo(output)
    52      sys.exit(0)
    53  
    54  
    55  @main.command('run')
    56  @click.argument('file', required=False, type=click.File('rb'))
    57  @click.option('-c', '--cmd', help='Program passed in as string')
    58  @click.option('-m', '-modname', '--modname', help='Run run library module as a script')
    59  @click.option('--go-action', default='run', type=click.Choice(['run', 'build', 'debug']),
    60                help='Action of the Go compilation')
    61  @click.option('--keep-main', is_flag=True,
    62                help='Do not clear the temporary folder containing the transpilation result of main script')
    63  def run(file=None, cmd=None, modname=None, keep_main=False, pep3147=True, go_action='run'):
    64      _ensure_gopath()
    65  
    66      if modname:
    67          stream = None
    68      elif file:
    69          stream = StringIO(file.read())
    70      elif cmd:
    71          stream = StringIO(cmd)
    72      else:   # Read from STDIN
    73          stdin = click.get_text_stream('stdin')
    74          if stdin.isatty():  # Interactive terminal -> REPL
    75              click.echo('Python REPL is not (yet) available.'
    76                         '\nTry to pipe in your code, or pass --help for more options',
    77                         err=True)
    78              sys.exit(1)
    79          else:               # Piped terminal
    80              stream = StringIO(stdin.read())
    81  
    82      if stream is not None:
    83          stream.seek(0)
    84          stream.name = '__main__.py'
    85  
    86      result = grumprun.main(stream=stream, modname=modname, pep3147=pep3147,
    87                             clean_tempfolder=(not keep_main), go_action=go_action)
    88      sys.exit(result)
    89  
    90  
    91  @main.command('depends')
    92  @click.argument('script')
    93  @click.option('-m', '-modname', '--modname', default='__main__', help='Python module name')
    94  def depends(script=None, modname=None):
    95      """
    96      Discover with modules are needed to run the 'script' provided
    97      """
    98      _ensure_gopath()
    99  
   100      package_dir = os.path.dirname(os.path.abspath(script))
   101      output = pydeps.main(script=script, modname=modname, package_dir=package_dir)
   102      for dep in output:
   103          click.echo(dep)
   104      sys.exit(0)
   105  
   106  
   107  def _ensure_gopath(raises=True):
   108      environ_gopath = os.environ.get('GOPATH', '')
   109  
   110      try:
   111          runtime_gopath = resource_filename(
   112              Requirement.parse('grumpy-runtime'),
   113              'grumpy_runtime/data/gopath',
   114          )
   115      except DistributionNotFound:
   116          runtime_gopath = None
   117  
   118      if runtime_gopath and runtime_gopath not in environ_gopath:
   119          gopaths = environ_gopath.split(':') + [runtime_gopath]
   120          new_gopath = os.pathsep.join([p for p in gopaths if p])  # Filter empty ones
   121          if new_gopath:
   122              os.environ['GOPATH'] = new_gopath
   123  
   124      if raises and not runtime_gopath and not environ_gopath:
   125          raise click.ClickException("Could not found the Grumpy Runtime 'data/gopath' resource.\n"
   126                                     "Is 'grumpy-runtime' package installed?")
   127      logger.info("GOPATH: %s", os.environ.get("GOPATH"))
   128  
   129  
   130  if __name__ == "__main__":
   131      import sys
   132      sys.exit(main())