Giter VIP home page Giter VIP logo

sonarqube-licensecheck's Introduction

SonarQube License-Check

Sonarcloud Status

This SonarQube plugin ensures that projects use dependencies with compliant licenses. All dependencies and licenses can be viewed per projects and exported to Excel 2003 XML Format. This enables a simple governance of dependencies and licenses for the whole organization.

License

This software is licensed under the Apache Software License, Version 2.0

Table of Contents

Features

Analysis

The plugin scans for dependencies defined in your project including all transitive dependencies.

Currently, supported formats are:

  • Maven POM files - all dependencies with scope "compile" and "runtime" are checked

  • Gradle projects which use JK1 plugin

  • NPM package.json files - all dependencies (except "devDependencies") are checked

    • Note that transitive dependencies are not scanned unless licensecheck.npm.resolvetransitive is set to true.

      Transitive

Project Dashboard

The plugin contains a project dashboard showing a list of dependencies with version and a list of all used licences. Each table shows the status of the license (allowed, not allowed, not found). You can also export the data to Excel.

Project Dashboard

Compatibility

This plugin is compatible:

  • 6.x version with 9 LTS (>= 9.5) and 10.x
  • 5.x version with 8.9 LTS and < 10 (9.x is compatible)
  • 4.x version with SonarQube 8.x

For all changes see CHANGELOG.md

Installation

Put the pre-built jar-file (from release downloads) in the directory $SONARQUBE_HOME/extensions/plugins and restart the server to install the plugin. Activate the rules of this plugin ("License is not allowed", "Dependency has unknown license") in your SonarQube quality profiles - otherwise the plugin is not executed.

Configuration

After booting the SonarQube Server with the License-Check Plugin be found in the tab Administration or also in the Configuration -> LicenseCheck drop down menu.

Configuration via Administration Tab

  • Within the General Settings and License Check you find the settings for the plugin.

  • Within the general settings the plugin can be manually enabled or disabled. By default, it is enabled.

    • Under "Dependency Mapping" you can map a dependency name/key (with regex) to a license, e.g. ^asm:asm$ to "BSD-3-Clause"

    • Under "License Mapping" you can map a license name (with regex) to a license, e.g. .*Apache.*2.* to "Apache-2.0".

      License Configuration1

    • Under "Licenses" you can allow or disallow licenses globally and add/edit the list of known licenses.

      License Configuration2

    • Under "Project Licenses" you can allow and disallow licenses for a specific project.

      License Configuration2

Configuration via License Menu

Administration -> Configuration(dropdown) -> License Check

alternative License Configuration1

  • Under "Licenses" you can allow or disallow licenses globally and add/edit the list of known licenses.

    alternative License Configuration2

    alternative License Configuration3

  • Under "Project Licenses" you can allow and disallow licenses for a specific project.

    alternative License Configuration4

    alternative License Configuration5

  • Under "Dependency Mapping" you can map a dependency name/key (with regex) to a license, e.g. ^asm:asm$ to "BSD-3-Clause"

    alternative License Configuration6

    alternative License Configuration7

  • Under "License Mappings" you can map a license name (with regex) to a license, e.g. .*Apache.*2.* to "Apache-2.0".

    alternative License Configuration8

    alternative License Configuration9

Activation rules in Quality Profile

You have to activate the new rules in a (new) quality profile, for each supported language (Groovy, Kotlin, Java, JavaScript, TypeScript) And you have to use this profile for your project.

  1. Step 1

    activate 1

  2. Step 2

    activate 2

  3. Step 3

    activate 3

  4. Step 4

    activate 4

  5. Step 5

    activate 5

  6. Step 6

    activate 6

  7. Step 7

    activate 7

Execution

When a project is analyzed using the mvn sonar:sonar in command line the extension is started automatically.

Please make sure to have all dependencies installed before launching the SonarQube analysis. So your complete build should look something like this:

mvn -B org.jacoco:jacoco-maven-plugin:prepare-agent install org.jacoco:jacoco-maven-plugin:report
mvn -B sonar:sonar

Supported Languages

Groovy, Kotlin, Java, JavaScript, TypeScript

Supported Project Types

Maven + NPM

When using Maven and a Javascript Package Manager, define the sonar.sources property to point to the files which contain dependency information.

...
<properties>
  <sonar.sources>pom.xml,package.json</sonar.sources>
<properties>
...

Maven

Maven works if your project/module has a pom.xml on its root level (running with Maven, Gradle or SonarScanner).

NPM

NPM works if your project/module has a package.json on its root level (running with Maven, Gradle or SonarScanner).

Gradle

Gradle project should use JK1 plugin https://github.com/jk1/Gradle-License-Report

Note: Please check above link for instructions or follow as mentioned below

Step1: Update build.gradle file with following code for using JK1 plugin

import com.github.jk1.license.filter.LicenseBundleNormalizer
import com.github.jk1.license.render.JsonReportRenderer

plugins {
  id 'com.github.jk1.dependency-license-report' version '1.13'
}

licenseReport {
    allowedLicensesFile = new File("$projectDir/src/main/resources/licenses/allowed-licenses.json")
    renderers = new JsonReportRenderer('license-details.json', false)
    filters = [new LicenseBundleNormalizer()]
}

Step 2: Update build.gradle file with following code for using SonarQube plugin

plugins {
    id 'org.sonarqube' version "3.0"
}

jar {
    enabled = true
}

sonarqube {
    properties {
        property "sonar.host.url", "http://localhost:9000"
    }
}

Step 3: run following command to generate your report license-details.json in build/reports/dependency-license

> gradle generateLicenseReport

Step 4: run following command for SonarQube

> gradle sonarqube

Configuration via Sonar API

You can also use the Sonar API to configure the plugin.

Plugin Activation

  • Get the setting

    curl -X GET -v -u USERNAME:PASSWORD "http://localhost:9000/api/settings/values?keys=licensecheck.activation"
    
  • Enable

    curl -X POST -v -u USERNAME:PASSWORD "http://localhost:9000/api/settings/set?key=licensecheck.activation&value=true"
    
  • Disable

    curl -X POST -v -u USERNAME:PASSWORD "http://localhost:9000/api/settings/set?key=licensecheck.activation&value=false"
    

Global License Settings

  • Get the setting
    curl -X GET -v -u USERNAME:PASSWORD "http://localhost:9000/api/settings/values?keys=licensecheck.license-set"
    

Project License Settings

  • Get the setting
curl -X GET -v -u USERNAME:PASSWORD "http://localhost:9000/api/settings/values?keys=licensecheck.project-license-set"

License Mapping

  • Get the setting

    curl -X GET -v -u USERNAME:PASSWORD "http://localhost:9000/api/settings/values?keys=licensecheck.license-mapping"
    

Dependency Mapping

  • Get the setting

    curl -X GET -v -u USERNAME:PASSWORD "http://localhost:9000/api/settings/values?keys=licensecheck.dep-mapping"
    

NPM Transitive setting

  • Get the setting

    curl -X GET -v -u USERNAME:PASSWORD "http://localhost:9000/api/settings/values?keys=licensecheck.npm.resolvetransitive"
    
  • Enable

    curl -X POST -v -u USERNAME:PASSWORD "http://localhost:9000/api/settings/set?key=licensecheck.npm.resolvetransitive&value=true"
    
  • Disable

    curl -X POST -v -u USERNAME:PASSWORD "http://localhost:9000/api/settings/set?key=licensecheck.npm.resolvetransitive&value=false"
    

sonarqube-licensecheck's People

Contributors

a-bertil avatar aaverkova avatar andreirinea avatar arran-nz avatar bananeweizen avatar chakrapanich avatar criztovyl avatar dependabot[bot] avatar derhecht avatar derkoe avatar flikkes avatar fvclaus avatar ivosh avatar janpopan avatar oliverlockwood avatar porscheinformatik-koc avatar rdsubhas avatar renovate[bot] avatar scuilion avatar tgwbean 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

sonarqube-licensecheck's Issues

sonar-maven-plugin analysis fails with NoClassDefFoundError

BUILD FAILURE
...
Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar (default-cli) on project XYZ: Execution default-cli of goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar failed: A required class was missing while executing org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar: com/hazelcast/util/collection/ArrayUtils
...
Caused by: java.lang.NoClassDefFoundError: com/hazelcast/util/collection/ArrayUtils
  at at.porscheinformatik.sonarqube.licensecheck.ValidateLicenses.lambda$checkSpdxLicenseWithAnd$5(ValidateLicenses.java:132)
  at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)

sonarqube: 7.6
sonarqube-licensecheck: v3.0.0-beta-2
maven: 3.3.9
jdk: 1.8.0_152
sonar-maven-plugin: 3.6.0.1398

Plugin 2.0x not scanning licenses with SonarQube v6.7.1 docker image

We are using SonarQube v6.7.1 alpine docker image to scan our current projects. Our plugin installation and server restart were successful.

We enabled the licenses globally by changing them to 'true' under configuration>license check option. And we activated the rules under quality profile. now when we scan any of Java, JavaScript, Maven projects that have LICENSE.md / LICENSE.txt file at root level in the repo, we don't see the 'Dependencies' and 'Licenses' table populated in Project dashboard > More > License check.

Are we supposed to enable any other configuration? or is there a format expected for licenses to be written in the .md/.txt files? Any help appreciated!

NullPointerException when executing on non-maven project with Sonar Runner

Caused by: java.lang.NullPointerException
at java.io.StringReader.<init>(StringReader.java:50)
at at.porscheinformatik.sonarqube.licensecheck.maven.MavenDependencyScanner.scan(MavenDependencyScanner.java:46)
at at.porscheinformatik.sonarqube.licensecheck.LicenseCheckSensor.analyse(LicenseCheckSensor.java:58)
at org.sonar.batch.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:58)
at org.sonar.batch.phases.SensorsExecutor.execute(SensorsExecutor.java:50)
at org.sonar.batch.phases.AbstractPhaseExecutor.execute(AbstractPhaseExecutor.java:83)
at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:192)

Most licenses not detected

Have been using https://www.mojohaus.org/license-maven-plugin/ to generate list of 3:rd party licenses example at https://hack23.github.io/cia/third-party-report.html .

But when using latest v3.0.0-beta-2 I get mostly "No License found for Dependency" : https://www.hack23.com/sonar/project/issues?id=com.hack23.cia%3Acia-all&resolved=false&rules=licensecheck%3Alicensecheck.unlisted&types=CODE_SMELL

Example "No License found for Dependency: com.amazonaws:aws-java-sdk-ec2" is detected as "The Apache Software License, Version 2.0" by maven-license-plugin but not by this plugin.

Have I missed something obvious ? When using license-maven-plugin, i actually have to specify license merges since a lots of project use different license string for the same project

<licenseMerges> <licenseMerge>GNU General Public License, version 2,with the Classpath Exception|GPLv2+CE|GPL2 w/ CPE|GNU General Public License, Version 2 with the Classpath Exception</licenseMerge> <licenseMerge>Common Public License|CPL</licenseMerge> <licenseMerge>Do What the Fuck You Want to Public License|WTFPL</licenseMerge> <licenseMerge>GNU Lesser General Public Licence (LGPL)|GNU Lesser General Public Licence|Lesser General Public License (LGPL)|GNU LESSER GENERAL PUBLIC LICENSE|GNU Lesser General Public License|LGPL</licenseMerge> <licenseMerge>GNU General Lesser Public License (LGPL) version 2.1|LGPL 2.1|GNU Lesser General Public License, Version 2.1</licenseMerge> <licenseMerge>The Apache Software License, Version 2.0|Apache License 2.0|Apache 2|Apache License, Version 2.0|Apache 2.0|Apache Software License - Version 2.0|Apache License, version 2.0|Apache License Version 2.0|ASF 2.0|AL 2.0</licenseMerge> <licenseMerge>The Apache Software License|Apache Software Licenses|ASL</licenseMerge> <licenseMerge>Eclipse Public License - Version 1.0|Eclipse Public License - v 1.0|Eclipse Public License (EPL), Version 1.0|Eclipse Public License 1.0</licenseMerge> <licenseMerge>Common Development and Distribution License (CDDL) version 1.0|Common Development and Distribution License (CDDL) v1.0|COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0|CDDL|Common Development and Distribution License</licenseMerge> <licenseMerge>Common Development and Distribution License (CDDL) version 1.1|CDDL 1.1</licenseMerge> <licenseMerge>The BSD License|BSD|BSD licence|BSD License</licenseMerge> <licenseMerge>Mozilla Public License Version 1.1|MPL 1.1</licenseMerge> <licenseMerge>The MIT License|MIT License|MIT license</licenseMerge> <licenseMerge>BSD style|dom4j|BSD-Style|BSD-Style License</licenseMerge> </licenseMerges>

Do I need to specify extra licenses if the exact string don't match for this plugin as well ?

All the best

Maven Dependencies do not take precedence over "auto determined" licence

prologue
we have a project that is using several components from the Jersey framework

  • com.sun.jersey:jersey-core
  • com.sun.jersey:jersey-client
  • com.sun.jersey.contribs:jersey-apache-client4

in maven these libs are labled with several licences (CDDL 1.1, GPL 1.1....)
see e.g.:

.... and actually all these lables are incorrect as the jersey project itself states that all components are licenced under EPL 2 / GPL 2)
see: https://jersey.github.io/license.html

In order to make the report correct again I now added a maven licence mapping via the administration ui of the plugin
image

issue

  • run a scan on such a project
  • expectation : these 3 components of jersey are reported as EPL 2 (as hopefully my explicit maven mapping takes precedence over the automatically determined license)
  • actual : these 3 components of jersey are reported as GPL 2
    image

context

  • sonarqube Community EditionVersion 7.7 (build 23042)
  • plugin version v3 beta 3

[Info] No licenses found for ...

This info is completly ignored in the report an at the ui:

[Info] 18:30:53.575 No licenses found for 'Indiana University Extreme! Lab Software License, vesion 1.1.1'
[Info] 18:30:53.590 No licenses found for 'Public Domain'

right?

So what happend with this pakages? There is nothing in the ui.

My testcase ist the software itself.

Not all licenses listed?

Thanks first of all for providing this plugin! It is exactly, what we were looking for.

I integrated both, v3.0.0-beta-4 and also the latest v3.0.0-rc1 into a SonarQube 7.6.

We have three quite large multi-module projects. One of them having more than 200 maven modules.
After invoking the analysis, there are a couple of licenses listed on the project's License Check overview. These licenses of all three status: Forbidden, Allowed, Unknown.

Only thing is, there should be way more licenses. An analysis using the license-maven-plugin showed about 500 licenses, whereas the sonarqube-licensecheck only lists about 50.
In addition it seems, that the number of listed licenses varies when running the analysis multiple times.
Is there any way I can debug this?

Thanks and all the best,
Frank

enhancement: provide metrics -> ready for quality gates

Hello,

first of all: THANK you for providing this awesome plugin that really already made my life easier big time in its current state :-)!!!!

While playing around with the plugin I wanted to define a quality gate in sonar so that projects with unknown or "not allowed" licences more visibly fail.
Unfortunately I had to find out that this does not seem to be supported in this plugin.

Proposal:

  • let the plugin yield 2 metrics
    • number of unknown licences
    • number of not allowed licences

With providing this 2 metrics projects could then set up corresponding Quality gates e.g. ("number of unknown licences > 0" -> fail).

This would help enforcing corresponding rules in the teams.

A similar approach is in place for e.g.
https://github.com/SonarSecurityCommunity/dependency-check-sonar-plugin

this plugin yields a full set of metrics that can be used in quality gates
image

known workaround

  • the license scanner reports unknown or not allowed licences as "blockers" so one could just set up a quality gate that fails at new or >0 blockers...but thats not very specific to licencing issues as blockers could also be caused by other types of issues

Thank you very much in advance for considering this requirements

Support for golang

Hello,
since we have had good experiences with the Licence Check, we would like to extend the analyses to even more projects. So we wanted to know if there are any efforts to support golang in the future?

Split rules to language "Java" and "JavaScript"

Currently both rules "Dependency has unknown license [license-check]" and "License is not allowed [license-check]" are under language Java even though NPM package.json is scanned.

We have to split the rules and assign the license issues to the corresponding language.

Licenses are not scanned correctly if Maven execution has `-B` or `--batch-mode` flag

Through much trial and error, I have discovered that licenses aren't scanned correctly (you just get licenses used by the first submodule) if you run Maven in batch mode e.g. mvn -B sonar:sonar instead of just mvn sonar:sonar.

This may have been the issue that was affecting people in tickets #34, #72.

I hope to find some time next week to look into the plugin code to see if it's something that can easily be fixed. If so I'll raise a PR to that effect; if not I'll raise a PR to note this in the documentation. In the meantime, I thought raising this issue might help others.

License is empty for Maven dependencies with classifier

When a module has a Maven dependency with a classifier then the licenses get not filled even though the license is set in the pom.xml and a valid license mapping is defined.

The classifier is displayed in the license check dashboard instead of the version.

Support for SonarQube 6.x

Support the 6.x versions of SonarQube (currently 6.7)

  • Adapt to 6.x API
  • Change the web API to be compatible with 6.x
  • Change the frontend to pure JS implementation

Broaden license scan usage to scan more type of files

Would be a great feature to open up this plugin so that more files types could be scanned, maybe configure which files from the UI in a similar way as the C++ (Community) plugin does.

Source code files:
.cpp, .c, .h. .hpp, cs, .js

Nuget packages:
.nuget, .nuspec

I've attached a screen shot of how the C++ (Community) plugin handles this.
image

Maven Dependecy Scanning not working in JDK 11 Maven Dependency Plugin >3.1

When running with JDK 11 and Maven Dependency Plugin >3.1 the dependency scanning fails with exceptions like this

[WARNING] Could not parse Maven POM \.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.8\jackson-module-parameter-names-2.9.8.jar -- module com.fasterxml.jackson.module.pom
java.io.FileNotFoundException: \.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.8\jackson-module-parameter-names-2.9.8.jar -- module com.fasterxml.jackson.module.pom (Could not find file)
        at java.base/java.io.FileInputStream.open0(Native Method)
        at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
        at at.porscheinformatik.sonarqube.licensecheck.maven.LicenseFinder.getLicenses(LicenseFinder.java:30)
        at at.porscheinformatik.sonarqube.licensecheck.maven.MavenDependencyScanner.lambda$loadLicenseFromPom$0(MavenDependencyScanner.java:183)
...

No way to scan submodules

As part of #22 , the support for submodules was removed. Unfortunately, that was a feature we depended on for the license check. After updating to 2.0.0 (non-beta) our builds no longer produce any output for this plugin. Would it be possible to make this a configurable value so that we can re-enable submodule traversal?

Configuration, filter for open and closed license type

Thanks for the plugin.
At a first glance i’m missing some filter for open and closed licenses.
Not everyone has a juristic background and in corporate environment you shouldn’t use a license that obliges to open source your code.

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

IllegalStateException: The web service 'api/licenses' is defined multiple times

I have recently set up a new Sonarqube instance and was excited to install the license check plugin for Sonarqube. Unfortunately, I'm seeing the following stack trace when attempting to deploy the license check plugin:

2017.10.19 20:36:09 ERROR web[][o.s.s.p.Platform] Background initialization failed. Stopping SonarQube
java.lang.IllegalStateException: The web service 'api/licenses' is defined multiple times
        at org.sonar.api.server.ws.WebService$Context.register(WebService.java:122)
        at org.sonar.api.server.ws.WebService$Context.access$300(WebService.java:102)
        at org.sonar.api.server.ws.WebService$NewController.done(WebService.java:160)
        at at.porscheinformatik.sonarqube.licensecheck.webservice.license.LicenseWs.define(LicenseWs.java:53)
        at org.sonar.server.ws.WebServiceEngine.<init>(WebServiceEngine.java:66)

The server configuration is attached. I'm not really sure what might be going on or how to determine what is already using the particular endpoint. Can you offer any insights?

sonar_system_info.json.zip

Support .NET & Nuget

Hello,
since we have had good experiences with the Licence Check, we would like to extend the analyses to even more projects. So we wanted to know if there are any efforts to support .NET with Nuget in the future?
If you like it, could we also participate in the development?
Many thanks in forwards!

Did "Using transporter WagonTransporter" work?

During the build stage Using transporter WagonTransporter works fine for us.
But it did not work for the licesencheck for me.

XXXXXX are replacements for internals.

build 01-Aug-2019 16:23:45 [WARNING] 16:23:45.850 Could not get dependency list via maven build 01-Aug-2019 16:23:45 [WARNING] 16:23:45.850 [ERROR] Some problems were encountered while processing the POMs: build 01-Aug-2019 16:23:45 The build could not read 1 project -> [Help 1] build 01-Aug-2019 16:23:45 build 01-Aug-2019 16:23:45 The project XXXXXXXX (C:\XXXXXXX\services\pom.xml) has 1 error build 01-Aug-2019 16:23:45 Non-resolvable parent POM for XXXXXXXX: Could not transfer artifact org.springframework.boot:spring-boot-starter-parent:pom:2.1.3.RELEASE from/to central (https://repo.maven.apache.org/maven2): sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target and 'parent.relativePath' points at wrong local POM @ XXXXXXXXXX, C:\XXXXXXXX\source\pom.xml, line 6, column 13 -> [Help 2] build 01-Aug-2019 16:23:45 build 01-Aug-2019 16:23:45 To see the full stack trace of the errors, re-run Maven with the -e switch. build 01-Aug-2019 16:23:45 Re-run Maven using the -X switch to enable full debug logging. build 01-Aug-2019 16:23:45 build 01-Aug-2019 16:23:45 For more information about the errors and possible solutions, please read the following articles: build 01-Aug-2019 16:23:45 [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException build 01-Aug-2019 16:23:45 [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException build 01-Aug-2019 16:23:45 build 01-Aug-2019 16:23:45 [DEBUG] 16:23:45.866 Saving depenencies for module [key=XXXXXXXXXXXXXX]: [] build 01-Aug-2019 16:23:45 [DEBUG] 16:23:45.866 Saving licenses for module [key=XXXXXXXXXXX]: [] build 01-Aug-2019 16:23:45 [INFO] 16:23:45.866 Sensor License Check [licensecheck] (done) | time=2706ms

Support sonar-scanner-maven > 3.3

The Maven dependency check does not work anymore with sonar-scanner-maven > 3.3. Seems like the new version does not set "sonar.maven.projectDependencies" anymore.

Maven application directory was not specified, and ${maven.home} is not provided in the system properties - sonarqube 7.4

hey,

sonarqube version: Community Edition Version 7.6 (build 21501)
licensecheck version: v2.0.1/sonarqube-licensecheck-plugin-2.0.1

we are running the plugin via the sonarqube scanner on jenkins and get the following error:

INFO: Sensor License Check [licensecheck]
WARN: Error reading file
java.lang.IllegalStateException: Maven application directory was not specified, and ${maven.home} is not provided in the system properties. Please specify at least on of these.
	at org.apache.maven.shared.invoker.MavenCommandLineBuilder.checkRequiredState(MavenCommandLineBuilder.java:124)
	at org.apache.maven.shared.invoker.MavenCommandLineBuilder.build(MavenCommandLineBuilder.java:59)
	at org.apache.maven.shared.invoker.DefaultInvoker.execute(DefaultInvoker.java:101)
	at at.porscheinformatik.sonarqube.licensecheck.maven.MavenDependencyScanner.readDependecyList(MavenDependencyScanner.java:114)
	at at.porscheinformatik.sonarqube.licensecheck.maven.MavenDependencyScanner.scan(MavenDependencyScanner.java:73)
	at at.porscheinformatik.sonarqube.licensecheck.LicenseCheckSensor.execute(LicenseCheckSensor.java:85)
	at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77)
	at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59)
	at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
	at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:408)
	at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:403)
	at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:360)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
	at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:126)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122)
	at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:73)
	at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67)
	at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
	at com.sun.proxy.$Proxy0.execute(Unknown Source)
	at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:185)
	at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:137)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:111)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:75)
	at org.sonarsource.scanner.cli.Main.main(Main.java:61)

