Skip to content

Commit

Permalink
Add cli option to supply path to the construct yaml file (supersedes #…
Browse files Browse the repository at this point in the history
…728) (#758)

Co-authored-by: jaimergp <jaimergp@users.noreply.github.com>
Co-authored-by: Kevin Mills <millsks@gmail.com>
Co-authored-by: Kevin Mills <35641675+millsks@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 5, 2024
1 parent a6228ac commit c9ad275
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 21 deletions.
20 changes: 17 additions & 3 deletions constructor/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ def get_output_filename(info):

def main_build(dir_path, output_dir='.', platform=cc_platform,
verbose=True, cache_dir=DEFAULT_CACHE_DIR,
dry_run=False, conda_exe="conda.exe"):
dry_run=False, conda_exe="conda.exe",
config_filename="construct.yaml"):
logger.info('platform: %s', platform)
if not os.path.isfile(conda_exe):
sys.exit("Error: Conda executable '%s' does not exist!" % conda_exe)
Expand All @@ -78,7 +79,7 @@ def main_build(dir_path, output_dir='.', platform=cc_platform,
except ValueError:
sys.exit("Error: invalid platform string '%s'" % platform)

construct_path = join(dir_path, 'construct.yaml')
construct_path = join(dir_path, config_filename)
info = construct_parse(construct_path, platform)
construct_verify(info)
info['CONSTRUCTOR_VERSION'] = __version__
Expand Down Expand Up @@ -357,6 +358,13 @@ def main():
action="store",
metavar="CONDA_EXE")

p.add_argument('--config-filename',
help="path to construct YAML file ready by constructor",
action="store",
metavar="FILENAME",
dest="config_filename",
default="construct.yaml")

p.add_argument('dir_path',
help="directory containing construct.yaml",
action="store",
Expand All @@ -381,6 +389,11 @@ def main():
dir_path = args.dir_path
if not isdir(dir_path):
p.error("no such directory: %s" % dir_path)
if os.sep in args.config_filename:
p.error("--config-filename can only be a filename, not a path")
full_config_path = os.path.join(dir_path, args.config_filename)
if not os.path.isfile(full_config_path):
p.error("no such file: %s" % full_config_path)

conda_exe = args.conda_exe
conda_exe_default_path = os.path.join(sys.prefix, "standalone_conda", "conda.exe")
Expand All @@ -404,7 +417,8 @@ def main():
out_dir = normalize_path(args.output_dir)
main_build(dir_path, output_dir=out_dir, platform=args.platform,
verbose=args.verbose, cache_dir=args.cache_dir,
dry_run=args.dry_run, conda_exe=conda_exe)
dry_run=args.dry_run, conda_exe=conda_exe,
config_filename=args.config_filename)


if __name__ == '__main__':
Expand Down
File renamed without changes.
19 changes: 19 additions & 0 deletions news/758-yaml-filename
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Enhancements

* Add a new `--config-filename` argument to specify an input file not named `construct.yaml`. (#727 via #758)

### Bug fixes

* <news item>

### Deprecations

* <news item>

### Docs

* <news item>

### Other

* <news item>
61 changes: 43 additions & 18 deletions tests/test_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from datetime import timedelta
from functools import lru_cache
from pathlib import Path
from typing import Iterable, Optional, Tuple
from typing import Generator, Iterable, Optional, Tuple

import pytest
from conda.base.context import context
Expand Down Expand Up @@ -179,7 +179,13 @@ def _run_installer_sh(installer, install_dir, installer_input=None, timeout=420)
return _execute(cmd, installer_input=installer_input, timeout=timeout)


def _run_installer_pkg(installer, install_dir, example_path=None, timeout=420):
def _run_installer_pkg(
installer,
install_dir,
example_path=None,
config_filename="construct.yaml",
timeout=420,
):
if os.environ.get("CI"):
# We want to run it in an arbitrary directory, but the options
# are limited here... We can only install to $HOME :shrug:
Expand All @@ -193,7 +199,7 @@ def _run_installer_pkg(installer, install_dir, example_path=None, timeout=420):
"CurrentUserHomeDirectory",
]
if example_path:
install_dir = calculate_install_dir(example_path / "construct.yaml")
install_dir = calculate_install_dir(example_path / config_filename)
install_dir = Path(os.environ["HOME"]) / install_dir
else:
# This command only expands the PKG, but does not install
Expand Down Expand Up @@ -222,6 +228,7 @@ def _run_installer(
installer: Path,
install_dir: Path,
installer_input: Optional[str] = None,
config_filename="construct.yaml",
check_sentinels=True,
request=None,
uninstall=True,
Expand All @@ -234,7 +241,13 @@ def _run_installer(
elif installer.suffix == ".pkg":
if request and ON_CI:
request.addfinalizer(lambda: shutil.rmtree(str(install_dir)))
_run_installer_pkg(installer, install_dir, example_path=example_path, timeout=timeout)
_run_installer_pkg(
installer,
install_dir,
example_path=example_path,
config_filename=config_filename,
timeout=timeout,
)
else:
raise ValueError(f"Unknown installer type: {installer.suffix}")
if check_sentinels:
Expand All @@ -250,9 +263,10 @@ def create_installer(
debug=CONSTRUCTOR_DEBUG,
with_spaces=False,
timeout=420,
config_filename="construct.yaml",
extra_constructor_args: Iterable[str] = None,
**env_vars,
) -> Tuple[Path, Path]:
) -> Generator[Tuple[Path, Path], None, None]:
if sys.platform.startswith("win") and conda_exe and _is_micromamba(conda_exe):
pytest.skip("Micromamba is not supported on Windows yet.")

Expand All @@ -265,6 +279,8 @@ def create_installer(
str(input_dir),
"--output-dir",
str(output_dir),
"--config-filename",
config_filename,
]
if conda_exe:
cmd.extend(["--conda-exe", conda_exe])
Expand All @@ -285,7 +301,7 @@ def _sort_by_extension(path):
for installer in sorted(installers, key=_sort_by_extension):
if installer.suffix == ".pkg" and ON_CI:
install_dir = Path("~").expanduser() / calculate_install_dir(
input_dir / "construct.yaml"
input_dir / config_filename
)
else:
install_dir = (
Expand Down Expand Up @@ -383,8 +399,16 @@ def test_example_miniforge(tmp_path, request):

def test_example_noconda(tmp_path, request):
input_path = _example_path("noconda")
for installer, install_dir in create_installer(input_path, tmp_path, with_spaces=True):
_run_installer(input_path, installer, install_dir, request=request)
for installer, install_dir in create_installer(
input_path, tmp_path, config_filename="constructor_input.yaml", with_spaces=True
):
_run_installer(
input_path,
installer,
install_dir,
config_filename="constructor_input.yaml",
request=request,
)


@pytest.mark.skipif(sys.platform != "darwin", reason="macOS only")
Expand Down Expand Up @@ -525,28 +549,28 @@ def test_register_envs(tmp_path, request):
assert str(install_dir) not in environments_txt


@pytest.mark.skipif(sys.platform != 'darwin', reason='MacOS only')
@pytest.mark.parametrize('domains', ({}, {'enable_anywhere': 'false', 'enable_localSystem': True}))
@pytest.mark.skipif(sys.platform != "darwin", reason="MacOS only")
@pytest.mark.parametrize("domains", ({}, {"enable_anywhere": "false", "enable_localSystem": True}))
def test_pkg_distribution_domains(tmp_path, domains):
recipe_path = _example_path('osxpkg')
input_path = tmp_path / 'input'
output_path = tmp_path / 'output'
recipe_path = _example_path("osxpkg")
input_path = tmp_path / "input"
output_path = tmp_path / "output"
shutil.copytree(str(recipe_path), str(input_path))
if domains:
with open(input_path / "construct.yaml", "a") as cyml:
cyml.write('pkg_domains:\n')
cyml.write("pkg_domains:\n")
for key, val in domains.items():
cyml.write(f" {key}: {val}\n")

installer, install_dir = next(create_installer(input_path, output_path))
cmd = ['pkgutil', '--expand', installer, output_path / "expanded"]
cmd = ["pkgutil", "--expand", installer, output_path / "expanded"]
_execute(cmd)
domains_file = output_path / "expanded" / 'Distribution'
domains_file = output_path / "expanded" / "Distribution"
assert domains_file.exists()

tree = ET.parse(domains_file)
found = {key: val for key, val in tree.find('domains').items()}
defaults = {'enable_anywhere': 'true', 'enable_currentUserHome': 'true'}
found = {key: val for key, val in tree.find("domains").items()}
defaults = {"enable_anywhere": "true", "enable_currentUserHome": "true"}
expected = {key: str(val).lower() for key, val in domains.items()} if domains else defaults
assert expected == found

Expand Down Expand Up @@ -574,4 +598,5 @@ def test_cross_osx_building(tmp_path):
tmp_path,
conda_exe=micromamba_arm64,
extra_constructor_args=["--platform", "osx-arm64"],
config_filename="constructor_input.yaml",
)

0 comments on commit c9ad275

Please sign in to comment.