diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..4a8659a47 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +* +!rust-toolchain.toml diff --git a/.gitignore b/.gitignore index 8ed136775..ea73bbd3e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ target/ # MSVC Windows builds of rustc generate these, which store debugging information *.pdb + +# Use e.g. `--cache-dir cache-docker` to keep a cache across container invocations +cache-* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..3f2118f42 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,14 @@ +# Contributing + +## Running inside a docker container + +Source distributions can run arbitrary code on build and can make unwanted modifications to your system (https://moyix.blogspot.com/2022/09/someones-been-messing-with-my-subnormals.html, https://pypi.org/project/nvidia-pyindex/), which can even occur when just resolving requirements. To prevent this, there's a Docker container you can run commands in: + +```bash +docker buildx build -t puffin-builder -f builder.dockerfile . +# Build for musl to avoid glibc errors, might not be required with your OS version +cargo build --target x86_64-unknown-linux-musl +docker run --rm -it -v $(pwd):/app puffin-builder /app/target/x86_64-unknown-linux-musl/debug/puffin-dev resolve-many --cache-dir /app/cache-docker /app/scripts/resolve/pypi_top_8k_flat.txt +``` + +We recommend using this container if you don't trust the dependency tree of the package(s) you are trying to resolve or install. diff --git a/builder.dockerfile b/builder.dockerfile new file mode 100644 index 000000000..9994ba4b8 --- /dev/null +++ b/builder.dockerfile @@ -0,0 +1,24 @@ +# Provide isolation for source distribution builds +# https://moyix.blogspot.com/2022/09/someones-been-messing-with-my-subnormals.html + +FROM ubuntu:22.04 +# Feel free to add build dependencies you need +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + python3 \ + python3-pip \ + python3-venv \ + build-essential \ + make \ + autoconf \ + curl \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +ENV HOME="/root" +WORKDIR /app +RUN python3 -m venv $HOME/venv-docker +ENV VIRTUAL_ENV="$HOME/venv-docker" +ENV PATH="$HOME/.cargo/bin:$HOME/venv-docker/bin:$PATH" +COPY rust-toolchain.toml rust-toolchain.toml +RUN rustup show diff --git a/crates/puffin-dev/src/resolve_many.rs b/crates/puffin-dev/src/resolve_many.rs index a81ecdfb9..f4e12961f 100644 --- a/crates/puffin-dev/src/resolve_many.rs +++ b/crates/puffin-dev/src/resolve_many.rs @@ -1,10 +1,10 @@ -use std::fs; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::Arc; use clap::Parser; use directories::ProjectDirs; +use fs_err as fs; use futures::stream::FuturesUnordered; use futures::StreamExt; use indicatif::ProgressStyle; @@ -24,6 +24,9 @@ pub(crate) struct ResolveManyArgs { list: PathBuf, #[clap(long)] limit: Option, + /// Path to the cache directory. + #[arg(global = true, long, env = "PUFFIN_CACHE_DIR")] + cache_dir: Option, } pub(crate) async fn resolve_many(args: ResolveManyArgs) -> anyhow::Result<()> { @@ -36,7 +39,10 @@ pub(crate) async fn resolve_many(args: ResolveManyArgs) -> anyhow::Result<()> { }; let project_dirs = ProjectDirs::from("", "", "puffin"); - let cache = project_dirs.as_ref().map(ProjectDirs::cache_dir); + let cache = args + .cache_dir + .as_deref() + .or_else(|| project_dirs.as_ref().map(ProjectDirs::cache_dir)); let platform = Platform::current()?; let venv = Virtualenv::from_env(platform, cache)?;