Last active 5 days ago

anduin's Avatar anduin revised this gist 5 days ago. Go to revision

1 file changed, 116 insertions

reset_git_repos.sh(file created)

@@ -0,0 +1,116 @@
1 + #!/bin/bash
2 +
3 + # 辅助函数,功能等同于 PowerShell 的 Clone-GitRepositories
4 + # $1: 包含仓库对象的 JSON 数组字符串
5 + # $2: 目标基础路径
6 + clone_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
58 + reset_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 + # ---
Newer Older