Skip to content

Commit 5d08e77

Browse files
authored
Merge pull request #241 from pre-commit/check_vcs_permalinks
Add hook for ensuring vcs permalinks
2 parents dec98f7 + 9db0a74 commit 5d08e77

File tree

6 files changed

+96
-0
lines changed

6 files changed

+96
-0
lines changed

.pre-commit-hooks.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@
9696
# for backward compatibility
9797
files: ''
9898
minimum_pre_commit_version: 0.15.0
99+
- id: check-vcs-permalinks
100+
name: Check vcs permalinks
101+
description: Ensures that links to vcs websites are permalinks.
102+
entry: check-vcs-permalinks
103+
language: python
104+
types: [text]
105+
# for backward compatibility
106+
files: ''
107+
minimum_pre_commit_version: 0.15.0
99108
- id: check-xml
100109
name: Check Xml
101110
description: This hook checks xml files for parseable syntax.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Add this to your `.pre-commit-config.yaml`
4040
- `check-json` - Attempts to load all json files to verify syntax.
4141
- `check-merge-conflict` - Check for files that contain merge conflict strings.
4242
- `check-symlinks` - Checks for symlinks which do not point to anything.
43+
- `check-vcs-permalinks` - Ensures that links to vcs websites are permalinks.
4344
- `check-xml` - Attempts to load all xml files to verify syntax.
4445
- `check-yaml` - Attempts to load all yaml files to verify syntax.
4546
- `debug-statements` - Check for pdb / ipdb / pudb statements in code.

hooks.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@
6464
entry: upgrade-your-pre-commit-version
6565
files: ''
6666
minimum_pre_commit_version: 0.15.0
67+
- id: check-vcs-permalinks
68+
language: system
69+
name: upgrade-your-pre-commit-version
70+
entry: upgrade-your-pre-commit-version
71+
files: ''
72+
minimum_pre_commit_version: 0.15.0
6773
- id: check-xml
6874
language: system
6975
name: upgrade-your-pre-commit-version
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from __future__ import absolute_import
2+
from __future__ import print_function
3+
from __future__ import unicode_literals
4+
5+
import argparse
6+
import re
7+
import sys
8+
9+
10+
GITHUB_NON_PERMALINK = re.compile(
11+
b'https://github.com/[^/]+/[^/]+/blob/master/[^# ]+#L\d+',
12+
)
13+
14+
15+
def _check_filename(filename):
16+
retv = 0
17+
with open(filename, 'rb') as f:
18+
for i, line in enumerate(f, 1):
19+
if GITHUB_NON_PERMALINK.search(line):
20+
sys.stdout.write('{}:{}:'.format(filename, i))
21+
getattr(sys.stdout, 'buffer', sys.stdout).write(line)
22+
retv = 1
23+
return retv
24+
25+
26+
def main(argv=None):
27+
parser = argparse.ArgumentParser()
28+
parser.add_argument('filenames', nargs='*')
29+
args = parser.parse_args(argv)
30+
31+
retv = 0
32+
for filename in args.filenames:
33+
retv |= _check_filename(filename)
34+
35+
if retv:
36+
print()
37+
print('Non-permanent github link detected.')
38+
print('On any page on github press [y] to load a permalink.')
39+
return retv
40+
41+
42+
if __name__ == '__main__':
43+
exit(main())

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
'check-json = pre_commit_hooks.check_json:check_json',
4444
'check-merge-conflict = pre_commit_hooks.check_merge_conflict:detect_merge_conflict',
4545
'check-symlinks = pre_commit_hooks.check_symlinks:check_symlinks',
46+
'check-vcs-permalinks = pre_commit_hooks.check_vcs_permalinks:main',
4647
'check-xml = pre_commit_hooks.check_xml:check_xml',
4748
'check-yaml = pre_commit_hooks.check_yaml:check_yaml',
4849
'debug-statement-hook = pre_commit_hooks.debug_statement_hook:debug_statement_hook',

tests/check_vcs_permalinks_test.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from __future__ import absolute_import
2+
from __future__ import unicode_literals
3+
4+
from pre_commit_hooks.check_vcs_permalinks import main
5+
6+
7+
def test_trivial(tmpdir):
8+
f = tmpdir.join('f.txt').ensure()
9+
assert not main((f.strpath,))
10+
11+
12+
def test_passing(tmpdir):
13+
f = tmpdir.join('f.txt')
14+
f.write_binary(
15+
# permalinks are ok
16+
b'https://github.com/asottile/test/blob/649e6/foo%20bar#L1\n'
17+
# links to files but not line numbers are ok
18+
b'https://github.com/asottile/test/blob/master/foo%20bar\n',
19+
)
20+
assert not main((f.strpath,))
21+
22+
23+
def test_failing(tmpdir, capsys):
24+
with tmpdir.as_cwd():
25+
tmpdir.join('f.txt').write_binary(
26+
b'https://github.com/asottile/test/blob/master/foo#L1\n',
27+
)
28+
29+
assert main(('f.txt',))
30+
out, _ = capsys.readouterr()
31+
assert out == (
32+
'f.txt:1:https://github.com/asottile/test/blob/master/foo#L1\n'
33+
'\n'
34+
'Non-permanent github link detected.\n'
35+
'On any page on github press [y] to load a permalink.\n'
36+
)

0 commit comments

Comments
 (0)