Skip to content

Commit 28d69fa

Browse files
fcollonvalFrederic Collonval
authored andcommitted
Merge execute and execute_with_auth
1 parent 3c33d1b commit 28d69fa

File tree

3 files changed

+46
-76
lines changed

3 files changed

+46
-76
lines changed

jupyterlab_git/git.py

Lines changed: 32 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -21,62 +21,28 @@ async def execute(
2121
cmdline: "List[str]",
2222
cwd: "Optional[str]" = None,
2323
env: "Optional[Dict[str, str]]" = None,
24+
username: "Optional[str]" = None,
25+
password: "Optional[str]" = None,
2426
) -> "Tuple[int, str, str]":
2527
"""Asynchronously execute a command.
2628
2729
Args:
2830
cmdline (List[str]): Command line to be executed
2931
cwd (Optional[str]): Current working directory
30-
env (Optional[Dict[str, str]]): Defines the environment variables for the new process.
32+
env (Optional[Dict[str, str]]): Defines the environment variables for the new process
33+
username (Optional[str]): User name
34+
password (Optional[str]): User password
3135
Returns:
3236
(int, str, str): (return code, stdout, stderr)
3337
"""
3438

35-
def call_subprocess(
36-
cmdline: "List[str]",
37-
cwd: "Optional[str]" = None,
38-
env: "Optional[Dict[str, str]]" = None,
39-
) -> "Tuple[int, bytes, bytes]":
40-
process = subprocess.Popen(
41-
cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd, env=env
42-
)
43-
output, error = process.communicate()
44-
return (process.returncode, output, error)
45-
46-
current_loop = tornado.ioloop.IOLoop.current()
47-
returncode, output, error = await current_loop.run_in_executor(
48-
None, call_subprocess, cmdline, cwd, env
49-
)
50-
51-
return returncode, output.decode("utf-8"), error.decode("utf-8")
52-
53-
54-
async def execute_with_authentication(
55-
cmdline: "List[str]",
56-
username: "str",
57-
password: "str",
58-
cwd: "Optional[str]" = None,
59-
env: "Optional[Dict[str, str]]" = None,
60-
) -> "Tuple[int, str]":
61-
"""Asynchronously execute a command.
62-
63-
Args:
64-
cmdline (List[str]): Command line to be executed
65-
username (str): User name
66-
password (str): User password
67-
cwd (Optional[str]): Current working directory
68-
env (Optional[Dict[str, str]]): Defines the environment variables for the new process.
69-
Returns:
70-
(int, str): (return code, output)
71-
"""
72-
73-
def call_subprocess(
39+
def call_subprocess_with_authentication(
7440
cmdline: "List[str]",
7541
username: "str",
7642
password: "str",
7743
cwd: "Optional[str]" = None,
7844
env: "Optional[Dict[str, str]]" = None,
79-
) -> "Tuple[int, str]":
45+
) -> "Tuple[int, str, str]":
8046
try:
8147
p = pexpect.spawn(
8248
cmdline[0], cmdline[1:], cwd=cwd, env=env, encoding="utf-8"
@@ -101,19 +67,34 @@ def call_subprocess(
10167
returncode = p.wait()
10268
p.close()
10369

104-
return returncode, response
70+
return returncode, "", response
10571
except pexpect.exceptions.EOF: # In case of pexpect failure
10672
response = p.before
10773
returncode = p.exitstatus
10874
p.close() # close process
109-
return returncode, response
75+
return returncode, "", response
11076

111-
current_loop = tornado.ioloop.IOLoop.current()
112-
returncode, output = await current_loop.run_in_executor(
113-
None, call_subprocess, cmdline, username, password, cwd, env
114-
)
11577

116-
return returncode, output
78+
def call_subprocess(
79+
cmdline: "List[str]",
80+
cwd: "Optional[str]" = None,
81+
env: "Optional[Dict[str, str]]" = None,
82+
) -> "Tuple[int, str, str]":
83+
process = subprocess.Popen(
84+
cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd, env=env
85+
)
86+
output, error = process.communicate()
87+
return (process.returncode, output.decode("utf-8"), error.decode("utf-8"))
88+
89+
current_loop = tornado.ioloop.IOLoop.current()
90+
if username is not None and password is not None:
91+
return await current_loop.run_in_executor(
92+
None, call_subprocess_with_authentication, cmdline, username, password, cwd, env
93+
)
94+
else:
95+
return await current_loop.run_in_executor(
96+
None, call_subprocess, cmdline, cwd, env
97+
)
11798

11899

119100
class Git:
@@ -219,7 +200,7 @@ async def clone(self, current_path, repo_url, auth=None):
219200
env = os.environ.copy()
220201
if auth:
221202
env["GIT_TERMINAL_PROMPT"] = "1"
222-
code, error = await execute_with_authentication(
203+
code, _, error = await execute(
223204
["git", "clone", unquote(repo_url), "-q"],
224205
username=auth["username"],
225206
password=auth["password"],
@@ -722,7 +703,7 @@ async def pull(self, curr_fb_path, auth=None):
722703
env = os.environ.copy()
723704
if auth:
724705
env["GIT_TERMINAL_PROMPT"] = "1"
725-
code, error = await execute_with_authentication(
706+
code, _, error = await execute(
726707
["git", "pull", "--no-commit"],
727708
username=auth["username"],
728709
password=auth["password"],
@@ -751,7 +732,7 @@ async def push(self, remote, branch, curr_fb_path, auth=None):
751732
env = os.environ.copy()
752733
if auth:
753734
env["GIT_TERMINAL_PROMPT"] = "1"
754-
code, error = await execute_with_authentication(
735+
code, _, error = await execute(
755736
["git", "push", remote, branch],
756737
username=auth["username"],
757738
password=auth["password"],

jupyterlab_git/tests/test_clone.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,9 @@ async def test_git_clone_failure_from_git():
6464
@pytest.mark.asyncio
6565
async def test_git_clone_with_auth_success():
6666
with patch("os.environ", {"TEST": "test"}):
67-
with patch(
68-
"jupyterlab_git.git.execute_with_authentication"
69-
) as mock_authentication:
67+
with patch("jupyterlab_git.git.execute") as mock_authentication:
7068
# Given
71-
mock_authentication.return_value = tornado.gen.maybe_future((0, ""))
69+
mock_authentication.return_value = tornado.gen.maybe_future((0, "", ""))
7270

7371
# When
7472
auth = {"username": "asdf", "password": "qwerty"}
@@ -95,12 +93,10 @@ async def test_git_clone_with_auth_wrong_repo_url_failure_from_git():
9593
9694
"""
9795
with patch("os.environ", {"TEST": "test"}):
98-
with patch(
99-
"jupyterlab_git.git.execute_with_authentication"
100-
) as mock_authentication:
96+
with patch("jupyterlab_git.git.execute") as mock_authentication:
10197
# Given
10298
mock_authentication.return_value = tornado.gen.maybe_future(
103-
(128, "fatal: repository 'ghjkhjkl' does not exist")
99+
(128, "", "fatal: repository 'ghjkhjkl' does not exist")
104100
)
105101

106102
# When
@@ -131,13 +127,12 @@ async def test_git_clone_with_auth_auth_failure_from_git():
131127
132128
"""
133129
with patch("os.environ", {"TEST": "test"}):
134-
with patch(
135-
"jupyterlab_git.git.execute_with_authentication"
136-
) as mock_authentication:
130+
with patch("jupyterlab_git.git.execute") as mock_authentication:
137131
# Given
138132
mock_authentication.return_value = tornado.gen.maybe_future(
139133
(
140134
128,
135+
"",
141136
"remote: Invalid username or password.\r\nfatal: Authentication failed for 'ghjkhjkl'",
142137
)
143138
)

jupyterlab_git/tests/test_pushpull.py

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,12 @@ async def test_git_pull_fail():
3535
@pytest.mark.asyncio
3636
async def test_git_pull_with_auth_fail():
3737
with patch("os.environ", {"TEST": "test"}):
38-
with patch(
39-
"jupyterlab_git.git.execute_with_authentication"
40-
) as mock_execute_with_authentication:
38+
with patch("jupyterlab_git.git.execute") as mock_execute_with_authentication:
4139
# Given
4240
mock_execute_with_authentication.return_value = tornado.gen.maybe_future(
4341
(
4442
1,
43+
"",
4544
"remote: Invalid username or password.\r\nfatal: Authentication failed for 'repo_url'",
4645
)
4746
)
@@ -92,12 +91,10 @@ async def test_git_pull_success():
9291
async def test_git_pull_with_auth_success():
9392

9493
with patch("os.environ", {"TEST": "test"}):
95-
with patch(
96-
"jupyterlab_git.git.execute_with_authentication"
97-
) as mock_execute_with_authentication:
94+
with patch("jupyterlab_git.git.execute") as mock_execute_with_authentication:
9895
# Given
9996
mock_execute_with_authentication.return_value = tornado.gen.maybe_future(
100-
(0, "output")
97+
(0, "", "output")
10198
)
10299

103100
# When
@@ -145,13 +142,12 @@ async def test_git_push_fail():
145142
async def test_git_push_with_auth_fail():
146143

147144
with patch("os.environ", {"TEST": "test"}):
148-
with patch(
149-
"jupyterlab_git.git.execute_with_authentication"
150-
) as mock_execute_with_authentication:
145+
with patch("jupyterlab_git.git.execute") as mock_execute_with_authentication:
151146
# Given
152147
mock_execute_with_authentication.return_value = tornado.gen.maybe_future(
153148
(
154149
1,
150+
"",
155151
"remote: Invalid username or password.\r\nfatal: Authentication failed for 'repo_url'",
156152
)
157153
)
@@ -204,12 +200,10 @@ async def test_git_push_success():
204200
async def test_git_push_with_auth_success():
205201

206202
with patch("os.environ", {"TEST": "test"}):
207-
with patch(
208-
"jupyterlab_git.git.execute_with_authentication"
209-
) as mock_execute_with_authentication:
203+
with patch("jupyterlab_git.git.execute") as mock_execute_with_authentication:
210204
# Given
211205
mock_execute_with_authentication.return_value = tornado.gen.maybe_future(
212-
(0, "does not matter")
206+
(0, "", "does not matter")
213207
)
214208

215209
# When

0 commit comments

Comments
 (0)