#!/bin/sh
# 声明这是一个 shell 脚本，指定使用 /bin/sh 作为解释器

# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#    https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# 以上是关于该脚本遵循的 Apache 许可证相关信息，说明版权归属、使用条件等

# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
#   JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
#   M2_HOME - location of maven2's installed home dir
#   MAVEN_OPTS - parameters passed to the Java VM when running Maven
#     e.g. to debug Maven itself, use
#       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
#   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
# 以上是关于该脚本的描述，说明这是 Maven2 的启动脚本，以及所需和可选的环境变量

if [ -z "$MAVEN_SKIP_RC" ] ; then
  # 如果 MAVEN_SKIP_RC 环境变量为空（即未设置）
  if [ -f /etc/mavenrc ] ; then
    # 如果 /etc/mavenrc 文件存在
    . /etc/mavenrc
    # 执行 /etc/mavenrc 文件中的命令（通常用于设置环境变量等）
  fi

  if [ -f "$HOME/.mavenrc" ] ; then
    # 如果用户主目录下的 .mavenrc 文件存在
    . "$HOME/.mavenrc"
    # 执行该文件中的命令
  fi
fi

# OS specific support.  $var _must_ be set to either true or false.
cygwin=false;
# 定义变量 cygwin 并初始化为 false，表示是否是 Cygwin 系统
darwin=false;
# 定义变量 darwin 并初始化为 false，表示是否是 Darwin（Mac OS）系统
mingw=false
# 定义变量 mingw 并初始化为 false，表示是否是 MinGW 系统
case "`uname`" in
  # 根据系统的 uname 命令输出进行匹配
  CYGWIN*) cygwin=true ;;
  # 如果 uname 输出以 CYGWIN 开头，设置 cygwin 为 true
  MINGW*) mingw=true;;
  # 如果 uname 输出以 MINGW 开头，设置 mingw 为 true
  Darwin*) darwin=true
    # 如果是 Darwin 系统，设置 darwin 为 true
    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
    if [ -z "$JAVA_HOME" ]; then
      # 如果 JAVA_HOME 环境变量未设置
      if [ -x "/usr/libexec/java_home" ]; then
        # 如果 /usr/libexec/java_home 可执行
        export JAVA_HOME="`/usr/libexec/java_home`"
        # 使用 /usr/libexec/java_home 命令获取 JDK 路径并设置 JAVA_HOME 环境变量
      else
        export JAVA_HOME="/Library/Java/Home"
        # 否则，设置 JAVA_HOME 为默认的 Mac OS 上 Java 安装路径
      fi
    fi
    ;;
esac

if [ -z "$JAVA_HOME" ] ; then
  # 如果 JAVA_HOME 环境变量未设置
  if [ -r /etc/gentoo-release ] ; then
    # 如果 /etc/gentoo-release 文件可读（通常在 Gentoo 系统上）
    JAVA_HOME=`java-config --jre-home`
    # 使用 java-config --jre-home 命令获取 JDK 路径并设置 JAVA_HOME
  fi
fi

if [ -z "$M2_HOME" ] ; then
  # 如果 M2_HOME 环境变量未设置
  ## resolve links - $0 may be a link to maven's home
  PRG="$0"
  # 将当前脚本的路径赋值给 PRG 变量

  # need this for relative symlinks
  while [ -h "$PRG" ] ; do
    # 当 PRG 是一个符号链接时
    ls=`ls -ld "$PRG"`
    # 使用 ls -ld 命令获取符号链接的详细信息并赋值给 ls 变量
    link=`expr "$ls" : '.*-> \(.*\)$'`
    # 使用 expr 命令从 ls 变量中提取符号链接指向的目标路径并赋值给 link 变量
    if expr "$link" : '/.*' > /dev/null; then
      # 如果 link 是一个绝对路径
      PRG="$link"
      # 将 PRG 设置为链接的目标路径
    else
      PRG="`dirname "$PRG"`/$link"
      # 否则，根据当前 PRG 的目录和链接目标计算出完整路径并赋值给 PRG
    fi
  done

  saveddir=`pwd`
  # 保存当前工作目录到 saveddir 变量

  M2_HOME=`dirname "$PRG"`/..
  # 根据 PRG 计算出 Maven 安装目录的路径并赋值给 M2_HOME

  # make it fully qualified
  M2_HOME=`cd "$M2_HOME" && pwd`
  # 进入 M2_HOME 目录并获取其绝对路径，更新 M2_HOME

  cd "$saveddir"
  # 切换回之前保存的工作目录

  # echo Using m2 at $M2_HOME
  # （注释掉的行，原本可能用于输出使用的 M2_HOME 路径）
fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
  # 如果是 Cygwin 系统
  [ -n "$M2_HOME" ] &&
    M2_HOME=`cygpath --unix "$M2_HOME"`
  # 如果 M2_HOME 不为空，将其转换为 UNIX 格式路径
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
  # 如果 JAVA_HOME 不为空，将其转换为 UNIX 格式路径
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
  # 如果 CLASSPATH 不为空，将其转换为 UNIX 格式路径
fi

# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
  # 如果是 MinGW 系统
  [ -n "$M2_HOME" ] &&
    M2_HOME="`(cd "$M2_HOME"; pwd)`"
  # 如果 M2_HOME 不为空，进入该目录并获取其绝对路径（转换为 UNIX 格式）
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
  # 如果 JAVA_HOME 不为空，进入该目录并获取其绝对路径（转换为 UNIX 格式）
fi

if [ -z "$JAVA_HOME" ]; then
  # 如果 JAVA_HOME 环境变量未设置
  javaExecutable="`which javac`"
  # 使用 which 命令查找 javac 可执行文件的路径并赋值给 javaExecutable 变量
  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
    # 如果找到了 javac 可执行文件且不是 "no"（即有效路径）
    # readlink(1) is not available as standard on Solaris 10.
    readLink=`which readlink`
    # 使用 which 命令查找 readlink 命令的路径并赋值给 readLink 变量
    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
      # 如果找到了 readlink 命令且不是 "no"（即有效路径）
      if $darwin ; then
        # 如果是 Darwin 系统
        javaHome="`dirname \"$javaExecutable\"`"
        # 获取 javac 可执行文件所在目录并赋值给 javaHome 变量
        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
        # 进入 javaHome 目录并获取其绝对路径，再加上 javac 文件名，更新 javaExecutable
      else
        javaExecutable="`readlink -f \"$javaExecutable\"`"
        # 否则（非 Darwin 系统），使用 readlink -f 命令获取 javac 可执行文件的绝对路径并更新 javaExecutable
      fi
      javaHome="`dirname \"$javaExecutable\"`"
      # 获取更新后的 javaExecutable 所在目录并赋值给 javaHome 变量
      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
      # 从 javaHome 变量中提取 bin 目录的上一级目录路径并赋值给 javaHome 变量
      JAVA_HOME="$javaHome"
      # 将计算出的 JDK 路径设置为 JAVA_HOME 环境变量
      export JAVA_HOME
      # 导出 JAVA_HOME 环境变量
    fi
  fi
