Giter VIP home page Giter VIP logo

client-dependencies-gradle's Introduction

Client Dependencies Gradle Plugin

This Gradle plugin allows you to declare client side dependencies in build.gradle from bower, npm, yarn or git and with a much clearer dependencies resolution model. This plugin queries the registries directly so it doesn’t require or install node, npm or bower.

Getting Started

Gradle 2.0

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.craigburke.gradle:client-dependencies:1.4.1'
    }
}

apply plugin: 'com.craigburke.client-dependencies'

Gradle 2.1 and higher

plugins {
    id 'com.craigburke.client-dependencies' version '1.4.1'
}

Tasks

The plugin adds the following tasks to your build:

Task

Description

clientInstall

Installs all the client dependencies you have set in your build.gradle

clientRefresh

Refreshes client dependencies (if you add or modify your configuration)

clientClean

Removes client dependencies and clears the cache

clientReport

Prints a report of all dependencies and the resolved versions

Declaring dependencies

You can specify dependencies from different sources (npm, bower or git) and control which files are included in your project by using the DSL shown below.

⚠️
The following example shows the use of several different types of registries, this works but it’s best to stick to a single registry (NPM is recommended).
clientDependencies {
    bower {
        'jquery'('2.0.0') // <1>
    }
    npm {
        'bootstrap'('3.3.6', exclude: 'jquery') // <2>
        'restangular'('1.5.1', transitive: false) // <3>
        'angular-animate'('1.5.0', into: 'angular/modules') // <4>
        'animate.css'('1.0.0', url:'daneden/animate.css') // <5>
        'angular-ui-bootstrap'('1.3.x', from:'dist') { // <6>
            include 'ui-bootstrap-tpls.js'
        }
    }
    yarn {
        'angular'('1.5.8') // <7>
    }
}
  1. Installs jquery from bower and into the location (src/assets/vendor/jquery) using the default copy settings

  2. Installs bootstrap from npm and excludes the dependency jquery

  3. Installs restangular from npm but doesn’t include any child dependencies

  4. Changing the destination path using the into property. This is relative to the install path meaning this would install to the location src/assets/vendor/angular/modules.

  5. Use the url property to use a github repo as a dependency source (expands to https://www.github.com/danedan/animate.css.git). A full URL reference any git repository will also work here.

  6. The from property allows you to copy code only from a certain subfolder

  7. Installs angular from Yarn’s registry

💡
If you update your config and it doesn’t seem to be taking effect, try running the clientRefresh task.

The copy task

The files are copied using the DSL of Gradle’s copy task. See: Gradle Copy.

Default copy task

The default settings for the copy task are as follows:

clientDependencies {
    fileExtensions = ['css', 'js', 'eot', 'svg', 'ttf', 'woff', 'woff2', 'ts',
                      'jpg', 'jpeg', 'png', 'gif'] // <1>
    releaseFolders = ['dist', 'release'] // <2>
    copyIncludes = [] // <3>
    copyExcludes = ['**/*.min.js', '**/*.min.css', '**/*.map', '**/Gruntfile.js',
                        'gulpfile.js', 'source/**'] // <4>
}
  1. Default included file extensions

  2. Default release folders to look for. If a folder by this name is found then the file extension includes are relative to this folder. (ex dist/**/*.js instead of **/*.js)

  3. Default includes to append to the end of the copy task

  4. Default excludes to append to the end of the copy task

You can add to the default values listed above by using the following methods:

clientDependencies {
    fileExtensions 'ts' // <1>
    releaseFolders 'lib' // <2>
    copyIncludes '**' // <3>
    copyExcludes 'index.js' // <4>
}
  1. Adds the file extension (ts) to default fileExtensions

  2. Adds a release folders (lib) to the default release folder list

  3. Additional includes to append to the end of the copy task

  4. Additional excludes to append to the end of the copy task

You can also completely override the default copy task (this will then completely ignores the settings above)

clientDependencies {
    defaultCopy = {
        include '**'
        exclude '**/*.less', '**/*.sass'
    }
}

Overriding the copy task for an individual dependency

By passing a closure as the last argument of a dependency declaration you have full control of what files get copied and where they get copied to.

For example:

clientDependencies {
    npm {
        'bootstrap'('3.3.6') {
            include 'dist/**'
            exclude '**/*.min.*', '**/*.map', '**/npm.js'
            eachFile { it.path -= 'dist/' }
        }
    }
}

Registering custom registry

By default two registries named npm and bower are installed. You can either override these or register new custom registries. This allows you to also use it to separate out dependencies (production versus devevelopment dependencies for example).

