Skip to content

Commit ab0fc8a

Browse files
committed
refactor to separate getting info and creating config files
1 parent 9bd388d commit ab0fc8a

File tree

4 files changed

+129
-57
lines changed

4 files changed

+129
-57
lines changed

news/userinfo.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
**Added:**
2+
3+
* <news item>
4+
5+
**Changed:**
6+
7+
* Refactor get_user_info to separate the tasks of getting the info from config files
8+
and creating config files when they are missing.
9+
10+
**Deprecated:**
11+
12+
* <news item>
13+
14+
**Removed:**
15+
16+
* <news item>
17+
18+
**Fixed:**
19+
20+
* <news item>
21+
22+
**Security:**
23+
24+
* <news item>

src/diffpy/utils/tools.py

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import importlib.metadata
22
import json
3-
import os
43
from copy import copy
54
from pathlib import Path
65

@@ -56,7 +55,7 @@ def load_config(file_path):
5655
Returns
5756
-------
5857
dict:
59-
The configuration dictionary or None if file does not exist.
58+
The configuration dictionary or {} if the config file does not exist.
6059
6160
"""
6261
config_file = Path(file_path).resolve()
@@ -65,7 +64,7 @@ def load_config(file_path):
6564
config = json.load(f)
6665
return config
6766
else:
68-
return None
67+
return {}
6968

7069

7170
def _sorted_merge(*dicts):
@@ -91,9 +90,9 @@ def _create_global_config(args):
9190
return return_bool
9291

9392

94-
def get_user_info(args=None):
93+
def get_user_info(owner_name=None, owner_email=None, owner_orcid=None):
9594
"""
96-
Get username and email configuration.
95+
Get username, email and orcid configuration.
9796
9897
First attempts to load config file from global and local paths.
9998
If neither exists, creates a global config file.
@@ -111,27 +110,26 @@ def get_user_info(args=None):
111110
The dictionary containing username and email with corresponding values.
112111
113112
"""
114-
config_bool = True
113+
runtime_info = {"owner_name": owner_name, "owner_email": owner_email, "owner_orcid": owner_orcid}
114+
for key, value in copy(runtime_info).items():
115+
if value is None or value == "":
116+
del runtime_info[key]
115117
global_config = load_config(Path().home() / "diffpyconfig.json")
116118
local_config = load_config(Path().cwd() / "diffpyconfig.json")
117-
if global_config is None and local_config is None:
118-
print(
119-
"No global configuration file was found containing "
120-
"information about the user to associate with the data.\n"
121-
"By following the prompts below you can add your name and email to this file on the current "
122-
"computer and your name will be automatically associated with subsequent diffpy data by default.\n"
123-
"This is not recommended on a shared or public computer. "
124-
"You will only have to do that once.\n"
125-
"For more information, please refer to www.diffpy.org/diffpy.utils/examples/toolsexample.html"
126-
)
127-
config_bool = _create_global_config(args)
128-
global_config = load_config(Path().home() / "diffpyconfig.json")
129-
config = _sorted_merge(clean_dict(global_config), clean_dict(local_config), clean_dict(args))
130-
if config_bool is False:
131-
os.remove(Path().home() / "diffpyconfig.json")
132-
config = {"username": "", "email": ""}
133-
134-
return config
119+
# if global_config is None and local_config is None:
120+
# print(
121+
# "No global configuration file was found containing "
122+
# "information about the user to associate with the data.\n"
123+
# "By following the prompts below you can add your name and email to this file on the current "
124+
# "computer and your name will be automatically associated with subsequent diffpy data by default.\n"
125+
# "This is not recommended on a shared or public computer. "
126+
# "You will only have to do that once.\n"
127+
# "For more information, please refer to www.diffpy.org/diffpy.utils/examples/toolsexample.html"
128+
# )
129+
user_info = global_config
130+
user_info.update(local_config)
131+
user_info.update(runtime_info)
132+
return user_info
135133

136134

137135
def get_package_info(package_names, metadata=None):

tests/conftest.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ def user_filesystem(tmp_path):
1212
base_dir = Path(tmp_path)
1313
home_dir = base_dir / "home_dir"
1414
home_dir.mkdir(parents=True, exist_ok=True)
15-
cwd_dir = base_dir / "cwd_dir"
15+
cwd_dir = home_dir / "cwd_dir"
1616
cwd_dir.mkdir(parents=True, exist_ok=True)
17-
18-
home_config_data = {"username": "home_username", "email": "home@email.com"}
17+
home_config_data = {
18+
"owner_name": "home_ownername",
19+
"owner_email": "home@email.com",
20+
"owner_orcid": "home_orcid",
21+
}
1922
with open(home_dir / "diffpyconfig.json", "w") as f:
2023
json.dump(home_config_data, f)
21-
22-
yield tmp_path
24+
yield home_dir, cwd_dir
2325

2426

2527
@pytest.fixture

tests/test_tools.py

Lines changed: 76 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88
from diffpy.utils.tools import get_package_info, get_user_info
99

1010

11-
def _setup_dirs(monkeypatch, user_filesystem):
12-
cwd = Path(user_filesystem)
13-
home_dir = cwd / "home_dir"
14-
monkeypatch.setattr("pathlib.Path.home", lambda _: home_dir)
15-
os.chdir(cwd)
11+
def _setup_dirs(user_filesystem):
12+
home_dir, cwd_dir = user_filesystem.home_dir, user_filesystem.cwd_dir
13+
os.chdir(cwd_dir)
1614
return home_dir
1715

1816

@@ -24,15 +22,6 @@ def _run_tests(inputs, expected):
2422
assert config.get("email") == expected_email
2523

2624

27-
params_user_info_with_home_conf_file = [
28-
(["", ""], ["home_username", "home@email.com"]),
29-
(["cli_username", ""], ["cli_username", "home@email.com"]),
30-
(["", "cli@email.com"], ["home_username", "cli@email.com"]),
31-
([None, None], ["home_username", "home@email.com"]),
32-
(["cli_username", None], ["cli_username", "home@email.com"]),
33-
([None, "cli@email.com"], ["home_username", "cli@email.com"]),
34-
(["cli_username", "cli@email.com"], ["cli_username", "cli@email.com"]),
35-
]
3625
params_user_info_with_local_conf_file = [
3726
(["", ""], ["cwd_username", "cwd@email.com"]),
3827
(["cli_username", ""], ["cli_username", "cwd@email.com"]),
@@ -84,21 +73,80 @@ def _run_tests(inputs, expected):
8473
]
8574

8675

87-
@pytest.mark.parametrize("inputs, expected", params_user_info_with_home_conf_file)
88-
def test_get_user_info_with_home_conf_file(monkeypatch, inputs, expected, user_filesystem):
89-
_setup_dirs(monkeypatch, user_filesystem)
90-
_run_tests(inputs, expected)
91-
92-
93-
@pytest.mark.parametrize("inputs, expected", params_user_info_with_local_conf_file)
94-
def test_get_user_info_with_local_conf_file(monkeypatch, inputs, expected, user_filesystem):
95-
_setup_dirs(monkeypatch, user_filesystem)
96-
local_config_data = {"username": "cwd_username", "email": "cwd@email.com"}
97-
with open(Path(user_filesystem) / "diffpyconfig.json", "w") as f:
76+
@pytest.mark.parametrize(
77+
"runtime_inputs, expected",
78+
[ # config file in home is present, no config in cwd. various runtime values passed
79+
# C1: nothing passed in, expect uname, email, orcid from home_config
80+
({}, {"owner_name": "home_ownername", "owner_email": "home@email.com", "owner_orcid": "home_orcid"}),
81+
# C2: empty strings passed in, expect uname, email, orcid from home_config
82+
(
83+
{"owner_name": "", "owner_email": "", "owner_orcid": ""},
84+
{"owner_name": "home_ownername", "owner_email": "home@email.com", "owner_orcid": "home_orcid"},
85+
),
86+
# C3: just owner name passed in at runtime. expect runtime_oname but others from config
87+
(
88+
{"owner_name": "runtime_ownername"},
89+
{"owner_name": "runtime_ownername", "owner_email": "home@email.com", "owner_orcid": "home_orcid"},
90+
),
91+
# C4: just owner email passed in at runtime. expect runtime_email but others from config
92+
(
93+
{"owner_email": "runtime@email.com"},
94+
{"owner_name": "home_ownername", "owner_email": "runtime@email.com", "owner_orcid": "home_orcid"},
95+
),
96+
# C5: just owner ci passed in at runtime. expect runtime_orcid but others from config
97+
(
98+
{"owner_orcid": "runtime_orcid"},
99+
{"owner_name": "home_ownername", "owner_email": "home@email.com", "owner_orcid": "runtime_orcid"},
100+
),
101+
],
102+
)
103+
def test_get_user_info_with_home_conf_file(runtime_inputs, expected, user_filesystem, mocker):
104+
# user_filesystem[0] is tmp_dir/home_dir with the global config file in it, user_filesystem[1]
105+
# is tmp_dir/cwd_dir
106+
mocker.patch.object(Path, "home", return_value=user_filesystem[0])
107+
os.chdir(user_filesystem[1])
108+
actual = get_user_info(**runtime_inputs)
109+
assert actual == expected
110+
111+
112+
@pytest.mark.parametrize(
113+
"runtime_inputs, expected",
114+
[ # tests as before but now config file present in cwd and home but orcid
115+
# missing in the cwd config
116+
# C1: nothing passed in, expect uname, email from local config, orcid from home_config
117+
({}, {"owner_name": "cwd_ownername", "owner_email": "cwd@email.com", "owner_orcid": "home_orcid"}),
118+
# C2: empty strings passed in, expect uname, email, orcid from home_config
119+
(
120+
{"owner_name": "", "owner_email": "", "owner_orcid": ""},
121+
{"owner_name": "cwd_ownername", "owner_email": "cwd@email.com", "owner_orcid": "home_orcid"},
122+
),
123+
# C3: just owner name passed in at runtime. expect runtime_oname but others from config
124+
(
125+
{"owner_name": "runtime_ownername"},
126+
{"owner_name": "runtime_ownername", "owner_email": "cwd@email.com", "owner_orcid": "home_orcid"},
127+
),
128+
# C4: just owner email passed in at runtime. expect runtime_email but others from config
129+
(
130+
{"owner_email": "runtime@email.com"},
131+
{"owner_name": "cwd_ownername", "owner_email": "runtime@email.com", "owner_orcid": "home_orcid"},
132+
),
133+
# C5: just owner ci passed in at runtime. expect runtime_orcid but others from config
134+
(
135+
{"owner_orcid": "runtime_orcid"},
136+
{"owner_name": "cwd_ownername", "owner_email": "cwd@email.com", "owner_orcid": "runtime_orcid"},
137+
),
138+
],
139+
)
140+
def test_get_user_info_with_local_conf_file(runtime_inputs, expected, user_filesystem, mocker):
141+
# user_filesystem[0] is tmp_dir/home_dir with the global config file in it, user_filesystem[1] i
142+
# s tmp_dir/cwd_dir
143+
mocker.patch.object(Path, "home", return_value=user_filesystem[0])
144+
os.chdir(user_filesystem[1])
145+
local_config_data = {"owner_name": "cwd_ownername", "owner_email": "cwd@email.com"}
146+
with open(user_filesystem[1] / "diffpyconfig.json", "w") as f:
98147
json.dump(local_config_data, f)
99-
_run_tests(inputs, expected)
100-
os.remove(Path().home() / "diffpyconfig.json")
101-
_run_tests(inputs, expected)
148+
actual = get_user_info(**runtime_inputs)
149+
assert actual == expected
102150

103151

104152
@pytest.mark.parametrize("inputsa, inputsb, expected", params_user_info_with_no_home_conf_file)

0 commit comments

Comments
 (0)