fi

if [ -z "$JAVACMD" ] ; then
  # 如果 JAVACMD 变量未设置
  if [ -n "$JAVA_HOME"  ] ; then
    # 如果 JAVA_HOME 环境变量不为空
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # 如果 JAVA_HOME/jre/sh/java 可执行（IBM 的 JDK 在 AIX 上的特殊路径）
      JAVACMD="$JAVA_HOME/jre/sh/java"
      # 设置 JAVACMD 为该路径
    else
      JAVACMD="$JAVA_HOME/bin/java"
      # 否则，设置 JAVACMD 为标准的 JAVA_HOME/bin/java 路径
    fi
  else
    JAVACMD="`which java`"
    # 如果 JAVA_HOME 未设置，使用 which 命令查找 java 可执行文件的路径并设置为 JAVACMD
  fi
fi

if [ ! -x "$JAVACMD" ] ; then
  # 如果 JAVACMD 不是可执行文件
  echo "Error: JAVA_HOME is not defined correctly." >&2
  # 向标准错误输出流输出错误信息，提示 JAVA_HOME 定义不正确
  echo "  We cannot execute $JAVACMD" >&2
  # 向标准错误输出流输出无法执行 JAVACMD 的信息
  exit 1
  # 以错误状态码 1 退出脚本
fi

if [ -z "$JAVA_HOME" ] ; then
  # 如果 JAVA_HOME 环境变量未设置
  echo "Warning: JAVA_HOME environment variable is not set."
  # 输出警告信息，提示 JAVA_HOME 环境变量未设置
fi

CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# 设置 CLASSWORLDS_LAUNCHER 变量为指定的类名，用于启动类加载器

# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
  # 定义函数 find_maven_basedir，用于查找 Maven 项目的基础目录

  if [ -z "$1" ]
  then
    # 如果函数的第一个参数为空
    echo "Path not specified to find_maven_basedir"
    # 输出错误信息，提示未指定路径
    return 1
    # 以错误状态码 1 返回
  fi

  basedir="$1"
  # 将函数的第一个参数赋值给 basedir 变量
  wdir="$1"
  # 将函数的第一个参数赋值给 wdir 变量
  while [ "$wdir" != '/' ] ; do
    # 当 wdir 不是根目录时
    if [ -d "$wdir"/.mvn ] ; then
      # 如果 wdir 目录下存在 .mvn 子目录
      basedir=$wdir
      # 将 basedir 设置为 wdir
      break
      # 跳出循环
    fi
    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
    if [ -d "${wdir}" ]; then
      wdir=`cd "$wdir/.."; pwd`
      # 如果 wdir 是一个目录，进入上一级目录并获取其路径，更新 wdir
    fi
    # end of workaround
  done
  echo "${basedir}"
  # 输出找到的 Maven 项目基础目录路径
}

# concatenates all lines of a file
concat_lines() {
  # 定义函数 concat_lines，用于连接文件的所有行

  if [ -f "$1" ]; then
    # 如果函数的第一个参数是一个文件
    echo "$(tr -s '\n' ' ' < "$1")"
    # 使用 tr 命令将文件中的换行符替换为空格，并输出连接后的内容
  fi
}

BASE_DIR=`find_maven_basedir "$(pwd)"`
# 调用 find_maven_basedir 函数，传入当前工作目录路径，获取 Maven 项目基础目录并赋值给 BASE_DIR 变量
if [ -z "$BASE_DIR" ]; then
  # 如果 BASE_DIR 为空
  exit 1;
  # 以错误状态码 1 退出脚本
fi

##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
# 以下是关于自动从 Maven 中央仓库下载 maven-wrapper.jar 的扩展部分说明

if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
  # 如果在 Maven 项目基础目录下的 .mvn/wrapper 目录中存在可读取的 maven-wrapper.jar 文件
  if [ "$MVNW_VERBOSE" = true ]; then
    # 如果 MVNW_VERBOSE 环境变量为 true
    echo "Found .mvn/wrapper/maven-wrapper.jar"
    # 输出找到 maven-wrapper.jar 文件的信息
  fi
else
  # 如果不存在 maven-wrapper.jar 文件
  if [ "$MVNW_VERBOSE" = true ]; then
    # 如果 MVNW_VERBOSE 环境变量为 true
    echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
    # 输出未找到文件并开始下载的信息
  fi
  if [ -n "$MVNW_REPOURL" ]; then
    # 如果 MVNW_REPOURL 环境变量不为空
    jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
    # 设置 jarUrl 为指定仓库路径下的 maven-wrapper.jar 文件路径
  else
    jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
    # 否则，设置 jarUrl 为 Maven 中央仓库的 maven-wrapper.jar 文件路径
  fi
  while IFS="=" read key value; do
    # 按行读取文件内容，以 = 分割为键值对
    case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
    # 如果键为 wrapperUrl，将值赋给 jarUrl 并跳出循环
    esac
  done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
  # 从 .mvn/wrapper/maven-wrapper.properties 文件中读取内容进行处理

  if [ "$MVNW_VERBOSE" = true ]; then
    # 如果 MVNW_VERBOSE 环境变量为 true
    echo "Downloading from: $jarUrl"
    # 输出从哪个路径下载 maven-wrapper.jar 文件的信息
  fi
  wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
  # 设置 wrapperJarPath 为要下载到的本地路径

  if $cygwin; then
    # 如果是 Cygwin 系统
    wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
    # 将 wrapperJarPath 转换为 Windows 格式路径
  fi

  if command -v wget > /dev/null; then
    # 如果 wget 命令存在
    if [ "$MVNW_VERBOSE" = true ]; then
      # 如果 MVNW_VERBOSE 环境变量为 true
      echo "Found wget ... using wget"
      # 输出找到 wget 命令并将使用它下载的信息
    fi
    if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
      # 如果 MVNW_USERNAME 或 MVNW_PASSWORD 环境变量为空
      wget "$jarUrl" -O "$wrapperJarPath"
            # 使用 wget 命令从 jarUrl 下载文件并保存到 wrapperJarPath
          else
            wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
            # 如果有用户名和密码，使用它们进行认证后下载文件
          fi
        elif command -v curl > /dev/null; then
          # 如果 wget 不可用但 curl 命令存在
          if [ "$MVNW_VERBOSE" = true ]; then
            # 如果 MVNW_VERBOSE 环境变量为 true
            echo "Found curl ... using curl"
            # 输出找到 curl 命令并将使用它下载的信息
          fi
          if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
            # 如果 MVNW_USERNAME 或 MVNW_PASSWORD 环境变量为空
            curl -o "$wrapperJarPath" "$jarUrl" -f
            # 使用 curl 命令从 jarUrl 下载文件并保存到 wrapperJarPath，-f 表示失败时不显示进度条
          else
            curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
            # 如果有用户名和密码，使用它们进行认证后下载文件
          fi
        else
          # 如果 wget 和 curl 都不可用
          if [ "$MVNW_VERBOSE" = true ]; then
            # 如果 MVNW_VERBOSE 环境变量为 true
            echo "Falling back to using Java to download"
            # 输出将使用 Java 进行下载的信息
          fi
          javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
          # 设置 javaClass 为 MavenWrapperDownloader.java 文件的路径

          # For Cygwin, switch paths to Windows format before running javac
          if $cygwin; then
            # 如果是 Cygwin 系统
            javaClass=`cygpath --path --windows "$javaClass"`
            # 将 javaClass 路径转换为 Windows 格式
          fi

          if [ -e "$javaClass" ]; then
            # 如果 MavenWrapperDownloader.java 文件存在
            if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
              # 如果 MavenWrapperDownloader.class 文件不存在
              if [ "$MVNW_VERBOSE" = true ]; then
                # 如果 MVNW_VERBOSE 环境变量为 true
                echo " - Compiling MavenWrapperDownloader.java ..."
                # 输出正在编译 MavenWrapperDownloader.java 文件的信息
              fi
              # Compiling the Java class
              ("$JAVA_HOME/bin/javac" "$javaClass")
              # 使用 javac 命令编译 MavenWrapperDownloader.java 文件
            fi
            if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
              # 如果编译后的 MavenWrapperDownloader.class 文件存在
              # Running the downloader
              if [ "$MVNW_VERBOSE" = true ]; then
                # 如果 MVNW_VERBOSE 环境变量为 true
                echo " - Running MavenWrapperDownloader.java ..."
                # 输出正在运行 MavenWrapperDownloader.java 程序的信息
              fi
              ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
              # 使用 java 命令运行编译后的程序进行下载，传入项目基础目录作为参数
            fi
          fi
        fi
      fi
      ##########################################################################################
      # End of extension
      ##########################################################################################
      # 自动下载 maven-wrapper.jar 扩展部分结束

      export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
      # 导出 MAVEN_PROJECTBASEDIR 环境变量，如果 MAVEN_BASEDIR 未设置，则使用 BASE_DIR 的值

      if [ "$MVNW_VERBOSE" = true ]; then
        # 如果 MVNW_VERBOSE 环境变量为 true
        echo $MAVEN_PROJECTBASEDIR
        # 输出 MAVEN_PROJECTBASEDIR 的值
      fi

      MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
      # 将 MAVEN_PROJECTBASEDIR/.mvn/jvm.config 文件中的内容连接起来，并追加到 MAVEN_OPTS 变量后面

      # For Cygwin, switch paths to Windows format before running java
      if $cygwin; then
        # 如果是 Cygwin 系统
        [ -n "$M2_HOME" ] &&
          M2_HOME=`cygpath --path --windows "$M2_HOME"`
        # 如果 M2_HOME 不为空，将其转换为 Windows 格式路径
        [ -n "$JAVA_HOME" ] &&
          JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
        # 如果 JAVA_HOME 不为空，将其转换为 Windows 格式路径
        [ -n "$CLASSPATH" ] &&
          CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
        # 如果 CLASSPATH 不为空，将其转换为 Windows 格式路径
        [ -n "$MAVEN_PROJECTBASEDIR" ] &&
          MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
        # 如果 MAVEN_PROJECTBASEDIR 不为空，将其转换为 Windows 格式路径
      fi

      # Provide a "standardized" way to retrieve the CLI args that will
      # work with both Windows and non-Windows executions.
      MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
      # 将 MAVEN_CONFIG 变量的值和脚本的所有参数连接起来，赋值给 MAVEN_CMD_LINE_ARGS 变量
      export MAVEN_CMD_LINE_ARGS
      # 导出 MAVEN_CMD_LINE_ARGS 环境变量

      WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
      # 设置 WRAPPER_LAUNCHER 变量为 Maven 包装器的主类名

      exec "$JAVACMD" \
        # 执行 Java 命令
        $MAVEN_OPTS \
        # 传递 MAVEN_OPTS 变量中的参数给 Java 虚拟机
        -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
        # 设置 Java 类路径为 maven-wrapper.jar 文件所在路径
        "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
        # 设置系统属性 maven.home 和 maven.multiModuleProjectDirectory
        ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
        # 执行 WRAPPER_LAUNCHER 类，并传递 MAVEN_CONFIG 和脚本的所有参数
        #!/bin/sh
        # 声明这是一个 shell 脚本，指定使用 /bin/sh 作为解释器

        # ----------------------------------------------------------------------------
        # Licensed to the Apache Software Foundation (ASF) under one
        # or more contributor license agreements.  See the NOTICE file
        # distributed with this work for additional information
        # regarding copyright ownership.  The ASF licenses this file
        # to you under the Apache License, Version 2.0 (the
        # "License"); you may not use this file except in compliance
        # with the License.  You may obtain a copy of the License at
        #
        #    https://www.apache.org/licenses/LICENSE-2.0
        #
        # Unless required by applicable law or agreed to in writing,
        # software distributed under the License is distributed on an
        # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
        # KIND, either express or implied.  See the License for the
        # specific language governing permissions and limitations
        # under the License.
        # ----------------------------------------------------------------------------
        # 以上是关于该脚本遵循的 Apache 许可证相关信息，说明版权归属、使用条件等

        # ----------------------------------------------------------------------------
        # Maven2 Start Up Batch script
        #
        # Required ENV vars:
        # ------------------
        #   JAVA_HOME - location of a JDK home dir
        #
        # Optional ENV vars
        # -----------------
        #   M2_HOME - location of maven2's installed home dir
        #   MAVEN_OPTS - parameters passed to the Java VM when running Maven
        #     e.g. to debug Maven itself, use
        #       set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
        #   MAVEN_SKIP_RC - flag to disable loading of mavenrc files
        # ----------------------------------------------------------------------------
        # 以上是关于该脚本的描述，说明这是 Maven2 的启动脚本，以及所需和可选的环境变量

        if [ -z "$MAVEN_SKIP_RC" ] ; then
          # 如果 MAVEN_SKIP_RC 环境变量为空（即未设置）
          if [ -f /etc/mavenrc ] ; then
            # 如果 /etc/mavenrc 文件存在
            . /etc/mavenrc
            # 执行 /etc/mavenrc 文件中的命令（通常用于设置环境变量等，以配置 Maven 相关运行参数）
          fi

          if [ -f "$HOME/.mavenrc" ] ; then
            # 如果用户主目录下的 .mavenrc 文件存在
            . "$HOME/.mavenrc"
            # 执行该文件中的命令，进一步配置 Maven 运行相关的环境或参数
          fi
        fi

        # OS specific support.  $var _must_ be set to either true or false.
        cygwin=false;
        # 定义变量 cygwin 并初始化为 false，表示当前系统是否是 Cygwin 系统（Cygwin 是一个在 Windows 上模拟 Unix 环境的软件）
        darwin=false;
        # 定义变量 darwin 并初始化为 false，表示当前系统是否是 Darwin（Mac OS）系统
        mingw=false
        # 定义变量 mingw 并初始化为 false，表示当前系统是否是 MinGW 系统（MinGW 是在 Windows 上提供一套开源的开发工具集）
        case "`uname`" in
          # 根据系统的 uname 命令输出（获取系统名称）进行匹配
          CYGWIN*) cygwin=true ;;
          # 如果 uname 输出以 CYGWIN 开头，设置 cygwin 为 true，表明当前系统是 Cygwin 环境
          MINGW*) mingw=true;;
          # 如果 uname 输出以 MINGW 开头，设置 mingw 为 true，表明当前系统是 MinGW 环境
          Darwin*) darwin=true
            # 如果是 Darwin 系统，设置 darwin 为 true
            # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
            # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
            if [ -z "$JAVA_HOME" ]; then
              # 如果 JAVA_HOME 环境变量未设置
              if [ -x "/usr/libexec/java_home" ]; then
                # 如果 /usr/libexec/java_home 可执行（该命令可用于获取系统上可用的 JDK 路径）
                export JAVA_HOME="`/usr/libexec/java_home`"
                # 使用 /usr/libexec/java_home 命令获取 JDK 路径并设置 JAVA_HOME 环境变量
              else
                export JAVA_HOME="/Library/Java/Home"
                # 否则，设置 JAVA_HOME 为默认的 Mac OS 上 Java 安装路径（常见的默认路径）
              fi
            fi
            ;;
        esac

        if [ -z "$JAVA_HOME" ] ; then
          # 如果 JAVA_HOME 环境变量未设置
          if [ -r /etc/gentoo-release ] ; then
            # 如果 /etc/gentoo-release 文件可读（在 Gentoo Linux 系统中，该文件标识系统版本等信息）
            JAVA_HOME=`java-config --jre-home`
            # 使用 java-config --jre-home 命令获取 JDK 路径并设置 JAVA_HOME（适用于 Gentoo 系统获取 JDK 路径的方式）
          fi
        fi

        if [ -z "$M2_HOME" ] ; then
          # 如果 M2_HOME 环境变量未设置
          ## resolve links - $0 may be a link to maven's home
          PRG="$0"
          # 将当前脚本的路径赋值给 PRG 变量，$0 在 shell 中表示脚本本身的名称或路径
          # need this for relative symlinks
          while [ -h "$PRG" ] ; do
            # 当 PRG 是一个符号链接时（-h 用于判断是否为符号链接）
            ls=`ls -ld "$PRG"`
            # 使用 ls -ld 命令获取符号链接的详细信息并赋值给 ls 变量，包括链接指向的目标等信息
            link=`expr "$ls" : '.*-> \(.*\)$'`
            # 使用 expr 命令从 ls 变量中提取符号链接指向的目标路径并赋值给 link 变量，通过正则表达式匹配提取链接目标
            if expr "$link" : '/.*' > /dev/null; then
              # 如果 link 是一个绝对路径（通过判断路径是否以 / 开头来确定是否为绝对路径）
              PRG="$link"
              # 将 PRG 设置为链接的目标路径，更新 PRG 为实际的路径
            else
              PRG="`dirname "$PRG"`/$link"
              # 否则，根据当前 PRG 的目录和链接目标计算出完整路径并赋值给 PRG，拼接得到实际路径
            fi
          done

          saveddir=`pwd`
          # 保存当前工作目录到 saveddir 变量，pwd 命令用于获取当前工作目录路径
          M2_HOME=`dirname "$PRG"`/..
          # 根据 PRG 计算出 Maven 安装目录的路径并赋值给 M2_HOME，取 PRG 的目录的上一级目录作为 Maven 安装目录
          # make it fully qualified
          M2_HOME=`cd "$M2_HOME" && pwd`
          # 进入 M2_HOME 目录并获取其绝对路径，cd 命令进入目录，pwd 命令获取当前目录路径，更新 M2_HOME 为绝对路径
          cd "$saveddir"
          # 切换回之前保存的工作目录，恢复之前的工作目录状态
          # echo Using m2 at $M2_HOME
          # （注释掉的行，原本可能用于输出使用的 M2_HOME 路径，调试或信息展示用途）
        fi

        # For Cygwin, ensure paths are in UNIX format before anything is touched
        if $cygwin ; then
          # 如果是 Cygwin 系统
          [ -n "$M2_HOME" ] &&
            M2_HOME=`cygpath --unix "$M2_HOME"`
          # 如果 M2_HOME 不为空（-n 判断变量是否为空字符串），将其转换为 UNIX 格式路径，cygpath 用于转换 Cygwin 路径格式
          [ -n "$JAVA_HOME" ] &&
            JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
          # 如果 JAVA_HOME 不为空，将其转换为 UNIX 格式路径
          [ -n "$CLASSPATH" ] &&
            CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
          # 如果 CLASSPATH 不为空，将其转换为 UNIX 格式路径，确保路径格式符合 Cygwin 下的 UNIX 环境要求
        fi

        # For Mingw, ensure paths are in UNIX format before anything is touched
        if $mingw ; then
          # 如果是 MinGW 系统
          [ -n "$M2_HOME" ] &&
            M2_HOME="`(cd "$M2_HOME"; pwd)`"
          # 如果 M2_HOME 不为空，进入该目录并获取其绝对路径（转换为 UNIX 格式），通过 cd 和 pwd 命令组合实现
          [ -n "$JAVA_HOME" ] &&
            JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
          # 如果 JAVA_HOME 不为空，进入该目录并获取其绝对路径（转换为 UNIX 格式）
        fi

        if [ -z "$JAVA_HOME" ]; then
          # 如果 JAVA_HOME 环境变量未设置
          javaExecutable="`which javac`"
          # 使用 which 命令查找 javac 可执行文件的路径并赋值给 javaExecutable 变量，which 用于在系统路径中查找命令的可执行文件位置
          if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
            # 如果找到了 javac 可执行文件且不是 "no"（即有效路径，排除 which 未找到时输出的错误标识）
            # readlink(1) is not available as standard on Solaris 10.
            readLink=`which readlink`
            # 使用 which 命令查找 readlink 命令的路径并赋值给 readLink 变量，readlink 用于获取符号链接指向的实际路径
            if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
              # 如果找到了 readlink 命令且不是 "no"（即有效路径）
              if $darwin ; then
                # 如果是 Darwin 系统
                javaHome="`dirname \"$javaExecutable\"`"
                # 获取 javac 可执行文件所在目录并赋值给 javaHome 变量，dirname 用于获取路径的目录部分
                javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
                # 进入 javaHome 目录并获取其绝对路径（-P 选项用于获取物理路径，不包含符号链接），再加上 javac 文件名，更新 javaExecutable 为绝对路径的 javac 可执行文件
              else
                javaExecutable="`readlink -f \"$javaExecutable\"`"
                # 否则（非 Darwin 系统），使用 readlink -f 命令获取 javac 可执行文件的绝对路径并更新 javaExecutable，-f 选项用于获取符号链接的最终目标路径
              fi
              javaHome="`dirname \"$javaExecutable\"`"
              # 获取更新后的 javaExecutable 所在目录并赋值给 javaHome 变量
              javaHome=`expr "$javaHome" : '\(.*\)/bin'`
              # 从 javaHome 变量中提取 bin 目录的上一级目录路径并赋值给 javaHome 变量，通过正则表达式匹配提取路径部分
              JAVA_HOME="$javaHome"
              # 将计算出的 JDK 路径设置为 JAVA_HOME 环境变量
              export JAVA_HOME
              # 导出 JAVA_HOME 环境变量，使其在后续的子进程中也能使用
            fi
          fi
        fi

        if [ -z "$JAVACMD" ] ; then
          # 如果 JAVACMD 变量未设置
          if [ -n "$JAVA_HOME"  ] ; then
            # 如果 JAVA_HOME 环境变量不为空
            if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
              # 如果 JAVA_HOME/jre/sh/java 可执行（IBM 的 JDK 在 AIX 上的特殊路径下的 java 可执行文件）
              JAVACMD="$JAVA_HOME/jre/sh/java"
              # 设置 JAVACMD 为该路径，指定用于运行 Java 程序的命令路径
            else
              JAVACMD="$JAVA_HOME/bin/java"
              # 否则，设置 JAVACMD 为标准的 JAVA_HOME/bin/java 路径，这是常见的 Java 可执行文件路径
            fi
          else
            JAVACMD="`which java`"
            # 如果 JAVA_HOME 未设置，使用 which 命令查找 java 可执行文件的路径并设置为 JAVACMD，在系统路径中查找默认的 java 可执行文件
          fi
        fi

        if [ ! -x "$JAVACMD" ] ; then
          # 如果 JAVACMD 不是可执行文件（-x 判断文件是否可执行）
          echo "Error: JAVA_HOME is not defined correctly." >&2
          # 向标准错误输出流输出错误信息，提示 JAVA_HOME 定义不正确，>&2 表示输出到标准错误流
          echo "  We cannot execute $JAVACMD" >&2
          # 向标准错误输出流输出无法执行 JAVACMD 的信息
          exit 1
          # 以错误状态码 1 退出脚本，表示脚本执行出现错误
        fi

        if [ -z "$JAVA_HOME" ] ; then
          # 如果 JAVA_HOME 环境变量未设置
          echo "Warning: JAVA_HOME environment variable is not set."
          # 输出警告信息，提示 JAVA_HOME 环境变量未设置，可能会影响程序的正确运行
        fi

        CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
        # 设置 CLASSWORLDS_LAUNCHER 变量为指定的类名，用于指定使用 org.codehaus.plexus.classworlds.launcher.Launcher 类来启动类加载器，这是 Maven 中用于管理类加载的一种机制

        # traverses directory structure from process work directory to filesystem root
        # first directory with .mvn subdirectory is considered project base directory
        find_maven_basedir() {
          # 定义函数 find_maven_basedir，用于查找 Maven 项目的基础目录
          # 函数从当前进程的工作目录开始，向上遍历目录结构直到文件系统根目录，找到第一个包含.mvn 子目录的目录作为项目基础目录

          if [ -z "$1" ]
          then
            # 如果函数的第一个参数为空（$1 表示函数的第一个参数）
            echo "Path not specified to find_maven_basedir"
            # 输出错误信息，提示未指定路径给 find_maven_basedir 函数
            return 1
            # 以错误状态码 1 返回，表示函数执行失败
          fi

          basedir="$1"
          # 将函数的第一个参数赋值给 basedir 变量，作为起始查找的目录
          wdir="$1"
          # 将函数的第一个参数赋值给 wdir 变量，用于在循环中逐步向上遍历目录
          while [ "$wdir" != '/' ] ; do
            # 当 wdir 不是根目录时（循环条件，直到遍历到根目录为止）
            if [ -d "$wdir"/.mvn ] ; then
              # 如果 wdir 目录下存在 .mvn 子目录（-d 判断是否为目录）
              basedir=$wdir
              # 将 basedir 设置为 wdir，即找到了包含.mvn 子目录的目录，作为项目基础目录
              break
              # 跳出循环，不再继续向上遍历
            fi
            # workaround for JBEAP-8937 (on Solaris 10/Sparc)
            if [ -d "${wdir}" ]; then
              wdir=`cd "$wdir/.."; pwd`
              # 如果 wdir 是一个目录，进入上一级目录并获取其路径，更新 wdir 为上一级目录路径，这是一个针对 Solaris 10/Sparc 系统的特定处理（解决某些问题的变通方法）
            fi
            # end of workaround
          done
          echo "${basedir}"
          # 输出找到的 Maven 项目基础目录路径
        }

        # concatenates all lines of a file
        concat_lines() {
          # 定义函数 concat_lines，用于将文件的所有行连接成一行字符串

          if [ -f "$1" ]; then
          # 如果函数的第一个参数是一个文件（-f 判断是否为文件）
            echo "$(tr -s '\n' ' ' < "$1")"
            # 使用 tr 命令将文件中的换行符 '\n' 替换为空格 ' '，-s 选项用于压缩连续的多个换行符为一个空格，< "$1" 表示从文件中读取内容，然后输出连接后的内容
          fi
        }

        BASE_DIR=`find_maven_basedir "$(pwd)"`
        # 调用 find_maven_basedir 函数，传入当前工作目录路径（通过 pwd 命令获取），获取 Maven 项目基础目录并赋值给 BASE_DIR 变量
        if [ -z "$BASE_DIR" ]; then
          # 如果 BASE_DIR 为空（即未找到合适的项目基础目录）
          exit 1;
          # 以错误状态码 1 退出脚本，表示脚本执行失败，因为无法确定 Maven 项目基础目录
        fi

        ##########################################################################################
        # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
        # This allows using the maven

# OS specific support.  $var _must_ be set to either true or false.
cygwin=false;
# 定义变量 cygwin 并初始化为 false，表示是否是 Cygwin 系统
darwin=false;
# 定义变量 darwin 并初始化为 false，表示是否是 Darwin（Mac OS）系统
mingw=false
# 定义变量 mingw 并初始化为 false，表示是否是 MinGW 系统
case "`uname`" in
  # 根据系统的 uname 命令输出进行匹配
  CYGWIN*) cygwin=true ;;
  # 如果 uname 输出以 CYGWIN 开头，设置 cygwin 为 true
  MINGW*) mingw=true;;
  # 如果 uname 输出以 MINGW 开头，设置 mingw 为 true
  Darwin*) darwin=true
    # 如果是 Darwin 系统，设置 darwin 为 true
    # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
    # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
    if [ -z "$JAVA_HOME" ]; then
      # 如果 JAVA_HOME 环境变量未设置
      if [ -x "/usr/libexec/java_home" ]; then
        # 如果 /usr/libexec/java_home 可执行
        export JAVA_HOME="`/usr/libexec/java_home`"
        # 使用 /usr/libexec/java_home 命令获取 JDK 路径并设置 JAVA_HOME 环境变量
      else
        export JAVA_HOME="/Library/Java/Home"
        # 否则，设置 JAVA_HOME 为默认的 Mac OS 上 Java 安装路径
      fi
    fi
    ;;
esac

if [ -z "$JAVA_HOME" ] ; then
  # 如果 JAVA_HOME 环境变量未设置
  if [ -r /etc/gentoo-release ] ; then
    # 如果 /etc/gentoo-release 文件可读（通常在 Gentoo 系统上）
    JAVA_HOME=`java-config --jre-home`
    # 使用 java-config --jre-home 命令获取 JDK 路径并设置 JAVA_HOME
  fi
fi

if [ -z "$M2_HOME" ] ; then
  # 如果 M2_HOME 环境变量未设置
  ## resolve links - $0 may be a link to maven's home
  PRG="$0"
  # 将当前脚本的路径赋值给 PRG 变量

  # need this for relative symlinks
  while [ -h "$PRG" ] ; do
    # 当 PRG 是一个符号链接时
    ls=`ls -ld "$PRG"`
    # 使用 ls -ld 命令获取符号链接的详细信息并赋值给 ls 变量
    link=`expr "$ls" : '.*-> \(.*\)$'`
    # 使用 expr 命令从 ls 变量中提取符号链接指向的目标路径并赋值给 link 变量
    if expr "$link" : '/.*' > /dev/null; then
      # 如果 link 是一个绝对路径
      PRG="$link"
      # 将 PRG 设置为链接的目标路径
    else
      PRG="`dirname "$PRG"`/$link"
      # 否则，根据当前 PRG 的目录和链接目标计算出完整路径并赋值给 PRG
    fi
  done

  saveddir=`pwd`
  # 保存当前工作目录到 saveddir 变量

  M2_HOME=`dirname "$PRG"`/..
  # 根据 PRG 计算出 Maven 安装目录的路径并赋值给 M2_HOME

  # make it fully qualified
  M2_HOME=`cd "$M2_HOME" && pwd`
  # 进入 M2_HOME 目录并获取其绝对路径，更新 M2_HOME

  cd "$saveddir"
  # 切换回之前保存的工作目录

  # echo Using m2 at $M2_HOME
  # （注释掉的行，原本可能用于输出使用的 M2_HOME 路径）
fi

# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
  # 如果是 Cygwin 系统
  [ -n "$M2_HOME" ] &&
    M2_HOME=`cygpath --unix "$M2_HOME"`
  # 如果 M2_HOME 不为空，将其转换为 UNIX 格式路径
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
  # 如果 JAVA_HOME 不为空，将其转换为 UNIX 格式路径
  [ -n "$CLASSPATH" ] &&
    CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
  # 如果 CLASSPATH 不为空，将其转换为 UNIX 格式路径
fi

# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
  # 如果是 MinGW 系统
  [ -n "$M2_HOME" ] &&
    M2_HOME="`(cd "$M2_HOME"; pwd)`"
  # 如果 M2_HOME 不为空，进入该目录并获取其绝对路径（转换为 UNIX 格式）
  [ -n "$JAVA_HOME" ] &&
    JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
  # 如果 JAVA_HOME 不为空，进入该目录并获取其绝对路径（转换为 UNIX 格式）
fi

if [ -z "$JAVA_HOME" ]; then
  # 如果 JAVA_HOME 环境变量未设置
  javaExecutable="`which javac`"
  # 使用 which 命令查找 javac 可执行文件的路径并赋值给 javaExecutable 变量
  if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
    # 如果找到了 javac 可执行文件且不是 "no"（即有效路径）
    # readlink(1) is not available as standard on Solaris 10.
    readLink=`which readlink`
    # 使用 which 命令查找 readlink 命令的路径并赋值给 readLink 变量
    if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
      # 如果找到了 readlink 命令且不是 "no"（即有效路径）
      if $darwin ; then
        # 如果是 Darwin 系统
        javaHome="`dirname \"$javaExecutable\"`"
        # 获取 javac 可执行文件所在目录并赋值给 javaHome 变量
        javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
        # 进入 javaHome 目录并获取其绝对路径，再加上 javac 文件名，更新 javaExecutable
      else
        javaExecutable="`readlink -f \"$javaExecutable\"`"
        # 否则（非 Darwin 系统），使用 readlink -f 命令获取 javac 可执行文件的绝对路径并更新 javaExecutable
      fi
      javaHome="`dirname \"$javaExecutable\"`"
      # 获取更新后的 javaExecutable 所在目录并赋值给 javaHome 变量
      javaHome=`expr "$javaHome" : '\(.*\)/bin'`
      # 从 javaHome 变量中提取 bin 目录的上一级目录路径并赋值给 javaHome 变量
      JAVA_HOME="$javaHome"
      # 将计算出的 JDK 路径设置为 JAVA_HOME 环境变量
      export JAVA_HOME
      # 导出 JAVA_HOME 环境变量
    fi
  fi
fi

if [ -z "$JAVACMD" ] ; then
  # 如果 JAVACMD 变量未设置
  if [ -n "$JAVA_HOME"  ] ; then
    # 如果 JAVA_HOME 环境变量不为空
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
      # 如果 JAVA_HOME/jre/sh/java 可执行（IBM 的 JDK 在 AIX 上的特殊路径）
      JAVACMD="$JAVA_HOME/jre/sh/java"
      # 设置 JAVACMD 为该路径
    else
      JAVACMD="$JAVA_HOME/bin/java"
      # 否则，设置 JAVACMD 为标准的 JAVA_HOME/bin/java 路径
    fi
  else
    JAVACMD="`which java`"
    # 如果 JAVA_HOME 未设置，使用 which 命令查找 java 可执行文件的路径并设置为 JAVACMD
  fi
fi

if [ ! -x "$JAVACMD" ] ; then
  # 如果 JAVACMD 不是可执行文件
  echo "Error: JAVA_HOME is not defined correctly." >&2
  # 向标准错误输出流输出错误信息，提示 JAVA_HOME 定义不正确
  echo "  We cannot execute $JAVACMD" >&2
  # 向标准错误输出流输出无法执行 JAVACMD 的信息
  exit 1
  # 以错误状态码 1 退出脚本
fi

if [ -z "$JAVA_HOME" ] ; then
  # 如果 JAVA_HOME 环境变量未设置
  echo "Warning: JAVA_HOME environment variable is not set."
  # 输出警告信息，提示 JAVA_HOME 环境变量未设置
fi

CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# 设置 CLASSWORLDS_LAUNCHER 变量为指定的类名，用于启动类加载器

# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
  # 定义函数 find_maven_basedir，用于查找 Maven 项目的基础目录

  if [ -z "$1" ]
  then
    # 如果函数的第一个参数为空
    echo "Path not specified to find_maven_basedir"
    # 输出错误信息，提示未指定路径
    return 1
    # 以错误状态码 1 返回
  fi

  basedir="$1"
  # 将函数的第一个参数赋值给 basedir 变量
  wdir="$1"
  # 将函数的第一个参数赋值给 wdir 变量
  while [ "$wdir" != '/' ] ; do
    # 当 wdir 不是根目录时
    if [ -d "$wdir"/.mvn ] ; then
      # 如果 wdir 目录下存在 .mvn 子目录
      basedir=$wdir
      # 将 basedir 设置为 wdir
      break
      # 跳出循环
    fi
    # workaround for JBEAP-8937 (on Solaris 10/Sparc)
    if [ -d "${wdir}" ]; then
      wdir=`cd "$wdir/.."; pwd`
      # 如果 wdir 是一个目录，进入上一级目录并获取其路径，更新 wdir
    fi
    # end of workaround
  done
  echo "${basedir}"
  # 输出找到的 Maven 项目基础目录路径
}

# concatenates all lines of a file
concat_lines() {
  # 定义函数 concat_lines，用于连接文件的所有行

  if [ -f "$1" ]; then
    # 如果函数的第一个参数是一个文件
    echo "$(tr -s '\n' ' ' < "$1")"
    # 使用 tr 命令将文件中的换行符替换为空格，并输出连接后的内容
  fi
}

BASE_DIR=`find_maven_basedir "$(pwd)"`
# 调用 find_maven_basedir 函数，传入当前工作目录路径，获取 Maven 项目基础目录并赋值给 BASE_DIR 变量
if [ -z "$BASE_DIR" ]; then
  # 如果 BASE_DIR 为空
  exit 1;
  # 以错误状态码 1 退出脚本
fi

##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
# 以下是关于自动从 Maven 中央仓库下载 maven-wrapper.jar 的扩展部分说明

if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
  # 如果在 Maven 项目基础目录下的 .mvn/wrapper 目录中存在可读取的 maven-wrapper.jar 文件
  if [ "$MVNW_VERBOSE" = true ]; then
    # 如果 MVNW_VERBOSE 环境变量为 true
    echo "Found .mvn/wrapper/maven-wrapper.jar"
    # 输出找到 maven-wrapper.jar 文件的信息
  fi
