自动将scala import语句转换为库依赖
Automatically convert scala import sentences into library dependencies
我是 Scala 的新手:)
如果我理解正确,您必须首先在 build.sbt
文件的 Library Dependencies 中包含所需的库,然后才能 import 将所需的库放入 scala 脚本中。
但是,我必须反过来做。我必须编写一个 Python 脚本来自动将 Scala 的导入语句转换为库依赖语句,以便将它们插入到 build.sbt
文件中。
例如
发件人:
import org.apache.spark.sql.SparkSession
import json._
至:
libraryDependencies += "org.apache.spark" %% "spark-sql" % sparkVersion % "provided"
libraryDependencies += "com.mediamath" %%% "scala-json" % "1.0"
我知道库依赖的语法如下:
libraryDependencies += groupID % artifactID % revision % configuration
而且我们应该在 maven central repository 中查找 groupID
、artifactID
和 revision
。
但是,此手动查找不允许我自动编程转换。我错过了什么吗?我可以用来完成此任务的其他语法?还有其他方法吗?
所以在某些语言中,导入必须以特定方式完成。这样看起来像 "import all the stuff, then start doing things"
在 Scala 中,可以在源代码中的任何位置导入项目。这会使事情复杂化。例如,在 Spark 代码中,您间接向 Spark 应用程序主机询问它提供的符号,这些符号存储在 运行 时间传回给您的变量中,然后您导入这些符号。
import org.apache.spark.sql.SparkSession
val spark = SparkSession
.builder()
.appName("Spark SQL basic example")
.config("spark.some.config.option", "some-value")
.getOrCreate()
// For implicit conversions like converting RDDs to DataFrames
import spark.implicits._
(注意示例中的最后一行导入了创建的 spark 变量的 implicits
字段中保存的任何内容。
最后,Maven 神器的版本不止一个。不能安全地引用特定 Maven 工件的任何版本,因为并非所有项目都试图提供所有版本号之间的向后兼容性(即使他们尝试这样做,兼容性错误仍然存在)。
https://mvnrepository.com/artifact/org.apache.spark/spark-core列出了大约30个不同版本的spark-core,其他spark库使用的核心例程。如果您选择与现有 spark 服务不同的版本,您的应用程序将无法正常运行,因为 spark 通常不兼容主要版本号,而是兼容主要和次要版本号(2.3 编译代码将无法在 2.4 环境中工作)
此外,Scala 代码在其编译阶段使用大量优化例程。这些优化例程意味着通常不能在 Scala 2.12 运行 时间环境中使用 Scala 2.11 class。所有 classes 必须完全匹配其 运行 时间环境。要发现 运行time 环境,不检查导入语句,而是检查发生编译的机器中 Scala 运行time 的设置,并确保它们与目标相同输出将 运行 的环境。这就是为什么对于许多库,您会看到多次构建相同的版本号,例如
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>2.4.5</version>
</dependency>
对比
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.4.5</version>
</dependency>
(上面的示例是捏造的,但说明了为 2.11 和 2.12 编译的库的相同版本)
最后,导入不是对 Maven 工件名称的引用。相反,它们是 JAR 文件(一种 Maven 工件)中的元素。因此,您将遇到一个额外的问题,即发现哪个 JAR 文件包含导入的项目,而不必事先知道您正在使用哪个 JAR 文件。
简而言之,您正试图通过例程来逆转在此环境中编写程序的自然过程,因为您正试图修复一个没有记录他们打算使用的内容的程序员。但是,您的例程必须
- 获取进口商品,其中一些可能是在 运行 时间建造的,并列一个清单。
- 获取该项目列表,并以某种方式找到可以提供这些项目的所有 JAR 文件。
- 对于不同工件提供的每个导入项目,确定(无需输入)开发人员打算使用的工件之一。
- 对于该项目,发现所需的 Scala 版本(由部署环境确定),并查找该工件的 Scala 匹配版本。
- 对于该工件的版本列表,找到将与 spark 基础结构的其余部分一起使用的版本。
第 3 步和第 5 步需要解决类似于 "I parked my car, here's the keys, go find it" 的解决方案,其中汽车可能在世界任何地方,并且您无法从人那里获得比 "I parked my car"
更多的信息
第 4 步需要发现一些无法确定的东西,因为您可能不知道所有的部署位置,但您可以针对每个版本的 Scala 进行编译。
这个 post 的要点是你在做傻事。 sbt 文件是开发人员期望/需要的文档。一个开发人员如果懒得为他们正在使用的东西编写一行配置,那将是一场噩梦。忘记写那一行的开发人员很烦人,可以通过要求开发人员做他们忘记做的事情来轻松解决。
这忽略了构建 SBT 的 Maven 核心概念。因为假设您实际上成功地完成了步骤 1 到 5,并不是所有库版本的组合都可以一起工作,因为 Maven 和 SBT 都可以自动解决依赖关系。这意味着如果您导入 org:item:1.1 和 org:item2:1.0,org:item2:1.0 可能需要 org:item:1.3 并且您的完整版本中会有版本号冲突解决了 Maven 依赖项。在这样的情况下,只有一个库在 Java 1.8 项目中使用,如果使用的库与某些代码不兼容,人们(称为构建大师)通常需要调查构建配置并确定哪个需要更新工件的版本以修复不兼容性。
如果你的项目能写出来,那就太棒了。祝你好运!
我是 Scala 的新手:)
如果我理解正确,您必须首先在 build.sbt
文件的 Library Dependencies 中包含所需的库,然后才能 import 将所需的库放入 scala 脚本中。
但是,我必须反过来做。我必须编写一个 Python 脚本来自动将 Scala 的导入语句转换为库依赖语句,以便将它们插入到 build.sbt
文件中。
例如
发件人:
import org.apache.spark.sql.SparkSession
import json._
至:
libraryDependencies += "org.apache.spark" %% "spark-sql" % sparkVersion % "provided"
libraryDependencies += "com.mediamath" %%% "scala-json" % "1.0"
我知道库依赖的语法如下:
libraryDependencies += groupID % artifactID % revision % configuration
而且我们应该在 maven central repository 中查找 groupID
、artifactID
和 revision
。
但是,此手动查找不允许我自动编程转换。我错过了什么吗?我可以用来完成此任务的其他语法?还有其他方法吗?
所以在某些语言中,导入必须以特定方式完成。这样看起来像 "import all the stuff, then start doing things"
在 Scala 中,可以在源代码中的任何位置导入项目。这会使事情复杂化。例如,在 Spark 代码中,您间接向 Spark 应用程序主机询问它提供的符号,这些符号存储在 运行 时间传回给您的变量中,然后您导入这些符号。
import org.apache.spark.sql.SparkSession
val spark = SparkSession
.builder()
.appName("Spark SQL basic example")
.config("spark.some.config.option", "some-value")
.getOrCreate()
// For implicit conversions like converting RDDs to DataFrames
import spark.implicits._
(注意示例中的最后一行导入了创建的 spark 变量的 implicits
字段中保存的任何内容。
最后,Maven 神器的版本不止一个。不能安全地引用特定 Maven 工件的任何版本,因为并非所有项目都试图提供所有版本号之间的向后兼容性(即使他们尝试这样做,兼容性错误仍然存在)。
https://mvnrepository.com/artifact/org.apache.spark/spark-core列出了大约30个不同版本的spark-core,其他spark库使用的核心例程。如果您选择与现有 spark 服务不同的版本,您的应用程序将无法正常运行,因为 spark 通常不兼容主要版本号,而是兼容主要和次要版本号(2.3 编译代码将无法在 2.4 环境中工作)
此外,Scala 代码在其编译阶段使用大量优化例程。这些优化例程意味着通常不能在 Scala 2.12 运行 时间环境中使用 Scala 2.11 class。所有 classes 必须完全匹配其 运行 时间环境。要发现 运行time 环境,不检查导入语句,而是检查发生编译的机器中 Scala 运行time 的设置,并确保它们与目标相同输出将 运行 的环境。这就是为什么对于许多库,您会看到多次构建相同的版本号,例如
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>2.4.5</version>
</dependency>
对比
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.4.5</version>
</dependency>
(上面的示例是捏造的,但说明了为 2.11 和 2.12 编译的库的相同版本)
最后,导入不是对 Maven 工件名称的引用。相反,它们是 JAR 文件(一种 Maven 工件)中的元素。因此,您将遇到一个额外的问题,即发现哪个 JAR 文件包含导入的项目,而不必事先知道您正在使用哪个 JAR 文件。
简而言之,您正试图通过例程来逆转在此环境中编写程序的自然过程,因为您正试图修复一个没有记录他们打算使用的内容的程序员。但是,您的例程必须
- 获取进口商品,其中一些可能是在 运行 时间建造的,并列一个清单。
- 获取该项目列表,并以某种方式找到可以提供这些项目的所有 JAR 文件。
- 对于不同工件提供的每个导入项目,确定(无需输入)开发人员打算使用的工件之一。
- 对于该项目,发现所需的 Scala 版本(由部署环境确定),并查找该工件的 Scala 匹配版本。
- 对于该工件的版本列表,找到将与 spark 基础结构的其余部分一起使用的版本。
第 3 步和第 5 步需要解决类似于 "I parked my car, here's the keys, go find it" 的解决方案,其中汽车可能在世界任何地方,并且您无法从人那里获得比 "I parked my car"
更多的信息第 4 步需要发现一些无法确定的东西,因为您可能不知道所有的部署位置,但您可以针对每个版本的 Scala 进行编译。
这个 post 的要点是你在做傻事。 sbt 文件是开发人员期望/需要的文档。一个开发人员如果懒得为他们正在使用的东西编写一行配置,那将是一场噩梦。忘记写那一行的开发人员很烦人,可以通过要求开发人员做他们忘记做的事情来轻松解决。
这忽略了构建 SBT 的 Maven 核心概念。因为假设您实际上成功地完成了步骤 1 到 5,并不是所有库版本的组合都可以一起工作,因为 Maven 和 SBT 都可以自动解决依赖关系。这意味着如果您导入 org:item:1.1 和 org:item2:1.0,org:item2:1.0 可能需要 org:item:1.3 并且您的完整版本中会有版本号冲突解决了 Maven 依赖项。在这样的情况下,只有一个库在 Java 1.8 项目中使用,如果使用的库与某些代码不兼容,人们(称为构建大师)通常需要调查构建配置并确定哪个需要更新工件的版本以修复不兼容性。
如果你的项目能写出来,那就太棒了。祝你好运!