Handle cyclic Ubuntu dependencies
Dependencies
- [2]
PLQ2WBZ3Do not err when two recipes give the same output - [3]
APRNC3CWLooking up alternatives: fixing a bug - [4]
6MGFBMONDebug and cleanup - [5]
SI454P2VDocumentation and cleanup - [6]
KOWYPLMXNix and config.toml - [7]
HX4TXY2DFixed-output derivations enable the network - [8]
UWQB743KFirst working shell (with ocaml code) - [9]
ODUDDQRYAdding the OCaml interface
Change contents
- edit in src/main.rs at line 162
- edit in src/extract.rs at line 23
#[derive(Debug)]struct Vertex<'a> {pkg: deb::Stanza<'a>,downloaded: Downloaded,index: Option<usize>,lowlink: usize,on_stack: bool,scc: usize,deps: Vec<usize>,context_path: Option<Arc<PathBuf>>,final_path: Option<Arc<PathBuf>>,deps_paths: Vec<Arc<PathBuf>>,transitive_deps: Vec<Arc<PathBuf>>,transitive_deps_h: BTreeSet<Arc<PathBuf>>,ld_path: Vec<Arc<PathBuf>>,ld_path_h: BTreeSet<Arc<PathBuf>>,files: BTreeSet<Arc<String>>,} - edit in src/extract.rs at line 49
let files = Arc::new(Mutex::new(HashMap::new()));let mut seen = HashMap::new(); - replacement in src/extract.rs at line 50[5.17786]→[5.20122:20224](∅→∅),[5.20122]→[5.20122:20224](∅→∅),[5.20224]→[5.17787:17868](∅→∅),[5.17868]→[5.20257:20322](∅→∅),[5.20257]→[5.20257:20322](∅→∅),[5.20322]→[5.17869:17901](∅→∅),[5.17901]→[5.20322:20330](∅→∅),[5.20322]→[5.20322:20330](∅→∅)
let mut stack = vec![StackElt {package: pkg,rx: None,deps: Vec::new(),transitive_deps: Vec::new(),transitive_deps_h: BTreeSet::new(),ld_path: Vec::new(),ld_path_h: BTreeSet::new(),files: BTreeSet::new(),}];let mut seen: HashMap<_, (Vec<&str>, usize)> = HashMap::new();let mut stack = vec![(pkg, None)];let mut vertices = Vec::new();while let Some((pkg, rx)) = stack.pop() {info!("{:?}", pkg);if let Some(rx) = rx {let downloaded: Result<Result<Downloaded, Error>, _> = rx.await;let downloaded = downloaded.unwrap()?;seen.get_mut(pkg.package).unwrap().1 = vertices.len();vertices.push(Vertex {downloaded,deps: seen.get(pkg.package).unwrap().0.iter().map(|x| seen.get(x).unwrap().1).collect(),pkg,context_path: None,deps_paths: Vec::new(),files: BTreeSet::new(),final_path: None,ld_path: Vec::new(),ld_path_h: BTreeSet::new(),index: None,lowlink: 0,on_stack: false,scc: 0,transitive_deps: Vec::new(),transitive_deps_h: BTreeSet::new(),});} else if !seen.contains_key(pkg.package) {let rx = spawn_extract(client.clone(), &pkg).await;let depends = pkg.depends.clone();let pkg_package = pkg.package;stack.push((pkg, Some(rx)));let deps = push_deps(&depends, index, &mut stack).await;seen.insert(pkg_package, (deps, 0));}}let sccs = tarjan(&mut vertices);debug!("sccs: {:?}", sccs); - replacement in src/extract.rs at line 97
let mut paths = BTreeSet::new();while let Some(mut elt) = stack.pop() {info!("{:?}", elt);let files = Arc::new(Mutex::new(HashMap::new())); - replacement in src/extract.rs at line 99[5.20502]→[5.20502:20544](∅→∅),[5.20544]→[5.17940:17989](∅→∅),[5.17989]→[5.20592:20643](∅→∅),[5.20592]→[5.20592:20643](∅→∅),[5.20643]→[5.17990:18102](∅→∅),[5.18102]→[5.20721:20746](∅→∅),[5.20721]→[5.20721:20746](∅→∅),[5.20746]→[5.18103:18275](∅→∅),[5.18275]→[5.20817:20834](∅→∅),[5.20817]→[5.20817:20834](∅→∅),[5.20834]→[5.18276:18441](∅→∅),[5.18441]→[5.20910:21215](∅→∅),[5.20910]→[5.20910:21215](∅→∅),[5.21215]→[5.18442:18563](∅→∅),[5.18563]→[5.3344:3540](∅→∅),[5.3540]→[5.18665:18733](∅→∅),[5.18665]→[5.18665:18733](∅→∅),[5.18733]→[5.21371:21419](∅→∅),[5.21371]→[5.21371:21419](∅→∅),[5.21419]→[5.18734:18790](∅→∅)
if let Some(rx) = elt.rx.take() {let downloaded = rx.await.unwrap()?;info!("downloaded {:?}", elt.package);let final_path = elt.finalize(client, &files, downloaded, &mut stack, &mut result).await?;seen.insert(elt.package.package,(elt.ld_path, elt.transitive_deps, final_path),);paths = elt.files;} else {if let Some((ld_path, transitive_deps, final_path)) = seen.get(&elt.package.package) {debug!("already seen {:?}", elt.package.package);if let Some(last) = stack.iter_mut().rev().filter(|x| x.rx.is_some()).next() {for ld in ld_path {if last.ld_path_h.insert(ld.clone()) {last.ld_path.push(ld.clone());}}for dep in transitive_deps {if last.transitive_deps_h.insert(dep.clone()) {debug!("adding transitive dep: {:?} -> {:?}",last.package.package, dep);last.transitive_deps.push(dep.clone());}}last.deps.push(final_path.clone());for scc in sccs.iter() {for v in scc.iter() {let mut context_hasher = blake3::Hasher::new();context_hasher.update(vertices[*v].pkg.sha256.unwrap().as_bytes());for d in vertices[*v].deps.iter() {let w = &vertices[*d];if w.scc == vertices[*v].scc {// If in the same SCC, we can't know anything other than the SHA256.context_hasher.update(w.pkg.sha256.unwrap().as_bytes());} else {context_hasher.update(w.final_path.as_ref().unwrap().to_str().unwrap().as_bytes()); - edit in src/extract.rs at line 112
continue;} else {seen.insert(elt.package.package,(Vec::new(), Vec::new(), Arc::new(PathBuf::new())),); - edit in src/extract.rs at line 113
vertices[*v].context_path =Some(Arc::new(client.store_path.join(data_encoding::HEXLOWER.encode(context_hasher.finalize().as_bytes()),)));} - replacement in src/extract.rs at line 119
elt.spawn_extract(client.clone()).await;elt.push_deps(index, &mut stack).await;for v in scc.iter() {let f = finalize(&mut vertices, client, &files, *v).await?;vertices[*v].final_path = Some(f.clone());result.push(f) - edit in src/extract.rs at line 125
- replacement in src/extract.rs at line 128
paths: paths.into_iter().collect(),paths: vertices.last().unwrap().files.iter().cloned().collect(), - edit in src/extract.rs at line 130
}fn tarjan(vertices: &mut [Vertex]) -> Vec<Vec<usize>> {let mut sccs = Vec::new();let mut stack = Vec::new();let mut index = 0;struct C {vi: usize,wj: usize,}let mut call_stack = vec![C {vi: vertices.len() - 1,wj: 0,}];'outer: while let Some(mut c) = call_stack.pop() {if vertices[c.vi].index.is_none() {let ref mut v = vertices[c.vi];v.index = Some(index);v.lowlink = index;v.on_stack = true;index += 1;stack.push(c.vi);}while c.wj < vertices[c.vi].deps.len() {let wi = vertices[c.vi].deps[c.wj];if let Some(index) = vertices[wi].index {if vertices[wi].on_stack {vertices[c.vi].lowlink = vertices[c.vi].lowlink.min(index)}c.wj += 1;} else {c.wj += 1;call_stack.push(c);call_stack.push(C { vi: wi, wj: 0 });continue 'outer;}}if Some(vertices[c.vi].lowlink) == vertices[c.vi].index {let mut scc = Vec::new();while let Some(p) = stack.pop() {vertices[p].scc = sccs.len();vertices[p].on_stack = false;scc.push(p);if p == c.vi {break;}}sccs.push(scc)}}sccs - replacement in src/extract.rs at line 224
let mut f = std::io::BufReader::new(std::fs::File::open(&download.path)?);let d = match deb::Deb::read(&mut f) {Ok(d) => d,Err(e) => {std::fs::remove_file(&download.path).unwrap_or(());return Err(e.into());}};std::fs::create_dir_all(&path).unwrap_or(());match d.decompress(&mut f, &path) {let p = path.clone();let dp = download.path.clone();match tokio::task::spawn_blocking(move || {let mut f = std::io::BufReader::new(std::fs::File::open(&dp)?);let d = match deb::Deb::read(&mut f) {Ok(d) => d,Err(e) => {std::fs::remove_file(&dp).unwrap_or(());return Err(e.into());}};std::fs::create_dir_all(&p).unwrap_or(());d.decompress(&mut f, &p)}).await.unwrap(){ - edit in src/extract.rs at line 243
download.path = path; - replacement in src/extract.rs at line 244
Ok(())download.path = path;Ok::<(), Error>(()) - edit in src/extract.rs at line 254
}async fn spawn_extract<'a>(client: Client,stanza: &deb::Stanza<'a>,) -> tokio::sync::oneshot::Receiver<Result<Downloaded, Error>> {let url = client.url(stanza.file_name.as_deref());let sha256 = stanza.sha256.unwrap().to_string();let (tx, rx) = tokio::sync::oneshot::channel();tokio::spawn(async move {let permit = client.download_sem.clone().acquire_owned().await.unwrap();info!("downloading {:?}", url);let (mut task, _) = match client.download_url(&url, &sha256).await {Ok(x) => x,Err(e) => {tx.send(Err(e)).unwrap_or(());return Ok(());}};let is_extracted = std::fs::metadata(&task.path.with_extension("")).is_ok();info!("finished downloading {:?}", url);if !is_extracted {// Sets extensionif let Err(e) = extract_task(&client, &mut task).await {info!("finished extracting {:?} {:?}", url, e);tx.send(Err(e)).unwrap_or(());} else {info!("finished extracting {:?}, Ok", url);tx.send(Ok(task)).unwrap_or(());}info!("sent {:?}", url);} else {task.path.set_extension("");tx.send(Ok(task)).unwrap_or(());}drop(permit);Ok::<_, Error>(())});rx - replacement in src/extract.rs at line 312
impl<'a> StackElt<'a> {impl<'a> Vertex<'a> { - replacement in src/extract.rs at line 321
for d in self.deps.iter() {for d in self.deps_paths.iter() { - replacement in src/extract.rs at line 347
fn add_ld_paths(&mut self, path: &Path) -> Result<(), std::io::Error> {let mut ld_so = path.join("etc");fn add_ld_paths(&mut self) -> Result<(), std::io::Error> {let mut ld_so = self.downloaded.path.join("etc"); - replacement in src/extract.rs at line 380
fn find_libs(&mut self, path: &Path, dest: &Path) {fn find_libs(&mut self) { - replacement in src/extract.rs at line 382
let path = path.join(ld.strip_prefix("/").unwrap());let path = self.downloaded.path.join(ld.strip_prefix("/").unwrap()); - replacement in src/extract.rs at line 385
let path = Arc::new(dest.join(ld.strip_prefix("/").unwrap()));let path = Arc::new(self.context_path.as_ref().unwrap().join(ld.strip_prefix("/").unwrap()),); - replacement in src/extract.rs at line 472
for dep in self.transitive_deps.iter().rev() {for dep in self.deps_paths.iter().chain(self.transitive_deps.iter().rev()){ - edit in src/extract.rs at line 505
} - replacement in src/extract.rs at line 507[5.30633]→[5.30633:30794](∅→∅),[5.30794]→[5.24275:24354](∅→∅),[5.24354]→[5.30858:30986](∅→∅),[5.30858]→[5.30858:30986](∅→∅),[5.30986]→[5.24355:24381](∅→∅),[5.24381]→[5.30986:31089](∅→∅),[5.30986]→[5.30986:31089](∅→∅)
async fn finalize(&mut self,client: &Client,files: &Files,downloaded: Downloaded,stack: &mut Vec<StackElt<'a>>,result: &mut Vec<Arc<PathBuf>>,) -> Result<Arc<PathBuf>, Error> {let mut context_hasher = blake3::Hasher::new();context_hasher.update(self.package.sha256.unwrap().as_bytes());self.deps.sort();for d in self.deps.iter() {context_hasher.update(d.to_str().unwrap().as_bytes());async fn finalize<'a>(vertices: &mut [Vertex<'a>],client: &Client,files: &Files,v: usize,) -> Result<Arc<PathBuf>, Error> {debug!("finalize {:?} {:#?}",vertices[v].pkg.package, vertices[v].transitive_deps);let mut ld_path = std::mem::replace(&mut vertices[v].ld_path, Vec::new());let mut ld_path_h = std::mem::replace(&mut vertices[v].ld_path_h, BTreeSet::new());let mut transitive_deps = std::mem::replace(&mut vertices[v].transitive_deps, Vec::new());let mut transitive_deps_h =std::mem::replace(&mut vertices[v].transitive_deps_h, BTreeSet::new());let mut deps_paths = Vec::new();for dep in vertices[v].deps.clone().iter() {for ld in vertices[*dep].ld_path.iter() {if ld_path_h.insert(ld.clone()) {ld_path.push(ld.clone());} - replacement in src/extract.rs at line 530
debug!("finalize {:?} {:#?}",self.package.package, self.transitive_deps);let dest = client.store_path.join(data_encoding::HEXLOWER.encode(context_hasher.finalize().as_bytes()));for d in vertices[*dep].transitive_deps.iter() {if transitive_deps_h.insert(d.clone()) {debug!("adding transitive dep: {:?} -> {:?}",vertices[v].pkg.package, dep);transitive_deps.push(d.clone());}}deps_paths.push(if vertices[*dep].scc == vertices[v].scc {vertices[*dep].context_path.clone().unwrap()} else {vertices[*dep].final_path.clone().unwrap()})}vertices[v].ld_path = ld_path;vertices[v].ld_path_h = ld_path_h;vertices[v].transitive_deps = transitive_deps;vertices[v].transitive_deps_h = transitive_deps_h;vertices[v].deps_paths = deps_paths; - replacement in src/extract.rs at line 551
let lock = client.lock_store_path(&dest).await;let dest = vertices[v].context_path.clone().unwrap(); - replacement in src/extract.rs at line 553
// Find the extra ld paths to look for.self.add_ld_paths(&downloaded.path).unwrap();let lock = client.lock_store_path(&*dest).await; - replacement in src/extract.rs at line 555
let initial_deps_len = self.transitive_deps.len();// Find the libs in this package.self.find_libs(&downloaded.path, &dest);// Find the extra ld paths to look for.vertices[v].add_ld_paths().unwrap(); - replacement in src/extract.rs at line 558
let base_package_name = self.package.file_name.unwrap().split('/').last().unwrap();let base_package_name = Path::new(&base_package_name).with_extension("");let base_package_name = base_package_name.to_str().unwrap();let initial_deps_len = vertices[v].transitive_deps.len();// Find the libs in this package.vertices[v].find_libs(); - replacement in src/extract.rs at line 562[5.31726]→[5.31726:31790](∅→∅),[5.31790]→[5.24618:24992](∅→∅),[5.24992]→[5.33466:33498](∅→∅),[5.33466]→[5.33466:33498](∅→∅),[5.34260]→[5.34260:34277](∅→∅),[5.34277]→[5.24993:25046](∅→∅),[5.25046]→[5.34318:34430](∅→∅),[5.34318]→[5.34318:34430](∅→∅),[5.34430]→[5.25047:25339](∅→∅),[5.25339]→[5.34503:34561](∅→∅),[5.34503]→[5.34503:34561](∅→∅)
let final_path = if std::fs::metadata(&dest).is_err() {info!("create final path for {dest:?}");match self.create_final_path(client, &files, &downloaded.path, &dest, &base_package_name).await{Ok(x) => x,Err(e) => {tokio::fs::remove_dir_all(&dest).await.unwrap_or(());return Err(e);}}} else {info!("found, no patching: {:?}", dest);let mut output_hasher = blake3::Hasher::new();let blakesums = dest.join("blake3sums");let file = match tokio::fs::File::open(&blakesums).await {Ok(file) => file,Err(e) => {error!("Error {:?} {:?}: {:?}", blakesums, downloaded.path, e);return Err(e.into());}};hash_reader(file, &mut output_hasher).await?;let base_package_name = vertices[v].pkg.file_name.unwrap().split('/').last().unwrap();let base_package_name = Path::new(&base_package_name).with_extension("");let base_package_name = base_package_name.to_str().unwrap(); - replacement in src/extract.rs at line 572
let r = tokio::io::BufReader::new(tokio::fs::File::open(&dest.join("paths")).await.unwrap(),);let mut l = r.lines();while let Some(l) = l.next_line().await? {self.files.insert(Arc::new(l));let final_path = if std::fs::metadata(&*dest).is_err() {info!("create final path for {dest:?}");match vertices[v].create_final_path(client, &files, &dest, &base_package_name).await{Ok(x) => x,Err(e) => {tokio::fs::remove_dir_all(&*dest).await.unwrap_or(());return Err(e); - edit in src/extract.rs at line 583[5.25630]→[5.25630:25631](∅→∅),[5.25631]→[5.34561:34777](∅→∅),[5.34561]→[5.34561:34777](∅→∅),[5.34777]→[5.25632:25679](∅→∅),[5.25679]→[5.34777:34778](∅→∅),[5.34777]→[5.34777:34778](∅→∅),[5.34778]→[5.25680:25754](∅→∅),[5.25754]→[5.34778:34885](∅→∅),[5.34778]→[5.34778:34885](∅→∅),[5.34885]→[5.25755:25822](∅→∅),[5.25822]→[5.34941:35049](∅→∅),[5.34941]→[5.34941:35049](∅→∅)
client.store_path.join(&format!("{}-{}",data_encoding::HEXLOWER.encode(output_hasher.finalize().as_bytes()),base_package_name,))};let final_path = Arc::new(final_path);add_subst(downloaded.path.clone(), &dest, files.clone()).await?;// Replace prefix for all library deps we've just added,// in order to get a Merkle tree.for dep in &mut self.transitive_deps[initial_deps_len..] {let end = dep.strip_prefix(&dest).unwrap();*dep = Arc::new(final_path.join(&end)); - replacement in src/extract.rs at line 584[5.35059]→[5.35059:35124](∅→∅),[5.35124]→[5.25823:25887](∅→∅),[5.25887]→[5.35187:35286](∅→∅),[5.35187]→[5.35187:35286](∅→∅),[5.35286]→[5.25888:25949](∅→∅),[5.25949]→[2.0:420](∅→∅),[2.420]→[5.35531:35549](∅→∅),[5.35531]→[5.35531:35549](∅→∅),[5.35549]→[2.421:445](∅→∅)
info!("symlink {:?} {:?}", downloaded.path, final_path);match std::os::unix::fs::symlink(&dest, &*final_path) {Ok(()) => (),Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => {let got = std::fs::read_link(&*final_path)?;debug!("Path already exists, previous value {:?}", got);// This situation means that we've come to the same// result via different build recipes./*if dest != got {return Err(Error::WrongResultSymlink {expected: dest,got,});}*/} else {info!("found, no patching: {:?}", dest);let mut output_hasher = blake3::Hasher::new();let blakesums = dest.join("blake3sums");let file = match tokio::fs::File::open(&blakesums).await {Ok(file) => file,Err(e) => {error!("Error {:?} {:?}: {:?}",blakesums, vertices[v].downloaded.path, e);return Err(e.into()); - replacement in src/extract.rs at line 597
Err(e) => return Err(e.into()),}result.push(final_path.clone());};hash_reader(file, &mut output_hasher).await?; - replacement in src/extract.rs at line 600[5.35651]→[5.35651:35968](∅→∅),[5.35968]→[5.25992:26109](∅→∅),[5.26109]→[5.3618:3782](∅→∅),[5.3782]→[5.26203:26263](∅→∅),[5.26203]→[5.26203:26263](∅→∅),[5.26263]→[5.36112:36130](∅→∅),[5.36112]→[5.36112:36130](∅→∅),[5.36130]→[5.26264:26365](∅→∅),[5.26365]→[5.36130:36144](∅→∅),[5.36130]→[5.36130:36144](∅→∅),[5.36144]→[5.26366:26414](∅→∅)
// Maintenant, faire remonter les deps.if let Some(last) = stack.iter_mut().rev().filter(|x| x.rx.is_some()).next() {for ld in self.ld_path.iter() {if last.ld_path_h.insert(ld.clone()) {last.ld_path.push(ld.clone());}}for dep in self.transitive_deps.iter() {if last.transitive_deps_h.insert(dep.clone()) {debug!("adding transitive dep: {:?} -> {:?}",last.package.package, dep);last.transitive_deps.push(dep.clone());}}for f in self.files.iter() {last.files.insert(f.clone());}last.deps.push(final_path.clone());let r =tokio::io::BufReader::new(tokio::fs::File::open(&dest.join("paths")).await.unwrap());let mut l = r.lines();while let Some(l) = l.next_line().await? {vertices[v].files.insert(Arc::new(l)); - edit in src/extract.rs at line 606[5.36154]→[5.26415:26435](∅→∅),[5.26435]→[5.36154:36209](∅→∅),[5.36154]→[5.36154:36209](∅→∅),[5.36209]→[5.26436:26459](∅→∅),[5.26459]→[5.36224:36230](∅→∅),[5.36224]→[5.36224:36230](∅→∅)
drop(lock);info!("done with {:?}", self.package.package);Ok(final_path)} - replacement in src/extract.rs at line 607[5.36233]→[5.3783:3839](∅→∅),[5.3839]→[5.26539:27894](∅→∅),[5.26539]→[5.26539:27894](∅→∅),[5.27894]→[5.36881:36895](∅→∅),[5.36881]→[5.36881:36895](∅→∅),[5.36895]→[5.27895:27998](∅→∅)
async fn spawn_extract(&mut self, client: Client) {let client = client.clone();let url = client.url(self.package.file_name.as_deref());let sha256 = self.package.sha256.unwrap().to_string();let (tx, rx) = tokio::sync::oneshot::channel();tokio::spawn(async move {let permit = client.download_sem.clone().acquire_owned().await.unwrap();info!("downloading {:?}", url);let (mut task, _) = match client.download_url(&url, &sha256).await {Ok(x) => x,Err(e) => {tx.send(Err(e)).unwrap_or(());return Ok(());}};let is_extracted = std::fs::metadata(&task.path.with_extension("")).is_ok();info!("finished downloading {:?}", url);if !is_extracted {// Sets extensionif let Err(e) = extract_task(&client, &mut task).await {info!("finished extracting {:?} {:?}", url, e);tx.send(Err(e)).unwrap_or(());} else {info!("finished extracting {:?}, Ok", url);tx.send(Ok(task)).unwrap_or(());}info!("sent {:?}", url);} else {task.path.set_extension("");tx.send(Ok(task)).unwrap_or(());}drop(permit);Ok::<_, Error>(())});self.rx = Some(rx);}client.store_path.join(&format!("{}-{}",data_encoding::HEXLOWER.encode(output_hasher.finalize().as_bytes()),base_package_name,))};let final_path = Arc::new(final_path); - replacement in src/extract.rs at line 615[5.27999]→[5.27999:29023](∅→∅),[5.29023]→[3.0:49](∅→∅),[3.49]→[5.29023:29662](∅→∅),[5.29023]→[5.29023:29662](∅→∅),[5.29662]→[3.50:85](∅→∅),[3.85]→[5.29698:29724](∅→∅),[5.29698]→[5.29698:29724](∅→∅),[5.29724]→[5.37481:37503](∅→∅),[5.37481]→[5.37481:37503](∅→∅),[5.37503]→[3.86:214](∅→∅),[3.214]→[5.37503:37521](∅→∅),[5.29777]→[5.37503:37521](∅→∅),[5.37503]→[5.37503:37521](∅→∅)
async fn push_deps(self, index: &'a [deb::Index], stack: &mut Vec<StackElt<'a>>) {let depends = self.package.depends.clone();stack.push(self);for dep in depends.iter() {match dep {deb::Dep::Simple(s) => {debug!("dep {:?}", s);let Some(dep) = multi_lookup(index, &s.name).await else {panic!("could not find {:?}", s.name)};stack.push(StackElt {package: dep,rx: None,deps: Vec::new(),transitive_deps: Vec::new(),transitive_deps_h: BTreeSet::new(),ld_path: Vec::new(),ld_path_h: BTreeSet::new(),files: BTreeSet::new(),})}deb::Dep::Alternatives { alt } => {debug!("alt {:?}", alt);let stack_len = stack.len();for dep in alt {if let Some(dep_) = multi_lookup(index, &dep.name).await {stack.push(StackElt {package: dep_,rx: None,deps: Vec::new(),transitive_deps: Vec::new(),transitive_deps_h: BTreeSet::new(),ld_path: Vec::new(),ld_path_h: BTreeSet::new(),files: BTreeSet::new(),});break;}}if stack.len() == stack_len {panic!("Not found: {:?}", alt);}}add_subst(vertices[v].downloaded.path.clone(), &dest, files.clone()).await?;// Replace prefix for all library deps we've just added,// in order to get a Merkle tree.for dep in &mut vertices[v].transitive_deps[initial_deps_len..] {let end = dep.strip_prefix(&*dest).unwrap();*dep = Arc::new(final_path.join(&end));}info!("symlink {:?} {:?}", vertices[v].downloaded.path, final_path);match std::os::unix::fs::symlink(&*dest, &*final_path) {Ok(()) => (),Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => {let got = std::fs::read_link(&*final_path)?;debug!("Path already exists, previous value {:?}", got);// This situation means that we've come to the same// result via different build recipes./*if dest != got {return Err(Error::WrongResultSymlink {expected: dest,got,}); - edit in src/extract.rs at line 638
*/ - edit in src/extract.rs at line 640
Err(e) => return Err(e.into()), - edit in src/extract.rs at line 642
drop(lock);info!("done with {:?}", vertices[v].pkg.package);Ok(final_path)} - edit in src/extract.rs at line 647
impl<'a> Vertex<'a> { - edit in src/extract.rs at line 652
downloaded_path: &Path, - replacement in src/extract.rs at line 663
debug!("create_final_path {:?}", downloaded_path);for (f, meta) in find_files(downloaded_path.to_path_buf())? {debug!("create_final_path {:?}", self.downloaded.path);for (f, meta) in find_files(self.downloaded.path.to_path_buf())? { - replacement in src/extract.rs at line 666
let rel = f.strip_prefix(&downloaded_path).unwrap();let rel = f.strip_prefix(&self.downloaded.path).unwrap(); - replacement in src/extract.rs at line 740
.strip_prefix(&downloaded_path).strip_prefix(&self.downloaded.path) - replacement in src/extract.rs at line 766
for (f, _) in find_dirs(downloaded_path.to_path_buf())? {let rel = f.strip_prefix(&downloaded_path).unwrap();for (f, _) in find_dirs(self.downloaded.path.to_path_buf())? {let rel = f.strip_prefix(&self.downloaded.path).unwrap(); - replacement in src/extract.rs at line 780[5.37602]→[5.37602:37671](∅→∅),[5.37671]→[5.34916:34991](∅→∅),[5.34991]→[5.37731:37760](∅→∅),[5.37731]→[5.37731:37760](∅→∅),[5.37760]→[5.34992:35079](∅→∅),[5.35079]→[5.37796:37867](∅→∅),[5.37796]→[5.37796:37867](∅→∅),[5.37867]→[5.35080:35114](∅→∅)
#[derive(Debug)]struct StackElt<'a> {package: deb::Stanza<'a>,rx: Option<tokio::sync::oneshot::Receiver<Result<Downloaded, Error>>>,deps: Vec<Arc<PathBuf>>,transitive_deps: Vec<Arc<PathBuf>>,transitive_deps_h: BTreeSet<Arc<PathBuf>>,ld_path: Vec<Arc<PathBuf>>,ld_path_h: BTreeSet<Arc<PathBuf>>,files: BTreeSet<Arc<String>>,async fn push_deps<'a>(depends: &[deb::Dep<'a>],index: &'a [deb::Index],stack: &mut Vec<(deb::Stanza<'a>,Option<tokio::sync::oneshot::Receiver<Result<Downloaded, Error>>>,)>,) -> Vec<&'a str> {let mut d = Vec::new();for dep in depends.iter() {match dep {deb::Dep::Simple(s) => {debug!("dep {:?}", s);let Some(dep) = multi_lookup(index, &s.name).await else {panic!("could not find {:?}", s.name)};d.push(dep.package);stack.push((dep, None))}deb::Dep::Alternatives { alt } => {debug!("alt {:?}", alt);let stack_len = stack.len();for dep in alt {if let Some(dep_) = multi_lookup(index, &dep.name).await {d.push(dep_.package);stack.push((dep_, None));break;}}if stack.len() == stack_len {panic!("Not found: {:?}", alt);}}}}d - edit in src/container.rs at line 216
- replacement in src/container.rs at line 220
Ok(Ok(())) => std::process::exit(0),Ok(Err(Error::BuildReturn { status })) => std::process::exit(status),Ok(Ok(())) => {debug!("inner process ok");std::process::exit(0)}Ok(Err(Error::BuildReturn { status })) => {debug!("inner process {:?}", status);std::process::exit(status)} - edit in src/container.rs at line 381
let (uid, gid) = {let user_ffi = CString::new(user).unwrap();let pw = unsafe { libc::getpwnam(user_ffi.as_ptr()) };assert!(!pw.is_null());let pw = unsafe { &*pw };(pw.pw_uid, pw.pw_gid)}; - edit in src/container.rs at line 455
let (uid, gid) = {let user_ffi = CString::new(user).unwrap();let pw = unsafe { libc::getpwnam(user_ffi.as_ptr()) };assert!(!pw.is_null());let pw = unsafe { &*pw };(pw.pw_uid, pw.pw_gid)}; - replacement in config.toml at line 3
store_path = "/home/pe/Projets/elpe/store"store_path = "/elpe/store" - edit in Cargo.lock at line 442
][[package]]name = "elfedit-cli"version = "0.1.0"dependencies = ["clap","elfedit",