else
  # 如果不存在 maven-wrapper.jar 文件
  if [ "$MVNW_VERBOSE" = true ]; then
    # 如果 MVNW_VERBOSE 环境变量为 true
    echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
    # 输出未找到文件并开始下载的信息
  fi
  if [ -n "$MVNW_REPOURL" ]; then
    # 如果 MVNW_REPOURL 环境变量不为空
    jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
    # 设置 jarUrl 为指定仓库路径下的 maven-wrapper.jar 文件路径
  else
    jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar"
    # 否则，设置 jarUrl 为 Maven 中央仓库的 maven-wrapper.jar 文件路径
  fi
  while IFS="=" read key value; do
    # 按行读取文件内容，以 = 分割为键值对
    case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
    # 如果键为 wrapperUrl，将值赋给 jarUrl 并跳出循环
    esac
  done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
  # 从 .mvn/wrapper/maven-wrapper.properties 文件中读取内容进行处理

  if [ "$MVNW_VERBOSE" = true ]; then
    # 如果 MVNW_VERBOSE 环境变量为 true
    echo "Downloading from: $jarUrl"
    # 输出从哪个路径下载 maven-wrapper.jar 文件的信息
  fi
  wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
  # 设置 wrapperJarPath 为要下载到的本地路径

  if $cygwin; then
    # 如果是 Cygwin 系统
    wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
    # 将 wrapperJarPath 转换为 Windows 格式路径
  fi

  if command -v wget > /dev/null; then
    # 如果 wget 命令存在
    if [ "$MVNW_VERBOSE" = true ]; then
      # 如果 MVNW_VERBOSE 环境变量为 true
      echo "Found wget ... using wget"
      # 输出找到 wget 命令并将使用它下载的信息
    fi
    if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
      # 如果 MVNW_USERNAME 或 MVNW_PASSWORD 环境变量为空
      wget "$jarUrl" -O "$wrapperJarPath"
      # 使用 wget 命令从 jarUrl 下载文件并保存到 wrapperJarPath
    else
      wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
      # 如果有用户名和密码，使用它们进行认证后下载文件
    fi
  elif command -v curl > /dev/null; then
    # 如果 wget 不可用但 curl 命令存在
    if [ "$MVNW_VERBOSE" = true ]; then
      # 如果 MVNW_VERBOSE 环境变量为 true
      echo "Found curl ... using curl"
      # 输出找到 curl 命令并将使用它下载的信息
    fi
    if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
      # 如果 MVNW_USERNAME 或 MVNW_PASSWORD 环境变量为空
      curl -o "$wrapperJarPath" "$jarUrl" -f
      # 使用 curl 命令从 jarUrl 下载文件并保存到 wrapperJarPath，-f 表示失败时不显示进度条
    else
      curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
      # 如果有用户名和密码，使用它们进行认证后下载文件
    fi
  else
    # 如果 wget 和 curl 都不可用
    if [ "$MVNW_VERBOSE" = true ]; then
      # 如果 MVNW_VERBOSE 环境变量为 true
      echo "Falling back to using Java to download"
      # 输出将使用 Java 进行下载的信息
    fi
    javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
    # 设置 javaClass 为 MavenWrapperDownloader.java 文件的路径

    # For Cygwin, switch paths to Windows format before running javac
    if $cygwin; then
      # 如果是 Cygwin 系统
      javaClass=`cygpath --path --windows "$javaClass"`
      # 将 javaClass 路径转换为 Windows 格式
    fi

    if [ -e "$javaClass" ]; then
      # 如果 MavenWrapperDownloader.java 文件存在
      if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
        # 如果 MavenWrapperDownloader.class 文件不存在
        if [ "$MVNW_VERBOSE" = true ]; then
          # 如果 MVNW_VERBOSE 环境变量为 true
          echo " - Compiling MavenWrapperDownloader.java ..."
          # 输出正在编译 MavenWrapperDownloader.java 文件的信息
        fi
        # Compiling the Java class
        ("$JAVA_HOME/bin/javac" "$javaClass")
        # 使用 javac 命令编译 MavenWrapperDownloader.java 文件
      fi
      if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
        # 如果编译后的 MavenWrapperDownloader.class 文件存在
        # Running the downloader
        if [ "$MVNW_VERBOSE" = true ]; then
          # 如果 MVNW_VERBOSE 环境变量为 true
          echo " - Running MavenWrapperDownloader.java ..."
          # 输出正在运行 MavenWrapperDownloader.java 程序的信息
        fi
        ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
        # 使用 java 命令运行编译后的程序进行下载，传入项目基础目录作为参数
      fi
    fi
  fi
fi
##########################################################################################
# End of extension
##########################################################################################
# 自动下载 maven-wrapper.jar 扩展部分结束

export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
# 导出 MAVEN_PROJECTBASEDIR 环境变量，如果 MAVEN_BASEDIR 未设置，则使用 BASE_DIR 的值
if [ "$MVNW_VERBOSE" = true ]; then
  # 如果 MVNW_VERBOSE 环境变量为 true
  echo $MAVEN_PROJECTBASEDIR
  # 输出 MAVEN_PROJECTBASEDIR 的值
fi

MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# 调用 concat_lines 函数将 .mvn/jvm.config 文件内容拼接成一行，再与原有的 MAVEN_OPTS 拼接，作为新的 JVM 启动参数

# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
  # 若为 Cygwin 系统
  [ -n "$M2_HOME" ] && M2_HOME=`cygpath --path --windows "$M2_HOME"`
  # 若 M2_HOME 不为空，将其转换为 Windows 路径格式
  [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
  # 若 JAVA_HOME 不为空，将其转换为 Windows 路径格式
  [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
  # 若 CLASSPATH 不为空，将其转换为 Windows 路径格式
  [ -n "$MAVEN_PROJECTBASEDIR" ] && MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
  # 若 MAVEN_PROJECTBASEDIR 不为空，将其转换为 Windows 路径格式
fi

# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
# 将 MAVEN_CONFIG 环境变量的值和传递给脚本的所有参数拼接，存储到 MAVEN_CMD_LINE_ARGS 变量，用于统一管理命令行参数
export MAVEN_CMD_LINE_ARGS
# 导出 MAVEN_CMD_LINE_ARGS 环境变量，以便后续使用

WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
# 设置 WRAPPER_LAUNCHER 为 Maven 包装器的主类，用于启动 Maven 包装器

exec "$JAVACMD" \
  # 使用 exec 命令执行 Java 命令，替换当前 shell 进程
  $MAVEN_OPTS \
  # 传递 MAVEN_OPTS 作为 Java 虚拟机的启动参数
  -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
  # 设置类路径为 maven-wrapper.jar 文件所在路径
  "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
  # 设置两个系统属性，分别指定 Maven 主目录和多模块项目目录
  ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
  # 执行 Maven 包装器主类，并传递 MAVEN_CONFIG 和所有命令行参数，正式启动 Maven 构建过程