Have CI check if we need to commit regenerated archives
Unified · Split
| @@ -92,9 +92,13 @@ jobs: · 91 unmodified lines | |||
| 92 | with: | 92 | with: |
| 93 | tool: nextest | 93 | tool: nextest |
| 94 | - name: "Test (nextest)" | 94 | - name: "Test (nextest)" |
| 95 | env: | ||
| 96 | GIX_TEST_CREATE_ARCHIVES_EVEN_ON_CI: 1 | ||
| 95 | run: cargo nextest run --all --no-fail-fast | 97 | run: cargo nextest run --all --no-fail-fast |
| 96 | - name: Doctest | 98 | - name: Doctest |
| 97 | run: cargo test --doc | 99 | run: cargo test --doc |
| 100 | - name: Check that tracked archives are up to date | ||
| 101 | run: git diff --exit-code # If this fails, the fix is usually to commit a regenerated archive. | ||
| 98 | 102 | ||
| 99 | test-32bit: | 103 | test-32bit: |
| 100 | runs-on: ubuntu-latest | 104 | runs-on: ubuntu-latest |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | use std::{ | 11 | use std::{ |
| 12 | collections::BTreeMap, | 12 | collections::BTreeMap, |
| 13 | env, | ||
| 13 | ffi::OsString, | 14 | ffi::OsString, |
| 14 | io::Read, | 15 | io::Read, |
| 15 | path::{Path, PathBuf}, | 16 | path::{Path, PathBuf}, |
| @@ -150,8 +151,8 @@ fn git_version_from_bytes(bytes: &[u8]) -> Result<(u8, u8, u8)> { · 134 unmodified lines | |||
| 150 | 151 | ||
| 151 | /// Set the current working dir to `new_cwd` and return a type that returns to the previous working dir on drop. | 152 | /// Set the current working dir to `new_cwd` and return a type that returns to the previous working dir on drop. |
| 152 | pub fn set_current_dir(new_cwd: impl AsRef<Path>) -> std::io::Result<AutoRevertToPreviousCWD> { | 153 | pub fn set_current_dir(new_cwd: impl AsRef<Path>) -> std::io::Result<AutoRevertToPreviousCWD> { |
| 153 | let cwd = std::env::current_dir()?; | 154 | let cwd = env::current_dir()?; |
| 154 | std::env::set_current_dir(new_cwd)?; | 155 | env::set_current_dir(new_cwd)?; |
| 155 | Ok(AutoRevertToPreviousCWD(cwd)) | 156 | Ok(AutoRevertToPreviousCWD(cwd)) |
| 156 | } | 157 | } |
| 157 | 158 | ||
| @@ -166,7 +167,7 @@ pub struct AutoRevertToPreviousCWD(PathBuf); · 8 unmodified lines | |||
| 166 | 167 | ||
| 167 | impl Drop for AutoRevertToPreviousCWD { | 168 | impl Drop for AutoRevertToPreviousCWD { |
| 168 | fn drop(&mut self) { | 169 | fn drop(&mut self) { |
| 169 | std::env::set_current_dir(&self.0).unwrap(); | 170 | env::set_current_dir(&self.0).unwrap(); |
| 170 | } | 171 | } |
| 171 | } | 172 | } |
| 172 | 173 | ||
| @@ -461,7 +462,7 @@ fn scripted_fixture_read_only_with_args_inner( · 288 unmodified lines | |||
| 461 | crc_digest.update(&std::fs::read(&script_path).unwrap_or_else(|err| { | 462 | crc_digest.update(&std::fs::read(&script_path).unwrap_or_else(|err| { |
| 462 | panic!( | 463 | panic!( |
| 463 | "file {script_path:?} in CWD {:?} could not be read: {err}", | 464 | "file {script_path:?} in CWD {:?} could not be read: {err}", |
| 464 | std::env::current_dir().expect("valid cwd"), | 465 | env::current_dir().expect("valid cwd"), |
| 465 | ) | 466 | ) |
| 466 | })); | 467 | })); |
| 467 | for arg in &args { | 468 | for arg in &args { |
| @@ -548,7 +549,7 @@ fn scripted_fixture_read_only_with_args_inner( · 80 unmodified lines | |||
| 548 | script_location.display() | 549 | script_location.display() |
| 549 | ); | 550 | ); |
| 550 | } | 551 | } |
| 551 | let script_absolute_path = std::env::current_dir()?.join(script_path); | 552 | let script_absolute_path = env::current_dir()?.join(script_path); |
| 552 | let mut cmd = std::process::Command::new(&script_absolute_path); | 553 | let mut cmd = std::process::Command::new(&script_absolute_path); |
| 553 | let output = match configure_command(&mut cmd, &args, &script_result_directory).output() { | 554 | let output = match configure_command(&mut cmd, &args, &script_result_directory).output() { |
| 554 | Ok(out) => out, | 555 | Ok(out) => out, |
| @@ -569,7 +570,7 @@ fn scripted_fixture_read_only_with_args_inner( · 14 unmodified lines | |||
| 569 | output.stdout.as_bstr(), | 570 | output.stdout.as_bstr(), |
| 570 | output.stderr.as_bstr() | 571 | output.stderr.as_bstr() |
| 571 | ); | 572 | ); |
| 572 | create_archive_if_not_on_ci( | 573 | create_archive_if_we_should( |
| 573 | &script_result_directory, | 574 | &script_result_directory, |
| 574 | &archive_file_path, | 575 | &archive_file_path, |
| 575 | script_identity_for_archive, | 576 | script_identity_for_archive, |
| @@ -593,7 +594,7 @@ fn configure_command<'a>( · 17 unmodified lines | |||
| 593 | args: &[String], | 594 | args: &[String], |
| 594 | script_result_directory: &Path, | 595 | script_result_directory: &Path, |
| 595 | ) -> &'a mut std::process::Command { | 596 | ) -> &'a mut std::process::Command { |
| 596 | let mut msys_for_git_bash_on_windows = std::env::var_os("MSYS").unwrap_or_default(); | 597 | let mut msys_for_git_bash_on_windows = env::var_os("MSYS").unwrap_or_default(); |
| 597 | msys_for_git_bash_on_windows.push(" winsymlinks:nativestrict"); | 598 | msys_for_git_bash_on_windows.push(" winsymlinks:nativestrict"); |
| 598 | cmd.args(args) | 599 | cmd.args(args) |
| 599 | .stdout(std::process::Stdio::piped()) | 600 | .stdout(std::process::Stdio::piped()) |
| @@ -632,6 +633,14 @@ fn write_failure_marker(failure_marker: &Path) { · 32 unmodified lines | |||
| 632 | std::fs::write(failure_marker, []).ok(); | 633 | std::fs::write(failure_marker, []).ok(); |
| 633 | } | 634 | } |
| 634 | 635 | ||
| 636 | fn should_skip_all_archive_creation() -> bool { | ||
| 637 | // On Windows, we fail to remove the meta_dir and can't do anything about it, which means tests will see more | ||
| 638 | // in the directory than they should which makes them fail. It's probably a bad idea to generate archives on Windows | ||
| 639 | // anyway. Either Unix is portable OR no archive is created anywhere. This also means that Windows users can't create | ||
| 640 | // archives, but that's not a deal-breaker. | ||
| 641 | cfg!(windows) || (is_ci::cached() && env::var_os("GIX_TEST_CREATE_ARCHIVES_EVEN_ON_CI").is_none()) | ||
| 642 | } | ||
| 643 | |||
| 635 | fn is_lfs_pointer_file(path: &Path) -> bool { | 644 | fn is_lfs_pointer_file(path: &Path) -> bool { |
| 636 | const PREFIX: &[u8] = b"version https://gix-lfs"; | 645 | const PREFIX: &[u8] = b"version https://gix-lfs"; |
| 637 | let mut buf = [0_u8; PREFIX.len()]; | 646 | let mut buf = [0_u8; PREFIX.len()]; |
| @@ -642,14 +651,10 @@ fn is_lfs_pointer_file(path: &Path) -> bool { · 4 unmodified lines | |||
| 642 | .map_or(false, |_| buf.starts_with(PREFIX)) | 651 | .map_or(false, |_| buf.starts_with(PREFIX)) |
| 643 | } | 652 | } |
| 644 | 653 | ||
| 645 | /// The `script_identity` will be baked into the soon to be created `archive` as it identitifies the script | 654 | /// The `script_identity` will be baked into the soon to be created `archive` as it identifies the script |
| 646 | /// that created the contents of `source_dir`. | 655 | /// that created the contents of `source_dir`. |
| 647 | fn create_archive_if_not_on_ci(source_dir: &Path, archive: &Path, script_identity: u32) -> std::io::Result<()> { | 656 | fn create_archive_if_we_should(source_dir: &Path, archive: &Path, script_identity: u32) -> std::io::Result<()> { |
| 648 | // on windows, we fail to remove the meta_dir and can't do anything about it, which means tests will see more | 657 | if should_skip_all_archive_creation() || is_excluded(archive) { |
| 649 | // in the directory than they should which makes them fail. It's probably a bad idea to generate archives on windows | ||
| 650 | // anyway. Either unix is portable OR no archive is created anywhere. This also means that windows users can't create | ||
| 651 | // archives, but that's not a deal-breaker. | ||
| 652 | if cfg!(windows) || is_ci::cached() || is_excluded(archive) { | ||
| 653 | return Ok(()); | 658 | return Ok(()); |
| 654 | } | 659 | } |
| 655 | if is_lfs_pointer_file(archive) { | 660 | if is_lfs_pointer_file(archive) { |
| @@ -702,7 +707,7 @@ fn is_excluded(archive: &Path) -> bool { · 46 unmodified lines | |||
| 702 | let mut lut = EXCLUDE_LUT.lock(); | 707 | let mut lut = EXCLUDE_LUT.lock(); |
| 703 | lut.as_mut() | 708 | lut.as_mut() |
| 704 | .and_then(|cache| { | 709 | .and_then(|cache| { |
| 705 | let archive = std::env::current_dir().ok()?.join(archive); | 710 | let archive = env::current_dir().ok()?.join(archive); |
| 706 | let relative_path = archive.strip_prefix(cache.base()).ok()?; | 711 | let relative_path = archive.strip_prefix(cache.base()).ok()?; |
| 707 | cache | 712 | cache |
| 708 | .at_path( | 713 | .at_path( |
| @@ -746,7 +751,7 @@ fn extract_archive( · 37 unmodified lines | |||
| 746 | let mut buf = Vec::new(); | 751 | let mut buf = Vec::new(); |
| 747 | #[cfg_attr(feature = "xz", allow(unused_mut))] | 752 | #[cfg_attr(feature = "xz", allow(unused_mut))] |
| 748 | let mut input_archive = std::fs::File::open(archive)?; | 753 | let mut input_archive = std::fs::File::open(archive)?; |
| 749 | if std::env::var_os("GIX_TEST_IGNORE_ARCHIVES").is_some() { | 754 | if env::var_os("GIX_TEST_IGNORE_ARCHIVES").is_some() { |
| 750 | return Err(std::io::Error::new( | 755 | return Err(std::io::Error::new( |
| 751 | std::io::ErrorKind::Other, | 756 | std::io::ErrorKind::Other, |
| 752 | format!( | 757 | format!( |
| @@ -848,16 +853,16 @@ impl<'a> Env<'a> { · 95 unmodified lines | |||
| 848 | 853 | ||
| 849 | /// Set `var` to `value`. | 854 | /// Set `var` to `value`. |
| 850 | pub fn set(mut self, var: &'a str, value: impl Into<String>) -> Self { | 855 | pub fn set(mut self, var: &'a str, value: impl Into<String>) -> Self { |
| 851 | let prev = std::env::var_os(var); | 856 | let prev = env::var_os(var); |
| 852 | std::env::set_var(var, value.into()); | 857 | env::set_var(var, value.into()); |
| 853 | self.altered_vars.push((var, prev)); | 858 | self.altered_vars.push((var, prev)); |
| 854 | self | 859 | self |
| 855 | } | 860 | } |
| 856 | 861 | ||
| 857 | /// Unset `var`. | 862 | /// Unset `var`. |
| 858 | pub fn unset(mut self, var: &'a str) -> Self { | 863 | pub fn unset(mut self, var: &'a str) -> Self { |
| 859 | let prev = std::env::var_os(var); | 864 | let prev = env::var_os(var); |
| 860 | std::env::remove_var(var); | 865 | env::remove_var(var); |
| 861 | self.altered_vars.push((var, prev)); | 866 | self.altered_vars.push((var, prev)); |
| 862 | self | 867 | self |
| 863 | } | 868 | } |
| @@ -867,8 +872,8 @@ impl<'a> Drop for Env<'a> { · 3 unmodified lines | |||
| 867 | fn drop(&mut self) { | 872 | fn drop(&mut self) { |
| 868 | for (var, prev_value) in self.altered_vars.iter().rev() { | 873 | for (var, prev_value) in self.altered_vars.iter().rev() { |
| 869 | match prev_value { | 874 | match prev_value { |
| 870 | Some(value) => std::env::set_var(var, value), | 875 | Some(value) => env::set_var(var, value), |
| 871 | None => std::env::remove_var(var), | 876 | None => env::remove_var(var), |
| 872 | } | 877 | } |
| 873 | } | 878 | } |
| 874 | } | 879 | } |