Source code for pymyinstall.setuphelper.setup_creation

# -*- coding: utf-8 -*-
"""
Functions to help creating a setup

.. versionadded:: 1.1


:githublink:`%|py|8`
"""
import os
import sys
from ..installhelper import run_cmd

_setup_py = """
# -*- coding: utf-8 -*-
import sys
import os
import warnings
from distutils.core import setup
from setuptools import find_packages

#########
# settings
#########


project_var_name = "__NAME__"
sversion = "__VERSION__"
subversion = "__SUBVERSION__"
versionPython = "%s.%s" % (sys.version_info.major, sys.version_info.minor)
path = "Lib/site-packages/" + project_var_name
readme = 'README.rst'


KEYWORDS = project_var_name
DESCRIPTION = '''__DESCRIPTION___'''
CLASSIFIERS = [
    'Programming Language :: Python :: 3',
    'Intended Audience :: Developers',
    'Topic :: Scientific/Engineering',
    'Topic :: Education',
    'License :: OSI Approved :: MIT License',
    'Development Status :: 5 - Production/Stable'
]


#######
# data
#######

packages = find_packages('src', exclude='src')
package_dir = {k: "src/" + k.replace(".", "/") for k in packages}
package_data = {
    project_var_name : ["*.pyd", "*.dll", "*.so" ],
}


def verbose():
    print("---------------------------------")
    print("package_dir =", package_dir)
    print("packages    =", packages)
    print("package_data=", package_data)
    print("current     =", os.path.abspath(os.getcwd()))
    print("---------------------------------")


setup(
    name=project_var_name,
    version='%s%s' % (sversion, subversion),
    author='__AUTHOR__',
    author_email='__EMAIL__',
    url="__URL__",
    download_url="__DURL__",
    description=DESCRIPTION,
    long_description=long_description,
    keywords=KEYWORDS,
    classifiers=CLASSIFIERS,
    packages=packages,
    package_dir=package_dir,
    package_data=package_data,
    install_requires=[]
)
"""

_readme_rst = '''
.. _l-README:

README / Changes
================

.. image:: https://travis-ci.org/sdpython/pymyinstall.svg?branch=master
    :target: https://travis-ci.org/sdpython/pymyinstall
    :alt: Build status

.. image:: https://badge.fury.io/py/pymyinstall.svg
    :target: http://badge.fury.io/py/pymyinstall

.. image:: http://img.shields.io/pypi/dm/pymyinstall.png
    :alt: PYPI Package
    :target: https://pypi.python.org/pypi/pymyinstall

.. image:: http://img.shields.io/github/issues/sdpython/pymyinstall.png
    :alt: GitHub Issues
    :target: https://github.com/sdpython/pymyinstall/issues

.. image:: https://img.shields.io/badge/license-MIT-blue.svg
    :alt: MIT License
    :target: http://opensource.org/licenses/MIT


**Links:**

* `GitHub/__NAME__ <__URL__>`_
* `documentation <__URL__>`_
* `Blog <http:/__NAME__/helpsphinx/blog/main_0000.html#ap-main-0>`_
'''

if sys.version_info[0] == 2:
    from codecs import open


