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

Refactor Build System with Kotlin DSL using pre-compiled scripts. #5

Merged
merged 9 commits into from Jun 11, 2020

Conversation

android10
Copy link

This PR aims to refactor our gradle build system in order to organize it by functionality in a more modular way using Kotlin DSL pre-compiled scripts.

Includes:

  • Basic Build Variants Setup.
  • Quality: which includes Lint Configuration.
  • Compilation Options.
  • Minor Refactor.

Everything has been extracted In order to keep the main build.gradle.kts file small and easy to understand.

@android10 android10 added the enhancement New feature or request label Jun 10, 2020
jcenter()
google()
private enum class DEPENDENCIES(val value: String) {
AndroidBuildTools("com.android.tools.build:gradle:4.0.0")
Copy link
Contributor

Choose a reason for hiding this comment

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

wouldn't it make more sense to use string values class instead of an enum? this way the calls would DEPENDENCIES.AndroidBuildTools, instead of having to add .value behind it.

Copy link
Author

Choose a reason for hiding this comment

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

@Gardosen Enums create scoping and group values. I do not see any reason to use strings constants...plus it forces the client to use predefined values that belong to an specific scope.

Copy link

Choose a reason for hiding this comment

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

I don't know if we can use @StringDef at this level (guess it was an android thing), but it might be a good alternative. This looks a bit verbose for me too. I think enum here does not impose any level of strictness, since there's nothing that prevents us from putting any other String inside implementation block. why did you prefer enums here over sth like below? (which is also consistent with how we declare dependencies in app module)

object Dependencies {
  const val ANDROID_BUILD_TOOLS = "com.android..."
}

implementation(Dependencies.ANDROID_BUILD_TOOLS)

Copy link
Author

Choose a reason for hiding this comment

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

We cannot use @StringDef or I would not like to add the dependency just for having this. The Object does the job and keeps consistency. I will modify this.

DEV("dev"), INTERNAL("internal"), PUBLIC("public")
}

private enum class FlavorDimensions(val value: String) {
Copy link
Contributor

Choose a reason for hiding this comment

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

FlavorDimensions for the version? do we have a better name for this?

Copy link
Author

Choose a reason for hiding this comment

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

@Gardosen do you have a suggestion? Please also suggest how you would do it instead. That is what we are expecting from code reviews :). Otherwise that would be a complain. :)

A version is a version here in this case, I do not see any other way of describing it. 🤔

Copy link

Choose a reason for hiding this comment

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

FlavorDimensions is a gradle thing, so I think the name is ok. However, the name "version" is a bit confusing for me. Why did we choose that name? How does versioning contribute to dimensions?

Copy link
Author

Choose a reason for hiding this comment

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

Dimension is use to group flavors. You can group flavors based on different contexts/dimensions. In this case I did not find a better way of grouping this. Suggestions?

If we were to have for example these flavors:

  • Premium
  • Pro
  • Semi-Pro

Then dimension would be payments, because they are based/belong to this area.

Copy link

Choose a reason for hiding this comment

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

I usually put "default" as the name, if I have a single dimension

Copy link
Author

Choose a reason for hiding this comment

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

default does not tell me much. And I'm also considering to extend this with other dimensions related to "customer" which are custom builds.

Copy link
Author

Choose a reason for hiding this comment

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

Flavor Dimensions allow us to define groups of flavors. Gradle creates every combination between these groups for us. No need to mix and match by hand. That is why I find default a bit senseless. In any case, I want to merge this so I will get back to it. It is already modified.

applicationIdSuffix = ".${ProductFlavors.INTERNAL.value}"
versionNameSuffix = "-${ProductFlavors.INTERNAL.value}"
}
create(ProductFlavors.PUBLIC.value) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think ProductFlavors.PRODmakes more sense as a name convention for this flavor

Copy link
Author

Choose a reason for hiding this comment

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

I considered that, but the reason why not is that for the time being we will have this for the public, but there will be other product flavors that are specific for customers.

From my perspective: Release means Production, then you have different product flavors that satisfy different contexts. Does that make sense? How would you organize this then for custom builds for customers?

Copy link
Contributor

@mejdoo mejdoo Jun 11, 2020

Choose a reason for hiding this comment

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

I don't think the term release means production in this context. In our case, we have some combination between flavors/build types like devRelease and internalRelease but they don't have any relation with the production version except enabling proguard.

Anyway, it makes sense to use term PUBLIC if we wanna add more flavors for our customers.

Copy link
Author

Choose a reason for hiding this comment

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

Good point about the definition of release. And related to Public it is exactly what you pointed out. Thanks for the feedback.

app/build.gradle.kts Show resolved Hide resolved
jcenter()
google()
private enum class DEPENDENCIES(val value: String) {
AndroidBuildTools("com.android.tools.build:gradle:4.0.0")
Copy link

Choose a reason for hiding this comment

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

I don't know if we can use @StringDef at this level (guess it was an android thing), but it might be a good alternative. This looks a bit verbose for me too. I think enum here does not impose any level of strictness, since there's nothing that prevents us from putting any other String inside implementation block. why did you prefer enums here over sth like below? (which is also consistent with how we declare dependencies in app module)

object Dependencies {
  const val ANDROID_BUILD_TOOLS = "com.android..."
}

implementation(Dependencies.ANDROID_BUILD_TOOLS)

DEV("dev"), INTERNAL("internal"), PUBLIC("public")
}

private enum class FlavorDimensions(val value: String) {
Copy link

Choose a reason for hiding this comment

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

FlavorDimensions is a gradle thing, so I think the name is ok. However, the name "version" is a bit confusing for me. Why did we choose that name? How does versioning contribute to dimensions?

buildSrc/src/main/kotlin/scripts/variants.gradle.kts Outdated Show resolved Hide resolved
Copy link
Author

@android10 android10 left a comment

Choose a reason for hiding this comment

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

@mejdoo @gizemb I addressed your comments plus:

  • I have changed the flavor dimension to default. Let's define this later when we need it.
  • I got rid of enums in favor of objects for code readability and consistency.
  • Minor refactor

@android10 android10 requested a review from gizemb June 11, 2020 13:41
@android10 android10 merged commit 90068eb into master Jun 11, 2020
@android10 android10 deleted the feature-product-flavors branch June 11, 2020 13:59
gizemb added a commit that referenced this pull request Jun 17, 2020
gizemb added a commit that referenced this pull request Sep 3, 2020
* Inject dispatchers for testing purposes (#58)
gizemb added a commit that referenced this pull request Sep 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
4 participants