pijul nest
guest [sign in]

Bootstrapping the Rust part

pmeunier
Jul 26, 2025, 7:17 PM
LIMIMBOUN3DCIKKTHOK4TAXAWQXNVQXBTMNZYN22DJX4L4FZQH4AC

Dependencies

  • [2] F2C3TLOI Fetching URLs (server-side)
  • [3] RBGQQMWX Container: cleanup after failure
  • [4] AJLMC7UM Forwarding log to frontend
  • [5] A7YP2YT6 Adding /tmp to containers
  • [6] LTB4YNHF Rust compilation works!
  • [7] 6BIW5YDC Rust builder: compiling the crates
  • [8] 6MGFBMON Debug and cleanup
  • [9] YJYXDY6A Capturing stdout/stderr for the derivations that ask
  • [10] HX4TXY2D Fixed-output derivations enable the network
  • [11] BQ4E3XLA Forwarding stdout/stderr
  • [12] VAKO4QFF Formatting
  • [13] SI454P2V Documentation and cleanup
  • [14] UWQB743K First working shell (with ocaml code)
  • [15] BDEVQIAU Handle cyclic Ubuntu dependencies
  • [16] R7J4254Z Reorganisation of the frontend
  • [17] LQBZJUGC Adding a basic Rust builder
  • [18] LIUJQXB7 Allow merging two packages based on regular expressions of their name
  • [19] VWVW5VOI Copying the sources in /src instead of /
  • [20] ODUDDQRY Adding the OCaml interface
  • [*] KOWYPLMX Nix and config.toml

