blob: 8adf9774e9ef01e1cee148947327f1f97869d768 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
#!/usr/bin/env bash
# Return Submodule's Git Command
#
# $_extraArgs: extra args for git submodule update commandline
# $1: "init" or none
function echoGitCMDForSubModule {
local -A subParent
local gitCMDName='git '
for path in "${!subCommit[@]}"; do
configUrl="-c submodule.${subName[$path]}.url=\"\${srcdir}/${path//\//|}\" \\"
moduleParent=$path
while true; do
moduleParent=${moduleParent%\/*}
if [[ -f $gitRepo/$moduleParent/.gitmodules ]]; then
subParent[$moduleParent]+="$configUrl"$'\n'$(printf %"${#gitCMDName}"s); break
elif [[ $moduleParent == "${moduleParent%\/*}" ]]; then
subParent[.]+="$configUrl"$'\n'$(printf %"${#gitCMDName}"s); break
fi
done
done
count=1 && for parent in "${!subParent[@]}"; do
if [[ $1 == init ]]; then
echo -e "${gitCMDName}-C '$gitRepo/$parent' submodule init && \\"
fi
echo -en "${gitCMDName}${subParent[$parent]}-c protocol.file.allow=always -C '$gitRepo/$parent' submodule update ${_extraArgs}"
if [ "${#subParent[@]}" == "$count" ]; then echo; else echo " && \\"; fi
((count++))
done
}
declare subModuleSourceTextStart="# Auto generated by '${0##*/}', do not edit."
declare subModuleSourceTextEnd='# End'
# Return Submodule's Source Text
function echoSourceTextForSubModule {
sourceArrayName='source+=('
subModuleSourceText+="${subModuleSourceTextStart}"$'\n'"${sourceArrayName}"
count=1 && for path in "${!subCommit[@]}"; do
if [[ $path =~ ^(src|pkg|PKGBUILD|.SRCINFO)$ ]]; then
echo 'TODO: fix submodule that name as src,pkg,PKGBUILD or .SRCINFO.' && exit 1
fi
subModule="${path//\//|}::git+${subUrl[$path]}#commit=${subCommit[$path]}"
if [ "${#subCommit[@]}" == "$count" ]; then
subModuleSourceText+="'$subModule'"
else
subModuleSourceText+="'$subModule'"$'\n'$(printf %"${#sourceArrayName}"s)
fi
((count++))
done
subModuleSourceText+=") ${subModuleSourceTextEnd}"
echo "$subModuleSourceText"
}
# Update source array in PKGBUILD
#
# $1: [Path to PKGBUILD]
function updateBuildScriptForSubModule {
if buildScriptFile=$(readlink -se "$1"); then
buildScript=$(cat "$buildScriptFile" 2> /dev/null)
SourceText="$(echoSourceTextForSubModule)"
if [[ $buildScript != *$SourceText* ]]; then
sourceTextForSed=$(echo "$SourceText"|sed -ze 's&\n&\\n&g' -e 's&|&\\|&g')
sededbuildScript=$(echo "$buildScript" | sed -z "s|\n$subModuleSourceTextStart\nsource+=([^)]*) $subModuleSourceTextEnd\n|\n$sourceTextForSed|")
if [ "$buildScript" == "$sededbuildScript" ]; then
echo "$SourceText" >> "$buildScriptFile"
else
echo "$sededbuildScript" > "$buildScriptFile"
fi
# shellcheck disable=SC2181,SC2320
if [[ $? != 0 ]]; then
echo "Failed to update '$buildScriptFile'. The file has not been modified."
else
echo "The source of submodules in '$buildScriptFile' have been updated! Please update checksums, then do makepkg again."
fi && exit 2
else
echo "No update for Submodules, continue..." && exit 0
fi
else
echo "Failed to update '$buildScriptFile'. The file is not exist." && exit 1
fi
}
function printUsage {
cat <<-EOF
Update source array of Git submodules in PKGBUILD
Contain functions:
"echoSourceTextForSubModule": Echo source array of given Git repository
"echoGitCMDForSubModule": Echo Git command for PKGBUILD to change submodule's url
init: Whether to initialize the submodule, optional if you want to get the submodule of a submodule next time
force: Add '--force' parameter to command when update submodule
"updateBuildScriptForSubModule [Path to PKGBUILD]": Update source array and replace it in PKGBUILD
[Path to PKGBUILD]: The PKGBUILD that expected to be modified
example:
$ export _repo="[Path to Git repository]"
$ ${0##*/} echoSourceTextForSubModule
$ ${0##*/} echoGitCMDForSubModule init force
$ ${0##*/} updateBuildScriptForSubModule "[Path to PKGBUILD]"
EOF
}
declare -A subUrl
declare -A subName
declare -A subPath
declare -A subCommit
# Update arrays about Submodule
function readGitModules {
gitModules=$(git config -f "$gitRepo/.gitmodules" -l) || return 1
# Submodule's Commit Array
gitModulesStatus=$(git -C "$gitRepo" submodule status --recursive --cached) || return 1
IFS=$'\n' && for line in $gitModulesStatus; do
line=${line:1}; line=${line% (*)}
path=${line#* }
subCommit+=(["$path"]="${line% *}")
if [[ -f $gitRepo/$path/.gitmodules ]]; then
gitModules+=$'\n'$(git config -f "$gitRepo/$path/.gitmodules" -l | sed "s#.path=#.path=$path/#g") || return 1
fi
done && unset IFS
# Submodule's Path Array
IFS=$'\n' && for line in $gitModules; do
name=${line#submodule.}; name=${name%.*=*}
if [[ $line =~ .*.path=.* ]]; then
subName+=(["${line#*.path=}"]="$name") # So we can get name by path
subPath+=(["$name"]="${line#*.path=}")
fi
done && unset IFS
# Submodule's Url Array
IFS=$'\n' && for line in $gitModules; do
name=${line#submodule.}; name=${name%.*=*}
if [[ $line =~ .*.url=.* ]]; then
subUrl+=(["${subPath[$name]}"]="${line#*.url=}")
fi
done && unset IFS
# Only support 'path' and 'url'
}
if ! type git > /dev/null 2>&1; then
echo "This script needs \`git\` in order to work, aborting..." && exit 1
fi
gitRepo=${_repo:-$PWD}
if ! readGitModules; then
printUsage; echo "No submodule in '$gitRepo', aborting..."; exit 1
fi
case "$1" in
ForSource)
;;
echoGitCMDForSubModule)
for arg in "${@:2}"; do
case "$arg" in
'')
;;
force)
_extraArgs='--force'
;;
init)
_Args='init'
;;
*)
printUsage && exit 1
;;
esac
done
echoGitCMDForSubModule "$_Args"
;;
echoSourceTextForSubModule)
echoSourceTextForSubModule
;;
updateBuildScriptForSubModule)
updateBuildScriptForSubModule "${2:-$gitRepo/../../PKGBUILD}" # The path to PKGBUILD in most case
;;
*)
printUsage && exit 1
;;
esac
|