mirror of
https://gitee.com/zoujingli/ThinkAdmin.git
synced 2026-06-07 12:38:11 +08:00
fix: 修改脚本文件
This commit is contained in:
parent
70cc9c4f29
commit
10418015ca
38
.github/workflows/release.yml
vendored
38
.github/workflows/release.yml
vendored
@ -16,16 +16,32 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Find last tag
|
||||
id: last_tag
|
||||
run: echo "::set-output name=tag::$(git describe --tags --abbrev=0 || echo 'v0.0.0')"
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- name: Get second latest tag
|
||||
id: second_tag
|
||||
- name: Install dependencies
|
||||
run: npm install -g gen-git-log
|
||||
|
||||
- name: Find Last Tag
|
||||
id: last_tag
|
||||
run: |
|
||||
|
||||
Tags=$(git tag --list --sort=-version:refname)
|
||||
|
||||
# 获取倒数第一个标签
|
||||
FRIEST_LATEST_TAG=$(echo "$Tags" | awk 'NR==1 {print $1; exit}')
|
||||
|
||||
# 获取倒数第二个标签
|
||||
SECOND_LATEST_TAG=$(git tag --list --sort=-version:refname | awk 'NR==2 {print $1; exit}')
|
||||
SECOND_LATEST_TAG=$(echo "$Tags" | awk 'NR==1 {print $2; exit}')
|
||||
|
||||
# 如果没有倒数第一个标签,则输出为空字符串
|
||||
if [[ -z "$FRIEST_LATEST_TAG" ]]; then
|
||||
echo "::set-output name=tag_last::v1.0.0"
|
||||
else
|
||||
echo "::set-output name=tag_last::$FRIEST_LATEST_TAG"
|
||||
fi
|
||||
|
||||
# 如果没有倒数第二个标签,则输出为空字符串
|
||||
if [[ -z "$SECOND_LATEST_TAG" ]]; then
|
||||
@ -35,7 +51,9 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Generate Release Notes
|
||||
run: ./bin/genlog.sh -m tag -f ${{ steps.second_tag.outputs.tag_cmd }} -v ${{ steps.last_tag.outputs.tag }}
|
||||
run: |
|
||||
newTag=${{ steps.last_tag.outputs.tag_last }}
|
||||
git-log -m tag -f ${{ steps.last_tag.outputs.tag_cmd }} -v ${newTag#1}
|
||||
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
@ -43,8 +61,8 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ steps.last_tag.outputs.tag }}
|
||||
release_name: Release ${{ steps.last_tag.outputs.tag }}
|
||||
body_path: log/${{steps.last_tag.outputs.tag}}.md
|
||||
tag_name: ${{ steps.last_tag.outputs.tag_last }}
|
||||
release_name: Release ${{ steps.last_tag.outputs.tag_last }}
|
||||
body_path: log/${{steps.last_tag.outputs.tag_last}}.md
|
||||
draft: false
|
||||
prerelease: false
|
||||
529
bin/genlog.sh
529
bin/genlog.sh
@ -1,529 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# commit 类型 键
|
||||
TYPE_MAP=(feat fix refactor style docs chore build ci pref test)
|
||||
# commit 类型 值
|
||||
TYPE_TITLE_MAP=(新增 修改 重构 样式 文档 其他 构建 持续集成 优化 测试)
|
||||
# 当前日期+时间
|
||||
NOW=$(date "+%F %H:%M")
|
||||
# 起始日期
|
||||
SINCE="last.Monday"
|
||||
# 终止日期
|
||||
UNTIL=$(date +%F)
|
||||
# 是否覆盖文件,默认否
|
||||
FOUCE=0
|
||||
# 首行是否为生成日期,默认否
|
||||
PRINT_TIME=0
|
||||
# 输出目录
|
||||
OUTPUT_DIR="log"
|
||||
# 是否已设置作者, 默认否
|
||||
HAS_SET_AUTHOR=0
|
||||
|
||||
# function,去除字符串两头空格
|
||||
trim() {
|
||||
trimmed=$1
|
||||
# https://blog.csdn.net/dongwuming/article/details/50605911
|
||||
# 从变量$string的结尾, 删除最长匹配$substring的子串
|
||||
trimmed=${trimmed%% }
|
||||
# 从变量$string的开头, 删除最长匹配$substring的子串
|
||||
trimmed=${trimmed## }
|
||||
# TODO 首部空格无法全部移除
|
||||
trimmed=${trimmed## }
|
||||
echo $trimmed
|
||||
# 移除全部空格
|
||||
# echo ${trimmed// /}
|
||||
}
|
||||
|
||||
# function,是否应该强制生成文件
|
||||
shouldFouceResolve() {
|
||||
# 输出文件已存在 & 不强制生成 则提示并退出
|
||||
if [ -e $OUTPUT -a $FOUCE -eq 0 ]; then
|
||||
echo "${OUTPUT} already exists! \n
|
||||
Please update package.json or remove log file or add '-f' follow the command!\n
|
||||
"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
# function,首行是否应该输出生成日期
|
||||
shouldPrintTime() {
|
||||
if [ $PRINT_TIME -eq 1 ]; then
|
||||
echo "> Generated on ${NOW} By [Gen-Git-Log](https://www.npmjs.com/package/gen-git-log)\n"
|
||||
|
||||
case $MODE in
|
||||
branch)
|
||||
# 分支模式
|
||||
TITLE="${TARGET}...${SOURCE}"
|
||||
;;
|
||||
tag)
|
||||
# 标签模式
|
||||
TITLE="${TARGET}...$(getVersion)"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ ! -z $TITLE ]; then
|
||||
# 如果TITLE赋值则组装输出
|
||||
TITLE="## [${TITLE}](${REMOTE}/compare/${TITLE})"
|
||||
echo $TITLE
|
||||
fi
|
||||
fi
|
||||
}
|
||||
# function,获取版本
|
||||
getVersion() {
|
||||
# 判断是否自定义版本
|
||||
if [ -z $VERSION ]; then
|
||||
# 未传入版本
|
||||
VERSION=v1.0.0
|
||||
fi
|
||||
trim $VERSION
|
||||
}
|
||||
# function,生成输出文件路径
|
||||
generateOutPutPath() {
|
||||
# 输出文件路径,默认“v版本.md”
|
||||
echo "${OUTPUT_DIR}/$(getVersion).md"
|
||||
}
|
||||
# 生成指定SOURCE TARGET tag差异记录
|
||||
genSingleTagLog() {
|
||||
SOU=$1
|
||||
TAR=$2
|
||||
|
||||
if [ ! "$3"x = "0"x ]; then
|
||||
if [ $SOU = HEAD ]; then
|
||||
# 如果是与最新HEAD对比则将HEAD设为version
|
||||
TIT="## [$(getVersion)](${REMOTE}/compare/${TAR}...$(getVersion))"
|
||||
else
|
||||
TIT="## [${SOU}](${REMOTE}/compare/${TAR}...${SOU})"
|
||||
fi
|
||||
echo
|
||||
echo
|
||||
echo "${TIT} ($(git -C "${REPO}" log -1 --format=%ad --date=short $SOU))"
|
||||
fi
|
||||
|
||||
# 直接使用分支比对查找所有匹配 log
|
||||
GIT_PAGER=$(git -C "${REPO}" log --no-merges --reverse --format="${LOG_FORMAT}" "$SOU...$TAR")
|
||||
|
||||
if [ ! -z "$GIT_PAGER" ]; then
|
||||
# 字符串分隔符
|
||||
IFS="*"
|
||||
# 分割字符串为数组
|
||||
singleTagArr=($GIT_PAGER)
|
||||
# 还原分割符,否则会导致if判断失效
|
||||
IFS=""
|
||||
# 循环处理数组
|
||||
for s in ${singleTagArr[@]}; do
|
||||
# 去除字符串两头空格
|
||||
s=$(trim $s)
|
||||
# 判断字符串非空
|
||||
if [ ! -z $s ]; then
|
||||
# 替换全角冒号
|
||||
s=${s/:/:}
|
||||
# 循环commit 类型
|
||||
for type in ${TYPE_MAP[@]}; do
|
||||
# 组织正则
|
||||
reg="${type}:"
|
||||
# 判断commit类型
|
||||
if [[ ${s} == *"${reg}"* ]]; then
|
||||
# 裁剪字符串
|
||||
s=${s##*${reg}}
|
||||
s=${s%@*}
|
||||
# 移除空格
|
||||
s=$(trim $s)
|
||||
# 动态数组变量赋值
|
||||
eval COMMIT_${type}='(${COMMIT_'${type}'[*]} $s)'
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
# 处理数据
|
||||
typeIndex=0
|
||||
for type in ${TYPE_MAP[@]}; do
|
||||
# 拷贝数组
|
||||
eval type='(${COMMIT_'${type}'[*]})'
|
||||
|
||||
# 判断数组是否含有元素
|
||||
if [ ${#type[*]} != 0 ]; then
|
||||
echo "#### ${TYPE_TITLE_MAP[$typeIndex]}"
|
||||
|
||||
for i in ${type[@]}; do
|
||||
echo "* ${i}"
|
||||
done
|
||||
echo
|
||||
fi
|
||||
let typeIndex++
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# 生成tag
|
||||
genTagLog() {
|
||||
LOG_FORMAT="$FORMAT_DEFAULT @%ae"
|
||||
|
||||
OUTPUT=$(generateOutPutPath)
|
||||
|
||||
shouldFouceResolve
|
||||
|
||||
# 获取最新标签
|
||||
LASTEST_TAG=$(git -C "${REPO}" describe --tags $(git -C "${REPO}" rev-list --tags --max-count=1))
|
||||
|
||||
if [ -z $SOURCE ]; then
|
||||
SOURCE="HEAD"
|
||||
fi
|
||||
if [ -z $TARGET ]; then
|
||||
TARGET=$LASTEST_TAG
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
copy)
|
||||
# 如果传参为 copy 则将结果输出至剪切板
|
||||
genSingleTagLog $SOURCE $TARGET 0 | pbcopy
|
||||
;;
|
||||
release-note)
|
||||
# 如果传参为 release-note 则将结果直接输出
|
||||
genSingleTagLog $SOURCE master 0
|
||||
;;
|
||||
*)
|
||||
(
|
||||
shouldPrintTime
|
||||
genSingleTagLog $SOURCE $TARGET 0
|
||||
) >$OUTPUT
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 传参覆盖默认值
|
||||
while getopts "m:a:s:u:S:T:r:v:ftd:h" arg; do
|
||||
case $arg in
|
||||
m)
|
||||
# 模式
|
||||
MODE=$OPTARG
|
||||
;;
|
||||
a)
|
||||
# 作者
|
||||
AUTHOR=$OPTARG
|
||||
# 已设置作者
|
||||
HAS_SET_AUTHOR=1
|
||||
;;
|
||||
s)
|
||||
# 起始日期
|
||||
SINCE=$OPTARG
|
||||
;;
|
||||
u)
|
||||
# 终止日期
|
||||
UNTIL=$OPTARG
|
||||
;;
|
||||
S)
|
||||
# 源分支/标签
|
||||
SOURCE=$OPTARG
|
||||
;;
|
||||
T)
|
||||
# 目标分支/标签
|
||||
TARGET=$OPTARG
|
||||
;;
|
||||
r)
|
||||
# Git 仓库本地路径
|
||||
REPO=$OPTARG
|
||||
;;
|
||||
v)
|
||||
# 自定义版本
|
||||
VERSION=$OPTARG
|
||||
;;
|
||||
f)
|
||||
# 强制覆盖文件
|
||||
FOUCE=1
|
||||
;;
|
||||
t)
|
||||
# 首行输出生成日期
|
||||
PRINT_TIME=1
|
||||
;;
|
||||
d)
|
||||
# 输出目录路径
|
||||
OUTPUT_DIR=$OPTARG
|
||||
;;
|
||||
h)
|
||||
echo "
|
||||
Usage:\n
|
||||
git-log [options]\n
|
||||
|
||||
Options:\n
|
||||
-m 生成模式 默认:无(周报),可选:branch(分支比对)、tag(标签比对)、changelog(汇总日志)
|
||||
-a 想要过滤的作者 默认:$(git config user.name)
|
||||
-s 起始日期 默认:上周一,格式:2018-01-01
|
||||
-u 终止日期 默认:当天,格式:2018-01-01
|
||||
-S 源分支/标签 默认:无,比对模式:当前分支/最近标签
|
||||
-T 目标分支/标签 默认:无,比对模式:当前分支/当前HEAD
|
||||
-r Git 仓库本地路径 默认:当前目录
|
||||
-v 版本号 默认:无,比对模式:仓库路径下 package.json 中 VERSION 字段值
|
||||
-f 覆盖文件 默认:否,不需要传值
|
||||
-t log 首行为生成日期 默认:否,不需要传值
|
||||
-d log 输出目录 默认:仓库路径下 log 文件夹
|
||||
"
|
||||
exit 2
|
||||
;;
|
||||
?)
|
||||
echo "unknown argument"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 判断是否需要设置默认作者
|
||||
if [ $HAS_SET_AUTHOR -eq 0 ]; then
|
||||
# 没有设置过则使用默认作者
|
||||
AUTHOR=$(git -C "${REPO}" config user.name)
|
||||
fi
|
||||
|
||||
# 获取远程仓库地址
|
||||
REMOTE=$(git -C "${REPO}" remote -v)
|
||||
REMOTE=${REMOTE#*git@}
|
||||
if [ ${REMOTE:0:6}x = "origin"x ]; then
|
||||
# 如果是origin开头认为是http(s)协议checkout下来的,否则是ssh
|
||||
REMOTE=${REMOTE#*origin}
|
||||
REMOTE=${REMOTE%%.git *}
|
||||
else
|
||||
REMOTE=${REMOTE%%.git *}
|
||||
REMOTE="http://${REMOTE/://}"
|
||||
fi
|
||||
|
||||
REMOTE=$(trim $REMOTE)
|
||||
# 格式化 https://ruby-china.org/topics/939
|
||||
# %H: commit hash
|
||||
# %h: 短commit hash
|
||||
# %an: 提交人名字
|
||||
# %ae: 提交人邮箱
|
||||
# %cr: 提交日期, 相对格式(1 day ago)
|
||||
# %d: ref名称
|
||||
# %s: commit信息标题
|
||||
# %cd: 提交日期 (--date= 制定的格式)
|
||||
FORMAT_DEFAULT=" * %s ([%h](${REMOTE}/commit/%H)) "
|
||||
|
||||
# 判断是否指定仓库路径重写输出目录路径
|
||||
if [ -z $REPO ]; then
|
||||
OUTPUT_DIR="./${OUTPUT_DIR}"
|
||||
else
|
||||
OUTPUT_DIR="${REPO}/${OUTPUT_DIR}"
|
||||
fi
|
||||
|
||||
# 指定目录路径不存在则创建
|
||||
if [ ! -e $OUTPUT_DIR ]; then
|
||||
mkdir $OUTPUT_DIR
|
||||
fi
|
||||
|
||||
# 判断提交人,设定输出路径
|
||||
if [ -z $AUTHOR ]; then
|
||||
# 提交人为空
|
||||
LOG_FORMAT="$FORMAT_DEFAULT <%an>"
|
||||
|
||||
# 输出文件路径,默认“当前日期.md”
|
||||
OUTPUT="${OUTPUT_DIR}/$(date +%F).md"
|
||||
else
|
||||
# 有提交人
|
||||
LOG_FORMAT="$FORMAT_DEFAULT - %cr"
|
||||
|
||||
# 输出文件路径,默认“提交人名.md”
|
||||
OUTPUT="${OUTPUT_DIR}/${AUTHOR}.md"
|
||||
fi
|
||||
|
||||
# 默认分支为当前分支
|
||||
CURRENT_BRANCH=$(git -C "${REPO}" rev-parse --abbrev-ref HEAD)
|
||||
|
||||
case $MODE in
|
||||
branch)
|
||||
LOG_FORMAT="$FORMAT_DEFAULT @%ae"
|
||||
|
||||
OUTPUT=$(generateOutPutPath)
|
||||
|
||||
shouldFouceResolve
|
||||
|
||||
if [ -z $SOURCE ]; then
|
||||
SOURCE=$CURRENT_BRANCH
|
||||
fi
|
||||
if [ -z $TARGET ]; then
|
||||
TARGET=$CURRENT_BRANCH
|
||||
fi
|
||||
|
||||
# 直接使用分支比对查找所有匹配 log
|
||||
GIT_PAGER=$(git -C "${REPO}" log "$SOURCE...$TARGET" --no-merges --reverse --format="${LOG_FORMAT}")
|
||||
|
||||
(
|
||||
shouldPrintTime
|
||||
|
||||
if [ ! -z "$GIT_PAGER" ]; then
|
||||
# 字符串分隔符
|
||||
IFS="*"
|
||||
# 分割字符串为数组
|
||||
arr=($GIT_PAGER)
|
||||
# 还原分割符,否则会导致if判断失效
|
||||
IFS=""
|
||||
# 循环处理数组
|
||||
for s in ${arr[@]}; do
|
||||
# 去除字符串两头空格
|
||||
s=$(trim $s)
|
||||
# 判断字符串非空
|
||||
if [ ! -z $s ]; then
|
||||
# 替换全角冒号
|
||||
s=${s/:/:}
|
||||
# 循环commit 类型
|
||||
for type in ${TYPE_MAP[@]}; do
|
||||
# 组织正则
|
||||
reg="${type}:"
|
||||
# 判断commit类型
|
||||
if [[ ${s} == *"${reg}"* ]]; then
|
||||
# 裁剪字符串
|
||||
s=${s##*${reg}}
|
||||
s=${s%@*}
|
||||
# 移除空格
|
||||
s=$(trim $s)
|
||||
# 动态数组变量赋值
|
||||
eval COMMIT_${type}='(${COMMIT_'${type}'[*]} $s)'
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
done
|
||||
|
||||
# 处理数据
|
||||
typeIndex=0
|
||||
for type in ${TYPE_MAP[@]}; do
|
||||
# 拷贝数组
|
||||
eval type='(${COMMIT_'${type}'[*]})'
|
||||
|
||||
# 判断数组是否含有元素
|
||||
if [ ${#type[*]} != 0 ]; then
|
||||
echo "#### ${TYPE_TITLE_MAP[$typeIndex]}"
|
||||
|
||||
for i in ${type[@]}; do
|
||||
echo "* ${i}"
|
||||
done
|
||||
echo
|
||||
fi
|
||||
let typeIndex++
|
||||
done
|
||||
else
|
||||
echo "${SOURCE}...${TARGET} 分支无差异"
|
||||
fi
|
||||
) >$OUTPUT
|
||||
;;
|
||||
tag)
|
||||
genTagLog
|
||||
;;
|
||||
changelog)
|
||||
if [ -z $REPO ]; then
|
||||
OUTPUT="./CHANGELOG.md"
|
||||
else
|
||||
OUTPUT="${REPO}/CHANGELOG.md"
|
||||
fi
|
||||
|
||||
LOG_FORMAT="$FORMAT_DEFAULT @%ae"
|
||||
|
||||
shouldFouceResolve
|
||||
|
||||
# 标签列表
|
||||
TAG_LIST=$(git -C "${REPO}" tag)
|
||||
|
||||
# 字符串分隔符
|
||||
IFS="v"
|
||||
# 分割字符串为数组
|
||||
arr=($TAG_LIST)
|
||||
# 还原分割符,否则会导致if判断失效
|
||||
IFS=""
|
||||
# 第一次提交commit, 取duan hash
|
||||
LAST_TAG=$(git -C "${REPO}" rev-list --reverse HEAD | head -1)
|
||||
LAST_TAG=${LAST_TAG:0:6}
|
||||
FIRST_TAG="HEAD"
|
||||
|
||||
len=$((${#arr[@]} - 1))
|
||||
|
||||
(
|
||||
# 循环处理数组
|
||||
for ((i = $len; i > 0; i--)); do
|
||||
s=${arr[$i]}
|
||||
# 去除字符串两头空格
|
||||
s=v$(trim $s)
|
||||
# 判断字符串非空
|
||||
if [ ! -z $s ]; then
|
||||
# 不知道为什么一定要缓存一下,否则$s值错乱
|
||||
TEMP=$s
|
||||
echo $(genSingleTagLog $FIRST_TAG $s)
|
||||
FIRST_TAG=$TEMP
|
||||
fi
|
||||
done
|
||||
|
||||
genSingleTagLog $FIRST_TAG $LAST_TAG
|
||||
) >$OUTPUT
|
||||
;;
|
||||
publish)
|
||||
# 发布模式
|
||||
# 站在要发布分支上
|
||||
# 同步代码
|
||||
# 修改version
|
||||
# 执行该命令
|
||||
# 根据版本号生成log文件
|
||||
genTagLog
|
||||
# 添加所有文件到暂存区
|
||||
git -C "${REPO}" add --all
|
||||
# 生成commit
|
||||
git -C "${REPO}" commit -m "chore: publish version $(getVersion)"
|
||||
|
||||
# ***********目前大部分项目不允许使用命令行操作master代码,以下代码暂时废弃************** #
|
||||
# 用户确认目标分支 https://ask.helplib.com/bash/post_113951
|
||||
# BRANCH="master"
|
||||
# read -p"Target branch: master. (y: confirm; n: enter the target branch; c: cancel) " -n 1 -r
|
||||
# echo "\n"
|
||||
|
||||
# case $REPLY in
|
||||
# y)
|
||||
# ;;
|
||||
# n)
|
||||
# read -p"Please enter the target branch (For example, master): " -r
|
||||
# BRANCH=$REPLY
|
||||
# ;;
|
||||
# *)
|
||||
# echo "canceled"
|
||||
# exit 5
|
||||
# ;;
|
||||
# esac
|
||||
# 切到branch
|
||||
# git -C "${REPO}" checkout $BRANCH
|
||||
# 合并分支到branch
|
||||
# git -C "${REPO}" merge $CURRENT_BRANCH
|
||||
# 生成tag
|
||||
# git -C "${REPO}" tag -a "$(getVersion)" -m ""
|
||||
# 推送tag
|
||||
# git -C "${REPO}" push origin --tags
|
||||
# 推送代码
|
||||
git -C "${REPO}" push origin
|
||||
# 复制release note到剪切板
|
||||
pbcopy <$OUTPUT
|
||||
# 完成
|
||||
echo "Push success, Release note has been copied!"
|
||||
;;
|
||||
copy)
|
||||
genTagLog "copy"
|
||||
echo "Log has been copied to the clipboard"
|
||||
exit 6
|
||||
;;
|
||||
release-note)
|
||||
genTagLog "release-note"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
shouldFouceResolve
|
||||
|
||||
(
|
||||
shouldPrintTime
|
||||
# 先根据起始及终止时间查找符合条件的log并且把日期格式化后输出
|
||||
# 之后遍历所有输出的日期,在根据日期查询当天内的log进行打印
|
||||
git -C "${REPO}" log --since="${SINCE}" --until="${UNTIL}" --format="%cd" --date=short | sort -u | while read DATE; do
|
||||
GIT_PAGER=$(git -C "${REPO}" log --no-merges --reverse --format="${LOG_FORMAT}" --since="${DATE} 00:00:00" --until="${DATE} 23:59:59" --author="${AUTHOR}")
|
||||
if [ ! -z "$GIT_PAGER" ]; then
|
||||
echo "[${DATE}]"
|
||||
echo "${GIT_PAGER}"
|
||||
echo
|
||||
fi
|
||||
done
|
||||
) >$OUTPUT
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Log has been written to '${OUTPUT}'"
|
||||
Loading…
x
Reference in New Issue
Block a user