Coder Social home page Coder Social logo

gradle-node-plugin's People

Contributors

abelsromero avatar bjornmagnusson avatar datallah avatar dougborg avatar halfninja avatar janario avatar janrotter avatar jmcampanini avatar jochenberger avatar johnrengelman avatar kaitoy avatar konrad-garus avatar lanwen avatar madmas avatar mark-vieira avatar nmalaguti avatar retlat avatar s0x avatar stianl avatar tspaeth avatar zeroows 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 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

gradle-node-plugin's Issues

Using different version of npm / Release for 0.7

Hi,

Firstly, thanks for this plugin - it is fantasically useful.

I am struggling with npm at the moment, as due to npm/npm#5920 I need to use npm 2.1.3+...

Is there a way to get this to work using the version 0.6 of the plugin, or is there a release date for 0.7 which seems to natively provide for selecting an npm version?

Thanks!!

James

NodeTask.setEnvironment() does not work properly in download=true mode

Hello,

Since those changes :
8b4b26b

The this.environment variable is automatically set when using download=true.
This prevents the configuration of a custom environment.

NodeExecRunner should merge any configured environment and only ensure it's nodeBinDirPath is included in the PATH without overriding it completely.

Maybe something like this :

            def nodeBinDirPath = this.variant.nodeBinDir.getAbsolutePath()

            def nodeEnvironment = this.environment
            if (nodeEnvironment == null) {
                 nodeEnvironment = [:]
                 nodeEnvironment << System.getenv()
            }

            // Take care of Windows environments that may contain "Path" OR "PATH" - both existing
            // possibly (but not in parallel as of now)
            if (nodeEnvironment['Path'] != null) {
                nodeEnvironment['Path'] = nodeBinDirPath + File.pathSeparator + nodeEnvironment['Path']
            } else {
                nodeEnvironment['PATH'] = nodeBinDirPath + File.pathSeparator + nodeEnvironment['PATH']
            }
            this.environment = nodeEnvironment

Thank you.

Olivier

NpmTask doesn't have feature parity with NodeTask

NpmTask doesn't provide the methods to set the execOverrides.

Additionally the NpmExecRunner.doExecute() creates a new NodeExecRunner, so when adding the values to NpmTask, make sure to pass them along to the constructed NodeExecRunner

No such property: nodeModulesDir / unchangeable gulp/grunt-plugin path afterwards

Hey. I copied node extension block settings and gradle.build fails with error:

No such property: nodeModulesDir for class: com.moowork.gradle.node.NodeExtension_Decorated

Right after:

node {
    ...
    nodeModulesDir = file("${project.projectDir}/../something")
}

While workDir works fine

    workDir = file("${project.buildDir}/nodejs")

Edit:

I noticed that it seems to work in the 0.10-SNAPSHOT but I stumbled upon another issue.
When I change nodeModulesDir directory path, gradle-gulp/grunt plugins will fail because of gulp/grunt paths in src/main/groovy/com/moowork/gradle/gulp/GulpTask.groovy

private final static String GULP_SCRIPT = 'node_modules/gulp/bin/gulp.js';
...
def localGulp = this.project.file( GULP_SCRIPT )

Cheers

Question: Why task rules vs. concrete tasks?

I was just wondering what your take on this was. I was initially very attracted to task rules in a lot of my Gradle work. I later found that I usually already knew exactly what tasks I needed to create so it was pretty easy to adjust the rule to actually create a concrete task. This is nice from a user perspective because then gradle tasks gives you more info, you can use the short-hand camel-casing stuff, etc.

Specifically related to the gradle-node-plugin, I could see creating concrete tasks based on the output of npm --help or even a static list maintained in the plugin. This concept would also apply to the gradle-grunt-plugin you maintain. Let me know what you think.

Add default input/output's for NpmTask

Add default input/output's for NpmTask so we do not need to specify it on every npm_* action like this:

npm_update {
    inputs.file 'package.json'
    outputs.dir 'node_modules'
    args = ['--production', '--loglevel', 'warn']
}

Remove deprecated plugin name

Remove deprecated plugin name 'node'. Full name 'com.moowork.node' should be used. Right now it's using both names. Also update the documentation.

Blank space in Windows user path leads to error

Hi,
I have a blank space in my Windows user name and I am getting an error with the following stacktrace:

