mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-22 22:44:47 +03:00
imports map, leo install
This commit is contained in:
parent
4c1298d179
commit
bbc210d016
@ -28,6 +28,7 @@ use crate::{
|
||||
pub use leo_asg::{new_context, AsgContext as Context, AsgContext};
|
||||
use leo_asg::{Asg, AsgPass, FormattedError, Program as AsgProgram};
|
||||
use leo_ast::{Input, MainInput, Program as AstProgram};
|
||||
use leo_imports::ImportParser;
|
||||
use leo_input::LeoInputParser;
|
||||
use leo_package::inputs::InputPairs;
|
||||
use leo_parser::parse_ast;
|
||||
@ -39,6 +40,7 @@ use snarkvm_r1cs::{ConstraintSynthesizer, ConstraintSystem, SynthesisError};
|
||||
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
marker::PhantomData,
|
||||
path::{Path, PathBuf},
|
||||
@ -68,6 +70,7 @@ pub struct Compiler<'a, F: PrimeField, G: GroupType<F>> {
|
||||
asg: Option<AsgProgram<'a>>,
|
||||
options: CompilerOptions,
|
||||
proof_options: TheoremOptions,
|
||||
imports_map: HashMap<String, String>,
|
||||
_engine: PhantomData<F>,
|
||||
_group: PhantomData<G>,
|
||||
}
|
||||
@ -83,6 +86,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
context: AsgContext<'a>,
|
||||
options: Option<CompilerOptions>,
|
||||
proof_options: Option<TheoremOptions>,
|
||||
imports_map: HashMap<String, String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
program_name: package_name.clone(),
|
||||
@ -94,6 +98,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
context,
|
||||
options: options.unwrap_or_default(),
|
||||
proof_options: proof_options.unwrap_or_default(),
|
||||
imports_map,
|
||||
_engine: PhantomData,
|
||||
_group: PhantomData,
|
||||
}
|
||||
@ -113,6 +118,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
context: AsgContext<'a>,
|
||||
options: Option<CompilerOptions>,
|
||||
proof_options: Option<TheoremOptions>,
|
||||
imports_map: HashMap<String, String>,
|
||||
) -> Result<Self, CompilerError> {
|
||||
let mut compiler = Self::new(
|
||||
package_name,
|
||||
@ -121,6 +127,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
context,
|
||||
options,
|
||||
proof_options,
|
||||
imports_map,
|
||||
);
|
||||
|
||||
compiler.parse_program()?;
|
||||
@ -152,6 +159,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
context: AsgContext<'a>,
|
||||
options: Option<CompilerOptions>,
|
||||
proof_options: Option<TheoremOptions>,
|
||||
imports_map: HashMap<String, String>,
|
||||
) -> Result<Self, CompilerError> {
|
||||
let mut compiler = Self::new(
|
||||
package_name,
|
||||
@ -160,6 +168,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
context,
|
||||
options,
|
||||
proof_options,
|
||||
imports_map,
|
||||
);
|
||||
|
||||
compiler.parse_input(input_string, input_path, state_string, state_path)?;
|
||||
@ -263,7 +272,7 @@ impl<'a, F: PrimeField, G: GroupType<F>> Compiler<'a, F, G> {
|
||||
let asg = Asg::new(
|
||||
self.context,
|
||||
&self.program,
|
||||
&mut leo_imports::ImportParser::new(self.main_file_path.clone()),
|
||||
&mut ImportParser::new(self.main_file_path.clone(), self.imports_map.clone()),
|
||||
)?;
|
||||
|
||||
if self.proof_options.type_inferenced {
|
||||
|
@ -33,7 +33,7 @@ use leo_compiler::{
|
||||
use snarkvm_curves::edwards_bls12::Fq;
|
||||
use snarkvm_r1cs::TestConstraintSystem;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
pub const TEST_OUTPUT_DIRECTORY: &str = "/output/";
|
||||
const EMPTY_FILE: &str = "";
|
||||
@ -52,7 +52,15 @@ fn new_compiler() -> EdwardsTestCompiler {
|
||||
let path = PathBuf::from("/test/src/main.leo");
|
||||
let output_dir = PathBuf::from(TEST_OUTPUT_DIRECTORY);
|
||||
|
||||
EdwardsTestCompiler::new(program_name, path, output_dir, make_test_context(), None, None)
|
||||
EdwardsTestCompiler::new(
|
||||
program_name,
|
||||
path,
|
||||
output_dir,
|
||||
make_test_context(),
|
||||
None,
|
||||
None,
|
||||
HashMap::new(),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_program(program_string: &str) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
|
@ -14,7 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use leo_asg::*;
|
||||
use leo_synthesizer::{CircuitSynthesizer, SerializedCircuit, SummarizedCircuit};
|
||||
@ -40,7 +43,15 @@ fn new_compiler(path: PathBuf) -> EdwardsTestCompiler {
|
||||
let program_name = "test".to_string();
|
||||
let output_dir = PathBuf::from("/output/");
|
||||
|
||||
EdwardsTestCompiler::new(program_name, path, output_dir, make_test_context(), None, None)
|
||||
EdwardsTestCompiler::new(
|
||||
program_name,
|
||||
path,
|
||||
output_dir,
|
||||
make_test_context(),
|
||||
None,
|
||||
None,
|
||||
HashMap::new(),
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_program(program_string: &str) -> Result<EdwardsTestCompiler, CompilerError> {
|
||||
|
@ -18,7 +18,7 @@ use crate::errors::ImportParserError;
|
||||
use leo_asg::{AsgContext, AsgConvertError, ImportResolver, Program, Span};
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use std::path::PathBuf;
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
/// Stores imported packages.
|
||||
///
|
||||
@ -29,14 +29,16 @@ pub struct ImportParser<'a> {
|
||||
program_path: PathBuf,
|
||||
partial_imports: IndexSet<String>,
|
||||
imports: IndexMap<String, Program<'a>>,
|
||||
pub imports_map: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl<'a> ImportParser<'a> {
|
||||
pub fn new(program_path: PathBuf) -> Self {
|
||||
pub fn new(program_path: PathBuf, imports_map: HashMap<String, String>) -> Self {
|
||||
ImportParser {
|
||||
program_path,
|
||||
partial_imports: Default::default(),
|
||||
imports: Default::default(),
|
||||
imports_map,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -55,9 +57,8 @@ impl<'a> ImportResolver<'a> for ImportParser<'a> {
|
||||
if let Some(program) = self.imports.get(&full_path) {
|
||||
return Ok(Some(program.clone()));
|
||||
}
|
||||
let mut imports = Self::default();
|
||||
let path = self.program_path.clone();
|
||||
|
||||
let mut imports = self.clone(); // Self::default() was previously
|
||||
self.partial_imports.insert(full_path.clone());
|
||||
let program = imports
|
||||
.parse_package(context, path, package_segments, span)
|
||||
|
@ -103,21 +103,30 @@ impl<'a> ImportParser<'a> {
|
||||
.collect::<Result<Vec<_>, std::io::Error>>()
|
||||
.map_err(|error| ImportParserError::directory_error(error, span, &error_path))?;
|
||||
|
||||
// Keeping backward compatibilty for existing packages.
|
||||
// If index_map contains key, use it or try to access directly.
|
||||
// TODO: Remove when migration is possible.
|
||||
let package_name = self
|
||||
.imports_map
|
||||
.get(package_name)
|
||||
.unwrap_or(&package_name.to_string())
|
||||
.clone();
|
||||
|
||||
// Check if the imported package name is in the imports directory.
|
||||
let matched_import_entry = entries
|
||||
.into_iter()
|
||||
.find(|entry| entry.file_name().into_string().unwrap().eq(package_name));
|
||||
.find(|entry| entry.file_name().into_string().unwrap().eq(&package_name));
|
||||
|
||||
// Check if the package name was found in both the source and imports directory.
|
||||
match (matched_source_entry, matched_import_entry) {
|
||||
(Some(_), Some(_)) => Err(ImportParserError::conflicting_imports(Identifier::new_with_span(
|
||||
package_name,
|
||||
&package_name,
|
||||
span.clone(),
|
||||
))),
|
||||
(Some(source_entry), None) => self.parse_package_access(context, &source_entry, &segments[1..], span),
|
||||
(None, Some(import_entry)) => self.parse_package_access(context, &import_entry, &segments[1..], span),
|
||||
(None, None) => Err(ImportParserError::unknown_package(Identifier::new_with_span(
|
||||
package_name,
|
||||
&package_name,
|
||||
span.clone(),
|
||||
))),
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ use snarkvm_r1cs::ConstraintSystem;
|
||||
use structopt::StructOpt;
|
||||
use tracing::span::Span;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Compiler Options wrapper for Build command. Also used by other commands which
|
||||
/// require Build command output as their input.
|
||||
#[derive(StructOpt, Clone, Debug)]
|
||||
@ -126,7 +128,11 @@ impl Command for Build {
|
||||
|
||||
fn apply(self, context: Context, _: Self::Input) -> Result<Self::Output> {
|
||||
let path = context.dir()?;
|
||||
let package_name = context.manifest()?.get_package_name();
|
||||
let manifest = context
|
||||
.manifest()
|
||||
.map_err(|_| anyhow!("Package manifest not found, try running `leo init`"))?;
|
||||
let package_name = manifest.get_package_name();
|
||||
let imports_map = manifest.get_imports_map().unwrap_or(HashMap::new());
|
||||
|
||||
// Sanitize the package path to the root directory.
|
||||
let mut package_path = path.clone();
|
||||
@ -174,6 +180,7 @@ impl Command for Build {
|
||||
thread_leaked_context(),
|
||||
Some(self.compiler_options.clone().into()),
|
||||
Some(self.compiler_options.into()),
|
||||
imports_map,
|
||||
)?;
|
||||
|
||||
// Compute the current program checksum
|
||||
|
@ -33,9 +33,6 @@ pub use deploy::Deploy;
|
||||
pub mod init;
|
||||
pub use init::Init;
|
||||
|
||||
pub mod install;
|
||||
pub use install::Install;
|
||||
|
||||
pub mod lint;
|
||||
pub use lint::Lint;
|
||||
|
||||
|
@ -101,9 +101,9 @@ impl Command for Add {
|
||||
// Attempt to fetch the package.
|
||||
let reader = {
|
||||
let fetch = Fetch {
|
||||
author,
|
||||
author: author.clone(),
|
||||
package_name: package_name.clone(),
|
||||
version: self.version,
|
||||
version: self.version.clone(),
|
||||
};
|
||||
let bytes = context.api.run_route(fetch)?.bytes()?;
|
||||
std::io::Cursor::new(bytes)
|
||||
@ -114,7 +114,14 @@ impl Command for Add {
|
||||
{
|
||||
ImportsDirectory::create(&path)?;
|
||||
path.push(IMPORTS_DIRECTORY_NAME);
|
||||
path.push(package_name);
|
||||
|
||||
// Dumb compatibility hack.
|
||||
// TODO: Remove once `leo add` functionality is discussed.
|
||||
if self.version.is_some() {
|
||||
path.push(format!("{}-{}@{}", author, package_name, self.version.unwrap()));
|
||||
} else {
|
||||
path.push(package_name);
|
||||
}
|
||||
create_dir_all(&path)?;
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::{commands::Command, context::Context};
|
||||
use crate::{
|
||||
commands::{package::Add, Command},
|
||||
context::Context,
|
||||
};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use structopt::StructOpt;
|
||||
@ -43,20 +46,16 @@ impl Command for Install {
|
||||
.get_package_dependencies()
|
||||
.ok_or_else(|| anyhow!("Package has no dependencies"))?;
|
||||
|
||||
use crate::commands::package::Add;
|
||||
|
||||
for (_name, dep) in deps.iter() {
|
||||
Add::new(
|
||||
None,
|
||||
Some(dep.author.clone()),
|
||||
Some(dep.name.clone()),
|
||||
Some(dep.package.clone()),
|
||||
Some(dep.version.clone()),
|
||||
)
|
||||
.execute(context.clone())?;
|
||||
}
|
||||
|
||||
dbg!(deps);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -20,6 +20,9 @@ pub use add::Add;
|
||||
pub mod clone;
|
||||
pub use clone::Clone;
|
||||
|
||||
pub mod install;
|
||||
pub use install::Install;
|
||||
|
||||
pub mod login;
|
||||
pub use login::Login;
|
||||
|
||||
|
@ -113,6 +113,7 @@ impl Command for Test {
|
||||
thread_leaked_context(),
|
||||
Some(self.compiler_options.clone().into()),
|
||||
Some(self.compiler_options.clone().into()),
|
||||
std::collections::HashMap::new(),
|
||||
)?;
|
||||
|
||||
let temporary_program = program;
|
||||
|
@ -22,13 +22,12 @@ pub mod logger;
|
||||
pub mod updater;
|
||||
|
||||
use commands::{
|
||||
package::{Add, Clone, Login, Logout, Publish, Remove},
|
||||
package::{Add, Clone, Install, Login, Logout, Publish, Remove},
|
||||
Build,
|
||||
Clean,
|
||||
Command,
|
||||
Deploy,
|
||||
Init,
|
||||
Install,
|
||||
Lint,
|
||||
New,
|
||||
Prove,
|
||||
|
@ -38,7 +38,7 @@ pub struct Remote {
|
||||
pub struct Dependency {
|
||||
pub author: String,
|
||||
pub version: String,
|
||||
pub name: String,
|
||||
pub package: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -85,6 +85,23 @@ impl Manifest {
|
||||
self.dependencies.clone()
|
||||
}
|
||||
|
||||
/// Get HashMap of kind:
|
||||
/// import name => import directory
|
||||
/// Which then used in AST/ASG to resolve import paths.
|
||||
pub fn get_imports_map(&self) -> Option<HashMap<String, String>> {
|
||||
self.dependencies.clone().map(|dependencies| {
|
||||
dependencies
|
||||
.into_iter()
|
||||
.map(|(name, dependency)| {
|
||||
(
|
||||
name,
|
||||
format!("{}-{}@{}", dependency.author, dependency.package, dependency.version),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_package_license(&self) -> Option<String> {
|
||||
self.project.license.clone()
|
||||
}
|
||||
@ -119,6 +136,10 @@ license = "MIT"
|
||||
|
||||
[remote]
|
||||
author = "{author}" # Add your Aleo Package Manager username or team name.
|
||||
|
||||
[dependencies]
|
||||
# Define dependencies here in format:
|
||||
# name = {{ package = "package-name", author = "author", version = "version" }}
|
||||
"#,
|
||||
name = self.project.name,
|
||||
author = author
|
||||
|
Loading…
Reference in New Issue
Block a user