简介
您好,我正在尝试删除应用程序settings.gradle
中的重复代码。以下是我的文件当前的样子:
pluginManagement {
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
(You我可以忽略特定于技术的事情以及为什么必须这样做-让我们假设 * 必须这样做 *。如果您对更多细节感兴趣,请参阅this PR to Flutter)
很容易看出,负责从local.properties
文件中加载flutter.sdk
属性的代码重复了两次,因此我着手删除这种重复。
尝试1(变量)
起初,我尝试了下面的代码,但Gradle很快提醒我“pluginManagement {}块必须出现在脚本中的任何其他语句之前”。
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
pluginManagement {
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
include ':app'
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
尝试2(函数)
在前面的尝试中,错误消息说在pluginManagement {}
块之前不允许有 * 语句 *。我考虑过将代码移到一个单独的函数中,因为,在我(适度)的理解中,函数不是Groovy中的语句:
String flutterSdkPath() {
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
pluginManagement {
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
include ':app'
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
不幸的是,它仍然不起作用,并且错误只会变得不那么有用:
FAILURE: Build failed with an exception.
* Where:
Settings file '/Users/bartek/fvm/versions/master/examples/hello_world/android/settings.gradle' line: 20
* What went wrong:
A problem occurred evaluating settings 'android'.
> Could not get unknown property 'flutterSdkPath' for object of type org.gradle.plugin.management.internal.DefaultPluginManagementSpec.
我很确定它必须做一些关于如何pluginManagement {}
块被Gradle以特殊的方式处理的事情(也就是说,在settings.gradle
中的其余代码被评估之前,它首先被评估)
尝试3(类中的静态方法)
我想也许所有在pluginManagement {}
块之前的代码都被剥离了(?),所以我尝试创建一个包含静态方法的类:
pluginManagement {
includeBuild("${Flutter.flutterSdkPath}/packages/flutter_tools/gradle")
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
include ':app'
apply from: "${Flutter.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle"
class Flutter {
String flutterSdkPath() {
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
}
这一次,错误消息甚至更没有帮助:
* Where:
Settings file '/Users/bartek/fvm/versions/master/examples/hello_world/android/settings.gradle' line: 11
* What went wrong:
A problem occurred evaluating settings 'android'.
> Flutter
* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
在使用--stracktrace
标志运行Gradle后,我注意到这行:
... (<very long stack trace>)
Caused by: java.lang.NoClassDefFoundError: Flutter
...
这和我在第二次尝试中遇到的问题是一样的。
我不知道如何将属性加载代码移到一个地方,并从pluginManagement {}
块的内部和外部调用它。
我认为Gradle设置插件可以在这里工作,但我宁愿不这样做,除非必要。
3条答案
按热度按时间gcuhipw91#
pluginManagement块中应只包含插件相关配置:声明插件版本、应用插件和配置插件仓库。它应该是第一个块的原因是它在项目中的其他gradle文件之前运行。该块的目的不是用于通用脚本或导入其他文件。
不需要过度工程化。您想要提取的功能只是从
properties
文件中获取变量。使用
gradle.properties
在
settings.gradle
文件所在的项目根目录下创建一个文件gradle.properties
,并添加:在
settings.gradle
中,您可以使用它:有关如何使用Kotlin的参考和更多信息,请阅读插件版本管理
使用命令行注入
有多种方法可以实现。在这里你可以阅读更多关于Gradle, System, Environment, and Project properties的内容。它们从高优先级到低优先级的层次结构以及它们如何覆盖这些值:
1.命令行属性
1.系统特性
1.环境变量
1.主目录中的
gradle.properties
1.项目根目录中的
gradle.properties
简而言之,您只需要通过命令行将变量传递给
gradle
命令举一个简短的例子:
blpfk2vs2#
不幸的是,它仍然不起作用,并且错误只会变得不那么有用:
它说你试图引用的属性没有找到,因为你把它变成了一个方法,所以不再有这样的属性了。
如果您尝试调用该方法,它会告诉您未找到该方法。
我很确定它必须做一些关于如何
pluginManagement {}
块被Gradle以特殊的方式处理的事情(也就是说,在settings.gradle
中的其余代码被评估之前,它首先被评估)确切地说,它是单独提取和评估的。
pluginManagement
块可以定义插件存储库或包含带有设置插件的构建,因此要编译脚本的其余部分,它需要首先单独评估。这也是你不能使用块外部的属性或方法的原因。它必须是自包含的。我想也许所有在
pluginManagement {}
块之前的代码都被剥离了(?),所以我尝试创建一个包含静态方法的类:就像我说的,所有的都被“剥离”了,否则你也可以简单地在块后面定义方法并调用它。
我认为Gradle设置插件可以在这里工作,但我宁愿不这样做,除非必要。
设置插件在
pluginManagement
块之后被评估,因为该块可以定义包含的构建,其中包含设置插件或存储库,可以在其中找到设置插件,所以设置插件太晚了,无法配置该块。PS我也很乐意接受一个解释,为什么我在尝试1)的早期得到了一个错误,而不是在尝试2)。
不知道你说的“早期”是什么意思,这两个错误都或多或少是立即出现的。(它在KotlinDSL中是允许的,但在块内使用也不起作用),因此在解析脚本以提取块时会出错,而在尝试2中,当实际评估块时,由于它使用不存在的属性,因此会出现错误。
你可以通过使用“额外”属性来实现你想要实现的目标。使用它们通常是一种代码气味,只是一种解决方法,用于不正确地做一些事情,但这可能是使用它可能合适的罕见情况之一。
虽然
pluginManagment
块是单独计算的,但它仍然可以修改模型,因此您可以添加一个闭包作为额外的属性,然后该属性也可用于剩余的脚本:eivgtgni3#
在gradle.properties项目的根目录下创建一个文件www.example.com