BuildScripts/xcode/build_phases/api_generator.sh

351 lines
9.1 KiB
Bash
Executable File

#!/bin/sh
# Description:
# Generates API models & methods.
#
# Parameters:
# $1 - api generator version.
# $2 - path to generated code directory
#
# Required environment variables:
# SRCROOT - path to project folder.
#
# Optional environment variables:
# OUTPUT_PATH - path to Generated folder.
# API_SPEC_DIR - path to api specification folder
# VERBOSE - print debug messages
# API_NAME - project name that will be used by generator (example: OUTPUT_PATH/API_NAME/Classes )
#
# Examples of usage:
# . api_generator.sh 1.4.0-beta1
# . api_generator.sh 1.4.0-beta1 ${TARGET_NAME}/Generated
#
readonly EXIT_SUCCESS=0
readonly EXIT_FAILURE=1
readonly TRUE=1
readonly FALSE=0
readonly LOG_TAG="API-GENERATOR"
notice()
{
echo "${LOG_TAG}:NOTICE: ${1}" >&2
}
debug()
{
if [ ! -z "${VERBOSE}" ]; then
echo "${LOG_TAG}:DEBUG: ${1}" >&2
fi
}
exit_on_failure()
{
eval ${1}
local -r EXIT_CODE=$?
if [ ${EXIT_CODE} -ne 0 ]; then
echo "Recent command: \`${1}\` failed with code ${EXIT_CODE}"
exit ${EXIT_CODE}
fi
}
is_force_run()
{
if [ -z "${FORCE_RUN}" ]; then
echo ${FALSE}
return
fi
local -r STR_MODE=`tr "[:upper:]" "[:lower:]" <<< ${FORCE_RUN}`
if [ ${STR_MODE} == "yes" ] || [ ${STR_MODE} == "true" ] || [ ${STR_MODE} == "1" ]; then
echo ${TRUE}
else
echo ${FALSE}
fi
}
is_single_file()
{
if [ -z "${SINGLE_FILE}" ]; then
echo "true"
return
fi
local -r STR_MODE=`tr "[:upper:]" "[:lower:]" <<< ${SINGLE_FILE}`
if [ ${STR_MODE} == "no" ] || [ ${STR_MODE} == "false" ] || [ ${STR_MODE} == "0" ]; then
echo "false"
else
echo "true"
fi
}
get_api_spec_current_commit()
{
if [ -z "${API_SPEC_DIR}" ]; then
if [ ! -z "${1}" ]; then
echo `git -C ${1} rev-parse --verify HEAD`
else
echo `git rev-parse --verify HEAD`
fi
else
echo `git -C ${API_SPEC_DIR} rev-parse --verify HEAD`
fi
}
get_api_spec_status()
{
if [ -z "${API_SPEC_DIR}" ]; then
if [ ! -z "${1}" ]; then
echo `git -C ${1} status -s`
else
echo `git status -s`
fi
else
echo `git -C ${API_SPEC_DIR} status -s`
fi
}
is_api_spec_under_source_control()
{
local IS_UNDER_SOURCE_CONTROL_CHECK
if [ -z "${API_SPEC_DIR}" ]; then
if [ ! -z "${1}" ]; then
IS_UNDER_SOURCE_CONTROL_CHECK=`git -C ${1} rev-parse --is-inside-work-tree 2>/dev/null`
else
IS_UNDER_SOURCE_CONTROL_CHECK=`git rev-parse --is-inside-work-tree 2>/dev/null`
fi
else
IS_UNDER_SOURCE_CONTROL_CHECK=`git -C ${API_SPEC_DIR} rev-parse --is-inside-work-tree 2>/dev/null`
fi
if [ ${IS_UNDER_SOURCE_CONTROL_CHECK} = "true" ]; then
echo ${TRUE}
else
echo ${FALSE}
fi
}
is_api_spec_has_uncommited_changes()
{
if [ `is_api_spec_under_source_control` -eq ${TRUE} ]; then
local -r API_SPEC_STATUS=`get_api_spec_status`
if [ -z "${API_SPEC_STATUS}" ]; then
echo ${FALSE}
else
echo ${TRUE}
fi
else
echo ${FALSE}
fi
}
is_nothing_changed_since_last_check()
{
if [ `is_force_run` -eq ${TRUE} ]; then
notice "Force run detected. Skipping commits comparison."
echo ${TRUE}
fi
if [ -z "${COMMIT_FILE_PATH}" ]; then
if [ ! -z "${1}" ]; then
local -r COMMIT_FILE_PATH=${1}
else
debug "COMMIT_FILE_PATH should be defined or passed as first argument!"
echo ${FALSE}
fi
fi
if [ `is_api_spec_under_source_control` -eq ${TRUE} ]; then
local -r CURRENT_COMMIT=`get_api_spec_current_commit`
local -r LAST_CHECKED_COMMIT=`cat ${COMMIT_FILE_PATH} 2> /dev/null || echo ""`
if [ ${CURRENT_COMMIT} = "${LAST_CHECKED_COMMIT}" ]; then
if [ `is_api_spec_has_uncommited_changes` -eq ${TRUE} ]; then
notice "API spec has uncomitted changes."
echo ${FALSE}
else
echo ${TRUE}
fi
else
echo ${FALSE}
fi
else
echo ${FALSE}
fi
}
record_current_commit()
{
if [ `is_force_run` -eq ${TRUE} ]; then
notice "Force run detected. Commit won't be recorder."
exit ${EXIT_SUCCESS}
fi
if [ -z "${COMMIT_FILE_PATH}" ]; then
if [ ! -v "${1}" ]; then
local -r COMMIT_FILE_PATH=${1}
else
debug "COMMIT_FILE_PATH should be defined or passed as second argument!"
return ${EXIT_FAILURE}
fi
fi
local -r CURRENT_COMMIT=`get_api_spec_current_commit`
echo ${CURRENT_COMMIT} > ${COMMIT_FILE_PATH}
}
openapi_codegen()
{
if [ -z "${OPEN_API_SPEC_PATH}" ]; then
if [ ! -v "${1}" ]; then
local -r OPEN_API_SPEC_PATH=${1}
else
debug "OPEN_API_SPEC_PATH should be defined or passed as first argument!"
return ${EXIT_FAILURE}
fi
fi
if [ -z "${OUTPUT_PATH}" ]; then
if [ ! -v "${2}" ]; then
local -r OUTPUT_PATH=${2}
else
debug "OUTPUT_PATH should be defined or passed as second argument!"
return ${EXIT_FAILURE}
fi
fi
if [ -z "${VERSION}" ]; then
if [ ! -v "${3}" ]; then
local -r VERSION=${3}
else
debug "VERSION should be defined or passed as third argument!"
return ${EXIT_FAILURE}
fi
fi
if [ -z "${API_NAME}" ]; then
local -r API_NAME="${PROJECT_NAME}API"
fi
notice "OpenAPI spec generation for ${OPEN_API_SPEC_PATH}"
local -r CODEGEN_VERSION="3.0.34"
local -r CODEGEN_FILE_NAME="swagger-codegen-cli-${CODEGEN_VERSION}.jar"
local -r CODEGEN_DOWNLOAD_URL="https://repo1.maven.org/maven2/io/swagger/codegen/v3/swagger-codegen-cli/${CODEGEN_VERSION}/${CODEGEN_FILE_NAME}"
. build-scripts/xcode/aux_scripts/download_file.sh ${CODEGEN_FILE_NAME} ${CODEGEN_DOWNLOAD_URL}
local -r TINETWORKING_CODEGEN_FILE_NAME="codegen-${VERSION}.jar"
local -r DOWNLOAD_URL="https://maven.dev.touchin.ru/ru/touchin/codegen/${VERSION}/${TINETWORKING_CODEGEN_FILE_NAME}"
. build-scripts/xcode/aux_scripts/download_file.sh ${TINETWORKING_CODEGEN_FILE_NAME} ${DOWNLOAD_URL}
rm -rf ${OUTPUT_PATH}/${API_NAME} # remove previously generated API (if exists)
local -r OPENAPI_COMMAND="java -cp "Downloads/${CODEGEN_FILE_NAME}:Downloads/${TINETWORKING_CODEGEN_FILE_NAME}" io.swagger.codegen.v3.cli.SwaggerCodegen generate -l TINetworking -i ${OPEN_API_SPEC_PATH} -o ${OUTPUT_PATH} --additional-properties projectName=${API_NAME}"
exit_on_failure "${OPENAPI_COMMAND}"
# flatten folders hierarchy
mv ${OUTPUT_PATH}/${API_NAME}/Classes/Swaggers/* ${OUTPUT_PATH}/${API_NAME}/
rm -rf ${OUTPUT_PATH}/${API_NAME}/Classes
}
api_generator_codegen()
{
if [ -z "${API_SPEC_DIR}" ]; then
if [ ! -v "${1}" ]; then
local -r API_SPEC_DIR=${1}
else
debug "API_SPEC_DIR should be defined or passed as first argument!"
return ${EXIT_FAILURE}
fi
fi
if [ -z "${OUTPUT_PATH}" ]; then
if [ ! -v "${2}" ]; then
local -r OUTPUT_PATH=${2}
else
debug "OUTPUT_PATH should be defined or passed as second argument!"
return ${EXIT_FAILURE}
fi
fi
if [ -z "${VERSION}" ]; then
if [ ! -v "${3}" ]; then
local -r VERSION=${3}
else
debug "VERSION should be defined or passed as third argument!"
return ${EXIT_FAILURE}
fi
fi
notice "api-generator spec generation for ${API_SPEC_DIR}/main.json"
local -r FILE_NAME="api-generator-${VERSION}.jar"
local -r DOWNLOAD_URL="https://maven.dev.touchin.ru/ru/touchin/api-generator/${VERSION}/${FILE_NAME}"
. build-scripts/xcode/aux_scripts/download_file.sh ${FILE_NAME} ${DOWNLOAD_URL}
local -r API_GENERATOR_COMMAND="java -Xmx12g -jar Downloads/${FILE_NAME} generate-client-code --output-language SWIFT --specification-path ${API_SPEC_DIR} --output-path ${OUTPUT_PATH} --single-file $(is_single_file)"
exit_on_failure "${API_GENERATOR_COMMAND}"
}
readonly BUILD_PHASES_DIR=${SRCROOT}/build_phases
mkdir -p ${BUILD_PHASES_DIR}
readonly COMMIT_FILE_PATH=${BUILD_PHASES_DIR}/api-generator-commit
if [ `is_nothing_changed_since_last_check` -eq ${TRUE} ]; then
notice "Nothing was changed. API generation skipped."
exit ${EXIT_SUCCESS}
fi
readonly VERSION=$1
if [ -z "${OUTPUT_PATH}" ]; then
if [ ! -z "${2}" ]; then
readonly OUTPUT_PATH=${2}
else
readonly OUTPUT_PATH="Generated"
fi
fi
if [ -z "${API_SPEC_DIR}" ]; then
readonly API_SPEC_DIR="common/api"
fi
mkdir -p ${OUTPUT_PATH}
readonly OPEN_API_SPEC_PATH=`find ${API_SPEC_DIR} -maxdepth 1 -name '*.yaml' -o -name '*.yml' | head -n 1`
if [ -f "${OPEN_API_SPEC_PATH}" ]; then
openapi_codegen
elif [ -f "${API_SPEC_DIR}/main.json" ]; then
api_generator_codegen
else
notice "No api spec found!"
exit ${EXIT_FAILURE}
fi
if [ $? -ne ${EXIT_FAILURE} ]; then
record_current_commit
fi