3 # Report packages installing same file and not marked with
4 # conflicts or replaces.
5 # Without argument, find conflicts between packages in local
6 # repository at hostdir/binpkgs and packages indexed in xlocate.
7 # With single path as argument, read that local repository.
8 # With -a flag, find conflicts between packages indexed in xlocate.
11 binpkgs
="$PWD/hostdir/binpkgs"
12 elif [ "$1" = -a ]; then
14 elif [ -d "$1" ]; then
19 echo " check packages in ./hostdir/binpkgs"
20 echo "$0 path/to/hostdir/binpkgs"
21 echo " check packages there"
23 echo " check all packages indexed in xlocate"
27 declare -A newly_built conflicts_cache providers_cache pairs owners
28 repositories
=("--repository=${binpkgs}/bootstrap" "--repository=${binpkgs}" "--repository=${binpkgs}/nonfree")
32 [ -f "srcpkgs/$1/template" ]
40 # print the pkgname and packages that `provides` it
42 if [ "${providers_cache[$pkgname]}" = '' ]; then
43 local line provider_pkgver provided_pkgver provider_pkgname provided_pkgname
45 providers
[$pkgname]=$pkgname
46 while read -r line
; do
48 provider_pkgver
=${line%': '*}
49 provided_pkgver
=${line#*': '}
50 provider_pkgname
=${provider_pkgver%-*}
51 provided_pkgname
=${provided_pkgver%-*}
52 # comes from $(xbps-query -s $pkgname), so $pkgname can be substring
53 if [ "$provided_pkgname" = "$pkgname" ]; then
54 providers
[$provider_pkgname]=$provider_pkgname
56 done < <(xbps-query
"${repositories[@]}" -p provides
-R -s "$pkgname")
57 # leading space ensures ${[]} != ''
58 providers_cache
[$pkgname]=" ${providers[*]}"
60 echo ${providers_cache[$pkgname]}
64 # print list of packages that are _marked_ as conflicting with given one
66 if [ "${conflicts_cache[$pkgname]}" = '' ]; then
67 local in_conflict provider
69 while read -r in_conflict
; do
70 in_conflict
=${in_conflict%'<'*}
71 in_conflict
=${in_conflict%'>'*}
72 providers_of
"$in_conflict" > /dev
/null
# executing in same process to fill cache
73 for provider
in $
(providers_of
"$in_conflict"); do
74 all
[$provider]=$provider
76 done < <(xbps-query
"${repositories[@]}" -p conflicts
,replaces
-R "$pkgname")
77 # leading space ensures ${[]} != ''
78 conflicts_cache
[$pkgname]=" ${all[*]}"
80 echo ${conflicts_cache[$pkgname]}
84 # exit successfully if packages are _marked_ as conflicting
85 conflicts_of
"$1" > /dev
/null
# executing in same process to fill cache
86 case " $(conflicts_of "$1") " in
89 conflicts_of
"$2" > /dev
/null
# executing in same process to fill cache
90 case " $(conflicts_of "$2") " in
96 list_newly_built_files
() {
97 # print one line per file in newly built packages
98 # each line contains pkgname and file path
100 while read -r pkgver
; do
102 xbps-query
"${repositories[@]}" -i -f "$pkgname" |
sed s
'/ -> .*//;'" s/^/$pkgname /"
103 done < <(xbps-query
"${repositories[@]}" -i -R -s '' | cut
-d' ' -f 2)
106 list_interesting_files
() {
107 # list files potentially contained in more than one package
108 # each line contains pkgver/pkgname and file path
109 if partial_check
; then
110 list_newly_built_files
112 xlocate
/ |
sed s
'/ -> .*//' |
grep -F -f <(xlocate
/ |
sed 's/[^[:space:]]*[[:space:]]*//' |
sed s
'/ -> .*//' |
sort |
uniq -d)
116 group_by_file_full
() {
117 # create associative array `owners` mapping file to list of packages
118 # for packages potentially conflicting with newly built ones
119 local pkgver
file pkgname
120 while read -r pkgver
file; do
122 if template_exists
"$pkgname"; then
123 owners
[$file]+=" $pkgname"
125 done < <(list_interesting_files
)
128 group_by_file_partial
() {
129 # create associative array `owners` mapping file to list of packages
130 # for all packages in xlocate
132 ## newly built packages
133 while read -r pkgver
; do
135 newly_built
[$pkgname]=$pkgname
136 done < <(xbps-query
"${repositories[@]}" -i -R -s '' | cut
-d' ' -f 2)
137 while read -r pkgname
file; do
138 owners
[$file]+=" $pkgname"
139 done < <(list_newly_built_files
)
140 ## rest of repository
141 while read -r pkgver
file; do
143 if [ -z "${newly_built[$pkgname]}" ] && template_exists
"$pkgname"; then
144 owners
[$file]+=" $pkgname"
146 done < <(xlocate
/ |
sed s
'/ -> .*//' |
grep -F -f <(list_newly_built_files | cut
-d ' ' -f 2-))
150 # find package pairs owning same file and not marked as conflicting
152 while read -r pkg
file; do
153 for a
in ${owners[$file]}; do
154 for b
in ${owners[$file]}; do
155 if ! [ "$a" "<" "$b" ]; then
158 if partial_check
&& [ -z "${newly_built[$a]}" ] && [ -z "${newly_built[$b]}" ]; then
161 if ! conflict_between
"$a" "$b"; then
164 eval "${pairs["$a $b"]}"
165 pair_files
[$file]="$file"
166 pairs
["$a $b"]="${pair_files[@]@A}"
170 done < <(list_interesting_files
)
175 if [ "${#pairs[@]}" = 0 ]; then
176 echo 1>&2 "No conflicts found in" "${repositories[@]#*=}"
179 while read -r pair
; do
181 echo "${pair% *} and ${pair#* } conflict for"
183 eval "${pairs[$pair]}"
184 for file in "${pair_files[@]}"; do
187 done < <(printf '%s\n' "${!pairs[@]}" |
sort)
190 if partial_check
; then
191 group_by_file_partial