Skip to content

Commit 5b66d53

Browse files
elliot-barnaslonnie
authored andcommitted
[deps] raydepsets import all config (2/3) (ray-project#57584)
Adding workspace funcs to parse all configs not currently used in raydepsets --------- Signed-off-by: elliot-barn <[email protected]> Co-authored-by: Lonnie Liu <[email protected]> Signed-off-by: Josh Kodi <[email protected]>
1 parent c1975f3 commit 5b66d53

File tree

5 files changed

+137
-20
lines changed

5 files changed

+137
-20
lines changed

ci/raydepsets/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ py_test(
7070
srcs = ["tests/test_workspace.py"],
7171
data = [
7272
"tests/test_data/test.depsets.yaml",
73+
"tests/test_data/test2.depsets.yaml",
7374
],
7475
tags = [
7576
"ci_unit",

ci/raydepsets/tests/test_cli.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ def test_check_if_subset_exists(self):
276276
output="requirements_compiled_general.txt",
277277
append_flags=[],
278278
override_flags=[],
279+
config_name="test.depsets.yaml",
279280
)
280281
with self.assertRaises(RuntimeError):
281282
manager.check_subset_exists(
@@ -437,6 +438,7 @@ def test_build_graph_bad_operation(self):
437438
operation="invalid_op",
438439
requirements=["requirements_test.txt"],
439440
output="requirements_compiled_invalid_op.txt",
441+
config_name="test.depsets.yaml",
440442
)
441443
_overwrite_config_file(tmpdir, depset)
442444
with self.assertRaises(ValueError):
@@ -608,6 +610,7 @@ def test_copy_lock_files_to_temp_dir(self):
608610
constraints=["requirement_constraints_test.txt"],
609611
requirements=["requirements_test.txt"],
610612
output="requirements_compiled_test.txt",
613+
config_name="test.depsets.yaml",
611614
)
612615
_overwrite_config_file(tmpdir, depset)
613616
manager = _create_test_manager(tmpdir, check=True)
@@ -632,6 +635,7 @@ def test_diff_lock_files_out_of_date(self):
632635
constraints=["requirement_constraints_test.txt"],
633636
requirements=["requirements_test.txt"],
634637
output="requirements_compiled_test.txt",
638+
config_name="test.depsets.yaml",
635639
)
636640
_overwrite_config_file(tmpdir, depset)
637641
manager = _create_test_manager(tmpdir, check=True)
@@ -666,6 +670,7 @@ def test_diff_lock_files_up_to_date(self):
666670
constraints=["requirement_constraints_test.txt"],
667671
requirements=["requirements_test.txt"],
668672
output="requirements_compiled_test.txt",
673+
config_name="test.depsets.yaml",
669674
)
670675
_overwrite_config_file(tmpdir, depset)
671676
manager = _create_test_manager(tmpdir, check=True)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
build_arg_sets:
2+
py311_cpu:
3+
CUDA_VERSION: cpu
4+
PYTHON_VERSION: py311
5+
6+
depsets:
7+
- name: other_config_depset
8+
operation: expand
9+
depsets:
10+
- expand_general_depset__${PYTHON_VERSION}_${CUDA_VERSION}
11+
- expanded_depset__${PYTHON_VERSION}_${CUDA_VERSION}
12+
output: requirements_compiled_other_config.txt
13+
build_arg_sets:
14+
- py311_cpu
15+
- name: pre_hook_test_depset
16+
operation: compile
17+
requirements:
18+
- requirements_test.txt
19+
output: requirements_compiled_pre_hook.txt
20+
pre_hooks:
21+
- pre-hook-test.sh
22+
- name: pre_hook_invalid_test_depset
23+
operation: compile
24+
requirements:
25+
- requirements_test.txt
26+
output: requirements_compiled_pre_hook_invalid.txt
27+
pre_hooks:
28+
- pre-hook-error-test.sh

ci/raydepsets/tests/test_workspace.py

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@ def test_parse_build_arg_sets():
1818
with tempfile.TemporaryDirectory() as tmpdir:
1919
copy_data_to_tmpdir(tmpdir)
2020
workspace = Workspace(dir=tmpdir)
21-
config = workspace.load_config(path=Path(tmpdir) / "test.depsets.yaml")
22-
assert config.build_arg_sets["py311_cpu"].build_args == {
23-
"CUDA_VERSION": "cpu",
24-
"PYTHON_VERSION": "py311",
25-
}
26-
assert config.build_arg_sets["py311_cuda128"].build_args == {
27-
"CUDA_VERSION": 128,
28-
"PYTHON_VERSION": "py311",
29-
}
21+
config = workspace.load_config(config_path=Path(tmpdir) / "test.depsets.yaml")
22+
assert "general_depset__py311_cpu" in [depset.name for depset in config.depsets]
23+
assert "build_args_test_depset__py311_cpu" in [
24+
depset.name for depset in config.depsets
25+
]
26+
assert "expanded_depset__py311_cpu" in [
27+
depset.name for depset in config.depsets
28+
]
3029

3130

3231
def test_substitute_build_args():
@@ -65,17 +64,78 @@ def test_invalid_build_arg_set():
6564
)
6665
with pytest.raises(KeyError):
6766
workspace = Workspace(dir=tmpdir)
68-
workspace.load_config(path=Path(tmpdir) / "test.depsets.yaml")
67+
workspace.load_config(config_path=Path(tmpdir) / "test.depsets.yaml")
6968

7069

7170
def test_parse_pre_hooks():
7271
with tempfile.TemporaryDirectory() as tmpdir:
7372
copy_data_to_tmpdir(tmpdir)
7473
workspace = Workspace(dir=tmpdir)
75-
config = workspace.load_config(path=Path(tmpdir) / "test.depsets.yaml")
74+
config = workspace.load_config(config_path=Path(tmpdir) / "test2.depsets.yaml")
7675
pre_hook_depset = get_depset_by_name(config.depsets, "pre_hook_test_depset")
7776
assert pre_hook_depset.pre_hooks == ["pre-hook-test.sh"]
7877

7978

79+
def test_load_first_config():
80+
with tempfile.TemporaryDirectory() as tmpdir:
81+
copy_data_to_tmpdir(tmpdir)
82+
workspace = Workspace(dir=tmpdir)
83+
config = workspace.load_config(config_path=Path(tmpdir) / "test.depsets.yaml")
84+
assert config.depsets is not None
85+
assert len(config.depsets) == 8
86+
87+
88+
def test_load_second_config():
89+
with tempfile.TemporaryDirectory() as tmpdir:
90+
copy_data_to_tmpdir(tmpdir)
91+
workspace = Workspace(dir=tmpdir)
92+
config = workspace.load_config(config_path=Path(tmpdir) / "test2.depsets.yaml")
93+
assert config.depsets is not None
94+
assert len(config.depsets) == 3
95+
96+
97+
# load all configs should always load all depsets
98+
def test_load_all_configs_first_config():
99+
with tempfile.TemporaryDirectory() as tmpdir:
100+
copy_data_to_tmpdir(tmpdir)
101+
workspace = Workspace(dir=tmpdir)
102+
config = workspace.load_configs(config_path=Path(tmpdir) / "test.depsets.yaml")
103+
assert config.depsets is not None
104+
assert len(config.depsets) == 11
105+
106+
107+
# load all configs should always load all depsets
108+
def test_load_all_configs_second_config():
109+
with tempfile.TemporaryDirectory() as tmpdir:
110+
copy_data_to_tmpdir(tmpdir)
111+
workspace = Workspace(dir=tmpdir)
112+
config = workspace.load_configs(config_path=Path(tmpdir) / "test2.depsets.yaml")
113+
assert config.depsets is not None
114+
assert len(config.depsets) == 11
115+
116+
117+
def test_merge_configs():
118+
with tempfile.TemporaryDirectory() as tmpdir:
119+
copy_data_to_tmpdir(tmpdir)
120+
workspace = Workspace(dir=tmpdir)
121+
config = workspace.load_config(config_path=Path(tmpdir) / "test.depsets.yaml")
122+
config2 = workspace.load_config(config_path=Path(tmpdir) / "test2.depsets.yaml")
123+
merged_config = workspace.merge_configs([config, config2])
124+
assert merged_config.depsets is not None
125+
assert len(merged_config.depsets) == 11
126+
127+
128+
def test_get_configs_dir():
129+
with tempfile.TemporaryDirectory() as tmpdir:
130+
copy_data_to_tmpdir(tmpdir)
131+
workspace = Workspace(dir=tmpdir)
132+
configs_dir = workspace.get_configs_dir(
133+
configs_path=Path(tmpdir) / "test.depsets.yaml"
134+
)
135+
assert len(configs_dir) == 2
136+
assert f"{tmpdir}/test.depsets.yaml" in configs_dir
137+
assert f"{tmpdir}/test2.depsets.yaml" in configs_dir
138+
139+
80140
if __name__ == "__main__":
81141
sys.exit(pytest.main(["-v", __file__]))