INFO: Dependency sonarqube-scanner uses a not allowed licooense LGPL-3.0
INFO: Sensor License Check [licensecheck] (done) | time=82ms

is it required to have maven installed on the sonarqube instance?

Possibility to add ECCN information.

Along with the license information for a package we need to consider its ECCN classification.
Would it make sense to add support for this in the licensecheck plugin?
At least add a field when mapping maven dependencies?
Thanks!

By the way , great plugin! :-)

Supplied spdx_license_list.json contains data not matching the software.

After installing this plugin I get a row in my Sonarqube database - properties table - with the prop_key = licensecheck.licenses.
The text_value contains the json data for licenses, but the format does not seem to match what the plugin expects.
The data contains the 'osiApproved' property while the software seems to use 'status'.
In addition, the value in the database is interpreted as boolean as there is no double-qoutes in the data file. The program is expecting String not Boolean when parsing the json data from the database.
This causes an exception in the plugin when trying to display the licenses.

Cannot start sonarqube with plugin installed.

I am currently building a sonarqube docker image and was intending to use your plugin. The stack trace is below. I have attached the dockerfile.
Dockerfile.txt

sonarqube_1 | java.lang.IllegalStateException: The web service 'api/licenses' is defined multiple times
sonarqube_1 | at org.sonar.api.server.ws.WebService$Context.register(WebService.java:122)
sonarqube_1 | at org.sonar.api.server.ws.WebService$Context.access$300(WebService.java:102)
sonarqube_1 | at org.sonar.api.server.ws.WebService$NewController.done(WebService.java:160)
sonarqube_1 | at at.porscheinformatik.sonarqube.licensecheck.webservice.license.LicenseWs.define(LicenseWs.java:
53)
sonarqube_1 | at org.sonar.server.ws.WebServiceEngine.(WebServiceEngine.java:66)
sonarqube_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
sonarqube_1 | at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
sonarqube_1 | at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.jav
a:45)
sonarqube_1 | at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
sonarqube_1 | at org.picocontainer.injectors.AbstractInjector.newInstance(AbstractInjector.java:145)
sonarqube_1 | at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:342)
sonarqube_1 | at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractI
njector.java:270)
sonarqube_1 | at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:3
64)
sonarqube_1 | at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(Abst
ractInjectionFactory.java:56)
sonarqube_1 | at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
sonarqube_1 | at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
sonarqube_1 | at org.picocontainer.DefaultPicoContainer.instantiateComponentAsIsStartable(DefaultPicoContainer.j
ava:1034)
sonarqube_1 | at org.picocontainer.DefaultPicoContainer.addAdapterIfStartable(DefaultPicoContainer.java:1026)
sonarqube_1 | at org.picocontainer.DefaultPicoContainer.startAdapters(DefaultPicoContainer.java:1003)
sonarqube_1 | at org.picocontainer.DefaultPicoContainer.start(DefaultPicoContainer.java:767)
sonarqube_1 | at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:143)
sonarqube_1 | at org.sonar.server.platform.platformlevel.PlatformLevel.start(PlatformLevel.java:88)
sonarqube_1 | at org.sonar.server.platform.platformlevel.PlatformLevel4.start(PlatformLevel4.java:533)
sonarqube_1 | at org.sonar.server.platform.Platform.start(Platform.java:231)
sonarqube_1 | at org.sonar.server.platform.Platform.startLevel34Containers(Platform.java:205)
sonarqube_1 | at org.sonar.server.platform.Platform.access$500(Platform.java:46)
sonarqube_1 | at org.sonar.server.platform.Platform$1.lambda$doRun$0(Platform.java:119)
sonarqube_1 | at org.sonar.server.platform.Platform$AutoStarterRunnable.runIfNotAborted(Platform.java:391)
sonarqube_1 | at org.sonar.server.platform.Platform$1.doRun(Platform.java:119)
sonarqube_1 | at org.sonar.server.platform.Platform$AutoStarterRunnable.run(Platform.java:375)
sonarqube_1 | at java.lang.Thread.run(Thread.java:748)

SonarQube 7.7 with the plugin 3.0.0-Beta3 - no license rules

I installed the latest version of the plugin 3.0.0-beta3 on our SonarQube 7.7 and enabled the license scan, but could not find the license rules to enable for the license scan to work.
I ran the scan on our JS/NPM project and nothing is found(assuming the scan is not happening without those rules as mentioned in your docs) - Am I suppose to do anything in order to have those rules show up(so that I can enable them)?

Gradle Support added

Hi,

