代码拉取完成,页面将自动刷新
#!/usr/bin/env bash
# Copyright (c) 2024 maminjie <canpool@163.com>
# SPDX-License-Identifier: MulanPSL-2.0
CUR_DIR=$(pwd)
WORK_DIR="$CUR_DIR/oe_diff_workspace"
YUM_DIR="$WORK_DIR/yum"
YUM_CONFIG_FILE="$YUM_DIR/yum.conf"
RPM_DIR="$WORK_DIR/rpm"
A_REPOS=""
B_REPOS=""
HAS_DIST_FLAG=1
OUT_DIFF_FLAG=0
RPM_DOWNLOAD_FLAG=0
usage() {
printf "diff rpm packages between the two systems based on dnf repository
usage:
bash oe_diff.sh [-h] [-a REPOSITORY [-a ...]] [-b REPOSITORY [-b ...]] [-u] [-t]
optional arguments:
-a REPOSITORY A dnf repository address link (can be specified multiple times)
-b REPOSITORY B dnf repository address link (can be specified multiple times)
-u the flag that only output difference items
-t the flag that rpm name does not contain the dist suffix
-d the flag that download new rpm
-h show the help message and exit
examples:
bash oe_diff.sh -a A_ADDR -b B_ADDR
bash oe_diff.sh -a A_ADDR1 -a A_ADDR2 -b B_ADDR1 -b B_ADDR2
\n"
}
log_error() {
echo "ERROR: $1"
}
parse_cmdline() {
if [ $# -eq 0 ]; then
usage; exit 0
fi
# parse cmd line arguments
while getopts ":a:b:utdh" opt; do
case "$opt" in
a)
if [ -z "$A_REPOS" ]; then
A_REPOS="$OPTARG"
else
A_REPOS="$A_REPOS $OPTARG"
fi
;;
b)
if [ -z "$B_REPOS" ]; then
B_REPOS="$OPTARG"
else
B_REPOS="$B_REPOS $OPTARG"
fi
;;
u)
OUT_DIFF_FLAG=1
;;
t)
HAS_DIST_FLAG=0
;;
d)
RPM_DOWNLOAD_FLAG=1
;;
h)
usage; exit 0
;;
?)
echo "please check the params."; usage; return 1
;;
esac
done
if [[ -z "$A_REPOS" || -z "$B_REPOS" ]]; then
echo "invalid REPOSITORY arguments"; return 1
fi
return 0
}
check_requires() {
local ret=0
for c in repoquery rpmdev-vercmp yumdownloader; do
command -v $c >/dev/null
if [ $? -ne 0 ]; then
echo "command $c not found"
ret=1
fi
done
return $ret
}
clean() {
cd "$CUR_DIR" || :
[[ -d "${WORK_DIR}" ]] && rm -rf "${WORK_DIR}"
}
create_yum_repo() {
local yum_dir="$YUM_DIR"
local yum_config_file="$YUM_CONFIG_FILE"
local yum_repo_dir="${yum_dir}/yum.repos.d"
local yum_repo_file="${yum_repo_dir}/os.repo"
mkdir -p "$yum_repo_dir"
cat > "${yum_config_file}" <<EOF
[main]
gpgcheck=1
installonly_limit=3
clean_requirements_on_remove=True
best=True
skip_if_unavailable=False
reposdir=${yum_repo_dir}
EOF
local i=1
for repo in $A_REPOS; do
cat >> "${yum_repo_file}" <<EOF
[a_repo_$i]
name=a_repo_$i
baseurl=$repo
enabled=1
gpgcheck=0
EOF
((i++))
done
i=1
for repo in $B_REPOS; do
cat >> "${yum_repo_file}" <<EOF
[b_repo_$i]
name=b_repo_$i
baseurl=$repo
enabled=1
gpgcheck=0
EOF
((i++))
done
}
# get_repo_args repo_ids
get_repo_args() {
local repo_args=""
for r in $1; do
repo_args="$repo_args --repo $r"
done
echo "$repo_args"
}
# get_packages repo_ids
get_packages() {
local repo_ids="$1"
local repo_args=""
for r in $repo_ids; do
repo_args="$repo_args --repo $r"
done
repoquery -c "$YUM_CONFIG_FILE" -q --qf="%{name},%{epoch}:%{version}-%{release},%{arch}" --all --latest-limit=1 $repo_args
}
get_binary_packages() {
echo "$1" | grep -v ",src$" | grep -v "debuginfo," | grep -v "debugsource,"
}
get_source_packages() {
echo "$1" | grep ",src$"
}
get_debug_packages() {
echo "$1" | grep -E "(debuginfo|debugsource),"
}
# do_diff type a_pkgs b_pkgs
do_diff() {
# type,pkg_name,op,version_change,a_rpm_name,a_ver_full,b_rpm_name,b_ver_full
# equal updated degraded added removed unknown
local t=$1
local a_pkgs=($2)
local b_pkgs=($3)
local a_len=${#a_pkgs[@]}
local b_len=${#b_pkgs[@]}
local i=0 j=0
while true; do
local new_flag=0
local pkg_name=""
local item=""
if [ $i -lt $a_len ]; then
local a_pkg=${a_pkgs[$i]}
local a_name=${a_pkg%%,*}
local a_arch=${a_pkg##*,}
local a_ver_full=$(echo "$a_pkg" | cut -d , -f 2)
local a_ver_cmp=$a_ver_full
local a_epoch=${a_ver_full%%:*}
local a_ver_str=${a_ver_full##*:}
local a_ver=$a_ver_str
if [ $HAS_DIST_FLAG -eq 1 ]; then
a_ver=${a_ver_str%.*}
a_ver_cmp=${a_ver_full%.*}
fi
local a_rpm_name="$a_name-$a_ver_str.$a_arch.rpm"
pkg_name="$a_name"
if [ $j -lt $b_len ]; then
local b_pkg=${b_pkgs[$j]}
local b_name=${b_pkg%%,*}
local b_arch=${b_pkg##*,}
local b_ver_full=$(echo "$b_pkg" | cut -d , -f 2)
local b_ver_cmp=$b_ver_full
local b_epoch=${b_ver_full%%:*}
local b_ver_str=${b_ver_full##*:}
local b_ver=$b_ver_str
if [ $HAS_DIST_FLAG -eq 1 ]; then
b_ver=${b_ver_str%.*}
b_ver_cmp=${b_ver_full%.*}
fi
local b_rpm_name="$b_name-$b_ver_str.$b_arch.rpm"
if [[ "$a_name" = "$b_name" ]]; then
rpmdev-vercmp $a_ver_cmp $b_ver_cmp > /dev/null
local ret=$?
local op="unknown"
local ver_change="$a_ver -> $b_ver"
if [ $ret -eq 0 ]; then
op="equal"
ver_change="$a_ver"
elif [ $ret -eq 11 ]; then
# a is newer than b
op="degraded"
elif [ $ret -eq 12 ]; then
# a is older than b
op="updated"
new_flag=1
fi
((i++))
((j++))
if [[ $OUT_DIFF_FLAG -eq 1 && "$op" = "equal" ]]; then
continue
else
item="$t,$a_name,$op,$ver_change,$a_rpm_name,$a_ver_full,$b_rpm_name,$b_ver_full"
fi
elif [[ "$a_name" < "$b_name" ]]; then
item="$t,$a_name,removed,$a_ver,$a_rpm_name,$a_ver_full,,"
((i++))
else
new_flag=1
pkg_name="$b_name"
item="$t,$b_name,added,$b_ver,,,$b_rpm_name,$b_ver_full"
((j++))
fi
else
item="$t,$a_name,removed,$a_ver,$a_rpm_name,$a_ver_full,,"
((i++))
fi
else
if [ $j -lt $b_len ]; then
local b_pkg=${b_pkgs[$j]}
local b_name=${b_pkg%%,*}
local b_arch=${b_pkg##*,}
local b_ver_full=$(echo "$b_pkg" | cut -d , -f 2)
local b_epoch=${b_ver_full%%:*}
local b_ver_str=${b_ver_full##*:}
local b_ver=$b_ver_str
if [ $HAS_DIST_FLAG -eq 1 ]; then
b_ver=${b_ver_str%.*}
fi
local b_rpm_name="$b_name-$b_ver_str.$b_arch.rpm"
new_flag=1
pkg_name="$b_name"
item="$t,$b_name,,,added,$b_rpm_name,$b_ver_full,$b_ver"
((j++))
else
break
fi
fi
if [[ $RPM_DOWNLOAD_FLAG -eq 1 ]]; then
if [[ $new_flag -eq 1 && -n "$pkg_name" ]]; then
echo "$item" | tee -a "$WORK_DIR/diff.csv"
local rpm_list_file="$RPM_DIR/rpmlist.$t"
echo "$pkg_name" >> $rpm_list_file
fi
else
echo "$item"
fi
done
}
# download_rpm repo_ids
download_rpm() {
local types="binary source debug"
for t in $types; do
local rpm_list_file="$RPM_DIR/rpmlist.$t"
if [ -f "$rpm_list_file" ]; then
local rpm_dir="$RPM_DIR/$t"
local args=""
if [ "$t" = "source" ]; then
args="--source"
fi
mkdir -p $rpm_dir
yumdownloader -c "$YUM_CONFIG_FILE" $args --destdir $rpm_dir $(get_repo_args "$1") $(cat $rpm_list_file | tr '\n' ' ')
fi
done
}
do_main() {
clean
mkdir -p "$YUM_DIR"
if [ $RPM_DOWNLOAD_FLAG -eq 1 ]; then
mkdir -p "$RPM_DIR"
fi
create_yum_repo
local repo_ids=$(dnf repolist -c $YUM_CONFIG_FILE | grep -v "repo id" | awk '{print $1}')
local a_repos=$(echo "$repo_ids" | grep a_repo_)
local b_repos=$(echo "$repo_ids" | grep b_repo_)
local a_pkgs=$(get_packages "$a_repos")
local b_pkgs=$(get_packages "$b_repos")
echo "type,pkg_name,op,version_change,a_rpm_name,a_ver_full,b_rpm_name,b_ver_full"
local a_bin_pkgs=$(get_binary_packages "$a_pkgs")
local b_bin_pkgs=$(get_binary_packages "$b_pkgs")
do_diff "binary" "$a_bin_pkgs" "$b_bin_pkgs"
local a_src_pkgs=$(get_source_packages "$a_pkgs")
local b_src_pkgs=$(get_source_packages "$b_pkgs")
do_diff "source" "$a_src_pkgs" "$b_src_pkgs"
local a_dbg_pkgs=$(get_debug_packages "$a_pkgs")
local b_dbg_pkgs=$(get_debug_packages "$b_pkgs")
do_diff "debug" "$a_dbg_pkgs" "$b_dbg_pkgs"
if [ $RPM_DOWNLOAD_FLAG -eq 1 ]; then
download_rpm "$b_repos"
else
clean
fi
return 0
}
main() {
parse_cmdline "$@"
if [ $? -ne 0 ]; then
log_error "parse params failed, try -h for help"
return 1
fi
check_requires
if [ $? -ne 0 ]; then
log_error "check requires failed"
return 1
fi
do_main
if [ $? -ne 0 ]; then
return 1
fi
return 0
}
main "$@"
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。