Skip to content

Commit

Permalink
fix: noarch entry-points and rework how we run tests (#301)
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv authored Nov 16, 2023
1 parent b5aa656 commit 62fc493
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 30 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/end-to-end.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
strategy:
matrix:
os: ["ubuntu-latest", "windows-latest"]
fail-fast: false

name: Run tests
runs-on: ${{ matrix.os }}
Expand All @@ -36,5 +37,5 @@ jobs:
cache: true
# build in release mode so that it's reasonably fast to run the tests
- run: cargo build --release
- run: cargo test -p rust-tests
- run: cargo test -p rust-tests -- --test-threads 1
# - run: pixi run end_to_end_test
23 changes: 23 additions & 0 deletions rust-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,4 +374,27 @@ mod tests {
assert!(rattler_build.is_ok());
assert!(rattler_build.unwrap().status.code().unwrap() == 1);
}

#[test]
fn test_noarch_flask() {
let tmp = tmp("test_noarch_flask");
let rattler_build =
rattler().build::<_, _, &str>(recipes().join("flask"), tmp.as_dir(), None);
assert!(rattler_build.is_ok());
assert!(rattler_build.unwrap().status.success());

let pkg = get_extracted_package(tmp.as_dir(), "flask");
// this is to ensure that the clone happens correctly
let license = pkg.join("info/licenses/LICENSE.rst");
assert!(license.exists());

assert!(pkg.join("info/test/run_test.sh").exists());
assert!(pkg.join("info/test/run_test.bat").exists());
assert!(pkg.join("info/test/run_test.py").exists());
assert!(pkg.join("info/test/test_time_dependencies.json").exists());
// make sure that the entry point does not exist
assert!(!pkg.join("python-scripts/flask").exists());

assert!(pkg.join("info/link.json").exists())
}
}
36 changes: 22 additions & 14 deletions src/packaging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,17 +653,22 @@ fn write_test_files(output: &Output, tmp_dir_path: &Path) -> Result<Vec<PathBuf>
}