clientDependencies {
    registry 'npmLocal', type:'npm', url:'http://www.example.com/npm/'
    registry 'npmDev', type: 'npm', url:'http://www.example.com/npm/'
    registry 'bowerLocal', type:'bower', url:'http://www.example.com/bower/'

    npmLocal {
        'bootstrap'('3.3.6')
        'myJSLib'('1.0.0')
    }

    npmDev {
        'lodash'('2.4.1')
        'grunt'('1.0.0')
        'grunt-contrib-clean'('~0.6.0')
        'colors'('^0.6.2')
    }

    bowerLocal {
        'jquery'('2.0.0')
        'myBowerJSLib'('1.0.0')
     }
}

Additional Properties

What follows are additional configuration options. With the possible exception of installDir you typically won’t need to set any of these options.

clientDependencies {
    installDir = 'src/assets/vendor' // <1>
    cacheDir = 'build/client-cache/' // <2>
    userAgent = 'client-dependencies-gradle' // <3>
    useGlobalCache = true // <4>
    checkDownloads = true // <5>
    threadPoolSize = 10 // <6>
}
  1. Location that dependencies are installed to

  2. Location of the local project cache

  3. User agent used when making web requests

  4. Whether the global caches for bower and npm are searched when resolving dependencies

  5. Whether downloads are checked and verified

  6. Size of thread pool used when downloading and installing dependencies

Special for Bower repositories

Github credentials can be set in the clientDependencies block:

clientDependencies {
    githubUsername = project.hasProperty('githubUsername') ? project.githubUsername : '' // <1>
    githubPassword = project.hasProperty('githubPassword') ? project.githubPassword : '' // <2>
}
  1. Your Github Username

  2. Your Github password or if you use two factor login (and you really should), your personal access token (see: https://github.com/settings/tokens)

If you don’t want to use your username and password you can obtain Github token here https://github.com/settings/tokens/new and use it this way:

clientDependencies {
    githubToken = project.hasProperty('githubToken') ? project.githubToken : ''
}
🔥
that it is important never to store your Github credentials in your build.gradle file. Instead you can set the values in ~/.gradle/gradle.properties where they are for your eyes only.

Contributors

Thank you to the following people who have made significant contributions to this project:

client-dependencies-gradle's People

Contributors

bkoehm avatar craigburke avatar erichelgeson avatar filipblondeel avatar magx2 avatar mrampson avatar sbglasius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

client-dependencies-gradle's Issues

Refactor registry

Pull some of the common logic of the two registries into RegistryBase.

npe in BowerRegistry

somehow i am seeing NullPointerExceptions for bower dependencies that used to resolve with bower-installer-gradle. while this one works:

clientDependencies {
    bower {
        jquery "2.0.0"
    }
}

this one gives a npe:

clientDependencies {
    bower {
        angular "1.5.0"
    }
}

stacktrace:

Caused by: java.lang.NullPointerException: Cannot get property 'fullVersion' on null object
        at com.craigburke.gradle.client.registry.BowerRegistry.loadDependency(BowerRegistry.groovy:125)
        at com.craigburke.gradle.client.plugin.ClientDependenciesPlugin$_installDependencies_closure4$_closure10.doCall(ClientDependenciesPlugin.groovy:75)
        at groovyx.gpars.pa.CallClosure.call(CallClosure.java:47)

from a quick look at the repositories, i can just offer a wild guess: maybe a mismatch of the bower.json version and the actual tag name has something to do with it? they seem to be the same for jquery but not for a lot of other packages (v prefix)..

Bower dependancies without github tags error out

I have a bower package that is using the github resolver. it has no tags and is bombing out

clientDependencies {
    bower {
        'elusive-icons'('2.0.0')
    }
}
Execution failed for task ':clientInstall'.
> groovy.json.JsonException: Unable to process url: https://api.github.com/repos/reduxframework/Elusive-Icons/git/refs/tags

That repo has no tags so it 404's

Using version '1.1.4'

Any interest in making this useful to devs who might use npm and gradle?

In other words, you might have a project that has javascript and java. Our JS folks tend to use javascript tools (npm, etc) and java folks don't want to know anything about it. The idea is that they could both be used and have it work together.

Some things that would need to change is where it looks for package.json and the sections of package.json that is looks at (devDependencies for instance).

Might need to put things in node_modules or have the ability to copy certain sub directories in the package to certain places in the file system (or both).

Support Authenticated (and/or Conditional) requests to prevent GitHub API rate limiting

Hi!

I'm running clientInstall with the following configuration

clientDependencies {
    bower {
        'polymer'('1.4.0') { source '*' }
        'app-route'('0.9.1', url: 'PolymerElements/app-route') { source '*' }
        'paper-input'('1.0.0', url: 'PolymerElements/paper-input') { source '*' }
    }
}

and get the following response after successfully downloading 15 dependencies

{
  "message": "API rate limit exceeded for 10.101.110.11. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)",
  "documentation_url": "https://developer.github.com/v3/#rate-limiting"
}

Is there a way to supply user credentials to prevent rate limiting?

For requests using Basic Authentication or OAuth, you can make up to 5,000 requests per hour. For unauthenticated requests, the rate limit allows you to make up to 60 requests per hour. Unauthenticated requests are associated with your IP address, and not the user making requests.

Follow-up question which might (not) be a separate issue:
Does the plugin support conditional requests?

Most responses return an ETag header. Many responses also return a Last-Modified header. You can use the values of these headers to make subsequent requests to those resources using the If-None-Match and If-Modified-Since headers, respectively. If the resource has not changed, the server will return a 304 Not Modified. Also note: making a conditional request and receiving a 304 response does not count against your Rate Limit, so we encourage you to use it whenever possible.

Thanks again.

/Johannes

Unable to clean cached dependencies on Windows

When running gradle in daemon mode, some git object files are left open/locked, preventing a subsequent run of clientClean. An example on Windows7 + Git Bash (with org.gradle.daemon = true defined in .gradle/gradle.properties):

$ gradlew clientInstall
:clientInstall

BUILD SUCCESSFUL

Total time: 4.588 secs

$ gradlew clientClean
:clientClean FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':clientClean'.
> Unable to delete file: C:\Users\me\git\projectx\build\client-cache\bower\some-js-lib\1.2.3\.git\objects\pack\pack-df66b80a9b56f748396e2aa74daad6124db34c23.pack

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 3.744 secs

This can be worked around by disabling the gradle daemon with the --no-daemon switch. The issue remains for some IDE integrations where the daemon is always used. See e.g. https://discuss.gradle.org/t/disable-gradle-daemon-in-eclipse/11503. The tool is currently broken on these platforms.

A likely fix would be to close() the Grgit instance in GitResolver.groovy after use.

.bower.json needed

Some bower packages uses .bower.json instead bower.json. Plugin trying to search bower.json and fails with error
for example:
lodash 4.15.0 uses .bower.json
jade 1.11.0 — .bower.json too

Dependency report task

Add gradle task to list client dependencies (clientReport). Should be similar to the gradle dependencies task.

Does not appear to work with NPM orgs

Angular 2 RC uses a new NPM org @angular with dependencies in it (https://www.npmjs.com/~angular). When attempting to install with this plugin, it puts the dependencies in folders like this:

grails-app/assets/npm/angular-common
grails-app/assets/npm/angular-compiler
grails-app/assets/npm/angular-core
grails-app/assets/npm/angular-http
grails-app/assets/npm/angular-platform-browser
grails-app/assets/npm/angular-platform-browser-dynamic
grails-app/assets/npm/angular-router
grails-app/assets/npm/angular-router-deprecated
grails-app/assets/npm/angular-upgrade

When instead, I think they should all be under a common @angular folder like this:

grails-app/assets/npm/@angular/common
grails-app/assets/npm/@angular/compiler
grails-app/assets/npm/@angular/core
grails-app/assets/npm/@angular/http
grails-app/assets/npm/@angular/platform-browser
grails-app/assets/npm/@angular/platform-browser-dynamic
grails-app/assets/npm/@angular/router
grails-app/assets/npm/@angular/router-deprecated
grails-app/assets/npm/@angular/upgrade

Circular dependencies should not result in an exception

This build script

plugins {
    id "com.craigburke.client-dependencies" version "1.1.4"
}

clientDependencies {
    installDir = 'src/main/resources/static/vendor'

    npm {
        'react' ('15.x.x')
        'react-dom' ('15.x.x')
        'babelify' ('7.3.0')
        'babel-preset-react' ('6.x.x')
    }
}

throws the following exception:

* What went wrong:
Execution failed for task ':web-frontend:clientReport'.
> com.craigburke.gradle.client.registry.core.CircularDependencyException: com.craigburke.gradle.client.registry.core.CircularDependencyException: com.craigburke.gradle.client.registry.core.CircularDependencyException: com.craigburke.gradle.client.registry.core.CircularDependencyException: com.craigburke.gradle.client.registry.core.CircularDependencyException: com.craigburke.gradle.client.registry.core.CircularDependencyException: com.craigburke.gradle.client.registry.core.CircularDependencyException: Circular dependency created by dependency babel-types@^6.9.0

It seems like circular dependencies are supported by npm, so they should also be supported by the client dependencies plugin.

Bower throws NPE when same dependency resolves in parellel

From #17 @zyro23

NPE is thrown with the following:

clientDependencies {
    bower {
        'angular-material'('1.0.6')
    }
}

angular-material has the following 4 dependencies:

"angular": "^1.4.8",
"angular-animate": "^1.4.8",
"angular-aria": "^1.4.8",
"angular-messages": "^1.4.8"

Those resolve fine. But those last three have an additional dependency on [email protected] So they're colliding as they all try to resolve those at the same time. I'll fix that.

"exclude" should exclude a dependency transitively

The following build script

plugins {
    id "com.craigburke.client-dependencies" version "1.1.4"
}

clientDependencies {
    installDir = 'src/main/resources/static/vendor'

    npm {
        'react' ('15.x.x')
        'react-dom' ('15.x.x')
        'babelify' ('7.3.0', exclude: 'babel-types')
        'babel-preset-react' ('6.x.x')
    }
}

Does not exclude "babel-types" from "babelify" - I guess because it is a transitive dependency. The script produces the following exception:

* What went wrong:
Execution failed for task ':web-frontend:clientReport'.
> com.craigburke.gradle.client.registry.core.CircularDependencyException: com.craigburke.gradle.client.registry.core.CircularDependencyException: com.craigburke.gradle.client.registry.core.CircularDependencyException: com.craigburke.gradle.client.registry.core.CircularDependencyException: Circular dependency created by dependency babel-types@^6.9.0

Excluding a dependency should also work when the library does not directly depend on the excluded dependency.

Use local caches

Check local caches first to resolve bower and npm dependencies.

npm - support scoped packages

it seems that currently, scoped packages are not supported.

for example, the angular2-material alpha packages are published under the angular2-material scope, e.g.: npm install --save @angular2-material/core. see

:clientInstall FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':clientInstall'.
> groovy.json.JsonException: groovy.json.JsonException: Unable to process url: https://registry.npmjs.org/@angular2-material/core

support for scoped packages would be great :)

Register custom repository

Be able to register custom bower or npm repos.

clientDependencies {
     registry name: 'npmLocal', type:'npm', url:'http://www.example.com/npm/'
     registry name: 'bowerLocal', type:'bower', url:'http://www.example.com/bower/'
}

Improve custom registry documentation

I defined a custom registry, cradle doesn't seem to complain about it, but the custom registry doesn't look like it is searched for dependency. Also, it would be nice to be able to override the default registry and be able to tell the plugin to just use a particular registry in the case of you using an npm proxy cache. Or am I missing something.

Shorter urls for github

foo('1.0.0', url: 'foo/foo')
should be equivilant to
'foo'('1.0.0', url:'https://github.com/foo/foo')

angular2 transitive dependencies and eachFile

Hi Craig,

Thanks for working on this! Once you get it finished it should go in the Grails angular-profile.

I'm trying to install angular2 in a Grails 3.1.4 app using the snippet below along with version 0.5.0 of your plugin. Unfortunately, it also installs the transitive dependencies, and I need to do those individually. Am I doing something wrong, or will this work in a newer release? I see you're up to 1.0.0-SNAPSHOT.

clientDependencies {
    installDir = 'grails-app/assets/npm'

    npm {
        'angular2'('2.0.0-beta.14') {
            include 'src/**/*.js'
            exclude '**/*.ts'
            transitive false
            into 'javascripts/' 
        }
    }
}

Also, I couldn't get into or the eachFile closure to work. For example, I wanted to have the angular files in grails-app/assets/npm/javascripts/angular2, but they end up in grails-app/assets/npm/angular2/javascripts/angular2.

I suspect I'm misusing the closure technique, but I assumed it would accept the same properties as the simpler method.

Thanks again,

Ken

Couldn't resolve dependency iron-autogrow-textarea@PolymerElements/iron-autogrow-textarea#^1.0.0 for PolymerElements/paper-input

Hi Craig, thanks for an awesome plugin.

I'm trying to include PolymerElements/paper-input from GitHub as a bower module but the clientInstall task fails on a dependency.

My build.gradle contains:

clientDependencies {
    bower {
        'PolymerElements/paper-input'('1.0.0') { source '*' }
    }
}

Upon running clientInstall I get the following error:

Execution failed for task ':clientInstall'.
> com.craigburke.gradle.client.registry.core.DependencyResolveException: Couldn't resolve iron-autogrow-textarea@PolymerElements/iron-autogrow-textarea#^1.0.0

The bower.json for PolymerElements/paper-input contains:

"dependencies": {
    "polymer": "Polymer/polymer#^1.2.0",
    "iron-autogrow-textarea": "PolymerElements/iron-autogrow-textarea#^1.0.0", // <--
    "iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
    "iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
    "iron-input": "PolymerElements/iron-input#^1.0.0",
    "paper-styles": "PolymerElements/paper-styles#^1.1.4",
    "iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0"
}

Thankful for any help on this issue!

/Johannes

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.