Add basic project files for an empty project

This commit is contained in:
Andrew Miner
2019-07-05 20:39:07 -06:00
parent 0a6ed88fef
commit cb5a4e42bf
10 changed files with 511 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
# This file allows you to configure how the build.sh script operates. It will
# be sourced immediately before running a build command. Feel free to leave it
# empty if you don't need any modifications.
+7
View File
@@ -0,0 +1,7 @@
*.egg-info/
*.swo
*.swp
.eggs/
.env
__pycache__
usr/
+20
View File
@@ -0,0 +1,20 @@
args==0.1.0
clint==0.5.1
coverage==4.5.3
future==0.17.1
importlib-metadata==0.18
jedi==0.14.0
Mako==1.0.7
mamba==0.9.3
MarkupSafe==1.1.1
mock==3.0.5
parso==0.5.0
pluggy==0.12.0
pycodestyle==2.3.1
pydocstyle==2.1.1
pyflakes==1.6.0
python-language-server==0.17.0+1.gc185cf8
six==1.12.0
snowballstemmer==1.9.0
sure==1.4.7
zipp==0.5.1
+1
View File
@@ -0,0 +1 @@
3.6.8
Executable
+396
View File
@@ -0,0 +1,396 @@
#!/usr/bin/env bash
USAGE=$(cat <<-END
USAGE: $0 <command> <options>*
init: install all development dependencies
--no-auto-refresh: skip the step of refreshing this build.sh script from
the tip of master in the boom-pylib repository
--nuke: completely remove the ./usr directory before initializing
edit: launch vim with settings to use the projects version of python
lint: run various programs to catch programming & style errors
test: run automated tests. By default, all tests are run once, and then the
script exits. There are a number of options to change this default. Some
conflict with one another (e.g., --watch and --functional). Whichever is
declared last will take precedence.
Unit tests are those which run completely within the process space of
the test runner (i.e., no disk or network access).
Functional tests are those which require no 3rd-party software be
installed or servers set up, but which otherwise do anything else.
Integration tests have no limits on what they may require.
--all (optional) turn on all test types
--circle-ci: (optional) only run tests which can pass in CircleCI.
Implies --no-integration.
--format: (optional) either "progress" or "documentation"
--messy: (optional) leave scratch directories behind in ./tmp
--watch: (optional) watch all the source files and repeat the tests
when things change. Implies --no-functional and --no-integration.
--(no-)functional: (optional) turn on/off functional tests
--(no-)unit: (optional) turn on/off unit tests
--(no-)integration: (optional) turn on/off integration tests
--none: (optional) turn off all test types
clean: remove temporary or one-off data from the ./tmp directory
python: start a Python REPL console which is sure to use the correct
version of Python pre-initialized with all the correct versions of
this packages dependencies
publish: publish this package as an official release on GemFury. This should
only be performed on the master branch, and only after a change has been
merged which updates the package version.
refresh: refresh this build script and its related helper files. This will
download the latest version from the boom-pylib repo and replace the
files in your current repo.
upgrade: upgrade any Python dependencies which have new versions available
END
)
AUTO_REFRESH="YES"
BUILD_CONFIG=".build_cfg.sh"
CIRCLE_CI="NO"
COMMAND="help"
CONFIRM="NO"
ENV_FILE=".env"
FORMAT="progress"
LINT_INCLUDE="src"
LINT_EXCLUDE="--exclude=.ropeproject"
MESSY="NO"
NUKE="NO"
PYTHON=$(which python)
PYTHON_VERSION="3.6"
TEST_FILE=".pylib.testing"
TEST_FUNCTIONAL="YES"
TEST_INTEGRATION="YES"
TEST_RUN=1
TEST_UNIT="YES"
VIRTUAL_ENV="./usr"
WATCH="NO"
[[ "$USER" == "" ]] && USER=$(whoami)
VIRTUAL_BIN="$VIRTUAL_ENV/bin"
# Helper Functions #####################################################################################################
function build-native-component {
# do nothing. Packages may override this function if they have a native component to build.
return 0
}
function build-python-env {
PYTHON_ENV="MESSY=$MESSY USER=$USER"
}
function check-python-version {
if ! $PYTHON --version | grep -q $PYTHON_VERSION; then
echo "Please update PYTHON in .env to refer to a Python $PYTHON_VERSION executable."
exit 1
fi
return 0
}
function die {
printf "$*\n"
echo
exit 1
}
function execute-functional-tests {
if [[ "$TEST_FUNCTIONAL" == "YES" ]]; then
printf "\nRunning functional tests...\n"
eval $PYTHON_ENV $VIRTUAL_BIN/mamba run src --format=$FORMAT -t functional
return $?
fi
return 0
}
function execute-integration-tests {
if [[ "$TEST_INTEGRATION" == "YES" ]]; then
printf "\nRunning integration tests...\n"
eval $PYTHON_ENV $VIRTUAL_BIN/mamba run src --format=$FORMAT -t integration
return $?
fi
return 0
}
function execute-test-run {
echo "Starting test run $TEST_RUN at $(date):"
echo "unit: $TEST_UNIT, functional: $TEST_FUNCTIONAL, integration: $TEST_INTEGRATION"
build-python-env
build-native-component \
&& execute-unit-tests \
&& execute-functional-tests \
&& execute-integration-tests \
|| return 1
return 0
}
function execute-unit-tests {
if [[ "$TEST_UNIT" == "YES" ]]; then
printf "\nRunning unit tests...\n"
eval $PYTHON_ENV $VIRTUAL_BIN/mamba run src --format=$FORMAT -t unit
return $?
fi
return 0
}
function init-custom {
# do nothing. repos with custom initialization can override this function
return 0
}
function on-unknown-argument {
die "Unknown argument: $1"
}
function usage {
die "$*\nTry \"$0 help\" for details"
}
function watch-source-files {
fswatch -o -r src -e '.*' -i '\.cpp$' -i '\.h$' -i '\.py$' -m poll_monitor
}
function write-build-config {
[[ -e "$BUILD_CONFIG" ]] && rm "$BUILD_CONFIG"
echo "# This file allows you to configure how the build.sh script operates. It will" >> $BUILD_CONFIG
echo "# be sourced immediately before running a build command. Feel free to leave it" >> $BUILD_CONFIG
echo "# empty if you don't need any modifications." >> $BUILD_CONFIG
}
function write-env-file {
[[ -e "$ENV_FILE" ]] && rm "$ENV_FILE"
echo '# The location of a `python` executable for Python v3.6' >> $ENV_FILE
echo "PYTHON=$PYTHON" >> $ENV_FILE
echo '# The authentication token used for uploading to GemFury' >> $ENV_FILE
echo "GEMFURY_TOKEN=$GEMFURY_TOKEN" >> $ENV_FILE
}
# Local Commands #######################################################################################################
function command-build {
build-native-component
}
function command-clean {
if [[ "$CONFIRM" == "YES" ]]; then
rm -rf ./tmp
else
echo "Removing ./tmp... (skipped)"
echo ""
fi
[[ "$CONFIRM" == "YES" ]] || printf "This was a dry run. To actually delete files, add: --confirm\n\n"
}
function command-edit {
source $VIRTUAL_BIN/activate
export VIRTUAL_ENV
$EDITOR
}
function command-help {
echo "$USAGE" | more
echo ""
exit
}
function command-init {
if [[ "$AUTO_REFRESH" == "YES" ]]; then
command-refresh-build || exit 1
fi
check-python-version || exit 1
[[ "$NUKE" == "YES" && -d $VIRTUAL_ENV ]] && rm -rf $VIRTUAL_ENV
$PYTHON -m venv --copies $VIRTUAL_ENV
./usr/bin/pip install --upgrade pip
unset PYTHONPATH
export PYTHONPATH
$VIRTUAL_BIN/pip install -r requirements.txt
init-custom
$VIRTUAL_BIN/pip freeze | grep -v '^-e' > .pip.lock
}
function command-lint {
$VIRTUAL_BIN/pycodestyle $LINT_INCLUDE $LINT_EXCLUDE
(( RESULT = $RESULT + $? ))
$VIRTUAL_BIN/pydocstyle $LINT_INCLUDE
(( RESULT = $RESULT + $? ))
$VIRTUAL_BIN/pyflakes $LINT_INCLUDE
(( RESULT = $RESULT + $? ))
return $RESULT
}
function command-publish {
CURRENT_BRANCH=$(git branch | grep '^\*' | awk '{print $2}')
if [[ "$CURRENT_BRANCH" == "master" ]]; then
[[ "$GEMFURY_TOKEN" == "" ]] && die "Please make sure GEMFURY_TOKEN is defined in $ENV_FILE"
$VIRTUAL_BIN/python setup.py sdist
PACKAGE="dist/$(ls dist | head -n1)"
PUBLISHED_VERSION=$( \
curl -s https://$GEMFURY_TOKEN@pypi.fury.io/boomtechnology/$PACKAGE \
| grep boom-pylib- \
| sed "s/.*$PACKAGE-\([0-9.].*\).tar.gz.*/\1/" \
| tail -n1
)
CURRENT_VERSION=$(cat setup.py | grep version= | sed 's/.*version="\(.*\)".*/\1/')
if [[ "$PUBLISHED_VERSION" != "$CURRENT_VERSION" ]]; then
curl -F package=@$PACKAGE https://$GEMFURY_TOKEN@push.fury.io/boomtechnology \
|| die "\nUploading package failed!"
else
echo "Version $CURRENT_VERSION has already been published, skipping publish..."
fi
rm -rf dist 2>/dev/null
else
echo "Not on master branch, skipping publish..."
fi
}
function command-python {
source $VIRTUAL_BIN/activate
eval $PYTHON_ENV $VIRTUAL_BIN/python
}
function command-refresh-build {
# Install the Git Hooks
pushd .git/hooks >/dev/null
ls ../../src/hooks | while read HOOK_FILE; do
ln -sf "../../src/hooks/$HOOK_FILE" .
done
popd >/dev/null
if cat .git/config | grep 'url =' | head -n1 | grep -q boom-pylib; then
# We're already in the boom-pylib repo.
return 0
fi
# Download the current version of boom-pylib
TMP_REPO=".boom-pylib"
rm -rf $TMP_REPO 2>/dev/null
git clone -q --depth 1 [email protected]:boomtechnology/boom-pylib.git $TMP_REPO
# Copy over the files we need, replacing existing copies
mkdir -p src
rm -rf src/hooks 2>/dev/null
cp $TMP_REPO/build.sh .build.sh.new
cp -R $TMP_REPO/src/hooks src/hooks
# Get rid of the boom-pylib repo
rm -rf $TMP_REPO 2>/dev/null
(sleep 1; mv .build.sh.new build.sh) &
}
function command-test {
RESULT=0
function do-watched-run {
rm -rf ./tmp 2>/dev/null
execute-test-run > $TEST_FILE.out 2>&1
RESULT=$?
clear
cat "$TEST_FILE.out"
rm "$TEST_FILE.out"
rm "$TEST_FILE"
printf "\nWaiting for changes...\n"
}
if [[ "$WATCH" == "YES" ]]; then
clear
execute-test-run
echo "Waiting for changes..."
rm $TEST_FILE 2> /dev/null
watch-source-files | while read FILE; do
if [[ ! -e $TEST_FILE ]]; then
touch $TEST_FILE
(( TEST_RUN = TEST_RUN + 1 ))
printf "\nChanges detected! Re-running tests...\n"
do-watched-run &
fi
done
else
execute-test-run
RESULT=$?
fi
[[ "$MESSY" == "NO" ]] && rm -rf ./tmp 2>/dev/null
return $RESULT
}
function command-upgrade-pip {
$VIRTUAL_BIN/pip install -r requirements.txt --upgrade
$VIRTUAL_BIN/pip freeze | grep -v '^-e' > .pip.lock
}
# Process Arguments ####################################################################################################
[[ -e $ENV_FILE ]] && source $ENV_FILE
[[ -e $BUILD_CONFIG ]] || write-build-config
source $BUILD_CONFIG
write-env-file
while [[ "$1" != "" ]]; do
case "$1" in
build) COMMAND="build";;
clean) COMMAND="clean";;
edit) COMMAND="edit";;
help|--help|-h|-?) COMMAND="help";;
init) COMMAND="init";;
lint) COMMAND="lint";;
python) COMMAND="python";;
publish) COMMAND="publish";;
refresh) COMMAND="refresh-build";;
test) COMMAND="test";;
upgrade) COMMAND="upgrade-pip";;
--all) TEST_UNIT="YES"; TEST_FUNCTIONAL="YES"; TEST_INTEGRATION="YES";;
--no-refresh) AUTO_REFRESH="NO";;
--circle-ci) CIRCLE_CI="YES"; TEST_INTEGRATION="NO";;
--confirm) CONFIRM="YES";;
--format) shift; FORMAT="$1";;
--functional) TEST_FUNCTIONAL="YES";;
--integration) TEST_INTEGRATION="YES";;
--messy) MESSY="YES";;
--no-functional) TEST_FUNCTIONAL="NO";;
--no-integration) TEST_INTEGRATION="NO";;
--no-unit) TEST_UNIT="NO";;
--none) TEST_UNIT="NO"; TEST_FUNCTIONAL="NO"; TEST_INTEGRATION="NO";;
--nuke) NUKE="YES";;
--unit) TEST_UNIT="YES";;
--watch) TEST_FUNCTIONAL="NO"; TEST_INTEGRATION="NO"; WATCH="YES";;
*) on-unknown-argument $1;;
esac
shift
done
# Script ###############################################################################################################
"command-$COMMAND"
+13
View File
@@ -0,0 +1,13 @@
--index-url https://[email protected]/boomtechnology/
--extra-index-url https://pypi.org/simple
Mako==1.0.7
mamba==0.9.3
pycodestyle==2.3.1
pydocstyle==2.1.1
pyflakes==1.6.0
sure==1.4.7
git+ssh://[email protected]/andrewminer/python-language-server#egg=python-language-server
-e .
+2
View File
@@ -0,0 +1,2 @@
[pycodestyle]
max-line-length = 120
+20
View File
@@ -0,0 +1,20 @@
"""Define the pycursesui package."""
# Taken from the following sample: https://github.com/pypa/sampleproject/blob/master/setup.py
import setuptools
setuptools.setup(
name="pycursesui",
version="0.0.1",
description="A python UI framework for command-line applications using curses",
author="Andrew Miner",
author_email="[email protected]",
packages=[
"pycurses",
],
package_dir={"": "src"},
install_requires=[
],
)
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env bash
if git branch | grep -q '^\* master'; then
echo ""
echo "ERROR: Please don't commit directly to master. Instead, create a working branch"
echo " and submit a pull request."
echo ""
exit 1
fi
MASTER_VERSION=$(git show master:setup.py | grep version= | sed 's/.*version="\(.*\)".*/\1/')
CURRENT_VERSION=$(cat setup.py | grep version= | sed 's/.*version="\(.*\)".*/\1/')
if [[ "$MASTER_VERSION" == "$CURRENT_VERSION" ]]; then
echo ""
echo "ERROR: It looks like you've forgotten to update the package version for your"
echo " changes. Please update setup.py with a new version number."
echo ""
exit 1
fi
echo "Checking for stray fit/fdescription..."
if egrep -rn 'with f(it|description)' src; then
echo ""
echo "ERROR: Please remove fit/fdescription from tests before committing."
echo ""
exit 1
fi
echo "Running linters..."
./build.sh lint || exit 1
echo "Running tests..."
./build.sh test || exit 1
echo "All pre-commit checks passed!"
EXIT_CODE=0
if git status | grep -q "not staged"; then
echo ""
echo "WARNING: It looks like you forgot to add some of your changes! If this was"
echo " unintentional, use 'git add -A' to add your missing changes. Otherwise,"
echo " use 'git commit -n' to ignore this check."
echo ""
EXIT_CODE=1
fi
exit $EXIT_CODE
+3
View File
@@ -0,0 +1,3 @@
"""A python UI framework for command-line applications using curses."""
__all__ = []