git-format-staged 2.1.3 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -17
- package/git-format-staged +22 -13
- package/package.json +2 -5
package/README.md
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
[](https://travis-ci.org/hallettj/git-format-staged)
|
|
4
4
|
|
|
5
5
|
Consider a project where you want all code formatted consistently. So you use
|
|
6
|
-
a formatting command. (For example I use [prettier
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
a formatting command. (For example I use [prettier][] in my Javascript and
|
|
7
|
+
Typescript projects.) You want to make sure that everyone working on the project
|
|
8
|
+
runs the formatter, so you use a tool like [husky][] to install a git pre-commit
|
|
9
|
+
hook. The naive way to write that hook would be to:
|
|
10
10
|
|
|
11
11
|
- get a list of staged files
|
|
12
12
|
- run the formatter on those files
|
|
@@ -30,12 +30,21 @@ version of the file that is committed will be formatted properly - the warning
|
|
|
30
30
|
just means that working tree copy of the file has been left unformatted. The
|
|
31
31
|
patch step can be disabled with the `--no-update-working-tree` option.
|
|
32
32
|
|
|
33
|
-
[prettier
|
|
33
|
+
[prettier]: https://prettier.io/
|
|
34
34
|
[husky]: https://www.npmjs.com/package/husky
|
|
35
35
|
|
|
36
|
-
|
|
37
36
|
## How to install
|
|
38
37
|
|
|
38
|
+
### Install with Nix
|
|
39
|
+
|
|
40
|
+
Install via the CLI:
|
|
41
|
+
|
|
42
|
+
$ nix profile add github:hallettj/git-format-staged
|
|
43
|
+
|
|
44
|
+
Or add to your flake imports, and use the `default` package output.
|
|
45
|
+
|
|
46
|
+
### Install with NPM
|
|
47
|
+
|
|
39
48
|
Requires Python version 3 or 2.7.
|
|
40
49
|
|
|
41
50
|
Install as a development dependency in a project that uses npm packages:
|
|
@@ -46,12 +55,15 @@ Or install globally:
|
|
|
46
55
|
|
|
47
56
|
$ npm install --global git-format-staged
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
### Or just copy the script
|
|
59
|
+
|
|
60
|
+
Requires Python version 3 or 2.7.
|
|
61
|
+
|
|
62
|
+
If you do not use the above methods you can copy the
|
|
50
63
|
[`git-format-staged`](./git-format-staged) script from this repository and
|
|
51
64
|
place it in your executable path. The script is MIT-licensed - so you can check
|
|
52
65
|
the script into version control in your own open source project if you wish.
|
|
53
66
|
|
|
54
|
-
|
|
55
67
|
## How to use
|
|
56
68
|
|
|
57
69
|
For detailed information run:
|
|
@@ -73,6 +85,13 @@ file names.
|
|
|
73
85
|
The formatter command must read file content from `stdin`, and output formatted
|
|
74
86
|
content to `stdout`.
|
|
75
87
|
|
|
88
|
+
Note that the syntax of the `fnmatch` glob match is a is a bit different from
|
|
89
|
+
normal shell globbing. So if you need to match multiple patterns, you should
|
|
90
|
+
pass multiple arguments with different patterns, and they will be grouped.
|
|
91
|
+
So instead of e.g. `'src/**/*.{js,jsx,ts}'`, you would use:
|
|
92
|
+
|
|
93
|
+
$ git-format-staged --formatter 'prettier --stdin-filepath "{}"' 'src/*.js' 'src/*.jsx' 'src/*.ts'
|
|
94
|
+
|
|
76
95
|
Files can be excluded by prefixing a pattern with `!`. For example:
|
|
77
96
|
|
|
78
97
|
$ git-format-staged --formatter 'prettier --stdin-filepath "{}"' '*.js' '!flow-typed/*'
|
|
@@ -116,23 +135,26 @@ notation) so that you can see them.
|
|
|
116
135
|
Follow these steps to automatically format all Javascript files on commit in
|
|
117
136
|
a project that uses npm.
|
|
118
137
|
|
|
119
|
-
Install git-format-staged, husky, and a formatter (I use prettier
|
|
138
|
+
Install git-format-staged, husky, and a formatter (I use `prettier`):
|
|
120
139
|
|
|
121
|
-
$ npm install --save-dev git-format-staged husky prettier
|
|
140
|
+
$ npm install --save-dev git-format-staged husky prettier
|
|
122
141
|
|
|
123
|
-
Add a `
|
|
142
|
+
Add a `prepare` script to install husky when running `npm install`:
|
|
124
143
|
|
|
125
|
-
"
|
|
126
|
-
|
|
127
|
-
}
|
|
144
|
+
$ npm set-script prepare "husky install"
|
|
145
|
+
$ npm run prepare
|
|
128
146
|
|
|
129
|
-
|
|
130
|
-
|
|
147
|
+
Add the pre-commit hook:
|
|
148
|
+
|
|
149
|
+
$ npx husky add .husky/pre-commit "git-format-staged --formatter 'prettier --stdin-filepath \"{}\"' '*.js' '*.ts'"
|
|
150
|
+
$ git add .husky/pre-commit
|
|
151
|
+
|
|
152
|
+
Once again note that the formatter command and the `'*.js'` and `'*.ts'`
|
|
153
|
+
patterns are quoted!
|
|
131
154
|
|
|
132
155
|
That's it! Whenever a file is changed as a result of formatting on commit you
|
|
133
156
|
will see a message in the output from `git commit`.
|
|
134
157
|
|
|
135
|
-
|
|
136
158
|
## Comparisons to similar utilities
|
|
137
159
|
|
|
138
160
|
There are other tools that will format or lint staged files. What distinguishes
|
package/git-format-staged
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
2
|
#
|
|
3
3
|
# Git command to transform staged files according to a command that accepts file
|
|
4
4
|
# content on stdin and produces output on stdout. This command is useful in
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
# Usage: git-format-staged [OPTION]... [FILE]...
|
|
10
10
|
# Example: git-format-staged --formatter 'prettier --stdin-filepath "{}"' '*.js'
|
|
11
11
|
#
|
|
12
|
-
# Tested with Python 3.
|
|
12
|
+
# Tested with Python 3.10 and Python 2.7.
|
|
13
13
|
#
|
|
14
14
|
# Original author: Jesse Hallett <jesse@sitr.us>
|
|
15
15
|
|
|
@@ -22,12 +22,12 @@ import re
|
|
|
22
22
|
import subprocess
|
|
23
23
|
import sys
|
|
24
24
|
|
|
25
|
-
# The string
|
|
26
|
-
VERSION = '
|
|
25
|
+
# The string 3.1.0 is replaced during the publish process.
|
|
26
|
+
VERSION = '3.1.0'
|
|
27
27
|
PROG = sys.argv[0]
|
|
28
28
|
|
|
29
29
|
def info(msg):
|
|
30
|
-
print(msg, file=sys.
|
|
30
|
+
print(msg, file=sys.stdout)
|
|
31
31
|
|
|
32
32
|
def warn(msg):
|
|
33
33
|
print('{}: warning: {}'.format(PROG, msg), file=sys.stderr)
|
|
@@ -36,7 +36,7 @@ def fatal(msg):
|
|
|
36
36
|
print('{}: error: {}'.format(PROG, msg), file=sys.stderr)
|
|
37
37
|
exit(1)
|
|
38
38
|
|
|
39
|
-
def format_staged_files(file_patterns, formatter, git_root, update_working_tree=True, write=True):
|
|
39
|
+
def format_staged_files(file_patterns, formatter, git_root, update_working_tree=True, write=True, verbose=False):
|
|
40
40
|
try:
|
|
41
41
|
output = subprocess.check_output([
|
|
42
42
|
'git', 'diff-index',
|
|
@@ -53,7 +53,7 @@ def format_staged_files(file_patterns, formatter, git_root, update_working_tree=
|
|
|
53
53
|
continue
|
|
54
54
|
if not (matches_some_path(file_patterns, entry_path)):
|
|
55
55
|
continue
|
|
56
|
-
if format_file_in_index(formatter, entry, update_working_tree=update_working_tree, write=write):
|
|
56
|
+
if format_file_in_index(formatter, entry, update_working_tree=update_working_tree, write=write, verbose=verbose):
|
|
57
57
|
info('Reformatted {} with {}'.format(entry['src_path'], formatter))
|
|
58
58
|
except Exception as err:
|
|
59
59
|
fatal(str(err))
|
|
@@ -61,9 +61,9 @@ def format_staged_files(file_patterns, formatter, git_root, update_working_tree=
|
|
|
61
61
|
# Run formatter on file in the git index. Creates a new git object with the
|
|
62
62
|
# result, and replaces the content of the file in the index with that object.
|
|
63
63
|
# Returns hash of the new object if formatting produced any changes.
|
|
64
|
-
def format_file_in_index(formatter, diff_entry, update_working_tree=True, write=True):
|
|
64
|
+
def format_file_in_index(formatter, diff_entry, update_working_tree=True, write=True, verbose=False):
|
|
65
65
|
orig_hash = diff_entry['dst_hash']
|
|
66
|
-
new_hash = format_object(formatter, orig_hash, diff_entry['src_path'])
|
|
66
|
+
new_hash = format_object(formatter, orig_hash, diff_entry['src_path'], verbose=verbose)
|
|
67
67
|
|
|
68
68
|
# If the new hash is the same then the formatter did not make any changes.
|
|
69
69
|
if not write or new_hash == orig_hash:
|
|
@@ -90,13 +90,16 @@ file_path_placeholder = re.compile('\{\}')
|
|
|
90
90
|
|
|
91
91
|
# Run formatter on a git blob identified by its hash. Writes output to a new git
|
|
92
92
|
# blob, and returns the hash of the new blob.
|
|
93
|
-
def format_object(formatter, object_hash, file_path):
|
|
93
|
+
def format_object(formatter, object_hash, file_path, verbose=False):
|
|
94
94
|
get_content = subprocess.Popen(
|
|
95
95
|
['git', 'cat-file', '-p', object_hash],
|
|
96
96
|
stdout=subprocess.PIPE
|
|
97
97
|
)
|
|
98
|
+
command = re.sub(file_path_placeholder, file_path, formatter)
|
|
99
|
+
if verbose:
|
|
100
|
+
info(command)
|
|
98
101
|
format_content = subprocess.Popen(
|
|
99
|
-
|
|
102
|
+
command,
|
|
100
103
|
shell=True,
|
|
101
104
|
stdin=get_content.stdout,
|
|
102
105
|
stdout=subprocess.PIPE
|
|
@@ -145,7 +148,7 @@ def replace_file_in_index(diff_entry, new_object_hash):
|
|
|
145
148
|
|
|
146
149
|
def patch_working_file(path, orig_object_hash, new_object_hash):
|
|
147
150
|
patch = subprocess.check_output(
|
|
148
|
-
['git', 'diff', orig_object_hash, new_object_hash]
|
|
151
|
+
['git', 'diff', '--no-ext-diff', '--color=never', orig_object_hash, new_object_hash]
|
|
149
152
|
)
|
|
150
153
|
|
|
151
154
|
# Substitute object hashes in patch header with path to working tree file
|
|
@@ -254,6 +257,11 @@ if __name__ == '__main__':
|
|
|
254
257
|
version='%(prog)s version {}'.format(VERSION),
|
|
255
258
|
help='Display version of %(prog)s'
|
|
256
259
|
)
|
|
260
|
+
parser.add_argument(
|
|
261
|
+
'--verbose',
|
|
262
|
+
help='Show the formatting commands that are running',
|
|
263
|
+
action='store_true'
|
|
264
|
+
)
|
|
257
265
|
parser.add_argument(
|
|
258
266
|
'files',
|
|
259
267
|
nargs='+',
|
|
@@ -266,5 +274,6 @@ if __name__ == '__main__':
|
|
|
266
274
|
formatter=vars(args)['formatter'],
|
|
267
275
|
git_root=get_git_root(),
|
|
268
276
|
update_working_tree=not vars(args)['no_update_working_tree'],
|
|
269
|
-
write=not vars(args)['no_write']
|
|
277
|
+
write=not vars(args)['no_write'],
|
|
278
|
+
verbose=vars(args)['verbose']
|
|
270
279
|
)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "git-format-staged",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Git command to transform staged files according to a command that accepts file content on stdin and produces output on stdout.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "ava",
|
|
@@ -28,9 +28,6 @@
|
|
|
28
28
|
"files": [
|
|
29
29
|
"git-format-staged"
|
|
30
30
|
],
|
|
31
|
-
"release": {
|
|
32
|
-
"branches": "master"
|
|
33
|
-
},
|
|
34
31
|
"devDependencies": {
|
|
35
32
|
"@commitlint/cli": "^8.3.5",
|
|
36
33
|
"@commitlint/config-conventional": "^8.3.4",
|
|
@@ -42,7 +39,7 @@
|
|
|
42
39
|
"husky": "^4.2.5",
|
|
43
40
|
"micromatch": "^4.0.2",
|
|
44
41
|
"prettier-standard": "^9.1.1",
|
|
45
|
-
"semantic-release": "^
|
|
42
|
+
"semantic-release": "^19.0.2",
|
|
46
43
|
"strip-indent": "^3.0.0",
|
|
47
44
|
"tmp": "0.2.0",
|
|
48
45
|
"ts-node": "^8.9.1",
|