Giter Club home page Giter Club logo

addlicense's Introduction

addlicense

The program ensures source code files have copyright license headers by scanning directory patterns recursively.

It modifies all source files in place and avoids adding a license header to any file that already has one.

addlicense requires go 1.16 or later.

install

go install github.com/google/addlicense@latest

usage

addlicense [flags] pattern [pattern ...]

-c      copyright holder (default "Google LLC")
-check  check only mode: verify presence of license headers and exit with non-zero code if missing
-f      license file
-ignore file patterns to ignore, for example: -ignore **/*.go -ignore vendor/**
-l      license type: apache, bsd, mit, mpl (default "apache")
-s      Include SPDX identifier in license header. Set -s=only to only include SPDX identifier.
-v      verbose mode: print the name of the files that are modified
-y      copyright year(s) (default is the current year)

The pattern argument can be provided multiple times, and may also refer to single files. Directories are processed recursively.

For example, to run addlicense across everything in the current directory and all subdirectories:

addlicense .

The -ignore flag can use any pattern supported by doublestar.

Running in a Docker Container

The simplest way to get the addlicense docker image is to pull from GitHub Container Registry:

docker pull ghcr.io/google/addlicense:latest

Alternately, you can build it from source yourself:

docker build -t ghcr.io/google/addlicense .

Once you have the image, you can test that it works by running:

docker run -it ghcr.io/google/addlicense -h

Finally, to run it, mount the directory you want to scan to /src and pass the appropriate addlicense flags:

docker run -it -v ${PWD}:/src ghcr.io/google/addlicense -c "Google LLC" *.go

license

Apache 2.0

This is not an official Google product.

addlicense's People

Contributors

benma avatar bradrydzewski avatar bryanloz-xilinx avatar crazy-max avatar fashing avatar ghanekaromkar avatar leilee avatar maruel avatar mbrukman avatar mco-gh avatar mithun avatar mjduijn avatar morgante avatar piotrsikora avatar pmeric avatar rotemreiss avatar sjswerdlow avatar srgbtl avatar talal avatar thefirstofthe300 avatar tomeraberbach avatar tpryan avatar tweksteen avatar verbanicm avatar willnorris avatar wzshiming avatar x1ddos avatar xorima avatar xuehaipan avatar yangjingzhou 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

addlicense's Issues

Support adding license header in .txt, .patch and .tmpl files

Hi, can addlicense support adding the license header to .txt, .patch and .tmpl files? Or is it intentional to not support these use cases?

We want to use addlicense to add the license header to various types of files automatically and we're willing to contribute if it is not a design decision to not support them.

Configuration file with configuration options

Would be nice for example to configure comment styles for different file extensions in a config file, instead of having to modify the source code. The config file could also be used to configure paths to ignore, or to configure the patterns that determine whether a file already has a license header.

Implementations of these features are included in the Nokia fork of addlicense. If you are interested in pulling only some parts, see the different branches there.

Using `//` comments for C++ header files

Hello :)

Currently .h files use /* style comments, and I'd like to contribute a way to use // comments instead. I presume just changing the default is not an option, so I'd like to ask what would be the most principled solution. A command line flag?

holder i.e the -c flag converts & to &

It looks like y'all are doing a conversion to print ampersand for an html file. I'm working in a plain text code base so this kind of conversion doesn't make much sense.

Year spans

Sometimes it's necessary to set a year span in the license header, e.g. "2010-2019", but it's only possible to pass integers. Any chance this feature could be added?

Ignore pattern?

Would be nice to have a way to specify ignore pattern(s) in form of regex applied to path of the file(from project's root(e.g. current directry for the tool)).

Customize License check string

License could have different formats. For Instance, instead of string "copyright" some licenses just has "(c)". As of now this plugin just checks for string "copyright".

return bytes.Contains(bytes.ToLower(b[:n]), []byte("copyright")) ||

it would be nice to have customize checks.

How does pattern work?

Hello there,

I'm using this on nancy, and more or less, great tool!

However, it's a bit too nuclear with the . pattern, and adding licenses to files that we need to exclude (primarily GitHub templates, but we also don't really need licenses on files that really don't have IP (Dockerfile, gorelease.yml, etc...), so I was looking at using the pattern to basically only check and apply to **/*.go files, and maybe a couple others here and there. There isn't really much documentation I can see on pattern, so I figured I'd ask about usage, and then send y'all a PR with it included in the README for other goofballs like myself!

Cheers!

Why use http:// for Apache 2.0 License

This tool right now adds a link with http:// for Apache 2.0 license

// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

but some of our internal tests check for https://. https://github.com/GoogleCloudPlatform/golang-samples/blob/73d60a5de091dcdda5e4f753b594ef18eee67906/license_test.go#L32

I know the license text itself uses http:// to apply the license, but should we switch to https://?

Can a new tag be added?

Hi maintainers,

There are couple of cool fixes since your last release, would you mind doing a new release?

Trailing whitespace

When licenses are added for files which prefix licenses with " * ", any empty lines end up generating trailing whitespace. This is undesirable and should instead be removed.

Add support for checking if the year is correct

  • Currently it only checks if the file has the license header and does not validate the year on the license
  • Would be nice to check if the year on the header matches the one passed in as the argument or the default one (current year)

Bug: Files generated by stringer are skipped

I've found that in recent versions of addlicense, any file generated by stringer is skipped or has its license comment striped, if present.

The files generated by strinnger have the following file header comments:

// Code generated by "stringer -type=EVENT"; DO NOT EDIT.

The "EVENT" value changes between files but the rest of the comment is standard. I suspect something in that comment is causing the file to be skipped by addlicense.

Unfortunately, it doesn't just skip those files, it actively strips the addlicense comment if you add it manually.

Add option to log modified files

