Last active
August 28, 2018 12:38
-
-
Save Tabea-K/18832ee43336481e9c8f48a041ab02c6 to your computer and use it in GitHub Desktop.
Bash script to generate the directory structure and files needed for the generation of an empty python project template. The first argument supplied is used as the main name of the python project, the second as the name of the main python code file. A directory "tests" is generated for unit tests, which also includes an example test case.
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
#!/bin/bash | |
# This creates a more or less empty template for a python package | |
# containing unit tests | |
# Author: Tabea Kischka, 2018-07-02 | |
# Version 2.0, last update: 2018-08-28 | |
########################################################################################################### | |
# get options | |
########################################################################################################### | |
usage(){ | |
echo -ne "Run like this:\ncreate_empty_python_package_template.sh -p PACKAGENAME -m NAMEOFMAINSCRIPT -a AUTHORNAME\n" | |
echo -ne "-p\tPACKAGENAME\t\tThe name you choose for your python package\n" | |
echo -ne "-m\tNAMEOFMAINSCRIPT\t\tThe name you choose for the main script of your package\n" | |
echo -ne "-a\tAUTHOR\t\tYour name (will be included in the README file)\n" | |
echo -ne -ne "\n\nIn the end the directory structure will look like this:\n\n | |
. | |
├── README.rst | |
├── package_name | |
│ ├── __init__.py | |
│ ├── main_script_name.py | |
│ └── tests | |
│ ├── test_package_name.py | |
│ └── testdata.txt | |
└── setup.py\n\n" | |
exit 1 | |
} | |
while getopts "p:m:a:h" opt | |
do | |
case "${opt}" | |
in | |
p) PACKAGENAME="$OPTARG";; | |
m) MAINSCRIPTNAME="$OPTARG";; | |
a) AUTHOR="$OPTARG";; | |
h) usage;; | |
*) usage;; | |
\?) echo "Invalid option: -$OPTARG" >&2; exit 1;; | |
:) echo "Option -$OPTARG requires an argument." >&2; exit 1;; | |
esac | |
done | |
if [ -z "${PACKAGENAME}" ] || [ -z "${MAINSCRIPTNAME}" ] || [ -z "${AUTHOR}" ]; then | |
usage | |
fi | |
if [ -d "$PACKAGENAME" ] | |
then | |
echo "ERROR: $PACKAGENAME already exists. Please choose another name." | |
exit 1 | |
fi | |
########################################################################################################### | |
# start generating files... | |
########################################################################################################### | |
D=`date` | |
echo " | |
------------------------ | |
Will now generate directory structure and files for the python project $PACKAGENAME | |
under the folder $PWD | |
------------------------ | |
" | |
########################################################################################################### | |
# make main dir | |
########################################################################################################### | |
mkdir "$PACKAGENAME" | |
cd "$PACKAGENAME" | |
########################################################################################################### | |
# create readme files | |
########################################################################################################### | |
echo "Python package $PACKAGENAME created on $D by $AUTHOR" > README.rst | |
########################################################################################################### | |
# generate file setup.py | |
########################################################################################################### | |
echo "from setuptools import setup | |
def readme(): | |
with open('README.rst') as f: | |
return f.read() | |
# if you want to include more test data within your package, you have to list it inside the list package_data in setup! | |
setup(name='${PACKAGENAME}', | |
version='0.1', | |
description='A super cool package that was generated with the python project template generator.', | |
long_description=readme(), | |
author='${AUTHOR}', | |
author_email='', | |
license='', | |
packages=['$PACKAGENAME'], | |
test_suite='nose.collector', | |
tests_require=['nose'], | |
package_data={'${PACKAGENAME}': ['README.rst', 'tests/testdata.txt']}, | |
include_package_data=True, | |
entry_points={ | |
'console_scripts': ['${PACKAGENAME}=${PACKAGENAME}.${MAINSCRIPTNAME}:main'], | |
}, | |
zip_safe=False)" > setup.py | |
########################################################################################################### | |
# make python script dir | |
########################################################################################################### | |
mkdir "$PACKAGENAME" | |
cd "$PACKAGENAME" | |
########################################################################################################### | |
# make init file | |
########################################################################################################### | |
echo "from $MAINSCRIPTNAME import *" > __init__.py | |
echo -ne "#!/usr/bin/env python | |
import sys | |
import os | |
import argparse | |
import logging | |
__version__ = '1.0' | |
script_description = 'Description of the $MAINSCRIPTNAME script' | |
def hello_world(): | |
return('hello world') | |
def print_infile_name(infile_fh): | |
return(infile_fh.name) | |
def main(): | |
# parse arguments | |
parser = argparse.ArgumentParser(description=script_description) | |
parser.add_argument('infile', | |
help='input file', | |
nargs='?', | |
type=argparse.FileType('r'), | |
default=sys.stdin) | |
parser.add_argument('-d', | |
help='run in debug mode, print lots of information', | |
action='store_const', | |
dest='loglevel', | |
const=logging.DEBUG, | |
default=logging.WARNING) | |
parser.add_argument('-d', | |
help='run in debug mode, print lots of information', | |
action='store_const', | |
dest='loglevel', | |
const=logging.DEBUG, | |
default=logging.WARNING) | |
parser.add_argument('-v', | |
help='run in verbose mode, print some more information', | |
action='store_const', | |
dest='loglevel', | |
const=logging.INFO, | |
default=logging.WARNING) | |
args = parser.parse_args() | |
# set up logging module | |
logging.basicConfig(format='[%(asctime)s - %(levelname)s] %(message)s', | |
datefmt='%Y-%m-%d %H:%M:%S', | |
level=args.loglevel) | |
logger = logging.getLogger(__name__) | |
logger.debug('logging set up!') | |
logger.debug('All arguments: %s' % args) | |
logger.info('Script starts!') | |
hello_world() | |
print_infile_name(args.infile) | |
" > "${MAINSCRIPTNAME}.py" | |
########################################################################################################### | |
# make test files | |
########################################################################################################### | |
mkdir tests | |
cd tests | |
echo "#!/usr/bin/env python | |
import unittest | |
import $MAINSCRIPTNAME | |
class MyTestCase(unittest.TestCase): | |
def test_hello_world(self): | |
text = $MAINSCRIPTNAME.hello_world() | |
self.assertEqual(text, 'hello world') | |
# Add more tests here | |
"> "test_${PACKAGENAME}.py" | |
echo -ne "This could be your test data\n" > testdata.txt | |
########################################################################################################### | |
# Last steps... | |
########################################################################################################### | |
# go back to the initial directory | |
cd ../.. | |
echo " | |
Finished! | |
You now have an empty template for your $PACKAGENAME python project! | |
You can add unit tests to the file $PACKAGENAME/tests/test_${PACKAGENAME}.py and run the | |
unit tests using this command: | |
cd $PWD/$PACKAGENAME && \ | |
python -m unittest discover -v -s tests | |
" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment