-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(nargo): Add commands to install and uninstall custom backends. (#…
- Loading branch information
1 parent
e6c139b
commit 28a413c
Showing
9 changed files
with
170 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
use std::{io::Cursor, path::Path}; | ||
|
||
/// Downloads a zipped archive and unpacks the backend binary to `destination_path`. | ||
/// | ||
/// # Backend Requirements | ||
/// | ||
/// In order for a backend to be compatible with this function: | ||
/// - `backend_url` must serve a gzipped tarball. | ||
/// - The tarball must only contain the backend's binary. | ||
/// - The binary file must be located at the archive root. | ||
pub fn download_backend(backend_url: &str, destination_path: &Path) { | ||
use flate2::read::GzDecoder; | ||
use tar::Archive; | ||
use tempfile::tempdir; | ||
|
||
// Download sources | ||
let compressed_file: Cursor<Vec<u8>> = download_binary_from_url(backend_url) | ||
.unwrap_or_else(|error| panic!("\n\nDownload error: {error}\n\n")); | ||
|
||
// Unpack the tarball | ||
let gz_decoder = GzDecoder::new(compressed_file); | ||
let mut archive = Archive::new(gz_decoder); | ||
|
||
let temp_directory = tempdir().expect("could not create a temporary directory"); | ||
archive.unpack(&temp_directory).unwrap(); | ||
|
||
// Assume that the archive contains a single file which is the backend binary. | ||
let mut archive_files = std::fs::read_dir(&temp_directory).unwrap(); | ||
let temp_binary_path = archive_files.next().unwrap().unwrap().path(); | ||
|
||
// Create directory to place binary in. | ||
std::fs::create_dir_all(destination_path.parent().unwrap()).unwrap(); | ||
|
||
// Rename the binary to the desired name | ||
std::fs::copy(temp_binary_path, destination_path).unwrap(); | ||
|
||
drop(temp_directory); | ||
} | ||
|
||
/// Try to download the specified URL into a buffer which is returned. | ||
fn download_binary_from_url(url: &str) -> Result<Cursor<Vec<u8>>, String> { | ||
let response = reqwest::blocking::get(url).map_err(|error| error.to_string())?; | ||
|
||
let bytes = response.bytes().unwrap(); | ||
|
||
// TODO: Check SHA of downloaded binary | ||
|
||
Ok(Cursor::new(bytes.to_vec())) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
use clap::Args; | ||
|
||
use crate::{backends::get_active_backend, errors::CliError}; | ||
|
||
/// Prints the name of the currently active backend | ||
#[derive(Debug, Clone, Args)] | ||
pub(crate) struct CurrentCommand; | ||
|
||
pub(crate) fn run(_args: CurrentCommand) -> Result<(), CliError> { | ||
println!("{}", get_active_backend()); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
use clap::Args; | ||
|
||
use acvm_backend_barretenberg::{backends_directory, download_backend}; | ||
|
||
use crate::errors::CliError; | ||
|
||
use super::ls_cmd::get_available_backends; | ||
|
||
/// Install a new backend | ||
#[derive(Debug, Clone, Args)] | ||
pub(crate) struct InstallCommand { | ||
backend: String, | ||
|
||
url: String, | ||
} | ||
|
||
pub(crate) fn run(args: InstallCommand) -> Result<(), CliError> { | ||
let installed_backends = get_available_backends(); | ||
|
||
assert!(!installed_backends.contains(&args.backend), "backend is already installed"); | ||
|
||
download_backend(&args.url, &backends_directory().join(args.backend).join("backend_binary")); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use clap::Args; | ||
|
||
use acvm_backend_barretenberg::backends_directory; | ||
|
||
use crate::{ | ||
backends::{ | ||
clear_active_backend, get_active_backend, set_active_backend, ACVM_BACKEND_BARRETENBERG, | ||
}, | ||
errors::CliError, | ||
}; | ||
|
||
use super::ls_cmd::get_available_backends; | ||
|
||
/// Uninstall a backend | ||
#[derive(Debug, Clone, Args)] | ||
pub(crate) struct UninstallCommand { | ||
backend: String, | ||
} | ||
|
||
pub(crate) fn run(args: UninstallCommand) -> Result<(), CliError> { | ||
let installed_backends = get_available_backends(); | ||
|
||
assert!(installed_backends.contains(&args.backend), "backend does not exist"); | ||
let active_backend = get_active_backend(); | ||
|
||
// Handle the case where we're uninstalling the currently active backend. | ||
if active_backend == args.backend { | ||
let barretenberg_is_installed = | ||
installed_backends.iter().any(|backend_name| backend_name == ACVM_BACKEND_BARRETENBERG); | ||
|
||
let new_active_backend = | ||
if args.backend != ACVM_BACKEND_BARRETENBERG && barretenberg_is_installed { | ||
// Prefer switching to barretenberg if possible. | ||
Some(ACVM_BACKEND_BARRETENBERG) | ||
} else { | ||
// Otherwise pick the first backend which isn't being uninstalled. | ||
installed_backends | ||
.iter() | ||
.find(|&backend_name| backend_name != &args.backend) | ||
.map(|name| name.as_str()) | ||
}; | ||
|
||
if let Some(backend) = new_active_backend { | ||
set_active_backend(backend) | ||
} else { | ||
// We've deleted the last backend. Clear the active backend file to be recreated once we install a new one. | ||
clear_active_backend() | ||
} | ||
} | ||
|
||
std::fs::remove_dir_all(&backends_directory().join(args.backend)) | ||
.expect("backend directory should be deleted"); | ||
|
||
Ok(()) | ||
} |