[cctbxbb] [git/cctbx] master: Generate libtbx.* wrappers from correct directory (ad736e2c8)
Billy Poon
BKPoon at lbl.gov
Fri Jun 1 13:32:24 PDT 2018
I don't think this is working on macOS. The configuration step is
generating error messages like,
Ignored: [Errno 2] No such file or directory: <command path>
In lines 1640-1643,
self.write_dispatcher(
source_file=libtbx.env.under_base(os.path.join('bin', ep.name)),
target_file=os.path.join('bin', 'libtbx.' + ep.name),
)
the source_file argument is always being constructed as
<base>/bin/<command> instead of using the directory from
self.get_setuptools_script_dir(). Should it be the bin_directory variable
instead (e.g. source_file=os.path.join(bin_directory, ep.name))?
As a side note, conda will put everything in bin because there is no
framework. For access to the window manager, you would call pythonw, which
points to a python inside a .app bundle.
--
Billy K. Poon
Research Scientist, Molecular Biophysics and Integrated Bioimaging
Lawrence Berkeley National Laboratory
1 Cyclotron Road, M/S 33R0345
Berkeley, CA 94720
Tel: (510) 486-5709
Fax: (510) 486-5909
Web: https://phenix-online.org
On Fri, Jun 1, 2018 at 3:15 AM CCTBX commit <
diamondlightsource.jenkins at gmail.com> wrote:
> Repository : ssh://g18-sc-serv-04.diamond.ac.uk/cctbx
> On branch : master
>
> ------------------------------
>
>
> commit ad736e2c8e65407615a7e6604b0544687ed8058c
> Author: Markus Gerstel <markus.gerstel at diamond.ac.uk>
> Date: Thu May 31 08:27:09 2018 +0100
>
> Generate libtbx.* wrappers from correct directory
>
> Python console scripts don't necessarily land in base/bin, specifically
> on MacOS this is not the case. Use setuptools etc. to find the actual
> Python console script location and use that directory instead. Fixes
> #177
>
> Add a function to regenerate all Python console scripts which can be
> called from an installer to relocate paths.
>
>
> ------------------------------
>
>
> ad736e2c8e65407615a7e6604b0544687ed8058c
> libtbx/env_config.py | 74 +++++++++++++++++++++++++-----
> libtbx/fastentrypoints.py | 112
> ++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 176 insertions(+), 10 deletions(-)
>
> diff --git a/libtbx/env_config.py b/libtbx/env_config.py
> index de5fc72dd..25daa2cb3 100644
> --- a/libtbx/env_config.py
> +++ b/libtbx/env_config.py
> @@ -1562,23 +1562,77 @@ selfx:
> source_file=source_file,
> target_file=module_name+"."+command)
>
> + def get_setuptools_script_dir():
> + '''
> + Find the location of python entry point console_scripts, ie. things
> like
> + 'pip', 'pytest', ...
> + This is different from simple /base/bin, eg. on MacOS.
> +
> +
> https://stackoverflow.com/questions/25066084/get-entry-point-script-file-location-in-setuputils-package
> + '''
> + from setuptools import Distribution
> + from setuptools.command.install import install
> + class OnlyGetScriptPath(install):
> + def run(self):
> + # does not call install.run() by design
> + self.distribution.install_scripts = self.install_scripts
> + dist = Distribution({'cmdclass': {'install': OnlyGetScriptPath}})
> + dist.dry_run = True # not sure if necessary, but to be safe
> + dist.parse_config_files()
> + command = dist.get_command_obj('install')
> + command.ensure_finalized()
> + command.run()
> + return dist.install_scripts
> +
> + def regenerate_entry_point_console_scripts(self, verbose=True):
> + '''
> + Creates all console_scripts entry point scripts from scratch and
> overwrites existing ones.
> + This is intended to be used by installers to relocate the entry point
> script paths.
> + '''
> + try:
> + import distutils.dist
> + import libtbx.fastentrypoints # monkeypatches setuptools
> + import pkg_resources
> + import setuptools.command.easy_install
> + except ImportError:
> + return
> +
> + # Prepare generic script generator
> + distribution = distutils.dist.Distribution({'name': 'setuptools'})
> + command = setuptools.command.easy_install.easy_install(distribution)
> + command.args = ['wheel'] # dummy argument
> + command.finalize_options()
> +
> + # Force regeneration of all known console_scripts
> + for pkg_resources_dist in pkg_resources.working_set:
> + console_scripts =
> pkg_resources_dist.get_entry_map().get('console_scripts')
> + if console_scripts:
> + if verbose:
> + print("Regenerating commands for %s: %s" % (
> + pkg_resources_dist,
> + list(console_scripts),
> + ))
> + command.install_wrapper_scripts(pkg_resources_dist)
> +
> def generate_entry_point_dispatchers(self):
> - # Write indirect dispatcher scripts for all console_scripts entry
> points
> - # that have existing dispatcher scripts in the base/bin directory, but
> - # add a 'libtbx.' prefix.
> - base_bin_directory = libtbx.env.under_base('bin')
> - if not os.path.isdir(base_bin_directory):
> + '''
> + Write indirect dispatcher scripts for all console_scripts entry points
> + that have existing dispatcher scripts in the base/bin directory, but
> + add a 'libtbx.' prefix.
> + '''
> + try:
> + import pkg_resources
> + bin_directory = get_setuptools_script_dir()
> + except ImportError:
> + return
> + if not os.path.isdir(bin_directory):
> return # do not create console_scripts dispatchers, only point to
> them
>
> - base_bin_dispatchers = set(os.listdir(base_bin_directory))
> + base_bin_dispatchers = set(os.listdir(bin_directory))
> existing_dispatchers = filter(lambda f: f.startswith('libtbx.'),
> self.bin_path.listdir())
> existing_dispatchers = set(map(lambda f: f[7:], existing_dispatchers))
> entry_point_candidates = base_bin_dispatchers - existing_dispatchers
>
> - try:
> - import pkg_resources
> - except ImportError:
> - return
> entry_points = pkg_resources.iter_entry_points('console_scripts')
> entry_points = filter(lambda ep: ep.name in entry_point_candidates,
> entry_points)
> for ep in entry_points:
> diff --git a/libtbx/fastentrypoints.py b/libtbx/fastentrypoints.py
> new file mode 100644
> index 000000000..9707f74a3
> --- /dev/null
> +++ b/libtbx/fastentrypoints.py
> @@ -0,0 +1,112 @@
> +# noqa: D300,D400
> +# Copyright (c) 2016, Aaron Christianson
> +# All rights reserved.
> +#
> +# Redistribution and use in source and binary forms, with or without
> +# modification, are permitted provided that the following conditions are
> +# met:
> +#
> +# 1. Redistributions of source code must retain the above copyright
> +# notice, this list of conditions and the following disclaimer.
> +#
> +# 2. 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.
> +#
> +# 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
> +# HOLDER 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.
> +'''
> +Monkey patch setuptools to write faster console_scripts with this format:
> +
> + import sys
> + from mymodule import entry_function
> + sys.exit(entry_function())
> +
> +This is better.
> +
> +(c) 2016, Aaron Christianson
> +http://github.com/ninjaaron/fast-entry_points
> +'''
> +from setuptools.command import easy_install
> +import re
> +TEMPLATE = '''\
> +# -*- coding: utf-8 -*-
> +# EASY-INSTALL-ENTRY-SCRIPT: '{3}','{4}','{5}'
> +__requires__ = '{3}'
> +import re
> +import sys
> +
> +from {0} import {1}
> +
> +if __name__ == '__main__':
> + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
> + sys.exit({2}())'''
> +
> +
> + at classmethod
> +def get_args(cls, dist, header=None): # noqa: D205,D400
> + """
> + Yield write_script() argument tuples for a distribution's
> + console_scripts and gui_scripts entry points.
> + """
> + if header is None:
> + # pylint: disable=E1101
> + header = cls.get_header()
> + spec = str(dist.as_requirement())
> + for type_ in 'console', 'gui':
> + group = type_ + '_scripts'
> + for name, ep in dist.get_entry_map(group).items():
> + # ensure_safe_name
> + if re.search(r'[\\/]', name):
> + raise ValueError("Path separators not allowed in script
> names")
> + script_text = TEMPLATE.format(
> + ep.module_name, ep.attrs[0], '.'.join(ep.attrs),
> + spec, group, name)
> + # pylint: disable=E1101
> + args = cls._get_script_args(type_, name, header, script_text)
> + for res in args:
> + yield res
> +
> +
> +# pylint: disable=E1101
> +easy_install.ScriptWriter.get_args = get_args
> +
> +
> +def main():
> + import os
> + import re
> + import shutil
> + import sys
> + dests = sys.argv[1:] or ['.']
> + filename = re.sub('\.pyc$', '.py', __file__)
> +
> + for dst in dests:
> + shutil.copy(filename, dst)
> + manifest_path = os.path.join(dst, 'MANIFEST.in')
> + setup_path = os.path.join(dst, 'setup.py')
> +
> + # Insert the include statement to MANIFEST.in if not present
> + with open(manifest_path, 'a+') as manifest:
> + manifest.seek(0)
> + manifest_content = manifest.read()
> + if 'include fastentrypoints.py' not in manifest_content:
> + manifest.write(('\n' if manifest_content else '') +
> + 'include fastentrypoints.py')
> +
> + # Insert the import statement to setup.py if not present
> + with open(setup_path, 'a+') as setup:
> + setup.seek(0)
> + setup_content = setup.read()
> + if 'import fastentrypoints' not in setup_content:
> + setup.seek(0)
> + setup.truncate()
> + setup.write('import fastentrypoints\n' + setup_content)
>
> ------------------------------
>
> To unsubscribe from the CCTBX-COMMIT list, click the following link:
> https://www.jiscmail.ac.uk/cgi-bin/webadmin?SUBED1=CCTBX-COMMIT&A=1
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://phenix-online.org/pipermail/cctbxbb/attachments/20180601/9dc0a032/attachment-0001.htm>
More information about the cctbxbb
mailing list