mirror of
https://gitlab.com/fdroid/fdroidserver.git
synced 2024-11-18 20:50:10 +01:00
Merge branch 'antiFeatures-from-config' into 'master'
allow Anti-Features to include localized descriptions about why they were added Closes #683 See merge request fdroid/fdroidserver!1350
This commit is contained in:
commit
86343cbf18
@ -41,7 +41,7 @@ metadata_v0:
|
|||||||
image: registry.gitlab.com/fdroid/fdroidserver:buildserver
|
image: registry.gitlab.com/fdroid/fdroidserver:buildserver
|
||||||
variables:
|
variables:
|
||||||
GIT_DEPTH: 1000
|
GIT_DEPTH: 1000
|
||||||
RELEASE_COMMIT_ID: 0124b9dde99f9cab19c034cbc7d8cc6005a99b48 # 2.3a0
|
RELEASE_COMMIT_ID: 1c2187a53bfb7a92cb9837435ae3717aacf5920d # 2.3a0
|
||||||
script:
|
script:
|
||||||
- git fetch https://gitlab.com/fdroid/fdroidserver.git $RELEASE_COMMIT_ID
|
- git fetch https://gitlab.com/fdroid/fdroidserver.git $RELEASE_COMMIT_ID
|
||||||
- cd tests
|
- cd tests
|
||||||
|
@ -597,7 +597,14 @@ include tests/main.TestCase
|
|||||||
include tests/metadata/apk/info.guardianproject.urzip.yaml
|
include tests/metadata/apk/info.guardianproject.urzip.yaml
|
||||||
include tests/metadata/apk/org.dyndns.fules.ck.yaml
|
include tests/metadata/apk/org.dyndns.fules.ck.yaml
|
||||||
include tests/metadata/app.with.special.build.params.yml
|
include tests/metadata/app.with.special.build.params.yml
|
||||||
|
include tests/metadata/app.with.special.build.params/en-US/antifeatures/50_Ads.txt
|
||||||
|
include tests/metadata/app.with.special.build.params/en-US/antifeatures/50_Tracking.txt
|
||||||
|
include tests/metadata/app.with.special.build.params/en-US/antifeatures/Ads.txt
|
||||||
|
include tests/metadata/app.with.special.build.params/en-US/antifeatures/NoSourceSince.txt
|
||||||
|
include tests/metadata/app.with.special.build.params/zh-CN/antifeatures/49_Tracking.txt
|
||||||
|
include tests/metadata/app.with.special.build.params/zh-CN/antifeatures/50_Ads.txt
|
||||||
include tests/metadata/com.politedroid.yml
|
include tests/metadata/com.politedroid.yml
|
||||||
|
include tests/metadata/dump/app.with.special.build.params.yaml
|
||||||
include tests/metadata/dump/com.politedroid.yaml
|
include tests/metadata/dump/com.politedroid.yaml
|
||||||
include tests/metadata/dump/org.adaway.yaml
|
include tests/metadata/dump/org.adaway.yaml
|
||||||
include tests/metadata/dump/org.smssecure.smssecure.yaml
|
include tests/metadata/dump/org.smssecure.smssecure.yaml
|
||||||
|
@ -546,6 +546,13 @@ def package_metadata(app, repodir):
|
|||||||
|
|
||||||
|
|
||||||
def convert_version(version, app, repodir):
|
def convert_version(version, app, repodir):
|
||||||
|
"""Convert the internal representation of Builds: into index-v2 versions.
|
||||||
|
|
||||||
|
The diff algorithm of index-v2 uses null/None to mean a field to
|
||||||
|
be removed, so this function handles any Nones that are in the
|
||||||
|
metadata file.
|
||||||
|
|
||||||
|
"""
|
||||||
ver = {}
|
ver = {}
|
||||||
if "added" in version:
|
if "added" in version:
|
||||||
ver["added"] = convert_datetime(version["added"])
|
ver["added"] = convert_datetime(version["added"])
|
||||||
@ -555,7 +562,7 @@ def convert_version(version, app, repodir):
|
|||||||
ver["file"] = {
|
ver["file"] = {
|
||||||
"name": "/{}".format(version["apkName"]),
|
"name": "/{}".format(version["apkName"]),
|
||||||
version["hashType"]: version["hash"],
|
version["hashType"]: version["hash"],
|
||||||
"size": version["size"]
|
"size": version["size"],
|
||||||
}
|
}
|
||||||
|
|
||||||
ipfsCIDv1 = version.get("ipfsCIDv1")
|
ipfsCIDv1 = version.get("ipfsCIDv1")
|
||||||
@ -619,24 +626,14 @@ def convert_version(version, app, repodir):
|
|||||||
else:
|
else:
|
||||||
manifest[en].append({"name": perm[0]})
|
manifest[en].append({"name": perm[0]})
|
||||||
|
|
||||||
antiFeatures = dict()
|
# index-v2 has only per-version antifeatures, not per package.
|
||||||
if "AntiFeatures" in app and app["AntiFeatures"]:
|
antiFeatures = app.get('AntiFeatures', {})
|
||||||
for antif in app["AntiFeatures"]:
|
for name, descdict in version.get('antiFeatures', dict()).items():
|
||||||
# TODO: get reasons from fdroiddata
|
antiFeatures[name] = descdict
|
||||||
# ver["antiFeatures"][antif] = {"en-US": "reason"}
|
|
||||||
antiFeatures[antif] = dict()
|
|
||||||
|
|
||||||
if "antiFeatures" in version and version["antiFeatures"]:
|
|
||||||
for antif in version["antiFeatures"]:
|
|
||||||
# TODO: get reasons from fdroiddata
|
|
||||||
# ver["antiFeatures"][antif] = {"en-US": "reason"}
|
|
||||||
antiFeatures[antif] = dict()
|
|
||||||
|
|
||||||
if app.get("NoSourceSince"):
|
|
||||||
antiFeatures["NoSourceSince"] = dict()
|
|
||||||
|
|
||||||
if antiFeatures:
|
if antiFeatures:
|
||||||
ver["antiFeatures"] = dict(sorted(antiFeatures.items()))
|
ver['antiFeatures'] = {
|
||||||
|
k: dict(sorted(antiFeatures[k].items())) for k in sorted(antiFeatures)
|
||||||
|
}
|
||||||
|
|
||||||
if "versionCode" in version:
|
if "versionCode" in version:
|
||||||
if version["versionCode"] > app["CurrentVersionCode"]:
|
if version["versionCode"] > app["CurrentVersionCode"]:
|
||||||
@ -881,9 +878,8 @@ def make_v1(apps, packages, repodir, repodict, requestsdict, fdroid_signing_key_
|
|||||||
for ikey, iname in sorted(lvalue.items()):
|
for ikey, iname in sorted(lvalue.items()):
|
||||||
lordered[lkey][ikey] = iname
|
lordered[lkey][ikey] = iname
|
||||||
app_dict['localized'] = lordered
|
app_dict['localized'] = lordered
|
||||||
antiFeatures = app_dict.get('antiFeatures', [])
|
# v1 uses a list of keys for Anti-Features
|
||||||
if apps[app_dict["packageName"]].get("NoSourceSince"):
|
antiFeatures = app_dict.get('antiFeatures', dict()).keys()
|
||||||
antiFeatures.append("NoSourceSince")
|
|
||||||
if antiFeatures:
|
if antiFeatures:
|
||||||
app_dict['antiFeatures'] = sorted(set(antiFeatures))
|
app_dict['antiFeatures'] = sorted(set(antiFeatures))
|
||||||
|
|
||||||
@ -915,6 +911,9 @@ def make_v1(apps, packages, repodir, repodict, requestsdict, fdroid_signing_key_
|
|||||||
continue
|
continue
|
||||||
if k in ('icon', 'icons', 'icons_src', 'ipfsCIDv1', 'name'):
|
if k in ('icon', 'icons', 'icons_src', 'ipfsCIDv1', 'name'):
|
||||||
continue
|
continue
|
||||||
|
if k == 'antiFeatures':
|
||||||
|
d[k] = sorted(v.keys())
|
||||||
|
continue
|
||||||
d[k] = v
|
d[k] = v
|
||||||
|
|
||||||
json_name = 'index-v1.json'
|
json_name = 'index-v1.json'
|
||||||
@ -1160,8 +1159,6 @@ def make_v0(apps, apks, repodir, repodict, requestsdict, fdroid_signing_key_fing
|
|||||||
antiFeatures = list(app.AntiFeatures)
|
antiFeatures = list(app.AntiFeatures)
|
||||||
if 'antiFeatures' in apklist[0]:
|
if 'antiFeatures' in apklist[0]:
|
||||||
antiFeatures.extend(apklist[0]['antiFeatures'])
|
antiFeatures.extend(apklist[0]['antiFeatures'])
|
||||||
if app.get("NoSourceSince"):
|
|
||||||
antiFeatures.append("NoSourceSince")
|
|
||||||
if antiFeatures:
|
if antiFeatures:
|
||||||
afout = sorted(set(antiFeatures))
|
afout = sorted(set(antiFeatures))
|
||||||
addElementNonEmpty('antifeatures', ','.join(afout), doc, apel)
|
addElementNonEmpty('antifeatures', ','.join(afout), doc, apel)
|
||||||
|
@ -624,6 +624,17 @@ def check_app_field_types(app):
|
|||||||
fieldtype=v.__class__.__name__,
|
fieldtype=v.__class__.__name__,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
elif t == metadata.TYPE_STRINGMAP and not isinstance(v, dict):
|
||||||
|
yield (
|
||||||
|
_(
|
||||||
|
"{appid}: {field} must be a '{type}', but it is a '{fieldtype}'!"
|
||||||
|
).format(
|
||||||
|
appid=app.id,
|
||||||
|
field=field,
|
||||||
|
type='dict',
|
||||||
|
fieldtype=v.__class__.__name__,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def check_antiFeatures(app):
|
def check_antiFeatures(app):
|
||||||
|
@ -114,7 +114,7 @@ class App(dict):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
self.Disabled = None
|
self.Disabled = None
|
||||||
self.AntiFeatures = []
|
self.AntiFeatures = dict()
|
||||||
self.Provides = None
|
self.Provides = None
|
||||||
self.Categories = []
|
self.Categories = []
|
||||||
self.License = 'Unknown'
|
self.License = 'Unknown'
|
||||||
@ -182,12 +182,14 @@ TYPE_SCRIPT = 5
|
|||||||
TYPE_MULTILINE = 6
|
TYPE_MULTILINE = 6
|
||||||
TYPE_BUILD = 7
|
TYPE_BUILD = 7
|
||||||
TYPE_INT = 8
|
TYPE_INT = 8
|
||||||
|
TYPE_STRINGMAP = 9
|
||||||
|
|
||||||
fieldtypes = {
|
fieldtypes = {
|
||||||
'Description': TYPE_MULTILINE,
|
'Description': TYPE_MULTILINE,
|
||||||
'MaintainerNotes': TYPE_MULTILINE,
|
'MaintainerNotes': TYPE_MULTILINE,
|
||||||
'Categories': TYPE_LIST,
|
'Categories': TYPE_LIST,
|
||||||
'AntiFeatures': TYPE_LIST,
|
'AntiFeatures': TYPE_STRINGMAP,
|
||||||
|
'RequiresRoot': TYPE_BOOL,
|
||||||
'AllowedAPKSigningKeys': TYPE_LIST,
|
'AllowedAPKSigningKeys': TYPE_LIST,
|
||||||
'Builds': TYPE_BUILD,
|
'Builds': TYPE_BUILD,
|
||||||
'VercodeOperation': TYPE_LIST,
|
'VercodeOperation': TYPE_LIST,
|
||||||
@ -277,7 +279,7 @@ class Build(dict):
|
|||||||
self.antcommands = []
|
self.antcommands = []
|
||||||
self.postbuild = ''
|
self.postbuild = ''
|
||||||
self.novcheck = False
|
self.novcheck = False
|
||||||
self.antifeatures = []
|
self.antifeatures = dict()
|
||||||
if copydict:
|
if copydict:
|
||||||
super().__init__(copydict)
|
super().__init__(copydict)
|
||||||
return
|
return
|
||||||
@ -358,7 +360,7 @@ flagtypes = {
|
|||||||
'forceversion': TYPE_BOOL,
|
'forceversion': TYPE_BOOL,
|
||||||
'forcevercode': TYPE_BOOL,
|
'forcevercode': TYPE_BOOL,
|
||||||
'novcheck': TYPE_BOOL,
|
'novcheck': TYPE_BOOL,
|
||||||
'antifeatures': TYPE_LIST,
|
'antifeatures': TYPE_STRINGMAP,
|
||||||
'timeout': TYPE_INT,
|
'timeout': TYPE_INT,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -649,8 +651,6 @@ def parse_metadata(metadatapath):
|
|||||||
metadatapath = Path(metadatapath)
|
metadatapath = Path(metadatapath)
|
||||||
app = App()
|
app = App()
|
||||||
app.metadatapath = metadatapath.as_posix()
|
app.metadatapath = metadatapath.as_posix()
|
||||||
if metadatapath.stem != '.fdroid':
|
|
||||||
app.id = metadatapath.stem
|
|
||||||
if metadatapath.suffix == '.yml':
|
if metadatapath.suffix == '.yml':
|
||||||
with metadatapath.open('r', encoding='utf-8') as mf:
|
with metadatapath.open('r', encoding='utf-8') as mf:
|
||||||
app.update(parse_yaml_metadata(mf))
|
app.update(parse_yaml_metadata(mf))
|
||||||
@ -659,6 +659,10 @@ def parse_metadata(metadatapath):
|
|||||||
_('Unknown metadata format: {path} (use: *.yml)').format(path=metadatapath)
|
_('Unknown metadata format: {path} (use: *.yml)').format(path=metadatapath)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if metadatapath.stem != '.fdroid':
|
||||||
|
app.id = metadatapath.stem
|
||||||
|
parse_localized_antifeatures(app)
|
||||||
|
|
||||||
if metadatapath.name != '.fdroid.yml' and app.Repo:
|
if metadatapath.name != '.fdroid.yml' and app.Repo:
|
||||||
build_dir = common.get_build_dir(app)
|
build_dir = common.get_build_dir(app)
|
||||||
metadata_in_repo = build_dir / '.fdroid.yml'
|
metadata_in_repo = build_dir / '.fdroid.yml'
|
||||||
@ -770,6 +774,115 @@ def parse_yaml_metadata(mf):
|
|||||||
return yamldata
|
return yamldata
|
||||||
|
|
||||||
|
|
||||||
|
def parse_localized_antifeatures(app):
|
||||||
|
"""Read in localized Anti-Features files from the filesystem.
|
||||||
|
|
||||||
|
To support easy integration with Weblate and other translation
|
||||||
|
systems, there is a special type of metadata that can be
|
||||||
|
maintained in a Fastlane-style directory layout, where each field
|
||||||
|
is represented by a text file on directories that specified which
|
||||||
|
app it belongs to, which locale, etc. This function reads those
|
||||||
|
in and puts them into the internal dict, to be merged with any
|
||||||
|
related data that came from the metadata.yml file.
|
||||||
|
|
||||||
|
This needs to be run after parse_yaml_metadata() since that
|
||||||
|
normalizes the data structure. Also, these values are lower
|
||||||
|
priority than what comes from the metadata file. So this should
|
||||||
|
not overwrite anything parse_yaml_metadata() puts into the App
|
||||||
|
instance.
|
||||||
|
|
||||||
|
metadata/<Application ID>/<locale>/antifeatures/<Version Code>_<Anti-Feature>.txt
|
||||||
|
metadata/<Application ID>/<locale>/antifeatures/<Anti-Feature>.txt
|
||||||
|
|
||||||
|
└── metadata/
|
||||||
|
└── <Application ID>/
|
||||||
|
├── en-US/
|
||||||
|
│ └── antifeatures/
|
||||||
|
│ ├── 123_Ads.txt -> "includes ad lib"
|
||||||
|
│ ├── 123_Tracking.txt -> "standard suspects"
|
||||||
|
│ └── NoSourceSince.txt -> "it vanished"
|
||||||
|
│
|
||||||
|
└── zh-CN/
|
||||||
|
└── antifeatures/
|
||||||
|
└── 123_Ads.txt -> "包括广告图书馆"
|
||||||
|
|
||||||
|
Gets parsed into the metadata data structure:
|
||||||
|
|
||||||
|
AntiFeatures:
|
||||||
|
NoSourceSince:
|
||||||
|
en-US: it vanished
|
||||||
|
Builds:
|
||||||
|
- versionCode: 123
|
||||||
|
antifeatures:
|
||||||
|
Ads:
|
||||||
|
en-US: includes ad lib
|
||||||
|
zh-CN: 包括广告图书馆
|
||||||
|
Tracking:
|
||||||
|
en-US: standard suspects
|
||||||
|
|
||||||
|
"""
|
||||||
|
app_dir = Path('metadata', app['id'])
|
||||||
|
if not app_dir.is_dir():
|
||||||
|
return
|
||||||
|
af_dup_msg = _('Duplicate Anti-Feature declaration at {path} was ignored!')
|
||||||
|
|
||||||
|
if app.get('AntiFeatures'):
|
||||||
|
app_has_AntiFeatures = True
|
||||||
|
else:
|
||||||
|
app_has_AntiFeatures = False
|
||||||
|
|
||||||
|
has_versionCode = re.compile(r'^-?[0-9]+_.*')
|
||||||
|
has_antifeatures_from_app = set()
|
||||||
|
for build in app.get('Builds', []):
|
||||||
|
antifeatures = build.get('antifeatures')
|
||||||
|
if antifeatures:
|
||||||
|
has_antifeatures_from_app.add(build['versionCode'])
|
||||||
|
|
||||||
|
for f in sorted(app_dir.glob('*/antifeatures/*.txt')):
|
||||||
|
path = f.as_posix()
|
||||||
|
left = path.index('/', 9) # 9 is length of "metadata/"
|
||||||
|
right = path.index('/', left + 1)
|
||||||
|
locale = path[left + 1 : right]
|
||||||
|
description = f.read_text()
|
||||||
|
if has_versionCode.match(f.stem):
|
||||||
|
i = f.stem.index('_')
|
||||||
|
versionCode = int(f.stem[:i])
|
||||||
|
antifeature = f.stem[i + 1 :]
|
||||||
|
if versionCode in has_antifeatures_from_app:
|
||||||
|
logging.error(af_dup_msg.format(path=f))
|
||||||
|
continue
|
||||||
|
if 'Builds' not in app:
|
||||||
|
app['Builds'] = []
|
||||||
|
found = False
|
||||||
|
for build in app['Builds']:
|
||||||
|
# loop though builds again, there might be duplicate versionCodes
|
||||||
|
if versionCode == build['versionCode']:
|
||||||
|
found = True
|
||||||
|
if 'antifeatures' not in build:
|
||||||
|
build['antifeatures'] = dict()
|
||||||
|
if antifeature not in build['antifeatures']:
|
||||||
|
build['antifeatures'][antifeature] = dict()
|
||||||
|
build['antifeatures'][antifeature][locale] = description
|
||||||
|
if not found:
|
||||||
|
app['Builds'].append(
|
||||||
|
{
|
||||||
|
'versionCode': versionCode,
|
||||||
|
'antifeatures': {
|
||||||
|
antifeature: {locale: description},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
elif app_has_AntiFeatures:
|
||||||
|
logging.error(af_dup_msg.format(path=f))
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
if 'AntiFeatures' not in app:
|
||||||
|
app['AntiFeatures'] = dict()
|
||||||
|
if f.stem not in app['AntiFeatures']:
|
||||||
|
app['AntiFeatures'][f.stem] = dict()
|
||||||
|
app['AntiFeatures'][f.stem][locale] = f.read_text()
|
||||||
|
|
||||||
|
|
||||||
def _normalize_type_string(v):
|
def _normalize_type_string(v):
|
||||||
"""Normalize any data to TYPE_STRING.
|
"""Normalize any data to TYPE_STRING.
|
||||||
|
|
||||||
@ -787,6 +900,61 @@ def _normalize_type_string(v):
|
|||||||
return str(v)
|
return str(v)
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_type_stringmap(k, v):
|
||||||
|
"""Normalize any data to TYPE_STRINGMAP.
|
||||||
|
|
||||||
|
The internal representation of this format is a dict of dicts,
|
||||||
|
where the outer dict's keys are things like tag names of
|
||||||
|
Anti-Features, the inner dict's keys are locales, and the ultimate
|
||||||
|
values are human readable text.
|
||||||
|
|
||||||
|
Metadata entries like AntiFeatures: can be written in many
|
||||||
|
forms, including a simple one-entry string, a list of strings,
|
||||||
|
a dict with keys and descriptions as values, or a dict with
|
||||||
|
localization.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
A dictionary with string keys, where each value is either a string
|
||||||
|
message or a dict with locale keys and string message values.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if v is None:
|
||||||
|
return dict()
|
||||||
|
if isinstance(v, str) or isinstance(v, int) or isinstance(v, float):
|
||||||
|
return {_normalize_type_string(v): dict()}
|
||||||
|
if isinstance(v, list) or isinstance(v, tuple) or isinstance(v, set):
|
||||||
|
retdict = dict()
|
||||||
|
for i in v:
|
||||||
|
if isinstance(i, dict):
|
||||||
|
# transitional format
|
||||||
|
if len(i) != 1:
|
||||||
|
_warn_or_exception(
|
||||||
|
_(
|
||||||
|
"'{value}' is not a valid {field}, should be {pattern}"
|
||||||
|
).format(field=k, value=v, pattern='key: value')
|
||||||
|
)
|
||||||
|
afname = _normalize_type_string(next(iter(i)))
|
||||||
|
desc = _normalize_type_string(next(iter(i.values())))
|
||||||
|
retdict[afname] = {common.DEFAULT_LOCALE: desc}
|
||||||
|
else:
|
||||||
|
retdict[_normalize_type_string(i)] = {}
|
||||||
|
return retdict
|
||||||
|
|
||||||
|
retdict = dict()
|
||||||
|
for af, afdict in v.items():
|
||||||
|
key = _normalize_type_string(af)
|
||||||
|
if afdict:
|
||||||
|
if isinstance(afdict, dict):
|
||||||
|
retdict[key] = afdict
|
||||||
|
else:
|
||||||
|
retdict[key] = {common.DEFAULT_LOCALE: _normalize_type_string(afdict)}
|
||||||
|
else:
|
||||||
|
retdict[key] = dict()
|
||||||
|
|
||||||
|
return retdict
|
||||||
|
|
||||||
|
|
||||||
def post_parse_yaml_metadata(yamldata):
|
def post_parse_yaml_metadata(yamldata):
|
||||||
"""Convert human-readable metadata data structures into consistent data structures.
|
"""Convert human-readable metadata data structures into consistent data structures.
|
||||||
|
|
||||||
@ -808,6 +976,9 @@ def post_parse_yaml_metadata(yamldata):
|
|||||||
elif _fieldtype == TYPE_STRING:
|
elif _fieldtype == TYPE_STRING:
|
||||||
if v or v == 0:
|
if v or v == 0:
|
||||||
yamldata[k] = _normalize_type_string(v)
|
yamldata[k] = _normalize_type_string(v)
|
||||||
|
elif _fieldtype == TYPE_STRINGMAP:
|
||||||
|
if v or v == 0: # TODO probably want just `if v:`
|
||||||
|
yamldata[k] = _normalize_type_stringmap(k, v)
|
||||||
else:
|
else:
|
||||||
if type(v) in (float, int):
|
if type(v) in (float, int):
|
||||||
yamldata[k] = str(v)
|
yamldata[k] = str(v)
|
||||||
@ -843,12 +1014,187 @@ def post_parse_yaml_metadata(yamldata):
|
|||||||
build_flag=k, value=v
|
build_flag=k, value=v
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
elif _flagtype == TYPE_STRINGMAP:
|
||||||
|
if v or v == 0:
|
||||||
|
build[k] = _normalize_type_stringmap(k, v)
|
||||||
|
|
||||||
builds.append(build)
|
builds.append(build)
|
||||||
|
|
||||||
if builds:
|
if builds:
|
||||||
yamldata['Builds'] = sorted(builds, key=lambda build: build['versionCode'])
|
yamldata['Builds'] = sorted(builds, key=lambda build: build['versionCode'])
|
||||||
|
|
||||||
|
no_source_since = yamldata.get("NoSourceSince")
|
||||||
|
# do not overwrite the description if it is there
|
||||||
|
if no_source_since and not yamldata.get('AntiFeatures', {}).get('NoSourceSince'):
|
||||||
|
if 'AntiFeatures' not in yamldata:
|
||||||
|
yamldata['AntiFeatures'] = dict()
|
||||||
|
yamldata['AntiFeatures']['NoSourceSince'] = {
|
||||||
|
common.DEFAULT_LOCALE: no_source_since
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _format_stringmap(appid, field, stringmap, versionCode=None):
|
||||||
|
"""Format TYPE_STRINGMAP taking into account localized files in the metadata dir.
|
||||||
|
|
||||||
|
If there are any localized versions on the filesystem already,
|
||||||
|
then move them all there. Otherwise, keep them in the .yml file.
|
||||||
|
|
||||||
|
The directory for the localized files that is named after the
|
||||||
|
field is all lower case, following the convention set by Fastlane
|
||||||
|
metadata, and used by fdroidserver.
|
||||||
|
|
||||||
|
"""
|
||||||
|
app_dir = Path('metadata', appid)
|
||||||
|
try:
|
||||||
|
next(app_dir.glob('*/%s/*.txt' % field.lower()))
|
||||||
|
files = []
|
||||||
|
overwrites = []
|
||||||
|
for name, descdict in stringmap.items():
|
||||||
|
for locale, desc in descdict.items():
|
||||||
|
outdir = app_dir / locale / field.lower()
|
||||||
|
if versionCode:
|
||||||
|
filename = '%d_%s.txt' % (versionCode, name)
|
||||||
|
else:
|
||||||
|
filename = '%s.txt' % name
|
||||||
|
outfile = outdir / filename
|
||||||
|
files.append(str(outfile))
|
||||||
|
if outfile.exists():
|
||||||
|
if desc != outfile.read_text():
|
||||||
|
overwrites.append(str(outfile))
|
||||||
|
else:
|
||||||
|
if not outfile.parent.exists():
|
||||||
|
outfile.parent.mkdir(parents=True)
|
||||||
|
outfile.write_text(desc)
|
||||||
|
if overwrites:
|
||||||
|
_warn_or_exception(
|
||||||
|
_(
|
||||||
|
'Conflicting "{field}" definitions between .yml and localized files:'
|
||||||
|
).format(field=field)
|
||||||
|
+ '\n'
|
||||||
|
+ '\n'.join(sorted(overwrites))
|
||||||
|
)
|
||||||
|
logging.warning(
|
||||||
|
_('Moving Anti-Features declarations to localized files:')
|
||||||
|
+ '\n'
|
||||||
|
+ '\n'.join(sorted(files))
|
||||||
|
)
|
||||||
|
return
|
||||||
|
except StopIteration:
|
||||||
|
pass
|
||||||
|
make_list = True
|
||||||
|
outlist = []
|
||||||
|
for name in sorted(stringmap):
|
||||||
|
outlist.append(name)
|
||||||
|
descdict = stringmap.get(name)
|
||||||
|
if descdict and any(descdict.values()):
|
||||||
|
make_list = False
|
||||||
|
break
|
||||||
|
if make_list:
|
||||||
|
return outlist
|
||||||
|
return stringmap
|
||||||
|
|
||||||
|
|
||||||
|
def _del_duplicated_NoSourceSince(app):
|
||||||
|
# noqa: D403 NoSourceSince is the word.
|
||||||
|
"""NoSourceSince gets auto-added to AntiFeatures, but can also be manually added."""
|
||||||
|
key = 'NoSourceSince'
|
||||||
|
if key in app:
|
||||||
|
no_source_since = app.get(key)
|
||||||
|
af_no_source_since = app.get('AntiFeatures', dict()).get(key)
|
||||||
|
if af_no_source_since == {common.DEFAULT_LOCALE: no_source_since}:
|
||||||
|
del app['AntiFeatures'][key]
|
||||||
|
|
||||||
|
|
||||||
|
def _field_to_yaml(typ, value):
|
||||||
|
"""Convert data to YAML 1.2 format that keeps the right TYPE_*."""
|
||||||
|
if typ == TYPE_STRING:
|
||||||
|
return str(value)
|
||||||
|
elif typ == TYPE_INT:
|
||||||
|
return int(value)
|
||||||
|
elif typ == TYPE_MULTILINE:
|
||||||
|
if '\n' in value:
|
||||||
|
return ruamel.yaml.scalarstring.preserve_literal(str(value))
|
||||||
|
else:
|
||||||
|
return str(value)
|
||||||
|
elif typ == TYPE_SCRIPT:
|
||||||
|
if type(value) == list:
|
||||||
|
if len(value) == 1:
|
||||||
|
return value[0]
|
||||||
|
else:
|
||||||
|
return value
|
||||||
|
else:
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def _builds_to_yaml(app):
|
||||||
|
builds = ruamel.yaml.comments.CommentedSeq()
|
||||||
|
for build in app.get('Builds', []):
|
||||||
|
if not isinstance(build, Build):
|
||||||
|
build = Build(build)
|
||||||
|
b = ruamel.yaml.comments.CommentedMap()
|
||||||
|
for field in build_flags:
|
||||||
|
if hasattr(build, field):
|
||||||
|
value = getattr(build, field)
|
||||||
|
if field == 'gradle' and value == ['off']:
|
||||||
|
value = [
|
||||||
|
ruamel.yaml.scalarstring.SingleQuotedScalarString('off')
|
||||||
|
]
|
||||||
|
typ = flagtype(field)
|
||||||
|
# don't check value == True for TYPE_INT as it could be 0
|
||||||
|
if value and typ == TYPE_STRINGMAP:
|
||||||
|
v = _format_stringmap(app['id'], field, value, build['versionCode'])
|
||||||
|
if v:
|
||||||
|
b[field] = v
|
||||||
|
elif value is not None and (typ == TYPE_INT or value):
|
||||||
|
b.update({field: _field_to_yaml(typ, 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
|
||||||
|
|
||||||
|
|
||||||
|
def _app_to_yaml(app):
|
||||||
|
cm = ruamel.yaml.comments.CommentedMap()
|
||||||
|
insert_newline = False
|
||||||
|
for field in yaml_app_field_order:
|
||||||
|
if field == '\n':
|
||||||
|
# next iteration will need to insert a newline
|
||||||
|
insert_newline = True
|
||||||
|
else:
|
||||||
|
value = app.get(field)
|
||||||
|
if value or field == 'Builds':
|
||||||
|
if field == 'Builds':
|
||||||
|
if app.get('Builds'):
|
||||||
|
cm.update({field: _builds_to_yaml(app)})
|
||||||
|
elif field == 'CurrentVersionCode':
|
||||||
|
cm[field] = _field_to_yaml(TYPE_INT, value)
|
||||||
|
elif field == 'AntiFeatures':
|
||||||
|
v = _format_stringmap(app['id'], field, value)
|
||||||
|
if v:
|
||||||
|
cm[field] = v
|
||||||
|
elif field == 'AllowedAPKSigningKeys':
|
||||||
|
value = [str(i).lower() for i in value]
|
||||||
|
if len(value) == 1:
|
||||||
|
cm[field] = _field_to_yaml(TYPE_STRING, value[0])
|
||||||
|
else:
|
||||||
|
cm[field] = _field_to_yaml(TYPE_LIST, value)
|
||||||
|
else:
|
||||||
|
cm[field] = _field_to_yaml(fieldtype(field), value)
|
||||||
|
|
||||||
|
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 write_yaml(mf, app):
|
def write_yaml(mf, app):
|
||||||
"""Write metadata in yaml format.
|
"""Write metadata in yaml format.
|
||||||
@ -859,87 +1205,9 @@ def write_yaml(mf, app):
|
|||||||
active file discriptor for writing
|
active file discriptor for writing
|
||||||
app
|
app
|
||||||
app metadata to written to the yaml file
|
app metadata to written to the yaml file
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def _field_to_yaml(typ, value):
|
_del_duplicated_NoSourceSince(app)
|
||||||
"""Convert data to YAML 1.2 format that keeps the right TYPE_*."""
|
|
||||||
if typ == TYPE_STRING:
|
|
||||||
return str(value)
|
|
||||||
elif typ == TYPE_INT:
|
|
||||||
return int(value)
|
|
||||||
elif typ == TYPE_MULTILINE:
|
|
||||||
if '\n' in value:
|
|
||||||
return ruamel.yaml.scalarstring.preserve_literal(str(value))
|
|
||||||
else:
|
|
||||||
return str(value)
|
|
||||||
elif typ == TYPE_SCRIPT:
|
|
||||||
if type(value) == list:
|
|
||||||
if len(value) == 1:
|
|
||||||
return value[0]
|
|
||||||
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 == '\n':
|
|
||||||
# next iteration will need to insert a newline
|
|
||||||
insert_newline = True
|
|
||||||
else:
|
|
||||||
if app.get(field) or field == 'Builds':
|
|
||||||
if field == 'Builds':
|
|
||||||
if app.get('Builds'):
|
|
||||||
cm.update({field: _builds_to_yaml(app)})
|
|
||||||
elif field == 'CurrentVersionCode':
|
|
||||||
cm.update({field: _field_to_yaml(TYPE_INT, getattr(app, field))})
|
|
||||||
elif field == 'AllowedAPKSigningKeys':
|
|
||||||
value = getattr(app, field)
|
|
||||||
if value:
|
|
||||||
value = [str(i).lower() for i in value]
|
|
||||||
if len(value) == 1:
|
|
||||||
cm.update({field: _field_to_yaml(TYPE_STRING, value[0])})
|
|
||||||
else:
|
|
||||||
cm.update({field: _field_to_yaml(TYPE_LIST, value)})
|
|
||||||
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):
|
|
||||||
builds = ruamel.yaml.comments.CommentedSeq()
|
|
||||||
for build in app.get('Builds', []):
|
|
||||||
if not isinstance(build, Build):
|
|
||||||
build = Build(build)
|
|
||||||
b = ruamel.yaml.comments.CommentedMap()
|
|
||||||
for field in build_flags:
|
|
||||||
if hasattr(build, field):
|
|
||||||
value = getattr(build, field)
|
|
||||||
if field == 'gradle' and value == ['off']:
|
|
||||||
value = [
|
|
||||||
ruamel.yaml.scalarstring.SingleQuotedScalarString('off')
|
|
||||||
]
|
|
||||||
typ = flagtype(field)
|
|
||||||
# don't check value == True for TYPE_INT as it could be 0
|
|
||||||
if value is not None and (typ == TYPE_INT or value):
|
|
||||||
b.update({field: _field_to_yaml(typ, 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 = _app_to_yaml(app)
|
yaml_app = _app_to_yaml(app)
|
||||||
yaml = ruamel.yaml.YAML()
|
yaml = ruamel.yaml.YAML()
|
||||||
yaml.indent(mapping=4, sequence=4, offset=2)
|
yaml.indent(mapping=4, sequence=4, offset=2)
|
||||||
|
@ -52,8 +52,9 @@ def remove_blank_flags_from_builds(builds):
|
|||||||
for build in builds:
|
for build in builds:
|
||||||
new = dict()
|
new = dict()
|
||||||
for k in metadata.build_flags:
|
for k in metadata.build_flags:
|
||||||
v = build[k]
|
v = build.get(k)
|
||||||
if v is None or v is False or v == [] or v == '':
|
# 0 is valid value, it should not be stripped
|
||||||
|
if v is None or v is False or v == '' or v == dict() or v == list():
|
||||||
continue
|
continue
|
||||||
new[k] = v
|
new[k] = v
|
||||||
newbuilds.append(new)
|
newbuilds.append(new)
|
||||||
@ -98,6 +99,7 @@ def main():
|
|||||||
print(path)
|
print(path)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# TODO these should be moved to metadata.write_yaml()
|
||||||
builds = remove_blank_flags_from_builds(app.get('Builds'))
|
builds = remove_blank_flags_from_builds(app.get('Builds'))
|
||||||
if builds:
|
if builds:
|
||||||
app['Builds'] = builds
|
app['Builds'] = builds
|
||||||
|
@ -294,7 +294,7 @@ class ExodusSignatureDataController(SignatureDataController):
|
|||||||
"warn_code_signatures": [tracker["code_signature"]],
|
"warn_code_signatures": [tracker["code_signature"]],
|
||||||
# exodus also provides network signatures, unused atm.
|
# exodus also provides network signatures, unused atm.
|
||||||
# "network_signatures": [tracker["network_signature"]],
|
# "network_signatures": [tracker["network_signature"]],
|
||||||
"AntiFeatures": ["Tracking"],
|
"AntiFeatures": ["Tracking"], # TODO
|
||||||
"license": "NonFree" # We assume all trackers in exodus
|
"license": "NonFree" # We assume all trackers in exodus
|
||||||
# are non-free, although free
|
# are non-free, although free
|
||||||
# trackers like piwik, acra,
|
# trackers like piwik, acra,
|
||||||
|
@ -158,7 +158,7 @@ def status_update_json(apps, apks):
|
|||||||
|
|
||||||
for appid in apps:
|
for appid in apps:
|
||||||
app = apps[appid]
|
app = apps[appid]
|
||||||
for af in app.get('AntiFeatures', []):
|
for af in app.get('AntiFeatures', dict()):
|
||||||
antiFeatures = output['antiFeatures'] # JSON camelCase
|
antiFeatures = output['antiFeatures'] # JSON camelCase
|
||||||
if af not in antiFeatures:
|
if af not in antiFeatures:
|
||||||
antiFeatures[af] = dict()
|
antiFeatures[af] = dict()
|
||||||
@ -351,7 +351,8 @@ def get_cache():
|
|||||||
if not isinstance(v, dict):
|
if not isinstance(v, dict):
|
||||||
continue
|
continue
|
||||||
if 'antiFeatures' in v:
|
if 'antiFeatures' in v:
|
||||||
v['antiFeatures'] = set(v['antiFeatures'])
|
if not isinstance(v['antiFeatures'], dict):
|
||||||
|
v['antiFeatures'] = {k: {} for k in sorted(v['antiFeatures'])}
|
||||||
if 'added' in v:
|
if 'added' in v:
|
||||||
v['added'] = datetime.fromtimestamp(v['added'])
|
v['added'] = datetime.fromtimestamp(v['added'])
|
||||||
|
|
||||||
@ -400,7 +401,7 @@ def has_known_vulnerability(filename):
|
|||||||
Janus is similar to Master Key but is perhaps easier to scan for.
|
Janus is similar to Master Key but is perhaps easier to scan for.
|
||||||
https://www.guardsquare.com/en/blog/new-android-vulnerability-allows-attackers-modify-apps-without-affecting-their-signatures
|
https://www.guardsquare.com/en/blog/new-android-vulnerability-allows-attackers-modify-apps-without-affecting-their-signatures
|
||||||
"""
|
"""
|
||||||
found_vuln = False
|
found_vuln = ''
|
||||||
|
|
||||||
# statically load this pattern
|
# statically load this pattern
|
||||||
if not hasattr(has_known_vulnerability, "pattern"):
|
if not hasattr(has_known_vulnerability, "pattern"):
|
||||||
@ -431,15 +432,23 @@ def has_known_vulnerability(filename):
|
|||||||
logging.debug(_('"{path}" contains recent {name} ({version})')
|
logging.debug(_('"{path}" contains recent {name} ({version})')
|
||||||
.format(path=filename, name=name, version=version))
|
.format(path=filename, name=name, version=version))
|
||||||
else:
|
else:
|
||||||
logging.warning(_('"{path}" contains outdated {name} ({version})')
|
msg = '"{path}" contains outdated {name} ({version})'
|
||||||
.format(path=filename, name=name, version=version))
|
logging.warning(
|
||||||
found_vuln = True
|
_(msg).format(path=filename, name=name, version=version)
|
||||||
|
)
|
||||||
|
found_vuln += msg.format(
|
||||||
|
path=filename, name=name, version=version
|
||||||
|
)
|
||||||
|
found_vuln += '\n'
|
||||||
break
|
break
|
||||||
elif name == 'AndroidManifest.xml' or name == 'classes.dex' or name.endswith('.so'):
|
elif name == 'AndroidManifest.xml' or name == 'classes.dex' or name.endswith('.so'):
|
||||||
if name in files_in_apk:
|
if name in files_in_apk:
|
||||||
logging.warning(_('{apkfilename} has multiple {name} files, looks like Master Key exploit!')
|
msg = '{apkfilename} has multiple {name} files, looks like Master Key exploit!'
|
||||||
.format(apkfilename=filename, name=name))
|
logging.warning(
|
||||||
found_vuln = True
|
_(msg).format(apkfilename=filename, name=name)
|
||||||
|
)
|
||||||
|
found_vuln += msg.format(apkfilename=filename, name=name)
|
||||||
|
found_vuln += '\n'
|
||||||
files_in_apk.add(name)
|
files_in_apk.add(name)
|
||||||
return found_vuln
|
return found_vuln
|
||||||
|
|
||||||
@ -545,7 +554,7 @@ def translate_per_build_anti_features(apps, apks):
|
|||||||
if d:
|
if d:
|
||||||
afl = d.get(apk['versionCode'])
|
afl = d.get(apk['versionCode'])
|
||||||
if afl:
|
if afl:
|
||||||
apk['antiFeatures'].update(afl)
|
apk['antiFeatures'].update(afl) # TODO
|
||||||
|
|
||||||
|
|
||||||
def _get_localized_dict(app, locale):
|
def _get_localized_dict(app, locale):
|
||||||
@ -1228,7 +1237,7 @@ def scan_apk(apk_file, require_signature=True):
|
|||||||
'features': [],
|
'features': [],
|
||||||
'icons_src': {},
|
'icons_src': {},
|
||||||
'icons': {},
|
'icons': {},
|
||||||
'antiFeatures': set(),
|
'antiFeatures': {},
|
||||||
}
|
}
|
||||||
ipfsCIDv1 = common.calculate_IPFS_cid(apk_file)
|
ipfsCIDv1 = common.calculate_IPFS_cid(apk_file)
|
||||||
if ipfsCIDv1:
|
if ipfsCIDv1:
|
||||||
@ -1263,8 +1272,9 @@ def scan_apk(apk_file, require_signature=True):
|
|||||||
apk['minSdkVersion'] = 3 # aapt defaults to 3 as the min
|
apk['minSdkVersion'] = 3 # aapt defaults to 3 as the min
|
||||||
|
|
||||||
# Check for known vulnerabilities
|
# Check for known vulnerabilities
|
||||||
if has_known_vulnerability(apk_file):
|
hkv = has_known_vulnerability(apk_file)
|
||||||
apk['antiFeatures'].add('KnownVuln')
|
if hkv:
|
||||||
|
apk['antiFeatures']['KnownVuln'] = {DEFAULT_LOCALE: hkv}
|
||||||
|
|
||||||
return apk
|
return apk
|
||||||
|
|
||||||
@ -1545,7 +1555,7 @@ def process_apk(apkcache, apkfilename, repodir, knownapks, use_date_from_apk=Fal
|
|||||||
if repodir == 'archive' or allow_disabled_algorithms:
|
if repodir == 'archive' or allow_disabled_algorithms:
|
||||||
try:
|
try:
|
||||||
common.verify_deprecated_jar_signature(apkfile)
|
common.verify_deprecated_jar_signature(apkfile)
|
||||||
apk['antiFeatures'].update(['KnownVuln', 'DisabledAlgorithm'])
|
apk['antiFeatures'].update(['KnownVuln', 'DisabledAlgorithm']) # TODO
|
||||||
except VerificationException:
|
except VerificationException:
|
||||||
skipapk = True
|
skipapk = True
|
||||||
else:
|
else:
|
||||||
@ -1885,7 +1895,7 @@ def archive_old_apks(apps, apks, archapks, repodir, archivedir, defaultkeepversi
|
|||||||
for apk in all_app_apks:
|
for apk in all_app_apks:
|
||||||
if len(keep) == keepversions:
|
if len(keep) == keepversions:
|
||||||
break
|
break
|
||||||
if 'antiFeatures' not in apk:
|
if 'antiFeatures' not in apk: # TODO
|
||||||
keep.append(apk)
|
keep.append(apk)
|
||||||
elif 'DisabledAlgorithm' not in apk['antiFeatures'] or disabled_algorithms_allowed():
|
elif 'DisabledAlgorithm' not in apk['antiFeatures'] or disabled_algorithms_allowed():
|
||||||
keep.append(apk)
|
keep.append(apk)
|
||||||
|
@ -77,6 +77,9 @@ Builds:
|
|||||||
maven: yes@..
|
maven: yes@..
|
||||||
srclibs:
|
srclibs:
|
||||||
- FacebookSDK@sdk-version-3.0.2
|
- FacebookSDK@sdk-version-3.0.2
|
||||||
|
antifeatures:
|
||||||
|
Tracking:
|
||||||
|
en-US: Uses the Facebook SDK.
|
||||||
|
|
||||||
- versionName: 2.1.1-c
|
- versionName: 2.1.1-c
|
||||||
versionCode: 50
|
versionCode: 50
|
||||||
|
@ -26,6 +26,7 @@ if localmodule not in sys.path:
|
|||||||
import fdroidserver
|
import fdroidserver
|
||||||
from fdroidserver import metadata
|
from fdroidserver import metadata
|
||||||
from fdroidserver.exception import MetaDataException
|
from fdroidserver.exception import MetaDataException
|
||||||
|
from fdroidserver.common import DEFAULT_LOCALE
|
||||||
|
|
||||||
|
|
||||||
def _get_mock_mf(s):
|
def _get_mock_mf(s):
|
||||||
@ -203,7 +204,8 @@ class MetadataTest(unittest.TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('git.Repo')
|
@mock.patch('git.Repo')
|
||||||
def test_read_metadata(self, git_repo):
|
@mock.patch('logging.error')
|
||||||
|
def test_read_metadata(self, logging_error, git_repo):
|
||||||
"""Read specified metadata files included in tests/, compare to stored output"""
|
"""Read specified metadata files included in tests/, compare to stored output"""
|
||||||
|
|
||||||
self.maxDiff = None
|
self.maxDiff = None
|
||||||
@ -216,6 +218,7 @@ class MetadataTest(unittest.TestCase):
|
|||||||
yaml = ruamel.yaml.YAML(typ='safe')
|
yaml = ruamel.yaml.YAML(typ='safe')
|
||||||
apps = fdroidserver.metadata.read_metadata()
|
apps = fdroidserver.metadata.read_metadata()
|
||||||
for appid in (
|
for appid in (
|
||||||
|
'app.with.special.build.params',
|
||||||
'org.smssecure.smssecure',
|
'org.smssecure.smssecure',
|
||||||
'org.adaway',
|
'org.adaway',
|
||||||
'org.videolan.vlc',
|
'org.videolan.vlc',
|
||||||
@ -234,6 +237,10 @@ class MetadataTest(unittest.TestCase):
|
|||||||
# yaml.register_class(metadata.Build)
|
# yaml.register_class(metadata.Build)
|
||||||
# yaml.dump(frommeta, fp)
|
# yaml.dump(frommeta, fp)
|
||||||
|
|
||||||
|
# errors are printed when .yml overrides localized
|
||||||
|
logging_error.assert_called()
|
||||||
|
self.assertEqual(3, len(logging_error.call_args_list))
|
||||||
|
|
||||||
@mock.patch('git.Repo')
|
@mock.patch('git.Repo')
|
||||||
def test_metadata_overrides_dot_fdroid_yml(self, git_Repo):
|
def test_metadata_overrides_dot_fdroid_yml(self, git_Repo):
|
||||||
"""Fields in metadata files should override anything in .fdroid.yml."""
|
"""Fields in metadata files should override anything in .fdroid.yml."""
|
||||||
@ -254,7 +261,8 @@ class MetadataTest(unittest.TestCase):
|
|||||||
metadata.parse_metadata(yml) # should not throw an exception
|
metadata.parse_metadata(yml) # should not throw an exception
|
||||||
|
|
||||||
@mock.patch('git.Repo')
|
@mock.patch('git.Repo')
|
||||||
def test_rewrite_yaml_fakeotaupdate(self, git_Repo):
|
@mock.patch('logging.error')
|
||||||
|
def test_rewrite_yaml_fakeotaupdate(self, logging_error, git_Repo):
|
||||||
with tempfile.TemporaryDirectory() as testdir:
|
with tempfile.TemporaryDirectory() as testdir:
|
||||||
testdir = Path(testdir)
|
testdir = Path(testdir)
|
||||||
fdroidserver.common.config = {'accepted_formats': ['yml']}
|
fdroidserver.common.config = {'accepted_formats': ['yml']}
|
||||||
@ -276,6 +284,10 @@ class MetadataTest(unittest.TestCase):
|
|||||||
(Path('metadata-rewrite-yml') / file_name).read_text(encoding='utf-8'),
|
(Path('metadata-rewrite-yml') / file_name).read_text(encoding='utf-8'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# errors are printed when .yml overrides localized
|
||||||
|
logging_error.assert_called()
|
||||||
|
self.assertEqual(3, len(logging_error.call_args_list))
|
||||||
|
|
||||||
@mock.patch('git.Repo')
|
@mock.patch('git.Repo')
|
||||||
def test_rewrite_yaml_fdroidclient(self, git_Repo):
|
def test_rewrite_yaml_fdroidclient(self, git_Repo):
|
||||||
with tempfile.TemporaryDirectory() as testdir:
|
with tempfile.TemporaryDirectory() as testdir:
|
||||||
@ -300,24 +312,24 @@ class MetadataTest(unittest.TestCase):
|
|||||||
|
|
||||||
@mock.patch('git.Repo')
|
@mock.patch('git.Repo')
|
||||||
def test_rewrite_yaml_special_build_params(self, git_Repo):
|
def test_rewrite_yaml_special_build_params(self, git_Repo):
|
||||||
with tempfile.TemporaryDirectory() as testdir:
|
"""Test rewriting a plain YAML metadata file without localized files."""
|
||||||
testdir = Path(testdir)
|
os.chdir(self.testdir)
|
||||||
|
os.mkdir('metadata')
|
||||||
|
appid = 'app.with.special.build.params'
|
||||||
|
file_name = Path('metadata/%s.yml' % appid)
|
||||||
|
shutil.copy(self.basedir / file_name, file_name)
|
||||||
|
|
||||||
# rewrite metadata
|
# rewrite metadata
|
||||||
allapps = fdroidserver.metadata.read_metadata()
|
allapps = fdroidserver.metadata.read_metadata({appid: -1})
|
||||||
for appid, app in allapps.items():
|
for appid, app in allapps.items():
|
||||||
if appid == 'app.with.special.build.params':
|
metadata.write_metadata(file_name, app)
|
||||||
fdroidserver.metadata.write_metadata(
|
|
||||||
testdir / (appid + '.yml'), app
|
|
||||||
)
|
|
||||||
|
|
||||||
# assert rewrite result
|
# assert rewrite result
|
||||||
self.maxDiff = None
|
self.maxDiff = None
|
||||||
file_name = 'app.with.special.build.params.yml'
|
self.assertEqual(
|
||||||
self.assertEqual(
|
file_name.read_text(),
|
||||||
(testdir / file_name).read_text(encoding='utf-8'),
|
(self.basedir / 'metadata-rewrite-yml' / file_name.name).read_text(),
|
||||||
(Path('metadata-rewrite-yml') / file_name).read_text(encoding='utf-8'),
|
)
|
||||||
)
|
|
||||||
|
|
||||||
def test_normalize_type_string(self):
|
def test_normalize_type_string(self):
|
||||||
"""TYPE_STRING currently has some quirky behavior."""
|
"""TYPE_STRING currently has some quirky behavior."""
|
||||||
@ -331,6 +343,18 @@ class MetadataTest(unittest.TestCase):
|
|||||||
self.assertEqual('false', metadata._normalize_type_string(False))
|
self.assertEqual('false', metadata._normalize_type_string(False))
|
||||||
self.assertEqual('true', metadata._normalize_type_string(True))
|
self.assertEqual('true', metadata._normalize_type_string(True))
|
||||||
|
|
||||||
|
def test_normalize_type_stringmap_none(self):
|
||||||
|
self.assertEqual(dict(), metadata._normalize_type_stringmap('key', None))
|
||||||
|
|
||||||
|
def test_normalize_type_stringmap_empty_list(self):
|
||||||
|
self.assertEqual(dict(), metadata._normalize_type_stringmap('AntiFeatures', []))
|
||||||
|
|
||||||
|
def test_normalize_type_stringmap_simple_list_format(self):
|
||||||
|
self.assertEqual(
|
||||||
|
{'Ads': {}, 'Tracking': {}},
|
||||||
|
metadata._normalize_type_stringmap('AntiFeatures', ['Ads', 'Tracking']),
|
||||||
|
)
|
||||||
|
|
||||||
def test_post_parse_yaml_metadata(self):
|
def test_post_parse_yaml_metadata(self):
|
||||||
yamldata = dict()
|
yamldata = dict()
|
||||||
metadata.post_parse_yaml_metadata(yamldata)
|
metadata.post_parse_yaml_metadata(yamldata)
|
||||||
@ -507,6 +531,96 @@ class MetadataTest(unittest.TestCase):
|
|||||||
_warning.assert_called_once()
|
_warning.assert_called_once()
|
||||||
_error.assert_called_once()
|
_error.assert_called_once()
|
||||||
|
|
||||||
|
def test_parse_localized_antifeatures(self):
|
||||||
|
"""Unit test based on reading files included in the test repo."""
|
||||||
|
app = dict()
|
||||||
|
app['id'] = 'app.with.special.build.params'
|
||||||
|
metadata.parse_localized_antifeatures(app)
|
||||||
|
self.maxDiff = None
|
||||||
|
self.assertEqual(
|
||||||
|
app,
|
||||||
|
{
|
||||||
|
'AntiFeatures': {
|
||||||
|
'Ads': {'en-US': 'please no'},
|
||||||
|
'NoSourceSince': {'en-US': 'no activity\n'},
|
||||||
|
},
|
||||||
|
'Builds': [
|
||||||
|
{
|
||||||
|
'versionCode': 50,
|
||||||
|
'antifeatures': {
|
||||||
|
'Ads': {
|
||||||
|
'en-US': 'includes ad lib\n',
|
||||||
|
'zh-CN': '包括广告图书馆\n',
|
||||||
|
},
|
||||||
|
'Tracking': {'en-US': 'standard suspects\n'},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'versionCode': 49,
|
||||||
|
'antifeatures': {
|
||||||
|
'Tracking': {'zh-CN': 'Text from zh-CN/49_Tracking.txt'},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'id': app['id'],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_localized_antifeatures_passthrough(self):
|
||||||
|
"""Test app values are cleanly passed through if no localized files."""
|
||||||
|
before = {
|
||||||
|
'id': 'placeholder',
|
||||||
|
'AntiFeatures': {'NonFreeDep': {}},
|
||||||
|
'Builds': [{'versionCode': 999, 'antifeatures': {'zero': {}, 'one': {}}}],
|
||||||
|
}
|
||||||
|
after = copy.deepcopy(before)
|
||||||
|
with tempfile.TemporaryDirectory() as testdir:
|
||||||
|
os.chdir(testdir)
|
||||||
|
os.mkdir('metadata')
|
||||||
|
os.mkdir(os.path.join('metadata', after['id']))
|
||||||
|
metadata.parse_localized_antifeatures(after)
|
||||||
|
self.assertEqual(before, after)
|
||||||
|
|
||||||
|
def test_parse_metadata_antifeatures_NoSourceSince(self):
|
||||||
|
"""Test that NoSourceSince gets added as an Anti-Feature."""
|
||||||
|
os.chdir(self.testdir)
|
||||||
|
yml = Path('metadata/test.yml')
|
||||||
|
yml.parent.mkdir()
|
||||||
|
with yml.open('w') as fp:
|
||||||
|
fp.write('AntiFeatures: Ads\nNoSourceSince: gone\n')
|
||||||
|
app = metadata.parse_metadata(yml)
|
||||||
|
self.assertEqual(
|
||||||
|
app['AntiFeatures'], {'Ads': {}, 'NoSourceSince': {DEFAULT_LOCALE: 'gone'}}
|
||||||
|
)
|
||||||
|
|
||||||
|
@mock.patch('logging.error')
|
||||||
|
def test_yml_overrides_localized_antifeatures(self, logging_error):
|
||||||
|
"""Definitions in .yml files should override the localized versions."""
|
||||||
|
app = metadata.parse_metadata('metadata/app.with.special.build.params.yml')
|
||||||
|
|
||||||
|
self.assertEqual(app['AntiFeatures'], {'UpstreamNonFree': {}})
|
||||||
|
|
||||||
|
self.assertEqual(49, app['Builds'][-3]['versionCode'])
|
||||||
|
self.assertEqual(
|
||||||
|
app['Builds'][-3]['antifeatures'],
|
||||||
|
{'Tracking': {DEFAULT_LOCALE: 'Uses the Facebook SDK.'}},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(50, app['Builds'][-2]['versionCode'])
|
||||||
|
self.assertEqual(
|
||||||
|
app['Builds'][-2]['antifeatures'],
|
||||||
|
{
|
||||||
|
'Ads': {
|
||||||
|
'en-US': 'includes ad lib\n',
|
||||||
|
'zh-CN': '包括广告图书馆\n',
|
||||||
|
},
|
||||||
|
'Tracking': {'en-US': 'standard suspects\n'},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
# errors are printed when .yml overrides localized
|
||||||
|
logging_error.assert_called()
|
||||||
|
self.assertEqual(3, len(logging_error.call_args_list))
|
||||||
|
|
||||||
def test_parse_yaml_srclib_corrupt_file(self):
|
def test_parse_yaml_srclib_corrupt_file(self):
|
||||||
with tempfile.TemporaryDirectory() as testdir:
|
with tempfile.TemporaryDirectory() as testdir:
|
||||||
testdir = Path(testdir)
|
testdir = Path(testdir)
|
||||||
@ -741,6 +855,257 @@ class MetadataTest(unittest.TestCase):
|
|||||||
self.assertNotIn('Provides', result)
|
self.assertNotIn('Provides', result)
|
||||||
self.assertNotIn('provides', result)
|
self.assertNotIn('provides', result)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_dict(self):
|
||||||
|
nonfreenet = 'free it!'
|
||||||
|
tracking = 'so many'
|
||||||
|
mf = io.StringIO(
|
||||||
|
textwrap.dedent(
|
||||||
|
f"""
|
||||||
|
AntiFeatures:
|
||||||
|
Tracking: {tracking}
|
||||||
|
NonFreeNet: {nonfreenet}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(mf),
|
||||||
|
{
|
||||||
|
'AntiFeatures': {
|
||||||
|
'NonFreeNet': {DEFAULT_LOCALE: nonfreenet},
|
||||||
|
'Tracking': {DEFAULT_LOCALE: tracking},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_metadata_build_antifeatures_old_style(self):
|
||||||
|
mf = _get_mock_mf(
|
||||||
|
textwrap.dedent(
|
||||||
|
"""
|
||||||
|
AntiFeatures:
|
||||||
|
- Ads
|
||||||
|
Builds:
|
||||||
|
- versionCode: 123
|
||||||
|
antifeatures:
|
||||||
|
- KnownVuln
|
||||||
|
- UpstreamNonFree
|
||||||
|
- NonFreeAssets
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(mf),
|
||||||
|
{
|
||||||
|
'AntiFeatures': {'Ads': {}},
|
||||||
|
'Builds': [
|
||||||
|
{
|
||||||
|
'antifeatures': {
|
||||||
|
'KnownVuln': {},
|
||||||
|
'NonFreeAssets': {},
|
||||||
|
'UpstreamNonFree': {},
|
||||||
|
},
|
||||||
|
'versionCode': 123,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_metadata_antifeatures_sort(self):
|
||||||
|
"""All data should end up sorted, to minimize diffs in the index files."""
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(
|
||||||
|
_get_mock_mf(
|
||||||
|
textwrap.dedent(
|
||||||
|
"""
|
||||||
|
Builds:
|
||||||
|
- versionCode: 123
|
||||||
|
antifeatures:
|
||||||
|
KnownVuln:
|
||||||
|
es: 2nd
|
||||||
|
az: zero
|
||||||
|
en-US: first
|
||||||
|
UpstreamNonFree:
|
||||||
|
NonFreeAssets:
|
||||||
|
AntiFeatures:
|
||||||
|
NonFreeDep:
|
||||||
|
Ads:
|
||||||
|
sw: 2nd
|
||||||
|
zh-CN: 3rd
|
||||||
|
de: 1st
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
{
|
||||||
|
'AntiFeatures': {
|
||||||
|
'Ads': {'de': '1st', 'sw': '2nd', 'zh-CN': '3rd'},
|
||||||
|
'NonFreeDep': {},
|
||||||
|
},
|
||||||
|
'Builds': [
|
||||||
|
{
|
||||||
|
'antifeatures': {
|
||||||
|
'KnownVuln': {'az': 'zero', 'en-US': 'first', 'es': '2nd'},
|
||||||
|
'NonFreeAssets': {},
|
||||||
|
'UpstreamNonFree': {},
|
||||||
|
},
|
||||||
|
'versionCode': 123,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_str(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(io.StringIO('AntiFeatures: Tracking')),
|
||||||
|
{'AntiFeatures': {'Tracking': {}}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_bool(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(io.StringIO('AntiFeatures: true')),
|
||||||
|
{'AntiFeatures': {'true': {}}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_int(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(io.StringIO('AntiFeatures: 1')),
|
||||||
|
{'AntiFeatures': {'1': {}}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_float(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(io.StringIO('AntiFeatures: 1.0')),
|
||||||
|
{'AntiFeatures': {'1.0': {}}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_list_float(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(io.StringIO('AntiFeatures:\n - 1.0\n')),
|
||||||
|
{'AntiFeatures': {'1.0': {}}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_dict_float(self):
|
||||||
|
mf = io.StringIO('AntiFeatures:\n 0.0: too early\n')
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(mf),
|
||||||
|
{'AntiFeatures': {'0.0': {'en-US': 'too early'}}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_dict_float_fail_value(self):
|
||||||
|
mf = io.StringIO('AntiFeatures:\n NoSourceSince: 1.0\n')
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(mf),
|
||||||
|
{'AntiFeatures': {'NoSourceSince': {'en-US': '1.0'}}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_metadata_type_stringmap_old_list(self):
|
||||||
|
mf = _get_mock_mf(
|
||||||
|
textwrap.dedent(
|
||||||
|
"""
|
||||||
|
AntiFeatures:
|
||||||
|
- Ads
|
||||||
|
- Tracking
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
{'AntiFeatures': {'Ads': {}, 'Tracking': {}}},
|
||||||
|
metadata.parse_yaml_metadata(mf),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_dict_no_value(self):
|
||||||
|
mf = io.StringIO(
|
||||||
|
textwrap.dedent(
|
||||||
|
"""\
|
||||||
|
AntiFeatures:
|
||||||
|
Tracking:
|
||||||
|
NonFreeNet:
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(mf),
|
||||||
|
{'AntiFeatures': {'NonFreeNet': {}, 'Tracking': {}}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_metadata_type_stringmap_transitional(self):
|
||||||
|
"""Support a transitional format, where users just append a text"""
|
||||||
|
ads = 'Has ad lib in it.'
|
||||||
|
tracking = 'opt-out reports with ACRA'
|
||||||
|
mf = _get_mock_mf(
|
||||||
|
textwrap.dedent(
|
||||||
|
f"""
|
||||||
|
AntiFeatures:
|
||||||
|
- Ads: {ads}
|
||||||
|
- Tracking: {tracking}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(mf),
|
||||||
|
{
|
||||||
|
'AntiFeatures': {
|
||||||
|
'Ads': {DEFAULT_LOCALE: ads},
|
||||||
|
'Tracking': {DEFAULT_LOCALE: tracking},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_dict_mixed_values(self):
|
||||||
|
ads = 'true'
|
||||||
|
tracking = 'many'
|
||||||
|
nonfreenet = '1'
|
||||||
|
mf = io.StringIO(
|
||||||
|
textwrap.dedent(
|
||||||
|
f"""
|
||||||
|
AntiFeatures:
|
||||||
|
Ads: {ads}
|
||||||
|
Tracking: {tracking}
|
||||||
|
NonFreeNet: {nonfreenet}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(mf),
|
||||||
|
{
|
||||||
|
'AntiFeatures': {
|
||||||
|
'Ads': {DEFAULT_LOCALE: ads},
|
||||||
|
'NonFreeNet': {DEFAULT_LOCALE: nonfreenet},
|
||||||
|
'Tracking': {DEFAULT_LOCALE: tracking},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_parse_yaml_app_antifeatures_stringmap_full(self):
|
||||||
|
ads = 'watching'
|
||||||
|
tracking = 'many'
|
||||||
|
nonfreenet = 'pipes'
|
||||||
|
nonfreenet_zh = '非免费网络'
|
||||||
|
self.maxDiff = None
|
||||||
|
mf = io.StringIO(
|
||||||
|
textwrap.dedent(
|
||||||
|
f"""
|
||||||
|
AntiFeatures:
|
||||||
|
Ads:
|
||||||
|
{DEFAULT_LOCALE}: {ads}
|
||||||
|
Tracking:
|
||||||
|
{DEFAULT_LOCALE}: {tracking}
|
||||||
|
NonFreeNet:
|
||||||
|
{DEFAULT_LOCALE}: {nonfreenet}
|
||||||
|
zh-CN: {nonfreenet_zh}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
metadata.parse_yaml_metadata(mf),
|
||||||
|
{
|
||||||
|
'AntiFeatures': {
|
||||||
|
'Ads': {DEFAULT_LOCALE: ads},
|
||||||
|
'NonFreeNet': {DEFAULT_LOCALE: nonfreenet, 'zh-CN': nonfreenet_zh},
|
||||||
|
'Tracking': {DEFAULT_LOCALE: tracking},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def test_write_yaml_1_line_scripts_as_string(self):
|
def test_write_yaml_1_line_scripts_as_string(self):
|
||||||
mf = io.StringIO()
|
mf = io.StringIO()
|
||||||
app = fdroidserver.metadata.App()
|
app = fdroidserver.metadata.App()
|
||||||
@ -931,6 +1296,87 @@ class MetadataTest(unittest.TestCase):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_write_yaml_build_antifeatures(self):
|
||||||
|
mf = io.StringIO()
|
||||||
|
app = metadata.App(
|
||||||
|
{
|
||||||
|
'License': 'Apache-2.0',
|
||||||
|
'Builds': [
|
||||||
|
metadata.Build(
|
||||||
|
{
|
||||||
|
'versionCode': 102030,
|
||||||
|
'versionName': 'v1.2.3',
|
||||||
|
'gradle': ['yes'],
|
||||||
|
'antifeatures': {
|
||||||
|
'a': {},
|
||||||
|
'b': {'de': 'Probe', 'en-US': 'test'},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
],
|
||||||
|
'id': 'placeholder',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
metadata.write_yaml(mf, app)
|
||||||
|
mf.seek(0)
|
||||||
|
self.assertEqual(
|
||||||
|
mf.read(),
|
||||||
|
textwrap.dedent(
|
||||||
|
"""\
|
||||||
|
License: Apache-2.0
|
||||||
|
|
||||||
|
Builds:
|
||||||
|
- versionName: v1.2.3
|
||||||
|
versionCode: 102030
|
||||||
|
gradle:
|
||||||
|
- yes
|
||||||
|
antifeatures:
|
||||||
|
a: {}
|
||||||
|
b:
|
||||||
|
de: Probe
|
||||||
|
en-US: test
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_write_yaml_build_antifeatures_old_style(self):
|
||||||
|
mf = io.StringIO()
|
||||||
|
app = metadata.App(
|
||||||
|
{
|
||||||
|
'License': 'Apache-2.0',
|
||||||
|
'Builds': [
|
||||||
|
metadata.Build(
|
||||||
|
{
|
||||||
|
'versionCode': 102030,
|
||||||
|
'versionName': 'v1.2.3',
|
||||||
|
'gradle': ['yes'],
|
||||||
|
'antifeatures': {'b': {}, 'a': {}},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
],
|
||||||
|
'id': 'placeholder',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
metadata.write_yaml(mf, app)
|
||||||
|
mf.seek(0)
|
||||||
|
self.assertEqual(
|
||||||
|
mf.read(),
|
||||||
|
textwrap.dedent(
|
||||||
|
"""\
|
||||||
|
License: Apache-2.0
|
||||||
|
|
||||||
|
Builds:
|
||||||
|
- versionName: v1.2.3
|
||||||
|
versionCode: 102030
|
||||||
|
gradle:
|
||||||
|
- yes
|
||||||
|
antifeatures:
|
||||||
|
- a
|
||||||
|
- b
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
def test_write_yaml_make_sure_provides_does_not_get_written(self):
|
def test_write_yaml_make_sure_provides_does_not_get_written(self):
|
||||||
mf = io.StringIO()
|
mf = io.StringIO()
|
||||||
app = fdroidserver.metadata.App()
|
app = fdroidserver.metadata.App()
|
||||||
@ -1248,6 +1694,219 @@ class MetadataTest(unittest.TestCase):
|
|||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
build.ndk_path()
|
build.ndk_path()
|
||||||
|
|
||||||
|
def test_del_duplicated_NoSourceSince(self):
|
||||||
|
app = {
|
||||||
|
'AntiFeatures': {'Ads': {}, 'NoSourceSince': {DEFAULT_LOCALE: '1.0'}},
|
||||||
|
'NoSourceSince': '1.0',
|
||||||
|
}
|
||||||
|
metadata._del_duplicated_NoSourceSince(app)
|
||||||
|
self.assertEqual(app, {'AntiFeatures': {'Ads': {}}, 'NoSourceSince': '1.0'})
|
||||||
|
|
||||||
|
def test_check_manually_extended_NoSourceSince(self):
|
||||||
|
app = {
|
||||||
|
'AntiFeatures': {'NoSourceSince': {DEFAULT_LOCALE: '1.0', 'de': '1,0'}},
|
||||||
|
'NoSourceSince': '1.0',
|
||||||
|
}
|
||||||
|
metadata._del_duplicated_NoSourceSince(app)
|
||||||
|
self.assertEqual(
|
||||||
|
app,
|
||||||
|
{
|
||||||
|
'AntiFeatures': {'NoSourceSince': {DEFAULT_LOCALE: '1.0', 'de': '1,0'}},
|
||||||
|
'NoSourceSince': '1.0',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_make_sure_nosourcesince_does_not_get_written(self):
|
||||||
|
appid = 'com.politedroid'
|
||||||
|
app = metadata.read_metadata({appid: -1})[appid]
|
||||||
|
builds = app['Builds']
|
||||||
|
app['Builds'] = [copy.deepcopy(builds[0])]
|
||||||
|
mf = io.StringIO()
|
||||||
|
metadata.write_yaml(mf, app)
|
||||||
|
mf.seek(0)
|
||||||
|
self.maxDiff = None
|
||||||
|
self.assertEqual(
|
||||||
|
mf.read(),
|
||||||
|
textwrap.dedent(
|
||||||
|
"""\
|
||||||
|
AntiFeatures:
|
||||||
|
- NonFreeNet
|
||||||
|
Categories:
|
||||||
|
- Time
|
||||||
|
License: GPL-3.0-only
|
||||||
|
SourceCode: https://github.com/miguelvps/PoliteDroid
|
||||||
|
IssueTracker: https://github.com/miguelvps/PoliteDroid/issues
|
||||||
|
|
||||||
|
AutoName: Polite Droid
|
||||||
|
Summary: Calendar tool
|
||||||
|
Description: Activates silent mode during calendar events.
|
||||||
|
|
||||||
|
RepoType: git
|
||||||
|
Repo: https://github.com/miguelvps/PoliteDroid.git
|
||||||
|
|
||||||
|
Builds:
|
||||||
|
- versionName: '1.2'
|
||||||
|
versionCode: 3
|
||||||
|
commit: 6a548e4b19
|
||||||
|
target: android-10
|
||||||
|
antifeatures:
|
||||||
|
- KnownVuln
|
||||||
|
- NonFreeAssets
|
||||||
|
- UpstreamNonFree
|
||||||
|
|
||||||
|
ArchivePolicy: 4 versions
|
||||||
|
AutoUpdateMode: Version v%v
|
||||||
|
UpdateCheckMode: Tags
|
||||||
|
CurrentVersion: '1.5'
|
||||||
|
CurrentVersionCode: 6
|
||||||
|
|
||||||
|
NoSourceSince: '1.5'
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_app_to_yaml_smokecheck(self):
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(metadata._app_to_yaml(dict()), ruamel.yaml.comments.CommentedMap)
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_app_to_yaml_build_list_empty(self):
|
||||||
|
app = metadata.App({'Builds': [metadata.Build({'rm': []})]})
|
||||||
|
self.assertEqual(dict(), metadata._app_to_yaml(app)['Builds'][0])
|
||||||
|
|
||||||
|
def test_app_to_yaml_build_list_string(self):
|
||||||
|
app = metadata.App({'Builds': [metadata.Build({'rm': 'one'})]})
|
||||||
|
self.assertEqual({'rm': 'one'}, metadata._app_to_yaml(app)['Builds'][0])
|
||||||
|
|
||||||
|
def test_app_to_yaml_build_list_one(self):
|
||||||
|
app = metadata.App({'Builds': [metadata.Build({'rm': ['one']})]})
|
||||||
|
self.assertEqual({'rm': ['one']}, metadata._app_to_yaml(app)['Builds'][0])
|
||||||
|
|
||||||
|
def test_app_to_yaml_build_list(self):
|
||||||
|
app = metadata.App({'Builds': [metadata.Build({'rm': ['b2', 'NO1']})]})
|
||||||
|
self.assertEqual({'rm': ['b2', 'NO1']}, metadata._app_to_yaml(app)['Builds'][0])
|
||||||
|
|
||||||
|
def test_app_to_yaml_AllowedAPKSigningKeys_two(self):
|
||||||
|
cm = metadata._app_to_yaml(metadata.App({'AllowedAPKSigningKeys': ['b', 'A']}))
|
||||||
|
self.assertEqual(['b', 'a'], cm['AllowedAPKSigningKeys'])
|
||||||
|
|
||||||
|
def test_app_to_yaml_AllowedAPKSigningKeys_one(self):
|
||||||
|
cm = metadata._app_to_yaml(metadata.App({'AllowedAPKSigningKeys': ['One']}))
|
||||||
|
self.assertEqual('one', cm['AllowedAPKSigningKeys'])
|
||||||
|
|
||||||
|
def test_app_to_yaml_int_hex(self):
|
||||||
|
cm = metadata._app_to_yaml(metadata.App({'CurrentVersionCode': 0xFF}))
|
||||||
|
self.assertEqual(255, cm['CurrentVersionCode'])
|
||||||
|
|
||||||
|
def test_app_to_yaml_int_underscore(self):
|
||||||
|
cm = metadata._app_to_yaml(metadata.App({'CurrentVersionCode': 1_2_3}))
|
||||||
|
self.assertEqual(123, cm['CurrentVersionCode'])
|
||||||
|
|
||||||
|
def test_app_to_yaml_int_0(self):
|
||||||
|
"""Document that 0 values fail to make it through."""
|
||||||
|
# TODO it should be possible to use `CurrentVersionCode: 0`
|
||||||
|
cm = metadata._app_to_yaml(metadata.App({'CurrentVersionCode': 0}))
|
||||||
|
self.assertFalse('CurrentVersionCode' in cm)
|
||||||
|
|
||||||
|
def test_format_stringmap_empty(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata._format_stringmap('🔥', 'test', dict()),
|
||||||
|
list(),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_format_stringmap_one_list(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata._format_stringmap('🔥', 'test', {'Tracking': {}, 'Ads': {}}),
|
||||||
|
['Ads', 'Tracking'],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_format_stringmap_one_list_empty_desc(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata._format_stringmap('🔥', 'test', {'NonFree': {}, 'Ads': {'en': ''}}),
|
||||||
|
['Ads', 'NonFree'],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_format_stringmap_three_list(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata._format_stringmap('🔥', 'test', {'B': {}, 'A': {}, 'C': {}}),
|
||||||
|
['A', 'B', 'C'],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_format_stringmap_two_dict(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata._format_stringmap('🔥', 'test', {'1': {'uz': 'a'}, '2': {}}),
|
||||||
|
{'1': {'uz': 'a'}, '2': {}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_format_stringmap_three_locales(self):
|
||||||
|
self.assertEqual(
|
||||||
|
metadata._format_stringmap(
|
||||||
|
'🔥', 'test', {'AF': {'uz': 'a', 'ko': 'b', 'zh': 'c'}}
|
||||||
|
),
|
||||||
|
{'AF': {'ko': 'b', 'uz': 'a', 'zh': 'c'}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_format_stringmap_move_build_antifeatures_to_filesystem(self):
|
||||||
|
os.chdir(self.testdir)
|
||||||
|
appid = 'a'
|
||||||
|
yml = Path('metadata/a.yml')
|
||||||
|
yml.parent.mkdir()
|
||||||
|
self.assertEqual(
|
||||||
|
metadata._format_stringmap(
|
||||||
|
appid, 'antifeatures', {'AF': {'uz': 'a', 'ko': 'b', 'zh': 'c'}}
|
||||||
|
),
|
||||||
|
{'AF': {'ko': 'b', 'uz': 'a', 'zh': 'c'}},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_format_stringmap_app_antifeatures_conflict(self):
|
||||||
|
"""Raise an error if a YAML Anti-Feature conflicts with a localized file."""
|
||||||
|
os.chdir(self.testdir)
|
||||||
|
appid = 'a'
|
||||||
|
field = 'AntiFeatures'
|
||||||
|
locale = 'ko'
|
||||||
|
yml = Path('metadata/a.yml')
|
||||||
|
antifeatures_ko = yml.parent / appid / locale / field.lower()
|
||||||
|
antifeatures_ko.mkdir(parents=True)
|
||||||
|
afname = 'Anti-🔥'
|
||||||
|
(antifeatures_ko / (afname + '.txt')).write_text('SOMETHING ELSE')
|
||||||
|
with self.assertRaises(MetaDataException):
|
||||||
|
metadata._format_stringmap(
|
||||||
|
appid, field, {afname: {'uz': 'a', locale: 'b', 'zh': 'c'}}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_format_stringmap_app_antifeatures_conflict_same_contents(self):
|
||||||
|
"""Raise an error if a YAML Anti-Feature conflicts with a localized file."""
|
||||||
|
os.chdir(self.testdir)
|
||||||
|
appid = 'a'
|
||||||
|
field = 'AntiFeatures'
|
||||||
|
locale = 'ko'
|
||||||
|
yml = Path('metadata/a.yml')
|
||||||
|
antifeatures_ko = yml.parent / appid / locale / field.lower()
|
||||||
|
antifeatures_ko.mkdir(parents=True)
|
||||||
|
afname = 'Anti-🔥'
|
||||||
|
(antifeatures_ko / (afname + '.txt')).write_text('b')
|
||||||
|
metadata._format_stringmap(
|
||||||
|
appid, field, {afname: {'uz': 'a', locale: 'b', 'zh': 'c'}}
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_format_stringmap_build_antifeatures_conflict(self):
|
||||||
|
"""Raise an error if a YAML Anti-Feature conflicts with a localized file."""
|
||||||
|
os.chdir(self.testdir)
|
||||||
|
appid = 'a'
|
||||||
|
field = 'antifeatures'
|
||||||
|
locale = 'ko'
|
||||||
|
versionCode = 123
|
||||||
|
yml = Path('metadata/a.yml')
|
||||||
|
antifeatures_ko = yml.parent / appid / locale / field.lower()
|
||||||
|
antifeatures_ko.mkdir(parents=True)
|
||||||
|
afname = 'Anti-🔥'
|
||||||
|
with (antifeatures_ko / ('%d_%s.txt' % (versionCode, afname))).open('w') as fp:
|
||||||
|
fp.write('SOMETHING ELSE')
|
||||||
|
with self.assertRaises(MetaDataException):
|
||||||
|
metadata._format_stringmap(
|
||||||
|
appid, field, {afname: {'uz': 'a', locale: 'b', 'zh': 'c'}}, versionCode
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class PostMetadataParseTest(unittest.TestCase):
|
class PostMetadataParseTest(unittest.TestCase):
|
||||||
"""Test the functions that post process the YAML input.
|
"""Test the functions that post process the YAML input.
|
||||||
@ -1263,9 +1922,9 @@ class PostMetadataParseTest(unittest.TestCase):
|
|||||||
fdroidserver.metadata.warnings_action = 'error'
|
fdroidserver.metadata.warnings_action = 'error'
|
||||||
|
|
||||||
def _post_metadata_parse_app_list(self, from_yaml, expected):
|
def _post_metadata_parse_app_list(self, from_yaml, expected):
|
||||||
app = {'AntiFeatures': from_yaml}
|
app = {'AllowedAPKSigningKeys': from_yaml}
|
||||||
metadata.post_parse_yaml_metadata(app)
|
metadata.post_parse_yaml_metadata(app)
|
||||||
return {'AntiFeatures': expected}, app
|
return {'AllowedAPKSigningKeys': expected}, app
|
||||||
|
|
||||||
def _post_metadata_parse_app_string(self, from_yaml, expected):
|
def _post_metadata_parse_app_string(self, from_yaml, expected):
|
||||||
app = {'Repo': from_yaml}
|
app = {'Repo': from_yaml}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
antiFeatures: !!set {}
|
antiFeatures: {}
|
||||||
features: []
|
features: []
|
||||||
hash: abfb3adb7496611749e7abfb014c5c789e3a02489e48a5c3665110d1b1acd931
|
hash: abfb3adb7496611749e7abfb014c5c789e3a02489e48a5c3665110d1b1acd931
|
||||||
hashType: sha256
|
hashType: sha256
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
antiFeatures: !!set {}
|
antiFeatures: {}
|
||||||
features: []
|
features: []
|
||||||
hash: 897486e1f857c6c0ee32ccbad0e1b8cd82f6d0e65a44a23f13f852d2b63a18c8
|
hash: 897486e1f857c6c0ee32ccbad0e1b8cd82f6d0e65a44a23f13f852d2b63a18c8
|
||||||
hashType: sha256
|
hashType: sha256
|
||||||
|
@ -77,6 +77,8 @@ Builds:
|
|||||||
maven: yes@..
|
maven: yes@..
|
||||||
srclibs:
|
srclibs:
|
||||||
- FacebookSDK@sdk-version-3.0.2
|
- FacebookSDK@sdk-version-3.0.2
|
||||||
|
antifeatures:
|
||||||
|
Tracking: Uses the Facebook SDK.
|
||||||
|
|
||||||
- versionName: 2.1.1-c
|
- versionName: 2.1.1-c
|
||||||
versionCode: 50
|
versionCode: 50
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
includes ad lib
|
@ -0,0 +1 @@
|
|||||||
|
standard suspects
|
@ -0,0 +1 @@
|
|||||||
|
please no
|
@ -0,0 +1 @@
|
|||||||
|
no activity
|
@ -0,0 +1 @@
|
|||||||
|
Text from zh-CN/49_Tracking.txt
|
@ -0,0 +1 @@
|
|||||||
|
包括广告图书馆
|
373
tests/metadata/dump/app.with.special.build.params.yaml
Normal file
373
tests/metadata/dump/app.with.special.build.params.yaml
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
AllowedAPKSigningKeys: []
|
||||||
|
AntiFeatures:
|
||||||
|
UpstreamNonFree: {}
|
||||||
|
ArchivePolicy: 0 versions
|
||||||
|
AuthorEmail: null
|
||||||
|
AuthorName: null
|
||||||
|
AuthorWebSite: null
|
||||||
|
AutoName: UberSync for Facebook
|
||||||
|
AutoUpdateMode: None
|
||||||
|
Binaries: null
|
||||||
|
Bitcoin: null
|
||||||
|
Builds:
|
||||||
|
- androidupdate: []
|
||||||
|
antcommands: []
|
||||||
|
antifeatures: {}
|
||||||
|
binary: null
|
||||||
|
build: ''
|
||||||
|
buildjni: []
|
||||||
|
commit: b3879c973e7cac3a3319
|
||||||
|
disable: ''
|
||||||
|
encoding: null
|
||||||
|
extlibs: []
|
||||||
|
forcevercode: false
|
||||||
|
forceversion: false
|
||||||
|
gradle: []
|
||||||
|
gradleprops: []
|
||||||
|
init: ''
|
||||||
|
maven: null
|
||||||
|
ndk: null
|
||||||
|
novcheck: false
|
||||||
|
oldsdkloc: false
|
||||||
|
output: null
|
||||||
|
patch: []
|
||||||
|
postbuild: ''
|
||||||
|
preassemble: []
|
||||||
|
prebuild: ''
|
||||||
|
rm: []
|
||||||
|
scandelete: []
|
||||||
|
scanignore: []
|
||||||
|
srclibs: []
|
||||||
|
subdir: null
|
||||||
|
submodules: false
|
||||||
|
sudo: ''
|
||||||
|
target: null
|
||||||
|
timeout: null
|
||||||
|
versionCode: 32
|
||||||
|
versionName: 1.0.0
|
||||||
|
- androidupdate: []
|
||||||
|
antcommands: []
|
||||||
|
antifeatures: {}
|
||||||
|
binary: null
|
||||||
|
build: ''
|
||||||
|
buildjni: []
|
||||||
|
commit: 252c8dd4c9
|
||||||
|
disable: ''
|
||||||
|
encoding: null
|
||||||
|
extlibs: []
|
||||||
|
forcevercode: false
|
||||||
|
forceversion: false
|
||||||
|
gradle: []
|
||||||
|
gradleprops: []
|
||||||
|
init: ''
|
||||||
|
maven: null
|
||||||
|
ndk: null
|
||||||
|
novcheck: false
|
||||||
|
oldsdkloc: false
|
||||||
|
output: null
|
||||||
|
patch: []
|
||||||
|
postbuild: ''
|
||||||
|
preassemble: []
|
||||||
|
prebuild: ''
|
||||||
|
rm: []
|
||||||
|
scandelete: []
|
||||||
|
scanignore: []
|
||||||
|
srclibs: []
|
||||||
|
subdir: null
|
||||||
|
submodules: false
|
||||||
|
sudo: ''
|
||||||
|
target: null
|
||||||
|
timeout: null
|
||||||
|
versionCode: 33
|
||||||
|
versionName: 1.0.1
|
||||||
|
- androidupdate: []
|
||||||
|
antcommands: []
|
||||||
|
antifeatures: {}
|
||||||
|
binary: null
|
||||||
|
build: ''
|
||||||
|
buildjni: []
|
||||||
|
commit: v1.2.0
|
||||||
|
disable: ''
|
||||||
|
encoding: null
|
||||||
|
extlibs: []
|
||||||
|
forcevercode: false
|
||||||
|
forceversion: false
|
||||||
|
gradle: []
|
||||||
|
gradleprops: []
|
||||||
|
init: ''
|
||||||
|
maven: null
|
||||||
|
ndk: null
|
||||||
|
novcheck: false
|
||||||
|
oldsdkloc: false
|
||||||
|
output: null
|
||||||
|
patch:
|
||||||
|
- appbrain.patch
|
||||||
|
postbuild: ''
|
||||||
|
preassemble: []
|
||||||
|
prebuild:
|
||||||
|
- sed -i 's@\(reference.1=\).*@\1$$FacebookSDK$$@' project.properties
|
||||||
|
- sed -i 's/Class\[\]/Class\<?\>\[\]/g' $$FacebookSDK$$/src/com/facebook/model/GraphObject.java
|
||||||
|
rm:
|
||||||
|
- libs/appbrain-sdk-android.jar
|
||||||
|
scandelete: []
|
||||||
|
scanignore: []
|
||||||
|
srclibs:
|
||||||
|
- FacebookSDK@sdk-version-3.0.1
|
||||||
|
subdir: null
|
||||||
|
submodules: false
|
||||||
|
sudo: ''
|
||||||
|
target: null
|
||||||
|
timeout: null
|
||||||
|
versionCode: 39
|
||||||
|
versionName: 1.2.0
|
||||||
|
- androidupdate: []
|
||||||
|
antcommands: []
|
||||||
|
antifeatures: {}
|
||||||
|
binary: null
|
||||||
|
build: ''
|
||||||
|
buildjni: []
|
||||||
|
commit: v1.2.2
|
||||||
|
disable: ''
|
||||||
|
encoding: null
|
||||||
|
extlibs:
|
||||||
|
- android/android-support-v4.jar
|
||||||
|
forcevercode: false
|
||||||
|
forceversion: false
|
||||||
|
gradle: []
|
||||||
|
gradleprops: []
|
||||||
|
init: ''
|
||||||
|
maven: null
|
||||||
|
ndk: null
|
||||||
|
novcheck: false
|
||||||
|
oldsdkloc: false
|
||||||
|
output: null
|
||||||
|
patch:
|
||||||
|
- appbrain.patch
|
||||||
|
postbuild: ''
|
||||||
|
preassemble: []
|
||||||
|
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
|
||||||
|
rm:
|
||||||
|
- libs/appbrain-sdk-android.jar
|
||||||
|
scandelete: []
|
||||||
|
scanignore: []
|
||||||
|
srclibs:
|
||||||
|
- FacebookSDK@sdk-version-3.0.2
|
||||||
|
subdir: null
|
||||||
|
submodules: false
|
||||||
|
sudo: ''
|
||||||
|
target: null
|
||||||
|
timeout: null
|
||||||
|
versionCode: 42
|
||||||
|
versionName: 1.2.2
|
||||||
|
- androidupdate: []
|
||||||
|
antcommands: []
|
||||||
|
antifeatures: {}
|
||||||
|
binary: null
|
||||||
|
build: ''
|
||||||
|
buildjni: []
|
||||||
|
commit: 2.1.1
|
||||||
|
disable: ''
|
||||||
|
encoding: null
|
||||||
|
extlibs: []
|
||||||
|
forcevercode: false
|
||||||
|
forceversion: false
|
||||||
|
gradle: []
|
||||||
|
gradleprops: []
|
||||||
|
init: ''
|
||||||
|
maven: yes
|
||||||
|
ndk: null
|
||||||
|
novcheck: false
|
||||||
|
oldsdkloc: false
|
||||||
|
output: null
|
||||||
|
patch:
|
||||||
|
- manifest-ads.patch
|
||||||
|
- mobilecore.patch
|
||||||
|
postbuild: ''
|
||||||
|
preassemble: []
|
||||||
|
prebuild: ''
|
||||||
|
rm: []
|
||||||
|
scandelete: []
|
||||||
|
scanignore: []
|
||||||
|
srclibs:
|
||||||
|
- FacebookSDK@sdk-version-3.0.2
|
||||||
|
subdir: null
|
||||||
|
submodules: false
|
||||||
|
sudo: ''
|
||||||
|
target: null
|
||||||
|
timeout: null
|
||||||
|
versionCode: 48
|
||||||
|
versionName: 2.1.1
|
||||||
|
- androidupdate: []
|
||||||
|
antcommands: []
|
||||||
|
antifeatures:
|
||||||
|
Tracking:
|
||||||
|
en-US: Uses the Facebook SDK.
|
||||||
|
binary: null
|
||||||
|
build: ''
|
||||||
|
buildjni: []
|
||||||
|
commit: 2.1.1
|
||||||
|
disable: ''
|
||||||
|
encoding: null
|
||||||
|
extlibs: []
|
||||||
|
forcevercode: false
|
||||||
|
forceversion: false
|
||||||
|
gradle: []
|
||||||
|
gradleprops: []
|
||||||
|
init: ''
|
||||||
|
maven: yes@..
|
||||||
|
ndk: null
|
||||||
|
novcheck: false
|
||||||
|
oldsdkloc: false
|
||||||
|
output: null
|
||||||
|
patch:
|
||||||
|
- manifest-ads.patch
|
||||||
|
- mobilecore.patch
|
||||||
|
postbuild: ''
|
||||||
|
preassemble: []
|
||||||
|
prebuild: ''
|
||||||
|
rm: []
|
||||||
|
scandelete: []
|
||||||
|
scanignore: []
|
||||||
|
srclibs:
|
||||||
|
- FacebookSDK@sdk-version-3.0.2
|
||||||
|
subdir: null
|
||||||
|
submodules: false
|
||||||
|
sudo: ''
|
||||||
|
target: null
|
||||||
|
timeout: null
|
||||||
|
versionCode: 49
|
||||||
|
versionName: 2.1.1-b
|
||||||
|
- androidupdate: []
|
||||||
|
antcommands: []
|
||||||
|
antifeatures:
|
||||||
|
Ads:
|
||||||
|
en-US: 'includes ad lib
|
||||||
|
|
||||||
|
'
|
||||||
|
zh-CN: '包括广告图书馆
|
||||||
|
|
||||||
|
'
|
||||||
|
Tracking:
|
||||||
|
en-US: 'standard suspects
|
||||||
|
|
||||||
|
'
|
||||||
|
binary: null
|
||||||
|
build: ''
|
||||||
|
buildjni: []
|
||||||
|
commit: 2.1.1
|
||||||
|
disable: ''
|
||||||
|
encoding: null
|
||||||
|
extlibs: []
|
||||||
|
forcevercode: false
|
||||||
|
forceversion: false
|
||||||
|
gradle: []
|
||||||
|
gradleprops: []
|
||||||
|
init: ''
|
||||||
|
maven: '2'
|
||||||
|
ndk: null
|
||||||
|
novcheck: false
|
||||||
|
oldsdkloc: false
|
||||||
|
output: null
|
||||||
|
patch:
|
||||||
|
- manifest-ads.patch
|
||||||
|
- mobilecore.patch
|
||||||
|
postbuild: ''
|
||||||
|
preassemble: []
|
||||||
|
prebuild: ''
|
||||||
|
rm: []
|
||||||
|
scandelete: []
|
||||||
|
scanignore: []
|
||||||
|
srclibs:
|
||||||
|
- FacebookSDK@sdk-version-3.0.2
|
||||||
|
subdir: null
|
||||||
|
submodules: false
|
||||||
|
sudo: ''
|
||||||
|
target: null
|
||||||
|
timeout: null
|
||||||
|
versionCode: 50
|
||||||
|
versionName: 2.1.1-c
|
||||||
|
- androidupdate: []
|
||||||
|
antcommands: []
|
||||||
|
antifeatures: {}
|
||||||
|
binary: null
|
||||||
|
build: ''
|
||||||
|
buildjni: []
|
||||||
|
commit: null
|
||||||
|
disable: Labelled as pre-release, so skipped
|
||||||
|
encoding: null
|
||||||
|
extlibs: []
|
||||||
|
forcevercode: false
|
||||||
|
forceversion: false
|
||||||
|
gradle: []
|
||||||
|
gradleprops: []
|
||||||
|
init: ''
|
||||||
|
maven: null
|
||||||
|
ndk: null
|
||||||
|
novcheck: false
|
||||||
|
oldsdkloc: false
|
||||||
|
output: null
|
||||||
|
patch: []
|
||||||
|
postbuild: ''
|
||||||
|
preassemble: []
|
||||||
|
prebuild: ''
|
||||||
|
rm: []
|
||||||
|
scandelete: []
|
||||||
|
scanignore: []
|
||||||
|
srclibs: []
|
||||||
|
subdir: null
|
||||||
|
submodules: false
|
||||||
|
sudo: ''
|
||||||
|
target: null
|
||||||
|
timeout: null
|
||||||
|
versionCode: 51
|
||||||
|
versionName: 2.1.2
|
||||||
|
Categories:
|
||||||
|
- System
|
||||||
|
Changelog: ''
|
||||||
|
CurrentVersion: 2.1.2
|
||||||
|
CurrentVersionCode: 49
|
||||||
|
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.'
|
||||||
|
Disabled: null
|
||||||
|
Donate: null
|
||||||
|
FlattrID: null
|
||||||
|
IssueTracker: https://github.com/loadrunner/Facebook-Contact-Sync/issues
|
||||||
|
Liberapay: null
|
||||||
|
License: GPL-3.0-only
|
||||||
|
Litecoin: null
|
||||||
|
MaintainerNotes: ''
|
||||||
|
Name: null
|
||||||
|
NoSourceSince: ''
|
||||||
|
OpenCollective: null
|
||||||
|
Provides: null
|
||||||
|
Repo: https://github.com/loadrunner/Facebook-Contact-Sync.git
|
||||||
|
RepoType: git
|
||||||
|
RequiresRoot: false
|
||||||
|
SourceCode: https://github.com/loadrunner/Facebook-Contact-Sync
|
||||||
|
Summary: Sync your Facebook Contacts
|
||||||
|
Translation: ''
|
||||||
|
UpdateCheckData: null
|
||||||
|
UpdateCheckIgnore: null
|
||||||
|
UpdateCheckMode: None
|
||||||
|
UpdateCheckName: null
|
||||||
|
VercodeOperation: []
|
||||||
|
WebSite: ''
|
||||||
|
added: null
|
||||||
|
id: app.with.special.build.params
|
||||||
|
lastUpdated: null
|
||||||
|
metadatapath: metadata/app.with.special.build.params.yml
|
@ -1,6 +1,8 @@
|
|||||||
AllowedAPKSigningKeys: []
|
AllowedAPKSigningKeys: []
|
||||||
AntiFeatures:
|
AntiFeatures:
|
||||||
- NonFreeNet
|
NoSourceSince:
|
||||||
|
en-US: '1.5'
|
||||||
|
NonFreeNet: {}
|
||||||
ArchivePolicy: 4 versions
|
ArchivePolicy: 4 versions
|
||||||
AuthorEmail: null
|
AuthorEmail: null
|
||||||
AuthorName: null
|
AuthorName: null
|
||||||
@ -13,9 +15,9 @@ Builds:
|
|||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures:
|
antifeatures:
|
||||||
- KnownVuln
|
KnownVuln: {}
|
||||||
- UpstreamNonFree
|
NonFreeAssets: {}
|
||||||
- NonFreeAssets
|
UpstreamNonFree: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -50,7 +52,7 @@ Builds:
|
|||||||
versionName: '1.2'
|
versionName: '1.2'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -85,7 +87,7 @@ Builds:
|
|||||||
versionName: '1.3'
|
versionName: '1.3'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -120,7 +122,7 @@ Builds:
|
|||||||
versionName: '1.4'
|
versionName: '1.4'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
AllowedAPKSigningKeys: []
|
AllowedAPKSigningKeys: []
|
||||||
AntiFeatures: []
|
AntiFeatures: {}
|
||||||
ArchivePolicy: null
|
ArchivePolicy: null
|
||||||
AuthorEmail: null
|
AuthorEmail: null
|
||||||
AuthorName: null
|
AuthorName: null
|
||||||
@ -11,7 +11,7 @@ Bitcoin: null
|
|||||||
Builds:
|
Builds:
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -47,7 +47,7 @@ Builds:
|
|||||||
versionName: '1.12'
|
versionName: '1.12'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -84,7 +84,7 @@ Builds:
|
|||||||
versionName: '1.15'
|
versionName: '1.15'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -121,7 +121,7 @@ Builds:
|
|||||||
versionName: '1.18'
|
versionName: '1.18'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -158,7 +158,7 @@ Builds:
|
|||||||
versionName: '1.19'
|
versionName: '1.19'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -195,7 +195,7 @@ Builds:
|
|||||||
versionName: '1.20'
|
versionName: '1.20'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -232,7 +232,7 @@ Builds:
|
|||||||
versionName: '1.21'
|
versionName: '1.21'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -267,7 +267,7 @@ Builds:
|
|||||||
versionName: '1.23'
|
versionName: '1.23'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -304,7 +304,7 @@ Builds:
|
|||||||
versionName: '1.24'
|
versionName: '1.24'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -341,7 +341,7 @@ Builds:
|
|||||||
versionName: '1.25'
|
versionName: '1.25'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -378,7 +378,7 @@ Builds:
|
|||||||
versionName: '1.26'
|
versionName: '1.26'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -415,7 +415,7 @@ Builds:
|
|||||||
versionName: '1.27'
|
versionName: '1.27'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -453,7 +453,7 @@ Builds:
|
|||||||
versionName: '1.29'
|
versionName: '1.29'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -491,7 +491,7 @@ Builds:
|
|||||||
versionName: '1.32'
|
versionName: '1.32'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -528,7 +528,7 @@ Builds:
|
|||||||
versionName: '1.33'
|
versionName: '1.33'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -566,7 +566,7 @@ Builds:
|
|||||||
versionName: '1.34'
|
versionName: '1.34'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -604,7 +604,7 @@ Builds:
|
|||||||
versionName: '1.35'
|
versionName: '1.35'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -642,7 +642,7 @@ Builds:
|
|||||||
versionName: '1.36'
|
versionName: '1.36'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -684,7 +684,7 @@ Builds:
|
|||||||
- android-libs/ActionBarSherlock
|
- android-libs/ActionBarSherlock
|
||||||
- android-libs/HtmlSpanner/htmlspanner
|
- android-libs/HtmlSpanner/htmlspanner
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -734,7 +734,7 @@ Builds:
|
|||||||
- android-libs/ActionBarSherlock
|
- android-libs/ActionBarSherlock
|
||||||
- android-libs/HtmlSpanner/htmlspanner
|
- android-libs/HtmlSpanner/htmlspanner
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -780,7 +780,7 @@ Builds:
|
|||||||
versionName: '2.3'
|
versionName: '2.3'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -818,7 +818,7 @@ Builds:
|
|||||||
versionName: '2.6'
|
versionName: '2.6'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -856,7 +856,7 @@ Builds:
|
|||||||
versionName: '2.7'
|
versionName: '2.7'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -894,7 +894,7 @@ Builds:
|
|||||||
versionName: '2.8'
|
versionName: '2.8'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -932,7 +932,7 @@ Builds:
|
|||||||
versionName: 2.8.1
|
versionName: 2.8.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -970,7 +970,7 @@ Builds:
|
|||||||
versionName: '2.9'
|
versionName: '2.9'
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -1008,7 +1008,7 @@ Builds:
|
|||||||
versionName: 2.9.1
|
versionName: 2.9.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
@ -1046,7 +1046,7 @@ Builds:
|
|||||||
versionName: 2.9.2
|
versionName: 2.9.2
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni:
|
buildjni:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
AllowedAPKSigningKeys: []
|
AllowedAPKSigningKeys: []
|
||||||
AntiFeatures: []
|
AntiFeatures: {}
|
||||||
ArchivePolicy: null
|
ArchivePolicy: null
|
||||||
AuthorEmail: null
|
AuthorEmail: null
|
||||||
AuthorName: null
|
AuthorName: null
|
||||||
@ -11,7 +11,7 @@ Bitcoin: null
|
|||||||
Builds:
|
Builds:
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -72,7 +72,7 @@ Builds:
|
|||||||
versionName: 0.3.3
|
versionName: 0.3.3
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -115,7 +115,7 @@ Builds:
|
|||||||
versionName: 0.3.3
|
versionName: 0.3.3
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -156,7 +156,7 @@ Builds:
|
|||||||
versionName: 0.4.2
|
versionName: 0.4.2
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -197,7 +197,7 @@ Builds:
|
|||||||
versionName: 0.5.1
|
versionName: 0.5.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -237,7 +237,7 @@ Builds:
|
|||||||
versionName: 0.5.2
|
versionName: 0.5.2
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -277,7 +277,7 @@ Builds:
|
|||||||
versionName: 0.5.3
|
versionName: 0.5.3
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
@ -317,7 +317,7 @@ Builds:
|
|||||||
versionName: 0.5.4
|
versionName: 0.5.4
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build: ''
|
build: ''
|
||||||
buildjni: []
|
buildjni: []
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
AllowedAPKSigningKeys: []
|
AllowedAPKSigningKeys: []
|
||||||
AntiFeatures: []
|
AntiFeatures: {}
|
||||||
ArchivePolicy: 9 versions
|
ArchivePolicy: 9 versions
|
||||||
AuthorEmail: null
|
AuthorEmail: null
|
||||||
AuthorName: null
|
AuthorName: null
|
||||||
@ -14,7 +14,7 @@ Builds:
|
|||||||
- ../java-libs/SlidingMenu
|
- ../java-libs/SlidingMenu
|
||||||
- ../java-libs/ActionBarSherlock
|
- ../java-libs/ActionBarSherlock
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -54,7 +54,7 @@ Builds:
|
|||||||
- ../java-libs/SlidingMenu
|
- ../java-libs/SlidingMenu
|
||||||
- ../java-libs/ActionBarSherlock
|
- ../java-libs/ActionBarSherlock
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
||||||
@ -94,7 +94,7 @@ Builds:
|
|||||||
- ../java-libs/SlidingMenu
|
- ../java-libs/SlidingMenu
|
||||||
- ../java-libs/ActionBarSherlock
|
- ../java-libs/ActionBarSherlock
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -134,7 +134,7 @@ Builds:
|
|||||||
- ../java-libs/SlidingMenu
|
- ../java-libs/SlidingMenu
|
||||||
- ../java-libs/ActionBarSherlock
|
- ../java-libs/ActionBarSherlock
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=mips ./compile.sh release
|
- cd ../ && ANDROID_ABI=mips ./compile.sh release
|
||||||
@ -171,7 +171,7 @@ Builds:
|
|||||||
versionName: 0.0.11-mips
|
versionName: 0.0.11-mips
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=mips ./compile.sh release
|
- cd ../ && ANDROID_ABI=mips ./compile.sh release
|
||||||
@ -210,7 +210,7 @@ Builds:
|
|||||||
versionName: 0.1.3-MIPS
|
versionName: 0.1.3-MIPS
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -249,7 +249,7 @@ Builds:
|
|||||||
versionName: 0.1.3-x86
|
versionName: 0.1.3-x86
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
||||||
@ -288,7 +288,7 @@ Builds:
|
|||||||
versionName: 0.1.3-ARM
|
versionName: 0.1.3-ARM
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -327,7 +327,7 @@ Builds:
|
|||||||
versionName: 0.1.3-ARMv7
|
versionName: 0.1.3-ARMv7
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -365,7 +365,7 @@ Builds:
|
|||||||
versionName: 0.9.0
|
versionName: 0.9.0
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -403,7 +403,7 @@ Builds:
|
|||||||
versionName: 0.9.0
|
versionName: 0.9.0
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -441,7 +441,7 @@ Builds:
|
|||||||
versionName: 0.9.1
|
versionName: 0.9.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -479,7 +479,7 @@ Builds:
|
|||||||
versionName: 0.9.1
|
versionName: 0.9.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -517,7 +517,7 @@ Builds:
|
|||||||
versionName: 0.9.5
|
versionName: 0.9.5
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -555,7 +555,7 @@ Builds:
|
|||||||
versionName: 0.9.5
|
versionName: 0.9.5
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -593,7 +593,7 @@ Builds:
|
|||||||
versionName: 0.9.6
|
versionName: 0.9.6
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -631,7 +631,7 @@ Builds:
|
|||||||
versionName: 0.9.6
|
versionName: 0.9.6
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -669,7 +669,7 @@ Builds:
|
|||||||
versionName: 0.9.7
|
versionName: 0.9.7
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -707,7 +707,7 @@ Builds:
|
|||||||
versionName: 0.9.7
|
versionName: 0.9.7
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=mips ./compile.sh release
|
- cd ../ && ANDROID_ABI=mips ./compile.sh release
|
||||||
@ -745,7 +745,7 @@ Builds:
|
|||||||
versionName: 0.9.7.1
|
versionName: 0.9.7.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -783,7 +783,7 @@ Builds:
|
|||||||
versionName: 0.9.7.1
|
versionName: 0.9.7.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -821,7 +821,7 @@ Builds:
|
|||||||
versionName: 0.9.7.1
|
versionName: 0.9.7.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -859,7 +859,7 @@ Builds:
|
|||||||
versionName: 0.9.8
|
versionName: 0.9.8
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
||||||
@ -897,7 +897,7 @@ Builds:
|
|||||||
versionName: 0.9.8
|
versionName: 0.9.8
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -935,7 +935,7 @@ Builds:
|
|||||||
versionName: 0.9.8
|
versionName: 0.9.8
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -973,7 +973,7 @@ Builds:
|
|||||||
versionName: 0.9.9
|
versionName: 0.9.9
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
||||||
@ -1011,7 +1011,7 @@ Builds:
|
|||||||
versionName: 0.9.9
|
versionName: 0.9.9
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -1049,7 +1049,7 @@ Builds:
|
|||||||
versionName: 0.9.9
|
versionName: 0.9.9
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -1087,7 +1087,7 @@ Builds:
|
|||||||
versionName: 0.9.10
|
versionName: 0.9.10
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
||||||
@ -1125,7 +1125,7 @@ Builds:
|
|||||||
versionName: 0.9.10
|
versionName: 0.9.10
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -1163,7 +1163,7 @@ Builds:
|
|||||||
versionName: 0.9.10
|
versionName: 0.9.10
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -1201,7 +1201,7 @@ Builds:
|
|||||||
versionName: 1.0.0
|
versionName: 1.0.0
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
||||||
@ -1239,7 +1239,7 @@ Builds:
|
|||||||
versionName: 1.0.0
|
versionName: 1.0.0
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -1277,7 +1277,7 @@ Builds:
|
|||||||
versionName: 1.0.0
|
versionName: 1.0.0
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
- cd ../ && ANDROID_ABI=x86 ./compile.sh release
|
||||||
@ -1315,7 +1315,7 @@ Builds:
|
|||||||
versionName: 1.0.1
|
versionName: 1.0.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi ./compile.sh release
|
||||||
@ -1353,7 +1353,7 @@ Builds:
|
|||||||
versionName: 1.0.1
|
versionName: 1.0.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
- cd ../ && ANDROID_ABI=armeabi-v7a ./compile.sh release
|
||||||
@ -1391,7 +1391,7 @@ Builds:
|
|||||||
versionName: 1.0.1
|
versionName: 1.0.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi" --release
|
- cd ../ && ./compile.sh -a "armeabi" --release
|
||||||
@ -1431,7 +1431,7 @@ Builds:
|
|||||||
versionName: 1.1.3
|
versionName: 1.1.3
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
||||||
@ -1471,7 +1471,7 @@ Builds:
|
|||||||
versionName: 1.1.3
|
versionName: 1.1.3
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "x86" --release
|
- cd ../ && ./compile.sh -a "x86" --release
|
||||||
@ -1511,7 +1511,7 @@ Builds:
|
|||||||
versionName: 1.1.3
|
versionName: 1.1.3
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi" --release
|
- cd ../ && ./compile.sh -a "armeabi" --release
|
||||||
@ -1551,7 +1551,7 @@ Builds:
|
|||||||
versionName: 1.1.5
|
versionName: 1.1.5
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
||||||
@ -1591,7 +1591,7 @@ Builds:
|
|||||||
versionName: 1.1.5
|
versionName: 1.1.5
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "x86" --release
|
- cd ../ && ./compile.sh -a "x86" --release
|
||||||
@ -1631,7 +1631,7 @@ Builds:
|
|||||||
versionName: 1.1.5
|
versionName: 1.1.5
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi" --release
|
- cd ../ && ./compile.sh -a "armeabi" --release
|
||||||
@ -1671,7 +1671,7 @@ Builds:
|
|||||||
versionName: 1.1.6
|
versionName: 1.1.6
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
||||||
@ -1711,7 +1711,7 @@ Builds:
|
|||||||
versionName: 1.1.6
|
versionName: 1.1.6
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "x86" --release
|
- cd ../ && ./compile.sh -a "x86" --release
|
||||||
@ -1751,7 +1751,7 @@ Builds:
|
|||||||
versionName: 1.1.6
|
versionName: 1.1.6
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi" --release
|
- cd ../ && ./compile.sh -a "armeabi" --release
|
||||||
@ -1791,7 +1791,7 @@ Builds:
|
|||||||
versionName: 1.2.0
|
versionName: 1.2.0
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
||||||
@ -1831,7 +1831,7 @@ Builds:
|
|||||||
versionName: 1.2.0
|
versionName: 1.2.0
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "x86" --release
|
- cd ../ && ./compile.sh -a "x86" --release
|
||||||
@ -1871,7 +1871,7 @@ Builds:
|
|||||||
versionName: 1.2.0
|
versionName: 1.2.0
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi" --release
|
- cd ../ && ./compile.sh -a "armeabi" --release
|
||||||
@ -1911,7 +1911,7 @@ Builds:
|
|||||||
versionName: 1.2.1
|
versionName: 1.2.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
||||||
@ -1951,7 +1951,7 @@ Builds:
|
|||||||
versionName: 1.2.1
|
versionName: 1.2.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "x86" --release
|
- cd ../ && ./compile.sh -a "x86" --release
|
||||||
@ -1991,7 +1991,7 @@ Builds:
|
|||||||
versionName: 1.2.1
|
versionName: 1.2.1
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi" --release
|
- cd ../ && ./compile.sh -a "armeabi" --release
|
||||||
@ -2031,7 +2031,7 @@ Builds:
|
|||||||
versionName: 1.2.2
|
versionName: 1.2.2
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
||||||
@ -2071,7 +2071,7 @@ Builds:
|
|||||||
versionName: 1.2.2
|
versionName: 1.2.2
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "x86" --release
|
- cd ../ && ./compile.sh -a "x86" --release
|
||||||
@ -2111,7 +2111,7 @@ Builds:
|
|||||||
versionName: 1.2.2
|
versionName: 1.2.2
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi" --release
|
- cd ../ && ./compile.sh -a "armeabi" --release
|
||||||
@ -2151,7 +2151,7 @@ Builds:
|
|||||||
versionName: 1.2.3
|
versionName: 1.2.3
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
||||||
@ -2191,7 +2191,7 @@ Builds:
|
|||||||
versionName: 1.2.3
|
versionName: 1.2.3
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "x86" --release
|
- cd ../ && ./compile.sh -a "x86" --release
|
||||||
@ -2231,7 +2231,7 @@ Builds:
|
|||||||
versionName: 1.2.3
|
versionName: 1.2.3
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi" --release
|
- cd ../ && ./compile.sh -a "armeabi" --release
|
||||||
@ -2271,7 +2271,7 @@ Builds:
|
|||||||
versionName: 1.2.4
|
versionName: 1.2.4
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
||||||
@ -2311,7 +2311,7 @@ Builds:
|
|||||||
versionName: 1.2.4
|
versionName: 1.2.4
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "x86" --release
|
- cd ../ && ./compile.sh -a "x86" --release
|
||||||
@ -2351,7 +2351,7 @@ Builds:
|
|||||||
versionName: 1.2.4
|
versionName: 1.2.4
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi" --release
|
- cd ../ && ./compile.sh -a "armeabi" --release
|
||||||
@ -2391,7 +2391,7 @@ Builds:
|
|||||||
versionName: 1.2.5
|
versionName: 1.2.5
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
||||||
@ -2431,7 +2431,7 @@ Builds:
|
|||||||
versionName: 1.2.5
|
versionName: 1.2.5
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "x86" --release
|
- cd ../ && ./compile.sh -a "x86" --release
|
||||||
@ -2471,7 +2471,7 @@ Builds:
|
|||||||
versionName: 1.2.5
|
versionName: 1.2.5
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi" --release
|
- cd ../ && ./compile.sh -a "armeabi" --release
|
||||||
@ -2511,7 +2511,7 @@ Builds:
|
|||||||
versionName: 1.2.6
|
versionName: 1.2.6
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
- cd ../ && ./compile.sh -a "armeabi-v7a" --release
|
||||||
@ -2551,7 +2551,7 @@ Builds:
|
|||||||
versionName: 1.2.6
|
versionName: 1.2.6
|
||||||
- androidupdate: []
|
- androidupdate: []
|
||||||
antcommands: []
|
antcommands: []
|
||||||
antifeatures: []
|
antifeatures: {}
|
||||||
binary: null
|
binary: null
|
||||||
build:
|
build:
|
||||||
- cd ../ && ./compile.sh -a "x86" --release
|
- cd ../ && ./compile.sh -a "x86" --release
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
"version": 20002,
|
"version": 20002,
|
||||||
"index": {
|
"index": {
|
||||||
"name": "/index-v2.json",
|
"name": "/index-v2.json",
|
||||||
"sha256": "a3c7e88a522a7228937e5c3d760fc239e3578e292035d88478d32fec9ff5eb54",
|
"sha256": "f4979b9db840cb51a99e80c20da676ba42b13133dbaa4819673bc43ed2ffc3f3",
|
||||||
"size": 52314,
|
"size": 52481,
|
||||||
"numPackages": 10
|
"numPackages": 10
|
||||||
},
|
},
|
||||||
"diffs": {}
|
"diffs": {}
|
||||||
|
@ -568,7 +568,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"antiFeatures": {
|
"antiFeatures": {
|
||||||
"NoSourceSince": {},
|
"NoSourceSince": {
|
||||||
|
"en-US": "1.5"
|
||||||
|
},
|
||||||
"NonFreeNet": {}
|
"NonFreeNet": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -602,7 +604,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"antiFeatures": {
|
"antiFeatures": {
|
||||||
"NoSourceSince": {},
|
"NoSourceSince": {
|
||||||
|
"en-US": "1.5"
|
||||||
|
},
|
||||||
"NonFreeNet": {}
|
"NonFreeNet": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -645,7 +649,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"antiFeatures": {
|
"antiFeatures": {
|
||||||
"NoSourceSince": {},
|
"NoSourceSince": {
|
||||||
|
"en-US": "1.5"
|
||||||
|
},
|
||||||
"NonFreeNet": {}
|
"NonFreeNet": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -689,7 +695,9 @@
|
|||||||
},
|
},
|
||||||
"antiFeatures": {
|
"antiFeatures": {
|
||||||
"KnownVuln": {},
|
"KnownVuln": {},
|
||||||
"NoSourceSince": {},
|
"NoSourceSince": {
|
||||||
|
"en-US": "1.5"
|
||||||
|
},
|
||||||
"NonFreeAssets": {},
|
"NonFreeAssets": {},
|
||||||
"NonFreeNet": {},
|
"NonFreeNet": {},
|
||||||
"UpstreamNonFree": {}
|
"UpstreamNonFree": {}
|
||||||
@ -1395,4 +1403,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -45,11 +45,11 @@ class RewriteMetaTest(unittest.TestCase):
|
|||||||
'versionCode': 3,
|
'versionCode': 3,
|
||||||
'commit': '6a548e4b19',
|
'commit': '6a548e4b19',
|
||||||
'target': 'android-10',
|
'target': 'android-10',
|
||||||
'antifeatures': [
|
'antifeatures': {
|
||||||
'KnownVuln',
|
'KnownVuln': {},
|
||||||
'UpstreamNonFree',
|
'UpstreamNonFree': {},
|
||||||
'NonFreeAssets',
|
'NonFreeAssets': {},
|
||||||
],
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -68,6 +68,24 @@ class RewriteMetaTest(unittest.TestCase):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_remove_blank_flags_from_builds_org_adaway_52(self):
|
||||||
|
"""Unset fields in Builds: entries should be removed."""
|
||||||
|
appid = 'org.adaway'
|
||||||
|
app = metadata.read_metadata({appid: -1})[appid]
|
||||||
|
builds = rewritemeta.remove_blank_flags_from_builds(app.get('Builds'))
|
||||||
|
self.assertEqual(
|
||||||
|
builds[-1],
|
||||||
|
{
|
||||||
|
'buildjni': ['yes'],
|
||||||
|
'commit': 'v3.0',
|
||||||
|
'gradle': ['yes'],
|
||||||
|
'preassemble': ['renameExecutables'],
|
||||||
|
'subdir': 'AdAway',
|
||||||
|
'versionCode': 52,
|
||||||
|
'versionName': '3.0',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def test_remove_blank_flags_from_builds_no_builds(self):
|
def test_remove_blank_flags_from_builds_no_builds(self):
|
||||||
"""Unset fields in Builds: entries should be removed."""
|
"""Unset fields in Builds: entries should be removed."""
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
@ -78,6 +96,43 @@ class RewriteMetaTest(unittest.TestCase):
|
|||||||
rewritemeta.remove_blank_flags_from_builds(dict()),
|
rewritemeta.remove_blank_flags_from_builds(dict()),
|
||||||
list(),
|
list(),
|
||||||
)
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
rewritemeta.remove_blank_flags_from_builds(list()),
|
||||||
|
list(),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
rewritemeta.remove_blank_flags_from_builds(set()),
|
||||||
|
list(),
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
rewritemeta.remove_blank_flags_from_builds(tuple()),
|
||||||
|
list(),
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_remove_blank_flags_from_builds_0_is_a_value(self):
|
||||||
|
self.assertEqual(
|
||||||
|
rewritemeta.remove_blank_flags_from_builds([{'versionCode': 0}]),
|
||||||
|
[{'versionCode': 0}],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_remove_blank_flags_from_builds_values_to_purge(self):
|
||||||
|
self.assertEqual(
|
||||||
|
rewritemeta.remove_blank_flags_from_builds(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
'antifeatures': dict(),
|
||||||
|
'forceversion': False,
|
||||||
|
'init': None,
|
||||||
|
'rm': '',
|
||||||
|
'scandelete': list(),
|
||||||
|
'versionCode': 0,
|
||||||
|
},
|
||||||
|
{'antifeatures': list(), 'versionCode': 1},
|
||||||
|
{'antifeatures': '', 'versionCode': 2},
|
||||||
|
]
|
||||||
|
),
|
||||||
|
[{'versionCode': 0}, {'versionCode': 1}, {'versionCode': 2}],
|
||||||
|
)
|
||||||
|
|
||||||
def test_rewrite_no_builds(self):
|
def test_rewrite_no_builds(self):
|
||||||
os.chdir(self.testdir)
|
os.chdir(self.testdir)
|
||||||
@ -144,6 +199,30 @@ class RewriteMetaTest(unittest.TestCase):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_remove_blank_flags_from_builds_app_with_special_build_params_af(self):
|
||||||
|
"""Unset fields in Builds: entries should be removed."""
|
||||||
|
appid = 'app.with.special.build.params'
|
||||||
|
app = metadata.read_metadata({appid: -1})[appid]
|
||||||
|
builds = rewritemeta.remove_blank_flags_from_builds(app.get('Builds'))
|
||||||
|
self.assertEqual(
|
||||||
|
builds[-2],
|
||||||
|
{
|
||||||
|
'antifeatures': {
|
||||||
|
'Ads': {'en-US': 'includes ad lib\n', 'zh-CN': '包括广告图书馆\n'},
|
||||||
|
'Tracking': {'en-US': 'standard suspects\n'},
|
||||||
|
},
|
||||||
|
'commit': '2.1.1',
|
||||||
|
'maven': '2',
|
||||||
|
'patch': [
|
||||||
|
'manifest-ads.patch',
|
||||||
|
'mobilecore.patch',
|
||||||
|
],
|
||||||
|
'srclibs': ['FacebookSDK@sdk-version-3.0.2'],
|
||||||
|
'versionCode': 50,
|
||||||
|
'versionName': '2.1.1-c',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def test_rewrite_scenario_trivial(self):
|
def test_rewrite_scenario_trivial(self):
|
||||||
sys.argv = ['rewritemeta', 'a', 'b']
|
sys.argv = ['rewritemeta', 'a', 'b']
|
||||||
|
|
||||||
|
@ -768,7 +768,7 @@ class UpdateTest(unittest.TestCase):
|
|||||||
'-1': 'res/drawable-mdpi-v4/icon_launcher.png'})
|
'-1': 'res/drawable-mdpi-v4/icon_launcher.png'})
|
||||||
self.assertEqual(apk_info['icons'], {})
|
self.assertEqual(apk_info['icons'], {})
|
||||||
self.assertEqual(apk_info['features'], [])
|
self.assertEqual(apk_info['features'], [])
|
||||||
self.assertEqual(apk_info['antiFeatures'], set())
|
self.assertEqual(apk_info['antiFeatures'], dict())
|
||||||
self.assertEqual(apk_info['versionName'], 'v1.6pre2')
|
self.assertEqual(apk_info['versionName'], 'v1.6pre2')
|
||||||
self.assertEqual(apk_info['hash'],
|
self.assertEqual(apk_info['hash'],
|
||||||
'897486e1f857c6c0ee32ccbad0e1b8cd82f6d0e65a44a23f13f852d2b63a18c8')
|
'897486e1f857c6c0ee32ccbad0e1b8cd82f6d0e65a44a23f13f852d2b63a18c8')
|
||||||
@ -819,7 +819,7 @@ class UpdateTest(unittest.TestCase):
|
|||||||
'hashType': 'sha256',
|
'hashType': 'sha256',
|
||||||
'packageName': 'no.min.target.sdk',
|
'packageName': 'no.min.target.sdk',
|
||||||
'features': [],
|
'features': [],
|
||||||
'antiFeatures': set(),
|
'antiFeatures': dict(),
|
||||||
'size': 14102,
|
'size': 14102,
|
||||||
'sig': 'b4964fd759edaa54e65bb476d0276880',
|
'sig': 'b4964fd759edaa54e65bb476d0276880',
|
||||||
'versionName': '1.2-fake',
|
'versionName': '1.2-fake',
|
||||||
@ -1433,7 +1433,7 @@ class UpdateTest(unittest.TestCase):
|
|||||||
'NoSourceSince': '',
|
'NoSourceSince': '',
|
||||||
'Repo': '',
|
'Repo': '',
|
||||||
'RepoType': '',
|
'RepoType': '',
|
||||||
'RequiresRoot': '',
|
'RequiresRoot': None,
|
||||||
'SourceCode': '',
|
'SourceCode': '',
|
||||||
'Summary': 'rocks.janicerand',
|
'Summary': 'rocks.janicerand',
|
||||||
'Translation': '',
|
'Translation': '',
|
||||||
|
Loading…
Reference in New Issue
Block a user