Skip to content

Commit e1b4f40

Browse files
authored
Merge pull request #106 from fermitools/issue-99
Add --server flag to override server given to ferry-cli
2 parents 56ed2a1 + fb80468 commit e1b4f40

File tree

4 files changed

+122
-30
lines changed

4 files changed

+122
-30
lines changed

.gitignore

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1+
# Build artifacts
2+
build/
3+
.vscode/
4+
__pycache__/
5+
ferry_cli.egg-info/
6+
7+
# Development artifacts
18
result.json
29
.venv
310
.git
4-
/tmp/*
5-
__pycache__
6-
.make_creds.sh
711
swagger.json
812
config/swagger.json
13+
14+
# Testing artifacts
15+
/tmp/*
16+
.make_creds.sh
917
remove

ferry_cli/__main__.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class FerryCLI:
4545
# pylint: disable=too-many-instance-attributes
4646
def __init__(
4747
self: "FerryCLI",
48+
base_url: Optional[str] = None,
4849
config_path: Optional[pathlib.Path] = None,
4950
authorizer: Auth = Auth(),
5051
print_help: bool = False,
@@ -53,6 +54,7 @@ def __init__(
5354
Initializes the FerryCLI instance.
5455
5556
Args:
57+
base_url (Optional[str]): The base URL for the Ferry API, if that should not come from the file specified by config_path.
5658
config_path (Optional[pathlib.Path]): The path to the configuration file. If None,
5759
a message will be printed indicating that a configuration file is required.
5860
authorizer (Auth): An instance of the Auth class used for authorization. Defaults to a dummy Auth instance.
@@ -90,7 +92,11 @@ def __init__(
9092
self.config_path = config_path
9193
self.configs = self.__parse_config_file()
9294
self.authorizer = authorizer
93-
self.base_url = self._sanitize_base_url(self.base_url)
95+
self.base_url = (
96+
self._sanitize_base_url(self.base_url)
97+
if base_url is None
98+
else self._sanitize_base_url(base_url)
99+
)
94100
self.dev_url = self._sanitize_base_url(self.dev_url)
95101

96102
def get_arg_parser(self: "FerryCLI") -> FerryParser:
@@ -615,7 +621,9 @@ def main() -> None:
615621
try:
616622
auth_args, other_args = get_auth_args()
617623
ferry_cli = FerryCLI(
618-
config_path=config_path, authorizer=set_auth_from_args(auth_args)
624+
config_path=config_path,
625+
authorizer=set_auth_from_args(auth_args),
626+
base_url=auth_args.server,
619627
)
620628
if auth_args.update or not os.path.exists(f"{CONFIG_DIR}/swagger.json"):
621629
if auth_args.debug_level != DebugLevel.QUIET:

ferry_cli/helpers/auth.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@ def get_auth_parser() -> "FerryParser":
213213
help="Get Ferry CLI support emails",
214214
action=request_project_info("email"),
215215
)
216+
auth_parser.add_argument(
217+
"-s",
218+
"--server",
219+
help="Server URL to use instead of configuration file api.base_url value",
220+
)
216221
auth_parser.add_argument(
217222
"--version",
218223
nargs=0,

tests/test_main.py

Lines changed: 96 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -124,39 +124,43 @@ def test_handle_show_configfile_envs_not_found(
124124
assert "Mocked write_config_file" in captured.out
125125

126126

127+
@pytest.mark.parametrize(
128+
"args, expected_out_substr",
129+
[
130+
(
131+
["-h"],
132+
"--show-config-file",
133+
), # If we pass -h, make sure --show-config-file shows up
134+
(
135+
["-h", "--show-config-file", "-e", "getAllGroups"],
136+
"--show-config-file",
137+
), # If we pass -h and --show-config-file, -h should win
138+
(
139+
["--show-config-file"],
140+
"Configuration file",
141+
), # Print out config file if we only pass --show-config-file
142+
(
143+
["--show-config-file", "-e", "getAllGroups"],
144+
"Configuration file",
145+
), # If we pass --show-config-file with other args, --show-config-file should print out the config file
146+
],
147+
)
127148
@pytest.mark.unit
128149
def test_show_configfile_flag_with_other_args(
129-
tmp_path, monkeypatch, write_and_set_fake_config_file
150+
tmp_path, monkeypatch, write_and_set_fake_config_file, args, expected_out_substr
130151
):
131152
# Since we have to handle --show-config-file outside of argparse, make sure we get the correct behavior given different combinations of args
132153
bindir = f"{os.path.dirname(os.path.dirname(os.path.abspath(__file__)))}/bin"
133154
exe = f"{bindir}/ferry-cli"
134155

135-
test_case = namedtuple("TestCase", ["args", "expected_out_substr"])
136-
137-
cases = (
138-
test_case(
139-
[sys.executable, exe, "-h"], "--show-config-file"
140-
), # If we pass -h, make sure --show-config-file shows up
141-
test_case(
142-
[sys.executable, exe, "-h", "--show-config-file", "-e", "getAllGroups"],
143-
"--show-config-file",
144-
), # If we pass -h and --show-config-file, -h should win
145-
test_case(
146-
[sys.executable, exe, "--show-config-file"], "Configuration file"
147-
), # Print out config file if we only pass --show-config-file
148-
test_case(
149-
[sys.executable, exe, "--show-config-file", "-e", "getAllGroups"],
150-
"Configuration file",
151-
), # If we pass --show-config-file with other args, --show-config-file should print out the config file
152-
)
156+
exe_args = [sys.executable, exe]
157+
exe_args.extend(args)
153158

154-
for case in cases:
155-
try:
156-
proc = subprocess.run(case.args, capture_output=True)
157-
except SystemExit:
158-
pass
159-
assert case.expected_out_substr in str(proc.stdout)
159+
try:
160+
proc = subprocess.run(exe_args, capture_output=True)
161+
except SystemExit:
162+
pass
163+
assert expected_out_substr in str(proc.stdout)
160164

161165

162166
@pytest.mark.unit
@@ -302,3 +306,70 @@ def test_handle_no_args_configfile_does_not_exist(
302306

303307
assert pytest_wrapped_e.type == SystemExit
304308
assert pytest_wrapped_e.value.code == 0
309+
310+
311+
@pytest.mark.parametrize(
312+
"base_url, expected_base_url",
313+
[
314+
(None, "https://example.com:12345/"), # Get base_url from config
315+
(
316+
"https://override_example.com:54321/",
317+
"https://override_example.com:54321/",
318+
), # Get base_url from override
319+
],
320+
)
321+
@pytest.mark.unit
322+
def test_override_base_url_FerryCLI(tmp_path, base_url, expected_base_url):
323+
# Set up fake config
324+
fake_config_text = """
325+
[api]
326+
base_url = https://example.com:12345/
327+
dev_url = https://example.com:12345/
328+
329+
"""
330+
fake_config = tmp_path / "config.ini"
331+
fake_config.write_text(fake_config_text)
332+
333+
cli = FerryCLI(config_path=fake_config, base_url=base_url)
334+
assert cli.base_url == expected_base_url
335+
336+
337+
@pytest.mark.parametrize(
338+
"args, expected_out_url",
339+
[
340+
([], "https://example.com:12345/"), # Get base_url from config
341+
(
342+
["--server", "https://override_example.com:54321/"],
343+
"https://override_example.com:54321/",
344+
), # Get base_url from override
345+
],
346+
)
347+
@pytest.mark.test
348+
def test_server_flag_main(tmp_path, monkeypatch, args, expected_out_url):
349+
# Run ferry-cli with overridden base_url in dryrun mode to endpoint ping. Then see if we see the correct server in output
350+
override_url = "https://override_example.com:54321/"
351+
# Set up fake config
352+
fake_config_text = """
353+
[api]
354+
base_url = https://example.com:12345/
355+
dev_url = https://example.com:12345/
356+
357+
"""
358+
# Fake config file
359+
p = tmp_path
360+
config_dir = p / "ferry_cli"
361+
config_dir.mkdir()
362+
config_file = config_dir / "config.ini"
363+
config_file.write_text(fake_config_text)
364+
monkeypatch.setenv("XDG_CONFIG_HOME", str(p.absolute()))
365+
366+
bindir = f"{os.path.dirname(os.path.dirname(os.path.abspath(__file__)))}/bin"
367+
exe = f"{bindir}/ferry-cli"
368+
369+
exe_args = [sys.executable, exe]
370+
exe_args.extend(args + ["--dryrun", "-e", "ping"])
371+
372+
proc = subprocess.run(exe_args, capture_output=True)
373+
assert f"Would call endpoint: {expected_out_url}ping with params" in str(
374+
proc.stdout
375+
)

0 commit comments

Comments
 (0)