Unified · Split
| @@ -1,3 +1,4 @@ | |||
| 1 | use std::io::Read; | ||
| 1 | use std::{ | 2 | use std::{ |
| 2 | collections::BTreeMap, | 3 | collections::BTreeMap, |
| 3 | path::{Path, PathBuf}, | 4 | path::{Path, PathBuf}, |
| @@ -186,12 +187,12 @@ fn create_archive_if_not_on_ci(source_dir: &Path, archive: &Path, script_identit · 182 unmodified lines | |||
| 186 | res | 187 | res |
| 187 | } | 188 | } |
| 188 | 189 | ||
| 189 | const META_NAME: &str = "__gitoxide_meta__"; | 190 | const META_DIR_NAME: &str = "__gitoxide_meta__"; |
| 190 | const META_IDENTITY: &str = "identity"; | 191 | const META_IDENTITY: &str = "identity"; |
| 191 | const META_GIT_VERSION: &str = "git-version"; | 192 | const META_GIT_VERSION: &str = "git-version"; |
| 192 | 193 | ||
| 193 | fn populate_meta_dir(destination_dir: &Path, script_identity: u32) -> std::io::Result<PathBuf> { | 194 | fn populate_meta_dir(destination_dir: &Path, script_identity: u32) -> std::io::Result<PathBuf> { |
| 194 | let meta_dir = destination_dir.join(META_NAME); | 195 | let meta_dir = destination_dir.join(META_DIR_NAME); |
| 195 | std::fs::create_dir_all(&meta_dir)?; | 196 | std::fs::create_dir_all(&meta_dir)?; |
| 196 | std::fs::write(meta_dir.join(META_IDENTITY), format!("{}", script_identity).as_bytes())?; | 197 | std::fs::write(meta_dir.join(META_IDENTITY), format!("{}", script_identity).as_bytes())?; |
| 197 | std::fs::write( | 198 | std::fs::write( |
| @@ -203,10 +204,46 @@ fn populate_meta_dir(destination_dir: &Path, script_identity: u32) -> std::io::R · 5 unmodified lines | |||
| 203 | 204 | ||
| 204 | /// `required_script_identity` is the identity of the script that generated the state that is contained in `archive`. | 205 | /// `required_script_identity` is the identity of the script that generated the state that is contained in `archive`. |
| 205 | /// If this is not the case, the arvhive will be ignored. | 206 | /// If this is not the case, the arvhive will be ignored. |
| 206 | fn extract_archive(_archive: &Path, destination_dir: &Path, _required_script_identity: u32) -> std::io::Result<()> { | 207 | fn extract_archive(archive: &Path, destination_dir: &Path, required_script_identity: u32) -> std::io::Result<()> { |
| 207 | std::fs::create_dir_all(destination_dir)?; | 208 | std::fs::create_dir_all(destination_dir)?; |
| 208 | // TODO | 209 | |
| 209 | Err(std::io::ErrorKind::NotFound.into()) | 210 | let mut archive_buf = Vec::<u8>::new(); |
| 211 | let mut decoder = xz2::bufread::XzDecoder::new(std::io::BufReader::new(std::fs::File::open(archive)?)); | ||
| 212 | std::io::copy(&mut decoder, &mut archive_buf)?; | ||
| 213 | |||
| 214 | let mut entry_buf = Vec::<u8>::new(); | ||
| 215 | let archive_identity: u32 = tar::Archive::new(std::io::Cursor::new(&mut &*archive_buf)) | ||
| 216 | .entries_with_seek()? | ||
| 217 | .filter_map(|e| e.ok()) | ||
| 218 | .find_map(|mut e: tar::Entry<'_, _>| { | ||
| 219 | let path = e.path().ok()?; | ||
| 220 | if path.parent()?.file_name()? == META_DIR_NAME && path.file_name()? == META_IDENTITY { | ||
| 221 | entry_buf.clear(); | ||
| 222 | e.read_to_end(&mut entry_buf).ok()?; | ||
| 223 | entry_buf.to_str().ok()?.trim().parse().ok() | ||
| 224 | } else { | ||
| 225 | None | ||
| 226 | } | ||
| 227 | }) | ||
| 228 | .ok_or_else(|| { | ||
| 229 | std::io::Error::new( | ||
| 230 | std::io::ErrorKind::Other, | ||
| 231 | "BUG: Could not find meta directory in our own archive", | ||
| 232 | ) | ||
| 233 | })?; | ||
| 234 | if archive_identity != required_script_identity { | ||
| 235 | return Err(std::io::ErrorKind::NotFound.into()); | ||
| 236 | } | ||
| 237 | |||
| 238 | for entry in tar::Archive::new(&mut &*archive_buf).entries()? { | ||
| 239 | let mut entry = entry?; | ||
| 240 | let path = entry.path()?; | ||
| 241 | if path.to_str() == Some(META_DIR_NAME) || path.parent().and_then(|p| p.to_str()) == Some(META_DIR_NAME) { | ||
| 242 | continue; | ||
| 243 | } | ||
| 244 | entry.unpack_in(&destination_dir)?; | ||
| 245 | } | ||
| 246 | Ok(()) | ||
| 210 | } | 247 | } |
| 211 | 248 | ||
| 212 | pub fn to_bstr_err(err: nom::Err<VerboseError<&[u8]>>) -> VerboseError<&BStr> { | 249 | pub fn to_bstr_err(err: nom::Err<VerboseError<&[u8]>>) -> VerboseError<&BStr> { |