Caused by: org.gradle.process.internal.ExecException: Process 'command 'cmd'' finished with non-zero exit value 1
        at org.gradle.process.internal.DefaultExecHandle$ExecResultImpl.assertNormalExitValue(DefaultExecHandle.java:365)
        at org.gradle.process.internal.DefaultExecAction.execute(DefaultExecAction.java:31)
        at org.gradle.api.internal.file.DefaultFileOperations.exec(DefaultFileOperations.java:151)
        at org.gradle.api.internal.project.AbstractProject.exec(AbstractProject.java:780)
        at org.gradle.api.internal.project.AbstractProject.exec(AbstractProject.java:776)
        at org.gradle.api.Project$exec$8.call(Unknown Source)
        at com.moowork.gradle.node.exec.ExecRunner.run(ExecRunner.groovy:43)
        at com.moowork.gradle.node.exec.NodeExecRunner.doExecute(NodeExecRunner.groovy:29)
        at com.moowork.gradle.node.exec.ExecRunner.execute(ExecRunner.groovy:73)
        at com.moowork.gradle.node.exec.ExecRunner$execute.call(Unknown Source)
        at com.moowork.gradle.node.exec.NpmExecRunner.doExecute(NpmExecRunner.groovy:37)
        at com.moowork.gradle.node.exec.ExecRunner.execute(ExecRunner.groovy:73)
        at com.moowork.gradle.node.exec.ExecRunner$execute.call(Unknown Source)

I have tried Release 0.9 and the latest 0.10-SNAPSHOT

Thanks in advance for your help!

VariantBuilderTest fails in windows

Due to some hardcoded path separators, VariantBuilderTest fails when executed in a Windows environment.
I have fixed this in my fork, but I'm not sure how to send it because I've seen that Travis is integrated to publish artifacts directly on everybuild.

Do you want me to send the PR anyway?

Cannot use workDir with spaces in path

If using a workDir with spaces in the path, such as C:\Issue Test\work, when trying to use an NpmTask to install, we get the error
'C:\Issue' is not recognized as an internal or external command, operable program or batch file.

Config and task looks as follows:

node {
    distBaseUrl = 'http://nodejs.org/dist'
    download = true
    workDir = file("C:/Issue Test/work")
}
task npmInstallTask(type: NpmTask) {
    args = ['install'] 
}

avoid npmInstall task

So if I create an npm task:

npm_update {
args = ['--production', '--loglevel', 'warn']
}

How can I specify the tasks input/output, to use the up to date tasks are not run feature of gradle?

Thanks,

64-bit versions of windows use 32-bit node.exe

The exeDependency for Windows always pulls in the 32-bit node.exe even when running a 64-bit version of windows.

I created PR #46 which will pull in the 64-bit version of node.exe when running 64-bit versions of Windows.

The specific nuisance this issue causes if you use node-sass, the node-sass installer looks at the process architecture to determine which libsass binding to install, and if I've already installed node-sass manually through an 'npm install' that will have installed the 64-bit binding in node_modules, and that will generate errors when gradle-node-plugin tries to run it with node.exe*32.

NoClassDefFoundError: ShortTypeHandling

Version 0.6 of the plugin throws that exception when run with gradle 1.x.
See:
http://glaforge.appspot.com/article/groovy-2-3-5-out-with-upward-compatibility?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+glaforge+%28Guillaume+Laforge%27s+blog+feed%29

If nothing else, the documentation could mention the additional dependency required.

However I believe it is also possible to build and release the jar with gradle 1.12, then the plugin should still work fine with both gradle1 and gradle2, and your users will not be affected.

Globally installed NPM is not used when running with download=false

Hello,
I'm trying to run my gradle-node-plugin with such configuration:
node {
download = false
}
I assume globally installed Node and NPM will be used. But I see such exception:
:project:nodeSetup SKIPPED
:project:npmSetup SKIPPED
:project:npmInstall
module.js:338
throw err;
^
Error: Cannot find module 'D:\project\node_modules\npm\bin\npm-cli.js'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:278:25)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
:project:npmInstall FAILED

FAILURE: Build failed with an exception.

Seems path to NPM is hardcoded to %wordingDir%\node_modules\npm\bin\npm-cli.js

SetupTask's "ext" property causes naming conflicts

The SetupTask currently has a property named ext of type NodeExtension. The name ext is probably a bad idea since Gradle developers will expect ext to be an ExtraPropertiesExtension based on http://www.gradle.org/docs/current/dsl/org.gradle.api.plugins.ExtraPropertiesExtension.html.

Even worse, the standard way of adding a property (or method) to a task is with a statement like task.ext.myProperty = 'myValue', but if a developer of plugin tries to do this, they will get a NullPointerException because ext starts out null.

Clarify documentation intro on default behavior

I spent 30 minutes trying to figure out why this plugin would not download node. The nodeSetup task was always being skipped. I had to add the node{download=true} to my buildscript.

The root "issue" was for me, was the documentation in the first paragraph made it sound like download=true was the default behavior. I had to dig through the code as to why and find that download=false is the default.

I suggest that the documentation clarify this, or (possibly better) the default is changed to true.

Thanks.

Expose node task's execResult

The node task should expose it's execResult as the Gradle Exec task does.

Use case: I want to ignore the exit value of some of my node-based test tasks (i.e. ignoreExitValue = true), but retrieve their actual success/failure status via execResult.exitValue.

Thanks,
Lance

Use user .gradle directory for cache

Use user .gradle directory for cache instead of current directory. It should be cached with the node/npm version number like this:

<user.home>/.gradle/node/node-vxx/
<user.home>/.gradle/node/npm-vxx/

This allowes for caching between node projects.

Node tasks should honour workDir property

Setting the workDir property on the node object doesn't also set the workingDir property on the default node tasks (such as npmInstall). This results in npm looking for my package.json in the directory of the project I'm running from rather than in my working directory. I've had to work around it by making a task npmInstallCustom as follows:

task npmInstallCustom(type: NpmTask) {
    execOverrides {
        it.workingDir = nodeBuildDir
    }

    setArgs( ['install'] )

    inputs.file { file("$nodeBuildDir/package.json") }
    outputs.dir { file("$nodeBuildDir/node_modules") }
}

Additionally the inputs file defined for the NpmInstallTask is a (possibly non-exstient) package.json in the project directory. Line 18 of NpmInstallTask.groovy reads:

getInputs().file( new File( this.project.getProjectDir(), 'package.json' ) )

It'd be good if the NpmInstallTask (and perhaps all NodeTasks or all NpmTasks?) defaulted its/their exec working directory and inputs directory to the working directory set on the node object.

(I've raised a similar issue with the grunt plugin.)

nodeSetup conflicts in multi-project build

In a multi-project Gradle build where 2 conditions are met:

  1. Multiple projects apply the 'node' plugins &
  2. Gradle parallel build mode is activated

The nodeSetup task can error because multiple instances of it could run at the same time. The tasks collide because they both try to extract to the same destination directory.

I've fixed this in my build by applying the plugin to the root project and then configuring all my tasks to depend on nodeSetup in the rootProject and then disabling the nodeSetup in each child project.

This ensures that in any given build there is only 1 nodeSetup that tries to run.

Unsupported OS: freebsd

Sorry if this not related to this repo, but I just can't figure out where to dig further.

$ ./gradlew npmInstall

FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':nodeSetup'.
> Unsupported OS: freebsd

* 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: 4.971 secs

My build.gradle is:

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }
    dependencies {
        classpath('org.springframework.boot:spring-boot-gradle-plugin:1.2.0.RELEASE')
        classpath('com.moowork.gradle:gradle-node-plugin:0.8')
        classpath('com.moowork.gradle:gradle-grunt-plugin:0.6')
        classpath('be.filipblondeel.gradle:gradle-gulp-plugin:0.1')
    }
}

Os is FreeBSD 9.

npm setup should set PATH to point to version of node

gradle-node-plugin v0.7

On a system without any version of node installed in the path, and specifying npmVersion, npmSetup will fail for some modules. It seems that these modules require running node, which isn't in the path.
You will need to remove node_modules if you switch between specifying the npmVersion and not..

Here is a minimal example:

package.json
{
"name": "example",
"description": "ex",
"author": "time4tea",
"dependencies": {
"safefs": "3.1.1"
}
}

build.gradle
apply plugin: 'node'

task wrapper(type: Wrapper) {
gradleVersion = '2.1'
}

node {
version = "0.10.33"
npmVersion = "2.1.6"
download = true
}

buildscript {
repositories {
jcenter()
mavenCentral()
}
dependencies {
classpath group: 'com.moowork.gradle', name: 'gradle-node-plugin', version:'0.7'
}
}

group = "net.time4tea.example"

npmInstall {
def bob = [:]
bob << System.getenv();
bob["PATH"] = bob["HOME"] + "/.gradle/nodejs/node-v0.10.33-linux-x64/bin:" + System.getenv('PATH')
// uncomment the next line to make me work...
//environment bob
}

Running the examples:

without path hack

rm -rf node_modules && ./gradlew npmInstall
:nodeSetup UP-TO-DATE
:npmSetup SKIPPED
:npmInstall
npm WARN package.json example@ No repository field.
npm WARN package.json example@ No README data

[email protected] preinstall /home/jrichardson/work/test/node_modules/safefs
node ./cyclic.js

sh: 1: node: not found

with path hack

:nodeSetup UP-TO-DATE
:npmSetup SKIPPED
:npmInstall
npm WARN package.json example@ No repository field.
npm WARN package.json example@ No README data

[email protected] preinstall /home/jrichardson/work/test/node_modules/safefs
node ./cyclic.js

[email protected] node_modules/safefs
└── [email protected]

BUILD SUCCESSFUL

Difficult to configure tasks that dependOn npmInstall task

Trying to do this in a build doesn't work:

apply plugin: 'grunt'
task mygrunt(type: GruntTask, dependsOn: npmInstall)

The error is that the npmInstall tasks doesn't exist at that point (which it doesn't). This because the task is being created in a project.afterEvaluate {} in the plugin.

The problem is workaround by applying the dependency within an afterEvaluate:

apply plugin:'grunt'
task mygrunt(type: GruntTask)
project.afterEvaluate {
   mygrunt.dependsOn npmInstall
}

But this isn't very clear to do.

How to prevent a NodeTask from failing the build (CI)

I have set up protractor-tests for our angular projects.
On jenkins the gradle script uses gradle-node-plugin to run the protractor tests.

task update_webdriver(type: NodeTask){
    script = file('node_modules/protractor/bin/webdriver-manager')
    args = ['update']
    npmInstall.dependsOn 'protractor_copy'
}
update_webdriver.dependsOn 'npmInstall'

task protractorTests(type: NodeTask) {
    script = file('node_modules/protractor/bin/protractor')
    args = ['protractor-conf.js']
    ignoreExitValue = false
}
protractorTests.dependsOn 'update_webdriver'

This is quite fast, but the problem I got: when a test fails, the gradle-job fails and is shown as error on jenkins (red), but I want it to behave like junit-tests where failing tests only makes the build UNSTABLE (yellow).
I already asked at Protractor(1178), I can change the status code Protractor returns on test-failure, but returning code 0 when all tests run but with failures is maybe not the correct solution. Is there a non-zero code where the gradle-task still succeeds? Or how to configure it to behave as desired?

create symlink for node binary in predictable locatin

In order to use a brunch.io for client-side web-application build (wich is part of the bigger gradle build) i'd love to create a small shell script wich looks like
~/.gradle/nodejs/node-v0.10.22-darwin-x64/bin/node "node_modules/brunch/bin/brunch" "$@"

The only problem so far that it is not portable: this path to node is platform-dependant and will fail on CI machine with Linux.

I wonder if an option can be added to this plugin configuration inside a build.gradle which handles a symlink creation in some plaftorm-independent location under ~/.gradle/nodejs/

node {
   symlink = true
   //or path inside ~/.gradle/nodejs/
   symlink = "bin/node"
}

I'm not that proficient with Groovy\gradle yet but this seems not a hard task so i could implement this if somebody show a direction to go.

Plugin on Windows attempts to download Linux version

The VariantBuilder will attempt to call

getTarGzDependency( 'linux', 'x86' )

if the variant is for Windows.

I think when the refactoring was done in 590fab4 that the code should have been

