#!/bin/bash - #=============================================================================== # # FILE: createPythonProject.sh # # USAGE: ./createPythonProject.sh # # DESCRIPTION: Create a new Python project # # VERSION: 1.9 # REQUIREMENTS: --- # BUGS: --- # NOTES: This script creates a pyproject.toml file in addition to the # setup.cfg file. However, the pyproject.toml file could completely # replace setup.cfg. But if you use legacy tools or need # specific configurations that are not supported in pyproject.toml, # you may still need setup.cfg. That's why this file is also created. # The setup.py file is no longer created because it is marked as deprecated. # # There is also a program written in C with the same name that can also be used # to create a new Python project: # # https://github.com/niftycode/createPythonProject # # AUTHOR: @niftycode # ORGANIZATION: # CREATED: December 10th, 2021 # REVISION: February 26th, 2025 #=============================================================================== set -o nounset # Treat unset variables as an error echo "Enter a project name:" read name mkdir $name cd $name # Create the subfolders 'docs' and 'tests' mkdir docs mkdir tests # Create __init__.py file in the 'tests' folder cd tests touch __init__.py cd .. # Create setup.py file (deprecated) # cat > setup.py << EOF # import setuptools # setuptools.setup() # EOF # Create setup.cfg file cat > setup.cfg << EOF [metadata] name = version = author = author_email = url = description = long_description = file: README.md long_description_content_type = text/markdown license = MIT license_file = LICENSE requires_python = >=3.12 classifiers = License :: OSI Approved :: MIT License Operating System :: OS Independent Programming Language :: Python :: 3 Programming Language :: Python :: 3.12 Programming Language :: Python :: 3.13 Programming Language :: Python :: Implementation :: CPython EOF # Create pyproject.toml file cat > pyproject.toml << EOF [build-system] requires = ["setuptools>=70.0"] build-backend = "setuptools.build_meta" EOF # Create requirements.txt file cat > requirements.txt << EOF setuptools wheel build flake8 flake8-import-order black mypy pytest pytest-cov EOF # Create .flake8 file cat > .flake8 << EOF [flake8] extend-ignore = E203, W503 max-line-length = 120 exclude = .git, __pycache__, docs/source/conf.py, build, dist max-complexity = 10 EOF # Create empty Changelog and Contributing files touch Changelog.md touch CONTRIBUTING.md # Create Readme file cat > README.md << EOF # $name EOF # Create .gitignore file cat > .gitignore << EOF ############################# #### Configuration Files #### ############################# .DS_Store .vscode .idea .fleet ############################# ### Build Files & Folders ### ############################# dist/ build/ wheels/ *.egg-info/ __pycache__/ ############################# ### venv & Code Coverage #### ############################# .venv/ .coverage /htmlcov ############################# ############ uv ############# ############################# .python-version uv.lock ############################# ########### Misc ############ ############################# .mypy_cache .pytest_cache EOF # Create subfolder with the name of the project and # create __init__.py and main.py file echo read -p "Should the project directory be named 'src'? (Y/n)" dir_name dir_name=${dir_name:-Y} if [ $dir_name = "Y" ] then mkdir src echo "[+] src created" cd src else mkdir $name echo "[+] $name created" cd $name fi touch __init__.py month=$(date "+%B") day=$(date "+%d") year=$(date "+%Y") # Create main.py file cat > main.py << EOF #!/usr/bin/env python3 """ Description goes here... Version: 1.0 Python 3.12+ Date created: $month $day, $year Date modified: - """ import logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger() def main() -> None: pass if __name__ == '__main__': main() EOF cd .. # Create mypy.ini file echo read -p "Do you need a mypy.ini file? (Y/n)" mypy mypy=${mypy:-Y} if [ $mypy = "Y" ] then touch mypy.ini echo "[+] Created mypy.ini file!" else echo "[-] mypy.ini will not be created" cd .. fi if test -f "mypy.ini"; then echo "[mypy]" >> mypy.ini echo "disable_error_code = import-untyped" >> mypy.ini echo "ignore_missing_imports = True" >> mypy.ini fi # Create pytest.ini file echo read -p "Do you need a pytest.ini file? (Y/n)" pytest pytest=${pytest:-Y} if [ $pytest = "Y" ] then touch pytest.ini echo "[+] Created pytest.ini file!" else echo "[-] pytest.ini will not be created" fi if test -f "pytest.ini"; then echo "[pytest]" >> pytest.ini echo "norecursedirs = .* src *.egg dist build" >> pytest.ini echo "addopts = -rsxX -l --tb=short --strict-markers" >> pytest.ini fi # Create virtual environment echo read -p "Do you need a virtual environment? (Y/n)" venv venv=${venv:-Y} if [ $venv = "Y" ] then echo "[+] Creating a virtual environment..." python3 -m venv .venv echo echo "Done!" echo echo "Start the virtual environment using 'source .venv/bin/activate'." else echo "[-] A virtual environment will not be created!" fi echo echo "-----------------------" echo "All done! Exit program." echo "-----------------------" echo