mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-30 23:03:00 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			376 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Groovy
		
	
	
	
	
	
			
		
		
	
	
			376 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Groovy
		
	
	
	
	
	
| import com.android.tools.profgen.ArtProfileKt
 | |
| import com.android.tools.profgen.ArtProfileSerializer
 | |
| import com.android.tools.profgen.DexFile
 | |
| import com.mikepenz.aboutlibraries.plugin.DuplicateMode
 | |
| 
 | |
| plugins {
 | |
|     alias libs.plugins.android.application
 | |
|     alias libs.plugins.kotlin.android
 | |
|     alias libs.plugins.kotlin.compose
 | |
|     alias libs.plugins.kotlin.kapt
 | |
|     alias libs.plugins.kotlin.parcelize
 | |
|     alias libs.plugins.checkstyle
 | |
|     alias libs.plugins.sonarqube
 | |
|     alias libs.plugins.hilt
 | |
|     alias libs.plugins.aboutlibraries
 | |
| }
 | |
| 
 | |
| android {
 | |
|     compileSdk 34
 | |
|     namespace 'org.schabi.newpipe'
 | |
| 
 | |
|     defaultConfig {
 | |
|         applicationId "org.schabi.newpipe"
 | |
|         resValue "string", "app_name", "NewPipe"
 | |
|         minSdk 21
 | |
|         targetSdk 33
 | |
|         if (System.properties.containsKey('versionCodeOverride')) {
 | |
|             versionCode System.getProperty('versionCodeOverride') as Integer
 | |
|         } else {
 | |
|             versionCode 1002
 | |
|         }
 | |
|         versionName "0.27.5"
 | |
|         if (System.properties.containsKey('versionNameSuffix')) {
 | |
|             versionNameSuffix System.getProperty('versionNameSuffix')
 | |
|         }
 | |
| 
 | |
|         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
 | |
| 
 | |
|         javaCompileOptions {
 | |
|             annotationProcessorOptions {
 | |
|                 arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     buildTypes {
 | |
|         debug {
 | |
|             debuggable true
 | |
| 
 | |
|             // suffix the app id and the app name with git branch name
 | |
|             def workingBranch = getGitWorkingBranch()
 | |
|             def normalizedWorkingBranch = workingBranch.replaceFirst("^[^A-Za-z]+", "").replaceAll("[^0-9A-Za-z]+", "")
 | |
|             if (normalizedWorkingBranch.isEmpty() || workingBranch == "master" || workingBranch == "dev") {
 | |
|                 // default values when branch name could not be determined or is master or dev
 | |
|                 applicationIdSuffix ".debug"
 | |
|                 resValue "string", "app_name", "NewPipe Debug"
 | |
|             } else {
 | |
|                 applicationIdSuffix ".debug." + normalizedWorkingBranch
 | |
|                 resValue "string", "app_name", "NewPipe " + workingBranch
 | |
|                 archivesBaseName = 'NewPipe_' + normalizedWorkingBranch
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         release {
 | |
|             if (System.properties.containsKey('packageSuffix')) {
 | |
|                 applicationIdSuffix System.getProperty('packageSuffix')
 | |
|                 resValue "string", "app_name", "NewPipe " + System.getProperty('packageSuffix')
 | |
|                 archivesBaseName = 'NewPipe_' + System.getProperty('packageSuffix')
 | |
|             }
 | |
|             minifyEnabled true
 | |
|             shrinkResources false // disabled to fix F-Droid's reproducible build
 | |
|             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 | |
|             archivesBaseName = 'app'
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     lint {
 | |
|         checkReleaseBuilds false
 | |
|         // Or, if you prefer, you can continue to check for errors in release builds,
 | |
|         // but continue the build even when errors are found:
 | |
|         abortOnError false
 | |
|         // suppress false warning ("Resource IDs will be non-final in Android Gradle Plugin version
 | |
|         // 5.0, avoid using them in switch case statements"), which affects only library projects
 | |
|         disable 'NonConstantResourceId'
 | |
|     }
 | |
| 
 | |
|     compileOptions {
 | |
|         // Flag to enable support for the new language APIs
 | |
|         coreLibraryDesugaringEnabled true
 | |
| 
 | |
|         sourceCompatibility JavaVersion.VERSION_17
 | |
|         targetCompatibility JavaVersion.VERSION_17
 | |
|         encoding 'utf-8'
 | |
|     }
 | |
| 
 | |
|     kotlinOptions {
 | |
|         jvmTarget = JavaVersion.VERSION_17
 | |
|     }
 | |
| 
 | |
|     sourceSets {
 | |
|         androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
 | |
|     }
 | |
| 
 | |
|     buildFeatures {
 | |
|         viewBinding true
 | |
|         compose true
 | |
|         buildConfig true
 | |
|     }
 | |
| 
 | |
|     packagingOptions {
 | |
|         resources {
 | |
|             // remove two files which belong to jsoup
 | |
|             // no idea how they ended up in the META-INF dir...
 | |
|             excludes += ['META-INF/README.md', 'META-INF/CHANGES',
 | |
|                          // 'COPYRIGHT' belongs to RxJava...
 | |
|                          'META-INF/COPYRIGHT']
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| configurations {
 | |
|     checkstyle
 | |
|     ktlint
 | |
| }
 | |
| 
 | |
| checkstyle {
 | |
|     getConfigDirectory().set(rootProject.file("checkstyle"))
 | |
|     ignoreFailures false
 | |
|     showViolations true
 | |
|     toolVersion = libs.versions.checkstyle.get()
 | |
| }
 | |
| 
 | |
| tasks.register('runCheckstyle', Checkstyle) {
 | |
|     source 'src'
 | |
|     include '**/*.java'
 | |
|     exclude '**/gen/**'
 | |
|     exclude '**/R.java'
 | |
|     exclude '**/BuildConfig.java'
 | |
|     exclude 'main/java/us/shandian/giga/**'
 | |
| 
 | |
|     classpath = configurations.checkstyle
 | |
| 
 | |
|     showViolations true
 | |
| 
 | |
|     reports {
 | |
|         xml.getRequired().set(true)
 | |
|         html.getRequired().set(true)
 | |
|     }
 | |
| }
 | |
| 
 | |
| def outputDir = "${project.buildDir}/reports/ktlint/"
 | |
| def inputFiles = project.fileTree(dir: "src", include: "**/*.kt")
 | |
| 
 | |
| tasks.register('runKtlint', JavaExec) {
 | |
|     inputs.files(inputFiles)
 | |
|     outputs.dir(outputDir)
 | |
|     getMainClass().set("com.pinterest.ktlint.Main")
 | |
|     classpath = configurations.ktlint
 | |
|     args "src/**/*.kt"
 | |
|     jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED")
 | |
| }
 | |
| 
 | |
| tasks.register('formatKtlint', JavaExec) {
 | |
|     inputs.files(inputFiles)
 | |
|     outputs.dir(outputDir)
 | |
|     getMainClass().set("com.pinterest.ktlint.Main")
 | |
|     classpath = configurations.ktlint
 | |
|     args "-F", "src/**/*.kt"
 | |
|     jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED")
 | |
| }
 | |
| 
 | |
| apply from: 'check-dependencies.gradle'
 | |
| 
 | |
| afterEvaluate {
 | |
|     if (!System.properties.containsKey('skipFormatKtlint')) {
 | |
|         preDebugBuild.dependsOn formatKtlint
 | |
|     }
 | |
|     preDebugBuild.dependsOn runCheckstyle, runKtlint, checkDependenciesOrder
 | |
| }
 | |
| 
 | |
| sonar {
 | |
|     properties {
 | |
|         property "sonar.projectKey", "TeamNewPipe_NewPipe"
 | |
|         property "sonar.organization", "teamnewpipe"
 | |
|         property "sonar.host.url", "https://sonarcloud.io"
 | |
|     }
 | |
| }
 | |
| 
 | |
| kapt {
 | |
|     correctErrorTypes true
 | |
| }
 | |
| 
 | |
| aboutLibraries {
 | |
|     // note: offline mode prevents the plugin from fetching licenses at build time, which would be
 | |
|     // harmful for reproducible builds
 | |
|     offlineMode = true
 | |
|     duplicationMode = DuplicateMode.MERGE
 | |
| }
 | |
| 
 | |
| dependencies {
 | |
| /** Desugaring **/
 | |
|     coreLibraryDesugaring libs.desugar.jdk.libs.nio
 | |
| 
 | |
| /** NewPipe libraries **/
 | |
|     implementation libs.teamnewpipe.nanojson
 | |
|     implementation libs.teamnewpipe.newpipe.extractor
 | |
|     implementation libs.teamnewpipe.nononsense.filepicker
 | |
| 
 | |
| /** Checkstyle **/
 | |
|     checkstyle libs.tools.checkstyle
 | |
|     ktlint libs.tools.ktlint
 | |
| 
 | |
| /** Kotlin **/
 | |
|     implementation libs.kotlin.stdlib
 | |
| 
 | |
| /** AndroidX **/
 | |
|     implementation libs.androidx.appcompat
 | |
|     implementation libs.androidx.cardview
 | |
|     implementation libs.androidx.constraintlayout
 | |
|     implementation libs.androidx.core.ktx
 | |
|     implementation libs.androidx.documentfile
 | |
|     implementation libs.androidx.fragment.compose
 | |
|     implementation libs.androidx.lifecycle.livedata
 | |
|     implementation libs.androidx.lifecycle.viewmodel
 | |
|     implementation libs.androidx.localbroadcastmanager
 | |
|     implementation libs.androidx.media
 | |
|     implementation libs.androidx.preference
 | |
|     implementation libs.androidx.recyclerview
 | |
|     implementation libs.androidx.room.runtime
 | |
|     implementation libs.androidx.room.rxjava3
 | |
|     kapt libs.androidx.room.compiler
 | |
|     implementation libs.androidx.swiperefreshlayout
 | |
|     implementation libs.androidx.work.runtime
 | |
|     implementation libs.androidx.work.rxjava3
 | |
|     implementation libs.androidx.material
 | |
| 
 | |
| /** Third-party libraries **/
 | |
|     // Instance state boilerplate elimination
 | |
|     implementation libs.livefront.bridge
 | |
|     implementation libs.android.state
 | |
|     kapt libs.android.state.processor
 | |
| 
 | |
|     // HTML parser
 | |
|     implementation libs.jsoup
 | |
| 
 | |
|     // HTTP client
 | |
|     implementation libs.okhttp
 | |
| 
 | |
|     // Media player
 | |
|     implementation libs.exoplayer.core
 | |
|     implementation libs.exoplayer.dash
 | |
|     implementation libs.exoplayer.database
 | |
|     implementation libs.exoplayer.datasource
 | |
|     implementation libs.exoplayer.hls
 | |
|     implementation libs.exoplayer.smoothstreaming
 | |
|     implementation libs.exoplayer.ui
 | |
|     implementation libs.extension.mediasession
 | |
| 
 | |
|     // Metadata generator for service descriptors
 | |
|     compileOnly libs.auto.service
 | |
|     kapt libs.auto.service.kapt
 | |
| 
 | |
|     // Manager for complex RecyclerView layouts
 | |
|     implementation libs.lisawray.groupie
 | |
|     implementation libs.lisawray.groupie.viewbinding
 | |
| 
 | |
|     // Image loading
 | |
|     implementation libs.coil.compose
 | |
|     implementation libs.coil.network.okhttp
 | |
| 
 | |
|     // Markdown library for Android
 | |
|     implementation libs.markwon.core
 | |
|     implementation libs.markwon.linkify
 | |
| 
 | |
|     // Crash reporting
 | |
|     implementation libs.acra.core
 | |
| 
 | |
|     // Properly restarting
 | |
|     implementation libs.process.phoenix
 | |
| 
 | |
|     // Reactive extensions for Java VM
 | |
|     implementation libs.rxjava3.rxjava
 | |
|     implementation libs.rxjava3.rxandroid
 | |
|     // RxJava binding APIs for Android UI widgets
 | |
|     implementation libs.rxbinding4.rxbinding
 | |
| 
 | |
|     // Date and time formatting
 | |
|     implementation libs.prettytime
 | |
| 
 | |
|     // Jetpack Compose
 | |
|     implementation(platform(libs.androidx.compose.bom))
 | |
|     implementation libs.androidx.compose.material3
 | |
|     implementation libs.androidx.compose.adaptive
 | |
|     implementation libs.androidx.activity.compose
 | |
|     implementation libs.androidx.compose.ui.tooling.preview
 | |
|     implementation libs.androidx.lifecycle.viewmodel.compose
 | |
|     implementation libs.androidx.compose.ui.text // Needed for parsing HTML to AnnotatedString
 | |
|     implementation libs.androidx.compose.material.icons.extended
 | |
| 
 | |
|     // Jetpack Compose related dependencies
 | |
|     implementation libs.androidx.paging.compose
 | |
|     implementation libs.androidx.navigation.compose
 | |
| 
 | |
|     // Coroutines interop
 | |
|     implementation libs.kotlinx.coroutines.rx3
 | |
| 
 | |
|     // Library loading for About screen
 | |
|     implementation libs.aboutlibraries.compose.m3
 | |
| 
 | |
|     // Hilt
 | |
|     implementation libs.hilt.android
 | |
|     kapt(libs.hilt.compiler)
 | |
| 
 | |
|     // Scroll
 | |
|     implementation libs.lazycolumnscrollbar
 | |
| 
 | |
| /** Debugging **/
 | |
|     // Memory leak detection
 | |
|     debugImplementation libs.leakcanary.object.watcher
 | |
|     debugImplementation libs.leakcanary.plumber.android
 | |
|     debugImplementation libs.leakcanary.android.core
 | |
|     // Debug bridge for Android
 | |
|     debugImplementation libs.stetho
 | |
|     debugImplementation libs.stetho.okhttp3
 | |
| 
 | |
|     // Jetpack Compose
 | |
|     debugImplementation libs.androidx.compose.ui.tooling
 | |
| 
 | |
| /** Testing **/
 | |
|     testImplementation libs.junit
 | |
|     testImplementation libs.mockito.core
 | |
| 
 | |
|     androidTestImplementation libs.androidx.junit
 | |
|     androidTestImplementation libs.androidx.runner
 | |
|     androidTestImplementation libs.androidx.room.testing
 | |
|     androidTestImplementation libs.assertj.core
 | |
| }
 | |
| 
 | |
| static String getGitWorkingBranch() {
 | |
|     try {
 | |
|         def gitProcess = "git rev-parse --abbrev-ref HEAD".execute()
 | |
|         gitProcess.waitFor()
 | |
|         if (gitProcess.exitValue() == 0) {
 | |
|             return gitProcess.text.trim()
 | |
|         } else {
 | |
|             // not a git repository
 | |
|             return ""
 | |
|         }
 | |
|     } catch (IOException ignored) {
 | |
|         // git was not found
 | |
|         return ""
 | |
|     }
 | |
| }
 | |
| 
 | |
| // fix reproducible builds
 | |
| project.afterEvaluate {
 | |
|     tasks.compileReleaseArtProfile.doLast {
 | |
|         outputs.files.each { file ->
 | |
|             if (file.toString().endsWith(".profm")) {
 | |
|                 println("Sorting ${file} ...")
 | |
|                 def version = ArtProfileSerializer.valueOf("METADATA_0_0_2")
 | |
|                 def profile = ArtProfileKt.ArtProfile(file)
 | |
|                 def keys = new ArrayList(profile.profileData.keySet())
 | |
|                 def sortedData = new LinkedHashMap()
 | |
|                 Collections.sort keys, new DexFile.Companion()
 | |
|                 keys.each { key -> sortedData[key] = profile.profileData[key] }
 | |
|                 new FileOutputStream(file).with {
 | |
|                     write(version.magicBytes$profgen)
 | |
|                     write(version.versionBytes$profgen)
 | |
|                     version.write$profgen(it, sortedData, "")
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | 
