chiark / gitweb /
prettify write_yaml metadata
authorMichael Pöhn <michael.poehn@fsfe.org>
Sun, 7 May 2017 00:13:25 +0000 (02:13 +0200)
committerMichael Pöhn <michael.poehn@fsfe.org>
Tue, 4 Jul 2017 09:51:08 +0000 (11:51 +0200)
fdroidserver/metadata.py
tests/metadata/app.with.speacial.build.params.txt [new file with mode: 0644]
tests/metadata/rewrite-yml/app.with.speacial.build.params.yml [new file with mode: 0644]
tests/rewritemeta.TestCase

index 1e252e58fda0c8ac0c478028389b25e7028268fd..3596d522aec2073f9fdc8ce04c03c7eaa6faece6 100644 (file)
@@ -49,7 +49,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 +179,7 @@ TYPE_SCRIPT = 5
 TYPE_MULTILINE = 6
 TYPE_BUILD = 7
 TYPE_BUILD_V2 = 8
+TYPE_INT = 9
 
 fieldtypes = {
     'Description': TYPE_MULTILINE,
@@ -318,6 +319,7 @@ class Build(dict):
 
 
 flagtypes = {
+    'versionCode': TYPE_INT,
     'extlibs': TYPE_LIST,
     'srclibs': TYPE_LIST,
     'patch': TYPE_LIST,
@@ -960,41 +962,67 @@ def write_yaml(mf, app):
         '''Creates a YAML representation of a App/Build instance'''
         return dumper.represent_dict(data)
 
-    def _builds_to_yaml(app):
+    def _field_to_yaml(typ, value):
+        if typ is TYPE_STRING:
+            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):
-                    if field is 'versionCode':
-                        b.update({field: int(getattr(build, field))})
-                    else:
-                        b.update({field: getattr(build, field)})
+                    b.update({field: _field_to_yaml(flagtype(field), getattr(build, field))})
             builds.append(b)
 
-        # insert extra empty lines between builds
+        # 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
 
-    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)
-    ruamel.yaml.add_representer(fdroidserver.metadata.Build, _class_as_dict_representer)
-    # yaml.dump(app.asOrderedDict(), mf, default_flow_style=False, Dumper=yamlordereddictloader.Dumper)
-
     yaml_app_field_order = [
         'Categories',
         'License',
@@ -1022,30 +1050,8 @@ def write_yaml(mf, app):
         'CurrentVersionCode',
     ]
 
-    preformated = ruamel.yaml.comments.CommentedMap()
-    insert_newline = False
-    for field in yaml_app_field_order:
-        if field is '\n':
-            insert_newline = True
-        else:
-            if (hasattr(app, field) and getattr(app, field)) or field is 'Builds':
-                if field in ['Description']:
-                    preformated.update({field: ruamel.yaml.scalarstring.preserve_literal(getattr(app, field))})
-                elif field is 'Builds':
-                    preformated.update({field: _builds_to_yaml(app)})
-                elif field is 'CurrentVersionCode':
-                    preformated.update({field: int(getattr(app, field))})
-                else:
-                    preformated.update({field: getattr(app, field)})
-
-                if insert_newline:
-                    insert_newline = False
-                    # inserting empty lines is not supported so we add a
-                    # bogus comment and over-write its value
-                    preformated.yaml_set_comment_before_after_key(field, 'bogus')
-                    preformated.ca.items[field][1][-1].value = '\n'
-
-    ruamel.yaml.round_trip_dump(preformated, mf, indent=4, block_seq_indent=2)
+    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'(?<!\\),')
diff --git a/tests/metadata/app.with.speacial.build.params.txt b/tests/metadata/app.with.speacial.build.params.txt
new file mode 100644 (file)
index 0000000..63d25e4
--- /dev/null
@@ -0,0 +1,64 @@
+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
+    srclibs=FacebookSDK@sdk-version-3.0.2
+    rm=libs/applovin*,libs/mobileCore*
+    extlibs=android/android-support-v4.jar
+    prebuild=cp 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.2,49
+    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/rewrite-yml/app.with.speacial.build.params.yml b/tests/metadata/rewrite-yml/app.with.speacial.build.params.yml
new file mode 100644 (file)
index 0000000..6f57979
--- /dev/null
@@ -0,0 +1,80 @@
+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
+    srclibs:
+      - FacebookSDK@sdk-version-3.0.2
+    rm:
+      - libs/applovin*
+      - libs/mobileCore*
+    extlibs:
+      - android/android-support-v4.jar
+    prebuild: |-
+        cp 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.2
+    versionCode: 49
+    disable: Labelled as pre-release, so skipped
+
+ArchivePolicy: 0 versions
+AutoUpdateMode: None
+UpdateCheckMode: None
+CurrentVersion: 2.1.2
+CurrentVersionCode: 49
index 47801747db47e5660f44dc51325e31cf799a8579..1801ebc3aa3a551dbdee56c1199bd1f22e9aa4fc 100755 (executable)
@@ -61,6 +61,27 @@ class RewritemetaTest(unittest.TestCase):
                 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.speacial.build.params':
+                fdroidserver.metadata.write_metadata(os.path.join(testdir, appid + '.yml'), app)
+
+        # assert rewrite result
+        with open(os.path.join(testdir, 'app.with.speacial.build.params.yml'), 'r', encoding='utf-8') as result:
+            with open('metadata/rewrite-yml/app.with.speacial.build.params.yml', 'r', encoding='utf-8') as orig:
+                self.maxDiff = None
+                self.assertEqual(result.read(), orig.read())
+
 
 if __name__ == "__main__":
     parser = optparse.OptionParser()