NewPipe icon indicating copy to clipboard operation
NewPipe copied to clipboard

Migrate project dependencies to using Version Catalogs

Open HatakeKakashri opened this issue 2 years ago • 1 comments

Checklist

  • [X] I made sure that there are no existing issues - open or closed - which I could contribute my information to.
  • [X] I have read the FAQ and my problem isn't listed.
  • [X] I'm aware that this is a request for NewPipe itself and that requests for adding a new service need to be made at NewPipeExtractor.
  • [X] I have taken the time to fill in all the required details. I understand that the feature request will be dismissed otherwise.
  • [X] This issue contains only one feature request.
  • [X] I have read and understood the contribution guidelines.

Feature description

Currently, the project manages dependencies by declaring them directly within the build.gradle file. This approach, while functional, can become cumbersome and difficult to maintain as the project grows and the number of dependencies increases.

This feature proposes migrating dependency management to Version Catalogs. Version catalogs are a centralized location within the Gradle build system to store and manage all project dependencies.

Why do you want this feature?

Version catalogs offer several advantages over declaring dependencies directly in build.gradle: https://developer.android.com/build/migrate-to-catalogs

Additional information

No response

HatakeKakashri avatar Mar 31 '24 18:03 HatakeKakashri

There doesn't seem to be a PR for this issue, so I want to try to implement this.

JL0000 avatar Nov 08 '24 11:11 JL0000

Sorry but I have to completely disagree on this topic:

can become cumbersome and difficult to maintain as the project grows and the number of dependencies increases

That's not a scalability problem nor difficult to maintain, otherwise we would have encountered difficulties for a long time.

It's also a lot better to remove dependencies if possible (for example if you use one file from a library copy that over instead of adding a 500KB lib).

Version catalogs offer several advantages over declaring dependencies directly in build.gradle

Please point these out because currently I don't see them for this project.

I had a look at Google's claimed "advantages"

makes managing dependencies and plugins easier when you have multiple modules Instead of hardcoding dependency names and versions in individual build files

Not affected - We don't have multiple modules

and updating each entry whenever you need to upgrade a dependency

We should get a automated dependency update tool like Renovate for this

central version catalog of dependencies that various modules can reference in a type-safe way with Android Studio assistance

Not sure what's meant with type-safe because currently we use a string and the new way is also a string... Also nobody needs Android Studio "assistance" to increment a version number.

I just had a look at the implementation of this and I personally find it a lot easier to read through

build.gradle

dependencies {
/** AndroidX **/
    implementation 'androidx.appcompat:appcompat:1.7.1'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.core:core-ktx:1.12.0'
    implementation 'androidx.documentfile:documentfile:1.0.1'
    implementation 'androidx.fragment:fragment-ktx:1.6.2'
}

as opposed to the new way:

build.gradle.kts

dependencies {
    /** AndroidX **/
    implementation(libs.androidx.appcompat)
    implementation(libs.androidx.cardview)
    implementation(libs.androidx.constraintlayout)
    implementation(libs.androidx.core)
    implementation(libs.androidx.documentfile)
}

libs.versions.toml

[versions]
acra = "5.11.3"
agp = "8.13.0"
appcompat = "1.7.1"
assertj = "3.24.2"
autoservice = "1.1.1"
bridge = "v2.0.2"
cardview = "1.0.0"
checkstyle = "10.12.1"
constraintlayout = "2.1.4"
...

