Also allow passing the repodata dir to repo2solv.sh.
[platform/upstream/libsolv.git] / tools / repo2solv.sh
1 #! /bin/sh
2 # repo2solv
3 #
4 # give it a directory of a local mirror of a repo and this
5 # tries to detect the repo type and generate one SOLV file on stdout
6
7 get_DESCRDIR () {
8   local d=$(grep '^DESCRDIR' content | sed 's/^DESCRDIR[[:space:]]\+\(.*[^[:space:]]\)[[:space:]]*$/\1/')
9   if  test -z "$d"; then
10     echo suse/setup/descr
11   else
12     echo ${d}
13   fi
14 }
15
16 test_susetags() {
17   if test -s content; then
18     DESCR=$(get_DESCRDIR)
19     test -d $DESCR
20     return $?
21   else
22     return 1
23   fi
24 }
25
26 repomd_findfile() {
27   local t=$1
28   local p=$2
29   local f
30   if test -n "$t" -a -s repomd.xml ; then
31     f=`repomdxml2solv -q $t:location < repomd.xml 2>/dev/null`
32     f=${f##*/}
33     if test -f "$f" ; then
34       echo "$f"
35       return
36     fi
37   fi
38   if test -f "$p.bz2" ; then
39     echo "$p.bz2"
40   elif test -f "$p.gz" ; then
41     echo "$p.gz"
42   elif test -f "$p" ; then
43     echo "$p"
44   fi
45 }
46
47 repomd_decompress() {
48   case $1 in
49    *.gz) gzip -dc "$1" ;;
50    *.bz2) bzip2 -dc "$1" ;;
51    *.lzma) lzma -dc "$1" ;;
52    *.xz) xz -dc "$1" ;;
53    *) cat "$1" ;;
54   esac
55 }
56
57 susetags_findfile_cat() {
58   if test -s "$1.xz" ; then
59     xz -dc "$1.xz"
60   elif test -s "$1.lzma" ; then
61     lzma -dc "$1.lzma"
62   elif test -s "$1.bz2" ; then
63     bzip2 -dc "$1.bz2"
64   elif test -s "$1.gz" ; then
65     gzip -dc "$1.gz"
66   elif test -s "$1" ; then
67     cat "$1"
68   fi
69 }
70
71 # signal an error if there is a problem
72 set -e
73
74 LANG=C
75 unset CDPATH
76 parser_options=${PARSER_OPTIONS:-}
77
78 findopt="-prune"
79 repotype=
80
81 while true ; do
82   if test "$1" = "-o" ; then
83     exec > "$2"
84     shift
85     shift
86   elif test "$1" = "-R" ; then
87     # recursive
88     findopt=
89     repotype=plaindir
90     shift
91   else
92     break
93   fi
94 done
95
96 dir="$1"
97 cd "$dir" || exit 1
98
99 if test -z "$repotype" ; then
100   # autodetect repository type
101   if test -d repodata -o -f repomd.xml; then
102     repotype=rpmmd
103   elif test_susetags ; then
104     repotype=susetags
105   else
106     repotype=plaindir
107   fi
108 fi
109
110 if test "$repotype" = rpmmd ; then
111   test -d repodata && {
112     cd repodata || exit 2
113   }
114
115   primfile=
116   primxml=`repomd_findfile primary primary.xml`
117   if test -n "$primxml" -a -s "$primxml" ; then
118     primfile=`mktemp` || exit 3
119     (
120      # fake tag to combine primary.xml and extensions
121      # like susedata.xml, other.xml, filelists.xml
122      echo '<rpmmd>'
123      if test -f $primxml ; then
124         repomd_decompress $primxml
125          # add a newline
126         echo
127      fi
128      susedataxml=`repomd_findfile susedata susedata.xml`
129      if test -f "$susedataxml" ; then
130         repomd_decompress "$susedataxml"
131      fi
132      echo '</rpmmd>'
133     ) | grep -v '\?xml' |  sed '1i\<?xml version="1.0" encoding="UTF-8"?>' | rpmmd2solv $parser_options > $primfile || exit 4
134   fi
135
136   prodfile=
137   prodxml=`repomd_findfile products products.xml`
138   if test -z "$prodxml" ; then
139     prodxml=`repomd_findfile product product.xml`
140   fi
141   if test -n "$prodxml" -a -s "$prodxml" ; then
142     prodfile=`mktemp` || exit 3
143     (
144      echo '<products>'
145      repomd_decompress "$prodxml"
146      echo '</products>'
147     ) | grep -v '\?xml' | rpmmd2solv $parser_options > $prodfile || exit 4
148   fi
149
150   patternfile=
151   patternxml=`repomd_findfile 'patterns' patterns.xml`
152   if test -n "$patternxml" -a -s "$patternxml" ; then
153       patternfile=`mktemp` || exit 3
154       repomd_decompress "$patternxml" | rpmmd2solv $parser_options > $patternfile || exit 4
155   fi
156
157   # This contains repomd.xml
158   # for now we only read some keys like timestamp
159   repomdfile=
160   repomdxml=`repomd_findfile '' repomd.xml`
161   if test -n "$repomdxml" -a -s "$repomdxml" ; then
162       repomdfile=`mktemp` || exit 3
163       repomd_decompress "$repomdxml" | repomdxml2solv $parser_options > $repomdfile || exit 4
164   fi
165
166   # This contains suseinfo.xml, which is an extension to repomd.xml
167   # for now we only read some keys like expiration and products
168   suseinfofile=
169   suseinfoxml=`repomd_findfile suseinfo suseinfo.xml`
170   if test -n "$suseinfoxml" -a -s "$suseinfoxml" ; then
171       suseinfofile=`mktemp` || exit 3
172       repomd_decompress "$suseinfoxml" | repomdxml2solv $parser_options > $suseinfofile || exit 4
173   fi
174
175   # This contains a updateinfo.xml* and maybe patches
176   updateinfofile=
177   updateinfoxml=`repomd_findfile updateinfo updateinfo.xml`
178   if test -n "$updateinfoxml" -a -s "$updateinfoxml" ; then
179       updateinfofile=`mktemp` || exit 3
180       repomd_decompress "$updateinfoxml" | updateinfoxml2solv $parser_options > $updateinfofile || exit 4
181   fi
182
183   # This contains a deltainfo.xml*
184   deltainfofile=
185   deltainfoxml=`repomd_findfile deltainfo deltainfo.xml`
186   if test -z "$deltainfoxml"; then 
187       deltainfoxml=`repomd_findfile prestodelta prestodelta.xml`
188   fi
189   if test -n "$deltainfoxml" -a -s "$deltainfoxml" ; then
190       deltainfofile=`mktemp` || exit 3
191       repomd_decompress "$deltainfoxml" | deltainfoxml2solv $parser_options > $deltainfofile || exit 4
192   fi
193
194   # Now merge primary, patches, updateinfo, and deltainfo
195   mergesolv $repomdfile $suseinfofile $primfile $prodfile $patternfile $updateinfofile $deltainfofile
196   rm -f $repomdfile $suseinfofile $primfile $patternfile $prodfile $updateinfofile $deltainfofile
197
198 elif test "$repotype" = susetags ; then
199   olddir=`pwd`
200   DESCR=$(get_DESCRDIR)
201   cd ${DESCR} || exit 2
202   (
203     # First packages
204     susetags_findfile_cat packages
205
206     # DU
207     susetags_findfile_cat packages.DU
208
209     # Now default language
210     susetags_findfile_cat packages.en
211
212     # Now patterns.  Not simply those files matching *.pat{,.gz,bz2},
213     # but only those mentioned in the file 'patterns'
214     if test -f patterns ; then
215       for i in `cat patterns`; do
216         if test -s "$i" ; then
217           repomd_decompress "$i"
218         fi
219       done
220     fi
221
222     # Now all other packages.{lang}.  Needs to come last as it switches
223     # languages for all following susetags files
224     for i in packages.* ; do
225       case $i in
226         *.gz|*.bz2|*.xz|*.lzma) name="${i%.*}" ;;
227         *) name="$i" ;;
228       esac
229       case $name in
230         # ignore files we handled already
231         *.DU | *.en | *.FL | packages ) continue ;;
232         *)
233           suff=${name#packages.}
234           echo "=Lan: $suff"
235           repomd_decompress "$i"
236       esac
237     done
238
239   ) | susetags2solv -c "${olddir}/content" $parser_options || exit 4
240   cd "$olddir"
241 elif test "$repotype" = plaindir ; then
242   find * -name .\* -prune -o $findopt -name \*.delta.rpm -o -name \*.patch.rpm -o -name \*.rpm -a -type f -print0 | rpms2solv -0 -m -
243 else
244   echo "unknown repository type '$repotype'" >&2
245   exit 1
246 fi