Change contents

  • file addition: server.rs (----------)
    [7.15]
    use elpe::extract::*;
    use elpe::*;
    use std::sync::Arc;
    use tokio::io::AsyncWriteExt;
    use tokio_stream::wrappers::ReceiverStream;
    use tokio_util::sync::PollSender;
    use tonic::codegen::tokio_stream::StreamExt;
    use tracing::*;
    pub struct Elpe {
    deb_client: elpe::Client,
    sender: tokio::sync::mpsc::UnboundedSender<(
    crate::container::BuildRequest,
    tokio::sync::mpsc::Sender<crate::container::Msg>,
    )>,
    t: Option<tokio::task::JoinHandle<Result<(), elpe::Error>>>,
    }
    pub mod proto {
    tonic::include_proto!("elpe");
    }
    impl Elpe {
    pub fn new(
    deb_client: elpe::Client,
    container_channel: elpe::container::ContainerChannel,
    ) -> Self {
    let (sender, receiver) = tokio::sync::mpsc::unbounded_channel::<(
    crate::container::BuildRequest,
    tokio::sync::mpsc::Sender<crate::container::Msg>,
    )>();
    let t = tokio::spawn(crate::container::forward(receiver, container_channel));
    Elpe {
    deb_client,
    sender,
    t: Some(t),
    }
    }
    pub async fn serve(mut self, addr: std::net::SocketAddr) {
    let t = self.t.take().unwrap();
    tokio::select! {
    _ = tonic::transport::Server::builder()
    .add_service(proto::elpe_server::ElpeServer::new(self))
    .serve(addr)
    => {}
    _ = t => {}
    }
    }
    }
    use std::pin::Pin;
    type ResponseStream =
    Pin<Box<dyn tokio_stream::Stream<Item = Result<proto::DerivationReply, tonic::Status>> + Send>>;
    #[tonic::async_trait]
    impl proto::elpe_server::Elpe for Elpe {
    async fn add_path(
    &self,
    request: tonic::Request<tonic::Streaming<proto::AddPathRequest>>,
    ) -> Result<tonic::Response<proto::DerivationReply>, tonic::Status> {
    let mut r = request.into_inner();
    debug!("add_path");
    let mut current_file = None;
    let ref store = self.deb_client.store_path();
    debug!("store");
    let tmp_dir = tempfile::tempdir_in(store).unwrap();
    debug!("store {:?}", tmp_dir);
    let mut hasher = blake3::Hasher::new();
    debug!("loop");
    loop {
    trace!("waiting for next in stream");
    let Some(r) = r.next().await else { break };
    let r = r.unwrap();
    match r.request {
    Some(proto::add_path_request::Request::File(f)) => {
    info!("Adding file {:?}", f.name);
    hasher.update(b"\0f");
    hasher.update(f.name.as_bytes());
    hasher.update(b"\0");
    let p = tmp_dir.path().join(&f.name);
    tokio::fs::create_dir_all(p.parent().unwrap()).await?;
    current_file = Some(tokio::fs::File::create(&p).await?)
    }
    Some(proto::add_path_request::Request::Directory(d)) => {
    info!("Adding file {:?}", d.name);
    hasher.update(b"\0d");
    hasher.update(d.name.as_bytes());
    hasher.update(b"\0");
    let p = tmp_dir.path().join(&d.name);
    tokio::fs::create_dir_all(&p).await.unwrap();
    }
    Some(proto::add_path_request::Request::Contents(c)) => {
    hasher.update(&c.content);
    current_file.as_mut().unwrap().write_all(&c.content).await?;
    }
    None => break,
    }
    }
    debug!("loop done");
    let path = store.join(data_encoding::HEXLOWER.encode(hasher.finalize().as_bytes()));
    use tokio::io::ErrorKind;
    let new = tmp_dir.into_path();
    match tokio::fs::rename(&new, &path).await {
    Ok(()) => (),
    Err(e) if e.kind() == ErrorKind::DirectoryNotEmpty => (),
    Err(e) => {
    tokio::fs::remove_dir_all(&new).await?;
    return Err(e.into());
    }
    }
    info!("add_path extracted to {:?}", path);
    Ok(tonic::Response::new(proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Ok(
    proto::DerivationResult {
    destdir: vec![path.to_str().unwrap().to_string()],
    paths: Vec::new(),
    path_patterns: Vec::new(),
    },
    )),
    }))
    }
    type DerivationStream = ResponseStream;
    async fn derivation(
    &self,
    request: tonic::Request<proto::DerivationRequest>,
    ) -> Result<tonic::Response<ResponseStream>, tonic::Status> {
    debug!("derivation request");
    let now = std::time::Instant::now();
    let r = request.into_inner();
    let (tx, rx) = tokio::sync::mpsc::channel(200);
    debug!("derivation request: {:?} {:?}", r.name, r.paths);
    self.sender
    .send((
    crate::container::BuildRequest {
    name: r.name.clone(),
    paths: r.paths,
    script: r.builder,
    target: r.target,
    output_hash: r.output_hash,
    },
    tx,
    ))
    .unwrap();
    use crate::container::Msg;
    let output_stream = ReceiverStream::new(rx).map(|x| {
    Ok(match x {
    Msg::Ok(out) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Ok(
    proto::DerivationResult {
    destdir: out
    .into_iter()
    .map(|x| x.to_str().unwrap().to_string())
    .collect(),
    paths: Vec::new(),
    path_patterns: Vec::new(),
    },
    )),
    },
    Msg::Error(p) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Error(p)),
    },
    Msg::Stdout(p) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Stdout(p)),
    },
    Msg::Stderr(p) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Stderr(p)),
    },
    })
    });
    info!("request {:?}: {:?}", r.name, now.elapsed());
    Ok(tonic::Response::new(Box::pin(output_stream)))
    }
    async fn add_url(
    &self,
    request: tonic::Request<proto::AddUrlRequest>,
    ) -> Result<tonic::Response<proto::DerivationReply>, tonic::Status> {
    let r = request.into_inner();
    debug!("add_url request {:?}", r);
    let p = self
    .deb_client
    .http_download(
    &r.url,
    match r.hash_algorithm {
    0 => {
    let mut h = [0; 32];
    h.clone_from_slice(&r.hash);
    Hash::Blake3(h)
    }
    1 => {
    let mut h = [0; 32];
    h.clone_from_slice(&r.hash);
    Hash::Sha256(h)
    }
    2 => {
    let mut h = [0; 64];
    h.clone_from_slice(&r.hash);
    Hash::Sha512(h)
    }
    _ => unreachable!(),
    },
    )
    .await
    .unwrap();
    Ok(tonic::Response::new(proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Ok(
    proto::DerivationResult {
    destdir: vec![p.to_str().unwrap().to_string()],
    paths: Vec::new(),
    path_patterns: Vec::new(),
    },
    )),
    }))
    }
    async fn ubuntu_release(
    &self,
    request: tonic::Request<proto::UbuntuReleaseRequest>,
    ) -> Result<tonic::Response<proto::DerivationReply>, tonic::Status> {
    debug!("ubuntu release {:?}", request);
    let now = std::time::Instant::now();
    let r = request.into_inner();
    let h = self.deb_client.in_release(r.release.clone()).await.unwrap();
    let arch = match r.arch {
    0 => "amd64",
    1 => "aarch64",
    _ => unreachable!(),
    };
    let p = self
    .deb_client
    .packages(&h, &r.repository, arch)
    .await
    .unwrap();
    info!(
    "ubuntu release request {:?}: {:?}",
    r.release,
    now.elapsed()
    );
    Ok(tonic::Response::new(proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Ok(
    proto::DerivationResult {
    destdir: vec![p.to_str().unwrap().to_string()],
    paths: Vec::new(),
    path_patterns: Vec::new(),
    },
    )),
    }))
    }
    type UbuntuPackageStream = ResponseStream;
    async fn ubuntu_package(
    &self,
    request: tonic::Request<proto::UbuntuPackageRequest>,
    ) -> Result<tonic::Response<Self::UbuntuPackageStream>, tonic::Status> {
    let now = std::time::Instant::now();
    let r = request.into_inner();
    let index: Result<Vec<_>, _> = r
    .index
    .into_iter()
    .map(|index| deb::Index::open(&index))
    .collect();
    let index = index.unwrap();
    let link_extra: Vec<_> = r
    .link_extra
    .into_iter()
    .map(|l| {
    (
    regex::Regex::new(&l.pkg).unwrap(),
    regex::Regex::new(&l.dep).unwrap(),
    )
    })
    .collect();
    let (tx, rx) = tokio::sync::mpsc::channel(200);
    use crate::extract::Msg;
    let output_stream = ReceiverStream::new(rx).map(|x| {
    Ok(match x {
    Msg::Downloading(p) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Loading(p)),
    },
    Msg::Ok(p) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Ok(
    proto::DerivationResult {
    destdir: p
    .result
    .iter()
    .rev()
    .map(|x| x.to_str().unwrap().to_string())
    .collect(),
    paths: p.paths.into_iter().filter_map(Arc::into_inner).collect(),
    path_patterns: Vec::new(),
    },
    )),
    },
    Msg::Error(e) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Error(e.to_string())),
    },
    })
    });
    match download_extract_deps(
    &index,
    &self.deb_client,
    &r.name,
    &link_extra,
    PollSender::new(tx.clone()),
    )
    .await
    {
    Ok(p) => {
    info!("path {:?} {:#?}", r.name, p);
    tx.send(Msg::Ok(p)).await.unwrap();
    }
    Err(e) => tx.send(Msg::Error(e)).await.unwrap(),
    }
    info!("ubuntu package request {:?}: {:?}", r.name, now.elapsed());
    Ok(tonic::Response::new(Box::pin(output_stream)))
    }
    }
  • edit in src/main.rs at line 2
    [7.286][7.1489:1511](),[7.1363][7.1489:1511]()
    use elpe::extract::*;
  • edit in src/main.rs at line 5
    [7.332][7.1421:1441](),[7.1556][7.1421:1441](),[7.1421][7.1421:1441](),[7.1441][7.1557:1587](),[7.1587][7.0:44](),[7.44][4.0:34](),[4.34][7.1587:1632](),[7.44][7.1587:1632](),[7.1587][7.1587:1632](),[7.1632][7.1441:1457](),[7.1441][7.1441:1457]()
    use std::sync::Arc;
    use tokio::io::AsyncWriteExt;
    use tokio_stream::wrappers::ReceiverStream;
    use tokio_util::sync::PollSender;
    use tonic::codegen::tokio_stream::StreamExt;
    use tracing::*;
  • edit in src/main.rs at line 6
    [7.1586][7.1586:1640]()
    pub mod proto {
    tonic::include_proto!("elpe");
    }
  • replacement in src/main.rs at line 7
    [7.1641][7.1641:1659](),[7.1659][7.1633:1752](),[7.1752][7.45:103](),[7.103][7.1815:1823](),[7.1815][7.1815:1823](),[7.1823][7.1694:1696](),[7.1694][7.1694:1696]()
    pub struct Elpe {
    deb_client: elpe::Client,
    sender: tokio::sync::mpsc::UnboundedSender<(
    crate::container::BuildRequest,
    tokio::sync::mpsc::Sender<crate::container::Msg>,
    )>,
    }
    [7.1641]
    [7.104]
    mod server;
  • edit in src/main.rs at line 9
    [7.105][7.105:248](),[7.248][7.1711:1775](),[7.1711][7.1711:1775](),[7.1775][7.1824:1847](),[7.1847][7.1800:1815](),[7.1800][7.1800:1815](),[7.1815][7.1848:2038](),[7.2038][4.35:63](),[4.63][7.2038:2075](),[7.2038][7.2038:2075](),[7.2075][7.333:387](),[7.387][4.64:188](),[4.188][7.2179:2228](),[7.2179][7.2179:2228](),[7.2228][4.189:213](),[4.213][7.2229:2482](),[7.2001][7.2229:2482](),[7.2482][4.214:269](),[4.269][7.2482:2922](),[7.2482][7.2482:2922](),[7.2922][4.270:325](),[4.325][7.2922:3477](),[7.2922][7.2922:3477](),[7.3477][4.326:355](),[4.355][7.3477:4356](),[7.3477][7.3477:4356](),[7.4356][7.249:294](),[7.294][7.4356:4456](),[7.4356][7.4356:4456](),[7.4456][7.295:361](),[7.361][7.4530:4606](),[7.4530][7.4530:4606](),[7.4606][7.362:418](),[7.418][7.4662:4898](),[7.4662][7.4662:4898](),[7.4898][7.0:48](),[7.48][7.4898:4975](),[7.4898][7.4898:4975](),[7.4975][7.419:718](),[7.718][2.0:204](),[2.204][7.796:1519](),[7.796][7.796:1519](),[7.1519][7.2198:2205](),[7.5566][7.2198:2205](),[7.2198][7.2198:2205](),[7.2205][2.205:1636](),[2.1636][7.2205:2249](),[7.2205][7.2205:2249](),[7.2249][7.5567:5703](),[7.5703][7.2371:2850](),[7.2371][7.2371:2850](),[7.2850][7.5704:5997](),[7.5997][7.2932:2951](),[7.2932][7.2932:2951](),[7.2951][4.356:404](),[4.404][7.2951:2995](),[7.2951][7.2951:2995](),[7.2995][7.5998:6060](),[7.6060][4.405:482](),[4.482][7.3117:3392](),[7.6134][7.3117:3392](),[7.3117][7.3117:3392](),[7.3392][7.0:1](),[7.1][7.0:294](),[7.294][4.483:803](),[4.803][7.6646:6665](),[7.6646][7.6646:6665](),[7.6665][4.804:2149](),[4.2149][7.4845:4851](),[7.4845][7.4845:4851](),[7.4851][7.388:391]()
    use std::pin::Pin;
    type ResponseStream =
    Pin<Box<dyn tokio_stream::Stream<Item = Result<proto::DerivationReply, tonic::Status>> + Send>>;
    #[tonic::async_trait]
    impl proto::elpe_server::Elpe for Elpe {
    async fn add_path(
    &self,
    request: tonic::Request<tonic::Streaming<proto::AddPathRequest>>,
    ) -> Result<tonic::Response<proto::DerivationReply>, tonic::Status> {
    let mut r = request.into_inner();
    debug!("add_path");
    let mut current_file = None;
    let ref store = self.deb_client.store_path();
    debug!("store");
    let tmp_dir = tempfile::tempdir_in(store).unwrap();
    debug!("store {:?}", tmp_dir);
    let mut hasher = blake3::Hasher::new();
    debug!("loop");
    loop {
    trace!("waiting for next in stream");
    let Some(r) = r.next().await else { break };
    let r = r.unwrap();
    match r.request {
    Some(proto::add_path_request::Request::File(f)) => {
    info!("Adding file {:?}", f.name);
    hasher.update(b"\0f");
    hasher.update(f.name.as_bytes());
    hasher.update(b"\0");
    let p = tmp_dir.path().join(&f.name);
    tokio::fs::create_dir_all(p.parent().unwrap()).await?;
    current_file = Some(tokio::fs::File::create(&p).await?)
    }
    Some(proto::add_path_request::Request::Directory(d)) => {
    info!("Adding file {:?}", d.name);
    hasher.update(b"\0d");
    hasher.update(d.name.as_bytes());
    hasher.update(b"\0");
    let p = tmp_dir.path().join(&d.name);
    tokio::fs::create_dir_all(&p).await.unwrap();
    }
    Some(proto::add_path_request::Request::Contents(c)) => {
    hasher.update(&c.content);
    current_file.as_mut().unwrap().write_all(&c.content).await?;
    }
    None => break,
    }
    }
    debug!("loop done");
    let path = store.join(data_encoding::HEXLOWER.encode(hasher.finalize().as_bytes()));
    use tokio::io::ErrorKind;
    let new = tmp_dir.into_path();
    match tokio::fs::rename(&new, &path).await {
    Ok(()) => (),
    Err(e) if e.kind() == ErrorKind::DirectoryNotEmpty => (),
    Err(e) => {
    tokio::fs::remove_dir_all(&new).await?;
    return Err(e.into());
    }
    }
    info!("add_path extracted to {:?}", path);
    Ok(tonic::Response::new(proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Ok(
    proto::DerivationResult {
    destdir: vec![path.to_str().unwrap().to_string()],
    paths: Vec::new(),
    path_patterns: Vec::new(),
    },
    )),
    }))
    }
    type DerivationStream = ResponseStream;
    async fn derivation(
    &self,
    request: tonic::Request<proto::DerivationRequest>,
    ) -> Result<tonic::Response<ResponseStream>, tonic::Status> {
    debug!("derivation request");
    let r = request.into_inner();
    let (tx, rx) = tokio::sync::mpsc::channel(200);
    self.sender
    .send((
    crate::container::BuildRequest {
    name: r.name,
    paths: r.paths,
    script: r.builder,
    target: r.target,
    output_hash: r.output_hash,
    },
    tx,
    ))
    .unwrap();
    use crate::container::Msg;
    let output_stream = ReceiverStream::new(rx).map(|x| {
    Ok(match x {
    Msg::Ok(out) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Ok(
    proto::DerivationResult {
    destdir: out
    .into_iter()
    .map(|x| x.to_str().unwrap().to_string())
    .collect(),
    paths: Vec::new(),
    path_patterns: Vec::new(),
    },
    )),
    },
    Msg::Error(p) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Error(p)),
    },
    Msg::Stdout(p) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Stdout(p)),
    },
    Msg::Stderr(p) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Stderr(p)),
    },
    })
    });
    Ok(tonic::Response::new(Box::pin(output_stream)))
    }
    async fn add_url(
    &self,
    request: tonic::Request<proto::AddUrlRequest>,
    ) -> Result<tonic::Response<proto::DerivationReply>, tonic::Status> {
    let r = request.into_inner();
    debug!("add_url request {:?}", r);
    let p = self
    .deb_client
    .http_download(
    &r.url,
    match r.hash_algorithm {
    0 => {
    let mut h = [0; 32];
    h.clone_from_slice(&r.hash);
    Hash::Blake3(h)
    }
    1 => {
    let mut h = [0; 32];
    h.clone_from_slice(&r.hash);
    Hash::Sha256(h)
    }
    2 => {
    let mut h = [0; 64];
    h.clone_from_slice(&r.hash);
    Hash::Sha512(h)
    }
    _ => unreachable!(),
    },
    )
    .await
    .unwrap();
    Ok(tonic::Response::new(proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Ok(
    proto::DerivationResult {
    destdir: vec![p.to_str().unwrap().to_string()],
    paths: Vec::new(),
    path_patterns: Vec::new(),
    },
    )),
    }))
    }
    async fn ubuntu_release(
    &self,
    request: tonic::Request<proto::UbuntuReleaseRequest>,
    ) -> Result<tonic::Response<proto::DerivationReply>, tonic::Status> {
    debug!("ubuntu release {:?}", request);
    let r = request.into_inner();
    let h = self.deb_client.in_release(r.release).await.unwrap();
    let arch = match r.arch {
    0 => "amd64",
    1 => "aarch64",
    _ => unreachable!(),
    };
    let p = self
    .deb_client
    .packages(&h, &r.repository, arch)
    .await
    .unwrap();
    Ok(tonic::Response::new(proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Ok(
    proto::DerivationResult {
    destdir: vec![p.to_str().unwrap().to_string()],
    paths: Vec::new(),
    path_patterns: Vec::new(),
    },
    )),
    }))
    }
    type UbuntuPackageStream = ResponseStream;
    async fn ubuntu_package(
    &self,
    request: tonic::Request<proto::UbuntuPackageRequest>,
    ) -> Result<tonic::Response<Self::UbuntuPackageStream>, tonic::Status> {
    debug!("request {:?}", request);
    let r = request.into_inner();
    let index: Result<Vec<_>, _> = r
    .index
    .into_iter()
    .map(|index| deb::Index::open(&index))
    .collect();
    let index = index.unwrap();
    let link_extra: Vec<_> = r
    .link_extra
    .into_iter()
    .map(|l| {
    (
    regex::Regex::new(&l.pkg).unwrap(),
    regex::Regex::new(&l.dep).unwrap(),
    )
    })
    .collect();
    let (tx, rx) = tokio::sync::mpsc::channel(200);
    use crate::extract::Msg;
    let output_stream = ReceiverStream::new(rx).map(|x| {
    Ok(match x {
    Msg::Downloading(p) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Loading(p)),
    },
    Msg::Ok(p) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Ok(
    proto::DerivationResult {
    destdir: p
    .result
    .iter()
    .rev()
    .map(|x| x.to_str().unwrap().to_string())
    .collect(),
    paths: p.paths.into_iter().filter_map(Arc::into_inner).collect(),
    path_patterns: Vec::new(),
    },
    )),
    },
    Msg::Error(e) => proto::DerivationReply {
    result: Some(proto::derivation_reply::Result::Error(e.to_string())),
    },
    })
    });
    match download_extract_deps(
    &index,
    &self.deb_client,
    &r.name,
    &link_extra,
    PollSender::new(tx.clone()),
    )
    .await
    {
    Ok(p) => {
    info!("path {:?} {:#?}", r.name, p);
    tx.send(Msg::Ok(p)).await.unwrap();
    }
    Err(e) => tx.send(Msg::Error(e)).await.unwrap(),
    }
    Ok(tonic::Response::new(Box::pin(output_stream)))
    }
    }
  • edit in src/main.rs at line 47
    [7.1043][7.1043:1044](),[7.1044][7.7101:7219](),[7.7101][7.7101:7219](),[7.7219][7.1520:1582](),[7.1582][7.7286:7300](),[7.7286][7.7286:7300]()
    let (sender, receiver) = tokio::sync::mpsc::unbounded_channel::<(
    crate::container::BuildRequest,
    tokio::sync::mpsc::Sender<crate::container::Msg>,
    )>();
  • replacement in src/main.rs at line 48
    [7.8639][7.7301:7387]()
    let t = tokio::spawn(crate::container::forward(receiver, container_channel));
    [7.8639]
    [7.8830]
    let elpe = server::Elpe::new(
    Client::new(&config.pgp_home, &config.store_path, &config.package_index),
    container_channel,
    );
  • edit in src/main.rs at line 53
    [7.8831][7.7388:7414](),[7.7414][7.1045:1143](),[7.1143][7.7502:7533](),[7.7502][7.7502:7533](),[7.7533][7.9063:9064](),[7.9063][7.9063:9064]()
    let elpe = Elpe {
    deb_client: Client::new(&config.pgp_home, &config.store_path, &config.package_index),
    sender,
    };
  • replacement in src/main.rs at line 54
    [7.7792][7.7792:8026]()
    tokio::select! {
    _ = tonic::transport::Server::builder()
    .add_service(proto::elpe_server::ElpeServer::new(elpe))
    .serve(addr)
    => {}
    _ = t => {}
    }
    [7.7792]
    [7.8026]
    elpe.serve(addr).await
  • edit in src/container.rs at line 5
    [7.44835]
    [7.1669]
    use std::os::fd::OwnedFd;
  • replacement in src/container.rs at line 80
    [7.46666][7.46666:46727]()
    debug!("received process response {:?}", x);
    [7.46666]
    [7.46727]
    info!("received process response {:?}", x);
  • replacement in src/container.rs at line 86
    [7.2385][7.2385:2450]()
    chan.send(resp).await.unwrap_or(());
    [7.2385]
    [7.2450]
    chan.send(resp).await.unwrap();
  • replacement in src/container.rs at line 90
    [7.2573][7.2573:2638]()
    chan.send(resp).await.unwrap_or(());
    [7.2573]
    [7.2638]
    chan.send(resp).await.unwrap();
  • edit in src/container.rs at line 141
    [7.48764]
    [7.48764]
    let mut n = 0;
  • replacement in src/container.rs at line 153
    [7.49250][7.2687:2863]()
    let (writer_out, mut reader_out) = tokio::net::unix::pipe::pipe().unwrap();
    let (writer_err, mut reader_err) = tokio::net::unix::pipe::pipe().unwrap();
    [7.49250]
    [7.49250]
    let m = n;
    n += 1;
  • edit in src/container.rs at line 156
    [7.49288]
    [7.2864]
    let (reader_out, writer_out) = std::io::pipe().unwrap();
    let (reader_err, writer_err) = std::io::pipe().unwrap();
    let reader_out_fd = reader_out.as_raw_fd();
    let reader_err_fd = reader_err.as_raw_fd();
    let writer_out_fd = writer_out.as_raw_fd();
    let writer_err_fd = writer_err.as_raw_fd();
  • replacement in src/container.rs at line 163
    [7.2929][7.2929:2967]()
    run_in_container(
    [7.2929]
    [7.2967]
    let writer_out_fd: OwnedFd = writer_out.into();
    let writer_err_fd: OwnedFd = writer_err.into();
    info!("run_in_container {}: {}", m, rec_msg.script);
    let result = run_in_container(
    m,
  • replacement in src/container.rs at line 171
    [7.3063][7.3063:3159]()
    writer_out.as_raw_fd(),
    writer_err.as_raw_fd(),
    [7.3063]
    [7.3159]
    reader_out_fd,
    writer_out_fd,
    reader_err_fd,
    writer_err_fd,
  • replacement in src/container.rs at line 176
    [7.3181][7.3181:3234]()
    .map_err(|e| format!("{:?}", e))
    [7.3181]
    [7.3234]
    .map_err(|e| format!("{:?}", e));
    info!("run_in_container {}: done", m);
    result
  • edit in src/container.rs at line 182
    [7.3290]
    [7.3290]
    let mut reader_out =
    tokio::net::unix::pipe::Receiver::from_owned_fd(reader_out.into()).unwrap();
    let mut reader_err =
    tokio::net::unix::pipe::Receiver::from_owned_fd(reader_err.into()).unwrap();
  • edit in src/container.rs at line 193
    [7.3590]
    [7.3590]
    info!(
    "waiting for run_in_container {} {:?} {:?}",
    m, stdout_closed, stderr_closed
    );
  • edit in src/container.rs at line 217
    [7.4882]
    [7.4882]
    } else {
    stdout_closed = true
  • edit in src/container.rs at line 233
    [7.5827]
    [7.5827]
    } else {
    stderr_closed = true
  • edit in src/container.rs at line 237
    [7.5883]
    [7.5883]
    _ = tokio::time::sleep(std::time::Duration::from_secs(10)) => {info!("Still waiting for {}", m)}
  • replacement in src/container.rs at line 243
    [7.49630][7.49630:49692]()
    debug!("drv_process replying {:?}", v.len());
    [7.49630]
    [7.49692]
    info!("drv_process {} replying {:?}", m, v.len());
  • edit in src/container.rs at line 246
    [7.6126]
    [7.49807]
    info!("sent {}", m);
  • edit in src/container.rs at line 254
    [7.6148]
    [7.6148]
    m: usize,
  • replacement in src/container.rs at line 258
    [7.6203][7.6203:6241]()
    stdout: RawFd,
    stderr: RawFd,
    [7.6203]
    [7.75]
    stdout_r: RawFd,
    stdout: OwnedFd,
    stderr_r: RawFd,
    stderr: OwnedFd,
  • edit in src/container.rs at line 272
    [5.105]
    [7.50195]
    debug!("{}", r.script);
  • edit in src/container.rs at line 285
    [7.50538]
    [7.50538]
    drop(stdout);
    drop(stderr);
  • edit in src/container.rs at line 297
    [7.50931]
    [7.114]
    info!("{} returning early", m);
  • edit in src/container.rs at line 321
    [7.171]
    [7.51447]
    info!("clone {}", m);
  • edit in src/container.rs at line 342
    [7.52049]
    [7.52049]
    unsafe {
    if libc::close(stdout_r) != 0 {
    error!("couldn't close");
    return Err(std::io::Error::last_os_error().into());
    }
    if libc::close(stderr_r) != 0 {
    error!("couldn't close");
    return Err(std::io::Error::last_os_error().into());
    }
    }
  • replacement in src/container.rs at line 354
    [7.6299][7.6299:6385]()
    user, &r, &tmp_dir, &dest, &store, &tmp_store, &name, stdout, stderr,
    [7.6299]
    [7.6385]
    user,
    &r,
    &tmp_dir,
    &dest,
    &store,
    &tmp_store,
    &name,
    stdout.as_raw_fd(),
    stderr.as_raw_fd(),
  • replacement in src/container.rs at line 376
    [7.52411][7.52411:52438]()
    debug!("waitpid");
    [7.52411]
    [7.52438]
    drop(stdout);
    drop(stderr);
    info!("waitpid {}", m);
  • replacement in src/container.rs at line 381
    [7.52528][7.52528:52573]()
    info!("return status {:?}", status);
    [7.52528]
    [7.52702]
    info!("{} return status {:?}", m, status);
  • edit in src/container.rs at line 395
    [3.174]
    [3.174]
    std::fs::remove_dir_all(&dest).unwrap_or(());
  • replacement in src/container.rs at line 540
    [7.57164][7.6400:6438]()
    stdout: RawFd,
    stderr: RawFd,
    [7.57164]
    [7.57164]
    stdout_w: RawFd,
    stderr_w: RawFd,
  • replacement in src/container.rs at line 662
    [7.6456][7.467:520]()
    if libc::dup2(stdout, this_stdout) < 0 {
    [7.6456]
    [7.520]
    if libc::dup2(stdout_w, this_stdout) < 0 {
  • replacement in src/container.rs at line 665
    [7.602][7.602:655]()
    if libc::dup2(stderr, this_stderr) < 0 {
    [7.602]
    [7.655]
    if libc::dup2(stderr_w, this_stderr) < 0 {
  • edit in src/container.rs at line 668
    [7.737][7.737:775](),[7.775][7.6491:6526](),[7.6491][7.6491:6526]()
    // libc::dup2(stdout, 1);
    libc::dup2(stderr, 2);
  • edit in shell.nix at line 101
    [7.70]
    [22.2728]
    ocamlPackages.ppx_string
    ocamlPackages.ppx_blob
  • file addition: semantic_versions.ml (----------)
    [7.55449]
    let of_string input =
    try
    Scanf.sscanf input "%u.%u.%u-%s" (fun v1 v2 v3 v4 -> (v1, v2, v3, Some v4))
    with _ -> Scanf.sscanf input "%u.%u.%u" (fun v1 v2 v3 -> (v1, v2, v3, None))
    let to_string (v1, v2, v3, v4) =
    match v4 with
    | None -> Printf.sprintf "%u.%u.%u" v1 v2 v3
    | Some s -> Printf.sprintf "%u.%u.%u-%s" v1 v2 v3 s
  • file addition: rust (d--r------)
    [7.55449]
  • file move: rust.ml (----------)rust.ml (----------)
    [0.15691]
    [7.32]
  • replacement in elpe/lib/rust/rust.ml at line 14
    [7.292][7.292:299]()
    http
    [7.292]
    [7.299]
    http ~name:crate
  • replacement in elpe/lib/rust/rust.ml at line 30
    [7.677][7.677:702]()
    method name = "rust"
    [7.677]
    [7.702]
    method name = "rust-unzip-" ^ pkg#name
  • replacement in elpe/lib/rust/rust.ml at line 39
    [7.1068][6.475:1069]()
    ("mkdir -p $DESTDIR; tar -xf " ^ List.hd zipped.destdir
    ^ " -C $DESTDIR; cd $DESTDIR/*; echo -n \\{\\\"files\\\":\\{ \
    >.cargo-checksum.json\n\
    n=0\n\
    for f in $(find . -type f -printf '%P\\n'); do\n\
    if [[ $n -gt 0 ]]; then\n\
    echo -n , >>.cargo-checksum.json\n\
    fi\n\
    echo -n \\\"$f\\\":\\\"$(sha256sum $f | cut -d\" \" -f 1)\\\" >> \
    .cargo-checksum.json;\n\
    n=$((n+1))\n\
    done\n\
    echo -n \\},\\\"package\\\":\\\"" ^ hash
    ^ "\\\"\\} >> .cargo-checksum.json")
    [7.1068]
    [7.1150]
    [%string
    {|mkdir -p $DESTDIR
    tar -xf %{List.hd zipped.destdir} -C $DESTDIR
    cd $DESTDIR/*
    echo -n \{\"files\":\{ >.cargo-checksum.json
    n=0
    for f in $(find . -type f -printf '%P\n'); do
    if [[ $n -gt 0 ]]; then
    echo -n , >>.cargo-checksum.json
    fi
    echo -n \"$f\":\"$(sha256sum $f | cut -d" " -f 1)\" >> .cargo-checksum.json
    n=$((n+1))
    done
    echo -n \},\"package\":\"%{hash}\"\} >> .cargo-checksum.json
    |}]
    method! install_phase = Lwt.return ""
  • edit in elpe/lib/rust/rust.ml at line 57
    [7.1156]
    [7.186]
    let extra_crate_dependencies name version =
    match (name, version) with
    | "openssl", _ | "openssl-sys", _ ->
    [ ubuntu "libssl-dev"; ubuntu "pkg-config" ]
    | _ -> []
  • replacement in elpe/lib/rust/rust.ml at line 83
    [7.466][7.466:845](),[7.845][6.1457:1525](),[6.1525][7.895:1110](),[7.895][7.895:1110]()
    Lwt.all
    (List.map
    (fun pkg ->
    try
    let source = str_from_toml_table "source" pkg in
    let checksum = str_from_toml_table "checksum" pkg in
    let name = str_from_toml_table "name" pkg in
    let version = str_from_toml_table "version" pkg in
    let h = fetch_crate source checksum name version in
    let drv = (unzip_checksum h checksum :> derivation) in
    let* built = drv#build in
    n_packages := !n_packages + 1;
    Lwt.return (Some (name, version, source, drv, built))
    with Not_found -> Lwt.return None)
    packages)
    [7.466]
    [7.1110]
    Lwt_list.map_s
    (fun pkg ->
    try
    let source = str_from_toml_table "source" pkg in
    let checksum = str_from_toml_table "checksum" pkg in
    let name = str_from_toml_table "name" pkg in
    let version = str_from_toml_table "version" pkg in
    let h = fetch_crate source checksum name version in
    let drv = (unzip_checksum h checksum :> derivation) in
    let* built = drv#build in
    n_packages := !n_packages + 1;
    Lwt.return (Some (name, version, source, drv, built))
    with Not_found -> Lwt.return None)
    packages
  • replacement in elpe/lib/rust/rust.ml at line 123
    [7.1673][7.1673:1780]()
    let platform =
    match platform with Some s -> " --filter-platform " ^ s | None -> ""
    in
    [7.1673]
    [7.1398]
    let platform = " --filter-platform " ^ platform in
  • replacement in elpe/lib/rust/rust.ml at line 126
    [7.1826][7.1826:1984](),[7.1984][6.1783:1979](),[6.1979][7.2128:2147](),[7.2128][7.2128:2147](),[7.2147][6.1980:2035](),[6.2035][7.2147:2331](),[7.2147][7.2147:2331]()
    List.fold_left
    (fun acc x ->
    match x with
    | Some (crate_name, version, _, _, built) ->
    let target =
    if Hashtbl.find_opt h crate_name = None then (
    Hashtbl.add h crate_name ();
    crate_name)
    else crate_name ^ "-" ^ version
    in
    List.iter self#add_path built.destdir;
    acc ^ "ln -s " ^ List.hd built.destdir ^ "/" ^ crate_name ^ "-"
    ^ version ^ " vendor/" ^ target ^ "\n"
    | None -> acc)
    "" packages
    [7.1826]
    [7.2331]
    let package_list =
    List.fold_left
    (fun acc x ->
    match x with
    | Some (crate_name, version, _, _, built) ->
    let target =
    if Hashtbl.find_opt h crate_name = None then (
    Hashtbl.add h crate_name ();
    crate_name)
    else crate_name ^ "-" ^ version
    in
    List.iter self#add_path built.destdir;
    [
    "ln -s ";
    List.hd built.destdir;
    "/";
    crate_name;
    "-";
    version;
    " vendor/";
    target;
    "\n";
    ]
    @ acc
    | None -> acc)
    [] packages
    in
    String.concat "" package_list
  • replacement in elpe/lib/rust/rust.ml at line 156
    [7.2358][7.2358:2913]()
    "export HOME=/home/me\nmkdir -p $HOME\nexport PATH=" ^ List.hd rustc
    ^ "/usr/lib/rust-" ^ rust_version ^ "/bin:" ^ List.hd cargo
    ^ "/usr/lib/rust-" ^ rust_version
    ^ "/bin:$PATH\nmkdir -p vendor .cargo\n" ^ packages
    ^ "\n\
    cat <<EOF >> .cargo/config.toml\n\
    [source.crates-io]\n\
    replace-with = \"vendored-sources\"\n\n\
    [source.vendored-sources]\n\
    directory = \"vendor\"\n\
    EOF\n\
    cargo metadata --offline --format-version 1" ^ platform
    [7.2358]
    [7.1630]
    [%string
    {|export HOME=/home/me
    mkdir -p $HOME
    export PATH=%{List.hd rustc}/usr/lib/rust-%{rust_version}/bin:%{List.hd cargo}/usr/lib/rust-%{rust_version}/bin:$PATH
    mkdir -p vendor .cargo
    %{packages}
    cat <<EOF >> .cargo/config.toml
    [source.crates-io]
    replace-with = "vendored-sources"
    [source.vendored-sources]
    directory = "vendor"
    EOF
    cargo metadata --offline --format-version 1 %{platform}
    |}]
  • replacement in elpe/lib/rust/rust.ml at line 178
    [6.2167][6.2167:2234]()
    type deps = { build_dependencies : string; dependencies : string }
    [6.2167]
    [6.2234]
    type deps = {
    build_dependencies : (string * string * string * bool * build_result) list;
    dependencies : (string * string * string * bool * build_result) list;
    transitive_build_dependencies : (string, build_result) Hashtbl.t;
    transitive_dependencies : (string, build_result) Hashtbl.t;
    }
  • replacement in elpe/lib/rust/rust.ml at line 187
    [6.2322][6.2322:2403]()
    class compiled_crate rust_version rustc cc platform package path deps features =
    [6.2322]
    [7.3151]
    class compiled_crate ~rust_version ~rustc ~cc ~host ~target ~package ~path
    ~dependencies ~features ~opt_level ~is_top_level =
    let package_deps =
    let d = package |> member "dependencies" |> to_list in
    let h = Hashtbl.create (List.length d) in
    List.iter (fun d -> Hashtbl.add h (d |> member "name" |> to_string) d) d;
    h
    in
  • edit in elpe/lib/rust/rust.ml at line 199
    [6.2503]
    [7.3250]
    method semantic_version = Semantic_versions.of_string self#version
  • replacement in elpe/lib/rust/rust.ml at line 201
    [7.3284][6.2504:2539]()
    val target_platform = platform
    [7.3284]
    [7.3284]
    method targets = package |> member "targets" |> to_list
  • edit in elpe/lib/rust/rust.ml at line 208
    [6.2672]
    [7.2324]
    let* deps = self#dependencies in
    let dependencies =
    String.concat " "
    (List.map
    (fun (_, _, _, _, r) -> List.hd r.destdir)
    deps.dependencies)
    in
    let build_dependencies =
    String.concat " "
    (List.map
    (fun (_, _, _, _, r) -> List.hd r.destdir)
    deps.build_dependencies)
    in
  • replacement in elpe/lib/rust/rust.ml at line 222
    [7.2341][6.2673:2814]()
    (s ^ "export HOME=/home/me\nmkdir -p $HOME\nexport PATH="
    ^ List.hd rustc ^ "/usr/lib/rust-" ^ rust_version ^ "/bin:$PATH\n")
    [7.2341]
    [7.2913]
    [%string
    {|%{s}
    for i in %{dependencies} %{build_dependencies}; do
    if [[ -s $i/lib/env ]]; then
    source $i/lib/env
    fi
    done
    export HOME=/home/me
    mkdir -p $HOME
    export PATH=%{List.hd rustc}/usr/lib/rust-%{rust_version}/bin:$PATH
    |}]
  • replacement in elpe/lib/rust/rust.ml at line 242
    [6.3090][6.3090:3154]()
    (fun acc x -> acc ^ " --cfg 'feature=\"" ^ x ^ "\"'")
    [6.3090]
    [6.3154]
    (fun acc x -> [%string {|%{acc} --cfg 'feature="%{x}"'|}])
  • replacement in elpe/lib/rust/rust.ml at line 272
    [7.4203][6.4189:4342]()
    method private compile_target setup platform target kind dependencies out =
    let initial_src_path = target |> member "src_path" |> to_string in
    [7.4203]
    [6.4342]
    method private compile_target setup target build_target kind
    transitive_dependencies dependencies out =
    let initial_src_path = build_target |> member "src_path" |> to_string in
  • replacement in elpe/lib/rust/rust.ml at line 276
    [6.4403][6.4403:4460]()
    let name = target |> member "name" |> to_string in
    [6.4403]
    [6.4460]
    let name = build_target |> member "name" |> to_string in
  • replacement in elpe/lib/rust/rust.ml at line 279
    [6.4519][6.4519:4595]()
    try " --edition=" ^ (target |> member "edition" |> to_string) ^ " "
    [6.4519]
    [6.4595]
    try
    " --edition=" ^ (build_target |> member "edition" |> to_string) ^ " "
  • replacement in elpe/lib/rust/rust.ml at line 285
    [6.4744][6.4744:4833]()
    let platform =
    match platform with Some p -> " --target " ^ p | None -> ""
    [6.4744]
    [6.4833]
    let dependencies_str =
    List.fold_left
    (fun acc (rename, name, h, is_proc_macro, b) ->
    acc ^ " --extern " ^ underscorize rename ^ "=" ^ List.hd b.destdir
    ^ "/lib/lib" ^ underscorize name ^ "-" ^ h
    ^
    if is_proc_macro then ".so"
    else if kind = "lib" then ".rmeta"
    else ".rlib")
    "" dependencies
    in
    let dependencies_str =
    Hashtbl.fold
    (fun _ v acc -> acc ^ " -L dependency=" ^ List.hd v.destdir ^ "/lib")
    transitive_dependencies dependencies_str
  • edit in elpe/lib/rust/rust.ml at line 303
    [6.4842]
    [6.4842]
    let target = " --target " ^ Platform.triple target in
  • replacement in elpe/lib/rust/rust.ml at line 306
    [7.4220][6.4870:5110]()
    !setup ^ "rustc --crate-name " ^ under ^ edition ^ src_path ^ platform
    ^ " --crate-type bin -C linker=gcc" ^ features_args ^ " -C metadata="
    ^ hash ^ " --out-dir " ^ out ^ dependencies ^ " --cap-lints allow\n"
    [7.4220]
    [6.5110]
    [%string
    {|
    %{!setup}
    set -x
    rustc --crate-name %{under} %{edition} %{src_path} %{target} --crate-type bin -C linker=gcc $RUSTC_FLAGS %{features_args} -C metadata=%{hash} --out-dir %{out} %{dependencies_str} -L dependency=../lib --cap-lints allow
    { set +x; } 2>/dev/null
    |}]
  • replacement in elpe/lib/rust/rust.ml at line 315
    [6.5138][6.5138:5501]()
    !setup ^ "rustc --crate-name " ^ under ^ edition ^ src_path
    ^ " --crate-type " ^ kind ^ platform
    ^ " --emit=dep-info,metadata,link -C embed-bitcode=no -C debuginfo=2"
    ^ features_args ^ " -C metadata=" ^ hash ^ " --out-dir " ^ out
    ^ " -C extra-filename=-" ^ hash ^ dependencies
    ^ " --cap-lints allow\n";
    [6.5138]
    [6.5501]
    [%string
    {|
    %{!setup}
    set -x
    rustc --crate-name %{under} %{edition} %{src_path} --crate-type %{kind} %{target} --emit=dep-info,metadata,link -C linker=gcc -C embed-bitcode=no -C debuginfo=2 $RUSTC_FLAGS %{if kind = "proc-macro" then " -C prefer-dynamic" else ""} %{features_args} -C metadata=%{hash} --out-dir %{out} -C extra-filename=-%{hash} %{dependencies_str} %{if kind = "proc-macro" then " --extern proc_macro" else ""} --cap-lints allow
    { set +x; } 2>/dev/null
    |}];
  • edit in elpe/lib/rust/rust.ml at line 325
    [6.5515]
    [6.5515]
    val accumulated_deps : (string, compiled_crate) Hashtbl.t option ref =
    ref None
    method accumulated_deps =
    match !accumulated_deps with
    | Some acc -> Lwt.return acc
    | None ->
    let h = Hashtbl.create 256 in
    let* _ =
    Lwt_list.iter_s
    (fun d ->
    let dd = Hashtbl.find package_deps d#name in
    let is_build =
    dd |> member "kind" |> to_option to_string = Some "build"
    in
    Hashtbl.add h d#name d;
    let* acc = d#accumulated_deps in
    Lwt.return
    (if not is_build then
    Hashtbl.iter (fun k v -> Hashtbl.add h k v) acc
    else ()))
    dependencies
    in
    accumulated_deps := Some h;
    Lwt.return h
  • replacement in elpe/lib/rust/rust.ml at line 360
    [6.5840][6.5840:6195]()
    let package_deps =
    let d = package |> member "dependencies" |> to_list in
    let h = Hashtbl.create (List.length d) in
    List.iter
    (fun d -> Hashtbl.add h (d |> member "name" |> to_string) d)
    d;
    h
    in
    let de = ref "" in
    let build_de = ref "" in
    [6.5840]
    [6.6195]
    let de = ref [] in
    let h = Hashtbl.create 256 in
    let build_h = Hashtbl.create 256 in
    let build_de = ref [] in
  • replacement in elpe/lib/rust/rust.ml at line 365
    [6.6217][6.6217:6244]()
    Lwt_list.map_p
    [6.6217]
    [6.6244]
    Lwt_list.map_s
  • replacement in elpe/lib/rust/rust.ml at line 368
    [6.6304][6.6304:6352]()
    Lwt.return (x#name, x#hash, b))
    [6.6304]
    [6.6352]
    Lwt.return (x, x#name, x#hash, b))
    dependencies
    in
    let* _ =
    Lwt_list.iter_s
    (fun (x, x_name, x_hash, b) ->
    let d = Hashtbl.find package_deps x_name in
    let is_build =
    d |> member "kind" |> to_option to_string = Some "build"
    in
    List.iter self#add_path b.destdir;
    let name =
    match d |> member "rename" |> to_option to_string with
    | Some rename -> rename
    | None -> x_name
    in
    let r, h = if is_build then (build_de, build_h) else (de, h) in
    let* acc = x#accumulated_deps in
    let* _ =
    Hashtbl.fold
    (fun name v acc ->
    if Hashtbl.find_opt h name = None then (
    let* _ = acc in
    let* b = v#build in
    List.iter self#add_path b.destdir;
    Hashtbl.add h name b;
    Lwt.return ())
    else Lwt.return ())
    acc (Lwt.return ())
    in
    let is_proc_macro =
    List.exists
    (fun t ->
    List.exists
    (fun k -> k = "proc-macro")
    (t |> member "kind" |> to_list |> filter_string))
    x#targets
    in
    r := (name, x_name, x_hash, is_proc_macro, b) :: !r;
    Lwt.return ())
  • edit in elpe/lib/rust/rust.ml at line 410
    [6.6384][6.6384:7125]()
    List.iter
    (fun (x_name, x_hash, b) ->
    let d = Hashtbl.find package_deps x_name in
    let is_build =
    d |> member "kind" |> to_option to_string = Some "build"
    in
    List.iter self#add_path b.destdir;
    let name =
    match d |> member "rename" |> to_option to_string with
    | Some rename -> rename
    | None -> x_name
    in
    let r = if is_build then build_de else de in
    r :=
    !r ^ " -L dependency=target/deps --extern " ^ name ^ "="
    ^ List.hd b.destdir ^ "/lib/lib" ^ x_name ^ "-" ^ x_hash
    ^ ".rlib")
    deps;
  • replacement in elpe/lib/rust/rust.ml at line 411
    [6.7126][6.7126:7207]()
    let result = { build_dependencies = !build_de; dependencies = !de } in
    [6.7126]
    [6.7207]
    let result =
    {
    build_dependencies = !build_de;
    transitive_build_dependencies = build_h;
    dependencies = !de;
    transitive_dependencies = h;
    }
    in
  • replacement in elpe/lib/rust/rust.ml at line 422
    [6.7284][6.7284:7349]()
    method! build_inputs = Lwt.return [ ubuntu "coreutils"; cc ]
    [6.7284]
    [6.7349]
    method! build_inputs =
    Lwt.return
    ([
    ubuntu "coreutils";
    ubuntu "sed";
    ubuntu "gcc";
    ubuntu "grep";
    ubuntu "gawk";
    cc;
    ]
    @ extra_crate_dependencies self#name self#version)
  • replacement in elpe/lib/rust/rust.ml at line 438
    [6.7481][6.7481:7562]()
    ref ("set -x\nmkdir -p target/build-" ^ hash ^ "\nexport RUSTC=rustc\n")
    [6.7481]
    [6.7562]
    ref ("mkdir -p target/build-" ^ hash ^ "\nexport RUSTC=rustc\n")
  • edit in elpe/lib/rust/rust.ml at line 448
    [6.7793]
    [6.7793]
    let v0, v1, v2, v4 = self#semantic_version in
    let name = self#name in
    let version = self#version in
  • edit in elpe/lib/rust/rust.ml at line 452
    [6.7853]
    [6.7853]
    setup :=
    !setup
    ^ [%string
    {|export OUT_DIR=$DESTDIR/lib
    export CARGO_PKG_VERSION="%{version}"
    export CARGO_PKG_NAME="%{name}"
    export CARGO_PKG_VERSION_MAJOR=%{v0#Int}
    export CARGO_PKG_VERSION_MINOR=%{v1#Int}
    export CARGO_PKG_VERSION_PATCH=%{v2#Int}
    export CARGO_PKG_VERSION_PATCH=%{Option.value v4 ~default:""}
    export TARGET="%{Platform.triple target}"
    export HOST="%{Platform.triple host}"
    export OPT_LEVEL=%{opt_level}
    export CARGO_CFG_UNIX=1
    export CARGO_CFG_TARGET_ABI=""
    export CARGO_CFG_TARGET_OS=linux
    export CARGO_CFG_TARGET_ENDIAN="%{Platform.string_of_endianness (Platform.endianness target)}"
    export CARGO_CFG_TARGET_POINTER_WIDTH=%{(Platform.pointer_width target)#Int}
    export CARGO_CFG_TARGET_ENV="%{Platform.env target}"
    export CARGO_CFG_TARGET_ARCH="%{Platform.string_of_arch target.arch}"
    |}];
  • replacement in elpe/lib/rust/rust.ml at line 487
    [6.8408][6.8408:8551]()
    (self#compile_target setup None target "bin"
    d.build_dependencies ("target/build-" ^ hash))
    [6.8408]
    [6.8551]
    (self#compile_target setup host target "bin"
    d.transitive_build_dependencies d.build_dependencies
    ("target/build-" ^ hash))
  • replacement in elpe/lib/rust/rust.ml at line 493
    [6.8686][6.8686:8760]()
    (true, None)
    (package |> member "targets" |> to_list)
    [6.8686]
    [6.8760]
    (true, None) self#targets
  • replacement in elpe/lib/rust/rust.ml at line 495
    [6.8769][6.8769:8818]()
    (* If there is a build script, call it. *)
    [6.8769]
    [6.8818]
    setup := !setup ^ "mkdir -p $OUT_DIR || true\n";
  • replacement in elpe/lib/rust/rust.ml at line 500
    [6.8890][6.8890:8966]()
    setup := !setup ^ "target/build-" ^ hash ^ "/" ^ bs_name ^ "\n"
    [6.8890]
    [6.8966]
    setup :=
    !setup
    ^ [%string
    {|CRATENAME=$(echo %{name} | sed -e "s/\(.*\)-sys$/\U\1/" -e "s/-/_/g")
    CRATEVERSION=$(echo %{version} | sed -e "s/[\.\+-]/_/g")
    |}]
    ^ String.trim [%blob "run_build_script.sh"]
    ^ [%string "<<< $(target/build-%{hash}/%{bs_name})\n"]
  • replacement in elpe/lib/rust/rust.ml at line 521
    [7.4771][7.4771:4794]()
    (fun target ->
    [7.4771]
    [7.4794]
    (fun build_target ->
  • replacement in elpe/lib/rust/rust.ml at line 524
    [7.4839][6.9257:9449]()
    if kind = "bin" then
    if !has_bin then ()
    else (
    has_bin := true;
    setup := !setup ^ "mkdir -p $DESTDIR/bin\n")
    [7.4839]
    [6.9449]
    if kind = "bin" then if !has_bin then () else has_bin := true
  • replacement in elpe/lib/rust/rust.ml at line 526
    [6.9488][6.9488:9604]()
    else (
    has_lib := true;
    setup := !setup ^ "mkdir -p $DESTDIR/lib\n");
    [6.9488]
    [7.4839]
    else has_lib := true;
  • replacement in elpe/lib/rust/rust.ml at line 531
    [6.9650][6.9650:9776]()
    self#compile_target setup target_platform target kind
    d.dependencies "$DESTDIR/lib"
    [6.9650]
    [6.9776]
    self#compile_target setup target build_target kind
    d.transitive_dependencies d.dependencies "$OUT_DIR"
  • replacement in elpe/lib/rust/rust.ml at line 536
    [7.4975][6.9819:10013]()
    let _ =
    self#compile_target setup target_platform target kind
    d.dependencies "$DESTDIR/bin"
    in
    ()
    [7.4975]
    [7.5020]
    if is_top_level then
    let _ =
    self#compile_target setup target build_target kind
    d.transitive_dependencies d.dependencies
    "$OUT_DIR/../bin"
    in
    ()
    else ()
  • replacement in elpe/lib/rust/rust.ml at line 545
    [7.5045][7.5045:5162]()
    (target |> member "kind" |> to_list |> filter_string))
    (package |> member "targets" |> to_list);
    [7.5045]
    [7.5162]
    (build_target |> member "kind" |> to_list |> filter_string))
    self#targets;
  • edit in elpe/lib/rust/rust.ml at line 548
    [7.5186]
    [7.5264]
    method! install_phase =
    Lwt.return
    {|
    if [[ -s target/env ]]; then
    mkdir -p $DESTDIR/lib
    cp target/env $DESTDIR/lib
    fi
    |}
  • replacement in elpe/lib/rust/rust.ml at line 559
    [7.4399][6.10014:10073]()
    let rust ?(rust_version = "1.84") ?(platform = None) src =
    [7.4399]
    [7.5346]
    let rec dfs nodes seen result n =
    match Hashtbl.find_opt seen n with
    | Some () -> result
    | None ->
    let _ = Hashtbl.add seen n () in
    let node = Hashtbl.find nodes n in
    let deps = node |> member "dependencies" |> to_list |> filter_string in
    let result = List.fold_left (dfs nodes seen) result deps in
    node :: result
    let topo_sort n_nodes nodes =
    let h = Hashtbl.create n_nodes in
    let nodes_list =
    List.fold_left
    (fun list node ->
    let id = node |> member "id" |> to_string in
    Hashtbl.add h id node;
    id :: list)
    [] nodes
    in
    let seen = Hashtbl.create n_nodes in
    List.fold_left (dfs h seen) [] nodes_list
    let rust ?(rust_version = "1.84") ?(target = !Platform.target)
    ?(host = !Platform.host) src =
  • edit in elpe/lib/rust/rust.ml at line 593
    [7.5896][6.10155:10194]()
    let cc = ubuntu "build-essential" in
  • replacement in elpe/lib/rust/rust.ml at line 595
    [7.5914][6.10195:10270]()
    new metadata rust_version cargo rustc platform src n_packages packages
    [7.5914]
    [7.5985]
    new metadata
    rust_version cargo rustc (Platform.triple target) src n_packages packages
  • replacement in elpe/lib/rust/rust.ml at line 609
    [7.6439][7.6439:6440]()
    [7.6439]
    [7.6440]
    let workspace_members =
    meta_json |> member "workspace_members" |> to_list |> filter_string
    in
  • edit in elpe/lib/rust/rust.ml at line 627
    [7.4515][7.4515:4516]()
  • replacement in elpe/lib/rust/rust.ml at line 633
    [7.7236][7.7236:7237]()
    [7.7236]
    [7.7237]
    let is_top_level = List.exists (fun w -> w = name) workspace_members in
    let cc = (cc :> derivation) in
  • replacement in elpe/lib/rust/rust.ml at line 637
    [6.10298][6.10298:10370]()
    rust_version rustc cc platform meta drv dependencies features
    [6.10298]
    [7.4792]
    ~rust_version ~rustc ~cc ~target ~host ~package:meta ~path:drv
    ~dependencies ~features ~opt_level:"3" ~is_top_level
  • replacement in elpe/lib/rust/rust.ml at line 641
    [7.7372][7.7372:7383]()
    nodes;
    [7.7372]
    [7.4862]
    (List.rev (topo_sort n_packages nodes));
  • replacement in elpe/lib/rust/rust.ml at line 643
    [7.4863][7.7384:7513]()
    Lwt.return
    (List.map (Hashtbl.find resolved)
    (meta_json |> member "workspace_members" |> to_list |> filter_string))
    [7.4863]
    Lwt.return (List.map (Hashtbl.find resolved) workspace_members)
  • file addition: run_build_script.sh (----------)
    [0.15691]
    while read cargo; do
    eval $(echo $cargo | sed -ne 's/cargo:rustc-link-arg=\(.*\)/RUSTC_FLAGS="-C link_arg=\1 $RUSTC_FLAGS"/p')
    eval $(echo $cargo | sed -ne 's/cargo:rustc-link-lib=\(.*\)/RUSTC_FLAGS="-l\1 $RUSTC_FLAGS"/p')
    eval $(echo $cargo | sed -ne 's/cargo:rustc-link-search=\(.*\)/RUSTC_FLAGS="-L\1 $RUSTC_FLAGS"/p')
    eval $(echo $cargo | sed -ne "s/cargo:rustc-cfg=\(.*\)/RUSTC_FLAGS='--cfg \1 $RUSTC_FLAGS'/p")
    eval $(echo $cargo | sed -ne 's/cargo:rustc-flags=\(.*\)/RUSTC_FLAGS="\1 $RUSTC_FLAGS"/p')
    echo $cargo | grep -P "^cargo:(?!:?(rustc-|warning=|rerun-if-changed=|rerun-if-env-changed))" \
    | gawk -F= "/^cargo::metadata=/ { gsub(/-/, \"_\", \$2); print \"export \" toupper(\"DEP_$(echo $CRATENAME)_\" \$2) \"=\" \"\\\"\"\$3\"\\\"\"; next }
    /^cargo:/ { sub(/^cargo::?/, \"\", \$1); gsub(/-/, \"_\", \$1); print \"export \" toupper(\"DEP_$(echo $CRATENAME)_\" \$1) \"=\" \"\\\"\"\$2\"\\\"\"; print \"export \" toupper(\"DEP_$(echo $CRATENAME)_$(echo $CRATEVERSION)_\" \$1) \"=\" \"\\\"\"\$2\"\\\"\"; next }" >> target/env
    done
  • file addition: platform.ml (----------)
    [7.55449]
    type arch = Amd64 | Aarch64
    type endianness = Little | Big
    type platform = { arch : arch; env : string }
    let default = { arch = Amd64; env = "gnu" }
    let endianness p = match p.arch with Amd64 | Aarch64 -> Little
    let env p = p.env
    let string_of_endianness = function Little -> "little" | Big -> "big"
    let string_of_arch = function Amd64 -> "x86_64" | Aarch64 -> "aarch64"
    let pointer_width _ = 64
    let triple p =
    match p.arch with
    | Amd64 -> "x86_64-unknown-linux-gnu"
    | Aarch64 -> "aarch64-unknown-linux-gnu"
    let host = ref default
    let target = ref default
  • edit in elpe/lib/elpegrpc.proto at line 73
    [7.55726]
    [7.55726]
    enum Endianness {
    big = 0;
    little = 1;
    }
  • edit in elpe/lib/elpegrpc.proto at line 93
    [7.16524]
    [7.55903]
    }
    message PlatformReply {
    Arch arch = 1;
    Endianness endianness = 2;
    int32 pointer_width = 3;
  • edit in elpe/lib/elpegrpc.proto at line 101
    [7.55906]
    [7.55906]
    message Empty {}
  • edit in elpe/lib/elpegrpc.proto at line 104
    [7.55921]
    [7.6582]
    rpc Handshake (Empty) returns (PlatformReply);
  • replacement in elpe/lib/elpe.ml at line 11
    [7.58601][7.64972:65023]()
    let rec walk_dir_rec encode f buf path path_name =
    [7.58601]
    [7.65023]
    let rec is_ignored ignored dir path current =
    match ignored with
    | [] -> current
    | (negated, dir_only, h) :: t ->
    is_ignored t dir path
    (if negated && current then not (Str.string_match h path 0)
    else if (dir_only && dir) || not dir_only then
    current || Str.string_match h path 0
    else current)
    let is_ignored_dir ignored path = is_ignored ignored true path false
    let is_ignored_file ignored path = is_ignored ignored false path false
    let rec walk_dir_rec encode f buf ignored path path_name =
  • replacement in elpe/lib/elpe.ml at line 43
    [7.65607][7.65607:66091]()
    let req =
    AddPathRequest.make
    ~request:
    (`Directory
    (AddPathRequest.Directory.make ~name:path_name
    ~permissions:0o644 ()))
    ()
    in
    let enc = encode req |> Writer.contents in
    f (Some enc);
    walk_dir_rec encode f buf path path_name
    [7.65607]
    [7.66091]
    if not (is_ignored_dir ignored path_name) then (
    let req =
    AddPathRequest.make
    ~request:
    (`Directory
    (AddPathRequest.Directory.make ~name:path_name
    ~permissions:0o644 ()))
    ()
    in
    let enc = encode req |> Writer.contents in
    f (Some enc);
    walk_dir_rec encode f buf ignored path path_name)
    else Lwt.return ()
  • replacement in elpe/lib/elpe.ml at line 57
    [7.66123][7.66123:67319]()
    let* file = Lwt_unix.openfile path [ O_RDONLY ] 0 in
    let ff =
    AddPathRequest.File.make ~name:path_name
    ~length:stat.st_size ~permissions:0o644 ()
    in
    let req = AddPathRequest.make ~request:(`File ff) () in
    let enc = encode req |> Writer.contents in
    let () = f (Some enc) in
    let rec read_all n =
    let* r = Lwt_unix.read file buf 0 4096 in
    if r != 0 then
    let req =
    AddPathRequest.make
    ~request:
    (`Contents
    (AddPathRequest.FileContents.make ~start:n
    ~content:(Bytes.sub buf 0 r) ()))
    ()
    in
    let enc = encode req |> Writer.contents in
    let () = f (Some enc) in
    read_all (n + r)
    else Lwt.return ()
    in
    read_all 0
    [7.66123]
    [7.67319]
    if not (is_ignored_file ignored path_name) then
    let* file = Lwt_unix.openfile path [ O_RDONLY ] 0 in
    let ff =
    AddPathRequest.File.make ~name:path_name
    ~length:stat.st_size ~permissions:0o644 ()
    in
    let req = AddPathRequest.make ~request:(`File ff) () in
    let enc = encode req |> Writer.contents in
    let () = f (Some enc) in
    let rec read_all n =
    let* r = Lwt_unix.read file buf 0 4096 in
    if r != 0 then
    let req =
    AddPathRequest.make
    ~request:
    (`Contents
    (AddPathRequest.FileContents.make ~start:n
    ~content:(Bytes.sub buf 0 r) ()))
    ()
    in
    let enc = encode req |> Writer.contents in
    let () = f (Some enc) in
    read_all (n + r)
    else Lwt.return ()
    in
    read_all 0
    else Lwt.return ()
  • replacement in elpe/lib/elpe.ml at line 92
    [7.67527][7.67527:67559]()
    let add_path connection path0 =
    [7.67527]
    [7.67559]
    let add_path connection ignored path0 =
  • replacement in elpe/lib/elpe.ml at line 104
    [7.67971][7.67971:68029]()
    let* _ = walk_dir_rec encode f buf path0 "" in
    [7.67971]
    [7.68029]
    let* _ = walk_dir_rec encode f buf ignored path0 "" in
  • edit in elpe/lib/elpe.ml at line 118
    [7.68469]
    [7.68469]
    let rec read_ignore ign =
    try
    let line = input_line ign in
    let rest = read_ignore ign in
    let regexp = Str.regexp {|\(\\#\)\|\(^#\)\|\(^!\)\|\(\*\*\)\|\*|} in
    let result = ref "" in
    let i = ref 0 in
    let negated = ref false in
    let _ =
    try
    let ended = ref false in
    while not !ended do
    let next = Str.search_forward regexp line !i in
    let _ =
    if next - !i > 0 then
    result := !result ^ Str.quote (String.sub line !i (next - !i))
    else ()
    in
    let m = Str.matched_string line in
    let _ =
    match m with
    | "!" -> negated := true
    | "#" -> ended := true
    | "**" -> result := !result ^ ".*"
    | "*" -> result := !result ^ "[^/]*"
    | "\\#" -> result := !result ^ "#"
    | m -> result := !result ^ Str.quote m
    in
    i := next + String.length m
    done
    with Not_found ->
    result :=
    !result ^ Str.quote (String.sub line !i (String.length line - !i))
    in
    if String.length !result > 0 then
    let dir_only = !result.[String.length !result - 1] = '/' in
    let result =
    if dir_only then String.sub !result 0 (String.length !result - 1)
    else !result
    in
    if String.contains result '/' then
    (!negated, dir_only, Str.regexp result) :: rest
    else
    (!negated, dir_only, Str.regexp ({|\(\(.+/\)\|^\)|} ^ result)) :: rest
    else rest
    with End_of_file -> []
  • edit in elpe/lib/elpe.ml at line 171
    [7.279]
    [7.58889]
    val cached = ref None
  • replacement in elpe/lib/elpe.ml at line 174
    [7.58910][7.58910:58998](),[7.59300][7.59300:59309](),[7.59309][7.280:313](),[7.313][7.59399:59439](),[7.59399][7.59399:59439](),[7.59439][7.68948:68969](),[7.7630][7.72562:72631](),[7.72562][7.72562:72631](),[7.72631][4.4737:4783](),[4.4783][7.72662:72688](),[7.72662][7.72662:72688]()
    let c =
    match !backend_conn with None -> failwith "no conn" | Some c -> c
    in
    let* res = add_path c p in
    let res, _ = Result.get_ok res in
    match res with
    | `Ok r -> Lwt.return { destdir = r.destdir; paths = r.paths }
    | `Error e -> raise (DerivationError e)
    | _ -> assert false
    [7.58910]
    [7.72688]
    match !cached with
    | None ->
    let c =
    match !backend_conn with None -> failwith "no conn" | Some c -> c
    in
    let ignored =
    try read_ignore (open_in ".ignore") with Sys_error _ -> []
    in
    let* res = add_path c ignored p in
    let res, _ = Result.get_ok res in
    let result =
    match res with
    | `Ok r -> { destdir = r.destdir; paths = r.paths }
    | `Error e -> raise (DerivationError e)
    | _ -> assert false
    in
    cached := Some result;
    Lwt.return result
    | Some cached -> Lwt.return cached
  • edit in elpe/lib/dune at line 1
    [7.62377]
    [7.62378]
    (include_subdirs unqualified)
  • replacement in elpe/lib/dune at line 3
    [7.62387][7.62387:62434](),[7.62434][7.314:406]()
    (name elpe)
    (public_name elpe)
    (modes byte)
    (libraries grpc-lwt lwt lwt.unix h2 h2-lwt-unix ocaml-protoc-plugin core yojson toml hex))
    [7.62387]
    [7.7727]
    (name elpe)
    (public_name elpe)
    (modes byte)
    (preprocess (pps ppx_blob ppx_string))
    (preprocessor_deps (file run_build_script.sh))
    (libraries grpc-lwt lwt lwt.unix h2 h2-lwt-unix ocaml-protoc-plugin core yojson toml hex))
  • replacement in elpe/lib/dune at line 12
    [7.62517][7.62517:62611](),[7.62611][7.72941:73010](),[7.73010][7.62676:62691](),[7.62676][7.62676:62691]()
    (targets elpegrpc.ml)
    (deps
    (:proto elpegrpc.proto))
    (action
    (run
    protoc
    -I
    .
    "--ocaml_out=annot=[@@deriving show { with_path = false }, eq]:."
    %{proto})))
    [7.62517]
    (targets elpegrpc.ml)
    (deps
    (:proto elpegrpc.proto))
    (action
    (run
    protoc
    -I
    .
    "--ocaml_out=annot=[@@deriving show { with_path = false }, eq]:."
    %{proto})))
  • edit in elpe/lib/derivation.ml at line 36
    [7.1296]
    [7.1296]
    let ubuntu_releases = Hashtbl.create 8
    let ubuntu_release_lock = Lwt_mutex.create ()
  • replacement in elpe/lib/derivation.ml at line 41
    [7.1356][7.1356:2288]()
    let req =
    Elpegrpc.Elpe.UbuntuReleaseRequest.make ~release ~arch ~repository ()
    in
    let open Ocaml_protoc_plugin in
    let encode, decode =
    Service.make_client_functions Elpegrpc.Elpe.Elpe.ubuntuRelease
    in
    let enc = encode req |> Writer.contents in
    Client.call ~service:"elpe.Elpe" ~rpc:"UbuntuRelease"
    ~do_request:
    (H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
    failwith "Error"))
    ~handler:
    (Client.Rpc.unary enc ~f:(fun decoder ->
    let+ decoder = decoder in
    match decoder with
    | Some decoder -> (
    Reader.create decoder |> decode |> function
    | Ok v -> v
    | Error e ->
    failwith
    (Printf.sprintf "Could not decode request: %s"
    (Result.show_error e)))
    | None -> Elpegrpc.Elpe.Elpe.Derivation.Response.make ()))
    ()
    [7.1356]
    [7.16525]
    Lwt_mutex.with_lock ubuntu_release_lock (fun () ->
    match Hashtbl.find_opt ubuntu_releases (release, arch, repository) with
    | None ->
    let req =
    Elpegrpc.Elpe.UbuntuReleaseRequest.make ~release ~arch ~repository
    ()
    in
    let open Ocaml_protoc_plugin in
    let encode, decode =
    Service.make_client_functions Elpegrpc.Elpe.Elpe.ubuntuRelease
    in
    let enc = encode req |> Writer.contents in
    let* r =
    Client.call ~service:"elpe.Elpe" ~rpc:"UbuntuRelease"
    ~do_request:
    (H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
    failwith "Error"))
    ~handler:
    (Client.Rpc.unary enc ~f:(fun decoder ->
    let+ decoder = decoder in
    match decoder with
    | Some decoder -> (
    Reader.create decoder |> decode |> function
    | Ok v -> v
    | Error e ->
    failwith
    (Printf.sprintf "Could not decode request: %s"
    (Result.show_error e)))
    | None -> Elpegrpc.Elpe.Elpe.Derivation.Response.make ()))
    ()
    in
    Hashtbl.add ubuntu_releases (release, arch, repository) r;
    Lwt.return r
    | Some x -> Lwt.return x)
  • edit in elpe/lib/derivation.ml at line 77
    [7.16587]
    [7.2288]
    let ubuntu_packages = Hashtbl.create 64
    let ubuntu_packages_locks = Hashtbl.create 64
  • replacement in elpe/lib/derivation.ml at line 81
    [7.2334][7.16588:16705]()
    let link_extra =
    List.map
    (fun (pkg, dep) -> Elpegrpc.Elpe.LinkExtra.make ~pkg ~dep ())
    link_extra
    [7.2334]
    [7.16705]
    let lock =
    try Hashtbl.find ubuntu_packages_locks (index, name)
    with Not_found ->
    let lock = Lwt_mutex.create () in
    Hashtbl.add ubuntu_packages_locks (index, name) lock;
    lock
  • replacement in elpe/lib/derivation.ml at line 88
    [7.16710][7.16710:16799](),[7.16799][7.2405:2579](),[7.2405][7.2405:2579](),[7.2579][4.4822:5909]()
    let req =
    Elpegrpc.Elpe.UbuntuPackageRequest.make ~index ~name ~link_extra ()
    in
    let open Ocaml_protoc_plugin in
    let encode, decode =
    Service.make_client_functions Elpegrpc.Elpe.Elpe.ubuntuPackage
    in
    let enc = encode req |> Writer.contents in
    let result = ref None in
    let* x =
    Client.call ~service:"elpe.Elpe" ~rpc:"UbuntuPackage"
    ~do_request:
    (H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
    failwith "Error"))
    ~handler:
    (Client.Rpc.server_streaming enc ~f:(fun responses ->
    Lwt_stream.iter_s
    (fun str ->
    Reader.create str |> decode |> function
    | Ok (`Ok v) ->
    result := Some v;
    Lwt.return ()
    | Ok (`Loading v) ->
    Printf.eprintf "Downloading %s\n" v;
    Stdlib.flush Stdlib.stderr;
    Lwt.return ()
    | Error e ->
    failwith
    (Printf.sprintf "Could not decode request: %s"
    (Result.show_error e))
    | _ -> Lwt.return ())
    responses))
    ()
    in
    match x with
    | Ok _ -> Lwt.return (Ok (Option.get !result))
    | Error e -> Lwt.return (Error e)
    type arch = Amd64 | Aarch64
    [7.16710]
    [7.3246]
    Lwt_mutex.with_lock lock (fun () ->
    match Hashtbl.find_opt ubuntu_packages (index, name) with
    | Some x -> Lwt.return x
    | None ->
    let link_extra =
    List.map
    (fun (pkg, dep) -> Elpegrpc.Elpe.LinkExtra.make ~pkg ~dep ())
    link_extra
    in
    let req =
    Elpegrpc.Elpe.UbuntuPackageRequest.make ~index ~name ~link_extra ()
    in
    let open Ocaml_protoc_plugin in
    let encode, decode =
    Service.make_client_functions Elpegrpc.Elpe.Elpe.ubuntuPackage
    in
    let enc = encode req |> Writer.contents in
    let result = ref None in
    let* x =
    Client.call ~service:"elpe.Elpe" ~rpc:"UbuntuPackage"
    ~do_request:
    (H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
    failwith "Error"))
    ~handler:
    (Client.Rpc.server_streaming enc ~f:(fun responses ->
    Lwt_stream.iter_s
    (fun str ->
    Reader.create str |> decode |> function
    | Ok (`Ok v) ->
    result := Some v;
    Lwt.return ()
    | Ok (`Loading v) ->
    Printf.eprintf "Downloading %s\n%!" v;
    Lwt.return ()
    | Error e ->
    failwith
    (Printf.sprintf "Could not decode request: %s"
    (Result.show_error e))
    | _ -> Lwt.return ())
    responses))
    ()
    in
    let result =
    match x with Ok _ -> Ok (Option.get !result) | Error e -> Error e
    in
    Hashtbl.add ubuntu_packages (index, name) result;
    Lwt.return result)
  • replacement in elpe/lib/derivation.ml at line 136
    [7.3247][4.5910:5966]()
    let ubuntu ?(release = "plucky") ?(arch = Amd64) name =
    [7.3247]
    [7.3287]
    let ubuntu ?(release = "plucky") ?(platform = !Platform.target) name =
  • replacement in elpe/lib/derivation.ml at line 157
    [6.10856][6.10856:10894]()
    match arch with
    [6.10856]
    [6.10894]
    match platform.arch with
  • replacement in elpe/lib/derivation.ml at line 215
    [7.5575][4.5967:6072]()
    Printf.printf "%s" buf;
    Stdlib.flush Stdlib.stdout
    [7.5575]
    [7.5625]
    Printf.printf "%s%!" buf
  • replacement in elpe/lib/derivation.ml at line 224
    [7.5944][4.6073:6179]()
    Printf.eprintf "%s" buf;
    Stdlib.flush Stdlib.stderr
    [7.5944]
    [7.5994]
    Printf.eprintf "%s%!" buf
  • replacement in elpe/lib/derivation.ml at line 364
    [7.10411][7.10411:10449]()
    let http ~url ~hash_algorithm ~hash =
    [7.10411]
    [7.10449]
    let http ~name ~url ~hash_algorithm ~hash =
  • replacement in elpe/lib/derivation.ml at line 367
    [7.10481][7.10481:10506]()
    method name = "http"
    [7.10481]
    [7.10506]
    method name = "http" ^ if name = "" then "" else "-" ^ name
  • replacement in elpe/lib/derivation.ml at line 407
    [6.13973][6.13973:13989]()
    let unzip pkg =
    [6.13973]
    [6.13989]
    let unzip ?(name = "") pkg =
  • replacement in elpe/lib/derivation.ml at line 410
    [6.14032][6.14032:14057]()
    method name = "rust"
    [6.14032]
    [6.14057]
    method name = "unzip" ^ if name = "" then "" else "-" ^ name
  • replacement in elpe/lib/derivation.ml at line 414
    [6.14126][6.14126:14336]()
    Lwt.return
    [
    (ubuntu "libc6-dev" :> derivation);
    (ubuntu "coreutils" :> derivation);
    (ubuntu "tar" :> derivation);
    (ubuntu "gzip" :> derivation);
    ]
    [6.14126]
    [6.14336]
    Lwt.return [ ubuntu "coreutils"; ubuntu "tar"; ubuntu "gzip" ]
  • edit in elpe/lib/derivation.ml at line 421
    [6.14511]
    let cc =
    object (self)
    inherit std_derivation
    method name = "cc"
    method! build_inputs = Lwt.return [ ubuntu "coreutils"; ubuntu "gcc" ]
    method! unpack_phase = Lwt.return ""
    method! build_phase =
    let* gcc = (ubuntu "gcc")#build in
    List.iter self#add_path gcc.destdir;
    Lwt.return
    ("mkdir -p $DESTDIR/usr/bin; ln -s " ^ List.hd gcc.destdir
    ^ "/usr/bin/gcc $DESTDIR/usr/bin/cc")
    end
  • edit in default.nix at line 122
    [7.11934]
    [7.69968]
    ocamlPackages.ppx_string
    ocamlPackages.ppx_blob