mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 11:12:48 +03:00
add lib.leo support
This commit is contained in:
parent
8825a0741c
commit
9c2a0e4ec6
@ -2,8 +2,8 @@ use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory},
|
||||
errors::{BuildError, CLIError},
|
||||
files::{ChecksumFile, MainFile, Manifest, MAIN_FILE_NAME},
|
||||
errors::CLIError,
|
||||
files::{ChecksumFile, LibFile, MainFile, Manifest, LIB_FILE_NAME, MAIN_FILE_NAME},
|
||||
};
|
||||
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||
|
||||
@ -18,7 +18,7 @@ pub struct BuildCommand;
|
||||
|
||||
impl CLI for BuildCommand {
|
||||
type Options = ();
|
||||
type Output = (Compiler<Fq, EdwardsGroupType>, bool);
|
||||
type Output = Option<(Compiler<Fq, EdwardsGroupType>, bool)>;
|
||||
|
||||
const ABOUT: AboutType = "Compile the current package as a program";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
@ -46,11 +46,19 @@ impl CLI for BuildCommand {
|
||||
package_path.pop();
|
||||
}
|
||||
|
||||
// Verify the main file exists
|
||||
if !MainFile::exists_at(&package_path) {
|
||||
return Err(BuildError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into());
|
||||
}
|
||||
// Compile the package starting with the lib.leo file
|
||||
if LibFile::exists_at(&package_path) {
|
||||
// Construct the path to the library file in the source directory
|
||||
let mut lib_file_path = package_path.clone();
|
||||
lib_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
lib_file_path.push(LIB_FILE_NAME);
|
||||
|
||||
// Compile the library file but do not output
|
||||
let _program = Compiler::<Fq, EdwardsGroupType>::new_from_path(package_name.clone(), lib_file_path)?;
|
||||
};
|
||||
|
||||
// Compile the main.leo file along with constraints
|
||||
if MainFile::exists_at(&package_path) {
|
||||
// Create the outputs directory
|
||||
OutputsDirectory::create(&package_path)?;
|
||||
|
||||
@ -60,7 +68,8 @@ impl CLI for BuildCommand {
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
// Load the program at `main_file_path`
|
||||
let program = Compiler::<Fq, EdwardsGroupType>::new_from_path(package_name.clone(), main_file_path.clone())?;
|
||||
let program =
|
||||
Compiler::<Fq, EdwardsGroupType>::new_from_path(package_name.clone(), main_file_path.clone())?;
|
||||
|
||||
// Compute the current program checksum
|
||||
let program_checksum = program.checksum()?;
|
||||
@ -98,6 +107,11 @@ impl CLI for BuildCommand {
|
||||
|
||||
log::info!("Compiled program in {:?}", main_file_path);
|
||||
|
||||
Ok((program, checksum_differs))
|
||||
return Ok(Some((program, checksum_differs)));
|
||||
}
|
||||
|
||||
// Return None when compiling a package for publishing
|
||||
// The published package does not need to have a main.leo
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,11 @@
|
||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
commands::BuildCommand,
|
||||
directories::SOURCE_DIRECTORY_NAME,
|
||||
errors::{CLIError, RunError},
|
||||
files::{Manifest, MAIN_FILE_NAME},
|
||||
};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
@ -24,14 +31,26 @@ impl CLI for DeployCommand {
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||
let (_program, _checksum_differs) = BuildCommand::output(options)?;
|
||||
|
||||
// Get the package name
|
||||
let path = current_dir()?;
|
||||
|
||||
match BuildCommand::output(options)? {
|
||||
Some((_program, _checksum_differs)) => {
|
||||
// Get the package name
|
||||
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
||||
|
||||
log::info!("Unimplemented - `leo deploy`");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
let mut main_file_path = path.clone();
|
||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
Err(CLIError::RunError(RunError::MainFileDoesNotExist(
|
||||
main_file_path.into_os_string(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,11 @@
|
||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
commands::BuildCommand,
|
||||
directories::SOURCE_DIRECTORY_NAME,
|
||||
errors::{CLIError, RunError},
|
||||
files::{Manifest, MAIN_FILE_NAME},
|
||||
};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
@ -24,14 +31,26 @@ impl CLI for LoadCommand {
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||
let (_program, _checksum_differs) = BuildCommand::output(options)?;
|
||||
|
||||
// Get the package name
|
||||
let path = current_dir()?;
|
||||
|
||||
match BuildCommand::output(options)? {
|
||||
Some((_program, _checksum_differs)) => {
|
||||
// Get the package name
|
||||
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
||||
|
||||
log::info!("Unimplemented - `leo deploy`");
|
||||
log::info!("Unimplemented - `leo load`");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
let mut main_file_path = path.clone();
|
||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
Err(CLIError::RunError(RunError::MainFileDoesNotExist(
|
||||
main_file_path.into_os_string(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,9 @@ impl CLI for PublishCommand {
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||
let (_program, _checksum_differs) = BuildCommand::output(options)?;
|
||||
// Build all program files.
|
||||
// It's okay if there's just a lib.leo file here
|
||||
let _output = BuildCommand::output(options)?;
|
||||
|
||||
// Get the package name
|
||||
let path = current_dir()?;
|
||||
|
@ -2,8 +2,9 @@ use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
commands::BuildCommand,
|
||||
errors::{CLIError, VerificationKeyFileError},
|
||||
files::{Manifest, ProvingKeyFile, VerificationKeyFile},
|
||||
directories::SOURCE_DIRECTORY_NAME,
|
||||
errors::{CLIError, RunError, VerificationKeyFileError},
|
||||
files::{Manifest, ProvingKeyFile, VerificationKeyFile, MAIN_FILE_NAME},
|
||||
};
|
||||
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||
|
||||
@ -40,12 +41,12 @@ impl CLI for SetupCommand {
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||
let (program, checksum_differs) = BuildCommand::output(options)?;
|
||||
|
||||
// Get the package name
|
||||
let path = current_dir()?;
|
||||
let package_name = Manifest::try_from(&path)?.get_package_name();
|
||||
|
||||
match BuildCommand::output(options)? {
|
||||
Some((program, checksum_differs)) => {
|
||||
// Check if a proving key and verification key already exists
|
||||
let keys_exist = ProvingKeyFile::new(&package_name).exists_at(&path)
|
||||
&& VerificationKeyFile::new(&package_name).exists_at(&path);
|
||||
@ -102,4 +103,15 @@ impl CLI for SetupCommand {
|
||||
|
||||
Ok((program, parameters, prepared_verifying_key))
|
||||
}
|
||||
None => {
|
||||
let mut main_file_path = path.clone();
|
||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
Err(CLIError::RunError(RunError::MainFileDoesNotExist(
|
||||
main_file_path.into_os_string(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,11 @@
|
||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError, files::Manifest};
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
commands::BuildCommand,
|
||||
directories::SOURCE_DIRECTORY_NAME,
|
||||
errors::{CLIError, RunError},
|
||||
files::{Manifest, MAIN_FILE_NAME},
|
||||
};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
@ -24,14 +31,26 @@ impl CLI for UnloadCommand {
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||
let (_program, _checksum_differs) = BuildCommand::output(options)?;
|
||||
|
||||
// Get the package name
|
||||
let path = current_dir()?;
|
||||
|
||||
match BuildCommand::output(options)? {
|
||||
Some((_program, _checksum_differs)) => {
|
||||
// Get the package name
|
||||
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
||||
|
||||
log::info!("Unimplemented - `leo deploy`");
|
||||
log::info!("Unimplemented - `leo load`");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
let mut main_file_path = path.clone();
|
||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
Err(CLIError::RunError(RunError::MainFileDoesNotExist(
|
||||
main_file_path.into_os_string(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
19
leo/errors/files/lib.rs
Normal file
19
leo/errors/files/lib.rs
Normal file
@ -0,0 +1,19 @@
|
||||
use std::io;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum LibFileError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
#[error("creating: {}", _0)]
|
||||
Creating(io::Error),
|
||||
|
||||
#[error("writing: {}", _0)]
|
||||
Writing(io::Error),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for LibFileError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
LibFileError::Crate("std::io", format!("{}", error))
|
||||
}
|
||||
}
|
@ -10,6 +10,9 @@ pub use self::gitignore::*;
|
||||
pub mod inputs;
|
||||
pub use self::inputs::*;
|
||||
|
||||
pub mod lib;
|
||||
pub use self::lib::*;
|
||||
|
||||
pub mod main;
|
||||
pub use self::main::*;
|
||||
|
||||
|
56
leo/files/lib.rs
Normal file
56
leo/files/lib.rs
Normal file
@ -0,0 +1,56 @@
|
||||
//! The `lib.leo` file.
|
||||
|
||||
use crate::{directories::source::SOURCE_DIRECTORY_NAME, errors::LibFileError};
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::{fs::File, io::Write, path::PathBuf};
|
||||
|
||||
pub static LIB_FILE_NAME: &str = "lib.leo";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct LibFile {
|
||||
pub package_name: String,
|
||||
}
|
||||
|
||||
impl LibFile {
|
||||
pub fn new(package_name: &str) -> Self {
|
||||
Self {
|
||||
package_name: package_name.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exists_at(path: &PathBuf) -> bool {
|
||||
let mut path = path.to_owned();
|
||||
if path.is_dir() {
|
||||
if !path.ends_with(SOURCE_DIRECTORY_NAME) {
|
||||
path.push(PathBuf::from(SOURCE_DIRECTORY_NAME));
|
||||
}
|
||||
path.push(PathBuf::from(LIB_FILE_NAME));
|
||||
}
|
||||
path.exists()
|
||||
}
|
||||
|
||||
pub fn write_to(self, path: &PathBuf) -> Result<(), LibFileError> {
|
||||
let mut path = path.to_owned();
|
||||
if path.is_dir() {
|
||||
if !path.ends_with(SOURCE_DIRECTORY_NAME) {
|
||||
path.push(PathBuf::from(SOURCE_DIRECTORY_NAME));
|
||||
}
|
||||
path.push(PathBuf::from(LIB_FILE_NAME));
|
||||
}
|
||||
|
||||
let mut file = File::create(&path)?;
|
||||
Ok(file.write_all(self.template().as_bytes())?)
|
||||
}
|
||||
|
||||
fn template(&self) -> String {
|
||||
format!(
|
||||
r#"// The '{}' lib function.
|
||||
circuit Circ {{
|
||||
c: field
|
||||
}}
|
||||
"#,
|
||||
self.package_name
|
||||
)
|
||||
}
|
||||
}
|
@ -10,6 +10,9 @@ pub use self::inputs::*;
|
||||
pub mod gitignore;
|
||||
pub use self::gitignore::*;
|
||||
|
||||
pub mod lib;
|
||||
pub use self::lib::*;
|
||||
|
||||
pub mod main;
|
||||
pub use self::main::*;
|
||||
|
||||
|
@ -24,9 +24,9 @@ impl<'ast> From<AstImportSymbol<'ast>> for ImportSymbol {
|
||||
impl fmt::Display for ImportSymbol {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if self.alias.is_some() {
|
||||
write!(f, "\t{} as {}", self.symbol, self.alias.as_ref().unwrap())
|
||||
write!(f, "{} as {}", self.symbol, self.alias.as_ref().unwrap())
|
||||
} else {
|
||||
write!(f, "\t{}", self.symbol)
|
||||
write!(f, "{}", self.symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user