diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..e2e55be7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "script/include"] + path = script/include + url = git@github.com:dod-ccpo/scriptz.git + branch = master diff --git a/.travis.yml b/.travis.yml index 486de5cc..02dab0db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,19 @@ sudo: required language: python python: "3.6" services: docker +git: + submodules: false env: global: - TESTER_IMAGE_NAME=atst-tester - PROD_IMAGE_NAME=atst-prod +before_install: + # Use sed to replace the SSH URL with the public URL + - sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules + # Manually initialize submodules + - git submodule update --init --recursive + before_script: - docker login -u $ATAT_DOCKER_REGISTRY_USERNAME -p $ATAT_DOCKER_REGISTRY_PASSWORD $ATAT_DOCKER_REGISTRY_URL - docker build --tag "${TESTER_IMAGE_NAME}" . -f deploy/docker/tester/Dockerfile diff --git a/README.md b/README.md index d759de47..fbd0daf9 100644 --- a/README.md +++ b/README.md @@ -3,19 +3,54 @@ [![Build Status](https://travis-ci.org/dod-ccpo/atst.svg?branch=master)](https://travis-ci.org/dod-ccpo/atst) +## Description + +This is the main user-facing web application for the ATAT stack. All end-user +requests are handled by ATST, with it making backend calls to various +microservices when appropriate. + ## Installation +### Requirements +See the [scriptz](https://github.com/dod-ccpo/scriptz) repository for the shared +requirements and guidelines for all ATAT applications. +Additionally, ATST requires a redis instance for session management. Have redis +installed and running. By default, ATST will try to connect to a redis instance +running on localhost on its default port, 6379. + +### Cloning +This project contains git submodules. Here is an example clone command that will +automatically initialize and update those modules: + + git clone --recurse-submodules git@github.com:dod-ccpo/atst.git + +If you have an existing clone that does not yet contain the submodules, you can +set them up with the following command: + + git submodule update --init --recursive + +### Setup +This application uses Pipenv to manage Python dependencies and a virtual +environment. Instead of the classic `requirements.txt` file, pipenv uses a +Pipfile and Pipfile.lock, making it more similar to other modern package managers +like yarn or mix. + +To perform the installation, run the setup script: + script/setup -The setup script installs pipenv, which is what this application uses to manage its dependences and virtualenv. Instead of the classic `requirements.txt` file, pipenv uses a Pipfile and Pipfile.lock, making it more similar to other modern package managers like yarn or mix. +The setup script creates the virtual environment, and then calls script/bootstrap +to install all of the Python and Node dependencies. To enter the virtualenv manually (a la `source .venv/bin/activate`): pipenv shell -If you want to automatically load the virtual environment whenever you enter the project directory, take a look at [direnv](https://direnv.net/). An `.envrc` file is included in this repository. direnv will activate and deactivate virtualenvs for you when you enter and leave the directory. +If you want to automatically load the virtual environment whenever you enter the +project directory, take a look at [direnv](https://direnv.net/). An `.envrc` +file is included in this repository. direnv will activate and deactivate +virtualenvs for you when you enter and leave the directory. -Additionally, ATST requires a redis instance for session management. Have redis installed and running. By default, ATST will try to connect to a redis instance running on localhost on its default port, 6379. ## Running (development) @@ -25,7 +60,7 @@ To start the app locally in the foreground and watch for changes: ## Testing -To run all linting and tests: +To run lint, static analysis, and unit tests: script/test diff --git a/script/include b/script/include new file mode 160000 index 00000000..7417942f --- /dev/null +++ b/script/include @@ -0,0 +1 @@ +Subproject commit 7417942f1614d6a7ad94e94d1621dca9b422dec2 diff --git a/script/include/alpine_setup_functions.inc.sh b/script/include/alpine_setup_functions.inc.sh deleted file mode 100755 index 19d60985..00000000 --- a/script/include/alpine_setup_functions.inc.sh +++ /dev/null @@ -1,30 +0,0 @@ -# alpine_setup_functions: Functions used by the run_alpine_setup script - -update_system_packages() { - apk update - apk upgrade -} - -install_package() { - local package_name=${1} - - apk add ${1} - return $? -} - -add_group() { - local group_name="${1}" - local gid="${2}" - - addgroup -g "${gid}" -S "${group_name}" - return $? -} - -add_user() { - local username="${1}" - local primary_group="${2}" - local uid="${3}" - - adduser -u "${3}" -D -S -G "${primary_group}" "${username}" - return $? -} diff --git a/script/include/bootstrap_functions.inc.sh b/script/include/bootstrap_functions.inc.sh deleted file mode 100644 index 599fc207..00000000 --- a/script/include/bootstrap_functions.inc.sh +++ /dev/null @@ -1,13 +0,0 @@ -# bootstrap_functions.inc.sh: Functions used by the bootstrap script - -install_python_packages() { - local install_flags="${1}" - - pipenv install ${install_flags} - return $? -} - -install_node_packages() { - npm install - return $? -} diff --git a/script/include/global_header.inc.sh b/script/include/global_header.inc.sh deleted file mode 100755 index 45989ee1..00000000 --- a/script/include/global_header.inc.sh +++ /dev/null @@ -1,12 +0,0 @@ -# global_header.inc: Any basic things that should be executed at the -# beginning of any and every script - -# If any command fails, immediately exit the script -set -e - -# Ensure the working directory is the app root directory -cd "$(dirname "${0}")/.." - -# Source all function definition files - -source ./script/include/helper_functions.inc.sh diff --git a/script/include/helper_functions.inc.sh b/script/include/helper_functions.inc.sh deleted file mode 100644 index 84792652..00000000 --- a/script/include/helper_functions.inc.sh +++ /dev/null @@ -1,28 +0,0 @@ -# helper_functions.inc.sh: General helper functions - -# Check pip to see if the given package is installed -# (returns 0 if installed, 2 if not installed) -check_system_pip_for () { - local package_name="${1}" - - # Use 'pip list' to see if the requested package is already installed - pip list --format=columns --disable-pip-version-check | \ - grep -Fe "${package_name}" >/dev/null 2>&1 - return $? -} - -pip_install () { - local packages="${1}" - local flags="${2}" - - run_command "pip install ${flags} ${packages}" - return $? -} - -# Used whenever an environment sensitive command is being run -run_command () { - local cmd="${1}" - - pipenv run ${cmd} - return $? -} diff --git a/script/include/run_alpine_setup b/script/include/run_alpine_setup deleted file mode 100755 index 837f7e67..00000000 --- a/script/include/run_alpine_setup +++ /dev/null @@ -1,26 +0,0 @@ -# run_alpine_setup: Install basic system requirements for an app to run - -# Load alpine setup functions -source ./script/include/alpine_setup_functions.inc.sh - -## Set option defaults -# If GROUP information is incomplete, use the default one -if [ -z "${APP_GROUP+is_set}" ] || \ - [ -z "${APP_GID+is_set}" ]; then - APP_GROUP="atat" - APP_GID="8000" -fi - -# If USER information is incomplete, error out -if [ -z "${APP_USER+is_set}" ] || \ - [ -z "${APP_UID+is_set}" ]; then - echo "ERROR: Missing app user information! Received: ${APP_USER}:${APP_UID}" - exit 1 -fi - -## Main -update_system_packages -install_package "bash" -install_package "dumb-init" -add_group "${APP_GROUP}" "${APP_GID}" -add_user "${APP_USER}" "${APP_GROUP}" "${APP_UID}" diff --git a/script/include/run_bootstrap b/script/include/run_bootstrap deleted file mode 100755 index 9115b004..00000000 --- a/script/include/run_bootstrap +++ /dev/null @@ -1,23 +0,0 @@ -# run_bootstrap: Install application dependencies - -# Load bootstrap functions -source ./script/include/bootstrap_functions.inc.sh - -## Set option defaults -# If PIPENV_INSTALL_FLAGS is not set, give it the default value of "--dev" -if [ -z "${PIPENV_INSTALL_FLAGS+is_set}" ]; then - PIPENV_INSTALL_FLAGS="--dev" -fi - -## Main -if [ "${INSTALL_PYTHON_PACKAGES}" = "true" ]; then - install_python_packages "${PIPENV_INSTALL_FLAGS}" -fi - -if [ "${INSTALL_NODE_PACKAGES}" = "true" ]; then - install_node_packages -fi - -if [ -n "${COMPILE_SASS_CMD}" ]; then - run_command "${COMPILE_SASS_CMD}" -fi diff --git a/script/include/run_setup b/script/include/run_setup deleted file mode 100755 index 376802f8..00000000 --- a/script/include/run_setup +++ /dev/null @@ -1,42 +0,0 @@ -# setup: Set up application for the first time after cloning, or set it -# back to the initial first unused state. - -# Load setup functions -source ./script/include/setup_functions.inc.sh - -## Set option defaults -# If CREATE_VENV is not set, set it to "true" -if [ -z "${CREATE_VENV+is_set}" ]; then - CREATE_VENV="true" -fi - -# If INSTALL_SASS is not set, set it to "false" -if [ -z "${INSTALL_SASS+is_set}" ]; then - INSTALL_SASS="false" -fi - -# If PIP_VERSION is not set, set it to "10.*" -if [ -z "${PIP_VERSION+is_set}" ]; then - PIP_VERSION="10.*" -fi - -## Main -# Remove any existing node modules as part of initial app setup or reset -rm -rf ./node_modules - -if [ "${CREATE_VENV}" = "true" ]; then - # Ensure pipenv is installed - if ! pipenv --version >/dev/null 2>&1 ; then - echo "ERROR: pipenv is malfunctioning or not present" - exit 1 - fi - create_virtual_environment - pip_install "pip==${PIP_VERSION}" "--upgrade" -fi - -if [ "${INSTALL_SASS}" = "true" ]; then - install_sass -fi - -# Install application dependencies -./script/bootstrap diff --git a/script/include/run_test b/script/include/run_test deleted file mode 100755 index d5f6bc5f..00000000 --- a/script/include/run_test +++ /dev/null @@ -1,17 +0,0 @@ -# run_test: Execute code checkers and unit tests - -# Load test functions -source ./script/include/test_functions.inc.sh - -## Set option defaults -# If PYTHON_FILES is not set, give it the default value of "app.py" -if [ -z "${PYTHON_FILES+is_set}" ]; then - PYTHON_FILES="app.py" -fi - -## Main -if [ "${RUN_PYTHON_TESTS}" = "true" ]; then - run_python_lint "${PYTHON_FILES}" - run_python_static_analysis "${PYTHON_FILES}" - run_python_unit_tests "${PYTHON_FILES}" -fi diff --git a/script/include/setup_functions.inc.sh b/script/include/setup_functions.inc.sh deleted file mode 100644 index ef0ff935..00000000 --- a/script/include/setup_functions.inc.sh +++ /dev/null @@ -1,48 +0,0 @@ -# setup_functions.inc.sh: Functions used by the setup script - -install_pipenv() { - return_code=0 - - # Ensure we are not in a virtual env already - if [ -z "${VIRTUAL_ENV+is_set}" ]; then - if ! check_system_pip_for pipenv; then - # pipenv is not installed, so install it - echo "Installing pipenv..." - pip install pipenv - # Capture pip exit code - return_code="${?}" - fi - fi - - return "${return_code}" -} - -create_virtual_environment() { - default_python_version=3.6 - # Parse out the required Python version from the Pipfile - python_version=$(grep python_version ./Pipfile | cut -d '"' -f 2) - - # If we ended up with an empty string for the required Python version, - # specify the default version - if [ -z "${python_version}" ]; then - python_version="${default_python_version}" - fi - - # Create a new virtual environment for the app - # The environment will be in a directory called .venv off the app - # root directory - echo "Creating virtual environment using Python version ${python_version}..." - PIPENV_VENV_IN_PROJECT=true pipenv --python "${python_version}" - return $? -} - -install_sass() { - if ! type sass >/dev/null; then - if type gem >/dev/null; then - echo 'Installing a sass compiler (gem)...' - gem install sass - else - echo 'Could not install a sass compiler. Please install a version of sass.' - fi - fi -} diff --git a/script/include/test_functions.inc.sh b/script/include/test_functions.inc.sh deleted file mode 100644 index 622c0bfb..00000000 --- a/script/include/test_functions.inc.sh +++ /dev/null @@ -1,20 +0,0 @@ -# test_functions.inc.sh: Functions used by the run_test script - -run_python_lint() { - local python_files="${1}" - - run_command "pylint ${python_files}" - return $? -} - -run_python_static_analysis() { - local python_files="${1}" - - run_command "bandit -c ./.bandit_config -r ${python_files}" - return $? -} - -run_python_unit_tests() { - run_command "python -m pytest -s" - return $? -}