Great plugin, thanks for open sourcing it!
I have recently forked it and added basic gradle support. Are you interested in merging that feature into your repository?
You can find the sources here: https://github.com/xellsys/sonarqube-licensecheck
Some open points on my end:

  • In the process of gathering the gradle dependencies I'm currently executing gradle (or gradlew if available) via java process execution. I think taking leverage of the gradle tooling api would be the cleaner choice. The best way would be to access the classes in the context the plugin is being executed in - however I'm uncertain if that is even possible. I would need to get a reference to the current project instance.
  • For the gradle process I'm also adding the -I flag for additional init script support (if the sonarqube task was called with additional init scripts). I believe reusing all or selected flags would be beneficiary (eg: --build-file)
  • To support the package -> license and regex -> license association features I had to access MavenLicenseService and MavenDependencyService. This is functionally redundant to the code in MavenDependencyScanner. Ideally this should be moved to a shared package.
  • I have added a ScannerResolver class which dynamically recognises whether it's a gradle or maven project. I'm not 100% certain this is the best way to go.
  • I have added some tests, but was unable to perform extensive manual / regression tests.
  • A general remark: there are other plugins out there gathering more extensive license information by parsing license files and such. This would also be an improvement I'm currently looking into - although rather independent from the gradle support.

best regards,
Benny

Empty Project Dashboard in SQ7.7 & other issues with 3.0.0-beta-3

Hello,
we use SonarQube 7.7 and SonarQube License Check Plugin 3.0.0-beta-3 to check java licenses und dependencies. "License is not allowed", "Dependency has unknown license" is enabled.
The first problem is, that license check don't use the global license list settings and analyze only for the specific project license specification.
sq_license_Check_issues
Do we have to update the "License Check - Maven Dependencies" for each license?
Because we only find the dependencies which are registered in "License Check - Maven Dependencies":
grafik

Project Dashboard Issue:
We always have an empty project dashboard, but for the same project we get dependencies issue (upperimage).
grafik

Thank for your support

Maven dependency scanner includes sub-modules

The Maven dependency scanner calls "dependency:list" recursive - that means a module includes all dependencies from all sub-modules (event when sonar.skip is enabled for the module).

The scanner should call "dependency:list" with "non-recursive" enabled.

Help for run License Check for NPM modules

Hello,
we already use License Check for Java from bug #44 and now want to use LicenseCheck for our NPM projects as well.
How is Sonar Qube configured to have all the necessary information for LicenseCheck and run the analysis?
Currently, no package.json is uploaded to the code files with Sonar Qube.
Thank you very much for your help.

Specify alternative settings.xml file.

In my Jenkins jobs I sometimes have to use different settings.xml files.
The licensecheck plugin seems to look for the settings.xml file in $HOME/.m2 even when I tell maven to use another with the '-s' option.
It would be great if the plugin could pick up that file (-s to maven).
If not, perhaps add an to specify an alternative settings.xml file.
E.g. by specifying a command-line option to maven like: -Dlicensecheck.settings.file=$HOME/.m2/mysettings.xml

NPE when JSON in settings is not valid

Plugin Version 3.1-rc2 (and also others)
Sonar 7.6

I get a NPE. This happens with different repos .

