chiark / gitweb /
Merge branch 'ndk' into 'master'
authorHans-Christoph Steiner <hans@eds.org>
Tue, 4 Jul 2017 12:34:42 +0000 (14:34 +0200)
committerHans-Christoph Steiner <hans@eds.org>
Tue, 4 Jul 2017 12:34:42 +0000 (14:34 +0200)
NDK r14b and r15b

See merge request !293

14 files changed:
buildserver/provision-apt-get-install
fdroidserver/build.py
fdroidserver/common.py
fdroidserver/metadata.py
fdroidserver/rewritemeta.py
fdroidserver/update.py
setup.py
tests/extra/convert_metadata_to_yaml_then_txt.sh [new file with mode: 0755]
tests/metadata-rewrite-yml/app.with.special.build.params.yml [new file with mode: 0644]
tests/metadata-rewrite-yml/fake.ota.update.yml [new file with mode: 0644]
tests/metadata-rewrite-yml/org.fdroid.fdroid.yml [new file with mode: 0644]
tests/metadata.TestCase
tests/metadata/app.with.special.build.params.txt [new file with mode: 0644]
tests/metadata/org.fdroid.fdroid.txt [new file with mode: 0644]

index c11d996b741492a5c68abde4f08f9dcfb3fb2e4f..a1b0f4b1e705eaa5a37c3c3da777dce914dc2a27 100644 (file)
@@ -91,6 +91,7 @@ packages="
  python3-pyasn1-modules
  python3-requests
  python3-yaml
+ python3-ruamel.yaml
  qt5-default
  qtbase5-dev
  quilt
index 1cfc7ff5055db82c7634e14f78b45da58cfc15b0..21e4fce2734b8cf964cd525f73e01fafdc5e99ab 100644 (file)
@@ -136,8 +136,8 @@ def build_server(app, build, vcs, build_dir, output_dir, log_dir, force):
         ftp.mkdir('metadata')
         ftp.mkdir('srclibs')
         ftp.chdir('metadata')
-        ftp.put(os.path.join('metadata', app.id + '.txt'),
-                app.id + '.txt')
+        ftp.put(app.metadatapath, os.path.basename(app.metadatapath))
+
         # And patches if there are any...
         if os.path.exists(os.path.join('metadata', app.id)):
             send_dir(os.path.join('metadata', app.id))
index f84ea0f1a6aaf9261fc4321b07b15fd0a23f00cb..c8fdaad529de3f49e1d9bb12b00d649a2da40583 100644 (file)
@@ -398,8 +398,8 @@ def get_local_metadata_files():
 
 def read_pkg_args(args, allow_vercodes=False):
     """
-    Given the arguments in the form of multiple appid:[vc] strings, this returns
-    a dictionary with the set of vercodes specified for each package.
+    :param args: arguments in the form of multiple appid:[vc] strings
+    :returns: a dictionary with the set of vercodes specified for each package
     """
 
     vercodes = {}
index 0c9d4831c596078ba24aee2fe1061d60a416ad6c..ac97edf3aeac9b8447fa091e82d87ea2057ababd 100644 (file)
@@ -25,7 +25,6 @@ import html
 import logging
 import textwrap
 import io
-
 import yaml
 # use libyaml if it is available
 try:
@@ -49,7 +48,7 @@ def warn_or_exception(value):
     elif warnings_action == 'error':
         raise MetaDataException(value)
     else:
-        logging.warn(value)
+        logging.warning(value)
 
 
 # To filter which ones should be written to the metadata files if
@@ -179,6 +178,7 @@ TYPE_SCRIPT = 5
 TYPE_MULTILINE = 6
 TYPE_BUILD = 7
 TYPE_BUILD_V2 = 8
