Last active 4 days ago

reset_git_repos.sh Raw
1#!/bin/bash
2
3# 辅助函数,功能等同于 PowerShell 的 Clone-GitRepositories
4# $1: 包含仓库对象的 JSON 数组字符串
5# $2: 目标基础路径
6clone_git_repositories() {
7 local repos_json="$1"
8 local destination_path="$2"
9
10 # 使用 jq -c '.[]' 来迭代 JSON 数组中的每个对象
11 # 'while read -r repo' 逐行读取每个对象
12 echo "$repos_json" | jq -c '.[]' | while read -r repo; do
13 # 跳过被 archive 的仓库
14 local is_archived
15 is_archived=$(echo "$repo" | jq -r '.archived')
16 if [[ "$is_archived" == "true" ]]; then
17 local repo_name
18 repo_name=$(echo "$repo" | jq -r '.name')
19 echo "Skipping archived repository: $repo_name"
20 continue
21 fi
22
23 local repo_name
24 repo_name=$(echo "$repo" | jq -r '.name')
25 local repo_url
26 repo_url=$(echo "$repo" | jq -r '.ssh_url_to_repo')
27
28 # 判断 topics 是否存在且有内容,取出第一个 topic;否则使用 "no-topic"
29 local first_topic
30 local topics_count
31 topics_count=$(echo "$repo" | jq -r '.topics | length')
32
33 if [[ "$topics_count" -gt 0 ]]; then
34 first_topic=$(echo "$repo" | jq -r '.topics[0]')
35 else
36 first_topic="no-topic"
37 fi
38
39 # 构造最终的 clone 目标路径:$destination_path/$first_topic/$repo_name
40 local topic_path="$destination_path/$first_topic"
41
42 # 'mkdir -p' 会创建所有必需的父目录,且如果目录已存在也不会报错
43 # 这替代了 Test-Path 和 New-Item
44 mkdir -p "$topic_path"
45
46 local repo_path="$topic_path/$repo_name"
47
48 if [[ ! -d "$repo_path" ]]; then
49 git clone "$repo_url" "$repo_path"
50 echo "Cloned $repo_name to $repo_path"
51 else
52 echo "$repo_name already exists at $repo_path, skipping."
53 fi
54 done
55}
56
57# 主函数,功能等同于 PowerShell 的 Reset-GitRepos
58reset_git_repos() {
59 echo "Deleting items..."
60 # Bash 使用正斜杠 '/' 作为路径分隔符
61 # 'rm -rf' 强制递归删除,且在目录不存在时不报错,类似 -ErrorAction SilentlyContinue
62 rm -rf "$HOME/Source/Repos/Aiursoft"
63 rm -rf "$HOME/Source/Repos/Anduin"
64 echo "Items deleted!"
65
66 sleep 5
67
68 # Bash 中使用 echo -e 和 ANSI 转义序列来输出颜色
69 echo -e "\033[0;32mCloning all repos...\033[0m"
70 local gitlab_base_url="https://gitlab.aiursoft.cn"
71 local api_url="$gitlab_base_url/api/v4"
72 local group_name="Aiursoft"
73 local user_name="Anduin"
74
75 local destination_path_aiursoft="$HOME/Source/Repos/Aiursoft"
76 local destination_path_anduin="$HOME/Source/Repos/Anduin"
77
78 # 'mkdir -p' 替代 Test-Path 和 New-Item
79 mkdir -p "$destination_path_aiursoft"
80 mkdir -p "$destination_path_anduin"
81
82 # 使用 curl -s (silent) 获取数据,并通过 jq 解析
83 local group_url="$api_url/groups?search=$group_name"
84 local group_request
85 group_request=$(curl -s "$group_url")
86 local group_id
87 group_id=$(echo "$group_request" | jq -r '.[0].id')
88
89 local user_url="$api_url/users?username=$user_name"
90 local user_request
91 user_request=$(curl -s "$user_url")
92 local user_id
93 user_id=$(echo "$user_request" | jq -r '.[0].id')
94
95 local repo_url_aiursoft="$api_url/groups/$group_id/projects?simple=true&per_page=999&visibility=public&page=1"
96 local repo_url_anduin="$api_url/users/$user_id/projects?simple=true&per_page=999&visibility=public&page=1"
97
98 # 使用 curl 获取数据,并立即用 jq 过滤掉 archived 的仓库
99 # jq 'map(select(.archived != true))' 会过滤数组并返回一个新数组
100 # 注意:PowerShell 中的 Where-Object { $_.archived -ne $true } 在这里被 jq 的 'select' 实现了
101 local repos_aiursoft
102 repos_aiursoft=$(curl -s "$repo_url_aiursoft" | jq '[.[] | select(.archived != true)]')
103 local repos_anduin
104 repos_anduin=$(curl -s "$repo_url_anduin" | jq '[.[] | select(.archived != true)]')
105
106 # 调用辅助函数,传入 JSON 字符串和目标路径
107 clone_git_repositories "$repos_aiursoft" "$destination_path_aiursoft"
108 clone_git_repositories "$repos_anduin" "$destination_path_anduin"
109}
110
111# ---
112# 如果你想让这个脚本被执行时自动运行,请取消下面这行的注释:
113# reset_git_repos
114#
115# 如果你想像 'source' 一样导入这些函数,请保持原样。
116# ---