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

Bun initial cleanup #292

Merged
merged 4 commits into from
Oct 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ abstract class BunExecRunner {
}

fun executeBunxCommand(project: ProjectApiHelper, extension: NodeExtension, nodeExecConfiguration: NodeExecConfiguration, variants: VariantComputer): ExecResult {
val bunExecConfiguration = NpmExecConfiguration("bunx") { variantComputer, nodeExtension, bunBinDir ->
variantComputer.computeBunxExec(nodeExtension, bunBinDir)
}
val bunExecConfiguration = NpmExecConfiguration("bunx"
) { variantComputer, nodeExtension, bunBinDir ->
variantComputer.computeBunxExec(nodeExtension, bunBinDir) }

val enhancedNodeExecConfiguration = NpmProxy.addProxyEnvironmentVariables(extension.nodeProxySettings.get(), nodeExecConfiguration)
val execConfiguration = computeExecConfiguration(extension, bunExecConfiguration, enhancedNodeExecConfiguration, variants).get()
Expand Down
117 changes: 50 additions & 67 deletions src/main/kotlin/com/github/gradle/node/variant/VariantComputer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.github.gradle.node.util.Platform
import com.github.gradle.node.util.mapIf
import com.github.gradle.node.util.zip
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider

Expand Down Expand Up @@ -40,6 +41,34 @@ fun computeNodeDir(nodeExtension: NodeExtension, osName: String, osArch: String)
}
}

/**
* Compute the path for a given command, from a given binary directory, taking Windows into account
*/
internal fun computeExec(nodeExtension: NodeExtension, binDirProvider: Provider<Directory>,
configurationCommand: Property<String>, unixCommand: String, windowsCommand: String): Provider<String> {
return zip(nodeExtension.download, configurationCommand, binDirProvider).map {
val (download, cfgCommand, binDir) = it
val command = if (nodeExtension.resolvedPlatform.get().isWindows()) {
cfgCommand.mapIf({ it == unixCommand }) { windowsCommand }
} else cfgCommand
if (download) binDir.dir(command).asFile.absolutePath else command
}
}

/**
* Compute the path for a given package, taken versions and user-configured working directories into account
*/
internal fun computePackageDir(packageName: String, packageVersion: Property<String>, packageWorkDir: DirectoryProperty): Provider<Directory> {
return zip(packageVersion, packageWorkDir).map {
val (version, workDir) = it
val dirnameSuffix = if (version.isNotBlank()) {
"-v${version}"
} else "-latest"
val dirname = "$packageName$dirnameSuffix"
workDir.dir(dirname)
}
}

/**
* Get the node archive name in Gradle dependency format, using zip for Windows and tar.gz everywhere else.
*
Expand Down Expand Up @@ -92,13 +121,8 @@ open class VariantComputer {
* Can be overridden by setting npmCommand.
*/
fun computeNpmExec(nodeExtension: NodeExtension, npmBinDirProvider: Provider<Directory>): Provider<String> {
return zip(nodeExtension.download, nodeExtension.npmCommand, npmBinDirProvider).map {
val (download, npmCommand, npmBinDir) = it
val command = if (nodeExtension.resolvedPlatform.get().isWindows()) {
npmCommand.mapIf({ it == "npm" }) { "npm.cmd" }
} else npmCommand
if (download) npmBinDir.dir(command).asFile.absolutePath else command
}
return computeExec(nodeExtension, npmBinDirProvider,
nodeExtension.npmCommand, "npm", "npm.cmd")
}

/**
Expand All @@ -107,62 +131,23 @@ open class VariantComputer {
* Can be overridden by setting npxCommand.
*/
fun computeNpxExec(nodeExtension: NodeExtension, npmBinDirProvider: Provider<Directory>): Provider<String> {
return zip(nodeExtension.download, nodeExtension.npxCommand, npmBinDirProvider).map {
val (download, npxCommand, npmBinDir) = it
val command = if (nodeExtension.resolvedPlatform.get().isWindows()) {
npxCommand.mapIf({ it == "npx" }) { "npx.cmd" }
} else npxCommand
if (download) npmBinDir.dir(command).asFile.absolutePath else command
}
}

