Specifically aimed at re-use
Last active
September 21, 2023 15:35
-
-
Save taikedz/6291300d2aa26a4e62e96364b6f10d00 to your computer and use it in GitHub Desktop.
Genericised setup.py file for re-use
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" Required file for using this repository as a PIP dependency. | |
This is not a development enviornment setup script, it should NOT be run manually. | |
-- To use this file in your library | |
Add it to the root of your repository | |
Edit the configuration vars | |
Done. | |
-- For someone to depend on your library | |
Indicate to add this to their requirements.txt a line like: | |
git+https://gitsite.example.com/my-space/my-lib@$TAG | |
replacing "$TAG" with a tag/commit they want to pin, or branch they want to track | |
""" | |
# For help adjusting this file, see | |
# https://setuptools.pypa.io/en/latest/userguide/quickstart.html | |
from glob import glob | |
import os | |
import setuptools | |
import sys | |
import re | |
# =================== | |
# Configuration of setup | |
# Track the version in a file in your lib | |
# Ensure a `MYLIB.version` module is present, and has a "get_version()" | |
# method returning the version string. | |
# (leave the `as MYLIB`) in place | |
import <my_lib> as MYLIB | |
REPO_URL="https://gitsite.example.com/my-space/my-lib" | |
BUG_TRACKER_URL="{}/issues".format(REPO_URL) | |
# Short description | |
DESCRIPTION = "My Awesome Library" | |
# Short-name for library (used in paths, etc) | |
LIB_NAME = "my-lib" | |
# Ownership details ... | |
OWNER = "My Organisation" | |
AUTHOR_NAME = "Jay Bloggs" | |
AUTHOR_EMAIL = "[email protected]" | |
# Any executable script files | |
SCRIPT_FILES = ['bin/my-lib-command.sh'] | |
# Files to include during installation | |
CONFIG_GLOBS = ["config/*.yaml", "config/*.json"] | |
# Packages (top-level dirs with a __init__.py file inside them) | |
# to exclude during installation | |
EXCLUDE_GLOBS = ["internal_tests"] | |
# note - in python2 , platform is "linux2" :-( | |
# Add a "requirements.{os_string}.txt" to add support for it | |
# e.g. "requirements.linux.txt" | |
SUPPORTED_OS_LIST = ("win32", "darwin", "linux") | |
# Optional - if trying to support two levels of python | |
#MIN_PYTHON_VERSION = "2.7" if sys.version_info.major == 2 else "3.6" | |
MIN_PYTHON_VERSION = "3.6" | |
# Load this file's content as the long-description | |
DESCRIPTION_FILE = "ABOUT.md" | |
LONG_DESCRIPTION_TYPE = "text/markdown" | |
# See classifiers on PyPi | |
# https://pypi.org/classifiers/ | |
CLASSIFIERS = [ | |
"Programming Language :: Python :: 3", | |
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", | |
# List multiple OS supports individually | |
"Operating System :: POSIX :: Linux", | |
"Operating System :: Microsoft :: Windows", | |
"Operating System :: MacOS :: MacOS X", | |
] | |
# / END OF CONFIG AREA | |
# ---------------------------------------------------- | |
# =========== | |
# Helpers | |
with open(DESCRIPTION_FILE) as fh: | |
LONG_DESCRIPTION = fh.read() | |
def uncomment_file(path:str): | |
""" Read a file, ignore all blank or comment lines, return each line as an individual list item | |
""" | |
with open(path) as fh: | |
return [L.strip() for L in fh.readlines() if not re.match("^\\s*(#.*)?$", L.strip())] | |
def get_all_files(globs): | |
all_files = [] | |
for pat in globs: | |
all_files.extend(glob(pat)) | |
return all_files | |
# ============ | |
# Load requirements | |
# Sometimes, the lib requires a specific platform to _work_ | |
if sys.platform not in SUPPORTED_OS_LIST: | |
print("""WARNING - platform {} cannot install some dependencies. | |
You can still develop with {}, | |
but your project will not run locally on this machine. | |
""".format(sys.platform, LIB_NAME)) | |
# Anywhere this package installed, use content from requirements.txt always ... | |
reqtxt_list = [] | |
if os.path.exists("requirements.txt"): | |
reqtxt_list.extend(uncomment_file("requirements.txt")) | |
# Add special support for some OSes - e.g. deployment environments, dev environments ... | |
for os_string in SUPPORTED_OS_LIST: | |
if sys.platform == os_string: | |
req_file = "requirements.{}.txt".format(os_string) | |
if os.path.isfile(req_file): | |
print("--- Selecting {} dependencies ---".format(os_string)) | |
extras = uncomment_file(req_file) | |
reqtxt_list.extend(extras) | |
# ============== | |
# Active setup routine | |
setuptools.setup( | |
name=LIB_NAME, | |
version=MYLIB.version.get_version(), | |
author=AUTHOR_NAME, | |
author_email=AUTHOR_EMAIL, | |
description=DESCRIPTION, | |
long_description=LONG_DESCRIPTION, | |
long_description_content_type=LONG_DESCRIPTION_TYPE, | |
url=REPO_URL, | |
scripts=get_all_files(SCRIPT_FILES), | |
project_urls={ | |
"Bug Tracker": BUG_TRACKER_URL, | |
}, | |
classifiers=CLASSIFIERS, | |
package_dir={LIB_NAME: LIB_NAME}, | |
python_requires=">=".format(MIN_PYTHON_VERSION), | |
install_requires=reqtxt_list, | |
packages=setuptools.find_packages(exclude=get_all_files(EXCLUDE_GLOBS)), | |
# Installs to f"{sys.prefix}/{dirname}" where 'dirname' is the first memebr of each tuple | |
data_files=[('{}/config'.format(LIB_NAME), get_all_files(CONFIG_GLOBS))] | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment