refactor(build-logic): move PSL download to task action

This commit is contained in:
Harsh Shandilya 2022-10-07 17:28:37 +05:30
parent 656669b55e
commit fe666e9ecb
No known key found for this signature in database
3 changed files with 85 additions and 93 deletions

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.7.10" />
<option name="version" value="1.7.20" />
</component>
</project>

View file

@ -1,29 +1,87 @@
/*
* Copyright © 2014-2022 The Android Password Store Authors. All Rights Reserved.
* SPDX-License-Identifier: GPL-3.0-only
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package app.passwordstore.gradle.psl
import java.util.TreeSet
import okhttp3.OkHttpClient
import okhttp3.Request
import okio.ByteString
import okio.ByteString.Companion.encodeUtf8
import okio.buffer
import okio.sink
import org.gradle.api.DefaultTask
import org.gradle.api.file.RegularFile
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
@CacheableTask
/**
* Based on PublicSuffixListGenerator from OkHttp:
* https://github.com/square/okhttp/blob/3ad1912f783e108b3d0ad2c4a5b1b89b827e4db9/okhttp/src/jvmTest/java/okhttp3/internal/publicsuffix/PublicSuffixListGenerator.java
*/
abstract class PSLUpdateTask : DefaultTask() {
@get:Input abstract val pslData: Property<PublicSuffixListData>
@get:OutputFile abstract val outputFile: RegularFileProperty
@TaskAction
fun updatePSL() {
writeListToDisk(outputFile.get(), pslData.get())
val pslData = fetchPublicSuffixList()
writeListToDisk(outputFile.get(), pslData)
}
private fun fetchPublicSuffixList(): PublicSuffixListData {
val client = OkHttpClient.Builder().build()
val request =
Request.Builder().url("https://publicsuffix.org/list/public_suffix_list.dat").build()
client.newCall(request).execute().use { response ->
val source = requireNotNull(response.body).source()
val data = PublicSuffixListData()
while (!source.exhausted()) {
val line = source.readUtf8LineStrict()
if (line.trim { it <= ' ' }.isEmpty() || line.startsWith("//")) {
continue
}
if (line.contains(WILDCARD_CHAR)) {
assertWildcardRule(line)
}
var rule = line.encodeUtf8()
if (rule.startsWith(EXCEPTION_RULE_MARKER)) {
rule = rule.substring(1)
// We use '\n' for end of value.
data.totalExceptionRuleBytes += rule.size + 1
data.sortedExceptionRules.add(rule)
} else {
data.totalRuleBytes += rule.size + 1 // We use '\n' for end of value.
data.sortedRules.add(rule)
}
}
return data
}
}
@Suppress("TooGenericExceptionThrown", "ThrowsCount")
private fun assertWildcardRule(rule: String) {
if (rule.indexOf(WILDCARD_CHAR) != 0) {
throw RuntimeException("Wildcard is not not in leftmost position")
}
if (rule.indexOf(WILDCARD_CHAR, 1) != -1) {
throw RuntimeException("Rule contains multiple wildcards")
}
if (rule.length == 1) {
throw RuntimeException("Rule wildcards the first level")
}
}
private fun writeListToDisk(destination: RegularFile, data: PublicSuffixListData) {
@ -43,4 +101,16 @@ abstract class PSLUpdateTask : DefaultTask() {
}
}
}
data class PublicSuffixListData(
var totalRuleBytes: Int = 0,
var totalExceptionRuleBytes: Int = 0,
val sortedRules: TreeSet<ByteString> = TreeSet(),
val sortedExceptionRules: TreeSet<ByteString> = TreeSet()
)
private companion object {
private const val WILDCARD_CHAR = "*"
private val EXCEPTION_RULE_MARKER = "!".encodeUtf8()
}
}

View file

@ -1,98 +1,20 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Copyright © 2014-2022 The Android Password Store Authors. All Rights Reserved.
* SPDX-License-Identifier: GPL-3.0-only
*/
package app.passwordstore.gradle.psl
import java.io.Serializable
import java.util.TreeSet
import okhttp3.OkHttpClient
import okhttp3.Request
import okio.ByteString
import okio.ByteString.Companion.encodeUtf8
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.register
/**
* Gradle plugin to update the public suffix list used by the `lib-publicsuffixlist` component.
*
* Base on PublicSuffixListGenerator from OkHttp:
* https://github.com/square/okhttp/blob/master/okhttp/src/test/java/okhttp3/internal/publicsuffix/PublicSuffixListGenerator.java
*/
/** Gradle plugin to update the public suffix list used by the `autofill-parser` library. */
@Suppress("Unused")
class PublicSuffixListPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.tasks.register<PSLUpdateTask>("updatePSL") {
val list = fetchPublicSuffixList()
pslData.set(list)
outputFile.set(project.layout.projectDirectory.file("src/main/assets/publicsuffixes"))
}
}
private fun fetchPublicSuffixList(): PublicSuffixListData {
val client = OkHttpClient.Builder().build()
val request =
Request.Builder().url("https://publicsuffix.org/list/public_suffix_list.dat").build()
client.newCall(request).execute().use { response ->
val source = requireNotNull(response.body).source()
val data = PublicSuffixListData()
while (!source.exhausted()) {
val line = source.readUtf8LineStrict()
if (line.trim { it <= ' ' }.isEmpty() || line.startsWith("//")) {
continue
}
if (line.contains(WILDCARD_CHAR)) {
assertWildcardRule(line)
}
var rule = line.encodeUtf8()
if (rule.startsWith(EXCEPTION_RULE_MARKER)) {
rule = rule.substring(1)
// We use '\n' for end of value.
data.totalExceptionRuleBytes += rule.size + 1
data.sortedExceptionRules.add(rule)
} else {
data.totalRuleBytes += rule.size + 1 // We use '\n' for end of value.
data.sortedRules.add(rule)
}
}
return data
}
}
@Suppress("TooGenericExceptionThrown", "ThrowsCount")
private fun assertWildcardRule(rule: String) {
if (rule.indexOf(WILDCARD_CHAR) != 0) {
throw RuntimeException("Wildcard is not not in leftmost position")
}
if (rule.indexOf(WILDCARD_CHAR, 1) != -1) {
throw RuntimeException("Rule contains multiple wildcards")
}
if (rule.length == 1) {
throw RuntimeException("Rule wildcards the first level")
}
}
companion object {
private const val WILDCARD_CHAR = "*"
private val EXCEPTION_RULE_MARKER = "!".encodeUtf8()
}
}
data class PublicSuffixListData(
var totalRuleBytes: Int = 0,
var totalExceptionRuleBytes: Int = 0,
val sortedRules: TreeSet<ByteString> = TreeSet(),
val sortedExceptionRules: TreeSet<ByteString> = TreeSet()
) : Serializable