From 3aa288fee324e64a8db409e5a32abaeebe38e6c2 Mon Sep 17 00:00:00 2001 From: Morgan Chorlton <32246773+morganchorlton3@users.noreply.github.com> Date: Wed, 12 Jun 2024 09:03:57 +0100 Subject: [PATCH] feat: Support passing extra args to poetry export (#584) --- README.md | 1 + package.py | 49 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index d28a8b57..7fdbe539 100644 --- a/README.md +++ b/README.md @@ -459,6 +459,7 @@ source_path = [ - `pip_requirements` - Controls whether to execute `pip install`. Set to `false` to disable this feature, `true` to run `pip install` with `requirements.txt` found in `path`. Or set to another filename which you want to use instead. When `source_path` is passed as a string containing a path (and not a list of maps), and `requirements.txt` is present, `pip install` is automatically executed. - `pip_tmp_dir` - Set the base directory to make the temporary directory for pip installs. Can be useful for Docker in Docker builds. - `poetry_install` - Controls whether to execute `poetry export` and `pip install`. Set to `false` to disable this feature, `true` to run `poetry export` with `pyproject.toml` and `poetry.lock` found in `path`. When `source_path` is passed as a string containing a path (and not a list of maps), and `pyproject.toml` with a build system `poetry` is present, `poetry export` and `pip install` are automatically executed. +- `poetry_export_extra_args` - A list of additional poetry arguments to add to the poetry export command - `npm_requirements` - Controls whether to execute `npm install`. Set to `false` to disable this feature, `true` to run `npm install` with `package.json` found in `path`. Or set to another filename which you want to use instead. - `npm_tmp_dir` - Set the base directory to make the temporary directory for npm installs. Can be useful for Docker in Docker builds. - `prefix_in_zip` - If specified, will be used as a prefix inside zip-archive. By default, everything installs into the root of zip-archive. diff --git a/package.py b/package.py index 7e96d784..1552e8e2 100644 --- a/package.py +++ b/package.py @@ -693,7 +693,9 @@ def pip_requirements_step(path, prefix=None, required=False, tmp_dir=None): step("pip", runtime, requirements, prefix, tmp_dir) hash(requirements) - def poetry_install_step(path, prefix=None, required=False): + def poetry_install_step( + path, poetry_export_extra_args=[], prefix=None, required=False + ): pyproject_file = path if os.path.isdir(path): pyproject_file = os.path.join(path, "pyproject.toml") @@ -703,7 +705,7 @@ def poetry_install_step(path, prefix=None, required=False): "poetry configuration not found: {}".format(pyproject_file) ) else: - step("poetry", runtime, path, prefix) + step("poetry", runtime, path, poetry_export_extra_args, prefix) hash(pyproject_file) pyproject_path = os.path.dirname(pyproject_file) poetry_lock_file = os.path.join(pyproject_path, "poetry.lock") @@ -807,6 +809,7 @@ def commands_step(path, commands): prefix = claim.get("prefix_in_zip") pip_requirements = claim.get("pip_requirements") poetry_install = claim.get("poetry_install") + poetry_export_extra_args = claim.get("poetry_export_extra_args", []) npm_requirements = claim.get("npm_package_json") runtime = claim.get("runtime", query.runtime) @@ -828,7 +831,12 @@ def commands_step(path, commands): if poetry_install and runtime.startswith("python"): if path: - poetry_install_step(path, prefix, required=True) + poetry_install_step( + path, + prefix=prefix, + poetry_export_extra_args=poetry_export_extra_args, + required=True, + ) if npm_requirements and runtime.startswith("nodejs"): if isinstance(npm_requirements, bool) and path: @@ -898,8 +906,16 @@ def execute(self, build_plan, zip_stream, query): # XXX: timestamp=0 - what actually do with it? zs.write_dirs(rd, prefix=prefix, timestamp=0) elif cmd == "poetry": - runtime, path, prefix = action[1:] - with install_poetry_dependencies(query, path) as rd: + ( + runtime, + path, + poetry_export_extra_args, + prefix, + ) = action[1:] + log.info("poetry_export_extra_args: %s", poetry_export_extra_args) + with install_poetry_dependencies( + query, path, poetry_export_extra_args + ) as rd: if rd: if pf: self._zip_write_with_filter(zs, pf, rd, prefix, timestamp=0) @@ -1094,7 +1110,7 @@ def install_pip_requirements(query, requirements_file, tmp_dir): @contextmanager -def install_poetry_dependencies(query, path): +def install_poetry_dependencies(query, path, poetry_export_extra_args): # TODO: # 1. Emit files instead of temp_dir @@ -1183,6 +1199,17 @@ def copy_file_to_target(file, temp_dir): # NOTE: poetry must be available in the build environment, which is the case with lambci/lambda:build-python* docker images but not public.ecr.aws/sam/build-python* docker images # FIXME: poetry install does not currently allow to specify the target directory so we export the # requirements then install them with "pip --no-deps" to avoid using pip dependency resolver + + poetry_export = [ + poetry_exec, + "export", + "--format", + "requirements.txt", + "--output", + "requirements.txt", + "--with-credentials", + ] + poetry_export_extra_args + poetry_commands = [ [ poetry_exec, @@ -1198,15 +1225,7 @@ def copy_file_to_target(file, temp_dir): "virtualenvs.in-project", "true", ], - [ - poetry_exec, - "export", - "--format", - "requirements.txt", - "--output", - "requirements.txt", - "--with-credentials", - ], + poetry_export, [ python_exec, "-m",