Skip to content

Commit

Permalink
Allows usage of custom source fork CPython, Pypy and UV.
Browse files Browse the repository at this point in the history
This enables enterprise use-cases.
  • Loading branch information
Coruscant11 committed Jul 30, 2024
1 parent 2980970 commit 9668d79
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ passthrough = [
"PYAPP_SELF_COMMAND",
"PYAPP_SKIP_INSTALL",
"PYAPP_UPGRADE_VIRTUALENV",
"PYAPP_UV_CUSTOM_SOURCE",
"PYAPP_UV_ENABLED",
"PYAPP_UV_ONLY_BOOTSTRAP",
"PYAPP_UV_VERSION",
Expand Down
27 changes: 27 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,17 @@ fn get_python_version() -> String {
DEFAULT_PYTHON_VERSION.to_string()
}

fn get_custom_source(name: &str) -> Option<String> {
let name = name.to_uppercase().replace(".", "_");
let variable_name = format!("PYAPP_PYTHON_CUSTOM_SOURCE_{}", name);
if let Ok(value) = env::var(variable_name) {
if !value.is_empty() {
return Some(value);
}
}
None
}

fn get_distribution_source() -> String {
let distribution_source = env::var("PYAPP_DISTRIBUTION_SOURCE").unwrap_or_default();
if !distribution_source.is_empty() {
Expand All @@ -318,6 +329,16 @@ fn get_distribution_source() -> String {

let selected_python_version = get_python_version();

// Return custom source if specified for this version
if let Some(custom_source) = get_custom_source(&selected_python_version) {
dbg!(
"Using custom source for version {}: {}",
&selected_python_version,
&custom_source
);
return custom_source;
}

// https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts
let selected_platform = match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
"windows" => "windows",
Expand Down Expand Up @@ -922,6 +943,11 @@ fn set_uv_only_bootstrap() {
}
}

fn set_uv_custom_source() {
let variable = "PYAPP_UV_CUSTOM_SOURCE";
set_runtime_variable(variable, env::var(variable).unwrap_or_default());
}

fn set_uv_version() {
let variable = "PYAPP_UV_VERSION";
let version = env::var(variable).unwrap_or("any".to_string());
Expand Down Expand Up @@ -1070,6 +1096,7 @@ fn main() {
set_pip_allow_config();
set_uv_enabled();
set_uv_only_bootstrap();
set_uv_custom_source();
set_uv_version();
set_allow_updates();
set_indicator();
Expand Down
6 changes: 5 additions & 1 deletion docs/config/distribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ Setting the `PYAPP_PYTHON_VERSION` option will determine the distribution used a
| `3.11` |
| `3.12` |

The source for pre-built distributions is the [python-build-standalone](https://github.com/indygreg/python-build-standalone) project.
The source for pre-built distributions is the [python-build-standalone](https://github.com/indygreg/python-build-standalone) repository.
Distributions are downloaded from the release section.

Some distributions have [variants](https://gregoryszorc.com/docs/python-build-standalone/main/running.html) that may be configured with the `PYAPP_DISTRIBUTION_VARIANT` option:

| Platform | Options |
| --- | --- |
| Linux | <ul><li><code>v1</code></li><li><code>v2</code></li><li><code>v3</code> (default)</li><li><code>v4</code></li></ul> |

If you want to change the repository URL in order to targer your own GitHub fork/mirror, you can set the `PYAPP_DISTRIBUTION_CPYTHON_REPOSITORY` option.

### PyPy

| ID |
Expand All @@ -34,6 +37,7 @@ Some distributions have [variants](https://gregoryszorc.com/docs/python-build-st
| `pypy3.10` |

The source of distributions is the [PyPy](https://www.pypy.org) project.
If you want to change the host in order target your own fork/mirror, you can set the `PYAPP_DISTRIBUTION_PYPY_HOST` option.

## Custom

Expand Down
6 changes: 6 additions & 0 deletions docs/config/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ These options have no effect when the project installation is [disabled](#skippi

You may set the `PYAPP_UV_ENABLED` option to `true` or `1` to use [UV](https://github.com/astral-sh/uv) for virtual environment creation and project installation.

Executable is downloaded from the release section of the repository.

### Custom repository

You may use your own GitHub fork/mirror of [UV repository](https://github.com/astral-sh/uv) by setting the `PYAPP_UV_REPOSITORY` option.

### Version ### {: #uv-version }

You may use a specific `X.Y.Z` version by setting the `PYAPP_UV_VERSION` option.
Expand Down
4 changes: 4 additions & 0 deletions docs/users.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ The following is not intended to be a complete enumeration. Be sure to view the
| [Litestar](https://github.com/litestar-org/litestar-fullstack/blob/dc72eee78173790c3e91b0c095ac9e70ba91bedd/scripts/post-builds.py)
| [Preservation Workbench](https://github.com/Preservation-Workbench/PWCode/blob/e7777806be35bd60ca8c33e677ffd77e38b277d0/build/make.sh)
| [tidal-wave](https://github.com/ebb-earl-co/tidal-wave/blob/6358ede21adb715a053b1e6cc73968933c3bed05/BUILDME.md#pyapp-created-binaries)

## Industry

- [Amadeus](https://amadeus.com) <sup>\[[1](https://github.com/ofek/pyapp/pull/147)|[2](https://github.com/AmadeusITGroup/pyapp)\]</sup>
24 changes: 24 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use anyhow::{Context, Result};
use base64::{engine::general_purpose::STANDARD_NO_PAD, Engine as _};
use directories::ProjectDirs;
use once_cell::sync::OnceCell;
use reqwest::Url;

static PLATFORM_DIRS: OnceCell<ProjectDirs> = OnceCell::new();
static INSTALLATION_DIRECTORY: OnceCell<PathBuf> = OnceCell::new();
Expand Down Expand Up @@ -206,6 +207,29 @@ pub fn uv_as_installer() -> bool {
uv_enabled() && !uv_only_bootstrap()
}

pub fn uv_custom_source() -> String {
env!("PYAPP_UV_CUSTOM_SOURCE").into()
}

pub fn uv_custom_source_artifact_name() -> String {
let custom_source = uv_custom_source();

let parsed =
Url::parse(&custom_source).expect(&format!("unable to parse url: {}", &custom_source));

// Try to find artifact name from URL path
if let Some(segments) = parsed.path_segments() {
if let Some(segment) = segments.last() {
return segment.into();
}
}

panic!(
"unable to determine artifact name from url: {}",
&custom_source
);
}

pub fn is_gui() -> bool {
env!("PYAPP_IS_GUI") == "1"
}
Expand Down
12 changes: 9 additions & 3 deletions src/distribution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,13 +488,20 @@ fn ensure_uv_available() -> Result<()> {
.with_context(|| format!("unable to create UV cache {}", &managed_uv_cache.display()))?;

let dir = tempdir().with_context(|| "unable to create temporary directory")?;
let artifact_name = app::uv_artifact_name();

let artifact_name: String = if app::uv_custom_source().is_empty() {
app::uv_artifact_name()
} else {
app::uv_custom_source_artifact_name()
};
let temp_path = dir.path().join(&artifact_name);

let mut f = fs::File::create(&temp_path)
.with_context(|| format!("unable to create temporary file: {}", &temp_path.display()))?;

let url = if uv_version == "any" {
let url = if !app::uv_custom_source().is_empty() {
app::uv_custom_source()
} else if uv_version == "any" {
format!(
"https://github.com/astral-sh/uv/releases/latest/download/{}",
&artifact_name,
Expand All @@ -505,7 +512,6 @@ fn ensure_uv_available() -> Result<()> {
&uv_version, &artifact_name,
)
};

network::download(&url, &mut f, "UV")?;

if artifact_name.ends_with(".zip") {
Expand Down

0 comments on commit 9668d79

Please sign in to comment.