1#!/bin/bash 2# Copyright (c) 2025 Huawei Device Co., Ltd. 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15 16set -eu 17set -o pipefail 18 19# Global variables 20SOURCES_LIST="/etc/apt/sources.list" 21BACKUP_FILE="/etc/apt/sources.list.backup" 22 23# Constants for pip configuration 24PIP_CONFIG_DIR="$HOME/.pip" 25PIP_CONFIG_FILE="$PIP_CONFIG_DIR/pip.conf" 26PIP_CONFIG_BACKUP="$PIP_CONFIG_DIR/pip.conf.backup" 27 28# Logging function 29log() { 30 local level=$1 31 shift 32 local message="$@" 33 local timestamp=$(date '+%Y-%m-%d %H:%M:%S') 34} 35 36# Check if root 37check_root() { 38 if [ "$EUID" -ne 0 ]; then 39 log "ERROR" "This script must be run as root (using sudo)" 40 exit 1 41 fi 42 log "INFO" "Root privileges verified" 43} 44 45# Create backup of sources.list 46backup_sources() { 47 if [ -f "$SOURCES_LIST" ]; then 48 cp "$SOURCES_LIST" "$BACKUP_FILE" 49 if [ $? -eq 0 ]; then 50 log "INFO" "Successfully backed up $SOURCES_LIST to $BACKUP_FILE" 51 else 52 log "ERROR" "Failed to create backup of $SOURCES_LIST" 53 exit 1 54 fi 55 else 56 log "ERROR" "Sources list file not found at $SOURCES_LIST" 57 exit 1 58 fi 59} 60 61# Detect distribution and codename 62detect_distribution() { 63 if [ -f /etc/lsb-release ]; then 64 . /etc/lsb-release 65 DISTRO_CODENAME=$DISTRIB_CODENAME 66 DISTRO_TYPE="ubuntu" 67 elif [ -f /etc/os-release ]; then 68 . /etc/os-release 69 DISTRO_CODENAME=$VERSION_CODENAME 70 if [[ "$ID" == "debian" ]]; then 71 DISTRO_TYPE="debian" 72 else 73 DISTRO_TYPE="ubuntu" 74 fi 75 else 76 log "ERROR" "Could not determine distribution version" 77 exit 1 78 fi 79 log "INFO" "Detected distribution: $DISTRO_TYPE ($DISTRO_CODENAME)" 80} 81 82# Generate sources.list content based on distribution 83generate_sources_content() { 84 if [[ "$DISTRO_TYPE" == "ubuntu" ]]; then 85 cat > "$SOURCES_LIST" << EOF 86# Tsinghua University Mirror for Ubuntu 87# Generated on $(date) 88deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ ${DISTRO_CODENAME} main restricted universe multiverse 89deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ ${DISTRO_CODENAME}-updates main restricted universe multiverse 90deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ ${DISTRO_CODENAME}-backports main restricted universe multiverse 91deb http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ ${DISTRO_CODENAME}-security main restricted universe multiverse 92 93# Source repositories 94# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ ${DISTRO_CODENAME} main restricted universe multiverse 95# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ ${DISTRO_CODENAME}-updates main restricted universe multiverse 96# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ ${DISTRO_CODENAME}-backports main restricted universe multiverse 97# deb-src http://mirrors.tuna.tsinghua.edu.cn/ubuntu/ ${DISTRO_CODENAME}-security main restricted universe multiverse 98EOF 99 elif [[ "$DISTRO_TYPE" == "debian" ]]; then 100 cat > "$SOURCES_LIST" << EOF 101# Tsinghua University Mirror for Debian 102# Generated on $(date) 103deb http://mirrors.tuna.tsinghua.edu.cn/debian/ ${DISTRO_CODENAME} main contrib non-free 104deb http://mirrors.tuna.tsinghua.edu.cn/debian/ ${DISTRO_CODENAME}-updates main contrib non-free 105deb http://mirrors.tuna.tsinghua.edu.cn/debian-security ${DISTRO_CODENAME}-security main contrib non-free 106 107# Source repositories 108# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ ${DISTRO_CODENAME} main contrib non-free 109# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian/ ${DISTRO_CODENAME}-updates main contrib non-free 110# deb-src http://mirrors.tuna.tsinghua.edu.cn/debian-security ${DISTRO_CODENAME}-security main contrib non-free 111EOF 112 fi 113 114 if [ $? -eq 0 ]; then 115 log "INFO" "Successfully generated new sources.list" 116 else 117 log "ERROR" "Failed to generate new sources.list" 118 exit 1 119 fi 120} 121 122# Cleanup function 123cleanup() { 124 if [ $? -ne 0 ]; then 125 log "ERROR" "Script failed with exit code $?" 126 fi 127} 128 129# Create pip config directory if it doesn't exist 130setup_pip_directory() { 131 if [ ! -d "$PIP_CONFIG_DIR" ]; then 132 mkdir -p "$PIP_CONFIG_DIR" 133 if [ $? -eq 0 ]; then 134 log "INFO" "Created pip config directory at $PIP_CONFIG_DIR" 135 else 136 log "ERROR" "Failed to create pip config directory" 137 return 1 138 fi 139 fi 140 return 0 141} 142 143# Backup existing pip configuration 144backup_pip_config() { 145 if [ -f "$PIP_CONFIG_FILE" ]; then 146 cp "$PIP_CONFIG_FILE" "$PIP_CONFIG_BACKUP" 147 if [ $? -eq 0 ]; then 148 log "INFO" "Backed up existing pip configuration to $PIP_CONFIG_BACKUP" 149 else 150 log "ERROR" "Failed to backup pip configuration" 151 return 1 152 fi 153 fi 154 return 0 155} 156 157# Update pip configuration to use Tsinghua mirror 158update_pip_mirror() { 159 setup_pip_directory || return 1 160 backup_pip_config || return 1 161 162 cat > "$PIP_CONFIG_FILE" << EOF 163[global] 164index-url = https://pypi.tuna.tsinghua.edu.cn/simple 165trusted-host = pypi.tuna.tsinghua.edu.cn 166EOF 167 168 if [ $? -eq 0 ]; then 169 log "INFO" "Successfully updated pip configuration to use Tsinghua mirror" 170 # Test pip configuration 171 if command -v pip3 >/dev/null 2>&1; then 172 if pip3 config list 2>&1 | grep -q "index-url='https://pypi.tuna.tsinghua.edu.cn/simple'"; then 173 log "INFO" "Pip configuration verified successfully" 174 else 175 log "WARNING" "Pip configuration might not be properly set" 176 fi 177 else 178 log "WARNING" "pip3 not found, skipping configuration verification" 179 fi 180 else 181 log "ERROR" "Failed to update pip configuration" 182 # Restore backup if it exists 183 if [ -f "$PIP_CONFIG_BACKUP" ]; then 184 cp "$PIP_CONFIG_BACKUP" "$PIP_CONFIG_FILE" 185 log "INFO" "Restored pip configuration backup" 186 fi 187 return 1 188 fi 189 return 0 190} 191 192main_update_apt_mirror() { 193 log "INFO" "Starting mirror update script" 194 check_root 195 backup_sources 196 detect_distribution 197 generate_sources_content 198 log "INFO" "Mirror update completed" 199} 200 201main_install_packages() { 202 apt update 203 apt install --yes python3 pip virtualenv clang antlr4 204} 205 206setup_compiler_env() { 207 local script_dir=$1 208 209 log "INFO" "Setting up venv" 210 virtualenv "${script_dir}/../compiler/.venv" 211 source "${script_dir}/../compiler/.venv/bin/activate" 212 213 log "INFO" "Setting up uv" 214 curl -LsSf https://astral.sh/uv/install.sh | sh 215 (cd "${script_dir}/../compiler" && uv sync) 216 217 log "INFO" "Generating antlr4 grammar" 218 (cd "${script_dir}/../compiler" && ./generate-grammar) 219 220 log "INFO" "Completed!" 221 echo "Hint: run the following command to begin:" 222 223 echo " source ${script_dir}/../compiler/.venv/bin/activate" 224 echo " ${script_dir}/../compiler/run-test ${script_dir}/../test/ani_array -ani" 225} 226 227main() { 228 script_dir=$(realpath "$(dirname "$0")") 229 230 case "${1:-}" in 231 update_apt_mirror) 232 main_update_apt_mirror 233 ;; 234 install_pkg) 235 main_install_packages 236 ;; 237 update_pip_mirror) 238 update_pip_mirror 239 ;; 240 setup_compiler_env) 241 setup_compiler_env "$script_dir" 242 ;; 243 *) 244 sudo "$0" update_apt_mirror 245 sudo "$0" install_pkg 246 "$0" update_pip_mirror 247 "$0" setup_compiler_env "$script_dir" 248 ;; 249 esac 250} 251 252# Set up trap for cleanup 253trap cleanup EXIT 254 255# Run main function 256main "$@" 257 258exit 0 259