/**
* Get the expected bunx binary name, bunx.cmd on Windows and bunx everywhere else.
*
* Can be overridden by setting bunxCommand.
*/
fun computeBunxExec(nodeExtension: NodeExtension, bunBinDirProvider: Provider<Directory>): Provider<String> {
return zip(nodeExtension.download, nodeExtension.npxCommand, bunBinDirProvider).map {
val (download, bunxCommand, bunBinDir) = it
val command = if (nodeExtension.resolvedPlatform.get().isWindows()) {
bunxCommand.mapIf({ it == "bunx" }) { "bunx.cmd" }
} else bunxCommand
if (download) bunBinDir.dir(command).asFile.absolutePath else command
}
return computeExec(nodeExtension, npmBinDirProvider,
nodeExtension.npxCommand, "npx", "npx.cmd")
}

fun computePnpmDir(nodeExtension: NodeExtension): Provider<Directory> {
return zip(nodeExtension.pnpmVersion, nodeExtension.pnpmWorkDir).map {
val (pnpmVersion, pnpmWorkDir) = it
val dirnameSuffix = if (pnpmVersion.isNotBlank()) {
"-v${pnpmVersion}"
} else "-latest"
val dirname = "pnpm$dirnameSuffix"
pnpmWorkDir.dir(dirname)
}
return computePackageDir("pnpm", nodeExtension.pnpmVersion, nodeExtension.pnpmWorkDir)
}

fun computePnpmBinDir(pnpmDirProvider: Provider<Directory>, platform: Property<Platform>) = computeProductBinDir(pnpmDirProvider, platform)

fun computePnpmExec(nodeExtension: NodeExtension, pnpmBinDirProvider: Provider<Directory>): Provider<String> {
return zip(nodeExtension.pnpmCommand, nodeExtension.download, pnpmBinDirProvider).map {
val (pnpmCommand, download, pnpmBinDir) = it
val command = if (nodeExtension.resolvedPlatform.get().isWindows()) {
pnpmCommand.mapIf({ it == "pnpm" }) { "pnpm.cmd" }
} else pnpmCommand
if (download) pnpmBinDir.dir(command).asFile.absolutePath else command
}
return computeExec(nodeExtension, pnpmBinDirProvider,
nodeExtension.pnpmCommand, "pnpm", "pnpm.cmd")
}

fun computeYarnDir(nodeExtension: NodeExtension): Provider<Directory> {
return zip(nodeExtension.yarnVersion, nodeExtension.yarnWorkDir).map {
val (yarnVersion, yarnWorkDir) = it
val dirnameSuffix = if (yarnVersion.isNotBlank()) {
"-v${yarnVersion}"
} else "-latest"
val dirname = "yarn$dirnameSuffix"
yarnWorkDir.dir(dirname)
}
return computePackageDir("yarn", nodeExtension.yarnVersion, nodeExtension.yarnWorkDir)
}

fun computeYarnBinDir(yarnDirProvider: Provider<Directory>, platform: Property<Platform>) = computeProductBinDir(yarnDirProvider, platform)
Expand All @@ -179,26 +164,24 @@ open class VariantComputer {
}

fun computeBunDir(nodeExtension: NodeExtension): Provider<Directory> {
return zip(nodeExtension.bunVersion, nodeExtension.bunWorkDir).map {
val (bunVersion, bunWorkDir) = it
val dirnameSuffix = if (bunVersion.isNotBlank()) {
"-v${bunVersion}"
} else "-latest"
val dirname = "bun$dirnameSuffix"
bunWorkDir.dir(dirname)
}
return computePackageDir("bun", nodeExtension.bunVersion, nodeExtension.bunWorkDir)
}

fun computeBunBinDir(bunDirProvider: Provider<Directory>, platform: Property<Platform>) = computeProductBinDir(bunDirProvider, platform)

fun computeBunExec(nodeExtension: NodeExtension, bunBinDirProvider: Provider<Directory>): Provider<String> {
return zip(nodeExtension.bunCommand, nodeExtension.download, bunBinDirProvider).map {
val (bunCommand, download, bunBinDir) = it
val command = if (nodeExtension.resolvedPlatform.get().isWindows()) {
bunCommand.mapIf({ it == "bun" }) { "bun.cmd" }
} else bunCommand
if (download) bunBinDir.dir(command).asFile.absolutePath else command
}
return computeExec(nodeExtension, bunBinDirProvider,
nodeExtension.bunCommand, "bun", "bun.cmd")
}