This is a feature request: for a caller, it would be good to know if the execution modified any file (e.g., as part of a presubmit test). One option is to change the exit code if at least one file has been modified. Another option (I would recommend) is to add an option (for instance, -l) which will print all the filenames that have been modified (see discussion at golang/go#24230 for a similar idea).

Happy to send a PR for option 2, if likely to be merged. Thanks.

Allow for reading from stdin and writing to stdout.

addlicense currently always modifies source files in-place. This makes it difficult to use in scripts or integrate into other formatting tools, such as the fix Mercurial extension.

Since the filename is unknown when operating on content from stdin, this would entail adding an option to specify the filename to assume. For example, clang-format has an --assume-filename option for this purpose.

Recursive check pattern

I have many directories with go code. For the addlicence works, I have to do this:

docker run --rm -it -v ${PWD}:/src ghcr.io/google/addlicense \
       -check \
       -ignore "**/*.swagger.go" \
       -ignore "**/**/*.swagger.go" \
       */*/*.go
       **/**/**/**/**/**/*.go \
       **/**/**/**/**/*.go \
       **/**/**/**/*.go \
       **/**/**/*.go \
       **/**/*.go \
       **/*.go \
       *.go

Is there a better way only to check Golang code in any path? And ignore some file patterns in any path?

What version is the first release?

#83 adds support for publishing pre-built artifacts and docker image when git tags are pushed. The question now is, what version is the first tagged release? Is it v0.0.1, v0.1.0 or v1.0.0 ?

As @crazy-max noted in #83, we definitely want to follow semver on subsequent releases, but because there never has been a previous release, there are no real constraints on whether this is considered a v0 or v1 release.

Personally, I'm leaning toward v1.0.0. The tool has been around for a while and is quite stable. And it is also widely enough adopted by major projects (etcd, opentelemetry, kubeflow, kubernetes, ossf/scorecard among many others) that we need to treat the current API as stable, regardless of the lack of a formal v1.0 release.

@mco-gh what do you think?

Docker pull fails with permissions error

The readme has an example command using docker, but it fails

docker run -v ${PWD}:/go/src/app/ -it google/addlicense -c "Google LLC" *.go
docker pull google/addlicense

Using default tag: latest
Error response from daemon: pull access denied for google/addlicense, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

addlicense does not modify files when the copyright year changes

I have just found out that addlicense does not modify the copyright year if a license text is already present. Could it be extended to check whether the license text + copyright holder + year is actually present? Currently it is e.g. not possible to switch to a new license by re-running addlicense -l $new_license without having to delete all existing license texts or to bump the copyright year.

Fix empty year generated copyright

Currently if the year is set to empty string -y="" the first header will have two consecutive empty spaces between Copyright and Holder.

Now:
// Copyright[ ][ ]OpenTelemetry Authors

After:
// Copyright[ ]OpenTelemetry Authors

change style for java files from comment to javadoc

Hi,
From what I see for some reason license added to the .java files in comment style.
When addlicense tool supports the common style which is already applied to the ".c" files.

https://github.com/google/addlicense/blob/master/main.go#L216-L217
Would you accept the PR to change that style?

Example from Spring boot project (probably the most common case of the Java project)
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/OnEndpointElementCondition.java#L1

Docker container

Docker container to run addlicense from.

A Dockerfile is included in the Nokia fork of addlicense. An image is also available on dockerhub if you are interested.

How to install? `go get` is deprecated

$ go get -u github.com/google/addlicense
go get: installing executables with 'go get' in module mode is deprecated.
Use 'go install pkg@version' instead.
For more information, see https://golang.org/doc/go-get-install-deprecation
or run 'go help get' or 'go help install'.

Intermittent failure

On some runs, freuqnetly enough, this completely erases the existing code, and replaces it with license text.

My guess is that there's perhaps a race condition somewhere in the code.

To replicate this, the following works for me -

  1. I invoke it like below (on a repo with just about 15 files) -
find | xargs ~/go/bin/addlicense

I have about 15 files.

There's a good chance that this erases one of my files with just the license. If it didn't -

  1. Git reset to remove the lincense again -
git reset --hard

And go to step 1 until you see this happening.

malformed module path "io/fs"

I used the command:

go get github.com/google/[email protected]

And the download started. However, it was interrupted by thiss error message:
build github.com/google/addlicense: cannot load io/fs: malformed module path "io/fs": missing dot in first path element

This is the whole download:

$ go get github.com/google/[email protected]
go: finding github.com v1.0.0
go: finding github.com/google v1.0.0
go: downloading github.com/bmatcuk/doublestar/v4 v4.0.2
go: downloading golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
go: extracting golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
go: extracting github.com/bmatcuk/doublestar/v4 v4.0.2
go: finding golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
go: finding github.com/bmatcuk/doublestar/v4 v4.0.2
build github.com/google/addlicense: cannot load io/fs: malformed module path "io/fs": missing dot in first path element

Feature Request: Add a version subcommand

I would like to know which version of addlicense I have installed to know whether I need to install a new one to fix a bug or update to the version a repo has pinned.

use GoReleaser to build and push container images

we've (w/@Dentrax) just noticed that this project currently uses GoReleaser to make a new release, and the buildx tool to build and push container images, so, we can use GoReleaser to do the same for container images. By doing so, we can remove an additional step in the GitHub Actions workflow for building/pushing container images, also, we can sign our container images or binaries with cosign too.

Feel free to assign this to us, if you agree with this idea, we would love to work on this ๐Ÿฅณ

Symfony fails on transformed PHP files

addlicense with a PHP file introduces the license header within separate PHP tags <?php ... ?> and introduces a blank line.

diff of a changed php file
@@ -1,4 +1,20 @@
 <?php
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+?>
+
+<?php
 
 namespace App;

This style of change causes Symfony to fail:

...
[builder] Script cache:clear returned with error code 255
[builder] !!  
[builder] !!  
[builder] !!  Fatal error: Namespace declaration statement has to be the very first statement or after any declare call in the script in /workspace/src/Kernel.php on line 19
[builder] !!  Symfony\Component\ErrorHandler\Error\FatalError {#19
[builder] !!    -error: array:4 [
[builder] !!      "type" => 64
[builder] !!      "message" => "Namespace declaration statement has to be the very first statement or after any declare call in the script"
[builder] !!      "file" => "/workspace/src/Kernel.php"
[builder] !!      "line" => 19
[builder] !!    ]
[builder] !!    #message: "Compile Error: Namespace declaration statement has to be the very first statement or after any declare call in the script"
[builder] !!    #code: 0
[builder] !!    #file: "./src/Kernel.php"
[builder] !!    #line: 19
[builder] !!  }

Changing the header to be within the original PHP tags keeps Symfony happy.

Copyright line should append after the SPDX identifier

I just tried SPDX flag first time and noticed addlicense adds copyright line before the SPDX identifier.

$ addlicense -s=only -c Furkan .

Actual:

Copyright ...
SPDX-License-Identifier:

My expectation according to other open source projects, solidity, etc.:

SPDX-License-Identifier:
Copyright ...

Any ways to reorder of those? Shouldn't the right way is the bottom one?

Why use "//" instead of "/* ... */" for Java and Kotlin?

It seems the majority of Java projects puts the license on top of the file via multiple comments /* ... */, but addlicense uses // for Java and Kotlin:

addlicense/main.go

Lines 220 to 221 in a029431

case ".cc", ".cpp", ".cs", ".go", ".hh", ".hpp", ".java", ".m", ".mm", ".proto", ".rs", ".scala", ".swift", ".dart", ".groovy", ".kt", ".kts", ".v", ".sv":
lic, err = prefix(tmpl, data, "", "// ", "")

Is there any reason for this? If not, I think we should move .java, .kt and .kts a few lines above with other languages that use /* ... */.

Apply license update

Unless I'm missing something in the documentation, there's no way to update the license and apply this change in the relevant files. This is particularly important when the year span changes and an update mechanism would be useful.

Support general comment blocks in addition to line comments

The tool only supports line comments at this time. Additionally, it will not detect existing general comment blocks, causing duplication where these have been used.

Example diff:

+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
 /*

 Licensed under the Apache License, Version 2.0 (the "License");

How to install this tool?

I installed Go and then installed as instructed by the readme:

go get -u github.com/google/addlicense

addlicense is still not an executable on my system as far as I can tell. How do I run addlicense?

provide fail-on-diff flag to enable checking licence headers

We (w/@Dentrax) thought that in scenarios such as checking license headers, we use addlicence tool like the following way:

  license-check:
    name: license boilerplate check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-go@v2
        with:
          go-version: '1.17.x'
      - name: Install addlicense
        run: go install github.com/google/addlicense@latest
      - name: Check license headers
        run: |
          set -e
          addlicense -l apache -c 'The Sigstore Authors' -v *
          git diff --exit-code

As you can see from the above GitHub Action definition, we use additional git commands to check that is there any leaked license headers in the codebase, so, what we are proposing is that we add this logic into addlicence tool with an additional flag-like --fail-on-diff.

Introduce a flag to prefer `//` over `/*...*/`

It would be great to have a non-multiline comment support enabled with a new flag. Multiline comments /*\n*\n*\n*/ takes more lines and makes it harder to read for me. Here is a simple proposal:

$ touch foo.c
$ addlicense -s=only -c Furkan .

Actual: (Multiline comment)

/*
 * Copyright 2022 Furkan
 * SPDX-License-Identifier: Apache-2.0
 */

New flag way: (comment)

// Copyright 2022 Furkan
// SPDX-License-Identifier: Apache-2.0

An extra whitespace indentation for the Apache License template

The Apache License template indents the URL with 5 spaces:

addlicense/tmpl.go

Lines 104 to 111 in 53d978a

const tmplApache = `Copyright{{ if .Year }} {{.Year}}{{ end }} {{.Holder}}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0

where the letter h is under a:

You may obtain a copy of the License at
     |
     http://www.apache.org/licenses/LICENSE-2.0

The generated license also indent with 5 spaces:

addlicense/tmpl.go

Lines 1 to 8 in 53d978a

// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//

In the Apache official license template: https://www.apache.org/licenses/LICENSE-2.0#apply

Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

The URL is indented by 4 spaces and the letter h is under m.

You can also find the LICENSE file is indent by 4 spaces (h under m):

addlicense/LICENSE

Lines 190 to 197 in 53d978a

Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0

Option to list files that will be modified

The capability to list files that will be modified, but without modifying them, will be very useful.

This will also allow addlicense to be used in CI environments, git-hooks, etc., to ensure licensing compliance.

Docker build fails due to upstream dep issue

Logs like:

#5 18.53 # github.com/golang/dep/gps
#5 18.53 pkg/mod/github.com/golang/[email protected]/gps/constraint.go:103:21: cannot use sv (type *semver.Version) as type semver.Version in field value
#5 18.53 pkg/mod/github.com/golang/[email protected]/gps/constraint.go:122:16: invalid type assertion: c.(semver.Version) (non-interface type *semver.Constraints on left)
#5 18.53 pkg/mod/github.com/golang/[email protected]/gps/constraint.go:149:4: undefined: semver.Constraint

Relates to issue: golang/dep#2223
Can be fixed by using this suggestion on that issue: golang/dep#2223 (comment)

[Proposal] Usage as module instead of CLI

I'm looking to integrate addLicense into an existing suite of internal FOSS compliance-related tooling, and part of that would be eased by decoupling the addLicense functions from the CLI-specific code that uses them. I'd like to propose the following changes (which I will happily create a PR for), but I wanted to check in with maintainers prior to doing so:

  1. Turn main() into a function that consists solely of flag parsing and calling a new Run() function
  2. Break out the rest of main() into a Run() function that takes in the parsed flag values and executes everything else (goroutines, etc)
  3. Export fileMatches, addLicense, licenseHeader, isGenerated, and hasLicense

@willnorris et al, are there any thoughts or concerns about that approach? My over-arching goal is to increase composability.

Ignore subdirectories pattern

Hey folks,

Is there any way to ignore subdirectories based on the directory name? We currently have a lerna monorepo and I find it difficult to exclude multiple node_modules folders.

The optimal would be to use it like this

addlicense -c "Neo4j Inc." -f license.txt -check ./**/*.{js,ts,css} -ignore **/node_modules/*

but it doesn't seem to work.

The directories also are in the following tree structure

.
โ”œโ”€โ”€ CONTRIBUTING.md
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ lerna.json
โ”œโ”€โ”€ license.js
โ”œโ”€โ”€ license.txt
โ”œโ”€โ”€ node_modules
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ packages
โ”‚ย ย  โ”œโ”€โ”€ base
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ node_modules
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ package.json
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ src
โ”‚ย ย  โ”œโ”€โ”€ html-storybook
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ node_modules
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ package.json
โ”‚ย ย  โ”œโ”€โ”€ react
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ node_modules
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ package.json
โ”‚ย ย  โ”‚ย ย  โ”œโ”€โ”€ src
โ”‚ย ย  โ”‚ย ย  โ””โ”€โ”€ tsconfig.json
โ”‚ย ย  โ””โ”€โ”€ react-storybook
โ”‚ย ย      โ”œโ”€โ”€ node_modules
โ”‚ย ย      โ”œโ”€โ”€ package.json
โ”‚ย ย      โ””โ”€โ”€ src
โ”œโ”€โ”€ tsconfig.json
โ””โ”€โ”€ yarn.lock

Ignore doesn't work without equals sign

I'm using the addlicense container like so:

$ podman run --rm -v $PWD:/src ghcr.io/google/addlicense -v -check -ignore node_modules/** .

But this doesn't skip node_modules directory. However, if I changed it to -ignore=node_modules/**, then it skips node_modules as expected.

If this isn't a bug then it should be made clear in the readme that = is required

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.