if ( !variant.windows) {

or reverse the code inside the conditionals around. Even the unit test in VariantBuilderTest seems to be wrong. There is no way you should grab the linux build if the property is Windows!

Align NodeTask interface to bettter match up with Exec / JavaExec

Right now the NodeTask task interface is a bit different than the interface on the standard Exec task. While I understand the implementation details behind these differences, I think it would be possible to have the NodeTask interface better match up with the standard Exec interface.

The main sticking points I have noticed so far:

  1. You have to use the execOverrides closure to set environment and other exec details rather than just having those attached to the main task definition / configuration closure.
  2. You have to assign args via the property args = ['an', 'array', 'of', 'arguments'] instead of a method args 'a', 'list', 'of', 'method', 'arguments'

There may be others - let me know what you think.

v0.10 nodeModulesDir does work

buildscript {
    repositories {
        mavenLocal()
        jcenter()
    }
    dependencies {
        classpath('com.moowork.gradle:gradle-node-plugin:0.10')
        classpath('com.moowork.gradle:gradle-grunt-plugin:0.6')
    }
}

apply plugin: 'com.moowork.node'
apply plugin: 'grunt'

node {
    // Version of node to use.
    version = '0.10.33'

    // Version of npm to use.
    npmVersion = '2.1.12'

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

    // If true, it will download node using above parameters.
    // If false, it will try to use globally installed node.
    download = true

    // Set the work directory for unpacking node
    workDir = file("${project.buildDir}/nodejs")

    // Set the work directory where node_modules should be located
// not available in 0.9
    nodeModulesDir = file("${project.projectDir}/foo")
}
ls -a foo/
.   ..

define proxy

Hello

I have to define a proxy for node. How i can configure that within this plugin?

Thanks

Broken output in console

Hello,

First of all let me thank you for the great plugin. As for the issue we are having is on Windows. When we execute any npm or node task, the output in the console seems to be getting prefixed with empty spaces on each line until it starts to look very strange. I tried this on default cmd and conemu and both are showing the same. Here is some of my output:

image

I couldn't find anything special in the source code that was causing this. Any ideas?

Thanks.

Deprecate download flag (useGlobalNode)

Deprecate download flag and introduce useGlobalNode instead. If this is true, then it will use global installed node (that is in path) instead of downloading node.

Add npmVersion to the plugin configuration DSL.

As referenced in #26:

Feature Specification

Add a new option that specifies the npmVersion:

node {
    version = '0.10.32'
    npmVersion = '1.4.26'
    download = true
}
  • If the version of npm is unset and download = true, NpmTasks shall use version of npm bundled with the version of node Gradle is going to manage for you.
  • Configuring a valid version of npm in the configuration closure shall install npm locally in the project's node_modules directory so different projects may configure different npmVersions.

Implementation Notes / Questions:

@srs, what would be your preference on how to handle the automatic installation of npm if npmVersion is configured?

Should I create a separate NodeTask called setupNpm and add it as an additional dependency of all the NodeTasks? I figured that may get tricky since it would be a NodeTask itself.

My other thought was to just make installing npm locally part of the SetupTask after the node distribution is extracted, but I think that would mean you would only get the npmVersion management feature if you have download set to true. Let me know if you have other ideas.

Publish SNAPSHOTs to jCenter.

Hey @srs, I think we chatted about this a while back, but it would be great to get SNAPSHOTs for this project and the grunt/gulp plugins published to jCenter.

I just set this up for the https://github.com/ReadyTalk/gradle-readytalk-js project just a few days ago, so you can look at that as an example if you want. I just had to install the travis gem and encrypt my username and api_key for bintray in the travis.yaml file:

gradle-node-plugin $ travis encrypt --add BINTRAY_USER=srs
gradle-node-plugin $ travis encrypt --add BINTRAY_KEY=srs_aPi_KeY

I just use the env variables directly in my build.gradle instead of passing them as properties, but setting properties with the env variables would work too:

language: groovy

jdk: oraclejdk7

env:
  global:
  - secure: QKGE85X6NL+kX0a9R989zwNDouUYac8MYtkfI9BBS8teBYJBMc/QSYjAGXZPOJR/VFaXFOTDwteYA08vIGKi5ASNJunOeHkCpyYUgxUQRj/NdwGs+c0z+raeS/L5UdAmRlCeZfmPe19HNXvW95plTLf5pv3VyRsENSQJkO1yJJk=
  - secure: FdV94loU+g9w+rU5EeCQbYrxpxURvZokdWNqe/NjbfKYf7u0VaEjcVqVttTA13fkd6N31sGE1c9hXnAAQ+zSMtxr37rGDkIA3GotwDObifPs1awLoeR7kLt56U2BLyS8BkSD1HiLMxHAaJ9NUBLvqkGajzHAEQOBF4tx0rZ3jcI=

script: ./gradlew ci

Add easy way to use gradle-managed node / npm binaries outside the gradle build.

First of all, thanks so much for this plugin. It has helped me greatly in the past week.

One thing that seems to be a bit of a pain for developers used to using node / npm tasks directly is that it is hard to invoke the same versions of node / npm used in the gradle build outside of gradle.

There are probably a few different ways to solve this, but I thought these two were worth consideration:

  1. Have the nodeSetup task create some links / shell scripts in the root of the project that can tie back to the appropriate node binaries in ~/.gradle/nodejs (or where ever they have that configured in the node {} closure).
  2. Delegate the management of node binaries to a tool that already does that well (https://github.com/creationix/nvm)

customize where the node_modules directory lives

I am trying to use this plugin to enable us to run jasmine tests on a project which not only includes js, but java as well. I think I will be successful, but I wish I were able to customize where the node_modules directory lives as I am able to customize where the node binaries live via node{ workingDir = file('someLocation')}.

I've seen references to lines like:

 outputs.dir file('node_modules')

but that line appears to have no effect when I change 'node_modules' to a different value.

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.