if !test.commands().is_empty() {
let test_file = if output.build_configuration.target_platform.is_windows() {
test_folder.join("run_test.bat")
} else {
test_folder.join("run_test.sh")
};
let mut command_files = vec![];
let target_platform = &output.build_configuration.target_platform;
if target_platform.is_windows() || target_platform == &Platform::NoArch {
command_files.push(test_folder.join("run_test.bat"));
}
if target_platform.is_unix() || target_platform == &Platform::NoArch {
command_files.push(test_folder.join("run_test.sh"));
}

let mut file = File::create(&test_file)?;
for el in test.commands() {
writeln!(file, "{}\n", el)?;
for cf in command_files {
let mut file = File::create(&cf)?;
for el in test.commands() {
writeln!(file, "{}\n", el)?;
}
test_files.push(cf);
}
test_files.push(test_file);
}

if !test.requires().is_empty() {
Expand Down Expand Up @@ -781,15 +786,16 @@ pub fn package_conda(

let mut tmp_files = HashSet::new();
for f in new_files {
let stripped = f.strip_prefix(prefix)?;
// temporary measure to remove pyc files that are not supposed to be there
if filter_pyc(f, new_files) {
continue;
}

if output.recipe.build().noarch().is_python() {
// we need to remove files in bin/ that are registered as entry points
if f.starts_with("bin") {
if let Some(name) = f.file_name() {
if stripped.starts_with("bin") {
if let Some(name) = stripped.file_name() {
if output
.recipe
.build()
Expand All @@ -802,8 +808,8 @@ pub fn package_conda(
}
}
// Windows
else if f.starts_with("Scripts") {
if let Some(name) = f.file_name() {
else if stripped.starts_with("Scripts") {
if let Some(name) = stripped.file_name() {
if output.recipe.build().entry_points().iter().any(|ep| {
format!("{}.exe", ep.command) == name.to_string_lossy()
|| format!("{}-script.py", ep.command) == name.to_string_lossy()
Expand Down Expand Up @@ -889,7 +895,9 @@ pub fn package_conda(
tracing::info!("\nFiles in package:\n");
tmp_files
.iter()
.map(|x| x.strip_prefix(tmp_dir_path).unwrap())
.map(|x| x.strip_prefix(tmp_dir_path))
.collect::<Result<Vec<_>, _>>()?
.iter()
.sorted()
.for_each(|f| tracing::info!(" - {}", f.to_string_lossy()));

Expand Down
24 changes: 9 additions & 15 deletions src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,17 @@ fn run_in_environment(
let mut additional_script = ShellScript::new(shell.clone(), Platform::current());

let os_vars = env_vars::os_vars(environment, &Platform::current());
for var in os_vars {
additional_script.set_env_var(&var.0, &var.1);
for (key, val) in os_vars {
if key == "PATH" {
continue;
}
additional_script.set_env_var(&key, &val);
}

additional_script.set_env_var("PREFIX", environment.to_string_lossy().as_ref());

writeln!(tmpfile, "{}", script.script)?;
writeln!(tmpfile, "{}", additional_script.contents)?;
writeln!(tmpfile, "{}", script.script)?;
writeln!(tmpfile, "{}", cmd)?;

let tmpfile_path = tmpfile.into_temp_path();
Expand Down Expand Up @@ -134,25 +137,16 @@ impl Tests {

match self {
Tests::Commands(path) => {
let contents = fs::read_to_string(path)?;
let ext = path.extension().unwrap().to_str().unwrap();
match (Platform::current().is_windows(), ext) {
(true, "bat") => {
tracing::info!("Testing commands:");
run_in_environment(
default_shell,
format!("cmd /c {}", path.to_string_lossy()),
cwd,
environment,
)
run_in_environment(default_shell, contents, cwd, environment)
}
(false, "sh") => {
tracing::info!("Testing commands:");
run_in_environment(
default_shell,
format!("bash -x {}", path.to_string_lossy()),
cwd,
environment,
)
run_in_environment(default_shell, contents, cwd, environment)
}
_ => Ok(()),
}
Expand Down
68 changes: 68 additions & 0 deletions test-data/recipes/flask/recipe.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Recipe licensed under BSD3 license from conda-forge
# Original recipe here: https://github.com/conda-forge/flask-feedstock/blob/main/recipe/meta.yaml

context:
name: flask
version: 3.0.0

package:
name: ${{ name }}
version: ${{ version }}

source:
url: https://pypi.io/packages/source/${{ name[0] }}/${{ name }}/flask-${{ version }}.tar.gz
sha256: cfadcdb638b609361d29ec22360d6070a77d7463dcb3ab08d2c2f2f168845f58

build:
number: 0
script: python -m pip install . -vv --no-deps --no-build-isolation
entry_points:
- flask = flask.cli:main
noarch: python

requirements:
host:
- python >=3.8
- flit-core <4
- pip
run:
- python >=3.8
- werkzeug >=3.0.0
- jinja2 >=3.1.2
- itsdangerous >=2.1.2
- click >=8.1.3
- importlib-metadata >=3.6.0
- blinker >=1.6.2

test:
requires:
- pip
imports:
- flask
- flask.json
commands:
- flask --help
- pip check

about:
homepage: https://palletsprojects.com/p/flask
license: BSD-3-Clause
license_family: BSD
license_file: LICENSE.rst
summary: A simple framework for building complex web applications.
description: |
Flask is a lightweight [WSGI](https://wsgi.readthedocs.io/) web application framework. It is designed
to make getting started quick and easy, with the ability to scale up to
complex applications. It began as a simple wrapper around [Werkzeug](https://werkzeug.palletsprojects.com/)
and [Jinja](https://jinja.palletsprojects.com/) and has become one of the most popular Python web
application frameworks.
Flask offers suggestions, but doesn't enforce any dependencies or
project layout. It is up to the developer to choose the tools and
libraries they want to use. There are many extensions provided by the
community that make adding new functionality easy.
documentation: https://flask.palletsprojects.com/
repository: https://github.com/pallets/flask/

extra:
recipe-maintainers:
- mygithubusername

0 comments on commit 62fc493

Please sign in to comment.