Skip to content

Commit

Permalink
Fixed merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
Sten Roger Sandvik committed Nov 29, 2016
2 parents 2dc1c34 + 00cc0c8 commit e334cf1
Show file tree
Hide file tree
Showing 18 changed files with 535 additions and 603 deletions.
70 changes: 64 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,44 @@ the class `NpmTask`:
args = ['install', 'express', '--save-dev']
}

Executing Yarn Tasks
---------------------

When adding the node plugin, you will have a yarn task already added. This
task will execute `yarn` and installs all dependencies in `package.json`.
It will only run when changes are made to `package.json`, `yarn.lock`, or `node_modules`.
Execute it like this:

$ gradle yarn

All npm command can also be invoked using underscore notation based on a gradle
rule:

$ gradle yarn_install
$ gradle yarn_upgrade
$ gradle yarn_ls
$ gradle yarn_cache_clean
...

These however are not shown when running gradle tasks, as they generated
dynamically. However they can be used for dependency declarations, such as:

yarn_install.dependsOn(yarn_cache_clean)

More arguments can be passed via the build.gradle file:

yarn_cache_clean {
args = ['--no-emoji', '--json']
}

If you want to extend the tasks more or create custom variants, you can extend
the class `YarnTask`:

task addExpress(type: YarnTask) {
// add the express package only
args = ['add', 'express', '--dev']
}

Configuring the Plugin
----------------------

Expand All @@ -139,6 +177,9 @@ You can configure the plugin using the "node" extension block, like this:
// Version of npm to use.
npmVersion = '2.1.5'

// Version of Yarn to use.
yarnVersion = '0.16.1'

// Base URL for fetching node distributions (change if you have a mirror).
distBaseUrl = 'https://nodejs.org/dist'

Expand All @@ -149,6 +190,12 @@ You can configure the plugin using the "node" extension block, like this:
// Set the work directory for unpacking node
workDir = file("${project.buildDir}/nodejs")

// Set the work directory for NPM
npmWorkDir = file("${project.buildDir}/npm")

// Set the work directory for Yarn
yarnWorkDir = file("${project.buildDir}/yarn")

// Set the work directory where node_modules should be located
nodeModulesDir = file("${project.projectDir}")
}
Expand All @@ -158,13 +205,24 @@ You can configure the plugin using the "node" extension block, like this:
Using a Custom (project-local) Version of `npm`
-----------------------------------------------

The plugin will use a locally-installed `npm` if it exists, regardless of the
method of installation.
If `npmVersion` is specified, the plugin installs that version of `npm` into `npmWorkDir`
by the `npmSetup` task and use it.

If `npmVersion` is not specified and a locally-installed `npm` exists, The plugin will
use it.

Otherwise, the plugin will use the `npm` bundled with the version of node installation.

Using a Custom (project-local) Version of `yarn`
-----------------------------------------------

The plugin never uses a locally-installed `yarn` because it may be deleted during
`yarn` execution.
Instead, it installs `yarn` into `yarnWorkDir` (`.gradle/yarn/` by default) by
the `yarnSetup` task and use it.

If you would like the plugin to install use a custom version of npm rather than
the one bundled with the version of node installation, you can set `npmVersion`
in the `node` extension block. The plugin will install the npm to the project's
`node_modules` directory by configuring the `npmSetup` task.
If you would like the plugin to install use a custom version of yarn, you can set
`yarnVersion` in the `node` extension block.

Building the Plugin
-------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.moowork.gradle.node

import com.moowork.gradle.AbstractIntegTest

