Skip to content

Instantly share code, notes, and snippets.

@taikedz
Last active September 21, 2023 15:35
Show Gist options
  • Save taikedz/6291300d2aa26a4e62e96364b6f10d00 to your computer and use it in GitHub Desktop.
Save taikedz/6291300d2aa26a4e62e96364b6f10d00 to your computer and use it in GitHub Desktop.
Genericised setup.py file for re-use

Generic setup.py

Specifically aimed at re-use

""" 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 = "j.bloggs@example.com"
# 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