[libraries]
acra-core = { module = "ch.acra:acra-core", version.ref = "acra" }
android-desugar = { module = "com.android.tools:desugar_jdk_libs_nio", version.ref = "desugar" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompat" }
androidx-cardview = { module = "androidx.cardview:cardview", version.ref = "cardview" }
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayout" }
androidx-core = { module = "androidx.core:core-ktx", version.ref = "core" }
androidx-documentfile = { module = "androidx.documentfile:documentfile", version.ref = "documentfile" }
...

litetex avatar Oct 15 '25 17:10 litetex

@litetex the main point imo is to have all versions in one file and not spread over various files and in different places. That's a big advantage that would prevent things like https://github.com/TeamNewPipe/NewPipeExtractor/pull/981#issuecomment-1326149128 . Even for single-subproject projects: now we have some versions specified inline, some others as variables in the base build.gradle, some others as variables in app/build.gradle. Also, from my experience in other projects it is indeed a bit better to use version catalogs wrt specifying stuff in gradle.

Stypox avatar Oct 16 '25 07:10 Stypox

the main point imo is to have all versions in one file and not spread over various files and in different places.

But the exact opposite is the case here. Instead of having 1 (maybe 2 when using a variable) place/line where dependencies are tracked, we would have at least 3 places in different places now.

Maybe we should do Maven then? Because at least they know how multi module projects work for over 15 years. Also Maven projects usually don't require waiting for 5 minutes to get imported in IJ/AS :P

Ok just kidding that ship sailed a long time on Android

But there is stuff like subprojects that might be used instead.

That's a big advantage that would prevent things like https://github.com/TeamNewPipe/NewPipeExtractor/pull/981#issuecomment-1326149128 .

  1. That's the extractor that's not the app. Different environment.
  2. The problem there was that the groupId was not renamed. The exact same thing can also happen when for example libs.androidx.constraintlayout is named incorrectly.

Even for single-subproject projects: now we have some versions specified inline, some others as variables in the base build.gradle, some others as variables in app/build.gradle

Currently there is 2 dependencies and 1 variable defined in the root build.gradle everything else is inside the app build.gradle


I still see no direct benefits in doing this. The current system works well and is IMHO a lot simpler and easier to understand and there is likely other stuff with higher priority and usefulness (for example preparing/updating to Gradle 9) so I really don't quite understand why this is pushed now.

If you guys still want to really do this "modernization": Well go on. However I would appreciate it if there was more consideration about the usefulness of the change before starting to implement it in the future.

litetex avatar Oct 16 '25 16:10 litetex

TLDR: I agree that this change is minor and gives only small benefits (in my opinion) / no advantage (in your opinion), but work is already finished so might as well merge it. The reason why I think version catalogs are useful is because they behave like a file holding all constant parameters in a program, instead of having parameters spread all over. Another benefit is related to version sharing among gradle projects.

With this said, I understand your position and I also don't like how Google keeps changing stuff and how Gradle keeps sucking even if they keep deprecating stuff every version. I am sorry if my statements come off as rough, or if I made you upset, and it is true that sometimes I push too much for unnecessarily adopting new stuff. Anyway, I don't really have a strong opinion on this and just wanted to explain why https://github.com/TeamNewPipe/NewPipe/pull/11684 was merged. I am fine even if we decide to revert it in the end, although that'd add even more work.

Btw, to give you more context, @theimpulson made his PR after asking on Matrix a few days ago.


If you guys still want to really do this "modernization": Well go on.

I don't want it 'cause "modernization", but because from my experience on https://github.com/Stypox/dicio-android it does make things a bit easier to manage. There I even used it to e.g. specify the JVM version (so it's the same across 3 projects and 1-2 places in the same project), and I can say it does help keep things a bit clearer. But this is just my experience and yours could obviously be different

But the exact opposite is the case here. Instead of having 1 (maybe 2 when using a variable) place/line where dependencies are tracked, we would have at least 3 places in different places now.

There might be 3 places, but 2 of them are checked at script compile time (i.e. "Sync project with Gradle files") by Android Studio: the reference in build.gradle won't compile if they don't exist in the version catalogs, and the two version/library definitions in the version catalog must match with each other. Also, Ctrl-clicking on stuff does the right thing because it's just a toml file (but good luck ctrl-clicking on Gradle variables to see where they are used, especially if your project isn't syncing for some reason).

The current system works well and is IMHO a lot simpler and easier to understand and there is likely other stuff with higher priority and usefulness (for example preparing/updating to Gradle 9) so I really don't quite understand why this is pushed now.

It's not being actively pushed, especially considring that the small amount of work needed for the migration was already done. A while ago somebody did it here, and it looked good so it was merged (not merged at random, but merged because it made sense in the eyes of snaik20 and also me). And now #12706 is just porting those changes to the dev branch. Maybe you are right, we could have skipped this migration, it's not like it was important, but now it's basically already done and just needs to be merged, no more efforts needed (and not too many efforts were needed to do the migration in the first place).

That's the extractor that's not the app. Different environment.

Yeah I know, it was just an example of the shortcomings of the current system.

The problem there was that the groupId was not renamed. The exact same thing can also happen when for example libs.androidx.constraintlayout is named incorrectly.

No, the problem was that I updated one of the groupIds in one of the gradle modules but forgot to do it in another, which wouldn't have happened with version catalogs. Since we might want to use multiple gradle modules in the app too in the future (e.g. NewPlayer might be made a submodule of the app, or maybe we will need to add a gradle plugin to do something), having version catalogs would help with sharing version definitions.

However I would appreciate it if there was more consideration about the usefulness of the change before starting to implement it in the future.

I think the reason why it was done without much thinking is because Google themselves recommends it so you expect the other thing that currently works to become deprecated after a while, and so you need to switch. This isn't the case here (yet), but again it's not like it took much time to do (probably took less than it took me to write this comment). Another reason was that I myself probably suggested this on the matrix channel for the refactor branch after finding it a good solution on other projects.

Stypox avatar Oct 16 '25 20:10 Stypox