mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-25 11:12:48 +03:00
impl zip file struct
This commit is contained in:
parent
6662b6261f
commit
d9b5c15d73
@ -10,7 +10,6 @@ use leo_compiler::{compiler::Compiler, group::edwards_bls12::EdwardsGroupType};
|
||||
use snarkos_algorithms::snark::KeypairAssembly;
|
||||
use snarkos_curves::{bls12_377::Bls12_377, edwards_bls12::Fq};
|
||||
|
||||
use crate::files::BytesFile;
|
||||
use clap::ArgMatches;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
|
||||
@ -60,30 +59,8 @@ impl CLI for BuildCommand {
|
||||
main_file_path.push(SOURCE_DIRECTORY_NAME);
|
||||
main_file_path.push(MAIN_FILE_NAME);
|
||||
|
||||
// Check if the program bytes exist
|
||||
let existing_bytes = BytesFile::new(&package_name).exists_at(&path);
|
||||
|
||||
let program = if existing_bytes {
|
||||
// Load the program ast from stored bytes
|
||||
let bytes = BytesFile::new(&package_name).read_from(&path)?;
|
||||
|
||||
let mut program = Compiler::<Fq, EdwardsGroupType>::from_bytes(bytes.as_slice())?;
|
||||
|
||||
program.set_path(main_file_path.clone());
|
||||
|
||||
program
|
||||
} else {
|
||||
// Load the program at `main_file_path`
|
||||
let program =
|
||||
Compiler::<Fq, EdwardsGroupType>::new_from_path(package_name.clone(), main_file_path.clone())?;
|
||||
|
||||
// Store the program ast as bytes
|
||||
let bytes = program.to_bytes()?;
|
||||
|
||||
BytesFile::new(&package_name).write_to(&path, bytes)?;
|
||||
|
||||
program
|
||||
};
|
||||
// Load the program at `main_file_path`
|
||||
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()?;
|
||||
|
@ -2,29 +2,12 @@ use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
commands::BuildCommand,
|
||||
directories::{INPUTS_DIRECTORY_NAME, OUTPUTS_DIRECTORY_NAME},
|
||||
errors::CLIError,
|
||||
files::{
|
||||
Manifest,
|
||||
BYTES_FILE_EXTENSION,
|
||||
CHECKSUM_FILE_EXTENSION,
|
||||
INPUTS_FILE_EXTENSION,
|
||||
PROOF_FILE_EXTENSION,
|
||||
PROVING_KEY_FILE_EXTENSION,
|
||||
VERIFICATION_KEY_FILE_EXTENSION,
|
||||
},
|
||||
files::{Manifest, ZipFile},
|
||||
};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
env::current_dir,
|
||||
fs::File,
|
||||
io::{Read, Write},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use walkdir::WalkDir;
|
||||
use zip::write::{FileOptions, ZipWriter};
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PublishCommand;
|
||||
@ -50,81 +33,17 @@ impl CLI for PublishCommand {
|
||||
let (_program, _checksum_differs) = BuildCommand::output(options)?;
|
||||
|
||||
// Get the package name
|
||||
let src_dir = current_dir()?;
|
||||
|
||||
// Build walkdir iterator from current package
|
||||
let walkdir = WalkDir::new(src_dir.clone());
|
||||
let path = current_dir()?;
|
||||
let package_name = Manifest::try_from(&path)?.get_package_name();
|
||||
|
||||
// Create zip file
|
||||
let package_name = Manifest::try_from(&src_dir)?.get_package_name();
|
||||
let mut zip_file = src_dir.clone();
|
||||
zip_file.push(PathBuf::from(format!("{}{}", package_name, ".zip".to_string())));
|
||||
|
||||
let file = &mut File::create(zip_file)?;
|
||||
let mut zip = ZipWriter::new(file);
|
||||
let zip_options = FileOptions::default()
|
||||
.compression_method(zip::CompressionMethod::Stored)
|
||||
.unix_permissions(0o755);
|
||||
|
||||
// Walk through files in directory and write desired ones to the zip file
|
||||
let mut buffer = Vec::new();
|
||||
for entry in walkdir.into_iter().filter_map(|e| e.ok()) {
|
||||
let path = entry.path();
|
||||
let name = path.strip_prefix(src_dir.as_path()).unwrap();
|
||||
|
||||
// filter excluded paths
|
||||
if is_excluded(name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// write file or directory
|
||||
if path.is_file() {
|
||||
log::info!("adding file {:?} as {:?}", path, name);
|
||||
zip.start_file_from_path(name, zip_options)?;
|
||||
let mut f = File::open(path)?;
|
||||
|
||||
f.read_to_end(&mut buffer)?;
|
||||
zip.write_all(&*buffer)?;
|
||||
buffer.clear();
|
||||
} else if name.as_os_str().len() != 0 {
|
||||
// Only if not root Avoids path spec / warning
|
||||
// and mapname conversion failed error on unzip
|
||||
log::info!("adding dir {:?} as {:?}", path, name);
|
||||
zip.add_directory_from_path(name, zip_options)?;
|
||||
}
|
||||
let zip_file = ZipFile::new(&package_name);
|
||||
if zip_file.exists_at(&path) {
|
||||
log::info!("Existing package zip file found. Skipping compression.")
|
||||
} else {
|
||||
zip_file.write(&path)?;
|
||||
}
|
||||
|
||||
zip.finish()?;
|
||||
|
||||
log::info!("zip file created");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn is_excluded(path: &Path) -> bool {
|
||||
// excluded directories: `/inputs`, `/outputs`
|
||||
if path.ends_with(INPUTS_DIRECTORY_NAME.trim_end_matches("/"))
|
||||
| path.ends_with(OUTPUTS_DIRECTORY_NAME.trim_end_matches("/"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// excluded extensions: `.in`, `.bytes`, `lpk`, `lvk`, `.proof`, `.sum`
|
||||
path.extension()
|
||||
.map(|ext| {
|
||||
if ext.eq(INPUTS_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(BYTES_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(PROVING_KEY_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(VERIFICATION_KEY_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(PROOF_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(CHECKSUM_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq("zip")
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
@ -1,15 +1,12 @@
|
||||
use crate::errors::*;
|
||||
|
||||
use walkdir::Error as WalkDirError;
|
||||
use zip::result::ZipError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum CLIError {
|
||||
#[error("{}", _0)]
|
||||
BuildError(BuildError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
BytesFileError(BytesFileError),
|
||||
BytesFileError(ZipFileError),
|
||||
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
@ -58,16 +55,10 @@ pub enum CLIError {
|
||||
|
||||
#[error("{}", _0)]
|
||||
VerificationKeyFileError(VerificationKeyFileError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
WalkDirError(WalkDirError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ZipError(ZipError),
|
||||
}
|
||||
|
||||
impl From<BytesFileError> for CLIError {
|
||||
fn from(error: BytesFileError) -> Self {
|
||||
impl From<ZipFileError> for CLIError {
|
||||
fn from(error: ZipFileError) -> Self {
|
||||
log::error!("{}\n", error);
|
||||
CLIError::BytesFileError(error)
|
||||
}
|
||||
@ -185,20 +176,6 @@ impl From<VerificationKeyFileError> for CLIError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<WalkDirError> for CLIError {
|
||||
fn from(error: WalkDirError) -> Self {
|
||||
log::error!("{}\n", error);
|
||||
CLIError::WalkDirError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ZipError> for CLIError {
|
||||
fn from(error: ZipError) -> Self {
|
||||
log::error!("{}\n", error);
|
||||
CLIError::ZipError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<leo_compiler::errors::CompilerError> for CLIError {
|
||||
fn from(error: leo_compiler::errors::CompilerError) -> Self {
|
||||
log::error!("{}\n", error);
|
||||
|
@ -1,5 +1,5 @@
|
||||
pub mod bytes;
|
||||
pub use self::bytes::*;
|
||||
pub mod zip;
|
||||
pub use self::zip::*;
|
||||
|
||||
pub mod checksum;
|
||||
pub use self::checksum::*;
|
||||
|
@ -1,7 +1,9 @@
|
||||
use std::{io, path::PathBuf};
|
||||
use walkdir::Error as WalkDirError;
|
||||
use zip::result::ZipError;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum BytesFileError {
|
||||
pub enum ZipFileError {
|
||||
#[error("{}: {}", _0, _1)]
|
||||
Crate(&'static str, String),
|
||||
|
||||
@ -13,10 +15,16 @@ pub enum BytesFileError {
|
||||
|
||||
#[error("writing: {}", _0)]
|
||||
Writing(io::Error),
|
||||
|
||||
#[error("{}", _0)]
|
||||
WalkDirError(#[from] WalkDirError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
ZipError(#[from] ZipError),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for BytesFileError {
|
||||
impl From<std::io::Error> for ZipFileError {
|
||||
fn from(error: std::io::Error) -> Self {
|
||||
BytesFileError::Crate("std::io", format!("{}", error))
|
||||
ZipFileError::Crate("std::io", format!("{}", error))
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
//! The program bytes file.
|
||||
|
||||
use crate::{directories::outputs::OUTPUTS_DIRECTORY_NAME, errors::BytesFileError};
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::{
|
||||
fs::{self, File},
|
||||
io::Write,
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
pub static BYTES_FILE_EXTENSION: &str = ".bytes";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct BytesFile {
|
||||
pub package_name: String,
|
||||
}
|
||||
|
||||
impl BytesFile {
|
||||
pub fn new(package_name: &str) -> Self {
|
||||
Self {
|
||||
package_name: package_name.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exists_at(&self, path: &PathBuf) -> bool {
|
||||
let path = self.setup_file_path(path);
|
||||
path.exists()
|
||||
}
|
||||
|
||||
/// Reads the program bytes from the given file path if it exists.
|
||||
pub fn read_from(&self, path: &PathBuf) -> Result<Vec<u8>, BytesFileError> {
|
||||
let path = self.setup_file_path(path);
|
||||
|
||||
Ok(fs::read(&path).map_err(|_| BytesFileError::FileReadError(path.clone()))?)
|
||||
}
|
||||
|
||||
/// Writes the given program bytes to a file.
|
||||
pub fn write_to(&self, path: &PathBuf, bytes: Vec<u8>) -> Result<(), BytesFileError> {
|
||||
let path = self.setup_file_path(path);
|
||||
|
||||
let mut file = File::create(&path)?;
|
||||
file.write_all(bytes.as_slice())?;
|
||||
|
||||
log::info!("program bytes stored to {:?}", path);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn setup_file_path(&self, path: &PathBuf) -> PathBuf {
|
||||
let mut path = path.to_owned();
|
||||
if path.is_dir() {
|
||||
if !path.ends_with(OUTPUTS_DIRECTORY_NAME) {
|
||||
path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME));
|
||||
}
|
||||
path.push(PathBuf::from(format!("{}{}", self.package_name, BYTES_FILE_EXTENSION)));
|
||||
}
|
||||
path
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
pub mod bytes;
|
||||
pub use self::bytes::*;
|
||||
pub mod zip;
|
||||
pub use self::zip::*;
|
||||
|
||||
pub mod checksum;
|
||||
pub use self::checksum::*;
|
||||
|
136
leo/files/zip.rs
Normal file
136
leo/files/zip.rs
Normal file
@ -0,0 +1,136 @@
|
||||
//! The program package zip file.
|
||||
|
||||
use crate::{
|
||||
directories::{INPUTS_DIRECTORY_NAME, OUTPUTS_DIRECTORY_NAME},
|
||||
errors::ZipFileError,
|
||||
files::{
|
||||
CHECKSUM_FILE_EXTENSION,
|
||||
INPUTS_FILE_EXTENSION,
|
||||
PROOF_FILE_EXTENSION,
|
||||
PROVING_KEY_FILE_EXTENSION,
|
||||
VERIFICATION_KEY_FILE_EXTENSION,
|
||||
},
|
||||
};
|
||||
|
||||
use serde::Deserialize;
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{Read, Write},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use walkdir::WalkDir;
|
||||
use zip::write::{FileOptions, ZipWriter};
|
||||
|
||||
pub static ZIP_FILE_EXTENSION: &str = ".zip";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ZipFile {
|
||||
pub package_name: String,
|
||||
}
|
||||
|
||||
impl ZipFile {
|
||||
pub fn new(package_name: &str) -> Self {
|
||||
Self {
|
||||
package_name: package_name.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exists_at(&self, path: &PathBuf) -> bool {
|
||||
let path = self.setup_file_path(path);
|
||||
path.exists()
|
||||
}
|
||||
|
||||
// /// Reads the program bytes from the given file path if it exists.
|
||||
// pub fn read_from(&self, path: &PathBuf) -> Result<Vec<u8>, ZipFileError> {
|
||||
// let path = self.setup_file_path(path);
|
||||
//
|
||||
// Ok(fs::read(&path).map_err(|_| ZipFileError::FileReadError(path.clone()))?)
|
||||
// }
|
||||
|
||||
/// Writes the current package contents to a zip file.
|
||||
pub fn write(&self, src_dir: &PathBuf) -> Result<(), ZipFileError> {
|
||||
// Build walkdir iterator from current package
|
||||
let walkdir = WalkDir::new(src_dir.clone());
|
||||
|
||||
// Create zip file
|
||||
let path = self.setup_file_path(src_dir);
|
||||
|
||||
let file = &mut File::create(&path)?;
|
||||
let mut zip = ZipWriter::new(file);
|
||||
let options = FileOptions::default()
|
||||
.compression_method(zip::CompressionMethod::Stored)
|
||||
.unix_permissions(0o755);
|
||||
|
||||
// Walk through files in directory and write desired ones to the zip file
|
||||
let mut buffer = Vec::new();
|
||||
for entry in walkdir.into_iter().filter_map(|e| e.ok()) {
|
||||
let path = entry.path();
|
||||
let name = path.strip_prefix(src_dir.as_path()).unwrap();
|
||||
|
||||
// filter excluded paths
|
||||
if is_excluded(name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// write file or directory
|
||||
if path.is_file() {
|
||||
log::info!("\tadding file {:?} as {:?}", path, name);
|
||||
zip.start_file_from_path(name, options)?;
|
||||
let mut f = File::open(path)?;
|
||||
|
||||
f.read_to_end(&mut buffer)?;
|
||||
zip.write_all(&*buffer)?;
|
||||
buffer.clear();
|
||||
} else if name.as_os_str().len() != 0 {
|
||||
// Only if not root Avoids path spec / warning
|
||||
// and mapname conversion failed error on unzip
|
||||
log::info!("\tadding dir {:?} as {:?}", path, name);
|
||||
zip.add_directory_from_path(name, options)?;
|
||||
}
|
||||
}
|
||||
|
||||
zip.finish()?;
|
||||
|
||||
log::info!("Package zip file created successfully {:?}", path);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn setup_file_path(&self, path: &PathBuf) -> PathBuf {
|
||||
let mut path = path.to_owned();
|
||||
if path.is_dir() {
|
||||
if !path.ends_with(OUTPUTS_DIRECTORY_NAME) {
|
||||
path.push(PathBuf::from(OUTPUTS_DIRECTORY_NAME));
|
||||
}
|
||||
path.push(PathBuf::from(format!("{}{}", self.package_name, ZIP_FILE_EXTENSION)));
|
||||
}
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
fn is_excluded(path: &Path) -> bool {
|
||||
// excluded directories: `/inputs`, `/outputs`
|
||||
if path.ends_with(INPUTS_DIRECTORY_NAME.trim_end_matches("/"))
|
||||
| path.ends_with(OUTPUTS_DIRECTORY_NAME.trim_end_matches("/"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// excluded extensions: `.in`, `.bytes`, `lpk`, `lvk`, `.proof`, `.sum`
|
||||
path.extension()
|
||||
.map(|ext| {
|
||||
if ext.eq(INPUTS_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(ZIP_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(PROVING_KEY_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(VERIFICATION_KEY_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(PROOF_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(CHECKSUM_FILE_EXTENSION.trim_start_matches("."))
|
||||
| ext.eq(ZIP_FILE_EXTENSION.trim_start_matches("."))
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
Loading…
Reference in New Issue
Block a user