[index] First prototype
This commit is contained in:
parent
123be3af3f
commit
802deb43eb
|
@ -97,7 +97,7 @@ android {
|
|||
getByName("androidTest").java.srcDir(file("src/androidAndroidTest/kotlin"))
|
||||
}
|
||||
defaultConfig {
|
||||
minSdkVersion 22
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 25
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
testInstrumentationRunnerArguments disableAnalytics: 'true'
|
||||
|
|
|
@ -4,8 +4,6 @@ android.useAndroidX=true
|
|||
|
||||
kotlin.code.style=official
|
||||
kotlin.mpp.stability.nowarn=true
|
||||
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||
kotlin.native.enableDependencyPropagation=false
|
||||
|
||||
# Gradle Maven Publish Info below (https://github.com/vanniktech/gradle-maven-publish-plugin)
|
||||
# These are common for all libraries in gradle submodules.
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
ktlint {
|
||||
version = "0.43.2"
|
||||
version = "0.45.2"
|
||||
android = true
|
||||
enableExperimentalRules = false
|
||||
verbose = true
|
||||
disabledRules = [
|
||||
"wrapping",
|
||||
"import-ordering",
|
||||
"no-blank-line-before-rbrace",
|
||||
]
|
||||
|
|
|
@ -147,6 +147,11 @@
|
|||
<trusting group="com.google.guava" name="listenablefuture"/>
|
||||
<trusting group="com.google.guava" name="listenablefuture" version="9999.0-empty-to-avoid-conflict-with-guava"/>
|
||||
</trusted-key>
|
||||
<trusted-key id="c7be5bcc9fec15518cfda882b0f3710fa64900e7">
|
||||
<trusting group="com.google.auto.value"/>
|
||||
<trusting group="com.google.auto.value" name="auto-value-annotations"/>
|
||||
<trusting group="^com[.]google[.]auto($|([.].*))" regex="true"/>
|
||||
</trusted-key>
|
||||
<trusted-key id="c7be5bcc9fec15518cfda882b0f3710fa64900e7">
|
||||
<trusting group="com.google.auto.value"/>
|
||||
<trusting group="^com[.]google[.]auto($|([.].*))" regex="true"/>
|
||||
|
@ -837,11 +842,21 @@
|
|||
<sha256 value="a97209d75a9a85815fa8934f5a4a320de1163ffe94e2f0b328c0c98a59660690" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.test.ext" name="junit" version="1.1.3">
|
||||
<artifact name="junit-1.1.3.aar">
|
||||
<sha256 value="a97209d75a9a85815fa8934f5a4a320de1163ffe94e2f0b328c0c98a59660690" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.test.services" name="storage" version="1.4.0">
|
||||
<artifact name="storage-1.4.0.aar">
|
||||
<sha256 value="35cfbf442abb83e5876cd5deb9de02ae047459f18f831097c5caa76d626bc38a" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.test.ext" name="junit" version="1.1.3">
|
||||
<artifact name="junit-1.1.3.aar">
|
||||
<sha256 value="a97209d75a9a85815fa8934f5a4a320de1163ffe94e2f0b328c0c98a59660690" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.test.uiautomator" name="uiautomator" version="2.2.0">
|
||||
<artifact name="uiautomator-2.2.0.aar">
|
||||
<sha256 value="2838e9d961dbffefbbd229a2bd4f6f82ac4fb2462975862a9e75e9ed325a3197" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
|
@ -973,6 +988,11 @@
|
|||
<sha256 value="056b300701b7cb53e22315b29103d1cd6e7346b04b47655448675c1fa71916a5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="ch.qos.logback" name="logback-classic" version="1.2.9">
|
||||
<artifact name="logback-classic-1.2.9.jar">
|
||||
<sha256 value="ad745cc243805800d1ebbf5b7deba03b37c95885e6bce71335a73f7d6d0f14ee" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="ch.qos.logback" name="logback-core" version="1.2.10">
|
||||
<artifact name="logback-core-1.2.10.jar">
|
||||
<sha256 value="ba51a3fe56691f9dd7fe742e4a73c3ab4aaaa32202c73409ba56f18687399a08" origin="Generated by Gradle"/>
|
||||
|
@ -983,6 +1003,11 @@
|
|||
<sha256 value="fc98d2d927bd2991d5f45d0ccd9039a08d162c6d0611e2f71172deae9dbe122c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="ch.qos.logback" name="logback-core" version="1.2.9">
|
||||
<artifact name="logback-core-1.2.9.jar">
|
||||
<sha256 value="4a9ef7ed809b1fbc6992bf87d404087c247e7a9766e25bb84377b58ed5c9eb58" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="classworlds" name="classworlds" version="1.1-alpha-2">
|
||||
<artifact name="classworlds-1.1-alpha-2.jar">
|
||||
<sha256 value="2bf4e59f3acd106fea6145a9a88fe8956509f8b9c0fdd11eb96fee757269e3f3" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
|
@ -1926,6 +1951,21 @@
|
|||
<sha256 value="68c2a5aa6e8f345743093e52b5b9e0190ba4d5a5215c0a59b4d7d33647208cbb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.goncalossilva" name="resources" version="0.2.1">
|
||||
<artifact name="resources-library-metadata-0.2.1-all.jar">
|
||||
<sha256 value="d668dfc7fa22605eda00bf23c0de7ed199c08f086f7be3267079bee4bdb772ac" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.goncalossilva" name="resources-jvm" version="0.2.1">
|
||||
<artifact name="resources-library-jvm-0.2.1.jar">
|
||||
<sha256 value="1c23299bf34a8b7ca06e63f2ba8aff9c815f0b4d925976433ff8dd837e228776" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.goncalossilva" name="resources-linuxX64" version="0.2.1">
|
||||
<artifact name="resources-library.klib">
|
||||
<sha256 value="6547c74b29706eae5ac48b6635c97a835009b5923ab6bfe418a9d6a314853501" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google" name="google" version="1">
|
||||
<artifact name="google-1.pom">
|
||||
<sha256 value="cd6db17a11a31ede794ccbd1df0e4d9750f640234731f21cff885a9997277e81" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
|
@ -1970,6 +2010,12 @@
|
|||
<sha256 value="bd60cd7a423b00fb824c27bdd0293aaf4781be1daba6ed256311103fb4b84108" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.auto" name="auto-common" version="0.11">
|
||||
<artifact name="auto-common-0.11.jar">
|
||||
<pgp value="3288b8be8512d6c0ca185268c51e6cbc7ff46f0b"/>
|
||||
<sha256 value="ec668cd50a3a66a5def17e6ae67423542e514181c0e9ab5b11959c0ac9c4222a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.auto" name="auto-common" version="0.8">
|
||||
<artifact name="auto-common-0.8.jar">
|
||||
<pgp value="92d3e6630b4b92cb2ef124994786cbe7d4906b68"/>
|
||||
|
@ -2036,6 +2082,11 @@
|
|||
<sha256 value="1c76cd462fc96e7aa96dc70ce82f0d54063d6df16db35c9c7d9cc0d1a99d3fff" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.auto.value" name="auto-value-annotations" version="1.6.3">
|
||||
<artifact name="auto-value-annotations-1.6.3.jar">
|
||||
<sha256 value="0e951fee8c31f60270bc46553a8586001b7b93dbb12aec06373aa99a150392c0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.auto.value" name="auto-value-annotations" version="1.7.4">
|
||||
<artifact name="auto-value-annotations-1.7.4.jar">
|
||||
<sha256 value="fedd59b0b4986c342f6ab2d182f2a4ee9fceb2c7e2d5bdc4dc764c92394a23d3" origin="Generated by Gradle"/>
|
||||
|
@ -2084,6 +2135,12 @@
|
|||
<sha256 value="19889dbdf1b254b2601a5ee645b8147a974644882297684c798afe5d63d78dfe" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.code.gson" name="gson" version="2.8.0">
|
||||
<artifact name="gson-2.8.0.jar">
|
||||
<pgp value="9e84765a7aa3e3d3d5598a408e3f0de7ae354651"/>
|
||||
<sha256 value="c6221763bd79c4f1c3dc7f750b5f29a0bb38b367b81314c4f71896e340c40825" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.code.gson" name="gson" version="2.8.5">
|
||||
<artifact name="gson-2.8.5.jar">
|
||||
<pgp value="afcc4c7594d09e2182c60e0f7a01b0f236e5430f"/>
|
||||
|
@ -2479,6 +2536,23 @@
|
|||
<sha256 value="a0700d84efe7cc3103557bd0522f9443681b96ba9559c4bb7f9dc9bf35243485" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.intellij" name="annotations" version="12.0">
|
||||
<artifact name="annotations-12.0.jar">
|
||||
<sha256 value="f8ab13b14be080fe2f617f90e55599760e4a1b4deeea5c595df63d0d6375ed6d" origin="Generated by Gradle because a key couldn't be downloaded"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.jakewharton.android.repackaged" name="dalvik-dx" version="9.0.0_r3">
|
||||
<artifact name="dalvik-dx-9.0.0_r3.jar">
|
||||
<pgp value="47bf592261cd1a8a69b703b4e0cb7823cfd00fbf"/>
|
||||
<sha256 value="b29c1c21e52ed6238cd3fed39d880a17ecf2360118604548cea8821be6801e1c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.linkedin.dexmaker" name="dexmaker" version="2.28.1">
|
||||
<artifact name="dexmaker-2.28.1.jar">
|
||||
<pgp value="8df3b0aa23ed78be5233f6c2dea3d207428ef16d"/>
|
||||
<sha256 value="824a109b2352138c3699760e1683385d0ed50ce526fc7982f8d65757743374bf" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.ibm.icu" name="icu4j" version="70.1">
|
||||
<artifact name="icu4j-70.1.jar">
|
||||
<pgp value="cb3190ca7842439e57f3712e44ce7bf2825ea2cd"/>
|
||||
|
@ -2499,56 +2573,111 @@
|
|||
<sha256 value="99ec69ef0628695c24dbbc2cc4b8d7c61a754697d624f5233fc65f43faf2d235" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest" name="ktlint" version="0.45.2">
|
||||
<artifact name="ktlint-0.45.2.jar">
|
||||
<sha256 value="279905d78118e9db41182ce214ac27e00a88c228537633175a27bc36671e0296" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-core" version="0.43.2">
|
||||
<artifact name="ktlint-core-0.43.2.jar">
|
||||
<sha256 value="401515a76b780a32ef9dfeaf69f77316934c4bb90f339488638311789eca7a1a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-core" version="0.45.2">
|
||||
<artifact name="ktlint-core-0.45.2.jar">
|
||||
<sha256 value="383e463ee7d1b082db7928110522925cc06389af1bec65da526a52d113d393f6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-baseline" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-baseline-0.43.2.jar">
|
||||
<sha256 value="733ee7e2cadb321d6597b3501c70c7da73117adaa0c6bc084dfc16c455d68806" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-baseline" version="0.45.2">
|
||||
<artifact name="ktlint-reporter-baseline-0.45.2.jar">
|
||||
<sha256 value="05262e8ab61191abf36ab481d2cde0fdd5b4e620ddde8e4c547af5937b9c60e0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-checkstyle" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-checkstyle-0.43.2.jar">
|
||||
<sha256 value="becafb4006b9f2e82c99749864a1a8de340ee84ac7271631a68981a44f51e808" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-checkstyle" version="0.45.2">
|
||||
<artifact name="ktlint-reporter-checkstyle-0.45.2.jar">
|
||||
<sha256 value="f587225e2a0a16673184e96aa7e52bebd1bb838376d683b602509da43841dd34" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-html" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-html-0.43.2.jar">
|
||||
<sha256 value="800392e150d3266e72ca53c6ccca3136d4e26445dd9216c6ac6cfc1ba3afafe5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-html" version="0.45.2">
|
||||
<artifact name="ktlint-reporter-html-0.45.2.jar">
|
||||
<sha256 value="c3f8cc9dacc1e0d2816c6a23b66b3e4af742f3aad11f882924d2807502aea71b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-json" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-json-0.43.2.jar">
|
||||
<sha256 value="9d4a94190d96d671000a06a50c9d1ce111d0dcf629bef8b4f0221a9e3f3699a0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-json" version="0.45.2">
|
||||
<artifact name="ktlint-reporter-json-0.45.2.jar">
|
||||
<sha256 value="7dc12cd16914f42255b376fae5b176b2d80bb2957a05b501a27b8d3e9f464bdc" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-plain" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-plain-0.43.2.jar">
|
||||
<sha256 value="1cab63f431ec4e9463df7a767f131ccfa8d76259c01fecc63a4c000063e8ee43" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-plain" version="0.45.2">
|
||||
<artifact name="ktlint-reporter-plain-0.45.2.jar">
|
||||
<sha256 value="d957c8647146fc79493fca30df84d26c532a71e1ad312f31f50b8fcd00f2fbd3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-sarif" version="0.43.2">
|
||||
<artifact name="ktlint-reporter-sarif-0.43.2.jar">
|
||||
<sha256 value="ed0046aaa4a2e4544197bfdccf88d472ef413a55ad05b6dc8aae41338e9d3748" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-reporter-sarif" version="0.45.2">
|
||||
<artifact name="ktlint-reporter-sarif-0.45.2.jar">
|
||||
<sha256 value="c2c8cb17e778516d57851ef8b1f604d472c07ecb635ef2115ed40de1fc63eb2e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-experimental" version="0.43.2">
|
||||
<artifact name="ktlint-ruleset-experimental-0.43.2.jar">
|
||||
<sha256 value="d89e0edcdca0ae375c090565e323520ab5d424d82fd6ac6290ea986d360f0b11" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-experimental" version="0.45.2">
|
||||
<artifact name="ktlint-ruleset-experimental-0.45.2.jar">
|
||||
<sha256 value="f9c886d091adbeb33317027a5b4ad8afd0bacdf902341925d75de698f9dd3f80" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-standard" version="0.43.2">
|
||||
<artifact name="ktlint-ruleset-standard-0.43.2.jar">
|
||||
<sha256 value="6774dc9d42aa7c7fdd4a7f3732b56fdab99ba78ce0c4eb5159036525657d0014" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-standard" version="0.45.2">
|
||||
<artifact name="ktlint-ruleset-standard-0.45.2.jar">
|
||||
<sha256 value="68efb16811780b6060120834a8d75ebd609d487824612f4bfff80ba02066e61c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-test" version="0.43.2">
|
||||
<artifact name="ktlint-ruleset-test-0.43.2.jar">
|
||||
<sha256 value="7270c4d98b2cda268c25397a02b7dea0ab8cb923958cb3853121e0d9366ce797" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.pinterest.ktlint" name="ktlint-ruleset-test" version="0.45.2">
|
||||
<artifact name="ktlint-ruleset-test-0.45.2.jar">
|
||||
<sha256 value="6660e92d94041b887e85b9620e4b7427d14c18724284092b3b35b2abebe879c1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.puppycrawl.tools" name="checkstyle" version="7.2">
|
||||
<artifact name="checkstyle-7.2.jar">
|
||||
<pgp value="06d34ed6ff73de368a772a781063fe98bcecb758"/>
|
||||
|
@ -2600,6 +2729,12 @@
|
|||
<sha256 value="2570fab55515cbf881d7a4ceef49fc515490bc027057e666776a2832465aeca0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.squareup" name="kotlinpoet" version="1.8.0">
|
||||
<artifact name="kotlinpoet-1.8.0.jar">
|
||||
<pgp value="afa2b1823fc021bfd08c211fd5f4c07a434ab3da"/>
|
||||
<sha256 value="a4f7f1f1306a97740b2c18c6089cddf65626764c4cd848aa83363681268e57f0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.squareup.okhttp3" name="okhttp" version="4.9.2">
|
||||
<artifact name="okhttp-4.9.2.jar">
|
||||
<sha256 value="3b2ee1b768c1df28c30d2fe6b38dda4d2c519210e30ca3d27950618c563c92de" origin="Generated by Gradle"/>
|
||||
|
@ -3594,6 +3729,106 @@
|
|||
<sha256 value="ed80b79d2426ec0f1fb900691dc61de64d83f649d0d0ad9f545413d6435cf9ff" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.mockk" name="mockk" version="1.12.3">
|
||||
<artifact name="mockk-1.12.3.jar">
|
||||
<sha256 value="dd39be18d38ba8c157d752f8e26aeb05ef80354f73f05faaac9f98c2f3c35496" origin="Generated by Gradle because a key couldn't be downloaded"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.mockk" name="mockk-agent-android" version="1.12.3">
|
||||
<artifact name="mockk-agent-android-1.12.3.aar">
|
||||
<sha256 value="3a14b27b3888370a8e6e8af62979efdd87f31451c798a41eca741f68ce7772ab" origin="Generated by Gradle because a key couldn't be downloaded"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.mockk" name="mockk-agent-api" version="1.12.3">
|
||||
<artifact name="mockk-agent-api-1.12.3.jar">
|
||||
<sha256 value="c9de731e90bbd7a27ed13e5370e7a10ab44b4fe1e85137bc15568494213aade3" origin="Generated by Gradle because a key couldn't be downloaded"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.mockk" name="mockk-agent-common" version="1.12.3">
|
||||
<artifact name="mockk-agent-common-1.12.3.jar">
|
||||
<sha256 value="201f62541a73bed02ec346e413e7f52f70d300cf8c3ead3d37fca8dfc42fc97c" origin="Generated by Gradle because a key couldn't be downloaded"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.mockk" name="mockk-android" version="1.12.3">
|
||||
<artifact name="mockk-android-1.12.3.aar">
|
||||
<sha256 value="3ad29a64b6bf8a1ce150f6cda36fdd56dec273a2fbcb169e84ccda6126aa3497" origin="Generated by Gradle because a key couldn't be downloaded"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.mockk" name="mockk-common" version="1.12.3">
|
||||
<artifact name="mockk-common-1.12.3.jar">
|
||||
<sha256 value="2fb0d511ab5ec1fa31981d1dba94a9f8da603787a81e59d36395c695b661a2ab" origin="Generated by Gradle because a key couldn't be downloaded"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.mockk" name="mockk-dsl" version="1.12.3">
|
||||
<artifact name="mockk-dsl-1.12.3.jar">
|
||||
<sha256 value="05ceb1530ec4e6f9c7a1fe9c5b194a97e48023a95aaa4b91c96364f70c020f93" origin="Generated by Gradle because a key couldn't be downloaded"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.mockk" name="mockk-dsl-jvm" version="1.12.3">
|
||||
<artifact name="mockk-dsl-jvm-1.12.3.jar">
|
||||
<sha256 value="038d1c794cb26e3f56d217fa31ccf9b9f08bdec18c50b078705ed8f2fe1006b9" origin="Generated by Gradle because a key couldn't be downloaded"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-buffer" version="4.1.34.Final">
|
||||
<artifact name="netty-buffer-4.1.34.Final.jar">
|
||||
<sha256 value="39dfe88df8505fd01fbf9c1dbb6b6fa9b0297e453c3dc4ce039ea578aea2eaa3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-codec" version="4.1.34.Final">
|
||||
<artifact name="netty-codec-4.1.34.Final.jar">
|
||||
<sha256 value="52e9eeb3638a8ed0911c72a508c05fa4f9d3391125eae46f287d3a8a0776211d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-codec-http" version="4.1.34.Final">
|
||||
<artifact name="netty-codec-http-4.1.34.Final.jar">
|
||||
<sha256 value="5df5556ef6b0e7ce7c72a359e4ca774fcdf8d8fe12f0b6332715eaa44cfe41f8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-codec-http2" version="4.1.34.Final">
|
||||
<artifact name="netty-codec-http2-4.1.34.Final.jar">
|
||||
<sha256 value="319f66f3ab0d3aac3477febf19c259990ee8c639fc7da8822dfa58e7dab1bdcf" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-codec-socks" version="4.1.34.Final">
|
||||
<artifact name="netty-codec-socks-4.1.34.Final.jar">
|
||||
<sha256 value="9c4ff58b648193942654db20f172d017441625754b902394f620f04074830346" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-common" version="4.1.34.Final">
|
||||
<artifact name="netty-common-4.1.34.Final.jar">
|
||||
<sha256 value="122931117eacf370b054d0e8a2411efa81de4956a6c3f938b0f0eb915969a425" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-handler" version="4.1.34.Final">
|
||||
<artifact name="netty-handler-4.1.34.Final.jar">
|
||||
<sha256 value="035616801fe9894ca2490832cf9976536dac740f41e90de1cdd4ba46f04263d1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-handler-proxy" version="4.1.34.Final">
|
||||
<artifact name="netty-handler-proxy-4.1.34.Final.jar">
|
||||
<sha256 value="f506c6acb97b3e0b0795cf9f0971d80bbab7c17086312fa225b98ccc94be6dff" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-resolver" version="4.1.34.Final">
|
||||
<artifact name="netty-resolver-4.1.34.Final.jar">
|
||||
<sha256 value="774221ed4c130b532865770b10630bc12d0d400127da617ee0ac8de2a7ac2097" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-transport" version="4.1.34.Final">
|
||||
<artifact name="netty-transport-4.1.34.Final.jar">
|
||||
<sha256 value="2b3f7d3a595101def7d411793a675bf2a325964475fd7bdbbe448e908de09445" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.opencensus" name="opencensus-api" version="0.21.0">
|
||||
<artifact name="opencensus-api-0.21.0.jar">
|
||||
<sha256 value="8e2cb0f6391d8eb0a1bcd01e7748883f0033b1941754f4ed3f19d2c3e4276fc8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.opencensus" name="opencensus-contrib-grpc-metrics" version="0.21.0">
|
||||
<artifact name="opencensus-contrib-grpc-metrics-0.21.0.jar">
|
||||
<sha256 value="29fc79401082301542cab89d7054d2f0825f184492654c950020553ef4ff0ef8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="io.netty" name="netty-buffer" version="4.1.34.Final">
|
||||
<artifact name="netty-buffer-4.1.34.Final.jar">
|
||||
<sha256 value="39dfe88df8505fd01fbf9c1dbb6b6fa9b0297e453c3dc4ce039ea578aea2eaa3" origin="Generated by Gradle"/>
|
||||
|
@ -3838,6 +4073,11 @@
|
|||
<sha256 value="941660d47822f9c0d80d40ea06d4981fcdc2b87cc625381b545efd7e6b449cef" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="net.java.dev.jna" name="jna" version="5.5.0">
|
||||
<artifact name="jna-5.5.0.jar">
|
||||
<sha256 value="b308faebfe4ed409de8410e0a632d164b2126b035f6eacff968d3908cafb4d9e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="net.java.dev.jna" name="jna" version="5.6.0">
|
||||
<artifact name="jna-5.6.0.jar">
|
||||
<pgp value="fa7929f83ad44c4590f6cc6815c71c0a4e0b8edd"/>
|
||||
|
@ -3849,6 +4089,16 @@
|
|||
<sha256 value="9ecea8bf2b1b39963939d18b70464eef60c508fed8820f9dcaba0c35518eabf7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="net.java.dev.jna" name="jna-platform" version="5.5.0">
|
||||
<artifact name="jna-platform-5.5.0.jar">
|
||||
<sha256 value="24d81621f82ac29fcdd9a74116031f5907a2343158e616f4573bbfa2434ae0d5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="net.java.dev.jna" name="jna-platform" version="5.6.0">
|
||||
<artifact name="jna-platform-5.6.0.jar">
|
||||
<sha256 value="9ecea8bf2b1b39963939d18b70464eef60c508fed8820f9dcaba0c35518eabf7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="net.ltgt.gradle" name="gradle-errorprone-plugin" version="0.0.16">
|
||||
<artifact name="gradle-errorprone-plugin-0.0.16.jar">
|
||||
<sha256 value="08915abc054a0e514911890a12834e266a9478ac79d208b24ad91bd71e4b633b" origin="Generated by Gradle"/>
|
||||
|
@ -4847,6 +5097,11 @@
|
|||
<sha256 value="ff563a4b2b3cb6c215629d6d5c652ad92c3939313d05073d3f6fed0aae67834f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-daemon-embeddable" version="1.6.20">
|
||||
<artifact name="kotlin-daemon-embeddable-1.6.20.jar">
|
||||
<sha256 value="ff563a4b2b3cb6c215629d6d5c652ad92c3939313d05073d3f6fed0aae67834f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin" version="1.6.10">
|
||||
<artifact name="kotlin-gradle-plugin-1.6.10.jar">
|
||||
<sha256 value="66c12048f8a4e9cf92ad65b12ac615702c11ae503f53c69f57f626128be1762a" origin="Generated by Gradle"/>
|
||||
|
@ -4857,6 +5112,11 @@
|
|||
<sha256 value="53fb7770ad9880e289b701d9fb729c824c59f44f2b0349ee6aac94380c4de129" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin" version="1.6.20">
|
||||
<artifact name="kotlin-gradle-plugin-1.6.20.jar">
|
||||
<sha256 value="53fb7770ad9880e289b701d9fb729c824c59f44f2b0349ee6aac94380c4de129" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-gradle-plugin-api" version="1.6.10">
|
||||
<artifact name="kotlin-gradle-plugin-api-1.6.10.jar">
|
||||
<sha256 value="7aa62528de3da7b66d97430c6d1b3f3781455b053231bbbf967e82900f527c44" origin="Generated by Gradle"/>
|
||||
|
@ -4942,6 +5202,11 @@
|
|||
<sha256 value="59c57ab609494d2a30d6ea3737428a56918ff0b8031081ea73b8472fdec06e44" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-reflect" version="1.4.31">
|
||||
<artifact name="kotlin-reflect-1.4.31.jar">
|
||||
<sha256 value="91fad0b42974a7d5811e30a61f05706e176b144235717c6de7e81e3a781028f2" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-reflect" version="1.4.32">
|
||||
<artifact name="kotlin-reflect-1.4.32.jar">
|
||||
<sha256 value="dbf19e9cdaa9c3c170f3f6f6ce3922f38dfc1d7fa1cab5b7c23a19da8b5eec5b" origin="Generated by Gradle"/>
|
||||
|
@ -5022,6 +5287,11 @@
|
|||
<sha256 value="b53a20cc9526459a8fb0d9c23e86de3166f8d65c1c66691fad52174a75fd5d09" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-serialization" version="1.6.20">
|
||||
<artifact name="kotlin-serialization-1.6.20.jar">
|
||||
<sha256 value="af8a3533e70273a3d92c4266c6072ab5b905892b4e46b051641b248e34b85613" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-scripting-jvm" version="1.6.20">
|
||||
<artifact name="kotlin-scripting-jvm-1.6.20.jar">
|
||||
<sha256 value="b53a20cc9526459a8fb0d9c23e86de3166f8d65c1c66691fad52174a75fd5d09" origin="Generated by Gradle"/>
|
||||
|
@ -5042,9 +5312,9 @@
|
|||
<sha256 value="52283996fe4067cd7330288b96ae67ecd463614dc741172c54d9d349ab6a9cd7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib" version="1.5.21">
|
||||
<artifact name="kotlin-stdlib-1.5.21.jar">
|
||||
<sha256 value="9d212b5aef23f805e0161853a5f5aefe8965b8766c889317b60f1b58bd1cf9ad" origin="Generated by Gradle"/>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib" version="1.5.30">
|
||||
<artifact name="kotlin-stdlib-1.5.30.jar">
|
||||
<sha256 value="c55608e9eb6df7327e74b21e271d324dc523cef31587b8d6d2393db08d6e000c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib" version="1.5.31">
|
||||
|
@ -5127,6 +5397,21 @@
|
|||
<sha256 value="ac12f092f12b575c1f9e0ab5025b1e610b0fe95663e26371c16c328895711bae" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.5.30">
|
||||
<artifact name="kotlin-stdlib-jdk7-1.5.30.jar">
|
||||
<sha256 value="7ce040646e6b9af662c96bbb988a1adcd4c994834d424e16960fa79fff93825d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.4.32">
|
||||
<artifact name="kotlin-stdlib-jdk7-1.4.32.jar">
|
||||
<sha256 value="5f801e75ca27d8791c14b07943c608da27620d910a8093022af57f543d5d98b6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.5.0">
|
||||
<artifact name="kotlin-stdlib-jdk7-1.5.0.jar">
|
||||
<sha256 value="ac12f092f12b575c1f9e0ab5025b1e610b0fe95663e26371c16c328895711bae" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.5.31">
|
||||
<artifact name="kotlin-stdlib-jdk7-1.5.31.jar">
|
||||
<sha256 value="a25bf47353ce899d843cbddee516d621a73473e7fba97f8d0301e7b4aed7c15f" origin="Generated by Gradle"/>
|
||||
|
@ -5137,6 +5422,11 @@
|
|||
<sha256 value="870d35fd266b2daf64c1080fe51824d3c368f7995384a8d7c5fc2fdc40eb7b3a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.6.0">
|
||||
<artifact name="kotlin-stdlib-jdk7-1.6.0.jar">
|
||||
<sha256 value="870d35fd266b2daf64c1080fe51824d3c368f7995384a8d7c5fc2fdc40eb7b3a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk7" version="1.6.10">
|
||||
<artifact name="kotlin-stdlib-jdk7-1.6.10.jar">
|
||||
<sha256 value="2aedcdc6b69b33bdf5cc235bcea88e7cf6601146bb6bcdffdb312bbacd7be261" origin="Generated by Gradle"/>
|
||||
|
@ -5187,6 +5477,11 @@
|
|||
<sha256 value="fdab1bf120e2b5e7ab6d7888e9ebc024ec6b8ca729361296395dab634b213695" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-stdlib-jdk8" version="1.6.20">
|
||||
<artifact name="kotlin-stdlib-jdk8-1.6.20.jar">
|
||||
<sha256 value="fdab1bf120e2b5e7ab6d7888e9ebc024ec6b8ca729361296395dab634b213695" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-test" version="1.6.10">
|
||||
<artifact name="kotlin-test-1.6.10.jar">
|
||||
<sha256 value="b891453cafbf961532d2ba0fb8969e40b0f7c168c9a2fc6a8cdf7c1b0577a36a" origin="Generated by Gradle"/>
|
||||
|
@ -5277,6 +5572,11 @@
|
|||
<sha256 value="e678e804cc55891e6c0576e113f725e388bb59341e906dd0f80104defe9a49c1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlin" name="kotlin-util-klib" version="1.6.20">
|
||||
<artifact name="kotlin-util-klib-1.6.20.jar">
|
||||
<sha256 value="e678e804cc55891e6c0576e113f725e388bb59341e906dd0f80104defe9a49c1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="atomicfu" version="0.16.3">
|
||||
<artifact name="atomicfu-metadata-0.16.3-all.jar">
|
||||
<sha256 value="c3c0546dd33e0ef75782734d9703eb3583a28414b1d4464fcbde56d70a7d5a6d" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
|
@ -5326,6 +5626,11 @@
|
|||
<sha256 value="ad89b520c22eab46e63610588a8c424040243294015ec214e30643c0efb7e5d4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-android" version="1.5.2">
|
||||
<artifact name="kotlinx-coroutines-android-1.5.2.jar">
|
||||
<sha256 value="86cf9892b0bd5306a8f4d7ad8a82356f614dc7d519eb3063b0887d7c2b405928" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-core" version="1.3.4">
|
||||
<artifact name="kotlinx-coroutines-core-1.3.4.jar">
|
||||
<sha256 value="17bec6112d93f5fcb11c27ecc8a14b48e30a5689ccf42c95025b89ba2210c28f" origin="Generated by Gradle"/>
|
||||
|
@ -5358,6 +5663,11 @@
|
|||
<sha256 value="78d6cc7135f84d692ff3752fcfd1fa1bbe0940d7df70652e4f1eaeec0c78afbb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-core-jvm" version="1.5.2">
|
||||
<artifact name="kotlinx-coroutines-core-jvm-1.5.2.jar">
|
||||
<sha256 value="2314c48aa1a39c05c11f3b385cdf3c56b1745f064314e4feabecebc1572b3ac1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-core-jvm" version="1.5.2-native-mt">
|
||||
<artifact name="kotlinx-coroutines-core-jvm-1.5.2-native-mt.jar">
|
||||
<sha256 value="db754be65cd22e18c8861a141cc35cedc3b659292eacb7f9d2c78a5386795dec" origin="Generated by Gradle"/>
|
||||
|
@ -5373,6 +5683,31 @@
|
|||
<sha256 value="bd5e3639e853cc1e8dca4db696ab29f95924453da93db96e20f30979e9463ef2" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-debug" version="1.5.2">
|
||||
<artifact name="kotlinx-coroutines-debug-1.5.2.jar">
|
||||
<sha256 value="f8f00f4f018d8445fb4c69655e433a8cb494c9b86cbaba841cc3ff54059c7d39" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-jdk8" version="1.6.0">
|
||||
<artifact name="kotlinx-coroutines-jdk8-1.6.0.jar">
|
||||
<sha256 value="cf93f59cafabea454b0bb03c4c3ea055f6ea17f7ff06770a765eca94dd5de867" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-slf4j" version="1.6.0">
|
||||
<artifact name="kotlinx-coroutines-slf4j-1.6.0.jar">
|
||||
<sha256 value="d8a019ae7be13992867be62d97e6993afc141a956010f5f704d569f5e9677167" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-test" version="1.5.2">
|
||||
<artifact name="kotlinx-coroutines-test-1.5.2.jar">
|
||||
<sha256 value="7f5ed01d76ecb37fc714bc0e0850b81cf753b0e968495a8db0efcd20fcb5ee60" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-test-jvm" version="1.6.0">
|
||||
<artifact name="kotlinx-coroutines-test-jvm-1.6.0.jar">
|
||||
<sha256 value="bef600516dbb41b237a883609a4f7468c2ed06d437ac13082ff4471723b4e88f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-coroutines-jdk8" version="1.6.0">
|
||||
<artifact name="kotlinx-coroutines-jdk8-1.6.0.jar">
|
||||
<sha256 value="cf93f59cafabea454b0bb03c4c3ea055f6ea17f7ff06770a765eca94dd5de867" origin="Generated by Gradle"/>
|
||||
|
@ -5391,21 +5726,62 @@
|
|||
<sha256 value="aedb7bc0b0669b51fb20c6f0ca2f6a7b3e7b76ebf46f64a5b2a842eaaa386913" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-metadata-jvm" version="0.3.0">
|
||||
<artifact name="kotlinx-metadata-jvm-0.3.0.jar">
|
||||
<sha256 value="fdaf7ba158465f6b6e9ce5762e0300fd681a976fbfeb5ed50fa5a2b26868cec8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-core" version="1.3.2">
|
||||
<artifact name="kotlinx-serialization-core-1.3.2.jar">
|
||||
<sha256 value="61d27c6a971b2c6ae70c97dca3aee642525fc428ffdf52b9e276708a9e40cea8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlinx-serialization-core-metadata-1.3.2-all.jar">
|
||||
<sha256 value="b5fe298c6242baab814f701fd21478a326f4b448409c789a4962337c05f4046e" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-core-jvm" version="1.1.0">
|
||||
<artifact name="kotlinx-serialization-core-jvm-1.1.0.jar">
|
||||
<sha256 value="69d18c700cfdf207b3e9bf6f5d58e7de08482d9e34d7c2a0adcb1db8082df943" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-core-jvm" version="1.3.2">
|
||||
<artifact name="kotlinx-serialization-core-jvm-1.3.2.jar">
|
||||
<sha256 value="4b0099a2d79c6ace9b67af8a016e03fb2f08e2f4a3213ad811ef9e9a1363a15c" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-core-linuxx64" version="1.3.0">
|
||||
<artifact name="kotlinx-serialization-core.klib">
|
||||
<sha256 value="ad49d11305253b69fdfab52bb88b2181701916871442081010c82950650021ad" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-core-linuxx64" version="1.3.2">
|
||||
<artifact name="kotlinx-serialization-core.klib">
|
||||
<sha256 value="8b70aea311112b67d58c42f1061e06f1fa351cd0abedfeb0410041596cf0ff50" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-json" version="1.3.2">
|
||||
<artifact name="kotlinx-serialization-json-1.3.2.jar">
|
||||
<sha256 value="8d58c910f51a2d23f24ac9aae4bb5a06e0273faeccc709b36458ddd2cacb0805" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="kotlinx-serialization-json-metadata-1.3.2-all.jar">
|
||||
<sha256 value="2f0dfe3bddb6c13f696c47113947b03a876f66aafcf593a66e7b840d203e5e17" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-json-jvm" version="1.1.0">
|
||||
<artifact name="kotlinx-serialization-json-jvm-1.1.0.jar">
|
||||
<sha256 value="cea6836d3a3990b7ac59f61a9534a0bf1c8d3932bd206080a3a13622ec7587d1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-json-jvm" version="1.3.2">
|
||||
<artifact name="kotlinx-serialization-json-jvm-1.3.2.jar">
|
||||
<sha256 value="706457ada21aba6cc4cdcc9637f20e700786e125ff100115c9b3e4027be03de6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.kotlinx" name="kotlinx-serialization-json-linuxx64" version="1.3.2">
|
||||
<artifact name="kotlinx-serialization-json.klib">
|
||||
<sha256 value="2a83e997494070d01e91d9d5d356f26cb1b2ba703fd063d7eee4ad60b9fe328c" origin="Generated by Gradle because artifact wasn't signed"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.jetbrains.trove4j" name="trove4j" version="20160824">
|
||||
<artifact name="trove4j-20160824.jar">
|
||||
<pgp value="33fd4bfd33554634053d73c0c2148900bcd3c2af"/>
|
||||
|
@ -5884,6 +6260,11 @@
|
|||
<sha256 value="35a77865bb9a451e99b95575cb154a5f08ecb007bd17e390817c0f31ab9db869" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="utils-reflector" version="4.4">
|
||||
<artifact name="utils-reflector-4.4.jar">
|
||||
<sha256 value="35a77865bb9a451e99b95575cb154a5f08ecb007bd17e390817c0f31ab9db869" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="utils-reflector" version="4.8.1">
|
||||
<artifact name="utils-reflector-4.8.1.jar">
|
||||
<sha256 value="d17357e5254e1e14ee258fc1604bbe011aa425fe5e7c768a04fd043476e41267" origin="Generated by Gradle"/>
|
||||
|
@ -5894,6 +6275,11 @@
|
|||
<sha256 value="c0e6cf0068ec62e86ba4e15959ed80255bd5190373f572bb5697f5143464dbf3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.slf4j" name="slf4j-android" version="1.7.36">
|
||||
<artifact name="slf4j-android-1.7.36.jar">
|
||||
<sha256 value="c0e6cf0068ec62e86ba4e15959ed80255bd5190373f572bb5697f5143464dbf3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.slf4j" name="slf4j-api" version="1.7.25">
|
||||
<artifact name="slf4j-api-1.7.25.jar">
|
||||
<pgp value="475f3b8e59e6e63aa78067482c7b12f2a511e325"/>
|
||||
|
@ -5961,6 +6347,12 @@
|
|||
<sha256 value="83168112220ac912a3dba0eebae90a4da5bf1e24b1bafd401e3d4f9f598bb2cb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.xerial" name="sqlite-jdbc" version="3.36.0">
|
||||
<artifact name="sqlite-jdbc-3.36.0.jar">
|
||||
<pgp value="56b505dc8a29c69138a430b9429c8816dea04cdb"/>
|
||||
<sha256 value="c0f13672668ec479dbf685dcadf6c2dd2fb44f266f99a90624dde46eb5524aaf" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="xerces" name="xercesImpl" version="2.12.0">
|
||||
<artifact name="xercesImpl-2.12.0.jar">
|
||||
<pgp value="51b52dc5dd452f92be342cc2858fc4c4f43856a3"/>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
/build
|
|
@ -0,0 +1,98 @@
|
|||
plugins {
|
||||
id 'org.jetbrains.kotlin.multiplatform'
|
||||
id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.20'
|
||||
id 'com.android.library'
|
||||
id "org.jlleitschuh.gradle.ktlint" version "10.2.1"
|
||||
}
|
||||
|
||||
group = 'org.fdroid'
|
||||
version = '0.1'
|
||||
|
||||
kotlin {
|
||||
android {
|
||||
compilations.all {
|
||||
kotlinOptions.jvmTarget = '1.8'
|
||||
}
|
||||
}
|
||||
// def hostOs = System.getProperty("os.name")
|
||||
// def isMingwX64 = hostOs.startsWith("Windows")
|
||||
// def nativeTarget
|
||||
// if (hostOs == "Mac OS X") nativeTarget = macosX64('native')
|
||||
// else if (hostOs == "Linux") nativeTarget = linuxX64("native") {
|
||||
// binaries { sharedLib { baseName = "fdroid_index" } }
|
||||
// }
|
||||
// else if (isMingwX64) nativeTarget = mingwX64("native")
|
||||
// else throw new GradleException("Host OS is not supported in Kotlin/Native.")
|
||||
|
||||
sourceSets {
|
||||
all {
|
||||
languageSettings {
|
||||
optIn('kotlin.RequiresOptIn')
|
||||
explicitApi('strict')
|
||||
}
|
||||
}
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2"
|
||||
implementation 'io.github.microutils:kotlin-logging:2.1.21'
|
||||
|
||||
implementation project(":download")
|
||||
implementation "io.ktor:ktor-io:2.0.0"
|
||||
}
|
||||
}
|
||||
sharedTest {
|
||||
dependencies {
|
||||
implementation kotlin('test')
|
||||
implementation "com.goncalossilva:resources:0.2.1"
|
||||
}
|
||||
}
|
||||
commonTest {
|
||||
dependsOn(sharedTest)
|
||||
}
|
||||
// JVM is disabled for now, because Android app is including it instead of Android library
|
||||
jvmMain {
|
||||
dependencies {
|
||||
}
|
||||
}
|
||||
jvmTest {
|
||||
dependencies {
|
||||
implementation 'junit:junit:4.13.2'
|
||||
}
|
||||
}
|
||||
androidMain {
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-reflect:1.6.20"
|
||||
implementation "org.slf4j:slf4j-android:1.7.36"
|
||||
}
|
||||
}
|
||||
androidTest {
|
||||
dependencies {
|
||||
implementation 'junit:junit:4.13.2'
|
||||
}
|
||||
}
|
||||
nativeMain {
|
||||
dependencies {
|
||||
}
|
||||
}
|
||||
nativeTest {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 31
|
||||
sourceSets {
|
||||
main.manifest.srcFile('src/androidMain/AndroidManifest.xml')
|
||||
getByName("androidTest").java.srcDir(file("src/androidAndroidTest/kotlin"))
|
||||
}
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
apply from: "${rootProject.rootDir}/gradle/ktlint.gradle"
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="org.fdroid.index">
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,17 @@
|
|||
package org.fdroid.index
|
||||
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
import org.fdroid.index.v1.IndexV1
|
||||
import org.fdroid.index.v2.IndexV2
|
||||
import java.io.InputStream
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
public fun IndexParser.parseV1(inputStream: InputStream): IndexV1 {
|
||||
return json.decodeFromStream(inputStream)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
public fun IndexParser.parseV2(inputStream: InputStream): IndexV2 {
|
||||
return json.decodeFromStream(inputStream)
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package org.fdroid.index
|
||||
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerializationException
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonDecoder
|
||||
import kotlinx.serialization.json.decodeFromJsonElement
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import org.fdroid.index.v2.IndexStreamReceiver
|
||||
import org.fdroid.index.v2.IndexV2
|
||||
import org.fdroid.index.v2.PackageV2
|
||||
import org.fdroid.index.v2.RepoV2
|
||||
import java.io.InputStream
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
public class IndexStreamProcessor(
|
||||
private val indexStreamReceiver: IndexStreamReceiver,
|
||||
private val json: Json = Json,
|
||||
) {
|
||||
public fun process(inputStream: InputStream) {
|
||||
json.decodeFromStream(IndexStreamSerializer(), inputStream)
|
||||
}
|
||||
|
||||
private inner class IndexStreamSerializer : KSerializer<IndexV2?> {
|
||||
override val descriptor = IndexV2.serializer().descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): IndexV2? {
|
||||
val jsonInput = decoder as? JsonDecoder ?: error("Can be deserialized only by JSON")
|
||||
val jsonObject = jsonInput.decodeJsonElement().jsonObject
|
||||
|
||||
val jsonRepo = jsonObject["repo"] ?: throw SerializationException()
|
||||
val repo = json.decodeFromJsonElement<RepoV2>(jsonRepo)
|
||||
val repoId = indexStreamReceiver.receive(null, repo)
|
||||
val packages = jsonObject["packages"]?.jsonObject ?: throw SerializationException()
|
||||
// TODO check that this isn't reading the entire stream already
|
||||
packages.entries.forEach { (packageId, jsonPackage) ->
|
||||
val p = json.decodeFromJsonElement<PackageV2>(jsonPackage)
|
||||
indexStreamReceiver.receive(repoId, packageId, p)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: IndexV2?) {
|
||||
error("Not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
package org.fdroid.index
|
||||
|
||||
import kotlinx.serialization.SerializationException
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonNull
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.int
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
import kotlinx.serialization.json.long
|
||||
import kotlinx.serialization.serializer
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KFunction
|
||||
import kotlin.reflect.KParameter
|
||||
import kotlin.reflect.full.createInstance
|
||||
import kotlin.reflect.full.memberProperties
|
||||
import kotlin.reflect.full.primaryConstructor
|
||||
|
||||
/**
|
||||
* A class using Kotlin reflection to implement JSON Merge Patch (RFC 7386) against data classes.
|
||||
* This approach loses type-safety, so you need to ensure that the structure of the [JsonObject]
|
||||
* matches exactly the structure of the data class you want to apply the diff on.
|
||||
* If something unexpected happens, [SerializationException] gets thrown.
|
||||
*/
|
||||
public object ReflectionDiffer {
|
||||
|
||||
@Throws(SerializationException::class)
|
||||
public fun applyDiff(obj: Map<*, *>, diff: JsonObject): Map<*, *> {
|
||||
return getMap(obj, diff)
|
||||
}
|
||||
|
||||
@Throws(SerializationException::class)
|
||||
public fun <T : Any> applyDiff(obj: T, diff: JsonObject): T {
|
||||
val constructor = obj::class.primaryConstructor ?: e("no primary constructor")
|
||||
val params = HashMap<KParameter, Any?>()
|
||||
constructor.parameters.forEach { parameter ->
|
||||
val prop = obj::class.memberProperties.find { memberProperty ->
|
||||
memberProperty.name == parameter.name
|
||||
} ?: e("no member property for constructor, is data class?")
|
||||
if (prop.name !in diff) {
|
||||
params[parameter] = prop.getter.call(obj)
|
||||
return@forEach
|
||||
}
|
||||
if (diff[prop.name] is JsonNull) {
|
||||
if (parameter.type.isMarkedNullable) params[parameter] = null
|
||||
else if (!parameter.isOptional) e("not nullable: ${parameter.name}")
|
||||
return@forEach
|
||||
}
|
||||
params[parameter] = when (prop.returnType.classifier) {
|
||||
Int::class -> diff[prop.name]?.jsonPrimitive?.int ?: e("${prop.name} no int")
|
||||
Long::class -> diff[prop.name]?.jsonPrimitive?.long ?: e("${prop.name} no long")
|
||||
String::class -> diff[prop.name]?.jsonPrimitive?.content
|
||||
?: e("${prop.name} no string")
|
||||
Map::class -> applyDiff(
|
||||
prop.getter.call(obj) as Map<*, *>,
|
||||
diff[prop.name]?.jsonObject ?: e("${prop.name} no map")
|
||||
)
|
||||
else -> {
|
||||
val newObj = prop.getter.call(obj)
|
||||
val jsonObject = diff[prop.name] as JsonObject
|
||||
if (newObj == null) {
|
||||
val factory = (prop.returnType.classifier as KClass<*>).primaryConstructor!!
|
||||
constructFromJson(factory, jsonObject)
|
||||
} else {
|
||||
applyDiff(newObj, jsonObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return constructor.callBy(params)
|
||||
}
|
||||
|
||||
@Throws(SerializationException::class)
|
||||
private fun <T : Any> constructFromJson(
|
||||
factory: KFunction<T>,
|
||||
diff: JsonObject,
|
||||
): T {
|
||||
val params = HashMap<KParameter, Any?>()
|
||||
factory.parameters.forEach { prop ->
|
||||
if (prop.name !in diff) e("${prop.name} required but not found")
|
||||
if (diff[prop.name] is JsonNull) {
|
||||
if (prop.type.isMarkedNullable) params[prop] = null
|
||||
else if (!prop.isOptional) e("not nullable: ${prop.name}")
|
||||
return@forEach
|
||||
}
|
||||
params[prop] = when (prop.type.classifier) {
|
||||
Int::class -> diff[prop.name]?.jsonPrimitive?.int ?: e("no int")
|
||||
Long::class -> diff[prop.name]?.jsonPrimitive?.long ?: e("no long")
|
||||
String::class -> diff[prop.name]?.jsonPrimitive?.content ?: e("no string")
|
||||
Map::class -> applyDiff(
|
||||
prop.type::class.createInstance(),
|
||||
diff[prop.name]?.jsonObject!!,
|
||||
)
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
return factory.callBy(params)
|
||||
}
|
||||
|
||||
@Throws(SerializationException::class)
|
||||
private fun getMap(map: Map<*, *>, jsonObject: JsonObject?): Map<*, *> {
|
||||
return map.toMutableMap().apply {
|
||||
jsonObject?.entries?.forEach { (key, value) ->
|
||||
if (value is JsonNull) remove(key)
|
||||
else set(key, value.jsonPrimitive.content)
|
||||
} ?: e("no object")
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(SerializationException::class)
|
||||
private fun e(msg: String): Nothing = throw SerializationException(msg)
|
||||
|
||||
public inline fun <reified T> Json.decodeOr(
|
||||
key: String,
|
||||
json: JsonObject,
|
||||
default: () -> T,
|
||||
): T {
|
||||
return if (json.containsKey(key)) {
|
||||
decodeFromJsonElement(serializersModule.serializer(), json)
|
||||
} else {
|
||||
default()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package org.fdroid.index
|
||||
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import org.fdroid.index.v2.FileV2
|
||||
import org.fdroid.index.v2.LocalizedTextV2
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
internal class ReflectionDifferTest {
|
||||
|
||||
@Test
|
||||
fun testLocalizedNullableTextV2Diff() {
|
||||
val old: LocalizedTextV2 = buildMap {
|
||||
put("de", "football")
|
||||
put("en", "bar")
|
||||
put("de-DE", "foo bar")
|
||||
}
|
||||
val json = """
|
||||
{
|
||||
"de": "foo",
|
||||
"en": null,
|
||||
"en-US": "bar"
|
||||
}
|
||||
""".trimIndent()
|
||||
val diff = Json.parseToJsonElement(json).jsonObject
|
||||
val result = ReflectionDiffer.applyDiff(old, diff)
|
||||
|
||||
assertEquals(3, result.size)
|
||||
assertEquals("foo", result["de"])
|
||||
assertEquals("bar", result["en-US"])
|
||||
assertEquals("foo bar", result["de-DE"])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFileDiffV2() {
|
||||
val old = FileV2(
|
||||
name = "foo",
|
||||
sha256 = "bar",
|
||||
size = Random.nextLong()
|
||||
)
|
||||
val json = """
|
||||
{
|
||||
"name": "foo bar",
|
||||
"size": null
|
||||
}
|
||||
""".trimIndent()
|
||||
val diff = Json.parseToJsonElement(json).jsonObject
|
||||
val result = ReflectionDiffer.applyDiff(old, diff)
|
||||
|
||||
assertEquals("foo bar", result.name)
|
||||
assertEquals("bar", result.sha256)
|
||||
assertEquals(null, result.size)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.fdroid.index
|
||||
|
||||
import io.ktor.utils.io.jvm.javaio.toByteReadChannel
|
||||
import io.ktor.utils.io.jvm.javaio.toInputStream
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.decodeFromStream
|
||||
import org.fdroid.index.v1.IndexV1
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import kotlin.test.Test
|
||||
|
||||
internal class StreamTest {
|
||||
|
||||
@Test
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
fun test() = runBlocking {
|
||||
val file = File("src/commonTest/resources/index-v1.json")
|
||||
val byteChannel = FileInputStream(file).toByteReadChannel()
|
||||
val index = Json.decodeFromStream<IndexV1>(byteChannel.toInputStream())
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.fdroid.index
|
||||
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.fdroid.index.v1.IndexV1
|
||||
import org.fdroid.index.v2.IndexV2
|
||||
|
||||
public object IndexParser {
|
||||
|
||||
@Volatile
|
||||
private var JSON: Json? = null
|
||||
|
||||
/**
|
||||
* Initializing [Json] is expensive, so using this method is preferable as it keeps returning
|
||||
* a single instance with the recommended settings.
|
||||
*/
|
||||
public val json: Json
|
||||
@JvmStatic
|
||||
get() {
|
||||
return JSON ?: synchronized(this) {
|
||||
Json {
|
||||
ignoreUnknownKeys = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun parseV1(str: String): IndexV1 {
|
||||
return json.decodeFromString(str)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
public fun parseV2(str: String): IndexV2 {
|
||||
return json.decodeFromString(str)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.fdroid.index.v1
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
public data class AppV1(
|
||||
val categories: List<String> = emptyList(), // missing in wind repo
|
||||
val antiFeatures: List<String> = emptyList(),
|
||||
val summary: String? = null,
|
||||
val description: String? = null,
|
||||
val changelog: String? = null,
|
||||
val translation: String? = null,
|
||||
val issueTracker: String? = null,
|
||||
val sourceCode: String? = null,
|
||||
val binaries: String? = null,
|
||||
val name: String? = null,
|
||||
val authorName: String? = null,
|
||||
val authorEmail: String? = null,
|
||||
val authorWebSite: String? = null,
|
||||
val authorPhone: String? = null,
|
||||
val donate: String? = null,
|
||||
val liberapayID: String? = null,
|
||||
val liberapay: String? = null,
|
||||
val openCollective: String? = null,
|
||||
val bitcoin: String? = null,
|
||||
val litecoin: String? = null,
|
||||
val flattrID: String? = null,
|
||||
val suggestedVersionName: String? = null, // missing in guardian project repo
|
||||
val suggestedVersionCode: String? = null, // missing in wind repo
|
||||
val license: String,
|
||||
val webSite: String? = null,
|
||||
val added: Long? = null, // missing in wind repo,
|
||||
val icon: String? = null,
|
||||
val packageName: String,
|
||||
val lastUpdated: Long? = null, // missing in wind repo,
|
||||
val localized: Map<String, Localized>? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class Localized(
|
||||
val description: String? = null,
|
||||
val name: String? = null,
|
||||
val icon: String? = null,
|
||||
val whatsNew: String? = null,
|
||||
val video: String? = null,
|
||||
val phoneScreenshots: List<String>? = null,
|
||||
val sevenInchScreenshots: List<String>? = null,
|
||||
val tenInchScreenshots: List<String>? = null,
|
||||
val wearScreenshots: List<String>? = null,
|
||||
val tvScreenshots: List<String>? = null,
|
||||
val featureGraphic: String? = null,
|
||||
val promoGraphic: String? = null,
|
||||
val tvBanner: String? = null,
|
||||
val summary: String? = null,
|
||||
)
|
|
@ -0,0 +1,31 @@
|
|||
package org.fdroid.index.v1
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
public data class IndexV1(
|
||||
val repo: RepoV1,
|
||||
val requests: Requests,
|
||||
val apps: List<AppV1>,
|
||||
val packages: Map<String, List<PackageV1>>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class RepoV1(
|
||||
val timestamp: Long,
|
||||
val version: Int,
|
||||
@SerialName("maxage")
|
||||
val maxAge: Int? = null, // missing in izzy repo
|
||||
val name: String,
|
||||
val icon: String,
|
||||
val address: String,
|
||||
val description: String,
|
||||
val mirrors: List<String> = emptyList(), // missing in izzy repo
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class Requests(
|
||||
val install: List<String>,
|
||||
val uninstall: List<String>,
|
||||
)
|
|
@ -0,0 +1,67 @@
|
|||
package org.fdroid.index.v1
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.element
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.JsonDecoder
|
||||
import kotlinx.serialization.json.intOrNull
|
||||
import kotlinx.serialization.json.jsonArray
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
|
||||
@Serializable
|
||||
public data class PackageV1(
|
||||
val added: Long? = null,
|
||||
val apkName: String,
|
||||
val hash: String,
|
||||
val hashType: String, // TODO enum?
|
||||
val minSdkVersion: Int? = null,
|
||||
val maxSdkVersion: Int? = null,
|
||||
val targetSdkVersion: Int? = minSdkVersion,
|
||||
val packageName: String,
|
||||
val sig: String? = null,
|
||||
val signer: String? = null,
|
||||
val size: Long,
|
||||
@SerialName("srcname")
|
||||
val srcName: String? = null,
|
||||
@SerialName("uses-permission")
|
||||
val usesPermission: List<PermissionV1> = emptyList(),
|
||||
@SerialName("uses-permission-sdk-23")
|
||||
val usesPermission23: List<PermissionV1> = emptyList(),
|
||||
val versionCode: Long? = null,
|
||||
val versionName: String,
|
||||
@SerialName("nativecode")
|
||||
val nativeCode: List<String>? = null,
|
||||
val features: List<String>? = null,
|
||||
val antiFeatures: List<String>? = null,
|
||||
)
|
||||
|
||||
@Serializable(with = PermissionV1Serializer::class)
|
||||
public data class PermissionV1(
|
||||
val name: String,
|
||||
val maxSdk: Int?,
|
||||
)
|
||||
|
||||
internal class PermissionV1Serializer : KSerializer<PermissionV1> {
|
||||
override val descriptor = buildClassSerialDescriptor("PermissionV1") {
|
||||
element<String>("name")
|
||||
element<Int?>("maxSdk")
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): PermissionV1 {
|
||||
val jsonInput = decoder as? JsonDecoder ?: error("Can be deserialized only by JSON")
|
||||
val jsonArray = jsonInput.decodeJsonElement().jsonArray
|
||||
if (jsonArray.size != 2) throw IllegalArgumentException()
|
||||
val name = jsonArray[0].jsonPrimitive.content
|
||||
val maxSdk = jsonArray[1].jsonPrimitive.intOrNull
|
||||
return PermissionV1(name, maxSdk)
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: PermissionV1) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.fdroid.index.v2
|
||||
|
||||
public interface IndexStreamReceiver {
|
||||
|
||||
public fun receive(repoId: Long? = null, repo: RepoV2): Long
|
||||
public fun receive(repoId: Long, packageId: String, p: PackageV2)
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package org.fdroid.index.v2
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
public data class EntryV2(
|
||||
val timestamp: Long,
|
||||
val version: Long,
|
||||
val maxAge: Int,
|
||||
val index: FileV2,
|
||||
val diffs: Map<String, FileV2>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class FileV2(
|
||||
val name: String,
|
||||
val sha256: String? = null,
|
||||
val size: Long? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class IndexV2(
|
||||
val repo: RepoV2,
|
||||
val packages: Map<String, PackageV2>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class RepoV2(
|
||||
val name: String,
|
||||
val icon: FileV2? = null,
|
||||
val address: String,
|
||||
val webBaseUrl: String?,
|
||||
val description: LocalizedTextV2 = emptyMap(),
|
||||
val mirrors: List<MirrorV2> = emptyList(),
|
||||
val timestamp: Long,
|
||||
val antiFeatures: Map<String, AntiFeatureV2> = emptyMap(),
|
||||
val categories: Map<String, CategoryV2> = emptyMap(),
|
||||
val releaseChannels: Map<String, ReleaseChannelV2> = emptyMap(),
|
||||
)
|
||||
|
||||
public typealias LocalizedTextV2 = Map<String, String>
|
||||
public typealias LocalizedFileV2 = Map<String, FileV2>
|
||||
public typealias LocalizedFileListV2 = Map<String, List<FileV2>>
|
||||
|
||||
@Serializable
|
||||
public data class MirrorV2(
|
||||
val url: String,
|
||||
val location: String? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class AntiFeatureV2(
|
||||
val icon: FileV2,
|
||||
val description: LocalizedTextV2,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class CategoryV2(
|
||||
val icon: FileV2,
|
||||
val description: LocalizedTextV2,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class ReleaseChannelV2(
|
||||
val description: LocalizedTextV2,
|
||||
)
|
|
@ -0,0 +1,136 @@
|
|||
package org.fdroid.index.v2
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
public data class PackageV2(
|
||||
val metadata: MetadataV2,
|
||||
val versions: Map<String, PackageVersionV2>,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class MetadataV2(
|
||||
val name: LocalizedTextV2? = null,
|
||||
val summary: LocalizedTextV2? = null,
|
||||
val description: LocalizedTextV2? = null,
|
||||
val added: Long,
|
||||
val lastUpdated: Long,
|
||||
val webSite: String? = null,
|
||||
val changelog: String? = null,
|
||||
val license: String? = null,
|
||||
val sourceCode: String? = null,
|
||||
val issueTracker: String? = null,
|
||||
val translation: String? = null,
|
||||
val preferredSigner: String? = null,
|
||||
val categories: List<String> = emptyList(),
|
||||
val author: Author? = null,
|
||||
val donation: Donation? = null,
|
||||
val icon: LocalizedFileV2? = null,
|
||||
val featureGraphic: LocalizedFileV2? = null,
|
||||
val promoGraphic: LocalizedFileV2? = null,
|
||||
val tvBanner: LocalizedFileV2? = null,
|
||||
val video: LocalizedTextV2? = null,
|
||||
val screenshots: Screenshots? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class Author(
|
||||
val name: String? = null,
|
||||
val email: String? = null,
|
||||
val website: String? = null,
|
||||
val phone: String? = null,
|
||||
) {
|
||||
internal constructor() : this(null, null, null, null)
|
||||
|
||||
val isNull: Boolean get() = (name == null && email == null && website == null && phone == null)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public data class Donation(
|
||||
val url: String? = null,
|
||||
val liberapayID: String? = null,
|
||||
val liberapay: String? = null,
|
||||
val openCollective: String? = null,
|
||||
val bitcoin: String? = null,
|
||||
val litecoin: String? = null,
|
||||
val flattrID: String? = null,
|
||||
) {
|
||||
internal constructor() : this(null, null, null, null, null, null, null)
|
||||
|
||||
val isNull: Boolean
|
||||
get() = (url == null && liberapayID == null && liberapay == null &&
|
||||
openCollective == null && bitcoin == null && litecoin == null && flattrID == null)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public data class Screenshots(
|
||||
val phone: LocalizedFileListV2? = null,
|
||||
val sevenInch: LocalizedFileListV2? = null,
|
||||
val tenInch: LocalizedFileListV2? = null,
|
||||
val wear: LocalizedFileListV2? = null,
|
||||
val tv: LocalizedFileListV2? = null,
|
||||
) {
|
||||
val isNull: Boolean
|
||||
get() = (phone == null && sevenInch == null && tenInch == null && wear == null
|
||||
&& tv == null)
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public data class PackageVersionV2(
|
||||
val added: Long,
|
||||
val file: FileV1,
|
||||
val src: FileV2? = null,
|
||||
val manifest: ManifestV2,
|
||||
val releaseChannels: List<String> = emptyList(),
|
||||
val antiFeatures: Map<String, LocalizedTextV2> = emptyMap(),
|
||||
val whatsNew: LocalizedTextV2 = emptyMap(),
|
||||
)
|
||||
|
||||
/**
|
||||
* Like [FileV2] with the only difference that the [sha256] hash can not be null.
|
||||
* Even in index-v1 this must exist, so we can use it as a primary key in the DB.
|
||||
*/
|
||||
@Serializable
|
||||
public data class FileV1(
|
||||
val name: String,
|
||||
val sha256: String,
|
||||
val size: Long? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class ManifestV2(
|
||||
val versionName: String,
|
||||
val versionCode: Long,
|
||||
val usesSdk: UsesSdkV2? = null,
|
||||
val maxSdkVersion: Int? = null,
|
||||
val signer: SignatureV2? = null, // TODO really null?
|
||||
val usesPermission: List<PermissionV2> = emptyList(),
|
||||
val usesPermissionSdk23: List<PermissionV2> = emptyList(),
|
||||
@SerialName("nativecode")
|
||||
val nativeCode: List<String> = emptyList(),
|
||||
val features: List<FeatureV2> = emptyList(), // TODO can probably be a List<String> again
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class UsesSdkV2(
|
||||
val minSdkVersion: Int,
|
||||
val targetSdkVersion: Int,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class SignatureV2(
|
||||
val sha256: List<String>,
|
||||
val hasMultipleSigners: Boolean = false,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class PermissionV2(
|
||||
val name: String,
|
||||
val maxSdkVersion: Int? = null,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
public data class FeatureV2(
|
||||
val name: String,
|
||||
)
|
|
@ -0,0 +1,49 @@
|
|||
package org.fdroid.index
|
||||
|
||||
import com.goncalossilva.resources.Resource
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.fdroid.index.v1.IndexV1
|
||||
import org.fdroid.index.v2.EntryV2
|
||||
import org.fdroid.index.v2.IndexV2
|
||||
import kotlin.test.Test
|
||||
|
||||
class Test {
|
||||
|
||||
@Test
|
||||
fun testIndexV1() {
|
||||
val indexStr = Resource("src/commonTest/resources/index-v1.json").readText()
|
||||
val index = Json.decodeFromString<IndexV1>(indexStr)
|
||||
|
||||
val indexArchiveStr =
|
||||
Resource("src/commonTest/resources/fdroid-archive/index-v1.json").readText()
|
||||
Json.decodeFromString<IndexV1>(indexArchiveStr)
|
||||
|
||||
val indexGuardianStr =
|
||||
Resource("src/commonTest/resources/guardian/index-v1.json").readText()
|
||||
Json.decodeFromString<IndexV1>(indexGuardianStr)
|
||||
|
||||
val indexIzzyStr = Resource("src/commonTest/resources/izzy/index-v1.json").readText()
|
||||
Json.decodeFromString<IndexV1>(indexIzzyStr)
|
||||
|
||||
val indexWindStr = Resource("src/commonTest/resources/wind/index-v1.json").readText()
|
||||
Json.decodeFromString<IndexV1>(indexWindStr)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIndexV2() {
|
||||
val entryStr = Resource("src/commonTest/resources/entry.json").readText()
|
||||
val entry = Json.decodeFromString<EntryV2>(entryStr)
|
||||
|
||||
val indexStr = Resource("src/commonTest/resources/index-v2.json").readText()
|
||||
val index = Json.decodeFromString<IndexV2>(indexStr)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDiffV2() {
|
||||
// val diff1Str = Resource("src/commonTest/resources/tmp.json").readText()
|
||||
// val diff1 = Json.decodeFromString<DiffV2>(diff1Str)
|
||||
// println(diff1)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package org.fdroid.index.v1
|
||||
|
||||
import com.goncalossilva.resources.Resource
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.junit.Assume.assumeTrue
|
||||
import kotlin.test.Test
|
||||
|
||||
internal class IndexV1Test {
|
||||
|
||||
@Test
|
||||
fun testIndexV1() {
|
||||
val indexRes = Resource("src/commonTest/resources/index-v1.json")
|
||||
assumeTrue(indexRes.exists())
|
||||
val indexStr = indexRes.readText()
|
||||
val index = Json.decodeFromString<IndexV1>(indexStr)
|
||||
|
||||
val indexArchiveRes = Resource("src/commonTest/resources/fdroid-archive/index-v1.json")
|
||||
assumeTrue(indexArchiveRes.exists())
|
||||
val indexArchiveStr = indexArchiveRes.readText()
|
||||
assumeTrue(indexRes.exists())
|
||||
Json.decodeFromString<IndexV1>(indexArchiveStr)
|
||||
|
||||
val indexGuardianRes = Resource("src/commonTest/resources/guardian/index-v1.json")
|
||||
assumeTrue(indexGuardianRes.exists())
|
||||
val indexGuardianStr = indexGuardianRes.readText()
|
||||
Json.decodeFromString<IndexV1>(indexGuardianStr)
|
||||
|
||||
val indexIzzyRes = Resource("src/commonTest/resources/izzy/index-v1.json")
|
||||
assumeTrue(indexIzzyRes.exists())
|
||||
val indexIzzyStr = indexIzzyRes.readText()
|
||||
Json.decodeFromString<IndexV1>(indexIzzyStr)
|
||||
|
||||
val indexWindRes = Resource("src/commonTest/resources/wind/index-v1.json")
|
||||
assumeTrue(indexWindRes.exists())
|
||||
val indexWindStr = indexWindRes.readText()
|
||||
Json.decodeFromString<IndexV1>(indexWindStr)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package org.fdroid.index.v2
|
||||
|
||||
import com.goncalossilva.resources.Resource
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.junit.Assume.assumeTrue
|
||||
import kotlin.test.Test
|
||||
|
||||
internal class IndexV2Test {
|
||||
|
||||
@Test
|
||||
fun testIndexV2() {
|
||||
val entryRes = Resource("src/commonTest/resources/entry.json")
|
||||
assumeTrue(entryRes.exists())
|
||||
val entryStr = entryRes.readText()
|
||||
val entry = Json.decodeFromString<EntryV2>(entryStr)
|
||||
|
||||
val indexRes = Resource("src/commonTest/resources/index-v2.json")
|
||||
assumeTrue(indexRes.exists())
|
||||
val indexStr = indexRes.readText()
|
||||
val index = Json.decodeFromString<IndexV2>(indexStr)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDiffV2() {
|
||||
// val diff1Res = Resource("src/commonTest/resources/tmp.json")
|
||||
// assumeTrue(diff1Res.exists())
|
||||
// val diff1Str = diff1Res.readText()
|
||||
// val diff1 = Json.decodeFromString<DiffV2>(diff1Str)
|
||||
// println(diff1)
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.fdroid.test
|
||||
|
||||
import kotlin.random.Random
|
||||
|
||||
public object DiffUtils {
|
||||
|
||||
/**
|
||||
* Create a map diff by adding or removing keys. Note that this does not change keys.
|
||||
*/
|
||||
public fun <T> Map<String, T?>.randomDiff(factory: () -> T): Map<String, T?> = buildMap {
|
||||
if (this@randomDiff.isNotEmpty()) {
|
||||
// remove random keys
|
||||
while (Random.nextBoolean()) put(this@randomDiff.keys.random(), null)
|
||||
// Note: we don't replace random keys, because we can't easily diff inside T
|
||||
}
|
||||
// add random keys
|
||||
while (Random.nextBoolean()) put(TestUtils.getRandomString(), factory())
|
||||
}
|
||||
|
||||
public fun <T> Map<String, T>.applyDiff(diff: Map<String, T?>): Map<String, T> =
|
||||
toMutableMap().apply {
|
||||
diff.entries.forEach { (key, value) ->
|
||||
if (value == null) remove(key)
|
||||
else set(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package org.fdroid.test
|
||||
|
||||
import org.fdroid.index.v2.Author
|
||||
import org.fdroid.index.v2.Donation
|
||||
import org.fdroid.index.v2.FileV2
|
||||
import org.fdroid.index.v2.LocalizedFileListV2
|
||||
import org.fdroid.index.v2.MetadataV2
|
||||
import org.fdroid.index.v2.Screenshots
|
||||
import org.fdroid.test.TestRepoUtils.getRandomFileV2
|
||||
import org.fdroid.test.TestRepoUtils.getRandomLocalizedFileV2
|
||||
import org.fdroid.test.TestRepoUtils.getRandomLocalizedTextV2
|
||||
import org.fdroid.test.TestUtils.getRandomList
|
||||
import org.fdroid.test.TestUtils.getRandomString
|
||||
import org.fdroid.test.TestUtils.orNull
|
||||
import kotlin.random.Random
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
public object TestAppUtils {
|
||||
|
||||
public fun getRandomMetadataV2(): MetadataV2 = MetadataV2(
|
||||
added = Random.nextLong(),
|
||||
lastUpdated = Random.nextLong(),
|
||||
name = getRandomLocalizedTextV2().orNull(),
|
||||
summary = getRandomLocalizedTextV2().orNull(),
|
||||
description = getRandomLocalizedTextV2().orNull(),
|
||||
webSite = getRandomString().orNull(),
|
||||
changelog = getRandomString().orNull(),
|
||||
license = getRandomString().orNull(),
|
||||
sourceCode = getRandomString().orNull(),
|
||||
issueTracker = getRandomString().orNull(),
|
||||
translation = getRandomString().orNull(),
|
||||
preferredSigner = getRandomString().orNull(),
|
||||
video = getRandomLocalizedTextV2().orNull(),
|
||||
author = getRandomAuthor().orNull(),
|
||||
donation = getRandomDonation().orNull(),
|
||||
icon = getRandomLocalizedFileV2().orNull(),
|
||||
featureGraphic = getRandomLocalizedFileV2().orNull(),
|
||||
promoGraphic = getRandomLocalizedFileV2().orNull(),
|
||||
tvBanner = getRandomLocalizedFileV2().orNull(),
|
||||
categories = getRandomList { getRandomString() }.orNull()
|
||||
?: emptyList(),
|
||||
screenshots = getRandomScreenshots().orNull(),
|
||||
)
|
||||
|
||||
public fun getRandomAuthor(): Author = Author(
|
||||
name = getRandomString().orNull(),
|
||||
email = getRandomString().orNull(),
|
||||
website = getRandomString().orNull(),
|
||||
phone = getRandomString().orNull(),
|
||||
)
|
||||
|
||||
public fun getRandomDonation(): Donation = Donation(
|
||||
url = getRandomString().orNull(),
|
||||
liberapay = getRandomString().orNull(),
|
||||
liberapayID = getRandomString().orNull(),
|
||||
openCollective = getRandomString().orNull(),
|
||||
bitcoin = getRandomString().orNull(),
|
||||
litecoin = getRandomString().orNull(),
|
||||
flattrID = getRandomString().orNull(),
|
||||
)
|
||||
|
||||
public fun getRandomScreenshots(): Screenshots? = Screenshots(
|
||||
phone = getRandomLocalizedFileListV2().orNull(),
|
||||
sevenInch = getRandomLocalizedFileListV2().orNull(),
|
||||
tenInch = getRandomLocalizedFileListV2().orNull(),
|
||||
wear = getRandomLocalizedFileListV2().orNull(),
|
||||
tv = getRandomLocalizedFileListV2().orNull(),
|
||||
).takeIf { !it.isNull }
|
||||
|
||||
public fun getRandomLocalizedFileListV2(): Map<String, List<FileV2>> =
|
||||
TestUtils.getRandomMap(Random.nextInt(1, 3)) {
|
||||
getRandomString() to getRandomList(Random.nextInt(1, 7)) {
|
||||
getRandomFileV2()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [Screenshots] include lists which can be ordered differently,
|
||||
* so we need to ignore order when comparing them.
|
||||
*/
|
||||
public fun assertScreenshotsEqual(s1: Screenshots?, s2: Screenshots?) {
|
||||
if (s1 != null && s2 != null) {
|
||||
assertLocalizedFileListV2Equal(s1.phone, s2.phone)
|
||||
assertLocalizedFileListV2Equal(s1.sevenInch, s2.sevenInch)
|
||||
assertLocalizedFileListV2Equal(s1.tenInch, s2.tenInch)
|
||||
assertLocalizedFileListV2Equal(s1.wear, s2.wear)
|
||||
assertLocalizedFileListV2Equal(s1.tv, s2.tv)
|
||||
} else {
|
||||
assertEquals(s1, s2)
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertLocalizedFileListV2Equal(l1: LocalizedFileListV2?, l2: LocalizedFileListV2?) {
|
||||
if (l1 != null && l2 != null) {
|
||||
l1.keys.forEach { key ->
|
||||
assertEquals(l1[key]?.toSet(), l2[key]?.toSet())
|
||||
}
|
||||
} else {
|
||||
assertEquals(l1, l2)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package org.fdroid.test
|
||||
|
||||
import org.fdroid.index.v2.AntiFeatureV2
|
||||
import org.fdroid.index.v2.CategoryV2
|
||||
import org.fdroid.index.v2.FileV2
|
||||
import org.fdroid.index.v2.LocalizedTextV2
|
||||
import org.fdroid.index.v2.MirrorV2
|
||||
import org.fdroid.index.v2.ReleaseChannelV2
|
||||
import org.fdroid.index.v2.RepoV2
|
||||
import org.fdroid.test.TestUtils.getRandomList
|
||||
import org.fdroid.test.TestUtils.getRandomString
|
||||
import org.fdroid.test.TestUtils.orNull
|
||||
import kotlin.random.Random
|
||||
|
||||
public object TestRepoUtils {
|
||||
|
||||
public fun getRandomMirror(): MirrorV2 = MirrorV2(
|
||||
url = getRandomString(),
|
||||
location = getRandomString().orNull()
|
||||
)
|
||||
|
||||
public fun getRandomLocalizedTextV2(size: Int = Random.nextInt(0, 23)): LocalizedTextV2 =
|
||||
buildMap {
|
||||
repeat(size) {
|
||||
put(getRandomString(4), getRandomString())
|
||||
}
|
||||
}
|
||||
|
||||
public fun getRandomFileV2(sha256Nullable: Boolean = true): FileV2 = FileV2(
|
||||
name = getRandomString(),
|
||||
sha256 = getRandomString(64).also { if (sha256Nullable) orNull() },
|
||||
size = Random.nextLong(-1, Long.MAX_VALUE)
|
||||
)
|
||||
|
||||
public fun getRandomLocalizedFileV2(): Map<String, FileV2> =
|
||||
TestUtils.getRandomMap(Random.nextInt(1, 8)) {
|
||||
getRandomString(4) to getRandomFileV2()
|
||||
}
|
||||
|
||||
public fun getRandomRepo(): RepoV2 = RepoV2(
|
||||
name = getRandomString(),
|
||||
icon = getRandomFileV2(),
|
||||
address = getRandomString(),
|
||||
description = getRandomLocalizedTextV2(),
|
||||
mirrors = getRandomList { getRandomMirror() },
|
||||
timestamp = System.currentTimeMillis(),
|
||||
antiFeatures = TestUtils.getRandomMap {
|
||||
getRandomString() to AntiFeatureV2(
|
||||
icon = getRandomFileV2(),
|
||||
name = getRandomLocalizedTextV2(),
|
||||
description = getRandomLocalizedTextV2(),
|
||||
)
|
||||
},
|
||||
categories = TestUtils.getRandomMap {
|
||||
getRandomString() to CategoryV2(
|
||||
icon = getRandomFileV2(),
|
||||
name = getRandomLocalizedTextV2(),
|
||||
description = getRandomLocalizedTextV2(),
|
||||
)
|
||||
},
|
||||
releaseChannels = TestUtils.getRandomMap {
|
||||
getRandomString() to ReleaseChannelV2(
|
||||
name = getRandomLocalizedTextV2(),
|
||||
description = getRandomLocalizedTextV2(),
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package org.fdroid.test
|
||||
|
||||
import kotlin.random.Random
|
||||
|
||||
public object TestUtils {
|
||||
|
||||
private val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
|
||||
|
||||
public fun getRandomString(length: Int = Random.nextInt(1, 128)): String = (1..length)
|
||||
.map { Random.nextInt(0, charPool.size) }
|
||||
.map(charPool::get)
|
||||
.joinToString("")
|
||||
|
||||
public fun <T> getRandomList(
|
||||
size: Int = Random.nextInt(0, 23),
|
||||
factory: () -> T,
|
||||
): List<T> = if (size == 0) emptyList() else buildList {
|
||||
repeat(size) {
|
||||
add(factory())
|
||||
}
|
||||
}
|
||||
|
||||
public fun <A, B> getRandomMap(
|
||||
size: Int = Random.nextInt(0, 23),
|
||||
factory: () -> Pair<A, B>,
|
||||
): Map<A, B> = if (size == 0) emptyMap() else buildMap {
|
||||
repeat(size) {
|
||||
val pair = factory()
|
||||
put(pair.first, pair.second)
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T> T.orNull(): T? {
|
||||
return if (Random.nextBoolean()) null else this
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package org.fdroid.test
|
||||
|
||||
import org.fdroid.index.v2.FeatureV2
|
||||
import org.fdroid.index.v2.FileV1
|
||||
import org.fdroid.index.v2.ManifestV2
|
||||
import org.fdroid.index.v2.PackageVersionV2
|
||||
import org.fdroid.index.v2.PermissionV2
|
||||
import org.fdroid.index.v2.SignatureV2
|
||||
import org.fdroid.index.v2.UsesSdkV2
|
||||
import org.fdroid.test.TestRepoUtils.getRandomFileV2
|
||||
import org.fdroid.test.TestRepoUtils.getRandomLocalizedTextV2
|
||||
import org.fdroid.test.TestUtils.getRandomList
|
||||
import org.fdroid.test.TestUtils.getRandomMap
|
||||
import org.fdroid.test.TestUtils.getRandomString
|
||||
import org.fdroid.test.TestUtils.orNull
|
||||
import kotlin.random.Random
|
||||
|
||||
internal object TestVersionUtils {
|
||||
|
||||
fun getRandomPackageVersionV2() = PackageVersionV2(
|
||||
added = Random.nextLong(),
|
||||
file = getRandomFileV2(false).let {
|
||||
FileV1(it.name, it.sha256!!, it.size)
|
||||
},
|
||||
src = getRandomFileV2().orNull(),
|
||||
manifest = getRandomManifestV2(),
|
||||
releaseChannels = getRandomList { getRandomString() },
|
||||
antiFeatures = getRandomMap { getRandomString() to getRandomLocalizedTextV2() },
|
||||
whatsNew = getRandomLocalizedTextV2(),
|
||||
)
|
||||
|
||||
fun getRandomManifestV2() = ManifestV2(
|
||||
versionName = getRandomString(),
|
||||
versionCode = Random.nextLong(),
|
||||
usesSdk = UsesSdkV2(
|
||||
minSdkVersion = Random.nextInt(),
|
||||
targetSdkVersion = Random.nextInt(),
|
||||
),
|
||||
maxSdkVersion = Random.nextInt().orNull(),
|
||||
signer = SignatureV2(getRandomList(Random.nextInt(1, 3)) {
|
||||
getRandomString(64)
|
||||
}).orNull(),
|
||||
usesPermission = getRandomList {
|
||||
PermissionV2(getRandomString(), Random.nextInt().orNull())
|
||||
},
|
||||
usesPermissionSdk23 = getRandomList {
|
||||
PermissionV2(getRandomString(), Random.nextInt().orNull())
|
||||
},
|
||||
nativeCode = getRandomList(Random.nextInt(0, 4)) { getRandomString() },
|
||||
features = getRandomList { FeatureV2(getRandomString()) },
|
||||
)
|
||||
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
include ':app'
|
||||
include ':download'
|
||||
include ':index'
|
Loading…
Reference in New Issue