/**
* Get the expected bunx binary name, bunx.cmd on Windows and bunx everywhere else.
*
* Can be overridden by setting bunxCommand.
*/
fun computeBunxExec(nodeExtension: NodeExtension, bunBinDirProvider: Provider<Directory>): Provider<String> {
return computeExec(nodeExtension, bunBinDirProvider,
nodeExtension.bunxCommand, "bunx", "bunx.cmd")
}

private fun computeProductBinDir(productDirProvider: Provider<Directory>, platform: Property<Platform>) =
Expand Down
8 changes: 8 additions & 0 deletions src/test/groovy/com/github/gradle/node/bun/BunUtils.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.github.gradle.node.bun

class BunUtils {
/**
* Version used in tests
*/
static VERSION = "1.0.3"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package com.github.gradle.node.bun.task

import com.github.gradle.AbstractIntegTest
import org.gradle.testkit.runner.TaskOutcome
import spock.lang.Ignore
import spock.lang.IgnoreIf

import static com.github.gradle.node.NodeExtension.DEFAULT_NODE_VERSION

@IgnoreIf({ os.windows })
class BunInstall_integTest extends AbstractIntegTest {

def 'install packages with bun (#gv.version)'() {
given:
gradleVersion = gv
Expand All @@ -16,22 +18,24 @@ class BunInstall_integTest extends AbstractIntegTest {
plugins {
id 'com.github.node-gradle.node'
}

node {
download = true
}
''')
writeEmptyPackageJson()

when:
def result = build('bunInstall')

then:
result.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result.task(":bunSetup").outcome == TaskOutcome.SUCCESS
result.task(":bunInstall").outcome == TaskOutcome.SUCCESS

when:
result = build('bunInstall')

then:
result.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result.task(":bunSetup").outcome == TaskOutcome.UP_TO_DATE
// because bun.lockb is generated only when needed
result.task(":bunInstall").outcome == TaskOutcome.UP_TO_DATE
Expand Down Expand Up @@ -196,7 +200,7 @@ class BunInstall_integTest extends AbstractIntegTest {
}

bunInstall {
nodeModulesOutputFilter {
nodeModulesOutputFilter {
exclude("is-number/package.json")
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.github.gradle.node.bun.task

import com.github.gradle.AbstractIntegTest
import com.github.gradle.node.Versions
import com.github.gradle.node.bun.BunUtils
import org.gradle.testkit.runner.TaskOutcome
import org.junit.Rule
import org.junit.contrib.java.lang.system.EnvironmentVariables
import spock.lang.Ignore
import spock.lang.IgnoreIf

Expand All @@ -20,36 +18,36 @@ class BunTask_integTest extends AbstractIntegTest {
def result1 = build(":test")

then:
result1.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result1.task(":bunSetup").outcome == TaskOutcome.SUCCESS
result1.task(":bunInstall").outcome == TaskOutcome.SUCCESS
result1.task(":npmInstall") == null
result1.task(":test").outcome == TaskOutcome.SUCCESS
result1.output.contains("1 passing")

when:
def result2 = build(":test")

then:
result2.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result2.task(":bunSetup").outcome == TaskOutcome.UP_TO_DATE
result2.task(":bunInstall").outcome == TaskOutcome.SUCCESS
result2.task(":npmInstall") == null
result2.task(":test").outcome == TaskOutcome.UP_TO_DATE

when:
def result3 = build(":test", "-DchangeInputs=true")

then:
result3.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result3.task(":bunSetup").outcome == TaskOutcome.UP_TO_DATE
result3.task(":bunInstall").outcome == TaskOutcome.UP_TO_DATE
result3.task(":npmInstall") == null
result3.task(":test").outcome == TaskOutcome.SUCCESS

when:
def result4 = build(":version")

then:
result4.task(":version").outcome == TaskOutcome.SUCCESS
result4.output.contains("> Task :version${System.lineSeparator()}1.0.3")
result4.output.contains("> Task :version${System.lineSeparator()}${BunUtils.VERSION}")

where:
gv << GRADLE_VERSIONS_UNDER_TEST
Expand All @@ -64,7 +62,6 @@ class BunTask_integTest extends AbstractIntegTest {
def result1 = build(":env")

then:
result1.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result1.task(":bunSetup").outcome == TaskOutcome.SUCCESS
result1.task(":bunInstall").outcome == TaskOutcome.SUCCESS
result1.task(":env").outcome == TaskOutcome.SUCCESS
Expand All @@ -74,7 +71,6 @@ class BunTask_integTest extends AbstractIntegTest {
def result2 = build(":env", "-DcustomEnv=true")

then:
result2.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result2.task(":bunSetup").outcome == TaskOutcome.UP_TO_DATE
result2.task(":bunInstall").outcome == TaskOutcome.SUCCESS
result2.task(":env").outcome == TaskOutcome.SUCCESS
Expand All @@ -85,7 +81,6 @@ class BunTask_integTest extends AbstractIntegTest {
def result3 = build(":env", "-DcustomEnv=true")

then:
result3.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result3.task(":bunSetup").outcome == TaskOutcome.UP_TO_DATE
result3.task(":bunInstall").outcome == TaskOutcome.UP_TO_DATE
result3.task(":env").outcome == TaskOutcome.UP_TO_DATE
Expand All @@ -94,7 +89,6 @@ class BunTask_integTest extends AbstractIntegTest {
def result4 = build(":env", "-DignoreExitValue=true", "-DnotExistingCommand=true")

then:
result4.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result4.task(":bunSetup").outcome == TaskOutcome.UP_TO_DATE
result4.task(":bunInstall").outcome == TaskOutcome.UP_TO_DATE
result4.task(":env").outcome == TaskOutcome.SUCCESS
Expand All @@ -104,7 +98,6 @@ class BunTask_integTest extends AbstractIntegTest {
def result5 = buildAndFail(":env", "-DnotExistingCommand=true")

then:
result5.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result5.task(":bunSetup").outcome == TaskOutcome.UP_TO_DATE
result5.task(":bunInstall").outcome == TaskOutcome.UP_TO_DATE
result5.task(":env").outcome == TaskOutcome.FAILED
Expand All @@ -114,7 +107,6 @@ class BunTask_integTest extends AbstractIntegTest {
def result6 = build(":pwd")

then:
result6.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result6.task(":bunSetup").outcome == TaskOutcome.UP_TO_DATE
result6.task(":bunInstall").outcome == TaskOutcome.UP_TO_DATE
result6.task(":pwd").outcome == TaskOutcome.SUCCESS
Expand All @@ -124,7 +116,6 @@ class BunTask_integTest extends AbstractIntegTest {
def result7 = build(":pwd", "-DcustomWorkingDir=true")

then:
result7.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result7.task(":bunSetup").outcome == TaskOutcome.UP_TO_DATE
result7.task(":bunInstall").outcome == TaskOutcome.UP_TO_DATE
result7.task(":pwd").outcome == TaskOutcome.UP_TO_DATE
Expand All @@ -133,7 +124,6 @@ class BunTask_integTest extends AbstractIntegTest {
def result8 = build(":pwd", "-DcustomWorkingDir=true", "--rerun-tasks")

then:
result8.task(":nodeSetup").outcome == TaskOutcome.SKIPPED
result8.task(":bunSetup").outcome == TaskOutcome.SUCCESS
result8.task(":bunInstall").outcome == TaskOutcome.SUCCESS
result8.task(":pwd").outcome == TaskOutcome.SUCCESS
Expand All @@ -146,7 +136,7 @@ class BunTask_integTest extends AbstractIntegTest {

then:
result9.task(":version").outcome == TaskOutcome.SUCCESS
result9.output.contains("> Task :version${System.lineSeparator()}1.0.3")
result9.output.contains("> Task :version${System.lineSeparator()}${BunUtils.VERSION}")

where:
gv << GRADLE_VERSIONS_UNDER_TEST
Expand All @@ -164,7 +154,7 @@ class BunTask_integTest extends AbstractIntegTest {

then:
result.task(":version").outcome == TaskOutcome.SUCCESS
result.output.contains("> Task :version${System.lineSeparator()}1.0.0")
result.output.contains("> Task :version${System.lineSeparator()}${BunUtils.VERSION}")

where:
gv << GRADLE_VERSIONS_UNDER_TEST
Expand Down
Loading