xref: /aosp_15_r20/development/build/tools/mk_sdk_repo_xml.sh (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
1*90c8c64dSAndroid Build Coastguard Worker#!/bin/bash
2*90c8c64dSAndroid Build Coastguard Worker#
3*90c8c64dSAndroid Build Coastguard Worker# Generates an SDK Repository XML based on the input files.
4*90c8c64dSAndroid Build Coastguard Worker
5*90c8c64dSAndroid Build Coastguard Workerset -e
6*90c8c64dSAndroid Build Coastguard Worker
7*90c8c64dSAndroid Build Coastguard WorkerPROG_DIR=$(dirname $0)
8*90c8c64dSAndroid Build Coastguard Worker
9*90c8c64dSAndroid Build Coastguard WorkerTYPES="tool platform-tool build-tool platform sample doc add-on system-image source"
10*90c8c64dSAndroid Build Coastguard WorkerOSES="linux macosx windows any linux-x86 darwin"
11*90c8c64dSAndroid Build Coastguard Worker
12*90c8c64dSAndroid Build Coastguard WorkerTMP_DIR=$(mktemp -d -t sdkrepo.tmp.XXXXXXXX)
13*90c8c64dSAndroid Build Coastguard Workertrap "rm -rf $TMP_DIR" EXIT
14*90c8c64dSAndroid Build Coastguard Worker
15*90c8c64dSAndroid Build Coastguard Workerfunction debug() {
16*90c8c64dSAndroid Build Coastguard Worker  echo "DEBUG: " $@ > /dev/stderr
17*90c8c64dSAndroid Build Coastguard Worker}
18*90c8c64dSAndroid Build Coastguard Worker
19*90c8c64dSAndroid Build Coastguard Workerfunction error() {
20*90c8c64dSAndroid Build Coastguard Worker  echo "*** ERROR: " $@
21*90c8c64dSAndroid Build Coastguard Worker  usage
22*90c8c64dSAndroid Build Coastguard Worker}
23*90c8c64dSAndroid Build Coastguard Worker
24*90c8c64dSAndroid Build Coastguard Workerfunction usage() {
25*90c8c64dSAndroid Build Coastguard Worker  cat <<EOFU
26*90c8c64dSAndroid Build Coastguard WorkerUsage: $0 output.xml xml-schema [type [os zip[:dest]]*...]*
27*90c8c64dSAndroid Build Coastguard Workerwhere:
28*90c8c64dSAndroid Build Coastguard Worker- schema is one of 'repository' or 'addon'
29*90c8c64dSAndroid Build Coastguard Worker- type is one of ${TYPES// /, } (or their plural).
30*90c8c64dSAndroid Build Coastguard Worker- os   is one of  ${OSES// /, }.
31*90c8c64dSAndroid Build Coastguard WorkerThere can be more than one zip for the same type
32*90c8c64dSAndroid Build Coastguard Workeras long as they use different OSes.
33*90c8c64dSAndroid Build Coastguard WorkerZip can be in the form "source:dest" to be renamed on the fly.
34*90c8c64dSAndroid Build Coastguard WorkerEOFU
35*90c8c64dSAndroid Build Coastguard Worker  exit 1
36*90c8c64dSAndroid Build Coastguard Worker}
37*90c8c64dSAndroid Build Coastguard Worker
38*90c8c64dSAndroid Build Coastguard Worker# Validate the tools we need
39*90c8c64dSAndroid Build Coastguard Workerif [[ ! -x $(which sha1sum) ]]; then
40*90c8c64dSAndroid Build Coastguard Worker  error "Missing tool: sha1sum (Linux: apt-get install coreutils; Mac: port install md5sha1sum)"
41*90c8c64dSAndroid Build Coastguard Workerfi
42*90c8c64dSAndroid Build Coastguard Worker
43*90c8c64dSAndroid Build Coastguard Workerif [[ -z "$XMLLINT" ]]; then
44*90c8c64dSAndroid Build Coastguard Worker  XMLLINT=xmllint
45*90c8c64dSAndroid Build Coastguard Workerfi
46*90c8c64dSAndroid Build Coastguard Worker
47*90c8c64dSAndroid Build Coastguard Worker# Parse input params
48*90c8c64dSAndroid Build Coastguard WorkerOUT="$1"
49*90c8c64dSAndroid Build Coastguard Worker[[ -z "$OUT" ]] && error "Missing output.xml name."
50*90c8c64dSAndroid Build Coastguard Workershift
51*90c8c64dSAndroid Build Coastguard Worker
52*90c8c64dSAndroid Build Coastguard Worker# Get the schema filename. E.g. ".../.../sdk-repository-10.xsd". Can be relative or absolute.
53*90c8c64dSAndroid Build Coastguard WorkerSCHEMA="$1"
54*90c8c64dSAndroid Build Coastguard Worker[[ ! -f "$SCHEMA" ]] && error "Invalid XML schema name: $SCHEMA."
55*90c8c64dSAndroid Build Coastguard Workershift
56*90c8c64dSAndroid Build Coastguard Worker
57*90c8c64dSAndroid Build Coastguard Worker# Get XML:NS for SDK from the schema
58*90c8c64dSAndroid Build Coastguard Worker# This will be something like "http://schemas.android.com/sdk/android/addon/3"
59*90c8c64dSAndroid Build Coastguard WorkerXMLNS=$(sed -n '/xmlns:sdk="/s/.*"\(.*\)".*/\1/p' "$SCHEMA")
60*90c8c64dSAndroid Build Coastguard Worker[[ -z "$XMLNS" ]] && error "Failed to find xmlns:sdk in $SCHEMA."
61*90c8c64dSAndroid Build Coastguard Worker#echo "## Using xmlns:sdk=$XMLNS"
62*90c8c64dSAndroid Build Coastguard Worker
63*90c8c64dSAndroid Build Coastguard Worker# Extract the schema version number from the XMLNS, e.g. it would extract "3"
64*90c8c64dSAndroid Build Coastguard WorkerXSD_VERSION="${XMLNS##*/}"
65*90c8c64dSAndroid Build Coastguard Worker
66*90c8c64dSAndroid Build Coastguard Worker# Get the root element from the schema. This is the first element
67*90c8c64dSAndroid Build Coastguard Worker# which name starts with "sdk-" (e.g. sdk-repository, sdk-addon)
68*90c8c64dSAndroid Build Coastguard WorkerROOT=$(sed -n -e '/xsd:element.*name="sdk-/s/.*name="\(sdk-[^"]*\)".*/\1/p' "$SCHEMA")
69*90c8c64dSAndroid Build Coastguard Worker[[ -z "$ROOT" ]] && error "Failed to find root element in $SCHEMA."
70*90c8c64dSAndroid Build Coastguard Worker#echo "## Using root element $ROOT"
71*90c8c64dSAndroid Build Coastguard Worker
72*90c8c64dSAndroid Build Coastguard Worker# Generate XML header
73*90c8c64dSAndroid Build Coastguard Workercat > "$OUT" <<EOFH
74*90c8c64dSAndroid Build Coastguard Worker<?xml version="1.0"?>
75*90c8c64dSAndroid Build Coastguard Worker<sdk:$ROOT
76*90c8c64dSAndroid Build Coastguard Worker    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
77*90c8c64dSAndroid Build Coastguard Worker    xmlns:sdk="$XMLNS">
78*90c8c64dSAndroid Build Coastguard WorkerEOFH
79*90c8c64dSAndroid Build Coastguard Worker
80*90c8c64dSAndroid Build Coastguard Worker# check_enum value value1 value2 value3...
81*90c8c64dSAndroid Build Coastguard Worker# returns valueN if matched or nothing.
82*90c8c64dSAndroid Build Coastguard Workerfunction check_enum() {
83*90c8c64dSAndroid Build Coastguard Worker  local VALUE="$1"
84*90c8c64dSAndroid Build Coastguard Worker  local i
85*90c8c64dSAndroid Build Coastguard Worker  shift
86*90c8c64dSAndroid Build Coastguard Worker  for i in "$@"; do
87*90c8c64dSAndroid Build Coastguard Worker    if [[ "$i" == "$VALUE" ]]; then
88*90c8c64dSAndroid Build Coastguard Worker      echo "$VALUE"
89*90c8c64dSAndroid Build Coastguard Worker      break;
90*90c8c64dSAndroid Build Coastguard Worker    fi
91*90c8c64dSAndroid Build Coastguard Worker  done
92*90c8c64dSAndroid Build Coastguard Worker}
93*90c8c64dSAndroid Build Coastguard Worker
94*90c8c64dSAndroid Build Coastguard Worker# Definition of the attributes we read from source.properties or manifest.ini
95*90c8c64dSAndroid Build Coastguard Worker# files and the equivalent XML element being generated.
96*90c8c64dSAndroid Build Coastguard Worker
97*90c8c64dSAndroid Build Coastguard WorkerATTRS=(
98*90c8c64dSAndroid Build Coastguard Worker  # Columns:
99*90c8c64dSAndroid Build Coastguard Worker  # --------------------------+------------------------+----------------------
100*90c8c64dSAndroid Build Coastguard Worker  # Name read from            | XML element written    | Min-XSD version
101*90c8c64dSAndroid Build Coastguard Worker  # source.properties         | to repository.xml      | where XML can be used
102*90c8c64dSAndroid Build Coastguard Worker  # --------------------------+------------------------+----------------------
103*90c8c64dSAndroid Build Coastguard Worker  # from source.properties for repository.xml packages
104*90c8c64dSAndroid Build Coastguard Worker  Pkg.Revision                  revision                 1
105*90c8c64dSAndroid Build Coastguard Worker  Pkg.Desc                      description              1
106*90c8c64dSAndroid Build Coastguard Worker  Platform.Version              version                  1
107*90c8c64dSAndroid Build Coastguard Worker  AndroidVersion.ApiLevel       api-level                1
108*90c8c64dSAndroid Build Coastguard Worker  AndroidVersion.CodeName       codename                 1
109*90c8c64dSAndroid Build Coastguard Worker  Platform.IncludedAbi          included-abi             5
110*90c8c64dSAndroid Build Coastguard Worker  Platform.MinToolsRev          min-tools-rev            1
111*90c8c64dSAndroid Build Coastguard Worker  Platform.MinPlatformToolsRev  min-platform-tools-rev   3
112*90c8c64dSAndroid Build Coastguard Worker  Sample.MinApiLevel            min-api-level            2
113*90c8c64dSAndroid Build Coastguard Worker  Layoutlib.Api                 layoutlib/api            4
114*90c8c64dSAndroid Build Coastguard Worker  Layoutlib.Revision            layoutlib/revision       4
115*90c8c64dSAndroid Build Coastguard Worker  # from source.properties for addon.xml packages
116*90c8c64dSAndroid Build Coastguard Worker  # (note that vendor is mapped to different XML elements based on the XSD version)
117*90c8c64dSAndroid Build Coastguard Worker  Extra.VendorDisplay           vendor-display           4
118*90c8c64dSAndroid Build Coastguard Worker  Extra.VendorId                vendor-id                4
119*90c8c64dSAndroid Build Coastguard Worker  Extra.Vendor                  vendor-id                4
120*90c8c64dSAndroid Build Coastguard Worker  Extra.Vendor                  vendor                   1
121*90c8c64dSAndroid Build Coastguard Worker  Extra.NameDisplay             name-display             4
122*90c8c64dSAndroid Build Coastguard Worker  Extra.Path                    path                     1
123*90c8c64dSAndroid Build Coastguard Worker  Extra.OldPaths                old-paths                3
124*90c8c64dSAndroid Build Coastguard Worker  Extra.MinApiLevel             min-api-level            2
125*90c8c64dSAndroid Build Coastguard Worker  # for system-image
126*90c8c64dSAndroid Build Coastguard Worker  SystemImage.Abi               abi                      r:3,s:1
127*90c8c64dSAndroid Build Coastguard Worker  SystemImage.TagId             tag-id                   r:9,s:2
128*90c8c64dSAndroid Build Coastguard Worker  SystemImage.TagDisplay        tag-display              r:9,s:2
129*90c8c64dSAndroid Build Coastguard Worker  Addon.VendorId                add-on/vendor-id         s:3
130*90c8c64dSAndroid Build Coastguard Worker  Addon.VendorDisplay           add-on/vendor-display    s:3
131*90c8c64dSAndroid Build Coastguard Worker  # from addon manifest.ini for addon.xml packages
132*90c8c64dSAndroid Build Coastguard Worker  # (note that vendor/name are mapped to different XML elements based on the XSD version)
133*90c8c64dSAndroid Build Coastguard Worker  vendor-id                     vendor-id                4
134*90c8c64dSAndroid Build Coastguard Worker  vendor-display                vendor-display           4
135*90c8c64dSAndroid Build Coastguard Worker  vendor                        vendor-display           4
136*90c8c64dSAndroid Build Coastguard Worker  vendor                        vendor                   1
137*90c8c64dSAndroid Build Coastguard Worker  name-id                       name-id                  4
138*90c8c64dSAndroid Build Coastguard Worker  name-display                  name-display             4
139*90c8c64dSAndroid Build Coastguard Worker  name                          name-display             4
140*90c8c64dSAndroid Build Coastguard Worker  name                          name                     1
141*90c8c64dSAndroid Build Coastguard Worker  description                   description              1
142*90c8c64dSAndroid Build Coastguard Worker  api                           api-level                1
143*90c8c64dSAndroid Build Coastguard Worker  version                       revision                 1
144*90c8c64dSAndroid Build Coastguard Worker  revision                      revision                 1
145*90c8c64dSAndroid Build Coastguard Worker)
146*90c8c64dSAndroid Build Coastguard Worker
147*90c8c64dSAndroid Build Coastguard Worker# Start with repo-10, addon-7 and sys-img-3, we don't encode the os/arch
148*90c8c64dSAndroid Build Coastguard Worker# in the <archive> attributes anymore. Instead we have separate elements.
149*90c8c64dSAndroid Build Coastguard Worker
150*90c8c64dSAndroid Build Coastguard Workerfunction uses_new_host_os() {
151*90c8c64dSAndroid Build Coastguard Worker  if [[ "$ROOT" == "sdk-repository" && "$XSD_VERSION" -ge "10" ]]; then return 0; fi
152*90c8c64dSAndroid Build Coastguard Worker  if [[ "$ROOT" == "sdk-addon"      && "$XSD_VERSION" -ge  "7" ]]; then return 0; fi
153*90c8c64dSAndroid Build Coastguard Worker  if [[ "$ROOT" == "sdk-sys-img"    && "$XSD_VERSION" -ge  "3" ]]; then return 0; fi
154*90c8c64dSAndroid Build Coastguard Worker  return 1
155*90c8c64dSAndroid Build Coastguard Worker}
156*90c8c64dSAndroid Build Coastguard Worker
157*90c8c64dSAndroid Build Coastguard WorkerATTRS_ARCHIVE=(
158*90c8c64dSAndroid Build Coastguard Worker  Archive.HostOs                host-os                   1
159*90c8c64dSAndroid Build Coastguard Worker  Archive.HostBits              host-bits                 1
160*90c8c64dSAndroid Build Coastguard Worker  Archive.JvmBits               jvm-bits                  1
161*90c8c64dSAndroid Build Coastguard Worker  Archive.MinJvmVers            min-jvm-version           1
162*90c8c64dSAndroid Build Coastguard Worker)
163*90c8c64dSAndroid Build Coastguard Worker
164*90c8c64dSAndroid Build Coastguard Worker
165*90c8c64dSAndroid Build Coastguard Worker# Starting with XSD repo-7 and addon-5, some revision elements are no longer just
166*90c8c64dSAndroid Build Coastguard Worker# integers. Instead they are in major.minor.micro.preview format. This defines
167*90c8c64dSAndroid Build Coastguard Worker# which elements. This depends on the XSD root element and the XSD version.
168*90c8c64dSAndroid Build Coastguard Worker#
169*90c8c64dSAndroid Build Coastguard Worker# Note: addon extra revision can't take a preview number. We don't enforce
170*90c8c64dSAndroid Build Coastguard Worker# this in this script. Instead schema validation will fail if the extra
171*90c8c64dSAndroid Build Coastguard Worker# source.property declares an RC and it gets inserted in the addon.xml here.
172*90c8c64dSAndroid Build Coastguard Worker
173*90c8c64dSAndroid Build Coastguard Workerif [[ "$ROOT" == "sdk-repository" && "$XSD_VERSION" -ge 7 ]] ||
174*90c8c64dSAndroid Build Coastguard Worker   [[ "$ROOT" == "sdk-addon"      && "$XSD_VERSION" -ge 5 ]]; then
175*90c8c64dSAndroid Build Coastguard WorkerFULL_REVISIONS=(
176*90c8c64dSAndroid Build Coastguard Worker  tool          revision
177*90c8c64dSAndroid Build Coastguard Worker  build-tool    revision
178*90c8c64dSAndroid Build Coastguard Worker  platform-tool revision
179*90c8c64dSAndroid Build Coastguard Worker  extra         revision
180*90c8c64dSAndroid Build Coastguard Worker  @             min-tools-rev
181*90c8c64dSAndroid Build Coastguard Worker  @             min-platform-tools-rev
182*90c8c64dSAndroid Build Coastguard Worker)
183*90c8c64dSAndroid Build Coastguard Workerelse
184*90c8c64dSAndroid Build Coastguard WorkerFULL_REVISIONS=()
185*90c8c64dSAndroid Build Coastguard Workerfi
186*90c8c64dSAndroid Build Coastguard Worker
187*90c8c64dSAndroid Build Coastguard Worker
188*90c8c64dSAndroid Build Coastguard Worker# Parse all archives.
189*90c8c64dSAndroid Build Coastguard Worker
190*90c8c64dSAndroid Build Coastguard Workerfunction needs_full_revision() {
191*90c8c64dSAndroid Build Coastguard Worker  local PARENT="$1"
192*90c8c64dSAndroid Build Coastguard Worker  local ELEMENT="$2"
193*90c8c64dSAndroid Build Coastguard Worker  shift
194*90c8c64dSAndroid Build Coastguard Worker  shift
195*90c8c64dSAndroid Build Coastguard Worker  local P E
196*90c8c64dSAndroid Build Coastguard Worker
197*90c8c64dSAndroid Build Coastguard Worker  while [[ "$1" ]]; do
198*90c8c64dSAndroid Build Coastguard Worker    P=$1
199*90c8c64dSAndroid Build Coastguard Worker    E=$2
200*90c8c64dSAndroid Build Coastguard Worker    if [[ "$E" == "$ELEMENT" ]] && [[ "$P" == "@" || "$P" == "$PARENT" ]]; then
201*90c8c64dSAndroid Build Coastguard Worker      return 0 # true
202*90c8c64dSAndroid Build Coastguard Worker    fi
203*90c8c64dSAndroid Build Coastguard Worker    shift
204*90c8c64dSAndroid Build Coastguard Worker    shift
205*90c8c64dSAndroid Build Coastguard Worker  done
206*90c8c64dSAndroid Build Coastguard Worker
207*90c8c64dSAndroid Build Coastguard Worker  return 1 # false
208*90c8c64dSAndroid Build Coastguard Worker}
209*90c8c64dSAndroid Build Coastguard Worker
210*90c8c64dSAndroid Build Coastguard Worker# Parses and print a full revision in the form "1.2.3 rc4".
211*90c8c64dSAndroid Build Coastguard Worker# Note that the format requires to have 1 space before the
212*90c8c64dSAndroid Build Coastguard Worker# optional "rc" (e.g. '1 rc4', not '1rc4') and no space after
213*90c8c64dSAndroid Build Coastguard Worker# the rc (so not '1 rc 4' either)
214*90c8c64dSAndroid Build Coastguard Workerfunction write_full_revision() {
215*90c8c64dSAndroid Build Coastguard Worker  local VALUE="$1"
216*90c8c64dSAndroid Build Coastguard Worker  local EXTRA_SPACE="$2"
217*90c8c64dSAndroid Build Coastguard Worker  local KEYS="major minor micro preview"
218*90c8c64dSAndroid Build Coastguard Worker  local V K
219*90c8c64dSAndroid Build Coastguard Worker
220*90c8c64dSAndroid Build Coastguard Worker  while [[ -n "$VALUE" && -n "$KEYS" ]]; do
221*90c8c64dSAndroid Build Coastguard Worker    # Take 1st segment delimited by . or space
222*90c8c64dSAndroid Build Coastguard Worker    V="${VALUE%%[. ]*}"
223*90c8c64dSAndroid Build Coastguard Worker
224*90c8c64dSAndroid Build Coastguard Worker    # Print it
225*90c8c64dSAndroid Build Coastguard Worker    if [[ "${V:0:2}" == "rc" ]]; then
226*90c8c64dSAndroid Build Coastguard Worker      V="${V:2}"
227*90c8c64dSAndroid Build Coastguard Worker      K="preview"
228*90c8c64dSAndroid Build Coastguard Worker      KEYS=""
229*90c8c64dSAndroid Build Coastguard Worker    else
230*90c8c64dSAndroid Build Coastguard Worker      K="${KEYS%% *}"
231*90c8c64dSAndroid Build Coastguard Worker    fi
232*90c8c64dSAndroid Build Coastguard Worker
233*90c8c64dSAndroid Build Coastguard Worker    if [[ -n "$V" && -n "$K" ]]; then
234*90c8c64dSAndroid Build Coastguard Worker        echo "$EXTRA_SPACE            <sdk:$K>$V</sdk:$K>"
235*90c8c64dSAndroid Build Coastguard Worker    fi
236*90c8c64dSAndroid Build Coastguard Worker
237*90c8c64dSAndroid Build Coastguard Worker    # Take the rest.
238*90c8c64dSAndroid Build Coastguard Worker    K="${KEYS#* }"
239*90c8c64dSAndroid Build Coastguard Worker    if [[ "$K" == "$KEYS" ]]; then KEYS=""; else KEYS="$K"; fi
240*90c8c64dSAndroid Build Coastguard Worker    V="${VALUE#*[. ]}"
241*90c8c64dSAndroid Build Coastguard Worker    if [[ "$V" == "$VALUE" ]]; then VALUE=""; else VALUE="$V"; fi
242*90c8c64dSAndroid Build Coastguard Worker  done
243*90c8c64dSAndroid Build Coastguard Worker}
244*90c8c64dSAndroid Build Coastguard Worker
245*90c8c64dSAndroid Build Coastguard Worker
246*90c8c64dSAndroid Build Coastguard Workerfunction parse_attributes() {
247*90c8c64dSAndroid Build Coastguard Worker  local PROPS="$1"
248*90c8c64dSAndroid Build Coastguard Worker  shift
249*90c8c64dSAndroid Build Coastguard Worker  local RESULT=""
250*90c8c64dSAndroid Build Coastguard Worker  local VALUE
251*90c8c64dSAndroid Build Coastguard Worker  local REV
252*90c8c64dSAndroid Build Coastguard Worker  local USED
253*90c8c64dSAndroid Build Coastguard Worker  local S
254*90c8c64dSAndroid Build Coastguard Worker
255*90c8c64dSAndroid Build Coastguard Worker  # Get the first letter of the schema name (e.g. sdk-repo => 'r')
256*90c8c64dSAndroid Build Coastguard Worker  # This can be r, a or s and would match the min-XSD per-schema value
257*90c8c64dSAndroid Build Coastguard Worker  # in the ATTRS list.
258*90c8c64dSAndroid Build Coastguard Worker  S=$(basename "$SCHEMA")
259*90c8c64dSAndroid Build Coastguard Worker  S="${S:4:1}"
260*90c8c64dSAndroid Build Coastguard Worker
261*90c8c64dSAndroid Build Coastguard Worker  # $1 here is the ATTRS list above.
262*90c8c64dSAndroid Build Coastguard Worker  while [[ "$1" ]]; do
263*90c8c64dSAndroid Build Coastguard Worker    # Check the version in which the attribute was introduced and
264*90c8c64dSAndroid Build Coastguard Worker    # ignore things which are too *new* for this schema. This lets
265*90c8c64dSAndroid Build Coastguard Worker    # us generate old schemas for backward compatibility purposes.
266*90c8c64dSAndroid Build Coastguard Worker    SRC=$1
267*90c8c64dSAndroid Build Coastguard Worker    DST=$2
268*90c8c64dSAndroid Build Coastguard Worker    REV=$3
269*90c8c64dSAndroid Build Coastguard Worker
270*90c8c64dSAndroid Build Coastguard Worker    if [[ $REV =~ ([ras0-9:,]+,)?$S:([0-9])(,.*)? ]]; then
271*90c8c64dSAndroid Build Coastguard Worker      # Per-schema type min-XSD revision. Format is "[<type>:rev],*]
272*90c8c64dSAndroid Build Coastguard Worker      # where type is one of r, a or s matching $S above.
273*90c8c64dSAndroid Build Coastguard Worker      REV="${BASH_REMATCH[2]}"
274*90c8c64dSAndroid Build Coastguard Worker    fi
275*90c8c64dSAndroid Build Coastguard Worker
276*90c8c64dSAndroid Build Coastguard Worker    if [[ ( $REV =~ ^[0-9]+ && $XSD_VERSION -ge $REV ) || $XSD_VERSION == $REV ]]; then
277*90c8c64dSAndroid Build Coastguard Worker      # Parse the property, if present. Any space is replaced by @
278*90c8c64dSAndroid Build Coastguard Worker      VALUE=$( grep "^$SRC=" "$PROPS" | cut -d = -f 2 | tr ' ' '@' | tr -d '\r' )
279*90c8c64dSAndroid Build Coastguard Worker      if [[ -n "$VALUE" ]]; then
280*90c8c64dSAndroid Build Coastguard Worker        # In case an XML element would be mapped multiple times,
281*90c8c64dSAndroid Build Coastguard Worker        # only use its first definition.
282*90c8c64dSAndroid Build Coastguard Worker        if [[ "${USED/$DST/}" == "$USED" ]]; then
283*90c8c64dSAndroid Build Coastguard Worker          USED="$USED $DST"
284*90c8c64dSAndroid Build Coastguard Worker          RESULT="$RESULT $DST $VALUE"
285*90c8c64dSAndroid Build Coastguard Worker        fi
286*90c8c64dSAndroid Build Coastguard Worker      fi
287*90c8c64dSAndroid Build Coastguard Worker    fi
288*90c8c64dSAndroid Build Coastguard Worker    shift
289*90c8c64dSAndroid Build Coastguard Worker    shift
290*90c8c64dSAndroid Build Coastguard Worker    shift
291*90c8c64dSAndroid Build Coastguard Worker  done
292*90c8c64dSAndroid Build Coastguard Worker
293*90c8c64dSAndroid Build Coastguard Worker  echo "$RESULT"
294*90c8c64dSAndroid Build Coastguard Worker}
295*90c8c64dSAndroid Build Coastguard Worker
296*90c8c64dSAndroid Build Coastguard Workerfunction output_attributes() {
297*90c8c64dSAndroid Build Coastguard Worker  local ELEMENT="$1"
298*90c8c64dSAndroid Build Coastguard Worker  local OUT="$2"
299*90c8c64dSAndroid Build Coastguard Worker  shift
300*90c8c64dSAndroid Build Coastguard Worker  shift
301*90c8c64dSAndroid Build Coastguard Worker  local KEY VALUE
302*90c8c64dSAndroid Build Coastguard Worker  local NODE LAST_NODE EXTRA_SPACE
303*90c8c64dSAndroid Build Coastguard Worker
304*90c8c64dSAndroid Build Coastguard Worker  while [[ "$1" ]]; do
305*90c8c64dSAndroid Build Coastguard Worker    KEY="$1"
306*90c8c64dSAndroid Build Coastguard Worker    VALUE="${2//@/ }"
307*90c8c64dSAndroid Build Coastguard Worker    NODE="${KEY%%/*}"
308*90c8c64dSAndroid Build Coastguard Worker    KEY="${KEY##*/}"
309*90c8c64dSAndroid Build Coastguard Worker    if [[ "$NODE" == "$KEY" ]]; then
310*90c8c64dSAndroid Build Coastguard Worker      NODE=""
311*90c8c64dSAndroid Build Coastguard Worker      EXTRA_SPACE=""
312*90c8c64dSAndroid Build Coastguard Worker    fi
313*90c8c64dSAndroid Build Coastguard Worker    if [[ "$NODE" != "$LAST_NODE" ]]; then
314*90c8c64dSAndroid Build Coastguard Worker      EXTRA_SPACE="    "
315*90c8c64dSAndroid Build Coastguard Worker      [[ "$LAST_NODE" ]] && echo "          </sdk:$LAST_NODE>" >> "$OUT"
316*90c8c64dSAndroid Build Coastguard Worker      LAST_NODE="$NODE"
317*90c8c64dSAndroid Build Coastguard Worker      [[ "$NODE"      ]] && echo "          <sdk:$NODE>" >> "$OUT"
318*90c8c64dSAndroid Build Coastguard Worker    fi
319*90c8c64dSAndroid Build Coastguard Worker    if needs_full_revision "$ELEMENT" "$KEY" ${FULL_REVISIONS[@]}; then
320*90c8c64dSAndroid Build Coastguard Worker      echo "$EXTRA_SPACE        <sdk:$KEY>"       >> "$OUT"
321*90c8c64dSAndroid Build Coastguard Worker      write_full_revision "$VALUE" "$EXTRA_SPACE" >> "$OUT"
322*90c8c64dSAndroid Build Coastguard Worker      echo "$EXTRA_SPACE        </sdk:$KEY>"      >> "$OUT"
323*90c8c64dSAndroid Build Coastguard Worker    else
324*90c8c64dSAndroid Build Coastguard Worker      echo "$EXTRA_SPACE        <sdk:$KEY>$VALUE</sdk:$KEY>" >> "$OUT"
325*90c8c64dSAndroid Build Coastguard Worker    fi
326*90c8c64dSAndroid Build Coastguard Worker    shift
327*90c8c64dSAndroid Build Coastguard Worker    shift
328*90c8c64dSAndroid Build Coastguard Worker  done
329*90c8c64dSAndroid Build Coastguard Worker  if [[ "$LAST_NODE" ]]; then echo "          </sdk:$LAST_NODE>" >> "$OUT"; fi
330*90c8c64dSAndroid Build Coastguard Worker}
331*90c8c64dSAndroid Build Coastguard Worker
332*90c8c64dSAndroid Build Coastguard Workerwhile [[ -n "$1" ]]; do
333*90c8c64dSAndroid Build Coastguard Worker  # Process archives.
334*90c8c64dSAndroid Build Coastguard Worker  # First we expect a type. For convenience the type can be plural.
335*90c8c64dSAndroid Build Coastguard Worker  TYPE=$(check_enum "${1%%s}" $TYPES)
336*90c8c64dSAndroid Build Coastguard Worker  [[ -z $TYPE ]] && error "Unknown archive type '$1'."
337*90c8c64dSAndroid Build Coastguard Worker  shift
338*90c8c64dSAndroid Build Coastguard Worker
339*90c8c64dSAndroid Build Coastguard Worker  ELEMENT="$TYPE"
340*90c8c64dSAndroid Build Coastguard Worker
341*90c8c64dSAndroid Build Coastguard Worker  MAP=""
342*90c8c64dSAndroid Build Coastguard Worker  FIRST="1"
343*90c8c64dSAndroid Build Coastguard Worker  LIBS_XML=""
344*90c8c64dSAndroid Build Coastguard Worker
345*90c8c64dSAndroid Build Coastguard Worker  OS=$(check_enum "$1" $OSES)
346*90c8c64dSAndroid Build Coastguard Worker  while [[ $OS ]]; do
347*90c8c64dSAndroid Build Coastguard Worker    shift
348*90c8c64dSAndroid Build Coastguard Worker    [[ $OS == "linux-x86" ]] && OS=linux
349*90c8c64dSAndroid Build Coastguard Worker    [[ $OS == "darwin" ]] && OS=macosx
350*90c8c64dSAndroid Build Coastguard Worker
351*90c8c64dSAndroid Build Coastguard Worker    SRC="$1"
352*90c8c64dSAndroid Build Coastguard Worker    DST="$1"
353*90c8c64dSAndroid Build Coastguard Worker    if [[ "${SRC/:/}" != "$SRC" ]]; then
354*90c8c64dSAndroid Build Coastguard Worker      DST="${SRC/*:/}"
355*90c8c64dSAndroid Build Coastguard Worker      SRC="${SRC/:*/}"
356*90c8c64dSAndroid Build Coastguard Worker    fi
357*90c8c64dSAndroid Build Coastguard Worker    [[ ! -f "$SRC" ]] && error "Missing file for archive $TYPE/$OS: $SRC"
358*90c8c64dSAndroid Build Coastguard Worker    shift
359*90c8c64dSAndroid Build Coastguard Worker
360*90c8c64dSAndroid Build Coastguard Worker    # Depending on the archive type, we need a number of attributes
361*90c8c64dSAndroid Build Coastguard Worker    # from the source.properties or the manifest.ini. We'll take
362*90c8c64dSAndroid Build Coastguard Worker    # these attributes from the first zip found.
363*90c8c64dSAndroid Build Coastguard Worker    #
364*90c8c64dSAndroid Build Coastguard Worker    # What we need vs. which package uses it:
365*90c8c64dSAndroid Build Coastguard Worker    # - description             all
366*90c8c64dSAndroid Build Coastguard Worker    # - revision                all
367*90c8c64dSAndroid Build Coastguard Worker    # - version                 platform
368*90c8c64dSAndroid Build Coastguard Worker    # - included-abi            platform
369*90c8c64dSAndroid Build Coastguard Worker    # - api-level               platform sample doc add-on system-image
370*90c8c64dSAndroid Build Coastguard Worker    # - codename                platform sample doc add-on system-image
371*90c8c64dSAndroid Build Coastguard Worker    # - min-tools-rev           platform sample
372*90c8c64dSAndroid Build Coastguard Worker    # - min-platform-tools-rev  tool
373*90c8c64dSAndroid Build Coastguard Worker    # - min-api-level           extra
374*90c8c64dSAndroid Build Coastguard Worker    # - vendor                  extra               add-on
375*90c8c64dSAndroid Build Coastguard Worker    # - path                    extra
376*90c8c64dSAndroid Build Coastguard Worker    # - old-paths               extra
377*90c8c64dSAndroid Build Coastguard Worker    # - abi                     system-image
378*90c8c64dSAndroid Build Coastguard Worker    #
379*90c8c64dSAndroid Build Coastguard Worker    # We don't actually validate here.
380*90c8c64dSAndroid Build Coastguard Worker    # Just take whatever is defined and put it in the XML.
381*90c8c64dSAndroid Build Coastguard Worker    # XML validation against the schema will be done at the end.
382*90c8c64dSAndroid Build Coastguard Worker
383*90c8c64dSAndroid Build Coastguard Worker    if [[ $FIRST ]]; then
384*90c8c64dSAndroid Build Coastguard Worker      FIRST=""
385*90c8c64dSAndroid Build Coastguard Worker
386*90c8c64dSAndroid Build Coastguard Worker      if unzip -l "$SRC" | grep -qs "source.properties" ; then
387*90c8c64dSAndroid Build Coastguard Worker        # Extract Source Properties
388*90c8c64dSAndroid Build Coastguard Worker        # unzip: -j=flat (no dirs), -q=quiet, -o=overwrite, -d=dest dir
389*90c8c64dSAndroid Build Coastguard Worker        unzip -j -q -o -d "$TMP_DIR" "$SRC" "*/source.properties"
390*90c8c64dSAndroid Build Coastguard Worker        PROPS="$TMP_DIR/source.properties"
391*90c8c64dSAndroid Build Coastguard Worker
392*90c8c64dSAndroid Build Coastguard Worker      elif unzip -l "$SRC" | grep -qs "manifest.ini" ; then
393*90c8c64dSAndroid Build Coastguard Worker        unzip -j -q -o -d "$TMP_DIR" "$SRC" "*/manifest.ini"
394*90c8c64dSAndroid Build Coastguard Worker        PROPS="$TMP_DIR/manifest.ini"
395*90c8c64dSAndroid Build Coastguard Worker
396*90c8c64dSAndroid Build Coastguard Worker        # Parse the libs for an addon and generate the <libs> node
397*90c8c64dSAndroid Build Coastguard Worker        # libraries is a semi-colon separated list
398*90c8c64dSAndroid Build Coastguard Worker        LIBS=$(parse_attributes "$PROPS" "libraries")
399*90c8c64dSAndroid Build Coastguard Worker        LIBS_XML="        <sdk:libs>"
400*90c8c64dSAndroid Build Coastguard Worker        for LIB in ${LIBS//;/ }; do
401*90c8c64dSAndroid Build Coastguard Worker          LIBS_XML="$LIBS_XML
402*90c8c64dSAndroid Build Coastguard Worker           <sdk:lib><sdk:name>$LIB</sdk:name></sdk:lib>"
403*90c8c64dSAndroid Build Coastguard Worker        done
404*90c8c64dSAndroid Build Coastguard Worker        LIBS_XML="$LIBS_XML
405*90c8c64dSAndroid Build Coastguard Worker        </sdk:libs>"
406*90c8c64dSAndroid Build Coastguard Worker
407*90c8c64dSAndroid Build Coastguard Worker      else
408*90c8c64dSAndroid Build Coastguard Worker        error "Failed to find source.properties or manifest.ini in $SRC"
409*90c8c64dSAndroid Build Coastguard Worker      fi
410*90c8c64dSAndroid Build Coastguard Worker
411*90c8c64dSAndroid Build Coastguard Worker      [[ ! -f $PROPS ]] && error "Failed to extract $PROPS from $SRC"
412*90c8c64dSAndroid Build Coastguard Worker      MAP=$(parse_attributes "$PROPS" ${ATTRS[@]})
413*90c8c64dSAndroid Build Coastguard Worker
414*90c8c64dSAndroid Build Coastguard Worker      # Time to generate the XML for the package
415*90c8c64dSAndroid Build Coastguard Worker      echo "    <sdk:${ELEMENT}>" >> "$OUT"
416*90c8c64dSAndroid Build Coastguard Worker      output_attributes "$ELEMENT" "$OUT" $MAP
417*90c8c64dSAndroid Build Coastguard Worker      [[ -n "$LIBS_XML" ]] && echo "$LIBS_XML" >> "$OUT"
418*90c8c64dSAndroid Build Coastguard Worker      echo "        <sdk:archives>" >> "$OUT"
419*90c8c64dSAndroid Build Coastguard Worker    fi
420*90c8c64dSAndroid Build Coastguard Worker
421*90c8c64dSAndroid Build Coastguard Worker    # Generate archive info
422*90c8c64dSAndroid Build Coastguard Worker    #echo "## Add $TYPE/$OS archive $SRC"
423*90c8c64dSAndroid Build Coastguard Worker    SIZE=$( stat -c %s "$SRC" )
424*90c8c64dSAndroid Build Coastguard Worker    SHA1=$( sha1sum "$SRC" | cut -d " "  -f 1 )
425*90c8c64dSAndroid Build Coastguard Worker
426*90c8c64dSAndroid Build Coastguard Worker    if uses_new_host_os ; then
427*90c8c64dSAndroid Build Coastguard Worker      USE_HOST_OS=1
428*90c8c64dSAndroid Build Coastguard Worker    else
429*90c8c64dSAndroid Build Coastguard Worker      OLD_OS_ATTR=" os='$OS'"
430*90c8c64dSAndroid Build Coastguard Worker    fi
431*90c8c64dSAndroid Build Coastguard Worker
432*90c8c64dSAndroid Build Coastguard Worker    cat >> "$OUT" <<EOFA
433*90c8c64dSAndroid Build Coastguard Worker            <sdk:archive$OLD_OS_ATTR>
434*90c8c64dSAndroid Build Coastguard Worker                <sdk:size>$SIZE</sdk:size>
435*90c8c64dSAndroid Build Coastguard Worker                <sdk:checksum type='sha1'>$SHA1</sdk:checksum>
436*90c8c64dSAndroid Build Coastguard Worker                <sdk:url>$DST</sdk:url>
437*90c8c64dSAndroid Build Coastguard WorkerEOFA
438*90c8c64dSAndroid Build Coastguard Worker    if [[ $USE_HOST_OS ]]; then
439*90c8c64dSAndroid Build Coastguard Worker      # parse the Archive.Host/Jvm info from the source.props if present
440*90c8c64dSAndroid Build Coastguard Worker      MAP=$(parse_attributes "$PROPS" ${ATTRS_ARCHIVE[@]})
441*90c8c64dSAndroid Build Coastguard Worker      # Always generate host-os if not present
442*90c8c64dSAndroid Build Coastguard Worker      if [[ "${MAP/ host-os /}" == "$MAP" ]]; then
443*90c8c64dSAndroid Build Coastguard Worker        MAP="$MAP host-os $OS"
444*90c8c64dSAndroid Build Coastguard Worker      fi
445*90c8c64dSAndroid Build Coastguard Worker      output_attributes "archive" "$OUT" $MAP
446*90c8c64dSAndroid Build Coastguard Worker    fi
447*90c8c64dSAndroid Build Coastguard Worker    echo "            </sdk:archive>" >> "$OUT"
448*90c8c64dSAndroid Build Coastguard Worker
449*90c8c64dSAndroid Build Coastguard Worker    # Skip to next arch/zip entry.
450*90c8c64dSAndroid Build Coastguard Worker    # If not a valid OS, close the archives/package nodes.
451*90c8c64dSAndroid Build Coastguard Worker    OS=$(check_enum "$1" $OSES)
452*90c8c64dSAndroid Build Coastguard Worker
453*90c8c64dSAndroid Build Coastguard Worker    if [[ ! "$OS" ]]; then
454*90c8c64dSAndroid Build Coastguard Worker      echo "        </sdk:archives>" >> "$OUT"
455*90c8c64dSAndroid Build Coastguard Worker      echo "    </sdk:${ELEMENT}>" >> "$OUT"
456*90c8c64dSAndroid Build Coastguard Worker    fi
457*90c8c64dSAndroid Build Coastguard Worker  done
458*90c8c64dSAndroid Build Coastguard Worker
459*90c8c64dSAndroid Build Coastguard Workerdone
460*90c8c64dSAndroid Build Coastguard Worker
461*90c8c64dSAndroid Build Coastguard Worker# Generate XML footer
462*90c8c64dSAndroid Build Coastguard Workerecho "</sdk:$ROOT>" >> "$OUT"
463*90c8c64dSAndroid Build Coastguard Worker
464*90c8c64dSAndroid Build Coastguard Worker#echo "## Validate XML against schema"
465*90c8c64dSAndroid Build Coastguard Worker$XMLLINT --noout --schema $SCHEMA "$OUT"
466