History

Merge pull request #1590 from EliahKagan/run-ci/check-clean

Have CI check if we need to commit regenerated archives

Sebastian Thiel committed 2 years ago

Commit 4f921402 parents c485a2b 4150af42 files · +31 −22Browse files

Unified · Split

2 files
  1. .github/workflows/ci.yml +4 −0
  2. tests/tools/src/lib.rs +27 −22
.github/workflows/ci.yml+4−0
@@ -92,9 +92,13 @@ jobs: · 91 unmodified lines
92 with:92 with:
93 tool: nextest93 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-fast97 run: cargo nextest run --all --no-fail-fast
96 - name: Doctest98 - name: Doctest
97 run: cargo test --doc99 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-latest104 runs-on: ubuntu-latest
tests/tools/src/lib.rs+27−22
@@ -10,6 +10,7 @@ · 9 unmodified lines
10 10
11use std::{11use 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.
152pub fn set_current_dir(new_cwd: impl AsRef<Path>) -> std::io::Result<AutoRevertToPreviousCWD> {153pub 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
167impl Drop for AutoRevertToPreviousCWD {168impl 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
636fn 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
635fn is_lfs_pointer_file(path: &Path) -> bool {644fn 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 script654/// 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`.
647fn create_archive_if_not_on_ci(source_dir: &Path, archive: &Path, script_identity: u32) -> std::io::Result<()> {656fn 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 more657 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 cache712 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 self859 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 self867 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 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t