File tree Expand file tree Collapse file tree 6 files changed +93
-0
lines changed
Expand file tree Collapse file tree 6 files changed +93
-0
lines changed Original file line number Diff line number Diff line change 5151 # for backward compatibility
5252 files : ' '
5353 minimum_pre_commit_version : 0.15.0
54+ - id : check-executables-have-shebangs
55+ name : Check that executables have shebangs
56+ description : Ensures that (non-binary) executables have a shebang.
57+ entry : check-executables-have-shebangs
58+ language : python
59+ types : [text, executable]
60+ # for backward compatibility
61+ files : ' '
62+ minimum_pre_commit_version : 0.15.0
5463- id : check-json
5564 name : Check JSON
5665 description : This hook checks json files for parseable syntax.
Original file line number Diff line number Diff line change @@ -34,6 +34,8 @@ Add this to your `.pre-commit-config.yaml`
3434 case-insensitive filesystem like MacOS HFS+ or Windows FAT.
3535- ` check-docstring-first ` - Checks for a common error of placing code before
3636 the docstring.
37+ - ` check-executables-have-shebangs ` - Checks that non-binary executables have a
38+ proper shebang.
3739- ` check-json ` - Attempts to load all json files to verify syntax.
3840- ` check-merge-conflict ` - Check for files that contain merge conflict strings.
3941- ` check-symlinks ` - Checks for symlinks which do not point to anything.
Original file line number Diff line number Diff line change 3434 entry : upgrade-your-pre-commit-version
3535 files : ' '
3636 minimum_pre_commit_version : 0.15.0
37+ - id : check-executables-have-shebangs
38+ language : system
39+ name : upgrade-your-pre-commit-version
40+ entry : upgrade-your-pre-commit-version
41+ files : ' '
42+ minimum_pre_commit_version : 0.15.0
3743- id : check-json
3844 language : system
3945 name : upgrade-your-pre-commit-version
Original file line number Diff line number Diff line change 1+ """Check that executable text files have a shebang."""
2+ from __future__ import absolute_import
3+ from __future__ import print_function
4+ from __future__ import unicode_literals
5+
6+ import argparse
7+ import pipes
8+ import sys
9+
10+
11+ def check_has_shebang (path ):
12+ with open (path , 'rb' ) as f :
13+ first_bytes = f .read (2 )
14+
15+ if first_bytes != b'#!' :
16+ print (
17+ '{path}: marked executable but has no (or invalid) shebang!\n '
18+ " If it isn't supposed to be executable, try: chmod -x {quoted}\n "
19+ ' If it is supposed to be executable, double-check its shebang.' .format (
20+ path = path ,
21+ quoted = pipes .quote (path ),
22+ ),
23+ file = sys .stderr ,
24+ )
25+ return 1
26+ else :
27+ return 0
28+
29+
30+ def main (argv = None ):
31+ parser = argparse .ArgumentParser (description = __doc__ )
32+ parser .add_argument ('filenames' , nargs = '*' )
33+ args = parser .parse_args (argv )
34+
35+ retv = 0
36+
37+ for filename in args .filenames :
38+ retv |= check_has_shebang (filename )
39+
40+ return retv
Original file line number Diff line number Diff line change 3939 'check-byte-order-marker = pre_commit_hooks.check_byte_order_marker:main' ,
4040 'check-case-conflict = pre_commit_hooks.check_case_conflict:main' ,
4141 'check-docstring-first = pre_commit_hooks.check_docstring_first:main' ,
42+ 'check-executables-have-shebangs = pre_commit_hooks.check_executables_have_shebangs:main' ,
4243 'check-json = pre_commit_hooks.check_json:check_json' ,
4344 'check-merge-conflict = pre_commit_hooks.check_merge_conflict:detect_merge_conflict' ,
4445 'check-symlinks = pre_commit_hooks.check_symlinks:check_symlinks' ,
Original file line number Diff line number Diff line change 1+ # -*- coding: utf-8 -*-
2+ from __future__ import absolute_import
3+ from __future__ import unicode_literals
4+
5+ import pytest
6+
7+ from pre_commit_hooks .check_executables_have_shebangs import main
8+
9+
10+ @pytest .mark .parametrize ('content' , (
11+ b'#!/bin/bash\n hello world\n ' ,
12+ b'#!/usr/bin/env python3.6' ,
13+ b'#!python' ,
14+ '#!☃' .encode ('UTF-8' ),
15+ ))
16+ def test_has_shebang (content , tmpdir ):
17+ path = tmpdir .join ('path' )
18+ path .write (content , 'wb' )
19+ assert main ((path .strpath ,)) == 0
20+
21+
22+ @pytest .mark .parametrize ('content' , (
23+ b'' ,
24+ b' #!python\n ' ,
25+ b'\n #!python\n ' ,
26+ b'python\n ' ,
27+ '☃' .encode ('UTF-8' ),
28+
29+ ))
30+ def test_bad_shebang (content , tmpdir , capsys ):
31+ path = tmpdir .join ('path' )
32+ path .write (content , 'wb' )
33+ assert main ((path .strpath ,)) == 1
34+ _ , stderr = capsys .readouterr ()
35+ assert stderr .startswith ('{}: marked executable but' .format (path .strpath ))
You can’t perform that action at this time.
0 commit comments