ci/raydepsets/workspace.py

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class Depset:
1616
name: str
1717
operation: str
1818
output: str
19+
config_name: str
1920
constraints: Optional[List[str]] = None
2021
override_flags: Optional[List[str]] = None
2122
append_flags: Optional[List[str]] = None
@@ -40,7 +41,7 @@ def _substitute_build_args(obj: Any, build_arg_set: BuildArgSet):
4041
return obj
4142

4243

43-
def _dict_to_depset(depset: dict) -> Depset:
44+
def _dict_to_depset(depset: dict, config_name: str) -> Depset:
4445
return Depset(
4546
name=depset.get("name"),
4647
requirements=depset.get("requirements", []),
@@ -53,16 +54,16 @@ def _dict_to_depset(depset: dict) -> Depset:
5354
append_flags=depset.get("append_flags", []),
5455
pre_hooks=depset.get("pre_hooks", []),
5556
packages=depset.get("packages", []),
57+
config_name=config_name,
5658
)
5759

5860

5961
@dataclass
6062
class Config:
6163
depsets: List[Depset] = field(default_factory=list)
62-
build_arg_sets: Dict[str, BuildArgSet] = field(default_factory=dict)
6364

6465
@classmethod
65-
def from_dict(cls, data: dict) -> "Config":
66+
def from_dict(cls, data: dict, config_name: str) -> "Config":
6667
build_arg_sets = cls.parse_build_arg_sets(data.get("build_arg_sets", {}))
6768
raw_depsets = data.get("depsets", [])
6869
depsets = []
@@ -75,10 +76,10 @@ def from_dict(cls, data: dict) -> "Config":
7576
if build_arg_set is None:
7677
raise KeyError(f"Build arg set {build_arg_set_key} not found")
7778
depset_yaml = _substitute_build_args(depset, build_arg_set)
78-
depsets.append(_dict_to_depset(depset_yaml))
79+
depsets.append(_dict_to_depset(depset_yaml, config_name))
7980
else:
80-
depsets.append(_dict_to_depset(depset))
81-
return Config(depsets=depsets, build_arg_sets=build_arg_sets)
81+
depsets.append(_dict_to_depset(depset, config_name))
82+
return Config(depsets=depsets)
8283

8384
@staticmethod
8485
def parse_build_arg_sets(build_arg_sets: Dict[str, dict]) -> Dict[str, BuildArgSet]:
@@ -98,7 +99,29 @@ def __init__(self, dir: str = None):
9899
if self.dir is None:
99100
raise RuntimeError("BUILD_WORKSPACE_DIRECTORY is not set")
100101

101-
def load_config(self, path: str) -> Config:
102-
with open(os.path.join(self.dir, path), "r") as f:
102+
def load_configs(self, config_path: str = None) -> Config:
103+
merged_configs = self.merge_configs(self.get_all_configs(config_path))
104+
return merged_configs
105+
106+
def get_all_configs(self, config_path: str = None) -> List[Config]:
107+
return [self.load_config(path) for path in self.get_configs_dir(config_path)]
108+
109+
def get_configs_dir(self, configs_path: str) -> List[str]:
110+
configs_dir = os.path.dirname(os.path.join(self.dir, configs_path))
111+
return [
112+
os.path.join(self.dir, configs_dir, path)
113+
for path in os.listdir(os.path.join(self.dir, configs_dir))
114+
if path.endswith(".depsets.yaml")
115+
]
116+
117+
def load_config(self, config_path: str) -> Config:
118+
with open(os.path.join(self.dir, config_path), "r") as f:
103119
data = yaml.safe_load(f)
104-
return Config.from_dict(data)
120+
config_name = os.path.basename(config_path)
121+
config = Config.from_dict(data, config_name)
122+
return config
123+
124+
def merge_configs(self, configs: List[Config]) -> Config:
125+
return Config(
126+
depsets=[depset for config in configs for depset in config.depsets]
127+
)

0 commit comments

Comments
 (0)