Skip to content

Instantly share code, notes, and snippets.

@madalinpopa
Created October 31, 2024 19:17
Init Django Project Script
#!/usr/bin/env bash
# Exit on error. Append "|| true" if you expect an error.
set -o errexit
# Exit on error inside any functions or subshells.
set -o errtrace
# Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR
set -o nounset
# Catch error in pipes
set -o pipefail
# Variables
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
readonly SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
readonly VENV_NAME=".venv"
readonly VENV_PATH="${PROJECT_ROOT}/${VENV_NAME}"
# Colors for output
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly NC='\033[0m' # No Color
readonly LOG_PREFIX_LENGTH=10 # Length of "INFO: " etc.
readonly LOG_WIDTH=50 # Total width of the banner
# Log functions
log_error() { printf "${RED}%-${LOG_PREFIX_LENGTH}s${NC}%s\n" "ERROR:" "$*" >&2; }
log_success() { printf "${GREEN}%-${LOG_PREFIX_LENGTH}s${NC}%s\n" "SUCCESS:" "$*"; }
log_info() { printf "${YELLOW}%-${LOG_PREFIX_LENGTH}s${NC}%s\n" "INFO:" "$*"; }
# Function to print banner
print_banner() {
local title="$1"
local border_line
border_line=$(printf '%*s' "$LOG_WIDTH" | tr ' ' '-')
log_info "$border_line"
log_info "|$(printf ' %*s ' $(( (LOG_WIDTH - 2 - ${#title}) / 2 )))"${title}"$(printf ' %*s |' $(( (LOG_WIDTH - 2 - ${#title} + 1) / 2 )))"
log_info "$border_line"
log_info ""
}
# Function to check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to check dependencies
check_dependencies() {
log_info "Checking dependencies..."
if ! command_exists python3; then
log_error "Python3 is not installed"
exit 1
fi
if ! command_exists uv; then
log_error "uv is not installed. Please install it first:"
log_error "curl -LsSf https://astral.sh/uv/install.sh | sh"
exit 1
fi
if ! command_exists npm; then
log_error "npm is not installed. Please install it first."
exit 1
fi
log_success "All dependencies are met"
}
# Function to check virtual environment
check_venv_exists() {
log_info "Checking virtual environment..."
# First check if virtual environment exists
if [[ ! -d "${VENV_PATH}" ]]; then
log_info "Virtual environment not found at ${VENV_PATH}"
return 1
fi
log_info "Virtual environment exists"
return 0
}
# Function to create virtual environment using uv
create_venv() {
log_info "Creating virtual environment using uv..."
if ! uv venv "${VENV_PATH}" &> /dev/null; then
log_error "Failed to create virtual environment"
exit 1
fi
log_success "Virtual environment created successfully at ${VENV_PATH}"
}
# Function to sync venv packages
sync_venv(){
log_info "Sync venv packages"
if ! uv sync &> /dev/null; then
log_error "Failed to sync venv packages"
return 1
fi
log_success "Venv packages synced successfully"
return 0
}
# Function to install npm packages
run_npm_install(){
log_info "Install npm packages"
if ! npm install &> /dev/null; then
log_error "Failed to install npm packages"
return 1
fi
log_success "Npm package installed successfully"
return 0
}
# Function to setup .env file
run_env_setup(){
log_info "Setting up environment variables..."
local env_template="${PROJECT_ROOT}/env.template"
local env_file="${PROJECT_ROOT}/.env"
# Create .env from template if it doesn't exist
if [[ ! -f "${env_file}" ]]; then
cp "${env_template}" "${env_file}"
log_success "Created .env from template"
else
log_info ".env file already exists"
fi
# Ensure .env is in .gitignore
local gitignore="${PROJECT_ROOT}/.gitignore"
if [[ ! -f "${gitignore}" ]] || ! grep -q "^.env$" "${gitignore}"; then
echo ".env" >> "${gitignore}"
log_success "Added .env to .gitignore"
fi
return 0
}
# Function to run python manage.py migrate
run_django_migrations(){
log_info "Run django migrations"
if ! uv run python manage.py makemigrations &> /dev/null; then
log_error "Failed to run manage.py makemigrations"
return 1
fi
if ! uv run python manage.py migrate &> /dev/null; then
log_error "Failed to run manage.py migrate"
return 1
fi
log_success "Migration run successfuly"
return 0
}
main() {
print_banner "Init Project"
check_dependencies
check_venv_exists || {
log_info "Virtual environment needs to be set up"
create_venv
}
sync_venv
run_npm_install
run_env_setup
run_django_migrations
}
# Execute main function
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment