Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support passing extra args to poetry export #584

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
49 changes: 34 additions & 15 deletions package.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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")
Expand Down Expand Up @@ -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)

Expand All @@ -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:
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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,
Expand All @@ -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",
Expand Down