29-Jul-2019 13:02:34 [INFO] 13:02:34.806 Sensor License Check [licensecheck] 29-Jul-2019 13:02:37 [WARNING] 13:02:37.312 Could not get dependency list via maven 29-Jul-2019 13:02:37 [INFO] ------------------------------------------------------------------------ 29-Jul-2019 13:02:37 [INFO] Reactor Summary: 29-Jul-2019 13:02:37 [INFO] 29-Jul-2019 13:02:37 [INFO] XXXX ........................................ FAILURE [01:13 min] 29-Jul-2019 13:02:37 [INFO] XXX .................................. SKIPPED 29-Jul-2019 13:02:37 [INFO] XXXX.......................... SKIPPED 29-Jul-2019 13:02:37 [INFO] ------------------------------------------------------------------------ 29-Jul-2019 13:02:37 [INFO] BUILD FAILURE 29-Jul-2019 13:02:37 [INFO] ------------------------------------------------------------------------ 29-Jul-2019 13:02:37 [INFO] Total time: 01:24 min 29-Jul-2019 13:02:37 [INFO] Finished at: 2019-07-29T13:02:37+02:00 29-Jul-2019 13:02:37 [INFO] Final Memory: 131M/1220M 29-Jul-2019 13:02:37 [INFO] ------------------------------------------------------------------------ 29-Jul-2019 13:02:37 [ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar (default-cli) on project de.bdr.goid: null: MojoExecutionException: NullPointerException -> [Help 1] 29-Jul-2019 13:02:37 org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar (default-cli) on project de.bdr.goid: null 29-Jul-2019 13:02:37 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:216) 29-Jul-2019 13:02:37 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153) 29-Jul-2019 13:02:37 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145) 29-Jul-2019 13:02:37 at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:116) 29-Jul-2019 13:02:37 at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:80) 29-Jul-2019 13:02:37 at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:51) 29-Jul-2019 13:02:37 at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128) 29-Jul-2019 13:02:37 at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:307) 29-Jul-2019 13:02:37 at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:193) 29-Jul-2019 13:02:37 at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:106) 29-Jul-2019 13:02:37 at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862) 29-Jul-2019 13:02:37 at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286) 29-Jul-2019 13:02:37 at org.apache.maven.cli.MavenCli.main(MavenCli.java:197) 29-Jul-2019 13:02:37 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 29-Jul-2019 13:02:37 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 29-Jul-2019 13:02:37 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 29-Jul-2019 13:02:37 at java.lang.reflect.Method.invoke(Method.java:498) 29-Jul-2019 13:02:37 at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289) 29-Jul-2019 13:02:37 at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229) 29-Jul-2019 13:02:37 at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415) 29-Jul-2019 13:02:37 at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356) 29-Jul-2019 13:02:37 Caused by: org.apache.maven.plugin.MojoExecutionException 29-Jul-2019 13:02:37 at org.sonarsource.scanner.maven.bootstrap.ScannerBootstrapper.execute(ScannerBootstrapper.java:67) 29-Jul-2019 13:02:37 at org.sonarsource.scanner.maven.SonarQubeMojo.execute(SonarQubeMojo.java:104) 29-Jul-2019 13:02:37 at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:134) 29-Jul-2019 13:02:37 at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:208) 29-Jul-2019 13:02:37 ... 20 more 29-Jul-2019 13:02:37 Caused by: java.lang.NullPointerException 29-Jul-2019 13:02:37 at org.glassfish.json.JsonObjectBuilderImpl$JsonObjectImpl.getString(JsonObjectBuilderImpl.java:196) 29-Jul-2019 13:02:37 at at.porscheinformatik.sonarqube.licensecheck.projectLicense.ProjectLicense.fromString(ProjectLicense.java:78) 29-Jul-2019 13:02:37 at at.porscheinformatik.sonarqube.licensecheck.projectLicense.ProjectLicenseService.getProjectLicenseList(ProjectLicenseService.java:32) 29-Jul-2019 13:02:37 at at.porscheinformatik.sonarqube.licensecheck.projectLicense.ProjectLicenseService.getProjectLicenseList(ProjectLicenseService.java:40) 29-Jul-2019 13:02:37 at at.porscheinformatik.sonarqube.licensecheck.license.LicenseService.getLicenses(LicenseService.java:39) 29-Jul-2019 13:02:37 at at.porscheinformatik.sonarqube.licensecheck.ValidateLicenses.getUsedLicenses(ValidateLicenses.java:53) 29-Jul-2019 13:02:37 at at.porscheinformatik.sonarqube.licensecheck.LicenseCheckSensor.execute(LicenseCheckSensor.java:106) 29-Jul-2019 13:02:37 at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:48) 29-Jul-2019 13:02:37 at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:85) 29-Jul-2019 13:02:37 at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:59) 29-Jul-2019 13:02:37 at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:77) 29-Jul-2019 13:02:37 at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:59) 29-Jul-2019 13:02:37 at org.sonar.scanner.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:82) 29-Jul-2019 13:02:37 at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136) 29-Jul-2019 13:02:37 at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122) 29-Jul-2019 13:02:37 at org.sonar.scanner.scan.ProjectScanContainer.scan(ProjectScanContainer.java:408) 29-Jul-2019 13:02:37 at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:403) 29-Jul-2019 13:02:37 at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:400) 29-Jul-2019 13:02:37 at org.sonar.scanner.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:400) 29-Jul-2019 13:02:37 at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:360) 29-Jul-2019 13:02:37 at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136) 29-Jul-2019 13:02:37 at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122) 29-Jul-2019 13:02:37 at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:126) 29-Jul-2019 13:02:37 at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:136) 29-Jul-2019 13:02:37 at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:122) 29-Jul-2019 13:02:37 at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:73) 29-Jul-2019 13:02:37 at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67) 29-Jul-2019 13:02:37 at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46) 29-Jul-2019 13:02:37 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 29-Jul-2019 13:02:37 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 29-Jul-2019 13:02:37 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 29-Jul-2019 13:02:37 at java.lang.reflect.Method.invoke(Method.java:498) 29-Jul-2019 13:02:37 at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60) 29-Jul-2019 13:02:37 at com.sun.proxy.$Proxy23.execute(Unknown Source) 29-Jul-2019 13:02:37 at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:185) 29-Jul-2019 13:02:37 at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:137) 29-Jul-2019 13:02:37 at org.sonarsource.scanner.maven.bootstrap.ScannerBootstrapper.execute(ScannerBootstrapper.java:65) 29-Jul-2019 13:02:37 ... 23 more 29-Jul-2019 13:02:37 [ERROR] 29-Jul-2019 13:02:37 [ERROR] 29-Jul-2019 13:02:37 [ERROR] For more information about the errors and possible solutions, please read the following articles: 29-Jul-2019 13:02:37 [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

Where is my mistake?

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.