mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 19:22:01 +03:00
add lib.leo support
This commit is contained in:
parent
8825a0741c
commit
9c2a0e4ec6
@ -2,8 +2,8 @@ use crate::{
|
|||||||
cli::*,
|
cli::*,
|
||||||
cli_types::*,
|
cli_types::*,
|
||||||
directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory},
|
directories::{source::SOURCE_DIRECTORY_NAME, OutputsDirectory},
|
||||||
errors::{BuildError, CLIError},
|
errors::CLIError,
|
||||||
files::{ChecksumFile, MainFile, Manifest, MAIN_FILE_NAME},
|
files::{ChecksumFile, LibFile, MainFile, Manifest, LIB_FILE_NAME, MAIN_FILE_NAME},
|
||||||
};
|
};
|
||||||
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ pub struct BuildCommand;
|
|||||||
|
|
||||||
impl CLI for BuildCommand {
|
impl CLI for BuildCommand {
|
||||||
type Options = ();
|
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 ABOUT: AboutType = "Compile the current package as a program";
|
||||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||||
@ -46,11 +46,19 @@ impl CLI for BuildCommand {
|
|||||||
package_path.pop();
|
package_path.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the main file exists
|
// Compile the package starting with the lib.leo file
|
||||||
if !MainFile::exists_at(&package_path) {
|
if LibFile::exists_at(&package_path) {
|
||||||
return Err(BuildError::MainFileDoesNotExist(package_path.as_os_str().to_owned()).into());
|
// 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
|
// Create the outputs directory
|
||||||
OutputsDirectory::create(&package_path)?;
|
OutputsDirectory::create(&package_path)?;
|
||||||
|
|
||||||
@ -60,7 +68,8 @@ impl CLI for BuildCommand {
|
|||||||
main_file_path.push(MAIN_FILE_NAME);
|
main_file_path.push(MAIN_FILE_NAME);
|
||||||
|
|
||||||
// Load the program at `main_file_path`
|
// 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
|
// Compute the current program checksum
|
||||||
let program_checksum = program.checksum()?;
|
let program_checksum = program.checksum()?;
|
||||||
@ -98,6 +107,11 @@ impl CLI for BuildCommand {
|
|||||||
|
|
||||||
log::info!("Compiled program in {:?}", main_file_path);
|
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 clap::ArgMatches;
|
||||||
use std::{convert::TryFrom, env::current_dir};
|
use std::{convert::TryFrom, env::current_dir};
|
||||||
@ -24,14 +31,26 @@ impl CLI for DeployCommand {
|
|||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
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 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();
|
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
||||||
|
|
||||||
log::info!("Unimplemented - `leo deploy`");
|
log::info!("Unimplemented - `leo deploy`");
|
||||||
|
|
||||||
Ok(())
|
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 clap::ArgMatches;
|
||||||
use std::{convert::TryFrom, env::current_dir};
|
use std::{convert::TryFrom, env::current_dir};
|
||||||
@ -24,14 +31,26 @@ impl CLI for LoadCommand {
|
|||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
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 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();
|
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
||||||
|
|
||||||
log::info!("Unimplemented - `leo deploy`");
|
log::info!("Unimplemented - `leo load`");
|
||||||
|
|
||||||
Ok(())
|
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)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
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
|
// Get the package name
|
||||||
let path = current_dir()?;
|
let path = current_dir()?;
|
||||||
|
@ -2,8 +2,9 @@ use crate::{
|
|||||||
cli::*,
|
cli::*,
|
||||||
cli_types::*,
|
cli_types::*,
|
||||||
commands::BuildCommand,
|
commands::BuildCommand,
|
||||||
errors::{CLIError, VerificationKeyFileError},
|
directories::SOURCE_DIRECTORY_NAME,
|
||||||
files::{Manifest, ProvingKeyFile, VerificationKeyFile},
|
errors::{CLIError, RunError, VerificationKeyFileError},
|
||||||
|
files::{Manifest, ProvingKeyFile, VerificationKeyFile, MAIN_FILE_NAME},
|
||||||
};
|
};
|
||||||
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||||
|
|
||||||
@ -40,12 +41,12 @@ impl CLI for SetupCommand {
|
|||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||||
let (program, checksum_differs) = BuildCommand::output(options)?;
|
|
||||||
|
|
||||||
// Get the package name
|
// Get the package name
|
||||||
let path = current_dir()?;
|
let path = current_dir()?;
|
||||||
let package_name = Manifest::try_from(&path)?.get_package_name();
|
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
|
// Check if a proving key and verification key already exists
|
||||||
let keys_exist = ProvingKeyFile::new(&package_name).exists_at(&path)
|
let keys_exist = ProvingKeyFile::new(&package_name).exists_at(&path)
|
||||||
&& VerificationKeyFile::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))
|
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 clap::ArgMatches;
|
||||||
use std::{convert::TryFrom, env::current_dir};
|
use std::{convert::TryFrom, env::current_dir};
|
||||||
@ -24,14 +31,26 @@ impl CLI for UnloadCommand {
|
|||||||
|
|
||||||
#[cfg_attr(tarpaulin, skip)]
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
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 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();
|
let _package_name = Manifest::try_from(&path)?.get_package_name();
|
||||||
|
|
||||||
log::info!("Unimplemented - `leo deploy`");
|
log::info!("Unimplemented - `leo load`");
|
||||||
|
|
||||||
Ok(())
|
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 mod inputs;
|
||||||
pub use self::inputs::*;
|
pub use self::inputs::*;
|
||||||
|
|
||||||
|
pub mod lib;
|
||||||
|
pub use self::lib::*;
|
||||||
|
|
||||||
pub mod main;
|
pub mod main;
|
||||||
pub use self::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 mod gitignore;
|
||||||
pub use self::gitignore::*;
|
pub use self::gitignore::*;
|
||||||
|
|
||||||
|
pub mod lib;
|
||||||
|
pub use self::lib::*;
|
||||||
|
|
||||||
pub mod main;
|
pub mod main;
|
||||||
pub use self::main::*;
|
pub use self::main::*;
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@ impl<'ast> From<AstImportSymbol<'ast>> for ImportSymbol {
|
|||||||
impl fmt::Display for ImportSymbol {
|
impl fmt::Display for ImportSymbol {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
if self.alias.is_some() {
|
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 {
|
} else {
|
||||||
write!(f, "\t{}", self.symbol)
|
write!(f, "{}", self.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user