Swift Package Manager plugin for Kotlin#1
Conversation
| * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. | ||
| */ | ||
|
|
||
| @file:Suppress("PackageDirectoryMismatch") // Old package for compatibility |
There was a problem hiding this comment.
Remove this annotation and move sources to org.jetbrains.kotlin.gradle.plugin.spm package
| // TODO: List<String> or String | ||
| @Input | ||
| @Optional | ||
| var defaultLocalization: List<String>? = null |
There was a problem hiding this comment.
Add KDoc with references to corresponding SPM configuration parameters (for another properties too)
| // } | ||
| } | ||
|
|
||
| class SystemLibrary( |
There was a problem hiding this comment.
Make SystemLibrary implementing org.gradle.api.Named
| @Optional | ||
| var resources: List<Resource>? = null | ||
|
|
||
| fun dependencies(configure: TargetDependencies.() -> Unit) { |
There was a problem hiding this comment.
Functions with Kotlin lambdas parameters are visible only from kts scripts. To provide corresponding functionality to groovy scripts implement the overloading (see CocoapodsExtension.CocoapodsDependency#git(java.lang.String, groovy.lang.Closure<?>))
| dependenciesProduct = dependency.products | ||
| } | ||
|
|
||
| fun exclude(configure: ExcludePath.() -> Unit) { |
There was a problem hiding this comment.
The same as for dependencies
| excludePaths = exclude.paths | ||
| } | ||
|
|
||
| fun sources(configure: SourceFile.() -> Unit) { |
There was a problem hiding this comment.
The same as for dependencies
| sourceFiles = sources.files | ||
| } | ||
|
|
||
| fun resources(configure: Resource.() -> Unit) { |
There was a problem hiding this comment.
The same as for dependencies
| // fun swiftSettings() {} | ||
| // fun linkerSettings() {} | ||
|
|
||
| class Resource() { |
There was a problem hiding this comment.
It worth moving nested declarations into separate files because there are no private visibility restrictions.
| @Optional | ||
| var localization: Localization? = null | ||
|
|
||
| constructor(path: String) : this() { |
There was a problem hiding this comment.
Try to replace multiple constructors with default values or introduce builder for creating instances.
| platforms = supportedPlatform.platforms | ||
| } | ||
|
|
||
| fun products(configure: Products.() -> Unit) { |
There was a problem hiding this comment.
overloading with overloading groovy.lang.Closure (see CocoapodsExtension.CocoapodsDependency#git(java.lang.String, groovy.lang.Closure))
| // TODO: cLanguageStandard: CLanguageStandard? = nil, | ||
| // TODO: cxxLanguageStandard: CXXLanguageStandard? = nil | ||
|
|
||
| fun platforms(configure: SupportedPlatform.() -> Unit) { |
| productsExecutables = product.executables | ||
| } | ||
|
|
||
| fun dependencies(configure: Dependencies.() -> Unit) { |
| dependencies = dependency.dependencies | ||
| } | ||
|
|
||
| fun targets(configure: Targets.() -> Unit) { |
| } | ||
|
|
||
| // TODO: add fun with another params (supportedPlatform) | ||
| class SupportedPlatform() { |
There was a problem hiding this comment.
Please, try to rethink this part. Supported is just the attribute of platform, but here SupportedPlatform is responsible for holding info like container and could be changed by its function calls.
There was a problem hiding this comment.
Take a look at org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType and its usages (for example, org/jetbrains/kotlin/gradle/plugin/mpp/KotlinMultiplatformPlugin.kt:302)
| platforms.add(platform) | ||
| } | ||
|
|
||
| enum class PlatformType { |
There was a problem hiding this comment.
MPP plugin contains proper API for platforms, re-use it (see org.jetbrains.kotlin.gradle.plugin.KotlinTarget#getPlatformType)
| } | ||
|
|
||
| class Products { | ||
| var libraries = mutableListOf<ProductType.Library>() |
| } | ||
|
|
||
| sealed class ProductType { | ||
| class Executable(@Input val name: String) { |
There was a problem hiding this comment.
Nesting is not required here but significantly complicates code-readability. Make sources more flat, please.
| } | ||
| } | ||
|
|
||
| class Library(@Input val name: String) { |
| class Dependencies { | ||
| var dependencies = mutableListOf<Package>() | ||
|
|
||
| fun `package`(url: String, version: String) { |
There was a problem hiding this comment.
Manual overloading and `` quotes are not required. Use default parameters with @JvmOverloads annotation
| } | ||
|
|
||
| /** TODO | ||
| * Все target оказались одинаковыми по сигнатурам, |
There was a problem hiding this comment.
А обрабатывать в плагине их тоже нужно одинаково? Думаю, что нет, поэтому важно дизайнить API с заделом на будущее.
| } | ||
|
|
||
| class Targets { | ||
| // TODO: так и оставить как 3 списка? |
There was a problem hiding this comment.
Полиморфизм + 1 список. И классы, хранящие коллекцию каких-то сущностей, для удобства называют с суффиксом Container.
| var libraries = mutableListOf<SystemLibrary>() | ||
| var binaries = mutableListOf<BinaryTarget>() | ||
|
|
||
| fun target(name: String, configure: Target.() -> Unit) { |
There was a problem hiding this comment.
Don't forget about Groovy overloadings
zoldater
left a comment
There was a problem hiding this comment.
TODO для следующей итерации код-ревью:
- Распределить сущности по файлам и пакетам в разумных масштабах
- Посмотреть на некоторые сущности - таргеты, платформы и т.д., которые есть в MPP-плагине и могут быть переиспользованы. За конкретными примерами пиши в личку, подскажу.
- Не самые удачные абстракции с классами-контейнерами, которые аккумулируют в себе дофига логики. Скорее всего большая часть из них может быть заменена на проперть с
project.container(<YourClassHere>::class.java)и обработку - Если есть набор сущностей, похожих по сигнатурам, но отличающихся по какому-либо признаку, даже если сейчас этот признак не имеет значения, используем полиморфизм.
- Избегаем копи-пасты, излишней мутабельности и велосипедостроения.
Rework container for entities.
| /** | ||
| * TODO: comment | ||
| * | ||
| * @see [Product](https://docs.swift.org/package-manager/PackageDescription/PackageDescription.html#product) |
There was a problem hiding this comment.
Наверное стоит оставить только один источник (первый с оф. документации, второй с github), Но проблема в том, что в них разная информации (не актуальная)
There was a problem hiding this comment.
Пока это для нашего с тобой пользования, можешь не запариваться
| val platforms = mutableListOf<SupportedPlatform>() | ||
|
|
||
| fun macOS(version: String) { | ||
| val platform = SupportedPlatform(Family.OSX, version) |
There was a problem hiding this comment.
Такое использование Family подойдет? Или имелось в виду, что стоит полностью переработать SupportedPlatforms ?
There was a problem hiding this comment.
Такая реализация вполне хороша
|
|
||
| package org.jetbrains.kotlin.gradle.plugin.spm.utils | ||
|
|
||
| abstract class StringUnaryPlusContainer { |
There was a problem hiding this comment.
Хорошая идея? Или не стоит так выносить логику?
There was a problem hiding this comment.
Идея хорошая, но лучше закинуть в companion targetBlock'а и снизить видимость
| class Executable(name: String) : AbstractProduct(name) | ||
|
|
||
| class Library(name: String, private val type: LibraryType) : AbstractProduct(name) { | ||
| enum class LibraryType { |
There was a problem hiding this comment.
Выбрал вариант с enum, как по мне, удобнее чем просто String. Но заставляет импортировать enum в gradle. Насколько это ок?
https://github.com/PaGr0m/spm-sample/blob/c50f8ea6d2cfc3e4e981c24788ce0d9208b97cbd/build.gradle.kts#L1
There was a problem hiding this comment.
Это лучше, чем сырая строка, но для up-to-date проверок нужна будет динамическая строковая проперть
| @Input | ||
| lateinit var name: String | ||
|
|
||
| private val platformsContainer = project.container(SupportedPlatformBlock.SupportedPlatform::class.java) |
There was a problem hiding this comment.
Может тоже стоит создать интерфейс, как и с другими контейнерами? Хоть тут он особо не нужен, так как реализация одна. Но читаемость улучшит
|
Пример DSL синтаксиса: build.gradle.kts example |
| } | ||
|
|
||
| data class SupportedPlatform( | ||
| @Input val type: Family, |
There was a problem hiding this comment.
Family - элемент перечисления, как Input его использовать нельзя. Пометь как Internal и добавь стринговую проперть c type.name как Input
| } | ||
|
|
||
| abstract class AbstractTarget(private val name: String) : Target { | ||
| override fun getName(): String = name |
| private val name: String, | ||
| val `package`: String, | ||
| val condition: String? = null | ||
| ) : TargetDependency { |
There was a problem hiding this comment.
TargetDependency тоже сюда можно перенести
No description provided.