brainmaestro / composer-git-hooks Goto Github PK
View Code? Open in Web Editor NEWEasily manage git hooks in your composer config
License: MIT License
Easily manage git hooks in your composer config
License: MIT License
I'm new to composer-git-hooks
, and not an expert in PHP, so this error annoys me a bit. When installing the dependencies with ./composer.phar install
, everything goes fine until try to install the git hooks:
> Vendor/bin/cghooks add --ignore-lock
PHP Fatal error: Class 'CakeException' not found in /home/piranna/Trabajo/Prior/whitelabel-server/Plugin/JwtAuth/Controller/Component/Auth/TokenExpiredException.php on line 2
Script Vendor/bin/cghooks add --ignore-lock handling the post-install-cmd event returned with error code 255
How can I fix it? And how can an unrelated code on my project afect the git hooks install step?
Hi! I found this package extra useful for my workflow at my job. I just wanted to share my experience implementing it and a couple of thoughts.
I felt the "post-install-cmd": "cghooks add --ignore-lock",
suggestion very misleading, if I understood correctly, it would add the cghooks.lock
file to my gitignore (in my case breaking my gitignore, as the last line was not empty), and my coworker would get the gitignore modified too (as the package would not find a cghooks.lock
file.
On the other hand, I had issues when doing a composer install --no-dev
deploy.
My first attemp was checking the COMPOSER_DEV_MODE
env variable, but it did not work in my Docker environment. I solved it with a command -v
call. Also, I had to specify the git-dir
because the package was not finding it on my Docker container (and I don't have any clue about why).
My last problem appeared when doing composer install
after a composer install --no-dev
. I had to solve this by uninstalling the hooks before every installation.
This is an excerpt of my final composer.json
file. I think that the readme could be improved, and the workflow rethinked to be easier!
{
"require-dev": {
"overtrue/phplint": "^1.1",
"brainmaestro/composer-git-hooks": "^2.8"
},
"scripts": {
"pre-install-cmd": "command -v vendor/bin/cghooks >/dev/null 2>&1 || exit 0; vendor/bin/cghooks remove --git-dir=.git",
"post-install-cmd": "command -v vendor/bin/cghooks >/dev/null 2>&1 || exit 0; vendor/bin/cghooks add --git-dir=.git",
"post-update-cmd": "command -v vendor/bin/cghooks >/dev/null 2>&1 || exit 0; vendor/bin/cghooks update --git-dir=.git",
"phplint": "./vendor/bin/phplint",
"test": [
"@composer run phplint"
]
},
"scripts-descriptions": {
"test": "Run all tests"
},
"extra": {
"hooks": {
"pre-commit": [
"composer run test"
],
"post-merge": "composer install"
}
}
}
Are there any plans on upgrading symfony/console dependency to 6 since right now it conflicts with it, because it is locked to ^5?
Hey,
It looks like to me that you @BrainMaestro don't have the time to maintain this package, would it be possible to give access to some of the people who have contributed and are willing to continue maintain this project?
There is plenty of us using it and it would be a lot easier than us creating each their own fork.
I have updated my project to PHP 8.2 and the warning has started to appear. My brainmaestro/composer-git-hooks version of is v2.8.5
Deprecated: trim(): Passing null to parameter #1 ($string) of type string is deprecated in /vendor/brainmaestro/composer-git-hooks/src/helpers.php on line 54
You can reconstruct this bug by using vardrop/cghooks-test
When defining an array as a composer git hook on windows, only the first in the array gets executed. This bug may be related to running in windows as running the same project in wsl
will result in the expected output.
composer.json
{
"require-dev": {
"brainmaestro/composer-git-hooks": "^2.8"
},
"scripts": {
"post-install-cmd": "cghooks add --ignore-lock",
"post-update-cmd": "cghooks update",
"cghooks": "vendor/bin/cghooks"
},
"extra": {
"hooks": {
"pre-commit": [
"echo 1 lorem ipsum",
"echo 2 dolor eset"
]
}
},
"require": {
"php": "^8.0"
}
}
I have confirmed that the second script above never actually gets called by replacing echo 2 dolor eset
with touch test.txt
.
$ php -v
PHP 8.0.7 (cli) (built: Jun 2 2021 00:41:03) ( ZTS Visual C++ 2019 x64 )
Copyright (c) The PHP Group
Zend Engine v4.0.7, Copyright (c) Zend Technologies
$ composer -V
Composer version 2.1.2 2021-06-07 16:03:06
$ composer show brainmaestro/composer-git-hooks | rg versions
versions : * v2.8.5
$ git --version
git version 2.31.1.windows.1
When running composer cghooks pre-commit
, Id expect the output to be
$ composer cghooks pre-commit
> vendor/bin/cghooks 'pre-commit'
1 lorem ipsum
2 dolor eset
but given the above configuration it will result in
$ composer cghooks pre-commit
> vendor/bin/cghooks "pre-commit"
1 lorem ipsum
Nevertheless, running git commit
works as expected
$ git commit -m "feat: init"
1 lorem ipsum
2 dolor eset
[master (root-commit) 2c129d4] feat: init
(abbreviated)
This is probably a dumb question or something simple I am overlooking but for some reason no matter what I do I cannot seem to get my git commit -m"message here" to actually commit upon completion of the pre-commit hook. I have seen elsewhere online where if the hook returns 0 then the commit should complete as expected. I have even added multiple variations of exit 0 as the last script within the pre-commit array but with no luck.
The pre-commit hooks is running as expected but fails to actually add the new commit upon completion.
Not sure if this helps but I am working on a Laravel 5.8 project using and using the virtual box vm 'laravel/homestead' version '7.1.0'.
I have spent more time than I'd like to admit trying to get this to work so any help would be greatly appreciated. I hope this is the right channel to post this. Thanks!
When running git commit and then git status:
vagrant@homestead:~/code/notiifii$ git commit -m"test"
committing as [email protected]
Loaded config default from ".php_cs".
Fixed all files in 13.107 seconds, 12.000 MB memory used
vagrant@homestead:~/code/notiifii$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: .gitignore
new file: .php_cs
modified: app/Console/Kernel.php
modified: composer.json
modified: composer.lock
modified: routes/web.php
Here is the hooks section of my composer.json file. These are found under the extra section.
"hooks": { "pre-commit": [ "echo committing as $(git config user.email)", "php-cs-fixer fix --config=.php_cs", "git add ." ], "pre-push": [ "php-cs-fixer fix --dry-run --config=.php_cs", "phpunit" ], "post-merge": "composer install" },
Hi,
the version the fix from #106 does work as excepted. however we dont want to use dev-master.
is it possible to create a new bugfix version?
thx
My hooks are installed in a --absolute-git-dir
directory ;)
ls -al
total 2055
drwxrwxrwx 1 root root 12288 Jun 19 15:21 .
drwxrwxrwx 1 root root 4096 Jun 19 11:50 ..
drwxrwxrwx 1 root root 0 Jun 19 15:21 --absolute-git-dir
drwxrwxrwx 1 root root 0 Jan 16 17:33 app
[...]
git --version
git version 2.11.0
git rev-parse --absolute-git-dir
--absolute-git-dir
It seems --absolute-git-dir
was introduced in 2.13
Originally posted by @Broutard in #79 (comment)
Hi,
And first of all thanks for your job on this library ๐
I have this hook configuration :
# composer.json
"hooks": {
"pre-commit": [
"make cs.fixer.dryrun",
"make test.phpstan",
"make test.phpunit"
]
}
# makefile
test.phpstan:
docker-compose run etl vendor/bin/phpstan analyse -l8 src
test.phpunit:
docker-compose run etl bin/phpunit
cs.fixer.dryrun:
docker-compose run etl vendor/bin/php-cs-fixer -vvv fix --dry-run
This configuration creates the given pre-commit hook file :
#!/bin/sh
make cs.fixer.dryrun
make test.phpstan
make test.phpunit
The problem is that if, for example, make cs.fixer.dryrun
exit with an error it does not stop the pre-commit hook and the commit is validated.
In fact the only script wich could abort the commit is the last of the list.
AFAIK the '-e' option resolve this issue by exiting the script on the first error response from a line.
http://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#The-Set-Builtin
Actually I have enforced this behaviour by adding a pre-commit line in my composer.json
"hooks": {
"pre-commit": [
"set -e",
"make cs.fixer.dryrun",
"make test.phpstan",
"make test.phpunit"
]
}
But I'm surprized that this behaviour is not the one defined by default?
Did I miss something ?
Thanks
Calling this command, no matter which arguments are used fails:
bin/cghooks add
[Symfony\Component\Console\Exception\LogicException]
An option with shortcut "n" already exists.
add [-f|--force] [-n|--no-lock] [-i|--ignore-lock]
Seems like the console application already uses -n for something else.
Would be awesome if you could support PHP 7.3
Right now the requirements are set to < 7.3 thus its not installable without the --ignore-platform-reqs
arg.
brainmaestro/composer-git-hooks v2.6.0 requires php ^5.6 || >=7.0 <7.3 -> your PHP version (7.3.0) does not satisfy that requirement.
Hi,
thanks a lot for creating and sharing this amazing package.
I got stuck with a little issue and want you to ask for assistance.
I'm running Composer on a windows box. I have installed brainmaestro/composer-git-hooks
as recommended in the docs. If I run ./vendor/bin/cghooks pre-commit
everything works fine and as expected. But if I want to commit via git command git commit -am 'Add feature xy.'
I get an error:
error: cannot spawn .git/hooks/pre-commit: No such file or directory
Some research on this topic brought me to https://stackoverflow.com/a/20610055 with the suggestion to add the SHEBANG #!/bin/bash
to the hook files. After adding this, everything works fine.
Is there a way (or could we have a way) to add this SHEBANG automatically to the hook files generated by cghooks
?
My Composer file is looking as followed:
{
"scripts": {
"csw": [
"phpcs --standard=ruleset_psr2_win.xml --ignore=app/Http/Controllers/Auth,app/Http/Controllers/Controller.php app/Http/Controllers"
],
"cs": [
"phpcs --standard=psr2 --ignore=app/Http/Controllers/Auth,app/Http/Controllers/Controller.php app/Http/Controllers"
],
"test": [
"phpunit --coverage-text"
]
},
"extra": {
"hooks": {
"pre-commit": "composer csw",
"pre-push": "composer test"
}
}
}
Is it possible to create a new tag ... because of #113
Adding the hooks via cghooks add -l
, does not - as expected - create a cghooks.lock
file. I'm using cghooks 2.8.5 while reproducing this problem.
However, running cghooks remove
creates one, and there's no -l
or similar option to prevent this from being created.
Our usual workflow is to run composer install when merging/changing branches and composer.json/lock changed. Using the default config here will run vendor/bin/cghooks add --ignore-lock
each time and print No hooks were added. Try updating
I'd like to have a change there: instead of error when hooks exist, check if they are the same as the hook that would be created, and print a different message like All hooks are up to date
, to prevent confusing new people on the project, I would not want them to randomly run composer update.
What do you think?
Hi, first of all thank you for the great package.
While trying to add a custom hook for Git Flow (https://github.com/petervanderdoes/gitflow-avh/wiki/Reference:-Hooks-and-Filters) I figured out that cghooks doesn't allows it as it validates hook names against a list of official git hooks before adding them:
composer-git-hooks/src/Hook.php
Line 33 in 676162c
So, what about adding a --skip-validation
general option to BrainMaestro\GitHooks\Commands\Command
to allow adding hooks even if not officially supported by git? I can obviously create a PR if you wish.
My only concern is about the call made on the main executable to implement test commands:
Lines 32 to 34 in 676162c
I don't see a clean way to pass the --skip-validation
option to this call. We might just allow it to call all hooks if that doesn't concerns you.
What you think?
Version 2.7.0 will execute add
and update
commands when composer --no-dev
is provided, and skip the commands when in "dev mode"
This commit: a46097f implemented incorrect logic checking the composer "dev mode".
It contained this check (src/Commands/AddCommand.php:49
):
if (!$this->forceSetup && is_composer_dev_mode()) {
// skip silently
return;
}
that would silently skip executing the add or update commands when composer is in "dev mode".
Surely we want the commands to run in "dev mode", and by default, not run when the --no-dev
flag is provided.
This could simply be fixed by changing the check to:
if (!$this->forceSetup && is_composer_dev_mode() === false) {
// skip silently
return;
}
I can see that the commit was reverted here: 603989b
But no new version has been created! Anyone using version 2.7.0 will have the add
and update
commands silently skipped in "dev mode", and they will execute when the --no-dev
flag is passed!
At the very least, please create another tagged version after the revert commit 603989b
I'm wondering why the users' hooks need to be installed? Instead you could just have 1 hook script that calls cghooks
which can then read the composer.json
and execute the actual hooks.
I understand why we need to install a hook in the git folder, I just don't understand why it needs to be the actual users' hook instead of a single gchooks wrapper.
I have a laravel/pint configured with pre-commit hook, and it says PASS on the output but the stop-on-failure is triggered and commit does not go through.
"hooks": {
"config": {
"stop-on-failure": ["pre-commit"]
},
"pre-commit": [
"vendor/bin/pint"
],
"commit-msg": "grep -q '[A-Z]+-[0-9]+.*' $1",
"pre-push": [],
"post-merge": ""
}
Output:
............................................................................
............................................................................
............................................................................
............................................................................
............................................................................
............................................................................
............................................................................
............................................................................
......................................................................
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ Laravel
PASS ......................................................... 678 files
Introduced in #23.
composer-git-hooks/src/helpers.php
Line 3 in d3ba750
However, symfony/process
is missing from composer.json
:
composer-git-hooks/composer.json
Lines 18 to 21 in d3ba750
Hi there! First of all: great tool! I love to keep the setup of repositories simple and having the ability to set up git hooks via composer is just great!
I recently ran into this problem and can't seem to figure it out on my own. I did the following and got this error:
$ vendor/bin/cghooks update
: not foundcghooks: 2: vendor/bin/cghooks:
: not foundcghooks: 4: vendor/bin/cghooks:
vendor/bin/cghooks: 6: vendor/bin/cghooks: Syntax error: word unexpected (expecting "in")
Any ideas? I don't really know what information can be useful so you'll have to tell me. Thanks!
I had a new behavior after updating symfony dependencies to v2.8.4.
The composer.json does not change and has the following command in there:
"hooks": {
"commit-msg": [
"# https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type",
"rules='^(chore|docs|feat|fix|perf|refactor|style|test)(\\((\\w|[-_])+\\))?:.*'",
"test -n \"$(grep -E $rules \"$1\")\" || {",
" echo >&2 \"\"",
" echo >&2 \"Your commit message does not follow commit message rules!\"",
" echo >&2 \"Please use one of these prefixes: feat fix docs style refactor perf test chore\"",
" echo >&2 \"\"",
Before the commit message was generated like this and everything works fine:
#!/bin/sh
# https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type
rules='^(chore|docs|feat|fix|perf|refactor|style|test)(\((\w|[-_])+\))?:.*'
test -n "$(grep -E $rules "$1")" || {
echo >&2 ""
echo >&2 "Your commit message does not follow commit message rules!"
echo >&2 "Please use one of these prefixes: feat fix docs style refactor perf test chore"
echo >&2 ""
After the update the script generates something like this, which results in a syntax error:
#!/bin/sh
# https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type && \
rules='^(chore|docs|feat|fix|perf|refactor|style|test)(\((\w|[-_])+\))?:.*'
test -n "$(grep -E $rules "$1")" || {
echo >&2 "" && \
echo >&2 "Your commit message does not follow commit message rules!" && \
echo >&2 "Please use one of these prefixes: feat fix docs style refactor perf test chore" && \
echo >&2 "" && \
The syntax error is caused by the new && \
line endings.
Edit: for better readability I shortened the complete commit message to the relevant parts.
It would be nice to have worktree support: If you accidentally run (for example, within a "composer install" configuration) "cghooks update" (or similar) in a worktree dir, "file_put_contents" fails (there's no ".git" directory). It should detect if you are in a worktree and:
Problem 1
- brainmaestro/composer-git-hooks[v2.8.0, ..., v2.8.2] require symfony/console ^3.2 || ^4.0 -> found symfony/console[v3.2.0-BETA1, ..., 3.4.x-dev, v4.0.0-BETA1, ..., 4.4.x-dev] but the package is fixed to v6.1.5 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
- brainmaestro/composer-git-hooks[v2.8.3, ..., v2.8.5] require symfony/console ^3.2 || ^4.0 || ^5.0 -> found symfony/console[v3.2.0-BETA1, ..., 3.4.x-dev, v4.0.0-BETA1, ..., 4.4.x-dev, v5.0.0-BETA1, ..., 5.4.x-dev] but the package is fixed to v6.1.5 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
- Root composer.json requires brainmaestro/composer-git-hooks ^2.8 -> satisfiable by brainmaestro/composer-git-hooks[v2.8.0, ..., v2.8.5].
Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
You can also try re-running composer require with an explicit version constraint, e.g. "composer require brainmaestro/composer-git-hooks:*" to figure out if any version is installable, or "composer require brainmaestro/composer-git-hooks:^2.1" if you know which you need.
How can I solve this problem in laravel 9 and php 8?
[Question] How about to add option for lock file path?
Some projects has to have a lot of utility files like lock files and usually all of them are located in the project root. So why not to put cghooks.lock to some other place via cghooks binary option with project root by default?
{
......
"extra": {
"hooks": {
"cbf": "composer phpcbf app ext config database",
"pre-commit": "composer phplint && composer --no-ansi phpcs -- --parallel=10 --standard=PSR2 -n --colors --encoding=utf-8 --report-diff=change.diff app config database ext",
"post-commit": "php -r \"file_exists('./change.diff') && empty(trim(file_get_contents('./change.diff'))) && exec('rm ./change.diff');\" && echo committed",
"pre-push": "composer phplint && echo pushing!"
},
"customize_hooks": ["cbf"]
}
}
This my composer.json
file. I want to adavance git hooks feature.
Hi there,
I changed a pre-commit hook to run on pre-push, ran cghooks update
, but now the hook always runs on pre-commit..
All traces of pre-commit have been removed (composer.json, cghooks.lock) yet it still runs, even when opening new terminals.
I'm out of options at this point except composer removing the dependency
Considering PHP 7.4 isn't EOL until the end of the year it would be nice to still include in version 3.0
Commit failed - exit code 1 received, with output: '.git/hooks/pre-commit: line 2: $'\r': command not found
committing as
/usr/bin/env: php: No such file or directory'
When trying to commit via GitHub Desktop on Windows 10..
This is what my composer.json
looks like...
"extra": {
"laravel": {
"dont-discover": []
},
"hooks": {
"pre-commit": [
"echo committing as $(git config user.name)",
"vendor/bin/php-cs-fixer fix --using-cache=no ."
],
"commit-msg": "grep -q '[A-Z]+-[0-9]+.*' $1",
"pre-push": [
"vendor/bin/php-cs-fixer fix --dry-run --using-cache=no .",
"phpunit"
],
"post-merge": "composer update"
}
},
// ... some lines down
"scripts": {
"post-install-cmd": "cghooks add --ignore-lock",
"post-update-cmd": "cghooks update",
}
Hi,
I have the following script that checks that a commit message is formatted properly:
{
"prepare-commit-msg": [
"CUR_BRANCH=\"$(git branch | grep '*' | sed 's/* //')\"",
"if [ \"$CUR_BRANCH\" = '(no branch)' ]; then",
" exit 0",
"fi",
"COMMIT_REGEX='^(fixup! )*?(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\\([a-z ]+\\))?: .+$'",
"if ! grep -qE \"$COMMIT_REGEX\" \"$1\"; then",
" echo 'Invalid commit message, aborting... See https://github.com/pvdlg/conventional-changelog-metahub#commit-types' >&2",
" exit 1",
"fi"
]
}
Since #106, multiline commands entries are now joined with && \
. That brokes the bash script.
As json doesn't allow multline strings, I don't see other way to write the script.
I find convenient to write these little scripts in composer.json directly and not in separate script files.
Any thoughts?
Thanks
Currently everyone should write like this:
"extra": {
"hooks": {
"pre-commit": ""
}
}
But this is not supported:
"extra": {
"hooks": {
"pre-commit": [
"but",
"why?"
]
}
}
It totally makes sense to have more than one command there.
@BrainMaestro After updating to 2.7 i have face issue for the following scenario.
Project root directory has git folder, Inside that root directory i have another folder which contains project and where composer located.
So now when pre commit hook fired then it gives error Composer could not find a composer.json file
Also it is looking for composer.json in root folder of project where it is not located.
But it is located in another folder inside root directory
Would it be possible to publish a stable tag for 3.0.0?
Unfortunately this package is still broken with Symfony 6 if the projects minimum-stability is stable.
Thank you for this great tool!
Our composer.json
is in another directory than the .git/
directory. At the moment, the writing of hooks fails in this scenario.
Would it be okay for you to add an option like --git-dir='/path/to/.git'
which lets one define another path than just .git
?
Hi,
This is probably something right in front of my face but I'm hoping someone can spot my error here.
We are trying to use php-cs-fixer
in combination with composer-git-hooks
to lint staged files on pre-commit. It is working fine in Ubuntu but not windows 10. I have tried every combination of actions to get it to work (clear composer.lock, remove vendor, reinstall repo from scratch, --force-win and --no-lock flags, everything).
Here is our composer.json
{
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.15",
"brainmaestro/composer-git-hooks": "^2.8"
},
"require": {
"php": "7.3.*",
"ext-json": "*",
"ext-curl": "*",
},
"scripts": {
"post-install-cmd": "php vendor/bin/cghooks add --force-win",
"post-update-cmd": "php vendor/bin/cghooks update",
"pre-commit": [
"echo 'Linting all PHP files'",
"php vendor/bin/php-cs-fixer fix . --verbose --config .php_cs",
"git add -u"
]
}
}
Here is sample output of composer install
- happening on multiple windows machines
vendor/bin/cghooks update
and vendor/bin/cghooks add
produce the same result. No .git/hooks/pre-commit
file.
Can anyone spot anything? Many thanks.
Hey!
Currently the symfony/console
component is limited to ^5.0
.
Any plans to support Symfony 6?
It would be great to fasten up things. Instead of
"pre-commit": [ "phpcs-foo" ]
(parsing hundreds of files) it could be
"pre-commit": [ "phpcs-foo ${changedFiles[*]}" ]
rather an array than a string that is less flexible.
Passing this to the custom hooks can have multiple benefits but at least it speeds up things for static code analysis.
In addition the developer only gets rejected about things that he did "wrong" and not about some ignorant force push from other devs.
Is this possible right now or as a new feature?
This perhaps isn't an issue with the package more than a user experience issue, but if you modify your composer.json file and accidentally leave invalid markup ( say an extra comma at the end of an array ), then all of the cghooks
commands either fail silently or say there's nothing to do.
Perhaps simply executing a composer validate --no-check-lock
before each cghooks command would be sufficient?
Found this package on the Laravel-News blog and immediately thought it looks very similar to grumphp.
Check it out maybe you can draw some inspiration:
https://github.com/phpro/grumphp
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.