# SlapOS component for pygolang.
# pygolang.nexedi.com

[buildout]
extends =
    ../../component/cython/buildout.cfg

parts =
    pygolang
    gpython


# pygolang installed from released egg from pypi
[pygolang]
recipe  = zc.recipe.egg:custom
egg     = pygolang
setup-eggs =
    ${cython:egg}
    setuptools-dso
    gevent

# gpython program
[gpython]
recipe  = zc.recipe.egg:scripts
eggs    = ${pygolang:egg}
scripts = gpython
# convenience for gpython users
exe     = ${buildout:bin-directory}/gpython

# python-interpreter provides python interpreter with all specified eggs.
# eggs default to pygolang, but can be overwritten or changed in inherited section.
# if eggs are changes, they must still have pygolang.
[python-interpreter]
recipe = zc.recipe.egg:scripts
eggs   = ${pygolang:egg}
interpreter = python
# interpreter code that buildout generates cannot process `-m pytest --<pytest-option>`
# -> use pymain from gpython to workaround that.
initialization =
  # tail to pymain
  from gpython import pymain
  pymain(sys.argv)
  sys.exit(0)
# don't install scripts from listed eggs (avoid conflict with other sections
# that use zc.recipe.egg with eggs overlapping with ${:eggs} - ex neoppod)
# (we cannot use zc.recipe.egg:eggs because interpreter does not work there)
# NOTE with scripts=ø interpreter is not handled, so we use `scripts=python` as
# a workaround.
scripts = ${:interpreter}


# pyprog provides macro recipe to build python programs.
#
# Contrary to zc.recipe.egg:scripts it generates scripts that are run with
# sys.executable being correctly set. In particular it is valid to spawn
# sys.executable from inside the program and assume that all specified eggs are
# still accessible and can be imported.
#
# Usage example:
#
#   [myprog]
#   <= pyprog
#   exe = ${buildout:bin-directory}/myprog
#   entry = my.py.mod:main
#   eggs = ...
[pyprog]
recipe = slapos.recipe.build
initialization =
depends =
_name = ${:_buildout_section_name_}
init =
  name   = options['_name']  # options['_buildout_section_name_'] does not work
  exe    = options['exe']
  entry  = options['entry']
  eggs   = options['eggs']
  pyinit = options['initialization']

  options['depends'] += '$${.%s.pyprog:recipe}' % name

  # mod:func -> 'from mod import func; sys.exit(func())'
  mod, func = entry.split(':')
  entry_run = 'from %s import %s; sys.exit(%s())' % (mod, func, func)

  # indent pyinit with '  '
  __pyinit = '\n'.join(['  '+_ for _ in pyinit.splitlines()])

  self.buildout.parse("""
  # .X.pyprog is python program to start and run entry
  # it uses .X.pyexe as underlying python interpreter
  [.%(name)s.pyprog]
  recipe  = slapos.recipe.template
  exe     = %(exe)s
  output= $${:exe}
  inline =
    #!$${.%(name)s.pyexe:exe}
    import sys
  %(__pyinit)s
    %(entry_run)s

  # .X.pyexe is python interpreter used by .X.pyprog
  [.%(name)s.pyexe]
  <= python-interpreter
  eggs += %(eggs)s
  interpreter = $${:_buildout_section_name_}
  exe = $${buildout:bin-directory}/$${:interpreter}
  """ % locals())


[versions]
pygolang = 0.1
