Skip to content

Commit cc7066c

Browse files
committed
feat(commands/commit): apply prepare-commit-msg hook for Mac
1 parent aa35216 commit cc7066c

File tree

2 files changed

+69
-17
lines changed

2 files changed

+69
-17
lines changed

commitizen/commands/commit.py

+39-13
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import contextlib
22
import os
3+
import selectors
34
import sys
45
import tempfile
56

7+
from asyncio import set_event_loop_policy, get_event_loop_policy, DefaultEventLoopPolicy
8+
from io import IOBase
9+
610
import questionary
711

812
from commitizen import factory, git, out
@@ -19,14 +23,30 @@
1923
)
2024

2125

22-
class WrapStdin:
23-
def __init__(self):
24-
fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
25-
tty = open(fd, "wb+", buffering=0)
26+
class CZEventLoopPolicy(DefaultEventLoopPolicy):
27+
def get_event_loop(self):
28+
self.set_event_loop(self._loop_factory(selectors.SelectSelector()))
29+
return self._local._loop
30+
31+
class WrapStdx:
32+
def __init__(self, stdx:IOBase):
33+
self._fileno = stdx.fileno()
34+
if sys.platform == 'linux':
35+
if self._fileno == 0:
36+
fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
37+
tty = open(fd, "wb+", buffering=0)
38+
else:
39+
tty = open("/dev/tty", "w")
40+
else:
41+
fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
42+
if self._fileno == 0:
43+
tty = open(fd, "wb+", buffering=0)
44+
else:
45+
tty = open(fd, "rb+", buffering=0)
2646
self.tty = tty
2747

2848
def __getattr__(self, key):
29-
if key == "encoding":
49+
if key == "encoding" and (sys.platform != 'linux' or self._fileno == 0) :
3050
return "UTF-8"
3151
return getattr(self.tty, key)
3252

@@ -84,9 +104,11 @@ def __call__(self):
84104
old_stdin = sys.stdin
85105
old_stdout = sys.stdout
86106
old_stderr = sys.stderr
87-
sys.stdin = WrapStdin()
88-
sys.stdout = open("/dev/tty", "w")
89-
sys.stderr = open("/dev/tty", "w")
107+
old_event_loop_policy=get_event_loop_policy()
108+
set_event_loop_policy(CZEventLoopPolicy())
109+
sys.stdin = WrapStdx(sys.stdin)
110+
sys.stdout = WrapStdx(sys.stdout)
111+
sys.stderr = WrapStdx(sys.stderr)
90112

91113
if git.is_staging_clean() and not dry_run:
92114
raise NothingToCommitError("No files added to staging!")
@@ -98,18 +120,21 @@ def __call__(self):
98120
else:
99121
m = self.prompt_commit_questions()
100122

101-
out.info(f"\n{m}\n")
102-
103-
if dry_run:
104-
raise DryRunExit()
105-
106123
if commit_msg_file:
107124
sys.stdin.close()
108125
sys.stdout.close()
109126
sys.stderr.close()
127+
set_event_loop_policy(old_event_loop_policy)
110128
sys.stdin = old_stdin
111129
sys.stdout = old_stdout
112130
sys.stderr = old_stderr
131+
132+
out.info(f"\n{m}\n")
133+
134+
if dry_run:
135+
raise DryRunExit()
136+
137+
if commit_msg_file:
113138
defaultmesaage = ""
114139
with open(commit_msg_file) as f:
115140
defaultmesaage = f.read()
@@ -126,6 +151,7 @@ def __call__(self):
126151
else:
127152
c = git.commit(m)
128153

154+
129155
if c.return_code != 0:
130156
out.error(c.err)
131157

tests/commands/test_commit_command.py

+30-4
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ def test_commit_from_pre_commit_msg_hook(config, mocker, capsys):
197197
}
198198

199199
commit_mock = mocker.patch("commitizen.git.commit")
200-
mocker.patch("commitizen.commands.commit.WrapStdin")
200+
commit_mock.return_value = cmd.Command("success", "", "", "", 0)
201+
mocker.patch("commitizen.commands.commit.WrapStdx")
201202
mocker.patch("os.open")
202203
reader_mock = mocker.mock_open(read_data="\n\n#test\n")
203204
mocker.patch("builtins.open", reader_mock, create=True)
@@ -208,13 +209,38 @@ def test_commit_from_pre_commit_msg_hook(config, mocker, capsys):
208209
assert "Commit message is successful!" in out
209210
commit_mock.assert_not_called()
210211

211-
212-
def test_WrapStdin(mocker):
212+
def test_WrapStdx(mocker):
213213
mocker.patch("os.open")
214214
reader_mock = mocker.mock_open(read_data="data")
215215
mocker.patch("builtins.open", reader_mock, create=True)
216216

217-
wrap_stdin = commands.commit.WrapStdin()
217+
stdin_mock_fileno=mocker.patch.object(sys.stdin, 'fileno')
218+
stdin_mock_fileno.return_value = 0
219+
wrap_stdin = commands.commit.WrapStdx(sys.stdin)
218220

219221
assert wrap_stdin.encoding == "UTF-8"
220222
assert wrap_stdin.read() == "data"
223+
224+
225+
writer_mock = mocker.mock_open(read_data="data")
226+
mocker.patch("builtins.open", writer_mock, create=True)
227+
stdout_mock_fileno=mocker.patch.object(sys.stdout, 'fileno')
228+
stdout_mock_fileno.return_value = 1
229+
wrap_stout = commands.commit.WrapStdx(sys.stdout)
230+
wrap_stout.write("data")
231+
232+
writer_mock.assert_called_once_with("/dev/tty", 'w')
233+
writer_mock().write.assert_called_once_with("data")
234+
235+
236+
writer_mock = mocker.mock_open(read_data="data")
237+
mocker.patch("builtins.open", writer_mock, create=True)
238+
stderr_mock_fileno=mocker.patch.object(sys.stdout, 'fileno')
239+
stderr_mock_fileno.return_value = 2
240+
wrap_sterr = commands.commit.WrapStdx(sys.stderr)
241+
242+
243+
wrap_sterr.write("data")
244+
245+
writer_mock.assert_called_once_with("/dev/tty", 'w')
246+
writer_mock().write.assert_called_once_with("data")

0 commit comments

Comments
 (0)