Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the ability to use eternal plugins with forma #75

Merged
merged 2 commits into from
Jan 23, 2021

Conversation

ikarenkov
Copy link
Collaborator

Added the ability to use eternal plugins with forma.
Also added platform dependency type.

@ikarenkov
Copy link
Collaborator Author

#35

package tools.forma.android.plugin

import tools.forma.deps.FormaDependency
import emptyDependency
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused import

import org.gradle.kotlin.dsl.the
import tools.forma.deps.applyDependencies
import tools.forma.validation.EmptyValidator
import Forma
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused import

import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension
import tools.forma.android.plugin.PluginWrapper

object pluginWrappers {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about Plugins instead of pluginWrappers?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gradle already has plugins and will get naming collision
Снимок экрана 2021-01-14 в 23 43 41

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can name just object Plugins, cause suffix Wrappers doesn't describe behavior of that class.
Also, I has checked that, we don't get collision with Upper case

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we used lower case before, is it good idea to allow both naming styles? Maybe for Plugins it applicable but we need think about code style

PluginWrapper(pluginId, pluginExtension, dependencies, pluginConfiguration)
)

// TODO: maybe should crate withPlugins(vararg pluginWrapper: PluginWrapper<*>)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great Idea

import tools.forma.android.plugin.PluginWrapper
import kotlin.reflect.KClass

class FormaBuilder(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about TargetBuilder here?

import tools.forma.android.feature.kotlinAndroidFeatureDefinition
import tools.forma.android.target.LibraryTargetTemplate
import org.gradle.api.Project
import tools.forma.android.feature.*
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please avoid wildcard imports

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is just default code style settings from forma project, it brakes sometimes even if I set my own setting before. We should share code style for project using .idea

Copy link
Collaborator Author

@ikarenkov ikarenkov Jan 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course I'll fix it)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can commit project settings in the repo as well

private val project: Project
) {

fun <TPluginExtension : Any> withPlugin(
Copy link
Collaborator

@stepango stepango Jan 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the use-case for this function?
IMHO having full plugin configuration in target config is not desirable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I Agree, I'll remove it

).withPlugin(pluginWrappers.navigationSafeArgs)
Copy link
Collaborator

@stepango stepango Jan 14, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we establish a good practice by creating

androidLibraryWithNavigation(...) = androidLibrary(...).withPlugin(...)

wrapper function, so we'll make targets description in the same style?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO, creating new method for each combination of plugins is useless, it doesn't sole our tasks. We can use plugins for several targets? f.e. Kotlin.serialization can be used in library, utils, iml, androidLibrary, androidUtils and in this case we must create 5 copipaste of methods, if I understand you correctly. Also we can have combinations of plugins. In my opinion patterns like builder or decorator help us to combine several behaviors and keep it scalable without necessity to duplicate code

Copy link
Collaborator

@michaem michaem Jan 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, in modern projects, we'll get different combinations of custom plugins. In that case, many methods with name templates as `[target name]With[combination plugins] will be overhead for project self.

) {

init {
if (pluginConfiguration != null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of doing this check, we can create a data class that will contain plugin extension and plugin configuration so we can reuse it later if, for example, different targets would need a slightly different configuration. This way we make sure Plugin Extension and Plugin configuration will always be specified together + compile-time check instead of runtime.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep, nice idea

@@ -31,7 +31,8 @@ class FileSpec(
class NameSpec(
val name: String,
config: ConfigurationType,
val transitive: Boolean = false
val transitive: Boolean = false,
val platform: Boolean = false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we do a PlatformSpec instead?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, because it still nameSpec with specific behavior of resolving dependencies, platform is similar with transitive from this point of view. But it was just simple way to add platform, maybe we can add one more Spec and use it

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single type for it will be more clearly, than added overriding versions of transitive methods for passing one changing value of argument.

@@ -5,6 +5,7 @@ buildscript {
}
dependencies {
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.3.2")
classpath("com.google.firebase:firebase-crashlytics-gradle:2.4.1")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still have native gradle script part here. I think need to another issue to research, how could migrate on Forma API only

@@ -36,6 +36,18 @@ fun DependencyHandler.addDependencyTo(
configuration
)

// TODO: only using for platform, maybe make addPlatformDependencyTo?
fun DependencyHandler.addDependencyTo(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats real different of this method from same signature upper? Is't only in one parameter Dependency instead on String?


fun transitivePlatform(vararg names: String): NamedDependency = transitiveDeps(names = *names, transitive = true, platform = true)

fun transitiveDeps(vararg names: String, transitive: Boolean = true, platform: Boolean = false): NamedDependency =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that code is more java style way, by adding several overload methods for passing value for one argument, cause we don't have named parameters as it was in Java. This solution brings complicity for our API and will take some time to support documentation and improvements.
I think we need to add another type Platform, but I don't understand, whats impact we will be get from that.

@ikarenkov ikarenkov merged commit b4b26fd into master Jan 23, 2021
@ikarenkov ikarenkov deleted the custom_plugins_support branch January 23, 2021 10:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants