Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Split Nargo.toml operations into separate package #2224

Merged
merged 2 commits into from
Aug 9, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ members = [
"crates/noirc_driver",
"crates/nargo",
"crates/nargo_cli",
"crates/nargo_toml",
"crates/fm",
"crates/arena",
"crates/noirc_abi",
@@ -30,6 +31,7 @@ fm = { path = "crates/fm" }
iter-extended = { path = "crates/iter-extended" }
nargo = { path = "crates/nargo" }
nargo_cli = { path = "crates/nargo_cli" }
nargo_toml = { path = "crates/nargo_toml" }
noir_lsp = { path = "crates/lsp" }
noirc_abi = { path = "crates/noirc_abi" }
noirc_driver = { path = "crates/noirc_driver" }
1 change: 1 addition & 0 deletions crates/nargo_cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ dirs.workspace = true
url.workspace = true
iter-extended.workspace = true
nargo.workspace = true
nargo_toml.workspace = true
noir_lsp.workspace = true
noirc_driver.workspace = true
noirc_frontend.workspace = true
6 changes: 2 additions & 4 deletions crates/nargo_cli/src/cli/check_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use crate::{
errors::{CliError, CompileError},
find_package_manifest,
manifest::resolve_workspace_from_toml,
prepare_package,
};
use acvm::Backend;
use clap::Args;
use iter_extended::btree_map;
use nargo::package::Package;
use nargo_toml::{find_package_manifest, resolve_workspace_from_toml};
use noirc_abi::{AbiParameter, AbiType, MAIN_RETURN_NAME};
use noirc_driver::{check_crate, compute_function_signature, CompileOptions};
use noirc_frontend::{
@@ -116,11 +115,10 @@ fn create_input_toml_template(
mod tests {
use std::path::PathBuf;

use nargo_toml::{find_package_manifest, resolve_workspace_from_toml};
use noirc_abi::{AbiParameter, AbiType, AbiVisibility, Sign};
use noirc_driver::CompileOptions;

use crate::{find_package_manifest, manifest::resolve_workspace_from_toml};

use super::create_input_toml_template;

const TEST_DATA_DIR: &str = "tests/target_tests_data";
2 changes: 1 addition & 1 deletion crates/nargo_cli/src/cli/codegen_verifier_cmd.rs
Original file line number Diff line number Diff line change
@@ -14,13 +14,13 @@ use super::{
},
};
use crate::errors::CliError;
use crate::{find_package_manifest, manifest::resolve_workspace_from_toml};
use acvm::Backend;
use clap::Args;
use nargo::{
ops::{codegen_verifier, preprocess_program},
package::Package,
};
use nargo_toml::{find_package_manifest, resolve_workspace_from_toml};
use noirc_driver::CompileOptions;
use noirc_frontend::graph::CrateName;

4 changes: 2 additions & 2 deletions crates/nargo_cli/src/cli/compile_cmd.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ use iter_extended::try_vecmap;
use iter_extended::vecmap;
use nargo::package::Package;
use nargo::{artifacts::contract::PreprocessedContract, NargoError};
use nargo_toml::{find_package_manifest, resolve_workspace_from_toml};
use noirc_driver::{
compile_contracts, compile_main, CompileOptions, CompiledProgram, ErrorsAndWarnings, Warnings,
};
@@ -15,8 +16,7 @@ use clap::Args;
use nargo::ops::{preprocess_contract_function, preprocess_program};

use crate::errors::{CliError, CompileError};
use crate::manifest::resolve_workspace_from_toml;
use crate::{find_package_manifest, prepare_package};
use crate::prepare_package;

use super::fs::{
common_reference_string::{
3 changes: 1 addition & 2 deletions crates/nargo_cli/src/cli/execute_cmd.rs
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ use clap::Args;
use nargo::constants::PROVER_INPUT_FILE;
use nargo::package::Package;
use nargo::NargoError;
use nargo_toml::{find_package_manifest, resolve_workspace_from_toml};
use noirc_abi::input_parser::{Format, InputValue};
use noirc_abi::{Abi, InputMap};
use noirc_driver::{CompileOptions, CompiledProgram};
@@ -16,8 +17,6 @@ use super::compile_cmd::compile_package;
use super::fs::{inputs::read_inputs_from_file, witness::save_witness_to_dir};
use super::NargoConfig;
use crate::errors::CliError;
use crate::find_package_manifest;
use crate::manifest::resolve_workspace_from_toml;

/// Executes a circuit to calculate its return value
#[derive(Debug, Clone, Args)]
6 changes: 2 additions & 4 deletions crates/nargo_cli/src/cli/info_cmd.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
use acvm::Backend;
use clap::Args;
use nargo::package::Package;
use nargo_toml::{find_package_manifest, resolve_workspace_from_toml};
use noirc_driver::CompileOptions;
use noirc_frontend::graph::CrateName;

use crate::{
cli::compile_cmd::compile_package, errors::CliError, find_package_manifest,
manifest::resolve_workspace_from_toml,
};
use crate::{cli::compile_cmd::compile_package, errors::CliError};

use super::NargoConfig;

3 changes: 1 addition & 2 deletions crates/nargo_cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use clap::{Args, Parser, Subcommand};
use const_format::formatcp;
use nargo_toml::find_package_root;
use std::path::PathBuf;

use color_eyre::eyre;

use crate::find_package_root;

mod fs;

mod check_cmd;
3 changes: 1 addition & 2 deletions crates/nargo_cli/src/cli/prove_cmd.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ use nargo::artifacts::program::PreprocessedProgram;
use nargo::constants::{PROVER_INPUT_FILE, VERIFIER_INPUT_FILE};
use nargo::ops::{preprocess_program, prove_execution, verify_proof};
use nargo::package::Package;
use nargo_toml::{find_package_manifest, resolve_workspace_from_toml};
use noirc_abi::input_parser::Format;
use noirc_driver::CompileOptions;
use noirc_frontend::graph::CrateName;
@@ -21,8 +22,6 @@ use super::fs::{
proof::save_proof_to_dir,
};
use super::NargoConfig;
use crate::find_package_manifest;
use crate::manifest::resolve_workspace_from_toml;
use crate::{cli::execute_cmd::execute_program, errors::CliError};

/// Create proof for this program. The proof is returned as a hex encoded string.
6 changes: 2 additions & 4 deletions crates/nargo_cli/src/cli/test_cmd.rs
Original file line number Diff line number Diff line change
@@ -3,14 +3,12 @@ use std::io::Write;
use acvm::{acir::native_types::WitnessMap, Backend};
use clap::Args;
use nargo::{ops::execute_circuit, package::Package};
use nargo_toml::{find_package_manifest, resolve_workspace_from_toml};
use noirc_driver::{compile_no_check, CompileOptions};
use noirc_frontend::{graph::CrateName, hir::Context, node_interner::FuncId};
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};

use crate::{
cli::check_cmd::check_crate_and_report_errors, errors::CliError, find_package_manifest,
manifest::resolve_workspace_from_toml, prepare_package,
};
use crate::{cli::check_cmd::check_crate_and_report_errors, errors::CliError, prepare_package};

use super::{compile_cmd::optimize_circuit, NargoConfig};

3 changes: 1 addition & 2 deletions crates/nargo_cli/src/cli/verify_cmd.rs
Original file line number Diff line number Diff line change
@@ -12,14 +12,13 @@ use super::{
},
};
use crate::errors::CliError;
use crate::find_package_manifest;
use crate::manifest::resolve_workspace_from_toml;

use acvm::Backend;
use clap::Args;
use nargo::constants::{PROOF_EXT, VERIFIER_INPUT_FILE};
use nargo::ops::{preprocess_program, verify_proof};
use nargo::{artifacts::program::PreprocessedProgram, package::Package};
use nargo_toml::{find_package_manifest, resolve_workspace_from_toml};
use noirc_abi::input_parser::Format;
use noirc_driver::CompileOptions;
use noirc_frontend::graph::CrateName;
58 changes: 2 additions & 56 deletions crates/nargo_cli/src/errors.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,8 @@ use acvm::{
SmartContract,
};
use hex::FromHexError;
use nargo::{package::PackageType, NargoError};
use nargo::NargoError;
use nargo_toml::ManifestError;
use noirc_abi::errors::{AbiError, InputParserError};
use noirc_errors::reporter::ReportedErrors;
use noirc_frontend::graph::CrateName;
@@ -96,58 +97,3 @@ impl From<ReportedErrors> for CompileError {
Self::ReportedErrors(errors)
}
}

/// Errors covering situations where a package is either missing or malformed.
#[derive(Debug, Error)]
pub(crate) enum ManifestError {
/// Package doesn't have a manifest file
#[error("cannot find a Nargo.toml in {}", .0.display())]
MissingFile(PathBuf),

#[error("Cannot read file {0} - does it exist?")]
ReadFailed(PathBuf),

#[error("Nargo.toml is missing a parent directory")]
MissingParent,

#[error("Missing `type` field in {0}")]
MissingPackageType(PathBuf),

#[error("Cannot use `{1}` for `type` field in {0}")]
InvalidPackageType(PathBuf, String),

/// Package manifest is unreadable.
#[error("Nargo.toml is badly formed, could not parse.\n\n {0}")]
MalformedFile(#[from] toml::de::Error),

#[error("Unxpected workspace definition found in {0}")]
UnexpectedWorkspace(PathBuf),

#[error("Cannot find file {entry} which was specified as the `entry` field in {toml}")]
MissingEntryFile { toml: PathBuf, entry: PathBuf },

#[error(
r#"Cannot find file {entry} which is defaulted due to specifying `type = "{package_type}"` in {toml}"#
)]
MissingDefaultEntryFile { toml: PathBuf, entry: PathBuf, package_type: PackageType },

/// Invalid character `-` in package name
#[error("invalid character `-` in package name")]
InvalidPackageName,

/// Encountered error while downloading git repository.
#[error("{0}")]
GitError(String),

#[error("Selected package `{0}` was not found")]
MissingSelectedPackage(CrateName),

#[error("Default package was not found. Does {0} exist in your workspace?")]
MissingDefaultPackage(PathBuf),

#[error("Package `{0}` has type `bin` but you cannot depend on binary packages")]
BinaryDependency(CrateName),

#[error("Missing `name` field in {toml}")]
MissingNameField { toml: PathBuf },
}
58 changes: 1 addition & 57 deletions crates/nargo_cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -14,67 +14,11 @@ use noirc_frontend::{
graph::{CrateGraph, CrateId, CrateName},
hir::Context,
};
use std::{
collections::BTreeMap,
fs::ReadDir,
path::{Path, PathBuf},
};

use errors::ManifestError;
use std::collections::BTreeMap;

mod backends;
pub mod cli;
mod errors;
mod git;
mod manifest;

fn nargo_crates() -> PathBuf {
dirs::home_dir().unwrap().join("nargo")
}

/// Returns the path of the root directory of the package containing `current_path`.
///
/// Returns a `CliError` if no parent directories of `current_path` contain a manifest file.
fn find_package_root(current_path: &Path) -> Result<PathBuf, ManifestError> {
let manifest_path = find_package_manifest(current_path)?;

let package_root =
manifest_path.parent().expect("infallible: manifest file path can't be root directory");

Ok(package_root.to_path_buf())
}

/// Returns the path of the manifest file (`Nargo.toml`) of the package containing `current_path`.
///
/// Returns a `CliError` if no parent directories of `current_path` contain a manifest file.
fn find_package_manifest(current_path: &Path) -> Result<PathBuf, ManifestError> {
current_path
.ancestors()
.find_map(|dir| find_file(dir, "Nargo", "toml"))
.ok_or_else(|| ManifestError::MissingFile(current_path.to_path_buf()))
}

// Looks for file named `file_name` in path
fn find_file<P: AsRef<Path>>(path: P, file_name: &str, extension: &str) -> Option<PathBuf> {
let entries = list_files_and_folders_in(path)?;
let file_name = format!("{file_name}.{extension}");

find_artifact(entries, &file_name)
}

// There is no distinction between files and folders
fn find_artifact(entries: ReadDir, artifact_name: &str) -> Option<PathBuf> {
let entry = entries
.into_iter()
.flatten()
.find(|entry| entry.file_name().to_str() == Some(artifact_name))?;

Some(entry.path())
}

fn list_files_and_folders_in<P: AsRef<Path>>(path: P) -> Option<ReadDir> {
std::fs::read_dir(path).ok()
}

fn prepare_dependencies(
context: &mut Context,
20 changes: 20 additions & 0 deletions crates/nargo_toml/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "nargo_toml"
description = "Utilities for working with Nargo.toml files"
version.workspace = true
authors.workspace = true
edition.workspace = true

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
dirs.workspace = true
fm.workspace = true
nargo.workspace = true
noirc_frontend.workspace = true
serde.workspace = true
thiserror.workspace = true
toml.workspace = true
url.workspace = true

[dev-dependencies]
60 changes: 60 additions & 0 deletions crates/nargo_toml/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use std::path::PathBuf;

use nargo::package::PackageType;
use noirc_frontend::graph::CrateName;
use thiserror::Error;

/// Errors covering situations where a package is either missing or malformed.
#[derive(Debug, Error)]
pub enum ManifestError {
/// Package doesn't have a manifest file
#[error("cannot find a Nargo.toml in {}", .0.display())]
MissingFile(PathBuf),

#[error("Cannot read file {0} - does it exist?")]
ReadFailed(PathBuf),

#[error("Nargo.toml is missing a parent directory")]
MissingParent,

#[error("Missing `type` field in {0}")]
MissingPackageType(PathBuf),

#[error("Cannot use `{1}` for `type` field in {0}")]
InvalidPackageType(PathBuf, String),

/// Package manifest is unreadable.
#[error("Nargo.toml is badly formed, could not parse.\n\n {0}")]
MalformedFile(#[from] toml::de::Error),

#[error("Unexpected workspace definition found in {0}")]
UnexpectedWorkspace(PathBuf),

#[error("Cannot find file {entry} which was specified as the `entry` field in {toml}")]
MissingEntryFile { toml: PathBuf, entry: PathBuf },

#[error(
r#"Cannot find file {entry} which is defaulted due to specifying `type = "{package_type}"` in {toml}"#
)]
MissingDefaultEntryFile { toml: PathBuf, entry: PathBuf, package_type: PackageType },

/// Invalid character `-` in package name
#[error("invalid character `-` in package name")]
InvalidPackageName,

/// Encountered error while downloading git repository.
#[error("{0}")]
GitError(String),

#[error("Selected package `{0}` was not found")]
MissingSelectedPackage(CrateName),

#[error("Default package was not found. Does {0} exist in your workspace?")]
MissingDefaultPackage(PathBuf),

#[error("Package `{0}` has type `bin` but you cannot depend on binary packages")]
BinaryDependency(CrateName),

#[error("Missing `name` field in {toml}")]
MissingNameField { toml: PathBuf },
}
8 changes: 6 additions & 2 deletions crates/nargo_cli/src/git.rs → crates/nargo_toml/src/git.rs
Original file line number Diff line number Diff line change
@@ -9,10 +9,14 @@ fn resolve_folder_name(base: &url::Url, tag: &str) -> String {
folder_name
}

pub(crate) fn git_dep_location(base: &url::Url, tag: &str) -> PathBuf {
fn nargo_crates() -> PathBuf {
dirs::home_dir().unwrap().join("nargo")
}

fn git_dep_location(base: &url::Url, tag: &str) -> PathBuf {
let folder_name = resolve_folder_name(base, tag);

super::nargo_crates().join(folder_name)
nargo_crates().join(folder_name)
}

/// XXX: I'd prefer to use a GitHub library however, there
53 changes: 51 additions & 2 deletions crates/nargo_cli/src/manifest.rs → crates/nargo_toml/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{
collections::BTreeMap,
fs::ReadDir,
path::{Path, PathBuf},
};

@@ -11,7 +12,55 @@ use nargo::{
use noirc_frontend::graph::CrateName;
use serde::Deserialize;

use crate::{errors::ManifestError, git::clone_git_repo};
mod errors;
mod git;

pub use errors::ManifestError;
use git::clone_git_repo;

/// Returns the path of the root directory of the package containing `current_path`.
///
/// Returns a `CliError` if no parent directories of `current_path` contain a manifest file.
pub fn find_package_root(current_path: &Path) -> Result<PathBuf, ManifestError> {
let manifest_path = find_package_manifest(current_path)?;

let package_root =
manifest_path.parent().expect("infallible: manifest file path can't be root directory");

Ok(package_root.to_path_buf())
}

/// Returns the path of the manifest file (`Nargo.toml`) of the package containing `current_path`.
///
/// Returns a `CliError` if no parent directories of `current_path` contain a manifest file.
pub fn find_package_manifest(current_path: &Path) -> Result<PathBuf, ManifestError> {
current_path
.ancestors()
.find_map(|dir| find_file(dir, "Nargo", "toml"))
.ok_or_else(|| ManifestError::MissingFile(current_path.to_path_buf()))
}

// Looks for file named `file_name` in path
fn find_file<P: AsRef<Path>>(path: P, file_name: &str, extension: &str) -> Option<PathBuf> {
let entries = list_files_and_folders_in(path)?;
let file_name = format!("{file_name}.{extension}");

find_artifact(entries, &file_name)
}

// There is no distinction between files and folders
fn find_artifact(entries: ReadDir, artifact_name: &str) -> Option<PathBuf> {
let entry = entries
.into_iter()
.flatten()
.find(|entry| entry.file_name().to_str() == Some(artifact_name))?;

Some(entry.path())
}

fn list_files_and_folders_in<P: AsRef<Path>>(path: P) -> Option<ReadDir> {
std::fs::read_dir(path).ok()
}

#[derive(Debug, Deserialize, Clone)]
struct PackageConfig {
@@ -277,7 +326,7 @@ fn resolve_package_from_toml(toml_path: &Path) -> Result<Package, ManifestError>
}

/// Resolves a Nargo.toml file into a `Workspace` struct as defined by our `nargo` core.
pub(crate) fn resolve_workspace_from_toml(
pub fn resolve_workspace_from_toml(
toml_path: &Path,
selected_package: Option<CrateName>,
) -> Result<Workspace, ManifestError> {