Coder Social home page Coder Social logo

pre-commit-hooks's Introduction

Pre-commit git hooks

Git hooks to integrate with pre-commit.

Configure pre-commit

⚠️ These hooks now require Python3.

Add to .pre-commit-config.yaml in your git repo:

- repo: https://github.com/jumanjihouse/pre-commit-hooks
  rev: master  # or specific git tag
  hooks:
    - id: bundler-audit
    - id: check-mailmap
    - id: fasterer
    - id: forbid-binary
    - id: forbid-space-in-indent
    - id: git-check  # Configure in .gitattributes
    - id: git-dirty  # Configure in .gitignore
    - id: markdownlint # Configure in .mdlrc
    - id: reek
    - id: require-ascii
    - id: rubocop
    - id: script-must-have-extension
    - id: script-must-not-have-extension
    - id: shellcheck
    - id: shfmt

Two ways to invoke pre-commit

If you want to invoke the checks as a git pre-commit hook, run:

pre-commit install

If you want to run the checks on-demand (outside of git hooks), run:

pre-commit run --all-files --verbose

The test harness of this git repo uses the second approach to run the checks on-demand.

Available hooks

bundler-audit

What it does

  • Checks for vulnerable versions of gems in Gemfile.lock.
  • Checks for insecure gem sources (http://).
  • Allows ignoring certain advisories that have been manually worked around.
  • Prints advisory information.

More info

See https://github.com/rubysec/bundler-audit for details.

check-mailmap

What it does

Detect botched name/email translations in git history.

git shortlog -sn is useful to summarize contributors.

However, it gets muddy when an email address is associated with multiple names.
Reasons include:

  • the author's full name was messed up
  • not always written the same way
  • the author has multiple email addresses

More info

Sample output for good condition:

$ pre-commit run check-mailmap --all-files --verbose
[check-mailmap] Detect if an email address needs to be added to mailmap.......................Passed

Sample output for bad condition:

$ pre-commit run check-mailmap --all-files --verbose
[check-mailmap] Detect if an email address needs to be added to mailmap.......................Failed
hookid: check-mailmap

The following email addresses are associated with more than one name:

        [email protected]
        [email protected]

The associations include:

      2 Billy Bob <[email protected]>
      2 Bubba <[email protected]>

     13 John Doe <[email protected]>
      4 jdoe <[email protected]>

fasterer

What it does

Suggest ways to improve speed of Ruby code.

More info

fasterer suggests speed improvements that you can check in detail at the fast-ruby repo.

Note: You should not follow the suggestions blindly.

forbid-binary

What it does

Prevent binary files from being committed.

More info

Fail if a file appears to be a binary filetype. Override with an exclude regular expression, such as the example here.

forbid-space-in-indent

What it does

Prevent files with spaces within indentation from being committed.

More info

Fail if a file contains spaces within indentation. Override with an exclude regular expression, such as the example here.

git-check

What it does

Check both committed and uncommitted files for git conflict markers and whitespace errors according to core.whitespace and conflict-marker-size configuration in a git repo.

More info

This hook uses git itself to perform the checks.
The git-scm book describes here that there are six core.whitespace checks.

Enabled by default:

  • blank-at-eol, which looks for spaces at the end of a line
  • blank-at-eof, which looks for blank lines at the end of a file
  • space-before-tab, which looks for spaces before tabs at the beginning of a line

Disabled by default:

  • indent-with-non-tab, which looks for lines that begin with spaces instead of tabs (and is controlled by the tabwidth option)
  • tab-in-indent, which looks for tabs in the indentation portion of a line
  • cr-at-eol, which looks for carriage returns at the end of a line

Custom configuration (overrides)

The git documentation describes here how to configure the various checks.

The recommended place to persist the configuration is the .gitattributes file, described here. It provides fine control over configuration per file path for both core.whitespace and conflict-marker-size.

Real-world examples of .gitattributes file to configure overrides per path:

git-dirty

What it does

During the pre-commit stage, do nothing.
Otherwise, detect whether the git tree contains modified, staged, or untracked files.

More info

This is useful to run near the end of a CI process to see if a build step has modified the git tree in unexpected ways.

Custom configuration (overrides)

The recommended place to persist the configuration is the .gitignore file, described here.

markdownlint

What it does

Check markdown files and flag style issues.

More info

markdownlint is a ruby tool that examines markdown files against various style rules.

Custom configuration (overrides)

Provide .mdlrc in the top-level of your project git repo.

For an annotated example of overrides, see in this project:

protect-first-parent

What it does

Helps to ensure the first-parent sequence of commits on the default branch is a true record of commits.

This protection is probably best done as a pre-receive hook. However, central git repos like GitHub, GitLab, and so forth do not allow users to configure server-side hooks.

This client-side hook fills the gap to help prevent foxtrot merges.

More info

reek

What it does

Detect code smells in Ruby code.

More info

Reek is a tool that examines Ruby classes, modules and methods and reports any Code Smells it finds.

For an excellent introduction to Code Smells and Reek check out this blog post or that one. There is also this talk from RubyConfBY (there is also a slide deck if you prefer that).

Note: Do not follow the suggestions blindly.

This hook uses the identify library of pre-commit to identify ruby scripts. If the file is a ruby script, then run reek against the file.

Custom configuration (overrides)

The recommended place to persist the configuration is the .reek file, described here.

You can also create in-line comments in the source code for individual overrides.

require-ascii

What it does

Requires that text files have ascii-encoding, including the extended ascii set. This is useful to detect files that have unicode characters.

Custom configuration (overrides)

Use the built-in overrides from the pre-commit framework.

rubocop

What it does

RuboCop is a Ruby static code analyzer. Out of the box it enforces many of the guidelines outlined in the community Ruby Style Guide.

More info

This hook uses the identify library of pre-commit to identify ruby scripts. If the file is a ruby script, then run rubocop against the file. Additionally, run rubocop-rspec against rspec files.

Custom configuration (overrides)

Most aspects of rubocop behavior can be tweaked via various configuration options.

Rubocop-performance is documented here.

Rubocop-rspec is documented here.

script-must-have-extension

What it does

The Google shell style guide states:

Libraries must have a .sh extension and should not be executable.

This hook checks for conformance.

Default

Filter on files that are both shell and non-executable.

types: [shell, non-executable]

Custom configuration (overrides)

Suppose your local style guide is the opposite of the default.
In other words, you require executable scripts to end with .sh.
Put this in your .pre-commit-config.yaml:

- repo: https://github.com/jumanjihouse/pre-commit-hooks
  rev: <version>
  hooks:
    - id: script-must-have-extension
      name: Local policy is to use .sh extension for shell scripts
      types: [shell, executable]

Note the use of "name" to override the hook's default name and provide context for the override.

script-must-not-have-extension

What it does

The Google shell style guide states:

Executables should have no extension (strongly preferred)

This hook checks for conformance.

Default

Filter on files that are both shell and executable.

types: [shell, executable]

Custom configuration (overrides)

You can use this hook to forbid filename extensions on other types of files.
Put something like this in your .pre-commit-config.yaml:

- repo: https://github.com/jumanjihouse/pre-commit-hooks
  rev: <version>
  hooks:
    - id: script-must-not-have-extension
      name: Local policy is to exclude extension from all shell files
      types: [shell]

    - id: script-must-not-have-extension
      name: Executable Ruby scripts must not have a file extension
      types: [ruby, executable]

Note the use of "name" to override the hook's default name and provide context for the override.

shellcheck

What it does

Run shellcheck against scripts.

More info

This hook uses the identify library of pre-commit to identify shell scripts. If the file is a shell script, then run shellcheck against the file.

By default, this hooks passes -e SC1091 to shellcheck. Override locally with the args parameter in .pre-commit-config.yaml.

⚠️ The shellcheck hook requires shellcheck.

shfmt

What it does

Run shfmt -w against scripts with args.

More info

This hook uses the identify library of pre-commit to identify shell scripts. If the file is a shell script, then run shfmt against the file.

Override locally with .editorconfig.

⚠️ The shfmt hook requires a recent version of shfmt.

Contributing

Please see CONTRIBUTING.md.

Testing

Please see TESTING.md.

License

The code in this repo is licensed under the MIT License.

pre-commit-hooks's People

Contributors

acdha avatar ealprr avatar jumanjiman avatar mightynerderic avatar mvargeson avatar pigeonf avatar simmerz avatar vgautam-dialpad 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

pre-commit-hooks's Issues

Bug: Filenames with spaces are treated as multiple arguments which generate file not found errors

I tried activating the markdownlint hook for my repo, which runs without complaint with mdl . but with the pre-commit hook mdl crashed on some calls with a cryptic multi-line traceback which appears to be saying "File not found: ."

The problem appears to be that, while pre-commit correctly quotes filenames containing spaces when passing them as arguments to the hook script, the run-mdl Ruby script assumes that there are no spaces in the arguments and joins them all together with no quoting or escaping with args = ARGV.join(' ') and then calls mdl #{args} 2>&1. Cryptic tracebacks ensue.

I don't know Ruby, but the alternatives for fixing this are fairly clear:

  1. Use the shellescape builtin with something like ARGV.shellescape.join(' ') (I'm only speculating that this will function as desired in Ruby), or
  2. Iterate over each element of ARGV, running mdl on each and managing $CHILD_STATUS.exitstatus within the loop.

This is a blocker for me, I can't activate this hook if it can't handle filenames which contain spaces.

Other places where this construct is used may be seen via a search for ARGV.join(' ') within this repo.

Related: puts "args: #{args}" is handled inconsistently within the scripts. I agree with the comment and conditional seen in run-fasterer, run-reek and run-rubocop:

# ... pre-commit looks better if there is no output on success.
...
puts args if ENV['DEBUG']

It would be... better... if argument printing in all these scripts were harmonized to use puts "args: #{args}" if ENV['DEBUG'] (or whatever works, if my speculation about Ruby syntax is incorrect).

Markdownlint fails with "Could not find 'bundler'" on MacOS - install specific bundler version

I have a pre-commit coinfiguration clause like this.

- repo: https://github.com/jumanjihouse/pre-commit-hooks
  rev: 'master'  # Use the sha / tag you want to point at
  hooks:
  - id: markdownlint
    args:
    - -r MD046=consistent

when running pre-commit it failed like so:

/usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems/dependency.rb:311:in `to_specs': Could not find 'bundler' (>= 1.2.0, < 3) among 41 total gem(s) (Gem::MissingSpecError)
Checked in 'GEM_PATH=/Users/michael-mbp/.gem/ruby/2.6.0:/usr/local/lib/ruby/gems/2.6.0:/usr/local/Cellar/ruby/2.6.2/lib/ruby/gems/2.6.0:/Users/michael-mbp/.cache/pre-commit/repo1_2m2ecl/rbenv-default/gems', execute `gem env` for more information
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1449:in `block in activate_dependencies'
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1438:in `each'
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1438:in `activate_dependencies'
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1420:in `activate'
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1452:in `block in activate_dependencies'
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1438:in `each'
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1438:in `activate_dependencies'
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems/specification.rb:1420:in `activate'
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems.rb:304:in `block in activate_bin_path'
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems.rb:303:in `synchronize'
	from /usr/local/Cellar/ruby/2.6.2/lib/ruby/2.6.0/rubygems.rb:303:in `activate_bin_path'
	from /Users/michael-mbp/.cache/pre-commit/repo1_2m2ecl/rbenv-default/gems/bin/run-mdl:23:in `<main>'

This appears to be related to this issue with bundler - https://bundler.io/blog/2019/01/04/an-update-on-the-bundler-2-release.html

.mdlrc file appears to be ignored

I am trying to tune the settings for markdownlint but can't get the .mdlrc file to be used. This is on Ubuntu 18.04

I have put into the top of my git repository the file .mdlrc with contents:

verbose true
exclude_rule 'MD004'
exclude_rule 'MD005'
exclude_rule 'MD007'
exclude_rule 'MD012'
exclude_rule 'MD013'
exclude_rule 'MD019'
exclude_rule 'MD033'
exclude_rule 'MD034'
exclude_rule 'MD046'

the verbose setting definitely has an effect on the output of mdl but I cannot get the exclude_rule to work.

Also it appears that I had to execute

sudo gem install mdl

to get mdl install on the command line. I understand that pre-commit would have installed mdl under ~/.cache/pre-commit.

Could it be that the .mdlrc included with your pre-commit-hook is over ridding my repository's .mdlrc?

Error running pre-commit with shellcheck

When running pre-commit run --all-files on Mac OS X 10.15.7 (bash 5.1.4) with the following .pre-commit-config.yaml

an error is thrown

[ERROR] The hook shellcheckspecifiesadditional_dependenciesbut is using languagescript which does not install an environment. Perhaps you meant to use a specific language?

I have attempted to add additional configuration such as 'additional_dependencies' and 'language' but can't seem to get past this one. Is there some configuration missing that I cannot determine from the documentation?

check-mailmap always fails if `log.showSignature` is enabled in `gitconfig`

Detect if an email address needs to be added to mailmap.......................Failed
- hook id: check-mailmap
- exit code: 1

The following email addresses are associated with more than one name:

        0723
        [expired]
        [ultimate]
        [unknown]
        eest
        eet
        match
        messages.
        minutes.
        past

The associations include:


     19      4 minutes.  Encrypted 0 messages.
    409      Encrypted 0 messages.

after which there will be names and emails.

To reproduce, in repository that contains signed commits,

  1. Enable the check-mailmap pre-commit hook
  - repo: https://github.com/jumanjihouse/pre-commit-hooks
    rev: 3.0.0
    hooks:
      - id: bundler-audit
      - id: check-mailmap
  1. git config log.showSignature true
  2. pre-commit run --all-files

This check needs shfmt from ...

Check shell style with shfmt................................................Failed
- hook id: shfmt
- exit code: 1

This check needs shfmt from https://github.com/mvdan/sh/releases
This check needs shfmt from https://github.com/mvdan/sh/releases

Build: 786160960

I'm using pre-commit/[email protected]

It works on my local, but not on GitHub Actions. So I'm not sure what's the problem.

script-must-have-extension gets confused if path contains a dot

Both script-must-have-extension and script-must-not-have-extension fail on files that don't have an extension but do have a dot in the path leading up to them. Here are some pathological examples:

my_dir/.foo/executable_script # script-must-not-have-extension complains
my_dir/.foo/non_executable_script # script-must-have-extension does not complain

Scripts that begin with a dot are also problematic. For example: my_dir/.script

Some script hooks do not work on Windows

When running pre-commit on Windows 10, the Hooks check-mailmap, forbid-binary, forbid-space-in-indent, git-check, git-dirty, and shellcheck all Report Executable /bin/sh not found:

$ pre-commit run -a
Detect if an email address needs to be added to mailmap.......................Failed
- hook id: check-mailmap
- exit code: 1

Executable `/bin/sh` not found

Forbid binaries...............................................................Failed
- hook id: forbid-binary
- exit code: 1

Executable `/bin/sh` not found

Forbid spaces in indentation..................................................Failed
- hook id: forbid-space-in-indent
- exit code: 1

Executable `/bin/sh` not found

Check for conflict markers and core.whitespace errors.........................Failed
- hook id: git-check
- exit code: 1

Executable `/bin/sh` not found

Check if the git tree is dirty................................................Failed
- hook id: git-dirty
- exit code: 1

Executable `/bin/sh` not found

Test shell scripts with shellcheck............................................Failed
- hook id: shellcheck
- exit code: 1

Executable `/bin/sh` not found

When changing their Shebang to #!/usr/bin/env bash, they work correctly:

$ pre-commit run -a
Detect if an email address needs to be added to mailmap.......................Passed
Forbid binaries...............................................................Failed
- hook id: forbid-binary
- exit code: 1

[ERROR] demo.gif appears to be a binary file
[ERROR] addons/gut/fonts/CourierPrime-Italic.ttf appears to be a binary file
[ERROR] addons/gut/fonts/AnonymousPro-BoldItalic.ttf appears to be a binary file
[ERROR] addons/gut/fonts/CourierPrime-Bold.ttf appears to be a binary file
[ERROR] addons/gut/fonts/AnonymousPro-Bold.ttf appears to be a binary file
[ERROR] addons/gut/fonts/LobsterTwo-Bold.ttf appears to be a binary file
[ERROR] addons/gut/fonts/LobsterTwo-Regular.ttf appears to be a binary file
[ERROR] addons/gut/fonts/AnonymousPro-Italic.ttf appears to be a binary file
[ERROR] addons/gut/source_code_pro.fnt appears to be a binary file
[ERROR] addons/gut/fonts/CourierPrime-Regular.ttf appears to be a binary file
[ERROR] addons/gut/fonts/LobsterTwo-Italic.ttf appears to be a binary file
[ERROR] addons/gut/icon.png appears to be a binary file
[ERROR] addons/gut/fonts/CourierPrime-BoldItalic.ttf appears to be a binary file
[ERROR] addons/gut/fonts/AnonymousPro-Regular.ttf appears to be a binary file
[ERROR] addons/gut/fonts/LobsterTwo-BoldItalic.ttf appears to be a binary file
[ERROR] icon.png appears to be a binary file

Forbid spaces in indentation..................................................Failed
- hook id: forbid-space-in-indent
- exit code: 1

file_format.sh

Found space(s) within indentation in the above file(s).
addons/gut/gut_plugin.gd

Found space(s) within indentation in the above file(s).
gut.sh

Found space(s) within indentation in the above file(s).
.gutconfig.json
test/integration/test_hello_world.gd

Found space(s) within indentation in the above file(s).
test/unit/test_hello_world.gd

Found space(s) within indentation in the above file(s).

Check for conflict markers and core.whitespace errors.........................Passed
Check if the git tree is dirty................................................Failed
- hook id: git-dirty
- exit code: 1

M  .pre-commit-config.yaml
M  .pre-commit-config.yaml
M  .pre-commit-config.yaml
M  .pre-commit-config.yaml
M  .pre-commit-config.yaml
M  .pre-commit-config.yaml
M  .pre-commit-config.yaml
M  .pre-commit-config.yaml

Test shell scripts with shellcheck............................................Failed
- hook id: shellcheck
- exit code: 127

C:\Users\scher\.cache\pre-commit\repo0l4uhq52\pre_commit_hooks\shellcheck: line 13: shellcheck: command not found

Markdownlint fails with error in ruby gem install fake_gem__-0.0.0gem

Ok I've narrowed this down to markdownlint when I run pre-commit run --all-files with

- repo: https://github.com/jumanjihouse/pre-commit-hooks
  rev: 2.1.5
  hooks:
     -id: markdownlint

I get the errpr complaining about installation of fake gems. I'm on MacoS Big Sur with brew install rudy and ruby --version is '3.0.0p0`; so wondering if markdownlint does not get along with ruby 3.0?

[INFO] Installing environment for https://github.com/jumanjihouse/pre-commit-hooks.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
An unexpected error has occurred: CalledProcessError: command: ('/usr/local/Cellar/ruby/3.0.0_1/bin/ruby', '/usr/local/opt/ruby/bin/gem', 'install', '--no-document', '--no-format-executable', 'fake_gem__-0.0.0.gem')
return code: 1
expected return code: 0
stdout: (none)
stderr:
    ERROR:  While executing gem ... (NoMethodError)
        undefined method `request' for nil:NilClass

git-check checks all files, not just changed?

Thanks for writing the git-check plug-in! I was surprised, though, to find that it checks my whole tree, not just staged changes against the prior commit (if any).

Should it be calling git diff-index with --cached, and preferring HEAD, when it exists, to ${EMPTY_COMMIT}?

script-must-(not)-have-extension hook does report false results on Windows

Windows does not have a concept of executable , thus Identify which is used be pre-commit, reports all files as executable on Windows, even if git itself is aware which files are executable.
This makes the script-must-have-extension and script-must-not-have-extension hooks useless on Windows.
pre-commit themselves had the the same problem pre-commit/pre-commit-hooks#435

$ pre-commit run -a
Non-executable shell script filename ends in .sh.......(no files to check)Skipped
Executable shell script omits the filename extension.......................Failed
- hook id: script-must-not-have-extension
- exit code: 1

[ERROR] gut-copy.sh has an extension but should not
[ERROR] gut.sh has an extension but should not

$ identify-cli gut.sh
["executable", "file", "shell", "text"]

$ identify-cli gut-copy.sh
["executable", "file", "shell", "text"]

$ git ls-files -s gut.sh
100755 57765ec5365a5d2da0de57ecb31fbeee2bdbb7d4 0       gut.sh

$ git ls-files -s gut-copy.sh
100644 57765ec5365a5d2da0de57ecb31fbeee2bdbb7d4 0       gut-copy.sh

`require-ascii` doesn’t do what it says on the tin

According to the README:

require-ascii

What it does

Requires that text files have ascii-encoding, including the
extended ascii set.
This is useful to detect files that have unicode characters.

require-ascii will fail on files that are encoded in extended ASCII if:

  1. the file uses characters in the 128–255 range, and
  2. those characters aren’t followed by other characters that coincidentally make the sequence valid UTF-8 (see this table).

This script will generate a bunch of files that contain valid extended ASCII but fail when tested by require-ascii:

# The README links to <https://theasciicode.com.ar/>. There's many different
# ways you could extend ASCII, but that site in particular says "In 1981,
# IBM developed an extension of 8-bit ASCII code, called 'code page 437'..."
extended_ascii = "cp437"

for code_point in range(128, 256):
	# Create a file that should pass require-ascii, but won't.
	with open(f"{code_point}.cp437.txt", mode='wb') as file:
		file.write(code_point.to_bytes(1, 'little'))
	# Make sure that that file really does contain valid extended ASCII.
	with open(f"{code_point}.cp437.txt", mode='rt', encoding=extended_ascii) as file:
		# This should cause a UnicodeDecodeError if file contains
		# invalid extended ASCII.
		file.read()

A more accurate description of require-ascii would be:

require-ascii

What it does

Requires that text files use UTF-8 and only use code points ≤ 255.

False Positive On Second Commit in Repo

protect-first-parent reports an error when attempting to commit the second commit in a repository.

Protect first parent..........................................................Failed
- hook id: protect-first-parent
- exit code: 1

[ERROR] Foxtrot merge

Maybe you deleted a commit that was already pushed.
Maybe you ran "git pull" without the --rebase flag.

A possible fix is to run these commands client-side before pushing:

    git fetch --all
    git rebase main

Check the result with "git log --graph" before pushing again.

[FAIL] See errors above for /home/kurt/.cache/pre-commit/repoyqzer_ly/pre_commit_hooks/protect-first-parent

While testing this again on a fresh repository, I also see the following:

fatal: ambiguous argument 'main^..': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

It doesn't make any difference whether the second commit is to the default branch or a feature branch. The second case seems obviously caused by the attempt to get the commit before the HEAD of main, and presumably this also causes a crash for the initial commit to a repository. Since the HEAD of main is the initial commit, this fails. I don't understand what causes the first case yet though.

pre-commit hook shfmt does not work when commit from phpstorm

Hello,
If I commit from shell, everything is working correctly
But when I commit from phpstorm I have the following error
This check needs shfmt from https://github.com/mvdan/sh/releases

Full output

[WARNING] Unstaged files detected.
[INFO] Stashing unstaged files to /home/wsl/.cache/pre-commit/patch1647693104-25398.
mixed line ending........................................................Passed
fix end of files.........................................................Passed
check that executables have shebangs.....................................Passed
check that scripts with shebangs are executable..........................Passed
check xml............................................(no files to check)Skipped
check yaml...........................................(no files to check)Skipped
forbid new submodules................................(no files to check)Skipped
mixed line ending........................................................Passed
check json...........................................(no files to check)Skipped
Test shell scripts with shellcheck.......................................Passed
Check shell style with shfmt.............................................Failed
- hook id: shfmt
- exit code: 1
This check needs shfmt from https://github.com/mvdan/sh/releases
pyupgrade............................................(no files to check)Skipped
[INFO] Restored changes from /home/wsl/.cache/pre-commit/patch1647693104-25398.

Note that I'm using Phpstorm from windows with a mounted project in wsl
only shfmt seems to fail, other plugins seems to work

Error in pre-commit run [ERROR: Error installing fake_gem__-0.0.0.gem:]

Hello Team,

I'm trying to run pre-commit run -a which fails with below error:

[INFO] Installing environment for https://github.com/jumanjihouse/pre-commit-hooks.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
An unexpected error has occurred: CalledProcessError: command: ('/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby', '/usr/bin/gem', 'install', '--no-document', '--no-format-executable', '--no-user-install', '--install-dir', '/Users/kaveri.lolge/.cache/pre-commit/repod4b_9tky/rbenv-system/gems', '--bindir', '/Users/kaveri.lolge/.cache/pre-commit/repod4b_9tky/rbenv-system/gems/bin', 'fake_gem__-0.0.0.gem')
return code: 1
stdout:
    Successfully installed unicode-display_width-1.4.1
    Successfully installed ruby-progressbar-1.13.0
    Successfully installed rainbow-3.1.1
    Successfully installed powerpack-0.1.3
    Successfully installed ast-2.4.2
    Successfully installed parser-2.5.3.0
    Successfully installed parallel-1.23.0
    Building native extensions. This could take a while...
stderr:
    ERROR:  Error installing fake_gem__-0.0.0.gem:
        ERROR: Failed to build gem native extension.

Could you please help me fix this issue?

Thanks

(INVALID) Shell check download url has changed upstream.

INVALID you don't install shell check for us, we have it installed on our systems via packer
you can close this out as invalid.

Currently bumping our version of jumanjihouse/pre-commit-hooks to 2.1.4 to test if it's fixed.
EDIT:
same issue found with with 2.1.4

  - repo: https://github.com/jumanjihouse/pre-commit-hooks
    sha: 2.1.4
    hooks:
      - id: shellcheck
        exclude: >
            (?x)^(
                jjb/global-jjb/.*|
                jenkins-config/.*
            )$

Seeing this new error in our build logs.
our .pre-commit-config.yaml

   - repo: https://github.com/jumanjihouse/pre-commit-hooks
     sha: 2.0.2
     hooks:
       - id: shellcheck
         exclude: >
             (?x)^(
                 jjb/global-jjb/.*|
                 jenkins-config/.*
             )$

our tox.ini

[testenv:pre-commit]
basepython = python3
deps = pre-commit
commands =
    pre-commit install --hook-type commit-msg
    pre-commit run --all-files --show-diff-on-failure
    pre-commit run gitlint --hook-stage commit-msg --commit-msg-filename .git/COMMIT_EDITMSG


12:05:13 Test shell scripts with shellcheck.......................................Failed
12:05:13 - hook id: shellcheck
12:05:13 - exit code: 1
12:05:13 
12:05:13 You are downloading ShellCheck from the wrong URL!
12:05:13 
12:05:13 Please update to the correct URL:
12:05:13 https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz
12:05:13 
12:05:13 For more information, see:
12:05:13 https://github.com/koalaman/shellcheck/issues/1871
12:05:13 You are downloading ShellCheck from the wrong URL! https://git.opendaylight.org/gerrit/c/releng/builder/+/91779 

12:05:13 
12:05:13 Please update to the correct URL:
12:05:13 https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.x86_64.tar.xz
12:05:13 
12:05:13 For more information, see:
12:05:13 https://github.com/koalaman/shellcheck/issues/1871
12:05:13

shfmt hook whitespace in filename

Hi

Thanks for your work!

It seems the shfmt hook does not respect whitespaces in filename:

[RUN] shfmt -w -i 2 Test/Script Test1.sh Test/Script Test2.sh
lstat Test/Script: no such file or directory
lstat Test1.sh: no such file or directory
lstat Test/Script: no such file or directory
lstat Test2.sh: no such file or directory

pre-commit fails with Alpine 3.15

We were using Alpine 3.13 so far and upgrading to Alping 3.15 got in an upgrade of ruby to v3.0.3-r0, among other things.

I install ruby in my image:

...
        ruby=3.0.3-r0 \
        ruby-dev=3.0.3-r0 \
...

And then install pre-commit with version pre-commit==2.17.0.

However after all this, pre-commit install in my container fails with:

[INFO] Installing environment for https://github.com/jumanjihouse/pre-commit-hooks.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
An unexpected error has occurred: CalledProcessError: command: ('/usr/bin/ruby', '/usr/bin/gem', 'install', '--no-document', '--no-format-executable', 'fake_gem__-0.0.0.gem')
return code: 1
expected return code: 0
stdout: (none)
stderr:
    ERROR:  While executing gem ... (Gem::DependencyResolutionError)
        conflicting dependencies rubocop (>= 0.71.0) and rubocop (= 1.10.0)
      Activated rubocop-1.10.0
      which does not match conflicting dependency (>= 0.71.0)
    
      Conflicting dependency chains:
        fake_gem__ (= 0.0.0), 0.0.0 activated, depends on
        rubocop (= 1.10.0), 1.10.0 activated
    
      versus:
        fake_gem__ (= 0.0.0), 0.0.0 activated, depends on
        rubocop-performance (= 1.6.1), 1.6.1 activated, depends on
        rubocop (>= 0.71.0)
    
    
Check the log at /root/.cache/pre-commit/pre-commit.log

The log file has:

### version information
pre-commit version: 2.17.0
git --version: git version 2.34.1
sys.version:
    3.9.7 (default, Nov 24 2021, 21:15:59) 
    [GCC 10.3.1 20211027]
sys.executable: /usr/bin/python3
os.name: posix
sys.platform: linux

### error information

An unexpected error has occurred: CalledProcessError: command: ('/usr/bin/ruby', '/usr/bin/gem', 'install', '--no-document', '--no-format-executable', 'fake_gem__-0.0.0.gem')
return code: 1
expected return code: 0
stdout: (none)
stderr:
    ERROR:  While executing gem ... (Gem::DependencyResolutionError)
        conflicting dependencies rubocop (>= 0.71.0) and rubocop (= 1.10.0)
      Activated rubocop-1.10.0
      which does not match conflicting dependency (>= 0.71.0)
    
      Conflicting dependency chains:
        fake_gem__ (= 0.0.0), 0.0.0 activated, depends on
        rubocop (= 1.10.0), 1.10.0 activated
    
      versus:
        fake_gem__ (= 0.0.0), 0.0.0 activated, depends on
        rubocop-performance (= 1.6.1), 1.6.1 activated, depends on
        rubocop (>= 0.71.0)
    
Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/pre_commit/error_handler.py", line 70, in error_handler
    yield
  File "/usr/lib/python3.9/site-packages/pre_commit/main.py", line 396, in main
    return run(args.config, store, args)
  File "/usr/lib/python3.9/site-packages/pre_commit/commands/run.py", line 416, in run
    install_hook_envs(to_install, store)
  File "/usr/lib/python3.9/site-packages/pre_commit/repository.py", line 224, in install_hook_envs
    _hook_install(hook)
  File "/usr/lib/python3.9/site-packages/pre_commit/repository.py", line 82, in _hook_install
    lang.install_environment(
  File "/usr/lib/python3.9/site-packages/pre_commit/languages/ruby.py", line 135, in install_environment
    helpers.run_setup_cmd(
  File "/usr/lib/python3.9/site-packages/pre_commit/languages/helpers.py", line 52, in run_setup_cmd
    cmd_output_b(*cmd, cwd=prefix.prefix_dir, **kwargs)
  File "/usr/lib/python3.9/site-packages/pre_commit/util.py", line 154, in cmd_output_b
    raise CalledProcessError(returncode, cmd, retcode, stdout_b, stderr_b)
pre_commit.util.CalledProcessError: command: ('/usr/bin/ruby', '/usr/bin/gem', 'install', '--no-document', '--no-format-executable', 'fake_gem__-0.0.0.gem')
return code: 1
expected return code: 0
stdout: (none)
stderr:
    ERROR:  While executing gem ... (Gem::DependencyResolutionError)
        conflicting dependencies rubocop (>= 0.71.0) and rubocop (= 1.10.0)
      Activated rubocop-1.10.0
      which does not match conflicting dependency (>= 0.71.0)
    
      Conflicting dependency chains:
        fake_gem__ (= 0.0.0), 0.0.0 activated, depends on
        rubocop (= 1.10.0), 1.10.0 activated
    
      versus:
        fake_gem__ (= 0.0.0), 0.0.0 activated, depends on
        rubocop-performance (= 1.6.1), 1.6.1 activated, depends on
        rubocop (>= 0.71.0)

I have tried downgrading virtualenv to 20.0.33 (but I do not know how this is related), and there has been no change.

Has anyone made pre-commit work with the latest Alpine 3.15 stable image?

Potential bug: forbid-binary with git-lfs

Upstream issue: pre-commit/pre-commit#3028.

Summary

Tried to add a file to git lfs and this broke the forbid-binary hook.

Description

bash:

git lfs track "*.pdf"
git add foo.pdf && git commit -m "chore: Test LFS"

This now fails since the files are binary, even though they're stored as pointers:

Forbid binaries..........................................................Failed
- hook id: forbid-binary
- exit code: 1

Additional info

pre-commit --version
pre-commit 3.3.3

.pre-commit-config.yaml:

- repo: https://github.com/jumanjihouse/pre-commit-hooks
  rev: 3.0.0
  hooks:
  - id: forbid-binary

Proposed solution(s)

Maybe there's an easy fix around this, potentially even looking at .gitattributes?

post-merge doesn't seem to find files to check

I want to trigger a custom commit hook on post merge, ideally with a list of of incoming file changes.

Custom hook config:

-   id: run-pbi-tools-post-merge
    name: pbi-tools compile (post merge)
    description: invoke pbi-tools to compile powerbi proj-folders into reports
    entry: run-pbi-tools-post-merge
    language: python
    files: ''                   # all files
    require_serial: true        # no parallel invocation
    verbose: true
    stages: [post-merge]

Client-side repo config:

repos:
- [...]
-   repo: https://github.com/myorg/precommit_hooks
    rev: 0.1.3
    hooks:
    -   id: run-pbi-tools-post-merge

I've installed pre-commit for post-merge (pre-commit install -t post-merge), however pre-commit isn't invoking the hook:

git pull
Updating 87c6d50..f51cb2a
Fast-forward
 trigger.txt | Bin 0 -> 82 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 trigger.txt
pbi-tools compile (post merge).......................(no files to check)Skipped
- hook id: run-pbi-tools-post-merge

I would expect the hook to be invoked for trigger.txt.

Is this a misconception on my end?

Feature Request: check-mailmap alphabetize

I am a fan of check-mailmap and use this hook.

I think it would be cool if check-mailmap had an argument to confirm the .mailmap is alphabetically ordered.

Bonus points: in-place modify the .mailmap to be alphabetic, similar to how an autoformatter pre-commit hook (e.g. black, isort) would do.

Trailing whitespaces for Jinja2 (.j2) files

I've a simple file template.j2:

/**
 * @file
 * My file
 */

which doesn't have any trailing whitespace, however the hook reports otherwise in every single line.

I'm using .j2 extension as this is a Jinja2 template. If I change to .j3 it works fine.

$  pre-commit run -a
Check for conflict markers and core.whitespace errors.......................Failed
- hook id: git-check
- exit code: 2

template.j2:1: trailing whitespace.
+/**
template.j2:2: trailing whitespace.
+ * @file
template.j2:3: trailing whitespace.
+ * My file
template.j2:4: trailing whitespace.
+ */

My .pre-commit-config.yaml:

---
repos:
  - repo: https://github.com/jumanjihouse/pre-commit-hooks
    rev: master
    hooks:
      - id: git-check

I've tried to add exclude: '(\.j2)$' but it didn't help.

require-ascii.py syntax is incompatible with python 3

when running with require-ascii enabled, on python version 3.6, on OSX, the following error is observed:
Check file encoding.........................................................Failed
hookid: require-ascii

File "/Users/dstull/.cache/pre-commit/repojmex2sqj/py_env-python3.6/bin/require-ascii.py", line 26
print result.ljust(8) + filename.ljust(50),
^
SyntaxError: invalid syntax

I believe in python 3, print is a function and perhaps a wrapping of this line with () would fix it

confirmed - this makes the error go away:

    print(result.ljust(8) + filename.ljust(50)),
    print(dict)

require-ascii: Allow extended ASCII characters

Check file encoding.........................................................Failed
- hook id: require-ascii
- exit code: 1

README.md: line 270 column 11 character "©" (decimal 169)

I'd like to exclude the copyright character from README ("©"), is that possible, without disabling the whole hook?

Install fails with ruby 3.0

(Pointing instead to Ruby 2.7 works fine)

$ pre-commit run --all-files
[INFO] Installing environment for https://github.com/jumanjihouse/pre-commit-hooks.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
An unexpected error has occurred: CalledProcessError: command: ('/opt/local/bin/ruby3.0', '/opt/local/bin/gem', 'install', '--no-document', '--no-format-executable', 'fake_gem__-0.0.0.gem')
return code: 1
expected return code: 0
stdout: (none)
stderr:
    ERROR:  While executing gem ... (Gem::DependencyResolutionError)
        conflicting dependencies rubocop (>= 0.68.1) and rubocop (= 1.10.0)
      Activated rubocop-1.10.0
      which does not match conflicting dependency (>= 0.68.1)
    
      Conflicting dependency chains:
        fake_gem__ (= 0.0.0), 0.0.0 activated, depends on
        rubocop (= 1.10.0), 1.10.0 activated
    
      versus:
        fake_gem__ (= 0.0.0), 0.0.0 activated, depends on
        rubocop-rspec (= 1.40.0), 1.40.0 activated, depends on
        rubocop (>= 0.68.1)

Support for Ruby 3

$ pre-commit run -a
heck markdown files........................................................Failed
- hook id: markdownlint
- exit code: 1

Executable `/usr/bin/ruby2.7` not found

$ which -a ruby
/usr/bin/ruby
/bin/ruby

$ ruby --version
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux-gnu]

I'm using the following version:

  - repo: https://github.com/jumanjihouse/pre-commit-hooks
    rev: 2.1.6
    hooks:
      - id: markdownlint  # Configure in .mdlrc

CalledProcessError: command: ('/usr/bin/ruby', '/usr/bin/gem', 'install', '--no-document', '--no-format-executable', 'fake_gem__-0.0.0.gem')

Since upgrade ruby v3 I got this error when I try to do git commit/push =>

[INFO] Installing environment for https://github.com/jumanjihouse/pre-commit-hooks.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
An unexpected error has occurred: CalledProcessError: command: ('/usr/bin/ruby', '/usr/bin/gem', 'install', '--no-document', '--no-format-executable', 'fake_gem__-0.0.0.gem')
return code: 1
expected return code: 0
stdout: (none)
stderr:
    ERROR:  While executing gem ... (NoMethodError)
        undefined method `request' for nil:NilClass

My .pre-commit-config.yaml =>

---
repos:
 - repo: https://github.com/pre-commit/pre-commit-hooks
   rev: v3.4.0
   hooks:
    - id: trailing-whitespace
    - id: end-of-file-fixer
    - id: check-added-large-files
 - repo: https://github.com/jumanjihouse/pre-commit-hooks
   rev: 2.1.5
   hooks:
    - id: markdownlint
 - repo: https://github.com/adrienverge/yamllint.git
   rev: v1.26.0
   hooks:
    - id: yamllint

UnicodeDecodeError not handled in 'require-ascii'

I have modified it like this to work for my needs:

"""
require-ascii
"""

# http://python-future.org/compatible_idioms.html
from __future__ import print_function

import sys

status = 0

for filename in sys.argv:
    line_num = 0
    with open(filename, 'r', encoding='UTF-8') as fh:
        while True:
            line_num += 1
            try:
                line = fh.readline()
            except UnicodeDecodeError as e:
                print(f"{filename}: line {line_num} " + str(e))
                status = 1

            if not line:
                break

            col_num = 0
            for char in line:
                col_num += 1
                if ord(char) > 127:
                    print(
                        f"{filename}: line {line_num} column {col_num} " +
                        f"character \"{char}\" (decimal {ord(char)})"
                        )
                    status = 1

sys.exit(status)

This could probably be extended to provide column information too.

Support for perltidy

Wondering if you would like add support for [perltidy[(http://perltidy.sourceforge.net). We have been using it as a local hook and are looking to put it in a repo.

Thanks and let me know,
Map

create hook for bundler-audit

https://github.com/rubysec/bundler-audit

example invocation:

# Run a Security Audit of Gems used in Gemfile.lock
# note the below requires internet access
bundle-audit check --ignore CVE-2018-16476 --update

caveats:

  • ensure it finds correct bundle files
  • check if bundler-audit can be configured by an rc file to avoid CLI options (see also #15)

Executable `/usr/bin/ruby2.5` not found

The following error happens on GitHub Actions. I believe Ruby is installed fine.

Check markdown files.....................................................Failed
- hook id: markdownlint
- exit code: 1

Executable `/usr/bin/ruby2.5` not found

Any clues? This was working before.

Config:

  - repo: https://github.com/jumanjihouse/pre-commit-hooks
    rev: master
    hooks:
      - id: markdownlint

create hook to check mailmap

Background

git shortlog -sn is useful to summarize contributions to a git repo.

However, it gets muddy when an email address is associated with multiple names.
Reasons include:

  • the author's full name was messed up and/or
  • not always written the same way
  • the author has multiple email addresses

Create a pre-commit hook that detects botched translations.

Hook source

https://gist.github.com/jumanjiman/75616ec91f115abba0cde6f47bea2cb4

Sample outputs

Good condition

$ pre-commit run check-mailmap --all-files --verbose
[check-mailmap] Detect if an email address needs to be added to mailmap.......................Passed

Bad condition

$ pre-commit run check-mailmap --all-files --verbose
[check-mailmap] Detect if an email address needs to be added to mailmap.......................Failed
hookid: check-mailmap

The following email addresses are associated with more than one name:

        [email protected]
        [email protected]

The associations include:

     13 John Doe <[email protected]>
      4 jdoe <[email protected]>

      2 Billy Bob <[email protected]>
      2 Bubba <[email protected]>

False Positive When A Pushed Commit Is Amended

protect-first-parent reports an error once you amend a commit that has already been pushed to a feature branch even though this doesn't constitute a foxtrot merge.

Protect first parent..........................................................Failed
- hook id: protect-first-parent
- exit code: 1

[ERROR] Foxtrot merge

Maybe you deleted a commit that was already pushed.
Maybe you ran "git pull" without the --rebase flag.

A possible fix is to run these commands client-side before pushing:

    git fetch --all
    git rebase origin/pre-commit

Check the result with "git log --graph" before pushing again.

Perhaps a distinction should be made between the default branch and other branches?

consider filter/replace for unicode chars

The require-ascii hook fails if it detects unicode.

Current: it makes best-effort to show the offending character along with column/line number.
example:

path/to/filename: line 1773 column 39 character "’" (decimal 8217)

Consider: Add option to automatically replace (rewrite) offending characters with ascii equivalent.
e.g., replace unicode 8217 with ascii apostrophe.

allow bundler-audit to switch directory to ruby project path

currently when running bundler-audit, it must be ran inside the directory where .bundle directory and the Gemfile.lock file exists - see this issue for enhancement on that package: rubysec/bundler-audit#178 and code which is currently unreachable in that gem from the command line where it is set on the PWD: https://github.com/rubysec/bundler-audit/blob/master/lib/bundler/audit/scanner.rb#L42

until this is resolved, I need the ability to run this check and not assume the current working directory has the .bundle and Gemfile.lock

see this run from one directory above www (where the Gemfile.lock exists)

12:27 $ pre-commit run bundler-audit --all-files --verbose
[bundler-audit] Patch-level verification for bundler.......................Failed
hookid: bundler-audit

args: --update

Updating ruby-advisory-db ...
From https://github.com/rubysec/ruby-advisory-db
 * branch            master     -> FETCH_HEAD
Already up to date.
Updated ruby-advisory-db
ruby-advisory-db: 331 advisories
/Users/dstull/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-audit-0.6.0/lib/bundler/audit/scanner.rb:43:in `read': No such file or directory @ rb_sysopen - /Users/dstull/rails/configbuilder/Gemfile.lock (Errno::ENOENT)
	from /Users/dstull/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-audit-0.6.0/lib/bundler/audit/scanner.rb:43:in `initialize'
	from /Users/dstull/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-audit-0.6.0/lib/bundler/audit/cli.rb:41:in `new'
	from /Users/dstull/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-audit-0.6.0/lib/bundler/audit/cli.rb:41:in `check'
	from /Users/dstull/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/thor-0.20.3/lib/thor/command.rb:27:in `run'
	from /Users/dstull/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'
	from /Users/dstull/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/thor-0.20.3/lib/thor.rb:387:in `dispatch'
	from /Users/dstull/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/thor-0.20.3/lib/thor/base.rb:466:in `start'
	from /Users/dstull/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/bundler-audit-0.6.0/bin/bundle-audit:10:in `<top (required)>'
	from /Users/dstull/.rbenv/versions/2.3.1/bin/bundle-audit:23:in `load'
	from /Users/dstull/.rbenv/versions/2.3.1/bin/bundle-audit:23:in `<main>'

it would be nice if the run here accepted an argument that would be the directory that those files exist in, change directory, run check, then come back to original directory after the hook has ran

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.