+TYPE_INT = 9
 
 fieldtypes = {
     'Description': TYPE_MULTILINE,
@@ -318,6 +318,7 @@ class Build(dict):
 
 
 flagtypes = {
+    'versionCode': TYPE_INT,
     'extlibs': TYPE_LIST,
     'srclibs': TYPE_LIST,
     'patch': TYPE_LIST,
@@ -810,6 +811,12 @@ def post_metadata_parse(app):
         if type(v) in (float, int):
             app[k] = str(v)
 
+    if 'Builds' in app:
+        app['builds'] = app.pop('Builds')
+
+    if 'flavours' in app and app['flavours'] == [True]:
+        app['flavours'] = 'yes'
+
     if isinstance(app.Categories, str):
         app.Categories = [app.Categories]
     elif app.Categories is None:
@@ -817,22 +824,49 @@ def post_metadata_parse(app):
     else:
         app.Categories = [str(i) for i in app.Categories]
 
+    def _yaml_bool_unmapable(v):
+        return v in (True, False, [True], [False])
+
+    def _yaml_bool_unmap(v):
+        if v is True:
+            return 'yes'
+        elif v is False:
+            return 'no'
+        elif v == [True]:
+            return ['yes']
+        elif v == [False]:
+            return ['no']
+
+    _bool_allowed = ('disable', 'kivy', 'maven', 'buildozer')
+
     builds = []
     if 'builds' in app:
         for build in app['builds']:
             if not isinstance(build, Build):
                 build = Build(build)
             for k, v in build.items():
-                if flagtype(k) == TYPE_LIST:
-                    if isinstance(v, str):
-                        build[k] = [v]
-                    elif isinstance(v, bool):
-                        if v:
-                            build[k] = ['yes']
+                if not (v is None):
+                    if flagtype(k) == TYPE_LIST:
+                        if _yaml_bool_unmapable(v):
+                            build[k] = _yaml_bool_unmap(v)
+
+                        if isinstance(v, str):
+                            build[k] = [v]
+                        elif isinstance(v, bool):
+                            if v:
+                                build[k] = ['yes']
+                            else:
+                                build[k] = []
+                    elif flagtype(k) is TYPE_INT:
+                        build[k] = str(v)
+                    elif flagtype(k) is TYPE_STRING:
+                        if isinstance(v, bool) and k in _bool_allowed:
+                            build[k] = v
                         else:
-                            build[k] = []
-                elif flagtype(k) == TYPE_STRING and type(v) in (float, int):
-                    build[k] = str(v)
+                            if _yaml_bool_unmapable(v):
+                                build[k] = _yaml_bool_unmap(v)
+                            else:
+                                build[k] = str(v)
             builds.append(build)
 
     app.builds = sorted_builds(builds)
@@ -948,29 +982,150 @@ def parse_json_metadata(mf, app):
 
 
 def parse_yaml_metadata(mf, app):
-
-    yamlinfo = yaml.load(mf, Loader=YamlLoader)
-    app.update(yamlinfo)
+    yamldata = yaml.load(mf, Loader=YamlLoader)
+    app.update(yamldata)
     return app
 
 
 def write_yaml(mf, app):
 
+    import ruamel.yaml
+
+    _yaml_bools_true = ('y', 'Y', 'yes', 'Yes', 'YES',
+                        'true', 'True', 'TRUE',
+                        'on', 'On', 'ON')
+    _yaml_bools_false = ('n', 'N', 'no', 'No', 'NO',
+                         'false', 'False', 'FALSE',
+                         'off', 'Off', 'OFF')
+    _yaml_bools_plus_lists = []
+    _yaml_bools_plus_lists.extend(_yaml_bools_true)
+    _yaml_bools_plus_lists.extend([[x] for x in _yaml_bools_true])
+    _yaml_bools_plus_lists.extend(_yaml_bools_false)
+    _yaml_bools_plus_lists.extend([[x] for x in _yaml_bools_false])
+
     def _class_as_dict_representer(dumper, data):
         '''Creates a YAML representation of a App/Build instance'''
         return dumper.represent_dict(data)
 
-    empty_keys = [k for k, v in app.items() if not v]
-    for k in empty_keys:
-        del app[k]
-
-    for k in ['added', 'lastUpdated', 'id', 'metadatapath']:
-        if k in app:
-            del app[k]
-
-    yaml.add_representer(fdroidserver.metadata.App, _class_as_dict_representer)
-    yaml.add_representer(fdroidserver.metadata.Build, _class_as_dict_representer)
-    yaml.dump(app, mf, default_flow_style=False)
+    def _field_to_yaml(typ, value):
+        if typ is TYPE_STRING:
+            if value in _yaml_bools_plus_lists:
+                return ruamel.yaml.scalarstring.SingleQuotedScalarString(str(value))
+            return str(value)
+        elif typ is TYPE_INT:
+            return int(value)
+        elif typ is TYPE_MULTILINE:
+            if '\n' in value:
+                return ruamel.yaml.scalarstring.preserve_literal(str(value))
+            else:
+                return str(value)
+        elif typ is TYPE_SCRIPT:
+            if len(value) > 50:
+                return ruamel.yaml.scalarstring.preserve_literal(value)
+            else:
+                return value
+        else:
+            return value
+
+    def _app_to_yaml(app):
+        cm = ruamel.yaml.comments.CommentedMap()
+        insert_newline = False
+        for field in yaml_app_field_order:
+            if field is '\n':
+                # next iteration will need to insert a newline
+                insert_newline = True
+            else:
+                if (hasattr(app, field) and getattr(app, field)) or field is 'Builds':
+                    if field is 'Builds':
+                        cm.update({field: _builds_to_yaml(app)})
+                    elif field is 'CurrentVersionCode':
+                        cm.update({field: _field_to_yaml(TYPE_INT, getattr(app, field))})
+                    else:
+                        cm.update({field: _field_to_yaml(fieldtype(field), getattr(app, field))})
+
+                    if insert_newline:
+                        # we need to prepend a newline in front of this field
+                        insert_newline = False
+                        # inserting empty lines is not supported so we add a
+                        # bogus comment and over-write its value
+                        cm.yaml_set_comment_before_after_key(field, 'bogus')
+                        cm.ca.items[field][1][-1].value = '\n'
+        return cm
+
+    def _builds_to_yaml(app):
+        fields = ['versionName', 'versionCode']
+        fields.extend(build_flags_order)
+        builds = ruamel.yaml.comments.CommentedSeq()
+        for build in app.builds:
+            b = ruamel.yaml.comments.CommentedMap()
+            for field in fields:
+                if hasattr(build, field) and getattr(build, field):
+                    value = getattr(build, field)
+                    if field == 'gradle' and value == ['off']:
+                        value = [ruamel.yaml.scalarstring.SingleQuotedScalarString('off')]
+                    if field in ('disable', 'kivy', 'maven', 'buildozer'):
+                        if value == 'no':
+                            continue
+                        elif value == 'yes':
+                            value = 'yes'
+                    b.update({field: _field_to_yaml(flagtype(field), value)})
+            builds.append(b)
+
+        # insert extra empty lines between build entries
+        for i in range(1, len(builds)):
+            builds.yaml_set_comment_before_after_key(i, 'bogus')
+            builds.ca.items[i][1][-1].value = '\n'
+
+        return builds
+
+    yaml_app_field_order = [
+        'Disabled',
+        'AntiFeatures',
+        'Provides',
+        'Categories',
+        'License',
+        'AuthorName',
+        'AuthorEmail',
+        'AuthorWebSite',
+        'WebSite',
+        'SourceCode',
+        'IssueTracker',
+        'Changelog',
+        'Donate',
+        'FlattrID',
+        'Bitcoin',
+        'Litecoin',
+        '\n',
+        'Name',
+        'AutoName',
+        'Summary',
+        'Description',
+        '\n',
+        'RequiresRoot',
+        '\n',
+        'RepoType',
+        'Repo',
+        'Binaries',
+        '\n',
+        'Builds',
+        '\n',
+        'MaintainerNotes',
+        '\n',
+        'ArchivePolicy',
+        'AutoUpdateMode',
+        'UpdateCheckMode',
+        'UpdateCheckIgnore',
+        'VercodeOperation',
+        'UpdateCheckName',
+        'UpdateCheckData',
+        'CurrentVersion',
+        'CurrentVersionCode',
+        '\n',
+        'NoSourceSince',
+    ]
+
+    yaml_app = _app_to_yaml(app)
+    ruamel.yaml.round_trip_dump(yaml_app, mf, indent=4, block_seq_indent=2)
 
 
 build_line_sep = re.compile(r'(?<!\\),')
index 2d2d18037fc9ebc83335d6dc35f14ba8d8112d96..58fd79941fb0983728f6d0552465bf1033d24af7 100644 (file)
@@ -77,6 +77,8 @@ def main():
         if not options.to and ext not in supported:
             logging.info("Ignoring %s file at '%s'" % (ext, path))
             continue
+        else:
+            logging.info("rewriting '%s' to %s" % (appid, options.to))
 
         to_ext = ext
         if options.to is not None:
index b05700bd41aff9b34435a1310b598fc6704d123e..a0f4ca618c4beb40ab3ef63bc759bd0afee90dc9 100644 (file)
@@ -1721,20 +1721,15 @@ def main():
                 if 'name' not in apk:
                     logging.error(apk['packageName'] + ' does not have a name! Skipping...')
                     continue
-                f = open(os.path.join('metadata', apk['packageName'] + '.txt'), 'w', encoding='utf8')
-                f.write("License:Unknown\n")
-                f.write("Web Site:\n")
-                f.write("Source Code:\n")
-                f.write("Issue Tracker:\n")
-                f.write("Changelog:\n")
-                f.write("Summary:" + apk['name'] + "\n")
-                f.write("Description:\n")
-                f.write(apk['name'] + "\n")
-                f.write(".\n")
-                f.write("Name:" + apk['name'] + "\n")
-                f.close()
-                logging.info("Generated skeleton metadata for " + apk['packageName'])
-                newmetadata = True
+                with open(os.path.join('metadata', apk['packageName'] + '.yml'), 'w') as f:
+                    app = metadata.App()
+                    app.Name = apk['name']
+                    app.Summary = apk['name']
+                    app.CurrentVersionCode = 2147483647  # Java's Integer.MAX_VALUE
+                    app.Categories = [os.path.basename(os.path.dirname(os.getcwd()))]
+                    metadata.write_yaml(f, app)
+                    logging.info("Generated skeleton metadata for " + apk['packageName'])
+                    newmetadata = True
             else:
                 msg = apk['apkName'] + " (" + apk['packageName'] + ") has no metadata!"
                 if options.delete_unknown:
index 18661e95b11261e97786f64811ecf619d1ae12a1..c1705ed9d76f57ad0c10f5ef6f01f23a3057091b 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -38,6 +38,7 @@ setup(name='fdroidserver',
           'pyasn1-modules',
           'python-vagrant',
           'PyYAML',
+          'ruamel.yaml >= 0.13',
           'requests < 2.11',
           'docker-py == 1.9.0',
       ],
diff --git a/tests/extra/convert_metadata_to_yaml_then_txt.sh b/tests/extra/convert_metadata_to_yaml_then_txt.sh
new file mode 100755 (executable)
index 0000000..efc0335
--- /dev/null
@@ -0,0 +1,14 @@
+#! /bin/bash
+
+if [ ! -d metadata ]; then
+    echo 'no metadata directory present'
+    exit 1
+fi
+
+fdroid rewritemeta --to yml
+fdroid rewritemeta --to txt
+
+echo '## stripping maven, kivy, disable buildflags if they are set to "no"'
+sed -i '/^    maven=no$/d' metadata/*.txt
+sed -i '/^    kivy=no$/d' metadata/*.txt
+sed -i '/^    disable=no$/d' metadata/*.txt
diff --git a/tests/metadata-rewrite-yml/app.with.special.build.params.yml b/tests/metadata-rewrite-yml/app.with.special.build.params.yml
new file mode 100644 (file)
index 0000000..2b55701
--- /dev/null
@@ -0,0 +1,96 @@
+AntiFeatures:
+  - UpstreamNonFree
+Categories:
+  - System
+License: GPL-3.0
+SourceCode: https://github.com/loadrunner/Facebook-Contact-Sync
+IssueTracker: https://github.com/loadrunner/Facebook-Contact-Sync/issues
+
+AutoName: UberSync for Facebook
+Summary: Sync your Facebook Contacts
+Description: |-
+    To configure, go to "Settings => Accounts & Sync => Add Account". Depending on
+    how many friends you have, the first import might take a while, so be patient.
+
+    * Facebook does not allow to export phone numbers or emails: only names, pictures and statuses are synced.
+    * Facebook users have the option to block one or all apps: if they opt for that, they will be EXCLUDED from your friends list.
+
+    Appbrain SDK was removed before building.
+
+RepoType: git
+Repo: https://github.com/loadrunner/Facebook-Contact-Sync.git
+
+Builds:
+  - versionName: 1.0.0
+    versionCode: 32
+    commit: b3879c973e7cac3a3319
+
+  - versionName: 1.0.1
+    versionCode: 33
+    commit: 252c8dd4c9
+
+  - versionName: 1.2.0
+    versionCode: 39
+    commit: v1.2.0
+    patch:
+      - appbrain.patch
+    srclibs:
+      - FacebookSDK@sdk-version-3.0.1
+    rm:
+      - libs/appbrain-sdk-android.jar
+    prebuild: |-
+        sed -i 's@\(reference.1=\).*@\1$$FacebookSDK$$@' project.properties && sed -i 's/Class\[\]/Class\<?\>\[\]/g' $$FacebookSDK$$/src/com/facebook/model/GraphObject.java
+
+  - versionName: 1.2.2
+    versionCode: 42
+    commit: v1.2.2
+    patch:
+      - appbrain.patch
+    srclibs:
+      - FacebookSDK@sdk-version-3.0.2
+    rm:
+      - libs/appbrain-sdk-android.jar
+    extlibs:
+      - android/android-support-v4.jar
+    prebuild: |-
+        mv libs/android-support-v4.jar $$FacebookSDK$$/libs/ && sed -i 's@\(reference.1=\).*@\1$$FacebookSDK$$@' project.properties && sed -i 's/Class\[\]/Class\<?\>\[\]/g'          $$FacebookSDK$$/src/com/facebook/model/GraphObject.java
+
+  - versionName: 2.1.1
+    versionCode: 48
+    commit: 2.1.1
+    patch:
+      - manifest-ads.patch
+      - mobilecore.patch
+    maven: 'yes'
+    srclibs:
+      - FacebookSDK@sdk-version-3.0.2
+
+  - versionName: 2.1.1-b
+    versionCode: 49
+    commit: 2.1.1
+    patch:
+      - manifest-ads.patch
+      - mobilecore.patch
+    maven: yes@..
+    srclibs:
+      - FacebookSDK@sdk-version-3.0.2
+
+  - versionName: 2.1.1-c
+    versionCode: 50
+    commit: 2.1.1
+    patch:
+      - manifest-ads.patch
+      - mobilecore.patch
+    maven: '2'
+    srclibs:
+      - FacebookSDK@sdk-version-3.0.2
+
+  - versionName: 2.1.2
+    versionCode: 51
+    disable: Labelled as pre-release, so skipped
+
+ArchivePolicy: 0 versions
+AutoUpdateMode: None
+UpdateCheckMode: None
+CurrentVersion: 2.1.2
+CurrentVersionCode: 49
diff --git a/tests/metadata-rewrite-yml/fake.ota.update.yml b/tests/metadata-rewrite-yml/fake.ota.update.yml
new file mode 100644 (file)
index 0000000..dc8b6b9
--- /dev/null
@@ -0,0 +1,44 @@
+Categories:
+  - System
+License: Apache-2.0
+WebSite: https://f-droid.org
+SourceCode: https://gitlab.com/fdroid/privileged-extension
+IssueTracker: https://gitlab.com/fdroid/privileged-extension/issues
+Donate: https://f-droid.org/about
+
+AutoName: Fake OTA Update
+Summary: Tests whether OTA ZIP files are being include
+Description: |-
+    F-Droid can make use of system privileges or permissions to
+    install, update and remove applications on its own. The only way to obtain those
+    privileges is to become a system app.
+
+    This is where the Privileged Extension comes in - being a separate app and much
+    smaller, it can be installed as a system app and communicate with the main app
+    via AIDL IPC.
+
+    This has several advantages:
+
+    * Reduced disk usage in the system partition
+    * System updates don't remove F-Droid
+    * The process of installing into system via root is safer
+
+    This is packaged as an OTA (Over-The-Air) update ZIP file.  It must be installed
+    using TWRP or other Android recovery that can flash updates to the system from
+    the /data/data/org.fdroid.fdroid folder on the /data partition. The standalone
+    APK is called F-Droid Privileged Extension.
+
+RepoType: git
+Repo: https://gitlab.com/fdroid/privileged-extension.git
+
+Builds:
+  - versionName: 0.2.1
+    versionCode: 2000
+    commit: 0.2.1
+    output: app/build/distributions/FDroidPrivilegedExtensionFromBinaries-$$VERSION$$.zip
+    build: gradle assembleUpdateZipFromBinariesDebug
+
+AutoUpdateMode: Version %v
+UpdateCheckMode: Tags
+CurrentVersion: 0.2.1
+CurrentVersionCode: 2000
diff --git a/tests/metadata-rewrite-yml/org.fdroid.fdroid.yml b/tests/metadata-rewrite-yml/org.fdroid.fdroid.yml
new file mode 100644 (file)
index 0000000..1982ace
--- /dev/null
@@ -0,0 +1,950 @@
+Categories:
+  - System
+License: GPL-3.0+
+WebSite: https://f-droid.org
+SourceCode: https://gitlab.com/fdroid/fdroidclient
+IssueTracker: https://gitlab.com/fdroid/fdroidclient/issues
+Changelog: https://gitlab.com/fdroid/fdroidclient/raw/HEAD/CHANGELOG.md
+Donate: https://f-droid.org/about
+FlattrID: '343053'
+Bitcoin: 15u8aAPK4jJ5N8wpWJ5gutAyyeHtKX5i18
+
+AutoName: F-Droid
+Summary: Application manager
+Description: |-
+    Connects to F-Droid compatible repositories. The default repo is hosted at
+    f-droid.org, which contains only bona fide FOSS.
+
+    Android is open in the sense that you are free to install apks from anywhere you
+    wish, but there are many good reasons for using a client/repository setup:
+
+    * Be notified when updates are available
+    * Keep track of older and beta versions
+    * Filter apps that aren't compatible with the device
+    * Find apps via categories and searchable descriptions
+    * Access associated urls for donations, source code etc.
+    * Stay safe by checking repo index signatures and apk hashes
+
+RepoType: srclib
+Repo: fdroidclient
+
+Builds:
+  - versionName: '0.17'
+    versionCode: 8
+    commit: c626ce5f6d3e10ae15942f01ff028be310cc695a
+    init: rm -f build.xml
+
+  - versionName: '0.18'
+    versionCode: 9
+    commit: a6c9ed8d06b19315df9ba9041324f78139f7d238
+    init: rm -f build.xml
+
+  - versionName: '0.19'
+    versionCode: 10
+    commit: 540b7d0522f4d67a4896697f7342e4c75b4cbf59
+    init: rm -f build.xml
+
+  - versionName: '0.20'
+    versionCode: 11
+    commit: ddacfb856ad66c1c367e20c9cbecbfb15fe00813
+    init: rm -f build.xml
+
+  - versionName: '0.21'
+    versionCode: 12
+    commit: 49fa56aa6626a190f2d711120b69e435e9e615b1
+    init: rm -f build.xml
+
+  - versionName: '0.22'
+    versionCode: 13
+    commit: a6a33c942495cc4c74a7cb6e968efe0e00815e68
+    init: rm -f build.xml
+
+  - versionName: '0.23'
+    versionCode: 14
+    commit: aa58a8aad1a1c3832eafb9f1bdd6db8292d2c172
+    init: rm -f build.xml
+
+  - versionName: '0.24'
+    versionCode: 15
+    commit: 9b5fe2976443255b95027abd412f1c1e7f3d27b2
+    init: rm -f build.xml
+
+  - versionName: '0.25'
+    versionCode: 16
+    commit: 43977cc493e47a4dc841c4192ae8a40fb14b639b
+    init: rm -f build.xml
+
+  - versionName: '0.28'
+    versionCode: 19
+    commit: f881aabe5bd0ac94771b03f1318a6e0972ab4128
+    target: android-15
+
+  - versionName: '0.29'
+    versionCode: 20
+    commit: 87b229b95d0909bfd05c65c5670794e743626f6c
+    target: android-15
+
+  - versionName: '0.30'
+    versionCode: 21
+    commit: 497cb19840f79b31ae9590f5abd9e4df832b34ee
+    target: android-15
+
+  - versionName: '0.31'
+    versionCode: 22
+    commit: f99f8a544c7cb4d4a48ad09da00ad281af05f2ac
+    target: android-15
+
+  - versionName: '0.32'
+    versionCode: 23
+    commit: cc3970cc243e345416bfc62781ece6eeefd11495
+    target: android-15
+
+  - versionName: '0.33'
+    versionCode: 24
+    commit: 58eb580159aa4d54767f0af1736cad233fec2475
+    target: android-15
+
+  - versionName: 0.34-test
+    versionCode: 25
+    commit: 335d27b725b0f92e9e8804ae09518cd47bc7b021
+    target: android-15
+
+  - versionName: 0.35-test
+    versionCode: 26
+    commit: a06d18b029392669e98359f86c07e442a04e6a13
+    target: android-15
+
+  - versionName: 0.36-test
+    versionCode: 27
+    commit: 647e230c9e888c04bb0554078c5aa81da63548a0
+    target: android-15
+
+  - versionName: 0.37-test
+    versionCode: 28
+    commit: 3c02e3ccc147a34af42cedf7d85f18dc75c8efa8
+    target: android-15
+
+  - versionName: '0.38'
+    versionCode: 38
+    commit: 99b52c988d203811f434d6ac40675a63d5ae41ab
+    target: android-15
+
+  - versionName: 0.39-test
+    versionCode: 39
+    commit: 9a7d0b9f10710105d51d8206a7faa4408c60c20d
+    target: android-15
+
+  - versionName: '0.40'
+    versionCode: 40
+    commit: 51a67efdf1ee2819bee99d9263b2980dafaf761d
+    target: android-15
+
+  - versionName: '0.42'
+    versionCode: 42
+    commit: 36b815095ef51ca4f21887d973dbc0a50575cd65
+    target: android-15
+
+  - versionName: '0.43'
+    versionCode: 43
+    disable: sdk doesn't like tzm (at f2109e4e0bf1597c625221d8d2d10050f146ba5a)
+    commit: f2109e4e0bf1597c625221d8d2d10050f146ba5a
+    target: android-15
+
+  - versionName: '0.44'
+    versionCode: 44
+    disable: nasty upgrade bug
+    commit: '0.44'
+    target: android-15
+
+  - versionName: '0.45'
+    versionCode: 45
+    commit: '0.45'
+    target: android-15
+
+  - versionName: '0.46'
+    versionCode: 46
+    commit: '0.46'
+    target: android-15
+
+  - versionName: 0.47-test
+    versionCode: 47
+    commit: 0.47-test
+    target: android-17
+
+  - versionName: 0.48-test
+    versionCode: 48
+    commit: 0.48-test
+    target: android-17
+
+  - versionName: '0.50'
+    versionCode: 50
+    commit: '0.50'
+
+  - versionName: 0.51-test
+    versionCode: 51
+    commit: 0.51-test
+
+  - versionName: 0.52-test
+    versionCode: 52
+    commit: 0.52-test
+    submodules: true
+    prebuild: rm -rf extern/Universal-Image-Loader/downloads
+    androidupdate:
+      - .
+      - extern/Universal-Image-Loader/library
+
+  - versionName: 0.53-test
+    versionCode: 53
+    commit: 0.53-test
+    submodules: true
+    scandelete:
+      - yes
+
+  - versionName: '0.54'
+    versionCode: 540
+    commit: '0.54'
+    submodules: true
+    scandelete:
+      - yes
+
+  - versionName: '0.55'
+    versionCode: 550
+    commit: '0.55'
+    submodules: true
+
+  - versionName: 0.56-test
+    versionCode: 560
+    commit: 0.56-test
+    submodules: true
+
+  - versionName: 0.57-test
+    versionCode: 570
+    commit: 0.57-test
+    submodules: true
+
+  - versionName: '0.58'
+    versionCode: 580
+    commit: '0.58'
+    submodules: true
+
+  - versionName: 0.59-test
+    versionCode: 590
+    commit: 0.59-test
+    submodules: true
+
+  - versionName: 0.61-test
+    versionCode: 610
+    commit: 0.61-test
+    submodules: true
+
+  - versionName: '0.62'
+    versionCode: 620
+    commit: '0.62'
+    submodules: true
+
+  - versionName: '0.63'
+    versionCode: 630
+    commit: '0.63'
+    submodules: true
+
+  - versionName: 0.64-test
+    versionCode: 640
+    commit: 0.64-test
+    submodules: true
+
+  - versionName: '0.65'
+    versionCode: 650
+    commit: '0.65'
+    submodules: true
+
+  - versionName: '0.66'
+    versionCode: 660
+    commit: '0.66'
+    submodules: true
+
+  - versionName: 0.67-test
+    versionCode: 670
+    commit: 0.67-test
+    submodules: true
+
+  - versionName: 0.68-test
+    versionCode: 680
+    commit: 0.68-test
+    submodules: true
+
+  - versionName: 0.69-test
+    versionCode: 690
+    commit: 0.69-test
+    submodules: true
+
+  - versionName: 0.70-test
+    versionCode: 700
+    commit: 0.70-test
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.71'
+    versionCode: 710
+    disable: Broken MTM/AndroidPinning
+    commit: '0.71'
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.72'
+    versionCode: 720
+    disable: proguard issues
+    commit: '0.72'
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.73'
+    versionCode: 730
+    disable: local repos broken
+    commit: '0.73'
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.74'
+    versionCode: 740
+    disable: still some proguard issues
+    commit: '0.74'
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.75'
+    versionCode: 750
+    disable: repo update progress crasher
+    commit: '0.75'
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.76'
+    versionCode: 760
+    commit: '0.76'
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.77-test
+    versionCode: 770
+    commit: 0.77-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.78'
+    versionCode: 780
+    commit: '0.78'
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.79-test
+    versionCode: 790
+    commit: 0.79-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.80-test
+    versionCode: 800
+    commit: 0.80-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.81-test
+    versionCode: 810
+    commit: 0.81-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.82'
+    versionCode: 820
+    commit: '0.82'
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.83'
+    versionCode: 830
+    commit: '0.83'
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.84-test
+    versionCode: 840
+    commit: 0.84-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.85-test
+    versionCode: 850
+    commit: 0.85-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.86-test
+    versionCode: 860
+    commit: 0.86-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.87-test
+    versionCode: 870
+    commit: 0.87-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.88'
+    versionCode: 880
+    commit: '0.88'
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.89-test
+    versionCode: 890
+    commit: 0.89-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.90-test
+    versionCode: 900
+    commit: 0.90-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.91'
+    versionCode: 910
+    commit: '0.91'
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: '0.92'
+    versionCode: 920
+    commit: '0.92'
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.93-test
+    versionCode: 930
+    commit: 0.93-test
+    subdir: F-Droid
+    submodules: true
+    prebuild: ./ant-prepare.sh
+    androidupdate:
+      - .
+
+  - versionName: 0.94-test
+    versionCode: 940
+    commit: 0.94-test
+    subdir: F-Droid
+    submodules: true
+    gradle:
+      - yes
+
+  - versionName: 0.95-alpha1
+    versionCode: 95001
+    commit: 0.95-alpha1
+    subdir: F-Droid
+    submodules: true
+    gradle:
+      - yes
+
+  - versionName: 0.95-alpha2
+    versionCode: 95002
+    commit: v0.95-alpha2
+    subdir: F-Droid
+    submodules: true
+    gradle:
+      - yes
+
+  - versionName: '0.95'
+    versionCode: 95050
+    commit: v0.95
+    subdir: F-Droid
+    submodules: true
+    gradle:
+      - yes
+
+  - versionName: 0.95.1
+    versionCode: 95150
+    commit: v0.95.1
+    subdir: F-Droid
+    submodules: true
+    gradle:
+      - yes
+
+  - versionName: 0.96-alpha1
+    versionCode: 96001
+    commit: v0.96-alpha1
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.96-alpha2
+    versionCode: 96002
+    commit: v0.96-alpha2
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.96-alpha3
+    versionCode: 96003
+    commit: v0.96-alpha3
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.96-alpha4
+    versionCode: 96004
+    commit: v0.96-alpha4
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.96-alpha5
+    versionCode: 96005
+    commit: v0.96-alpha5
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.96-alpha6
+    versionCode: 96006
+    commit: v0.96-alpha6
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: '0.96'
+    versionCode: 96050
+    commit: v0.96
+    subdir: F-Droid
+    gradle:
+      - yes
+    scanignore:
+      - extern/AndroidPinning/res/raw/cacerts
+
+  - versionName: 0.96.1
+    versionCode: 96150
+    commit: v0.96.1
+    subdir: F-Droid
+    gradle:
+      - yes
+    scanignore:
+      - extern/AndroidPinning/res/raw/cacerts
+
+  - versionName: 0.97-alpha1
+    versionCode: 97001
+    commit: v0.97-alpha1
+    subdir: F-Droid
+    gradle:
+      - yes
+    scanignore:
+      - extern/AndroidPinning/res/raw/cacerts
+
+  - versionName: 0.97-alpha2
+    versionCode: 97002
+    commit: v0.97-alpha2
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.97-alpha3
+    versionCode: 97003
+    commit: v0.97-alpha3
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.97-alpha4
+    versionCode: 97004
+    commit: v0.97-alpha4
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.97-alpha5
+    versionCode: 97005
+    commit: v0.97-alpha5
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.97-alpha6
+    versionCode: 97006
+    commit: v0.97-alpha6
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.97-alpha7
+    versionCode: 97007
+    commit: v0.97-alpha7
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.97-alpha8
+    versionCode: 97008
+    commit: v0.97-alpha8
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: '0.97'
+    versionCode: 97050
+    commit: v0.97
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.98-alpha1
+    versionCode: 98001
+    commit: v0.98-alpha1
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.98-alpha2
+    versionCode: 98002
+    commit: v0.98-alpha2
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.98-alpha3
+    versionCode: 98003
+    commit: v0.98-alpha3
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.98-alpha4
+    versionCode: 98004
+    commit: v0.98-alpha4
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.98-alpha5
+    versionCode: 98005
+    commit: v0.98-alpha5
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.98-alpha6
+    versionCode: 98006
+    commit: v0.98-alpha6
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.98-alpha7
+    versionCode: 98007
+    commit: v0.98-alpha7
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: '0.98'
+    versionCode: 98050
+    commit: v0.98
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.98.1
+    versionCode: 98150
+    commit: v0.98.1
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.99-alpha1
+    versionCode: 99001
+    commit: v0.99-alpha1
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.99-alpha2
+    versionCode: 99002
+    commit: v0.99-alpha2
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: '0.99'
+    versionCode: 99050
+    commit: v0.99
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.99.1
+    versionCode: 99150
+    commit: v0.99.1
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.99.2
+    versionCode: 99250
+    commit: v0.99.2
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.100-alpha1
+    versionCode: 100001
+    commit: v0.100-alpha1
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.100-alpha2
+    versionCode: 100002
+    commit: v0.100-alpha2
+    subdir: F-Droid
+    gradle:
+      - yes
+
+  - versionName: 0.100-alpha3
+    versionCode: 100003
+    commit: v0.100-alpha3
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.100-alpha4
+    versionCode: 100004
+    commit: v0.100-alpha4
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.100-alpha5
+    versionCode: 100005
+    commit: v0.100-alpha5
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.100-alpha6
+    versionCode: 100006
+    commit: v0.100-alpha6
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.100-alpha7
+    versionCode: 100007
+    commit: v0.100-alpha7
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.100-alpha8
+    versionCode: 100008
+    commit: v0.100-alpha8
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: '0.100'
+    versionCode: 100050
+    commit: v0.100
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.100.1
+    versionCode: 100150
+    commit: v0.100.1
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.101-alpha1
+    versionCode: 101001
+    commit: v0.101-alpha1
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.101-alpha2
+    versionCode: 101002
+    commit: v0.101-alpha2
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.101-alpha3
+    versionCode: 101003
+    commit: v0.101-alpha3
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.101-alpha4
+    versionCode: 101004
+    commit: v0.101-alpha4
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.101-alpha5
+    versionCode: 101005
+    commit: v0.101-alpha5
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.101-alpha6
+    versionCode: 101006
+    commit: v0.101-alpha6
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: '0.101'
+    versionCode: 101050
+    commit: v0.101
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.102-alpha1
+    versionCode: 102001
+    commit: v0.102-alpha1
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.102-alpha2
+    versionCode: 102002
+    commit: v0.102-alpha2
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.102-alpha3
+    versionCode: 102003
+    commit: v0.102-alpha3
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: '0.102'
+    versionCode: 102050
+    commit: v0.102
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.102.1
+    versionCode: 102150
+    commit: v0.102.1
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.102.2
+    versionCode: 102250
+    commit: v0.102.2
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.102.3
+    versionCode: 102350
+    commit: v0.102.3
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.103-alpha1
+    versionCode: 103001
+    commit: v0.103-alpha1
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.103-alpha2
+    versionCode: 103002
+    commit: v0.103-alpha2
+    subdir: app
+    gradle:
+      - yes
+
+  - versionName: 0.103-alpha3
+    versionCode: 103003
+    commit: v0.103-alpha3
+    subdir: app
+    gradle:
+      - yes
+
+ArchivePolicy: 12 versions
+AutoUpdateMode: None
+UpdateCheckMode: Static
+CurrentVersion: 0.102.3
+CurrentVersionCode: 102350
index 791ac65256b5d5a193b1722909f9bf08b189fe7d..ee113287726b64a752ebf133ec6470bc8db13b1e 100755 (executable)
@@ -8,6 +8,7 @@ import os
 import sys
 import unittest
 import yaml
+import tempfile
 
 localmodule = os.path.realpath(
     os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..'))
@@ -54,6 +55,69 @@ class MetadataTest(unittest.TestCase):
             #     yaml.add_representer(fdroidserver.metadata.Build, _build_yaml_representer)
             #     yaml.dump(frommeta, f, default_flow_style=False)
 
+    def test_rewrite_yaml_fakeotaupdate(self):
+
+        # setup/reset test dir if necessary and setup params
+        tmpdir = os.path.join(os.path.dirname(__file__), '..', '.testfiles')
+        if not os.path.exists(tmpdir):
+            os.makedirs(tmpdir)
+        testdir = tempfile.mkdtemp(prefix='test_rewrite_metadata_', dir=tmpdir)
+        fdroidserver.common.config = {'accepted_formats': ['txt', 'yml']}
+
+        # rewrite metadata
+        allapps = fdroidserver.metadata.read_metadata(xref=True)
+        for appid, app in allapps.items():
+            if appid == 'fake.ota.update':
+                fdroidserver.metadata.write_metadata(os.path.join(testdir, appid + '.yml'), app)
+
+        # assert rewrite result
+        with open(os.path.join(testdir, 'fake.ota.update.yml'), 'r', encoding='utf-8') as result:
+            with open('metadata-rewrite-yml/fake.ota.update.yml', 'r', encoding='utf-8') as orig:
+                self.maxDiff = None
+                self.assertEqual(result.read(), orig.read())
+
+    def test_rewrite_yaml_fdroidclient(self):
+
+        # setup/reset test dir if necessary and setup params
+        tmpdir = os.path.join(os.path.dirname(__file__), '..', '.testfiles')
+        if not os.path.exists(tmpdir):
+            os.makedirs(tmpdir)
+        testdir = tempfile.mkdtemp(prefix='test_rewrite_metadata_', dir=tmpdir)
+        fdroidserver.common.config = {'accepted_formats': ['txt', 'yml']}
+
+        # rewrite metadata
+        allapps = fdroidserver.metadata.read_metadata(xref=True)
+        for appid, app in allapps.items():
+            if appid == 'org.fdroid.fdroid':
+                fdroidserver.metadata.write_metadata(os.path.join(testdir, appid + '.yml'), app)
+
+        # assert rewrite result
+        with open(os.path.join(testdir, 'org.fdroid.fdroid.yml'), 'r', encoding='utf-8') as result:
+            with open('metadata-rewrite-yml/org.fdroid.fdroid.yml', 'r', encoding='utf-8') as orig:
+                self.maxDiff = None
+                self.assertEqual(result.read(), orig.read())
+
+    def test_rewrite_yaml_special_build_params(self):
+
+        # setup/reset test dir if necessary and setup params
+        tmpdir = os.path.join(os.path.dirname(__file__), '..', '.testfiles')
+        if not os.path.exists(tmpdir):
+            os.makedirs(tmpdir)
+        testdir = tempfile.mkdtemp(prefix='test_rewrite_metadata_', dir=tmpdir)
+        fdroidserver.common.config = {'accepted_formats': ['txt', 'yml']}
+
+        # rewrite metadata
+        allapps = fdroidserver.metadata.read_metadata(xref=True)
+        for appid, app in allapps.items():
+            if appid == 'app.with.special.build.params':
+                fdroidserver.metadata.write_metadata(os.path.join(testdir, appid + '.yml'), app)
+
+        # assert rewrite result
+        with open(os.path.join(testdir, 'app.with.special.build.params.yml'), 'r', encoding='utf-8') as result:
+            with open('metadata-rewrite-yml/app.with.special.build.params.yml', 'r', encoding='utf-8') as orig:
+                self.maxDiff = None
+                self.assertEqual(result.read(), orig.read())
+
 
 if __name__ == "__main__":
     parser = optparse.OptionParser()
diff --git a/tests/metadata/app.with.special.build.params.txt b/tests/metadata/app.with.special.build.params.txt
new file mode 100644 (file)
index 0000000..db4970e
--- /dev/null
@@ -0,0 +1,72 @@
+AntiFeatures:UpstreamNonFree
+Categories:System
+License:GPL-3.0
+Web Site:
+Source Code:https://github.com/loadrunner/Facebook-Contact-Sync
+Issue Tracker:https://github.com/loadrunner/Facebook-Contact-Sync/issues
+
+Auto Name:UberSync for Facebook
+Summary:Sync your Facebook Contacts
+Description:
+To configure, go to "Settings => Accounts & Sync => Add Account". Depending on
+how many friends you have, the first import might take a while, so be patient.
+
+* Facebook does not allow to export phone numbers or emails: only names, pictures and statuses are synced.
+* Facebook users have the option to block one or all apps: if they opt for that, they will be EXCLUDED from your friends list.
+
+Appbrain SDK was removed before building.
+.
+
+Repo Type:git
+Repo:https://github.com/loadrunner/Facebook-Contact-Sync.git
+
+Build:1.0.0,32
+    commit=b3879c973e7cac3a3319
+
+Build:1.0.1,33
+    commit=252c8dd4c9
+
+Build:1.2.0,39
+    commit=v1.2.0
+    patch=appbrain.patch
+    srclibs=FacebookSDK@sdk-version-3.0.1
+    rm=libs/appbrain-sdk-android.jar
+    prebuild=sed -i 's@\(reference.1=\).*@\1$$FacebookSDK$$@' project.properties && \
+        sed -i 's/Class\[\]/Class\<?\>\[\]/g' $$FacebookSDK$$/src/com/facebook/model/GraphObject.java
+
+Build:1.2.2,42
+    commit=v1.2.2
+    patch=appbrain.patch
+    srclibs=FacebookSDK@sdk-version-3.0.2
+    rm=libs/appbrain-sdk-android.jar
+    extlibs=android/android-support-v4.jar
+    prebuild=mv libs/android-support-v4.jar $$FacebookSDK$$/libs/ && \
+        sed -i 's@\(reference.1=\).*@\1$$FacebookSDK$$@' project.properties && \
+        sed -i 's/Class\[\]/Class\<?\>\[\]/g'          $$FacebookSDK$$/src/com/facebook/model/GraphObject.java
+
+Build:2.1.1,48
+    commit=2.1.1
+    patch=manifest-ads.patch,mobilecore.patch
+    maven=yes
+    srclibs=FacebookSDK@sdk-version-3.0.2
+
+Build:2.1.1-b,49
+    commit=2.1.1
+    patch=manifest-ads.patch,mobilecore.patch
+    maven=yes@..
+    srclibs=FacebookSDK@sdk-version-3.0.2
+
+Build:2.1.1-c,50
+    commit=2.1.1
+    patch=manifest-ads.patch,mobilecore.patch
+    maven=2
+    srclibs=FacebookSDK@sdk-version-3.0.2
+
+Build:2.1.2,51
+    disable=Labelled as pre-release, so skipped
+
+Archive Policy:0 versions
+Auto Update Mode:None
+Update Check Mode:None
+Current Version:2.1.2
+Current Version Code:49
diff --git a/tests/metadata/org.fdroid.fdroid.txt b/tests/metadata/org.fdroid.fdroid.txt
new file mode 100644 (file)
index 0000000..912cd58
--- /dev/null
@@ -0,0 +1,720 @@
+Categories:System
+License:GPL-3.0+
+Web Site:https://f-droid.org
+Source Code:https://gitlab.com/fdroid/fdroidclient
+Issue Tracker:https://gitlab.com/fdroid/fdroidclient/issues
+Changelog:https://gitlab.com/fdroid/fdroidclient/raw/HEAD/CHANGELOG.md
+Donate:https://f-droid.org/about
+FlattrID:343053
+Bitcoin:15u8aAPK4jJ5N8wpWJ5gutAyyeHtKX5i18
+
+Auto Name:F-Droid
+Summary:Application manager
+Description:
+Connects to F-Droid compatible repositories. The default repo is hosted at
+f-droid.org, which contains only bona fide FOSS.
+
+Android is open in the sense that you are free to install apks from anywhere you
+wish, but there are many good reasons for using a client/repository setup:
+
+* Be notified when updates are available
+* Keep track of older and beta versions
+* Filter apps that aren't compatible with the device
+* Find apps via categories and searchable descriptions
+* Access associated urls for donations, source code etc.
+* Stay safe by checking repo index signatures and apk hashes
+.
+
+Repo Type:srclib
+Repo:fdroidclient
+
+Build:0.17,8
+    commit=c626ce5f6d3e10ae15942f01ff028be310cc695a
+    init=rm -f build.xml
+
+Build:0.18,9
+    commit=a6c9ed8d06b19315df9ba9041324f78139f7d238
+    init=rm -f build.xml
+
+Build:0.19,10
+    commit=540b7d0522f4d67a4896697f7342e4c75b4cbf59
+    init=rm -f build.xml
+
+Build:0.20,11
+    commit=ddacfb856ad66c1c367e20c9cbecbfb15fe00813
+    init=rm -f build.xml
+
+Build:0.21,12
+    commit=49fa56aa6626a190f2d711120b69e435e9e615b1
+    init=rm -f build.xml
+
+Build:0.22,13
+    commit=a6a33c942495cc4c74a7cb6e968efe0e00815e68
+    init=rm -f build.xml
+
+Build:0.23,14
+    commit=aa58a8aad1a1c3832eafb9f1bdd6db8292d2c172
+    init=rm -f build.xml
+
+Build:0.24,15
+    commit=9b5fe2976443255b95027abd412f1c1e7f3d27b2
+    init=rm -f build.xml
+
+Build:0.25,16
+    commit=43977cc493e47a4dc841c4192ae8a40fb14b639b
+    init=rm -f build.xml
+
+Build:0.28,19
+    commit=f881aabe5bd0ac94771b03f1318a6e0972ab4128
+    target=android-15
+
+Build:0.29,20
+    commit=87b229b95d0909bfd05c65c5670794e743626f6c
+    target=android-15
+
+Build:0.30,21
+    commit=497cb19840f79b31ae9590f5abd9e4df832b34ee
+    target=android-15
+
+Build:0.31,22
+    commit=f99f8a544c7cb4d4a48ad09da00ad281af05f2ac
+    target=android-15
+
+Build:0.32,23
+    commit=cc3970cc243e345416bfc62781ece6eeefd11495
+    target=android-15
+
+Build:0.33,24
+    commit=58eb580159aa4d54767f0af1736cad233fec2475
+    target=android-15
+
+Build:0.34-test,25
+    commit=335d27b725b0f92e9e8804ae09518cd47bc7b021
+    target=android-15
+
+Build:0.35-test,26
+    commit=a06d18b029392669e98359f86c07e442a04e6a13
+    target=android-15
+
+Build:0.36-test,27
+    commit=647e230c9e888c04bb0554078c5aa81da63548a0
+    target=android-15
+
+Build:0.37-test,28
+    commit=3c02e3ccc147a34af42cedf7d85f18dc75c8efa8
+    target=android-15
+
+Build:0.38,38
+    commit=99b52c988d203811f434d6ac40675a63d5ae41ab
+    target=android-15
+
+Build:0.39-test,39
+    commit=9a7d0b9f10710105d51d8206a7faa4408c60c20d
+    target=android-15
+
+Build:0.40,40
+    commit=51a67efdf1ee2819bee99d9263b2980dafaf761d
+    target=android-15
+
+Build:0.42,42
+    commit=36b815095ef51ca4f21887d973dbc0a50575cd65
+    target=android-15
+
+Build:0.43,43
+    disable=sdk doesn't like tzm (at f2109e4e0bf1597c625221d8d2d10050f146ba5a)
+    commit=f2109e4e0bf1597c625221d8d2d10050f146ba5a
+    target=android-15
+
+Build:0.44,44
+    disable=nasty upgrade bug
+    commit=0.44
+    target=android-15
+
+Build:0.45,45
+    commit=0.45
+    target=android-15
+
+Build:0.46,46
+    commit=0.46
+    target=android-15
+
+Build:0.47-test,47
+    commit=0.47-test
+    target=android-17
+
+Build:0.48-test,48
+    commit=0.48-test
+    target=android-17
+
+Build:0.50,50
+    commit=0.50
+
+Build:0.51-test,51
+    commit=0.51-test
+
+Build:0.52-test,52
+    commit=0.52-test
+    submodules=yes
+    prebuild=rm -rf extern/Universal-Image-Loader/downloads
+    update=.,extern/Universal-Image-Loader/library
+
+Build:0.53-test,53
+    commit=0.53-test
+    submodules=yes
+    scandelete=yes
+
+Build:0.54,540
+    commit=0.54
+    submodules=yes
+    scandelete=yes
+
+Build:0.55,550
+    commit=0.55
+    submodules=yes
+
+Build:0.56-test,560
+    commit=0.56-test
+    submodules=yes
+
+Build:0.57-test,570
+    commit=0.57-test
+    submodules=yes
+
+Build:0.58,580
+    commit=0.58
+    submodules=yes
+
+Build:0.59-test,590
+    commit=0.59-test
+    submodules=yes
+
+Build:0.61-test,610
+    commit=0.61-test
+    submodules=yes
+
+Build:0.62,620
+    commit=0.62
+    submodules=yes
+
+Build:0.63,630
+    commit=0.63
+    submodules=yes
+
+Build:0.64-test,640
+    commit=0.64-test
+    submodules=yes
+
+Build:0.65,650
+    commit=0.65
+    submodules=yes
+
+Build:0.66,660
+    commit=0.66
+    submodules=yes
+
+Build:0.67-test,670
+    commit=0.67-test
+    submodules=yes
+
+Build:0.68-test,680
+    commit=0.68-test
+    submodules=yes
+
+Build:0.69-test,690
+    commit=0.69-test
+    submodules=yes
+
+Build:0.70-test,700
+    commit=0.70-test
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.71,710
+    disable=Broken MTM/AndroidPinning
+    commit=0.71
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.72,720
+    disable=proguard issues
+    commit=0.72
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.73,730
+    disable=local repos broken
+    commit=0.73
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.74,740
+    disable=still some proguard issues
+    commit=0.74
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.75,750
+    disable=repo update progress crasher
+    commit=0.75
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.76,760
+    commit=0.76
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.77-test,770
+    commit=0.77-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.78,780
+    commit=0.78
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.79-test,790
+    commit=0.79-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.80-test,800
+    commit=0.80-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.81-test,810
+    commit=0.81-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.82,820
+    commit=0.82
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.83,830
+    commit=0.83
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.84-test,840
+    commit=0.84-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.85-test,850
+    commit=0.85-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.86-test,860
+    commit=0.86-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.87-test,870
+    commit=0.87-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.88,880
+    commit=0.88
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.89-test,890
+    commit=0.89-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.90-test,900
+    commit=0.90-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.91,910
+    commit=0.91
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.92,920
+    commit=0.92
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.93-test,930
+    commit=0.93-test
+    subdir=F-Droid
+    submodules=yes
+    prebuild=./ant-prepare.sh
+    update=.
+
+Build:0.94-test,940
+    commit=0.94-test
+    subdir=F-Droid
+    submodules=yes
+    gradle=yes
+
+Build:0.95-alpha1,95001
+    commit=0.95-alpha1
+    subdir=F-Droid
+    submodules=yes
+    gradle=yes
+
+Build:0.95-alpha2,95002
+    commit=v0.95-alpha2
+    subdir=F-Droid
+    submodules=yes
+    gradle=yes
+
+Build:0.95,95050
+    commit=v0.95
+    subdir=F-Droid
+    submodules=yes
+    gradle=yes
+
+Build:0.95.1,95150
+    commit=v0.95.1
+    subdir=F-Droid
+    submodules=yes
+    gradle=yes
+
+Build:0.96-alpha1,96001
+    commit=v0.96-alpha1
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.96-alpha2,96002
+    commit=v0.96-alpha2
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.96-alpha3,96003
+    commit=v0.96-alpha3
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.96-alpha4,96004
+    commit=v0.96-alpha4
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.96-alpha5,96005
+    commit=v0.96-alpha5
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.96-alpha6,96006
+    commit=v0.96-alpha6
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.96,96050
+    commit=v0.96
+    subdir=F-Droid
+    gradle=yes
+    scanignore=extern/AndroidPinning/res/raw/cacerts
+
+Build:0.96.1,96150
+    commit=v0.96.1
+    subdir=F-Droid
+    gradle=yes
+    scanignore=extern/AndroidPinning/res/raw/cacerts
+
+Build:0.97-alpha1,97001
+    commit=v0.97-alpha1
+    subdir=F-Droid
+    gradle=yes
+    scanignore=extern/AndroidPinning/res/raw/cacerts
+
+Build:0.97-alpha2,97002
+    commit=v0.97-alpha2
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.97-alpha3,97003
+    commit=v0.97-alpha3
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.97-alpha4,97004
+    commit=v0.97-alpha4
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.97-alpha5,97005
+    commit=v0.97-alpha5
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.97-alpha6,97006
+    commit=v0.97-alpha6
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.97-alpha7,97007
+    commit=v0.97-alpha7
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.97-alpha8,97008
+    commit=v0.97-alpha8
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.97,97050
+    commit=v0.97
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.98-alpha1,98001
+    commit=v0.98-alpha1
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.98-alpha2,98002
+    commit=v0.98-alpha2
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.98-alpha3,98003
+    commit=v0.98-alpha3
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.98-alpha4,98004
+    commit=v0.98-alpha4
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.98-alpha5,98005
+    commit=v0.98-alpha5
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.98-alpha6,98006
+    commit=v0.98-alpha6
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.98-alpha7,98007
+    commit=v0.98-alpha7
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.98,98050
+    commit=v0.98
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.98.1,98150
+    commit=v0.98.1
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.99-alpha1,99001
+    commit=v0.99-alpha1
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.99-alpha2,99002
+    commit=v0.99-alpha2
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.99,99050
+    commit=v0.99
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.99.1,99150
+    commit=v0.99.1
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.99.2,99250
+    commit=v0.99.2
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.100-alpha1,100001
+    commit=v0.100-alpha1
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.100-alpha2,100002
+    commit=v0.100-alpha2
+    subdir=F-Droid
+    gradle=yes
+
+Build:0.100-alpha3,100003
+    commit=v0.100-alpha3
+    subdir=app
+    gradle=yes
+
+Build:0.100-alpha4,100004
+    commit=v0.100-alpha4
+    subdir=app
+    gradle=yes
+
+Build:0.100-alpha5,100005
+    commit=v0.100-alpha5
+    subdir=app
+    gradle=yes
+
+Build:0.100-alpha6,100006
+    commit=v0.100-alpha6
+    subdir=app
+    gradle=yes
+
+Build:0.100-alpha7,100007
+    commit=v0.100-alpha7
+    subdir=app
+    gradle=yes
+
+Build:0.100-alpha8,100008
+    commit=v0.100-alpha8
+    subdir=app
+    gradle=yes
+
+Build:0.100,100050
+    commit=v0.100
+    subdir=app
+    gradle=yes
+
+Build:0.100.1,100150
+    commit=v0.100.1
+    subdir=app
+    gradle=yes
+
+Build:0.101-alpha1,101001
+    commit=v0.101-alpha1
+    subdir=app
+    gradle=yes
+
+Build:0.101-alpha2,101002
+    commit=v0.101-alpha2
+    subdir=app
+    gradle=yes
+
+Build:0.101-alpha3,101003
+    commit=v0.101-alpha3
+    subdir=app
+    gradle=yes
+
+Build:0.101-alpha4,101004
+    commit=v0.101-alpha4
+    subdir=app
+    gradle=yes
+
+Build:0.101-alpha5,101005
+    commit=v0.101-alpha5
+    subdir=app
+    gradle=yes
+
+Build:0.101-alpha6,101006
+    commit=v0.101-alpha6
+    subdir=app
+    gradle=yes
+
+Build:0.101,101050
+    commit=v0.101
+    subdir=app
+    gradle=yes
+
+Build:0.102-alpha1,102001
+    commit=v0.102-alpha1
+    subdir=app
+    gradle=yes
+
+Build:0.102-alpha2,102002
+    commit=v0.102-alpha2
+    subdir=app
+    gradle=yes
+
+Build:0.102-alpha3,102003
+    commit=v0.102-alpha3
+    subdir=app
+    gradle=yes
+
+Build:0.102,102050
+    commit=v0.102
+    subdir=app
+    gradle=yes
+
+Build:0.102.1,102150
+    commit=v0.102.1
+    subdir=app
+    gradle=yes
+
+Build:0.102.2,102250
+    commit=v0.102.2
+    subdir=app
+    gradle=yes
+
+Build:0.102.3,102350
+    commit=v0.102.3
+    subdir=app
+    gradle=yes
+
+Build:0.103-alpha1,103001
+    commit=v0.103-alpha1
+    subdir=app
+    gradle=yes
+
+Build:0.103-alpha2,103002
+    commit=v0.103-alpha2
+    subdir=app
+    gradle=yes
+
+Build:0.103-alpha3,103003
+    commit=v0.103-alpha3
+    subdir=app
+    gradle=yes
+
+Archive Policy:12 versions
+Auto Update Mode:None
+Update Check Mode:Static
+Current Version:0.102.3
+Current Version Code:102350