class YarnInstall_integTest
extends AbstractIntegTest
{
def 'install packages with yarn'()
{
given:
writeBuild( '''
apply plugin: 'com.moowork.node'
node {
version = "6.9.1"
yarnVersion = "0.16.1"
download = true
workDir = file('build/node')
yarnWorkDir = file('build/yarn')
}
''' )
writeEmptyPackageJson()

when:
def result = runTasksSuccessfully( 'yarn' )

then:
result.wasExecuted( 'yarn' )

when:
result = runTasksSuccessfully( 'yarn' )

then:
result.wasUpToDate( 'yarn' )
}

def 'install packages with yarn in different directory'()
{
given:
writeBuild( '''
apply plugin: 'com.moowork.node'
node {
version = "6.9.1"
yarnVersion = "0.15.1"
download = true
workDir = file('build/node')
yarnWorkDir = file('build/yarn')
nodeModulesDir = file('subdirectory')
}
''' )
writeFile( 'subdirectory/package.json', """{
"name": "example",
"dependencies": {
}
}""" )

when:
def result = runTasksSuccessfully( 'yarn' )

then:
result.wasExecuted( 'yarn' )
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.moowork.gradle.node

import com.moowork.gradle.AbstractIntegTest

class YarnRule_integTest
extends AbstractIntegTest
{
def 'execute yarn_install rule'()
{
given:
writeBuild( '''
apply plugin: 'com.moowork.node'
node {
version = "6.9.1"
yarnVersion = "0.16.1"
download = true
workDir = file('build/node')
yarnWorkDir = file('build/yarn')
}
''' )
writeEmptyPackageJson()

when:
def result = runTasksSuccessfully( 'yarn_install' )

then:
result.wasExecuted( 'yarn_install' )
}

def 'can execute an yarn module using yarn_run_'()
{
given:
writeBuild( '''
apply plugin: 'com.moowork.node'
node {
version = "6.9.1"
yarnVersion = "0.17.5"
download = true
}
''' )

copyResources( 'fixtures/yarn/package.json', 'package.json' )

when:
def result = runTasksSuccessfully( 'yarn_run_parent' )

then:
result.success
fileExists( 'child1.txt' )
fileExists( 'child2.txt' )
fileExists( 'parent1.txt' )
fileExists( 'parent2.txt' )
}

}
15 changes: 15 additions & 0 deletions src/integTest/resources/fixtures/yarn/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "example",
"devDependencies": {
"yarn": "0.16.1",
"concurrently": "3.1.0"
},
"dependencies": {
"less": "2.6.1"
},
"scripts": {
"child1": "echo \"child1\" > child1.txt",
"child2": "echo \"child2\" > child2.txt",
"parent": "echo \"parent1\" > parent1.txt && concurrently \"yarn run child1\" \"yarn run child2\" && echo \"parent2\" > parent2.txt"
}
}
10 changes: 10 additions & 0 deletions src/main/groovy/com/moowork/gradle/node/NodeExtension.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,24 @@ class NodeExtension

def File workDir

def File npmWorkDir

def File yarnWorkDir

def File nodeModulesDir

def String version = '4.4.0'

def String npmVersion = ''

def String yarnVersion = ''

def String distBaseUrl = 'https://nodejs.org/dist'

def String npmCommand = 'npm'

def String yarnCommand = 'yarn'

def boolean download = false

def Variant variant
Expand All @@ -27,6 +35,8 @@ class NodeExtension
{
def cacheDir = new File( project.projectDir, '.gradle' )
this.workDir = new File( cacheDir, 'nodejs' )
this.npmWorkDir = new File( cacheDir, 'npm' )
this.yarnWorkDir = new File( cacheDir, 'yarn' )
this.nodeModulesDir = project.projectDir
}

Expand Down
31 changes: 31 additions & 0 deletions src/main/groovy/com/moowork/gradle/node/NodePlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class NodePlugin

private NpmSetupTask npmSetupTask

private YarnSetupTask yarnSetupTask

@Override
void apply( final Project project )
{
Expand All @@ -25,25 +27,30 @@ class NodePlugin
addGlobalTypes()
addTasks()
addNpmRule()
addYarnRule()

this.project.afterEvaluate {
this.config.variant = new VariantBuilder( this.config ).build()
configureSetupTask()
configureNpmSetupTask()
configureYarnSetupTask()
}
}

private void addGlobalTypes()
{
addGlobalTaskType( NodeTask )
addGlobalTaskType( NpmTask )
addGlobalTaskType( YarnTask )
}

private void addTasks()
{
this.project.tasks.create( NpmInstallTask.NAME, NpmInstallTask )
this.project.tasks.create( YarnInstallTask.NAME, YarnInstallTask )
this.setupTask = this.project.tasks.create( SetupTask.NAME, SetupTask )
this.npmSetupTask = this.project.tasks.create( NpmSetupTask.NAME, NpmSetupTask )
this.yarnSetupTask = this.project.tasks.create( YarnSetupTask.NAME, YarnSetupTask )
}

private void addGlobalTaskType( Class type )
Expand All @@ -70,6 +77,25 @@ class NodePlugin
}
}

private void addYarnRule()
{
// note this rule also makes it possible to specify e.g. "dependsOn yarn_install"
project.getTasks().addRule( 'Pattern: "yarn_<command>": Executes an Yarn command.' ) { String taskName ->
if ( taskName.startsWith( "yarn_" ) )
{
YarnTask yarnTask = project.getTasks().create( taskName, YarnTask.class )
String[] tokens = taskName.split( '_' ).tail() // all except first
yarnTask.yarnCommand = tokens

if (tokens.head().equalsIgnoreCase("run")) {
yarnTask.dependsOn(YarnInstallTask.NAME)
}

return yarnTask
}
}
}

private void configureSetupTask()
{
this.setupTask.setEnabled( this.config.download )
Expand All @@ -79,4 +105,9 @@ class NodePlugin
{
this.npmSetupTask.configureNpmVersion( this.config.npmVersion )
}

private void configureYarnSetupTask()
{
this.yarnSetupTask.configureYarnVersion( this.config.yarnVersion )
}
}
21 changes: 7 additions & 14 deletions src/main/groovy/com/moowork/gradle/node/exec/NpmExecRunner.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -26,23 +26,16 @@ class NpmExecRunner

def String npmScriptFile = this.variant.npmScriptFile
def File localNpm = project.file( new File( this.ext.nodeModulesDir, 'node_modules/npm/bin/npm-cli.js' ) )
def File workNpm = project.file( new File( this.ext.npmWorkDir, 'node_modules/npm/bin/npm-cli.js' ) )

// Use locally-installed npm if available
if ( localNpm.exists() )
// Use npm specified by user if available
if ( workNpm.exists() )
{
npmScriptFile = localNpm.absolutePath
npmScriptFile = workNpm.absolutePath
}

boolean notInstalling = !arguments.join(' ').startsWith('install')
boolean configuredLocalNpm = !project.node.npmVersion.empty

if ( !localNpm.exists() && configuredLocalNpm && notInstalling )
{
throw new InvalidUserDataException("""
Could not run npm command - local npm not found but requested in gradle node configuration.
A common reason for this is an npm-shrinkwrap.json file is present and un-installs npm.
To resolve this, add npm with version '${project.node.npmVersion}' to your package.json.
""".stripIndent())
// Use locally-installed npm if available
else if ( localNpm.exists() ) {
npmScriptFile = localNpm.absolutePath
}

def runner = new NodeExecRunner( this.project )
Expand Down
Loading

0 comments on commit e334cf1

Please sign in to comment.