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

Add support for exporting to a Maven project #3003

Merged
merged 57 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
d32e80e
Option to export pom file for a Java Project
yadavan88 Jul 5, 2024
ed199d5
Fixed format and linting issues
yadavan88 Jul 5, 2024
ad8dd90
Added todo comment
yadavan88 Jul 5, 2024
137dd08
resolved review comments
yadavan88 Jul 5, 2024
0b8ddee
revert accident edit
yadavan88 Jul 5, 2024
66b008d
Regenarated reference docs
yadavan88 Jul 6, 2024
51b9793
trying maven
yadavan88 Jul 8, 2024
593f8bf
Added support for scala with maven
yadavan88 Jul 9, 2024
60d1b4a
Linting issues fixed
yadavan88 Jul 9, 2024
ceb306a
resolved the scala version correctly and append to dependency
yadavan88 Jul 9, 2024
b0bee53
Merge branch 'VirtusLab:main' into maven-pom-export-java
yadavan88 Jul 9, 2024
6369f77
fixed scope issue
yadavan88 Jul 9, 2024
a698c5e
fixed the dependency issue
yadavan88 Jul 9, 2024
876b08a
Fixed format
yadavan88 Jul 10, 2024
fd7a0f2
Addressing review comments
yadavan88 Jul 10, 2024
e644114
Addressing review comments
yadavan88 Jul 10, 2024
adec2b2
Added tests for other scala version, fixed formatting and linting
yadavan88 Jul 10, 2024
087d412
Added tests for other scala version, fixed formatting and linting
yadavan88 Jul 10, 2024
11686b5
Added language separation for maven profiles
yadavan88 Jul 11, 2024
e8c0961
separate command in test for java and scala projects
yadavan88 Jul 11, 2024
1dac967
Fixed issues with pom generation
yadavan88 Jul 11, 2024
e54b77f
Merge branch 'main' into maven-pom-export-java
yadavan88 Jul 12, 2024
a012629
reformatting
yadavan88 Jul 12, 2024
e559909
fixed dependency resolution issue
yadavan88 Jul 12, 2024
069e655
Separated scala specific tests into a separate trait to support Maven…
yadavan88 Jul 14, 2024
fa6d8b6
Separated scala specific tests into a separate trait to support Maven…
yadavan88 Jul 14, 2024
39650bf
Passed the exec command as a build param in maven
yadavan88 Jul 14, 2024
8aac6d6
Passed the exec command as a build param in maven
yadavan88 Jul 14, 2024
88bac25
Adjusted maven export tests
yadavan88 Jul 14, 2024
4bba811
fixed formatting
yadavan88 Jul 14, 2024
4557846
Added option to define resource directory in maven pom
yadavan88 Jul 16, 2024
adac8e5
Update from upstream main
yadavan88 Jul 19, 2024
bcb75b6
fixed linting issues
yadavan88 Jul 19, 2024
a9e5068
Fixed scala version during export to maven
yadavan88 Jul 19, 2024
a9134e2
Fix tests in progress
yadavan88 Jul 19, 2024
f2b0711
Fix tests
yadavan88 Jul 20, 2024
941a2b5
moved zio test spec to scala-specific build tool test
yadavan88 Jul 22, 2024
4496734
Fixed maven tests
yadavan88 Jul 22, 2024
8e1ae90
scalafmt ran
yadavan88 Jul 22, 2024
efb1d45
disabled running scala export tests in maven java export
yadavan88 Jul 22, 2024
f16e501
Fixed zio export test for mill - temp fix
yadavan88 Jul 23, 2024
54a767a
Fixed some review comments and also fixed issue with zio test
yadavan88 Jul 23, 2024
6fef9bf
Used constants for maven default versions
yadavan88 Jul 24, 2024
1e37710
Used constants for maven default versions
yadavan88 Jul 24, 2024
c07f3ea
resolved conflicts
yadavan88 Jul 24, 2024
dcfd8c4
resolved conflicts
yadavan88 Jul 24, 2024
447ca5a
Fixed issue with test scope in maven export
yadavan88 Jul 24, 2024
46552c1
Fixed maven test
yadavan88 Jul 24, 2024
019ef92
Update build.sc
yadavan88 Jul 25, 2024
94f520c
Merge remote-tracking branch 'origin/main' into maven-pom-export-java
Gedochao Jul 25, 2024
d27eda1
removed old todo
yadavan88 Jul 25, 2024
d06d091
Merge remote-tracking branch 'origin/main' into maven-pom-export-java
Gedochao Jul 26, 2024
7f90cff
Fixed the issue with maven export when same libraries are coming from…
yadavan88 Jul 26, 2024
bc82d8d
added maven-exec plugin in java mode
yadavan88 Jul 27, 2024
34af0f0
Merge remote-tracking branch 'origin/main' into maven-pom-export-java
Gedochao Aug 7, 2024
bcbff33
addressed review comments
yadavan88 Aug 8, 2024
86c8bf5
Added maven groupId etc in command line
yadavan88 Aug 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,9 @@ trait Core extends ScalaCliCrossSbtModule
| def giter8Organization = "${Deps.giter8.dep.module.organization.value}"
| def giter8Name = "${Deps.giter8.dep.module.name.value}"
| def giter8Version = "${Deps.giter8.dep.version}"
|
| def mavenVersion = "3.8.1"
| def mavenScalaCompilerPluginVersion = "4.9.1"
yadavan88 marked this conversation as resolved.
Show resolved Hide resolved
|}
|""".stripMargin
if (!os.isFile(dest) || os.read(dest) != code)
Expand Down
34 changes: 29 additions & 5 deletions modules/cli/src/main/scala/scala/cli/commands/export0/Export.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ object Export extends ScalaCommand[ExportOptions] {
logger: Logger
): SbtProjectDescriptor =
SbtProjectDescriptor(sbtVersion, extraSettings, logger)

def mavenProjectDescriptor(
mavenPluginVersion: String,
mavenScalaPluginVersion: String,
extraSettings: Seq[String],
logger: Logger
): MavenProjectDescriptor =
MavenProjectDescriptor(mavenPluginVersion, mavenScalaPluginVersion, extraSettings, logger)

def millProjectDescriptor(
cache: FileCache[Task],
projectName: Option[String],
Expand Down Expand Up @@ -129,17 +138,22 @@ object Export extends ScalaCommand[ExportOptions] {
sys.exit(1)
}

val shouldExportToMill = options.mill.getOrElse(false)
val shouldExportToSbt = options.sbt.getOrElse(false)
if (shouldExportToMill && shouldExportToSbt) {
val shouldExportToMill = options.mill.getOrElse(false)
val shouldExportToSbt = options.sbt.getOrElse(false)
val shouldExportToMaven = options.maven.getOrElse(false)

val exportOptions = List(shouldExportToMill, shouldExportToSbt, shouldExportToMaven)

if (exportOptions.count(identity) > 1) {
logger.error(
s"Error: Cannot export to both mill and sbt. Please pick one build tool to export."
)
sys.exit(1)
}

if (!shouldExportToJson) {
val buildToolName = if (shouldExportToMill) "mill" else "sbt"
val buildToolName =
if (shouldExportToMill) "mill" else if (shouldExportToMaven) "maven" else "sbt"
logger.message(s"Exporting to a $buildToolName project...")
}
else if (!shouldExportJsonToStdout)
Expand Down Expand Up @@ -211,14 +225,24 @@ object Export extends ScalaCommand[ExportOptions] {
project.print(System.out)
}
else {
val sbtVersion = options.sbtVersion.getOrElse("1.10.1")
val sbtVersion = options.sbtVersion.getOrElse("1.10.1")
val defaultMavenCompilerVersion = options.mvnVersion.getOrElse(Constants.mavenVersion)
val defaultScalaMavenCompilerVersion =
options.mvnScalaVersion.getOrElse(Constants.mavenScalaCompilerPluginVersion)

def sbtProjectDescriptor0 =
sbtProjectDescriptor(options.sbtSetting.map(_.trim).filter(_.nonEmpty), sbtVersion, logger)

val projectDescriptor =
if (shouldExportToMill)
millProjectDescriptor(options.shared.coursierCache, options.project, logger)
else if (shouldExportToMaven)
mavenProjectDescriptor(
defaultMavenCompilerVersion,
defaultScalaMavenCompilerVersion,
Nil,
logger
) // todo: do we need extraSettings?
Gedochao marked this conversation as resolved.
Show resolved Hide resolved
else if (shouldExportToJson)
jsonProjectDescriptor(options.project, inputs.workspace, logger)
else // shouldExportToSbt isn't checked, as it's treated as default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ final case class ExportOptions(
@HelpMessage("Sets the export format to SBT")
sbt: Option[Boolean] = None,
@Group(HelpGroup.BuildToolExport.toString)
@Tag(tags.experimental)
@Tag(tags.inShortHelp)
@HelpMessage("Sets the export format to Maven")
yadavan88 marked this conversation as resolved.
Show resolved Hide resolved
@Name("mvn")
maven: Option[Boolean] = None,
@Group(HelpGroup.BuildToolExport.toString)
@Tag(tags.restricted)
@Tag(tags.inShortHelp)
@HelpMessage("Sets the export format to Mill")
Expand All @@ -50,6 +56,14 @@ final case class ExportOptions(
@Tag(tags.restricted)
@HelpMessage("Version of SBT to be used for the export")
sbtVersion: Option[String] = None,
@Group(HelpGroup.BuildToolExport.toString)
@Tag(tags.experimental)
@HelpMessage("Version of Maven Compiler Plugin to be used for the export")
mvnVersion: Option[String] = None,
@Group(HelpGroup.BuildToolExport.toString)
@Tag(tags.experimental)
@HelpMessage("Version of Maven Scala Plugin to be used for the export")
mvnScalaVersion: Option[String] = None,
@Name("o")
@Group(HelpGroup.BuildToolExport.toString)
@Tag(tags.restricted)
Expand Down
146 changes: 146 additions & 0 deletions modules/cli/src/main/scala/scala/cli/exportCmd/MavenProject.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package scala.cli.exportCmd

import os.RelPath

import java.nio.charset.StandardCharsets

import scala.build.options.{ConfigMonoid, Scope}
import scala.xml.{Elem, NodeSeq, PrettyPrinter, XML}

final case class MavenProject(
groupId: Option[String] = None,
artifactId: Option[String] = None,
version: Option[String] = None,
plugins: Seq[MavenPlugin] = Nil,
imports: Seq[String] = Nil,
settings: Seq[Seq[String]] = Nil,
dependencies: Seq[MavenLibraryDependency] = Nil,
mainSources: Seq[(os.SubPath, String, Array[Byte])] = Nil,
testSources: Seq[(os.SubPath, String, Array[Byte])] = Nil,
resourceDirectories: Seq[String] = Nil
// properties: Seq[(String, String)] = Nil // using Seq[Tuple] since derive was failing for Map
yadavan88 marked this conversation as resolved.
Show resolved Hide resolved
) extends Project {

def +(other: MavenProject): MavenProject =
MavenProject.monoid.orElse(this, other)

def writeTo(dir: os.Path): Unit = {

val nl = System.lineSeparator()
val charset = StandardCharsets.UTF_8

val buildMavenContent = MavenModel(
"4.0.0",
groupId.getOrElse("groupId"),
artifactId.getOrElse("artifactId"),
version.getOrElse("0.1-SNAPSHOT"),
dependencies,
plugins,
resourceDirectories
// properties
yadavan88 marked this conversation as resolved.
Show resolved Hide resolved
)

val prettyPrinter = new PrettyPrinter(width = 80, step = 2)
val formattedXml = prettyPrinter.format(buildMavenContent.toXml)

os.write(
dir / "pom.xml",
formattedXml.getBytes(charset)
)

for ((path, language, content) <- mainSources) {
val path0 = dir / "src" / "main" / language / path
os.write(path0, content, createFolders = true)
}
for ((path, language, content) <- testSources) {
val path0 = dir / "src" / "test" / language / path
os.write(path0, content, createFolders = true)
}

}
}

object MavenProject {
implicit val monoid: ConfigMonoid[MavenProject] = ConfigMonoid.derive
}

final case class MavenModel(
model: String,
groupId: String,
artifactId: String,
version: String,
dependencies: Seq[MavenLibraryDependency],
plugins: Seq[MavenPlugin],
resourceDirectories: Seq[String]
// properties: Seq[(String, String)] //todo: bring back only if it is needed
yadavan88 marked this conversation as resolved.
Show resolved Hide resolved
) {

private def resourceNodes: NodeSeq =
if (resourceDirectories.isEmpty)
NodeSeq.Empty
else {
val resourceNodes = resourceDirectories.map { path =>
<resource>
<directory>
{path}
</directory>
</resource>
}
<resources>
{resourceNodes}
</resources>
}

def toXml: Elem =
<project>
<modelVersion>{model}</modelVersion>
<groupId>{groupId}</groupId>
<artifactId>{artifactId}</artifactId>
<version>{version}</version>

<dependencies>
{dependencies.map(_.toXml)}
</dependencies>
<build>
{resourceNodes}
<plugins>
{plugins.map(_.toXml)}
</plugins>
</build>
</project>
}

final case class MavenLibraryDependency(
groupId: String,
artifactId: String,
version: String,
scope: Option[String] = None
) {

private val scopeParam = scope.fold(scala.xml.Null)(s => <scope>{s}</scope>)

def toXml: Elem =
<dependency>
<groupId>{groupId}</groupId>
<artifactId>{artifactId}</artifactId>
<version>{version}</version>
{scopeParam}
</dependency>
}

final case class MavenPlugin(
groupId: String,
artifactId: String,
version: String,
jdk: String,
additionalNode: Elem
) {

def toXml: Elem =
<plugin>
<groupId>{groupId}</groupId>
<artifactId>{artifactId}</artifactId>
<version>{version}</version>
{additionalNode}
</plugin>
}
Loading
Loading