Skip to content

Commit

Permalink
Stop manually creating a src dir in the Pip dependencies layer (#228)
Browse files Browse the repository at this point in the history
Since Pip will create the directory itself if needed (which is only when
there are editable mode VCS dependencies being installed).

This behaviour is already tested, via:
https://github.com/heroku/buildpacks-python/blob/ff51b31c65cbd1932fc4cdc585c60942efcfe836/tests/pip_test.rs#L197-L216
  • Loading branch information
edmorley authored Jul 19, 2024
1 parent ff51b31 commit 2add4a0
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Stopped manually creating a `src` directory inside the Pip dependencies layer. Pip will create the directory itself if needed (when there are editable VCS dependencies). ([#228](https://github.com/heroku/buildpacks-python/pull/228))

## [0.12.1] - 2024-07-15

### Changed
Expand Down
5 changes: 0 additions & 5 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,6 @@ fn on_python_layer_error(error: PythonLayerError) {

fn on_pip_dependencies_layer_error(error: PipDependenciesLayerError) {
match error {
PipDependenciesLayerError::CreateSrcDir(io_error) => log_io_error(
"Unable to create 'src' directory required for pip install",
"creating the 'src' directory in the pip layer, prior to running pip install",
&io_error,
),
PipDependenciesLayerError::PipInstallCommand(error) => match error {
StreamedCommandError::Io(io_error) => log_io_error(
"Unable to install dependencies using pip",
Expand Down
25 changes: 9 additions & 16 deletions src/layers/pip_dependencies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use libcnb::{Buildpack, Env};
use libherokubuildpack::log::log_info;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::{fs, io};

/// Layer containing the application's Python dependencies, installed using Pip.
pub(crate) struct PipDependenciesLayer<'a> {
Expand Down Expand Up @@ -56,17 +55,6 @@ impl Layer for PipDependenciesLayer<'_> {
let layer_env = generate_layer_env(layer_path);
let command_env = layer_env.apply(Scope::Build, self.command_env);

// When Pip installs dependencies from a VCS URL it has to clone the repository in order
// to install it. In standard installation mode the clone is made to a temporary directory
// and then deleted, however, when packages are installed in editable mode Pip must keep
// the repository around, since the directory is added to the Python path directly (via
// the `.pth` file created in `site-packages`). By default Pip will store the repository
// in the current working directory (the app dir), however, we would prefer it to be stored
// in the dependencies layer instead for consistency. (Plus if the dependencies layer were
// ever cached, storing the repository in the app dir would break on repeat-builds).
let src_dir = layer_path.join("src");
fs::create_dir(&src_dir).map_err(PipDependenciesLayerError::CreateSrcDir)?;

log_info("Running pip install");

utils::run_command_and_stream_output(
Expand Down Expand Up @@ -96,10 +84,16 @@ impl Layer for PipDependenciesLayer<'_> {
"--user",
"--requirement",
"requirements.txt",
// Clone any VCS repositories installed in editable mode into the directory created
// above, rather than the default of the current working directory (the app dir).
// When Pip installs dependencies from a VCS URL it has to clone the repository in order
// to install it. In standard installation mode the clone is made to a temporary directory
// and then deleted, however, when packages are installed in editable mode Pip must keep
// the repository around, since the directory is added to the Python path directly (via
// the `.pth` file created in `site-packages`). By default Pip will store the repository
// in the current working directory (the app dir), however, we would prefer it to be stored
// in the dependencies layer instead for consistency. (Plus if the dependencies layer were
// ever cached, storing the repository in the app dir would break on repeat-builds).
"--src",
&src_dir.to_string_lossy(),
&layer_path.join("src").to_string_lossy(),
])
.current_dir(&context.app_dir)
.env_clear()
Expand Down Expand Up @@ -139,7 +133,6 @@ fn generate_layer_env(layer_path: &Path) -> LayerEnv {
/// Errors that can occur when installing the project's dependencies into a layer using Pip.
#[derive(Debug)]
pub(crate) enum PipDependenciesLayerError {
CreateSrcDir(io::Error),
PipInstallCommand(StreamedCommandError),
}

Expand Down

0 comments on commit 2add4a0

Please sign in to comment.