[docs]def create_empty_folder_setup(fold, name, author=None, description=None, url=None, durl=None, version="0.1", subversion="0"): """ Creates a quick empty shell for a new project. :param fold: location :param name: name of the project :param author: author :param description: description :param url: url for the documentation :param durl: url to download it :param version: version :param subversion: third part of the version number :return: list of created files :githublink:`%|py|134` """ src = os.path.join(fold, "src") mod = os.path.join(src, name) create = [fold, src, mod] for f in create: if not os.path.exists(f): os.makedirs(f) replace = dict(__AUTHOR__=author, __DESCRIPTION__=description, __URL__=url, __DURL__=durl, __VERSION__=version, __SUBVERSION__=subversion, __NAME__=name) def adapt(content): for k, v in replace.items(): if v is not None: content = content.replace(k, v) return content readme = os.path.join(fold, "README.rst") with open(readme, "w", encoding="utf-8") as f: f.write(adapt(_readme_rst)) setup = os.path.join(fold, "setup.py") with open(setup, "w", encoding="utf-8") as f: f.write(adapt(_setup_py)) writ = [setup, readme] if sys.platform.startswith("win"): bat = os.path.join(fold, "wheel.bat") with open(bat, "w") as f: f.write("{0} setup.py bdist_wheel".format(sys.executable)) writ.append(bat) return writ
_setup_py_existing = """ # -*- coding: utf-8 -*- import sys import os import warnings from distutils.core import setup from setuptools import find_packages DESCRIPTION = '''__DESCRIPTION__''' packages = find_packages('src', exclude='src') package_dir = {k: 'src/' + k.replace(".", "/") for k in packages} package_data = { __PACKDATA__ } setup(name="__FOLDER__", version="__VERSION__", description=DESCRIPTION, long_description=DESCRIPTION, packages=packages, package_dir=package_dir, package_data=package_data ) """
[docs]def create_folder_setup(fold, wheel=True, output_path=None, fLOG=None, version=None, description=None): """ Creates a quick setup for an existing or installed projects. :param fold: folder or module (must be imported first) :param wheel: run the setup to build the wheel :param output_path: copies everything here it not None :param version: to overwrite version :param description: to overwrite description :return: list of created files .. exref:: :title: Create a setup from installed packages :lid: ex-torch-setup This packages :epkg:`pandas` into a wheel from the installed sources. Location of the sources can be specified too. :: from pymyinstall.setuphelper import create_folder_setup create_folder_setup('pandas', fLOG=print, output_path='.') :githublink:`%|py|221` """ if fLOG: fLOG("[create_folder_setup] process '{0}'".format(fold)) if not os.path.exists(fold): if fold not in sys.modules: raise ValueError("Unable to find module '{0}'".format(fold)) mod = sys.modules[fold] version = mod.__version__ if hasattr( mod, '__version__') else mod.VERSION info = dict(__VERSION__=version, __DESCRIPTION__=mod.__doc__, __FOLDER__=fold) fold = os.path.dirname(mod.__file__) else: info = dict() # Module name name = os.path.split(fold)[-1] if fLOG: fLOG("[create_folder_setup] name='{0}'".format(name)) fLOG("[create_folder_setup] fold='{0}'".format(fold)) if output_path is not None: # Copies everything. if fLOG: fLOG("[create_folder_setup] copy to '{0}'".format(output_path)) from pyquickhelper.filehelper import synchronize_folder dest = os.path.join(output_path, 'src', name) if not os.path.exists(dest): os.makedirs(dest) # , filter_copy=lambda name: '__pycache__' not in name) synchronize_folder(fold, dest) fold = dest fold_ = output_path else: raise ValueError("output_path must be specified") if len(info) == 0 and version is None: # Import the module. if name in sys.modules: del sys.modules[name] f = os.path.normpath(os.path.abspath(fold)) f_ = os.path.normpath(os.path.join(fold, '..')) if fold_ not in sys.path: sys.path.insert(0, f_) rem = True else: rem = False mod = __import__(name) if rem: ind = sys.path.index(f_) del sys.path[ind] del sys.modules[name] info = dict(__VERSION__=mod.__version__, __DESCRIPTION__=description or mod.__doc__, __FOLDER__=name) else: info = dict(__VERSION__=version, __DESCRIPTION__=description, __FOLDER__=name) # Package data from pyquickhelper.filehelper import explore_folder _, files = explore_folder(fold, fullname=False) pack = {} for f in files: ff = os.path.split(f)[0] f = os.path.relpath(f, fold) if '__pycache__' in f: continue ext = os.path.splitext(f)[-1] if ext in {'.py', '.pyc'}: # , '.pyd'}: continue f, n = os.path.split(f) f = f .replace("\\", "/").replace("/", ".") if f not in pack: pack[f] = [] init = os.path.join(ff, "__init__.py") while not os.path.exists(init): if fLOG: fLOG("[create_folder_setup] add '{0}'".format(init)) with open(init, "w") as fi: fi.write('# added for additional files') ff = os.path.split(ff)[0] init = os.path.join(ff, "__init__.py") pack[f].append(n) if fLOG: fLOG("[create_folder_setup] add '{0}' in '{1}'".format(n, f)) rows = [" '{2}{3}{0}': {1},".format( k, v, name, '.' if k else '') for k, v in pack.items()] info['__PACKDATA__'] = "\n".join(rows) # Writes setup.py script = _setup_py_existing for k, v in info.items(): if v is not None: script = script.replace(k, v) setup = os.path.join(fold_, 'setup.py') if fLOG: fLOG("[create_folder_setup] write='{0}'".format(setup)) with open(setup, "w") as f: f.write(script) if wheel: cmd = '"{0}" -u setup.py bdist_wheel'.format( sys.executable.replace("w.exe", ".exe")) out, err = run_cmd(cmd, wait=True, fLOG=fLOG, change_path=fold_) if fLOG: fLOG('[create_folder_setup] OUT --------------\n' + out) fLOG('[create_folder_setup] ERR --------------\n' + err) return [setup] else: return [setup]